Mapbox-gl-native: Shape overlays are unable to cross antimeridian

Created on 9 May 2016  路  10Comments  路  Source: mapbox/mapbox-gl-native

A polyline that straddles the antimeridian ends up taking the long way around the globe:

CLLocationCoordinate2D coords[2] = {
    CLLocationCoordinate2DMake(0, -170),
    CLLocationCoordinate2DMake(0, 170),
};
MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coords count:sizeof(coords) / sizeof(coords[0])];
[mapView addOverlay:polyline];

mapbox

The corresponding MapKit code does straddle the antimeridian:

mapkit

Also reproduces with polygons.

This is a very old bug that has reproduced in the iOS SDK since shape annotations were first implemented in #1655, but I was unable to find a ticket that adequately addresses it. The diagnosis in https://github.com/mapbox/mapbox-gl-native/issues/3879#issuecomment-183149498 probably applies here, even though point annotations are apparently unaffected as of #4285.

/cc @jfirebaugh @tobrun @bleege

Core bug

All 10 comments

Confirming that this also impacts the Android SDK as the corresponding code produces a similar screenshot.

// Android Binding Code
List<LatLng> points = Arrays.asList(new LatLng(0, -170), new LatLng(0, 170));
mapboxMap.addPolyline(new PolylineOptions().addAll(points));

This translates to the Core GL level by MapboxMap.addPolyline() calling MapView.addPolyline() which in turn calls addShapeAnnotations() in Core GL to do the rendering.

android-antimeridian-polyline

Can you do

CLLocationCoordinate2D coords[2] = {
    CLLocationCoordinate2DMake(0, -170),
    CLLocationCoordinate2DMake(0, -190),
};
MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coords count:sizeof(coords) / sizeof(coords[0])];
[mapView addOverlay:polyline];

MapKit may be doing some kind of guessing/snapping here but Mapbox GL JS certainly doesn't - much like GeoJSON that crosses the antimeridian, the only unambiguous way to represent this geometry is with coordinates >180 or <-180

@tmcw latest revision to the GeoJSON draft says

In representing features that cross the antimeridian, interoperability is improved by modifying their geometry. Any geometry that crosses the antimeridian SHOULD be represented by cutting it in two such that neither part's representation crosses the antimeridian.

https://github.com/geojson/draft-geojson/blob/master/middle.mkd#antimeridian-cutting

If we were to require the use of longitudes beyond 卤180掳 in order to add such features, I think that would be fine from a developer standpoint. Ideally, we'd handle the job of partitioning the feature along the antimeridian for the developer.

@1ec5 Do we have an update on a fix to this issue? We've seen this issue materialize with actual storm tracks in our development environment. See attached.
img_8181
img_8180

Is a possible workaround to:

  1. See if start and end longitude are within 90 degrees of each other.
  2. See if they straddle the -180/180 antemeridian.
  3. If so, swap pairs west-to-east if needed.

Step 3 doesn't look sound. If I'm not mistaken, you'd get the same result as the current behavior.

The right workaround will be too add or subtract 360 to longitudes that are "too far" away, e.g. so that the example [-170,0], [170,0] above will become [190,0], [170,0] or [-190,0], [-170,0]. Combined with a fix in https://github.com/mapbox/geojson-vt-cpp/pull/57, this should cover all use cases.

Closing this. The solution noted by @mourner along with the fix in geojson-vt-cpp works.

Noting that the workaround is no longer needed, now that mapbox/geojson-vt-cpp#57 has landed in mapbox/mapbox-gl-native#6088.

Was this page helpful?
0 / 5 - 0 ratings