Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeoJSON polylines will not cross the 180th meridian #3250

Closed
l85m opened this issue Sep 24, 2016 · 13 comments
Closed

GeoJSON polylines will not cross the 180th meridian #3250

l85m opened this issue Sep 24, 2016 · 13 comments

Comments

@l85m
Copy link

l85m commented Sep 24, 2016

Say I want to build a map that shows a route between Fiji and American Samoa. These two islands are separated by less than 1000 miles, but because the path between them crosses the 180th meridian mapbox js gl will always draw a geojson line so that it wraps around the world.

Expected Behavior

Mapbox JS GL should choose the shortest path between two lines even if the line crosses the 180th meridian.

Google Maps Example

Actual Behavior

Mapbox JS GL will wrap the line around the world if the line crosses the 180th meridian.

https://jsbin.com/nurexefeli/edit?html,output

@mourner
Copy link
Member

mourner commented Sep 24, 2016

This is working as designed - if you need the line to cross the antimeridian, use a closer longitude beyond 180 - e.g. 179 to 188 instead of -172.

@mourner mourner closed this as completed Sep 24, 2016
@l85m
Copy link
Author

l85m commented Sep 24, 2016

Awesome, thanks for the fast response! I had no idea that longitude values above 180 were permitted. Is it in the docs somewhere or just a general convention that most would know?

I tried checking the issues here and stack overflow but did not find anything.

@livemixlove
Copy link

This is working as designed - if you need the line to cross the antimeridian, use a closer longitude beyond 180 - e.g. 179 to 188 instead of -172.

What is the reasoning for this?

I'm getting longitude values of less than -180 when dealing with user mouse events on maps in New Zealand. Our postgis database returns longitude values of +175. Saving a value of -185 will be returned as +175. It's causing problems with drawing lines interactively, and immediately (without a globe in front of us and some good coffee) we don't have a clean solution that we know works everywhere, globally.

What approach have you at Mapbox taken to dealing with this issue, and making sure lines are drawn correctly in different parts of the world? Or, can you point me to other users or libraries that have a nice solution?

@mourner
Copy link
Member

mourner commented Apr 18, 2017

What approach have you at Mapbox taken to dealing with this issue, and making sure lines are drawn correctly in different parts of the world?

You quoted the solution at the top of your comment.

@livemixlove
Copy link

But the implementation is not necessarily obvious. Or is it? We would need to consider edge cases and make sure we don't miss something and cause a bug later on. Our current workaround/hack is something like

mapbox_lon_wrap(longitude, map_center){
If (map_center is in new zealand and longitude is less than 0)
   return longitude+360
else return longitude
}

It would be nice to have a robust solution. What if we're mapping large cross-ocean geometry, say, a line that goes over New Zealand and England? Does someone have a nice little helper function to prevent geometry display issues? We have too many maps in different places at different scales to manually use the above solution on geometry.

Why not always draw the line of the shortest distance between two points, and only use "real" longitude values?

Related: why do mouse events sometimes give me < -180 values when near the 180th meridian? Or to hide/prevent geometry drawing issues that arise from the issue described in OP? What's happening under the hood to decide to provide the real longitude value or the wrapped longitude value? I understand why the map will accept and display these values (<-180, >+180), but, in our case, generating these values it's not the desired behavior because it doesn't match our postgis GeoJSON output.

@mourner
Copy link
Member

mourner commented Apr 18, 2017

When we're rendering a line segment that stretches through more than 180 degrees of longitude, does the user want to render a shorter line between two points, or does they really mean to render a long line across the world? This can't be determined automatically and depends on the use case. So we're leaving this to the user to decide and handle on their side.

For snapping a sequence of points, you could use the following simple snippet:

lng += lng - prevLng > 180 ? -360 : 
       prevLng - lng > 180 ? 360 : 0;

If you experience an issue with inconsistent mouse coordinates, please submit a new issue, making sure to fully fill the submission template including concrete steps to reproduce and a minimal JSFiddle test case.

@livemixlove
Copy link

Thanks for the thorough reply!

Giving your reasoning, which makes sense, what seems off to me is that the map will not show values over 540 or less than 540 longitude (at least when I tested it). If you could use any longitude value (and have it wrap infinitely around the planet), then this would be very convenient for iteration-based calculations and in line with the up-to-the-user ethos. As it stands though, one either has to implement logic to deal with the 180th meridian logic or you have to make sure you don't go beyond +/-540, which requires it's own wrapping function depending on the desired outcome.

In my opinion resolving/abstracting/hiding one of these issues in the mapbox library would be an improvement. Maybe make mapbox allow longitudes beyond 540 and -540?

@daamsie
Copy link

daamsie commented May 15, 2018

I've hacked the longitude of my displayed polylines basically as suggested, but the problem only fixes it for one cycle of the world. As @livemixlove said above, when we get over 540 longitude, we're out of luck.

Here is a jsfiddle showing the problem. The black line is without any adjustments - the red line with the adjustments to longitude made. You can see that on the second crossing of the dateline the hacked longitudes stop working.

I'd appreciate a re-opening of this issue, or at least being pointed to a plugin that will be able to handle displaying polylines like this.

@Nylle
Copy link

Nylle commented Mar 25, 2020

This is working as designed - if you need the line to cross the antimeridian, use a closer longitude beyond 180 - e.g. 179 to 188 instead of -172.

This statement kind of contradicts issue #4974 in mapbox-gl-native where a similar behaviour was corrected.

However, after applying the workaround mentioned above to my data-sets, MapBox Studio won't let me upload them, stating Input failed. Datasets don't support features outside longitude +/-180, latitude +/-90.

@sgillies
Copy link

@Nylle since the issue was closed there is a solution in the GeoJSON format itself: if you can split your lines or shapes at the antimeridian into multi-linestrings or multi-polygons, Studio will make them into a tileset and they will display as you expect. For example, check out the simple GeoJSON below. The MultiLineString has two parts, split at the anti-meridian.

{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"MultiLineString","coordinates":[[[170,-21],[180.0,-19]], [[-180.0, -19], [-170,-17]]]}}]}

Here it is overlaid on Mapbox satellite-streets in Studio.

Screenshot from 2020-03-25 15-34-54

@Nylle
Copy link

Nylle commented Mar 25, 2020

This is going to be tricky to implement in a generic fashion, but I guess I have no other choice.

Thank you very much for your reply.

@incarnateTheGreat
Copy link

When we're rendering a line segment that stretches through more than 180 degrees of longitude, does the user want to render a shorter line between two points, or does he really mean to render a long line across the world? This can't be determined automatically and depends on the use case. So we're leaving this to the user to decide and handle on their side.

For snapping a sequence of points, you could use the following simple snippet:

lng += lng - prevLng > 180 ? -360 : 
       prevLng - lng > 180 ? 360 : 0;

If you experience an issue with inconsistent mouse coordinates, please submit a new issue, making sure to fully fill the submission template including concrete steps to reproduce and a minimal JSFiddle test case.

Perfect. Thank you.

@jhoanborges
Copy link

2022 and i'm still having the same problem
image

frederickobrien added a commit to frederickobrien/paperback-router that referenced this issue Dec 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants