Map Center & Bounds do not update when Container Div is Resized - mapbox-gl-js

(pretty new to Mapbox and JS, so I'm in a bit over my head)
I'm working on a page where the user needs to adjust the size of map container. It needs to be able to get accurate bounds and center point of the resized map (via map.getBounds and map.getCenter).
When I use JS to adjust the size of the container div, the center and bounds are not adjusted.
Fiddle: http://jsfiddle.net/xcow63sm/3/
Panning/zooming results in updated center and bounds. Browser window resize (if you have width or height set to 100%) works too. I would expect changing the container dimensions would adjust center and bounds.
However, if you use the form fields to adjust the height/width of the container div, the center and bounds do not. I've tried (with increasing desperation):
function resize (){
var inputwidth = document.getElementsByName("mapwidth")[0].value;
var inputheight = document.getElementsByName("mapheight")[0].value;
var mapDiv = document.getElementById('map');
var mapcenter = map.getCenter();
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.updateSize();
map.update();
map.resize();
map.invalidateSize();
document.getElementById("mapcenter").value = mapcenter;
Edit: this seems to apply but I can't make sense of it: Resizing a leaflet map on container resize

If I understand you, you have two issues: you don't like how the map is positioned after its size changes, and you're getting white space.
Map positioning after resize
There are at least three valid options for how a map should update if, say, its width and height are suddenly doubled:
keep the same northern and western bound, extend the eastern and southern bounds. (Expanding the viewing area right and down)
move all four bounds outwards (keeping the centre of the map in the same place)
leave all four bounds where they are are, but change the zoom, so the same geographic area is displayed, but in more detail.
I think your issue is that Mapbox is choosing option 1, but you want one of the other two options. The solution, as I think you've discovered, is simply to do your own maths and set the bounds how you want them.
Map failing to repaint correctly
Your second issue is that when you resize, calling map.resize() isn't updating the internal size of the map properly, and you're left with white space. The reason for this is you're using animated CSS properties. So when you do this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
map.resize();
This doesn't work because the map's size hasn't actually transitioned to the new size yet. You can work around it like this:
mapDiv.style.width = inputwidth;
mapDiv.style.height = inputheight;
window.setTimeout(()=>map.resize(), 500);
There's probably a better event you can listen to, to keep updating as the map area expands.
Updated fiddle here: http://jsfiddle.net/xcow63sm/11/
Btw you should consult the documentation here. I'm not sure where you got map.updateSize() from but that's not Mapbox-GL-JS :)

Related

How to fit bounds and set max bounds at same time on window resize in MAPBOX?

To fit the map we use mapbox.fitBounds() and to set we do mapbox.setMaxBounds(), which avoid panning. This work's perfectly well on first load.
But on Window resize map get cropped and take the bounds reference from initially set maxbounds. I am trying to fit the map in viewport using setTimeout, so that map first fit on screen and then getting map bounds from mapbox.getBounds() set the value in mapbox.setMaxBounds(). But this is just an hack.
Is there any correct way to do so?
Please help... and thank you..
Hope you are all well...
After many days of struggle, we are able to find the perfect solution, for my own question posted...
Firstly,
mapbox.fitBounds() is the method on passing given bounds as args, will fit the geometry(polygon etc..), making the center point in the middle. But the only thing it does not disallow panning.
However, we can disallow panning using mapbox.setMaxBounds() which allow us to constrained to passed bounds.
But on window resize, somehow mapbox Map change the bounds as per internal logic, which will no longer be the same as passed bounds initially...
In order to fit the geometry on the viewport, at the same time disallow panning on window resize, we use Resize Observer to observe map's container, and in its callback, we just wrote, three lines
Set map.setMaxBounds(null) //to null
set fitbounds(bounds). //bounds of geometry that u have
Get bounds from viewport using
let bnds = mapbox.getBounds();
and finally set in map.setMaxBounds(bnds);
Note to pass the 3. point in requestAnimationFrame instead of setTimeout
UPDATED Code
MaxBounds and custom asymmetric padding in Mapbox GL
Hope this will help...
Thank you.

Add an image to the map and make sure aspect ratio is correct

I have tried adding an image to Leaflet using ImageOverlay, see for example the following code:
imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
var ol = L.imageOverlay(imageUrl, imageBounds).addTo(mymap);
Now the image is added, but I would like to use the aspect ratio of the image and I would prefer to actually set the image's center point instead of the bounds. Is this at all possible?
Size of the image is not that critical, lets say I want the width to be set to 60% of the current visible area of the map, I then want the height to be calculated so that the aspect ratio of the image is kept.
Problem is I am not sure I can just translate between latitude/longitude and x/y.
Is it correct to assume that the aspect ratio longitude/latitude is the same as for x/y if the map is quite zoomed in?
Is there an easier way to do this maybe?

Unity Resizing Dropdown Dynamically

I have a dropdown list on a filter panel which needs to stretch dynamically to fit the content as shown:
I have tried several content size fitters but cannot find anything, If possible I would like to set a max width it can expand to then truncate everything longer than that, I would also like it to expand only to the right with a right pivot point. I have found a similar example here: https://forum.unity3d.com/threads/resize-standard-dropdown-to-fit-content-width.400502/
Thanks!
Well. Lets start with the code from that Unity forum thread.
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
widest = Mathf.Max(item.preferredWidth, widest);
}
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
We want to have a max-width allowed, so any content longer than this will be truncated. So let's add that variable:
var maxWidth = 250f;
//or whatever value; you may wish this to be a property so you can edit it in the inspector
var widest = 0f;
foreach (var item in _inputMines.GetComponentsInChildren<Text>()) {
Now we use the smaller of the two width values. Then apply it to the content layout:
}
widest = Mathf.Min(maxWidth, widest);
_inputMines.GetComponent<LayoutElement>().preferredWidth = widest + 40;
The +40 should be retained because that deals with the scrollbar. Your maxWidth value should be chosen to account for this.
Finally we want the longer items to get cut off nicely.
Give each dropdown item a Rect Mask 2D component (Component -> UI -> Rect Mask 2D). The template object exists in the scene hierarchy before the game is run, just disabled. You can just add the component to the parent transform, the one with the image (so the text is clipped).
You'll need to make sure that the mask covers the same width as the image graphic and expands along with it, possibly slightly shorter on the X direction so the text gets cut off before the image border is drawn. This should happen automatically, but you will need to check and possibly make some alterations to the template object. Alternatively you can use an Image Mask, but you'll have to play with that one yourself, but it will allow for non-rectangular clipping.
That's it!

