I am currently working on a project which requires MapBox to be used. We have a persistent sidebar which is laid over the top of the map in HTML. The sidebar is 500px wide.
Everything works fine, except that when we center the map at a given co-ordinate pair, there is 500 pixels' worth of the map hidden. Essentially, I am looking for a function / formula that can be used to convert the latitude position used for centering to accommodate an extra 500 pixels, at a given zoom level.
Could anyone tell me of such an algorithm (ideally in JavaScript, but could easily be converted)? We have looked into the use node-sphericalmercator, but this doesn't quite achieve what we need.
Use L.fitBounds() and the padding options to do this with Leaflet, or if you can't use bounds, convert with latLngToPoint, move the point, and convert back.
Related
I have an SVG which I have imported using d3.xml and I am trying to zoom in when I have clicked one of the ellipses in my SVG. This almost works, though I am missing some functionality of locating the elements when the size of the SVG changes. Here is the code I am using to zoom:
svg.transition().duration(750).call(
zoom.transform,
d3.zoomIdentity
.translate(widthContainer/2 , heightContainer/2)
.scale(2)
.translate(-d3.select(this).attr('cx'), -d3.select(this).attr('cy')),
d3.pointer(event, svg.node())
);
This works when the size of the browser window represents the size in which the svg was created, because the cx and cy values of the ellipses then can be used to locate them, though when I increase the size of the browser window this of course doesn't work anymore because the cx and cy values are now way off. How can I center and zoom to an element independent of the current context? I'm guessing there is a way to find out the current scale of the parent div and then calculate the translate parameters from there but I haven't found anything after a couple hours of trying.
I found a solution to my problem, my biggest error was assuming that to make my map responsive I would need to update my vars widthContainer and heightContainer (which are used to make calculations in my code for the zoom position etc.) with the current viewport width when the page is loaded and on resize. This introduced a bunch of very weird behavior and led to me spending hours on debugging that could have been avoided.
The solution to making a map with zoom features responsive is to have these two vars set to fixed values. If you are using an SVG that you are reading as xml with d3, then use the values that are set in the SVG's viewbox attribute, e.g. viewBox="0 0 657.58 344.67".
Then you can handle your container, where your SVG element is in, as usual in css and set your width to 100% or whatever you please, and the map should act responsively. I'm a total noob in d3 and JS so this behaviour didn't seem logical to me, especially because the documentation on d3's zoomIdentity is very poor. To regular d3 users this probably seems obvious but I hope this reaches fellow d3 beginners out there.
I am making a map based on arcgis js api. I have a lot of symbols drew on graphiclayer but they are too dense and even overlapping with each other.
How could I make my map showing less points if I zoom out and more points if I zoom in ? I think in this way, overlapping would no more exist.
Thanks.
You could have a look at min and max scale of the GraphicsLayer object:
https://developers.arcgis.com/javascript/3/jsapi/graphicslayer-amd.html#maxscale
Then determine what scales are you interested in. This should stop the symbols from drawing if you zoom out too far out.
Im sorry if this question is for dummies.
I'm using mapbox on a web development and I have "side" panels next to my map.
The thing is that I want to center the map on a location that I capture by double clicking it.
I know that map.setView([lat,lng],number) or map.panTo([lat,lng]) do the centering magic, but they do it over the actual size of the map o div width.
I want to know if anyone knows if I can do a custom centering, like using the same map size but the center "calculation" occurs on the left or right half of the map.
I dont know how to catch this "resolution" all I know is that I need the half of the width that the map uses. Here is an image of what I want to do enter image description here
(probably a duplicate question with that one on GIS StackExchange: Change the center point of leaflet)
You will probably be interested in one of those plugins:
Leaflet-active-area
This plugin allows you to use a smaller portion of the map as an active area. All positioning methods (setView, fitBounds, setZoom) will be applied on this portion instead of the all map.
Leaflet.ControlledBounds
Inspired by Leaflet-active-area, automatically detects the largest area of the map not covered by any map controls and applies setView, fitBounds, setZoom, getBounds to that area.
finally I figured out how to center the panTo() the way i wanted.
i used this
myLayer.on('click',function(e){
var vista=$('#map').width()/4;
map.setView(new L.LatLng(e.latlng.lat, e.latlng.lng),15);
map.panBy([-vista,0]);}
I have a function that plots a polygon centered over a certain location. I noticed that when a user zooms, the size of the polygon stays geographically the same, meaning it changes screenwise (i.e. zooming out displays a larger portion of the map, while the polygon occupies a small portion of the map).
One could say that I position the polygon with respect to geographical measurements but I wish to size it with respect to screen ditto.
How can I do that?
I suppose I could find out the size of the viewer or screen and check that against boundaries of the map and so on. However, that sounds like a tedious approach and I trust that there's functionality in the API that does all that for me, likely much faster and more reliably.
Since polygons are tied to locations you will need to just draw an image on the screen instead. (Unless you like to inflict pain upon yourself and recalculate all the polygon locations when the zoom changes).
Basically, what I'm trying to do is use a map viewer as an image viewer with the same sort of efficient tile-loading, zoom/pan awesomeness without having to build it myself.
Specifically, I need an image viewer that will allow the image to grow and change while not altering the coordinates of any older (unchanged) tiles. This means that the center point (0,0), where the image started growing from, must always remain (0,0). So I'm looking for a library that will allow me to use a very basic Cartesian coordinate system (no map projection!), which will ask for tiles infinitely in all directions with no repetition (as opposed to how map libraries just ignore y-axis above and below the map, but the x axis repeats).
There's another catch. I need zoom level 0 to be zoomed in all the way. Since the image is constantly growing, there's no way to tell what the max zoom level will be, and the coordinates need to be based on the base image layer tiles so that every tile in zoom level z contains 2^z base layer tiles.
I am wondering if this is possible with OpenLayers and how to do it. If it's not, any suggestions of other (open-source javascript) libraries that can do this would be very appreciated! I've tried playing around with Polymaps, but the documentation is lacking too much for me to be able to tell if it will work. So far no luck.
Please let me know if none of this made sense, and I'll try to include some images or better explanations. Thanks!
I ended up using Polymaps after all, since I like it more than OpenLayers, because it's faster and has much smoother scrolling and panning. I wasn't able to do exactly what I wanted, but what I did was close enough.
I ended up writing my own layer (based on the po.image() layer), which disabled infinite horizontal looping of the map. I then wrote my own version of po.url() that modified the requests going to the server for tiles so that zooming was reversed (I just arbitrarily picked a 'max' zoom of 20, then when making a request subtract the zoom level from 20) and the x and y coordinates were converted to cartesian coordinates from the standard row, column coordinates Polymaps uses, based on the zoom level and the map centered at (0,0).
If anyone is interested in the code I can post it here. Let me know!
EDIT: I've posted the code on github at https://github.com/camupod/polymaps
The relevant files are src/Backwards* and examples/backwards (though it actually doesn't work, you might be able to clean some information about how it should work).