This question already has answers here:
Wrapping lines/polygons across the antimeridian in Leaflet.js
(3 answers)
Closed 1 year ago.
I am developing an application which needs to show a polyline which occassionally crosses the dateline. Problem is longitude bounds are -180 and +180. I have fenagled things to determine the index of the dateline in the array of coordinates. After crossing the index I just add +360 or -360 to continue the line as-is. This works and it shows the polyline. There is one catch. The user has to move the map left or right over the dateline. When that happens the polyline appears. This is obviously not a good solution.
Has anybody figured out how to display a polyline over dateline properly in leaflet from the get-go? Meaning without the need to move the map left or right to cross the dateline to make the polyline appear.
move the map left or right to cross the dateline to make the polyline appear
From the behaviour you describe, you probably have the map worldCopyJump option enabled.
With this option enabled, the map tracks when you pan to another "copy" of the world and seamlessly jumps to the original one so that all overlays like markers and vector layers are still visible.
But in your very case, your feature exists only on one "edge" of the world, so when the map jumps to the other edge, it looks like your feature disappeared.
In that case, simply remove that option from your map.
Related
I am developing an interactive map in HTML+JavaScript using mapboxgl (0.33.1). When the user clicks a button (which is associated with a particular location in the map), I call easeTo(), which put that location in the center of the map.
window.map.easeTo({
center: item.loc
});
Because my application has some overlapping UI over the bottom half of the map, I actually want to put that location not in the center of the map, but in the center of the top half of the map (25% from the top).
I'd appreciate if somebody could give me a hint how achieve it. My app knows the exact sizes of the window in Pixel (and also the zoom level), but (I assume) I need to convert it into the map-coordinate (from pixel) to add an appropriate offset to the "center" parameter I pass to easyTo() function.
I think I found the answer. I just need to call the project() method -- which was very hard to discover!
Is there any way to adjust the bounds of the map so that the right-edge of Russia doesn't appear over to the left? You can see in the image I have a MultiPolygon area overlaying Russia but the map and the overlay are split. I'd like that tiny piece of the country to be on the right if possible!
Edge of Russia on the wrong side of the map:
A workaround I can think of is using the maxBounds property, where you would shift the default bounds slightly to the right, along with minZoom: 1. This won't prevent the user from seeing the world several times for a short time if zoomed out far / panning outside, as it says there:
... bouncing the user back when he tries to pan outside the view
var map = L.map('map',{
maxBounds:[ [-90, -160], [90, 200] ],
minZoom: 1
}).setView([66.058, 189.459], 4);
Demo
Welcome to SO!
If your multi polygon is the blueish area, then I am afraid you have to refactor your data in order to achieve what you want (shifting the left area onto the right, as if it were stitched back to Russia main land).
Your data (probably GeoJSON?) contains a separate polygon which longitudes are in the [-180, -120] range. Leaflet has no choice but to display it on the left of your map, independently from the noWrap option.
So you would need to dig into your data, and add 360 degrees longitude to every node of this polygon, so that they now sit in the range [180, 300].
Or somehow introduce a "detection" in your code that would perform the longitude addition automatically for shapes which bounds and/or center are far away (let's say in the [-180, -120] longitude range). Leaflet does not perform that operation automatically out-of-the-box.
Note: the noWrap option is for your Tile Layer not to load tiles outside that "central" world (in order to avoid showing multiple copies of the world). But in your case, you want to show a part of Russia / Siberia on an "adjacent copy of the world", so you might want to remove that option, or you will have your polygon not sitting over any basemap.
Seems like a simple question, but I have been tearing my hair out for hours now.
I have a series of files ie.
kml_image_L1_0_0.jpg
kml_image_L2_0_0.jpg
kml_image_L2_0_1.jpg
kml_image_L2_1_0.jpg
kml_image_L2_1_1.jpg
etc. However just plotting them on the leaflet map surface understandibly puts the images at 0,0 on the earths surface, and the 0 zoom level inferred by the files should really be about 15 or so.
So I want to specify the latitude and longitude where the images should originate , and what zoom level they should start at. I have tried bounds (which doesn't display anything) and I have tried playing with offsetting the zoom level.
I need this because a user needs to click on an offline map to specify where they are and I need the GPS coordinates.
I also have a KML file but it seems to be of more help for plotting vector data on the map.
Any help is much appreciated, cheers.
If I understand correctly, the "kml_image_Lz_x_y.jpg" images that you have are actually tiles, with zoom, horizontal and vertical indices in their file name?
And your issue is that they use (z,x,y) numbers as if they started from the top-most level (zoom 0, single tile for entire world), but in fact they are just a small portion of the pyramid of tiles?
And you cannot use them as is because you still want to get actual geographic coordinates (latitude, longitude), which would be totally wrong if you used the tiles as if they were showing the entire world?
In that case, you have several options as workarounds:
The most simple and reliable would probably be to simply write a small script to rename all your tiles to their true (z,x,y) numbers.
Another option would be to modify the (z,x,y) numbers before they are written in the tile src attribute, and apply the appropriate offset (constant for z, scaled by z for x and y). That should probably happen in L.TileLayer.getTileUrl() method.
Good luck! :-)
i'm trying to do simple game in lazarus, but i'm stuck with one thing that i don't really want to overcomplicate. I have some circles on the screen (pretty small ones, 10pixels diameter) and i want to draw lines between two selected. So i thought i gonna make invisible hitboxes. I took care that two hitboxes doesn't intersect.
And i want to do simple drag and drop. If i drag circle or it's hitbox and drop it on another circle or it's hitbox i want to draw a line between those two circles. And my question is: is there a elegant way of knowing which circle belongs to a hitbox? Or maybe some other nice solution to this problem?
I'm not sure how exactly you have your setup, so the answer is quite generic.
You can start with the following:
Have a function to detect which circle is below cursor - CircleHitTest(X,Y: Integer): Integer;. If there's no circle at given XY - return -1.
Upon MouseDown detect which circle was under a cursor and store it's Id in variable DrawFrom.
Upon MouseUp detect which circle was under a cursor and store it's Id in variable DrawTo
If DrawFrom and DrawTo are two different and valid circles - draw a line between them.
I have a lot of annotations to manage inside the mapkit view.
The rules are :
1 -only show annotations when the mapView.region.span.longitudeDelta is above 0.042
2 -only show annotations inside the visible area.
3- remove the annotations when they comes out the visible area...
How I can do that ... Share your experience...
Thanks
You need a few things. One is to search your database for the pins with latitudes and longitudes inside the map's view. This is called a bounding box. The next is to remove the annotations when they move outside the visible rect of the map. Each time the map is moved, you'll have to recalculate what pins are in the box and what pins are outside but still on the map.
One hint I can give you is to divide the visible rect of the map into squares (maybe 17 x 23 squares of 20 x 20) and figure out if a pin goes into that square. If it does, mark that square as filled, and if another pin wants to go into that square, don't let it. This will allow you to filter the pins so there aren't too many on screen at one time.
It's not an easy problem, but if you do some search around you'll find your way through it. This cluster marker code for Google Maps might help.