iText: Do margins apply when using PdfContentByte?

I created a new document with 36 points margin all around:
Rectangle rect = new Rectangle(1224f, 792f);
Document doc = new Document(rect, 36f, 36f, 36f, 36f);
I drew a rectangle at (0, 0) using PdfContentByte:
cb.rectangle(0, 0, 100, 100);
cb.fill();
The rectangle gets drawn at the lower-left hand corner of the page. It ignores the margins completely. Is this the expected result?
Is this the expected result?
Yes, it is. The margins only are taken into account by operations adding content via the Document.
Whenever you access the content directly (DirectContent, UnderContent,OverContent), you can draw wherever you want.
When creating footers or headers, you actually rely on that behavior.
Furthermore, the margins have no influence on the coordinate system. As the coordinate system is configurable, one could have chosen 0,0 to be the lower left of the margin border. Actually you can do so by defining a page size rectangle that way. But that is not the normal usage of iText.

Leaflet.js shrink getBounds()

Leafletjs has a function pad(x) for increasing the latLng bounds. How do I shrink it? I've tried putting a negative number in there with little success.
I'm basically trying to see if a marker is within the current view, and if not center on that marker. But some markers can be plotted right on the edge of view and still be classed as in view. I'm trying to add inner padding on the current viewport bounds to avoid this.
if(!map.getBounds().pad(-1.5).contains(marker.getLatLng()))
You can use the paddingTopLeft, paddingBottomRight or padding options of L.Map's fitBounds method:
Sets the amount of padding in the top left corner of a map container that shouldn't be accounted for when setting the view to fit bounds. Useful if you have some control overlays on the map like a sidebar and you don't want them to obscure objects you're zooming to.
http://leafletjs.com/reference.html#map-paddingtopleft
map.fitBounds(layer, {'padding': [n, n]})
The negative value range for pad() is 0 to -0.5.
https://github.com/Leaflet/Leaflet/issues/5741
edit: link basically states that pad takes in a ratio of 1 not a typical percentage value. So to decrease the bounds by 50% (which would visually make it 0, because the left bounds would go in 50% to the middle, and the right bounds would also go in 50% to the middle, etc) the parameter value would be pad(-0.5) NOT pad(-50)
to increase add a positive ratio.