16

I am using leaflet maps to create a representation of a round-the-world challenge. I would like to add a polyline which heads east from tokyo and then appears west of south america on the map - but instead I get a line which crosses the map in the opposite direction (see yellow line).

enter image description here

I think this is probably related to datelines and /or coordinate systems but am a bit sketchy on the detail. Can anyone explain the theory behind what I need to do to get this to work? I am using the bluemarble projection from Nasa:

var bluemarble = new L.TileLayer.WMS("http://demo.opengeo.org/geoserver/wms", {
layers: 'bluemarble',
attribution: "Data © NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5
});
2
  • 2
    You need to break the polyline at the +-180 degree meridian. This requires finding the latitude at which the polyline crosses that meridian. Your GIS probably has methods to do the breaking. If not, a simple solution can be derived from code shown in a related thread. Are you able to execute code like this on your platform?
    – whuber
    Commented Jan 13, 2012 at 14:13
  • I agree with whuber. I have had to perform a similar task with polygons crossing +- 180. You have to split into multiple polylines/polygones each time you cross the +-180.
    – Steve
    Commented Jan 13, 2012 at 23:49

2 Answers 2

15
+100

You need to break the polyline at the +-180 degree meridian. This requires finding the latitude at which the polyline crosses that meridian. Your GIS probably has methods to do the breaking. If not, a simple solution can be derived from code shown in a related thread. Here are some details.

  • A polyline is represented as a sequence of vertices, each given in (lat, lon) form, with -180 <= lon <= 180. You need to check each successive pair to see whether it crosses the +-180 meridian. There's a quick test: if the absolute value of the difference of longitudes is 180 or greater, there is a crossing.

  • Within each segment (lat0,lon0) --> (lat1,lon1) that crosses the +-180 meridian, you need to break the polyline into two pieces where it crosses.

The key is finding the latitude of the break point with reasonable accuracy. This is most easily done with a spherical earth model: the error (compared to a more accurate ellipsoidal model) will be too small to notice.

Let the segment in question go from point 0 at (lat0,lon0) to point 1 at (lat1,lon1). The break point can be found by running a straight line segment in 3D between the two points as represented in Cartesian coordinates and finding where the y coordinate is zero. The Cartesian coordinates are

(x0, y0, z0) = (cos(lon0)*sin(lat0), sin(lon0)*sin(lat0), cos(lat0))

and a similar expression giving (x1, y1, z1) for point 1. Solve the equation

t * y0 + (1-t) * y1 = 0

for t; that is,

t = y1 / (y1 - y0).

The coordinates of the intersection are therefore

(x, y, z) = (t * x0 + (1-t) * x1, 0, t * z0 + (1-t) * z1)

This point (which lies beneath the earth's surface somewhere beneath the +-180 meridian) has latitude equal to

lat2 = ATan(z/x).

The break point needs to be represented in two ways. When attaching it after (lat0, lon0) to terminate the first part of the broken polyline, use (lat2, -180) if lon0 is negative and otherwise use (lat2, 180). When attaching it before (lat1, lon1) to start the second part of the broken polyline, follow a similar rule.

In exceptional cases, one or both of point 0 and point 1 may be on the +-180 meridian. Following this procedure will cause you to place a zero-length segment on one of the polyline pieces you create. If this might cause a problem with the GIS, test for this condition.

Note that a polyline can cross this meridian more than once. Therefore, after finding the first break and breaking the polyline into two parts, you need to process the second part in the same way.

5
  • 1
    What whuber said is OK but i think there is a typo at the following sentence: >When attaching it after (lat0, lon0) to terminate the first part of the broken >polyline, use (lat2, -180) if lat0 is negative and otherwise use (lat2, 180). I think it must be : >use (lat2, -180) if lon0 is negative and otherwise use (lat2, 180)
    – Georgi
    Commented Sep 25, 2013 at 14:37
  • @Georgi Thanks for catching that; I think you're right and I will make the change.
    – whuber
    Commented Sep 25, 2013 at 15:30
  • I had to implement this in Leaflet.js, here's my code: gist.github.com/mikeatlas/0b69b354a8d713989147
    – Mike Atlas
    Commented Oct 24, 2014 at 22:19
  • Thank you, @Mike. I love the zig-zag illustration: that is exactly the kind of circumstance I was envisioning while I wrote this answer. If you want a really severe test, see what happens to a polyline that runs along the +-180 degree meridian itself (and crosses both poles)!
    – whuber
    Commented Oct 24, 2014 at 22:27
  • @whuber I may just need to try that :/ Will post results
    – Mike Atlas
    Commented Oct 27, 2014 at 15:00
0

For a related discussion, perhaps this ticket is interesting:

"vector projection over wrapping boundary is split"

https://trac.osgeo.org/grass/ticket/1527

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.