如何在世界范围内制作折线包装?


14

我正在使用传单地图来创建环球挑战的表示。我想添加一条折线,该折线从东京向东行驶,然后在地图上出现在南美洲的西部-但我得到一条沿相反方向与地图交叉的线(请参见黄线)。

在此处输入图片说明

我认为这可能与日期线和/或坐标系有关,但在细节上有些粗略。谁能解释我需要做些什么才能使它起作用?我正在使用美国国家航空航天局的bluemarble投影:

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
您需要在+ -180度子午线处折断折线。这需要找到折线与子午线相交的纬度。您的GIS可能具有完成任务的方法。如果不是,则可以从相关线程中显示的代码中得出简单的解决方案。您是否可以在平台上执行这样的代码?
Whuber

我同意胡言乱语。我不得不对跨过+-180的多边形执行类似的任务。每次跨过+ -180时,您都必须拆分为多个折线/多边形。
史蒂夫

Answers:


13

您需要在+ -180度子午线处折断折线。 这需要找到折线与子午线相交的纬度。您的GIS可能具有完成任务的方法。如果不是,则可以从相关线程中显示的代码中得出简单的解决方案。这里有一些细节。

  • 折线表示为一系列顶点,每个顶点都以(lat,lon)形式给出,其-180 <= lon <=180。您需要检查每对连续的对,以查看其是否穿过+ -180子午线。有一个快速测试:如果经度差的绝对值等于或大于180,则存在交叉。

  • 在穿过+ -180子午线的每个线段(lat0,lon0)->(lat1,lon1)中,您需要将折线分成两段。

关键是要以合理的精度找到断点的纬度。 使用球形地球模型最容易做到这一点:误差(与更精确的椭球模型相比)将很小,难以察觉。

让所讨论的段从(lat0,lon0)的点0到(lat1,lon1)的点1。可以通过在直角坐标表示的两点之间运行3D直线段并找到y坐标为零的位置来找到断点。在笛卡尔坐标

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

并给出点1的相似表达式(x1,y1,z1)。

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

对于t 那是,

t = y1 / (y1 - y0).

因此,交点的坐标为

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

该点(位于地球表面以下+ -180子午线以下)的纬度等于

lat2 = ATan(z/x).

断点需要以两种方式表示。 当在(lat0,lon0)之后附加它以终止折线的第一部分时,如果lon0为负,则使用(lat2,-180),否则使用(lat2,180)。将其附加到(lat1,lon1)之前以开始折线的第二部分时,请遵循类似的规则。

在特殊情况下,点0和点1之一或两者可能在+ -180子午线上。遵循此步骤将导致您在创建的多段线之一上放置零长度线段。如果这可能会导致GIS问题,请测试这种情况。

请注意,一条折线可以多次穿越此子午线。因此,在找到第一个折线并将折线分为两部分后,您需要以相同的方式处理第二部分。


1
呜咽的说的还可以,但我认为以下句子有错别字:>在(lat0,lon0)之后附加它以终止折线的第一部分> polyline时,如果lat0为负且使用(lat2,-180)否则请使用(lat2,180)。我认为它必须是:>如果lon0为负,则使用(lat2,-180),否则使用(lat2,180)
Georgi

@Georgi感谢您注意到这一点;我认为您是对的,我会做出改变。
ub

我必须在Leaflet.js中实现它,这是我的代码:gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas

谢谢@Mike。我喜欢锯齿形的插图:这正是我编写此答案时所设想的那种情况。如果您要进行严格的测试,请看看沿+ -180度子午线本身(并同时穿过两个极点)的折线会发生什么!
ub

@whuber我可能只需要尝试一下:/将发布结果
Mike Atlas

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.