查找从沿海点 A 到沿海点 B 的海上路径
我面临着看似棘手的挑战,试图找出一条从一个海港到另一个海港的海上路径。最终目标是将其绘制在 Google(或 Bing)地图上作为折线。
路径需要:
- 合理,因为船不能越过陆地(显然)
- 不要距离海岸线太近。船不能离岸那么远,
- 也不能太复杂。它将在 Google 地图上绘制,因此 2000 点的折线无法完成。
- 做到最短,但不能牺牲以上三点
所以,我的第一个想法是获取世界各地海岸线的数据。这样的东西可以在这里找到。不幸的是,它还不完整。 OpenStreetMap 显示了这些数据,并且加勒比岛屿等地区的海岸线缺失。
我还考虑过地理编码(不够可靠,而且我会消耗数千个尝试绘制路线的请求)
我的下一个想法是以某种方式使用Google地图并测试一个点是否是蓝色的。 GMaps.NET 是一个很棒的 .NET 映射组件,它允许我通过创建其呈现的位图并测试其颜色来实现此目的一个像素。
第一个问题是,此命中测试的准确性仅与我测试的图像的分辨率图像一样好。对于彼此靠近的端口来说,这很好,对于较远的端口来说,精度会受到影响。
第二个问题,假设我使用某种“蓝色像素测试”方法,什么算法适合寻找路线。 A* 算法 看起来很有希望,但我不确定如何将路径从存在中“推出”到靠近海岸的地方。也不知道如何降低折线的复杂性。
所以......任何输入:想法、想法、链接、示例代码等都将受到欢迎。谢谢。
(我应该补充一点,这是一个旅游网站。准确性并不是太重要,我不指导运输或其他任何事情)
I have the seemingly tricky challenge of trying to work out a path, by sea, from one sea port to another sea port. The eventual aim is to plot this on a Google (or Bing) Map as a polyline.
The path needs to:
- Be plausible, as a ship can't go over land (obviously)
- Not run too close to the coast line. Ships can't go that far near to shore
- Not be too complex. It's going to be plotted on Google Maps so a 2000 point polyline wont do.
- Be the shortest, but not at the expense of the above three points
So, my first idea was obtain data on coast lines around the world. Such a thing is available here. Unfortunately it's incomplete however. OpenStreetMap shows this data and shorelines for things like Caribbean islands are missing.
I also thought about Geocoding (not reliable enough plus I would burn through thousands of requests trying to plot a route)
My next idea was to somehow use Google Maps and test if a point is blue or not. GMaps.NET, a great .NET Mapping component, allowed me to achieve this by creating a bitmap of what it renders and testing the color of a pixel.
First problem is that the accuracy of this hit testing is only as good as the resolution image of the image I test against. For ports close to each other, this is fine for ports further away, the accuracy suffers.
Second problem, assuming I use some kind of 'blue pixel testing' method, is what algorithm is right for finding a route. The A* algorithm looks promising, but I'm not sure how to push the path 'out' from the being to near to the coast. Nor how to reduce complexity of the polyline.
So ... any input: ideas, thoughts, links, sample code, etc would be welcome. Thanks.
(I should add that this is for a travel site. Accuracy isn't too important, I'm not directing shipping or anything)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是一个使用 R 的解决方案。可以进一步完善,只需使某些区域对于最短路径算法变得昂贵或便宜即可。例如,排除北冰洋、允许主要河流/运河、指定已知的旅行首选航线。
Here's a solution using R. Could be much refined, simply by making certain regions expensive or cheap for the shortest path algorithm. For example exclude the Arctic Ocean, allow major rivers/canals, make known shipping routes preferred for travel.
为了简化从 A* 搜索中获得的折线,您可以使用类似 道格拉斯-普克。另请参阅此参考文献列表: http://maven.smith.edu/~orourke/ TOPP/P24.html。
替代想法:应用 A* 的通常方法是将每个像素视为可能的状态(位置),但没有理由不能仅使用像素的子集作为可能的状态反而。如果将起点和端点附近的状态密度设置为高,将远离任一端点的状态密度设置为低,那么您将自动获得以短而精确的运动开始和结束,但中间有长直线段的路径(例如穿越太平洋时)。如果这样做,您可能还想增加陆地附近的位置密度。
另一个可能的 A* 调整:您可以将“当前方向”合并到状态中,并惩罚导致方向改变的运动。这往往会在您的路径中产生长直线。这将使您的状态空间乘以 8,但这可能是可以忍受的。因为您只是增加了解决方案的成本,所以您通常使用的直线到目的地启发式对于这个新的成本函数仍然是可接受的,因此不会出现任何复杂情况。
To simplify the polyline you get from e.g. A* search, you can use an algorithm like Douglas-Peucker. See also this list of references: http://maven.smith.edu/~orourke/TOPP/P24.html.
Alternative idea: The usual way to apply A* would be to consider each pixel as a possible state (position), but there's no reason why you couldn't use just a subset of the pixels as possible states instead. If you make the density of states near the beginning and endpoints high, and the density of states far from either endpoint low, then you'll automatically get paths that begin and end with short, precise movements, but have long straight segments in the middle (e.g. when crossing the Pacific). If you do this, you might want to also increase the density of positions near land.
Another possible A* tweak: You can incorporate "current direction" into the state, and penalise movements that cause a change in direction. This will tend to produce long straight lines in your path. This will multiply your state space by 8, but that's probably bearable. Because you're only adding to the cost of a solution, the straight-line-to-destination heuristic you would normally use remains admissible for this new cost function, so no complications arise there.
首先创建世界的二值海洋图像(白色:是海,黑色:不是海),然后腐蚀该图像。侵蚀后的所有白点均可通航。当然,忽略一两个奇怪的沙洲。
正如您可能猜到的那样,这种方法揭示了寻路中的一个核心问题:大多数船只必须非常靠近陆地才能到达港口,这违反了导航规则。然而,这个问题可以通过在与给定港口相邻的最近的可航行海点开始航行来解决。
First create the binary sea image of the world (white: is sea, black: not sea), then erode the image. All white points after erosion are navigable. Neglecting the odd sandbank or two, of course.
As you might guess, this approach reveals a central problem in your pathfinding: Most ships have to steer quite close to land to reach a port, violating the navigation rules. However, that could be solved by starting navigation at the closest navigable sea point adjacent to a given harbour.
如果我是你,我会选择图论方法。您唯一的问题是收集数据库的边缘。如果您有它们,您可以使用 A* 或 Dijkstra 算法来规划最短路线。
不管怎样,如果我认为是正确的,你需要类似于 (Searoutefinder) 的东西,对吗?祝你好运!
If I were you I would choose a graph theory approach. Your only problem would be to gather the edges of the database. If you have them you can use A* or Dijkstra's algo to plan the shortest route.
Anyways, if I assume it right you need something similar to (Searoutefinder) right? Good luck!
这是使用 scgraph 的 Python 方法。理论上,您可以使用 scgraph 来解决各种网络图的最短路径,使用一些经过修改的 Dijkstra 算法,这些算法设计对稀疏图非常有效。
该软件包附带了一些基本的网络图来帮助您入门。有几个海事网络图可供使用。
以下是文档中的一个示例,使用稍作修改(针对反子午线支持进行调整)的 Marnet 数据:
根据您的绘图需求,您需要为您正在使用的 gis 系统相应地设置坐标路径的格式。
这将产生如下路由:
注:scgraph 产生的长度假设所有非基于网络的地理旅行的迂回系数为 3。这用作一种方式强迫优化算法选择一个与所提供的坐标相当接近但可能不在网络中的网络节点。假设您使用具有海事网络数据的实际海港,这种影响应该是微乎其微的。然而,如果您不小心选择了位于内陆地区中部的港口,则旅程的第一段/最后一段将增加 3 倍的大圆距离。
作为旁注,您可能希望简化最终路由以减少数据开销。减少数据开销的一个好选择是mapshaper(web,cli)。
Here is a Python approach using scgraph. In theory, you can use scgraph to solve shortest path for various network graphs using some modified Dijkstra algorithms designed to be very efficient for sparse graphs.
The package comes with some basic network graphs to get you started. There are a couple of maritime network graphs to use.
Here is an example from the docs using a slightly modified (adjusted for anti meridian support) Marnet data:
Depending on your graphing needs you would need to format the coordinate path accordingly for the gis system you are using.
This would produce a route like:
Note: The length produced by scgraph assumes that all non network based geograph travel has a circuity factor of 3. This is used as a way to force the optimization algorithm to choose a reasonably close network node to the provided coordinates that might not be in the network. Assuming you use an actual seaport with maritime network data, this effect should be marginal. If however you accidentally choose a port located in the middle of a landlocked area, that first leg / last leg of the journey will add 3x the great circle distance traveled.
As a side note, you might want to simplify the end route to reduce data overhead. A good option for reducing data overhead is mapshaper (web, cli).