我为那些喜欢这类事情的人提供了解决问题的练习。我正在开发一个使用 Google 地图的地图应用程序。用户首先输入一系列坐标和“半径”。然后,用户请求绘制一条线或一个区域。这些图是使用多边形在谷歌地图上进行的。换句话说,给定由蓝点和距离定义的蓝线(或区域),计算红点并绘制红色多边形,其中边距用户提供的边给定距离:
我已经成功地通过计算正向和反向方位角,然后在适当的方向上找到与这些方位角成 90 度的点,使其在“大多数”情况下都能工作。对于弧线,我只是计算了沿该弧线以 5 度间隔的位置点。在锐角内部的情况下,我确定两条线相交的位置并使用该点,但有时当该点处的交叉轨道距离大于所提供的半径时,这会严重失败。
我希望有人知道更简单的方法?也许无论跨轨道与半径距离的比率如何,它都始终有效?或者也许已经存在一个库可以做到这一点?
我希望我所做的事情是有意义的......这很难用语言表达。也许如果我有这些词,搜索就会有帮助。
I have an exercise in problem solving for those who like that kind of thing. I'm working on a mapping application that uses Google Maps. A user first enters a series of coordinates and a "radius". The user then requests either a line or an area be plotted. The plots are taking place on Google Maps using polygons. In other words, given the blue line (or area) defined by the blue points and a distance, calculate the red points and draw the red polygon where the edges are of the given distance away from the user-provided edges:
I have managed to get this to work in "most" situations by calculate forward and reverse bearings, then finding the points with a bearing 90 degrees off these in the appropriate direction. For the arcs I just calculated the location points along that arc at 5 degree intervals. In the case of the inside of an acute angle, I determine where the two lines intersect and use that point, but this fails miserably sometimes when the cross-track distance at that point is greater than the radius that was provided.
I'm hoping someone knows of an easier way? Maybe one that works all the time regardless of the ratio of the cross-track to radius distances? Or maybe a library already exists to do this?
I hope what I'm trying to do makes sense... It's hard to put in words. Maybe if I had the words a search would have been helpful even.
发布评论
评论(2)
好吧,答案比我想象的要简单。这让我回想起大约 15 年前在 CompSci 101 期间学到的一课:
“尽可能使用现有的库。”
一旦我发现(通过谷歌搜索),我正在寻找的东西不被称为“偏移”或“比例”,而实际上在 GIS 计算中被称为“缓冲区”,这很简单。有一些很棒的库,例如 Clipper .com/users/359538/angus-johnson">Angus Johnson 可以做到这一点,但我想要一些特定于 JavaScript 的东西。
这让我来到 arcGIS 的几何服务。他们甚至有 Google 地图版本,但它只是 API v2 。幸运的是,我通过 arcGIS 论坛找到了一个不受支持的官方版本,该版本可与 GMaps API v3 配合使用。
所以,我的解决方案是使用名为 arcgislink,其缓冲功能与 Google 地图 LatLng 点、Google 地图多边形/折线以及任何标准 arcGIS 类型完美配合。如果其他人需要使用 Google 地图执行此操作,我强烈建议您查看他们的库。
Well, the answer turned out to be simpler than I thought. It took me back to a lesson I was taught during CompSci 101 almost 15 years ago:
"Use existing libraries whenever possible."
Once I found out (via googling), that what I'm looking for isn't called an "offset" or a "scale" but is actually called a "buffer" in GIS computing, it was simple. There are some great libraries like Clipper by Angus Johnson that can do it, but I wanted something JavaScript specific.
That brought me to arcGIS's GeometryService. They even have a Google Maps version but it's only API v2. Luckily, there's an official, unsupported version I found via the arcGIS forums that works with GMaps API v3.
So, my solution was to use that, called arcgislink, and it's buffer function works perfectly with Google Maps LatLng points, Google Maps Polygons/Polylines, and any of the standard arcGIS types. Anyone else needing to do this with Google Maps, I highly recommend looking at their libraries.
在一般设置中,这个问题非常困难,因为它是一个全局问题(您不能仅在每个多边形顶点进行本地求解,而只能处理两个传入边)。而且还因为涉及圆弧而感到不安。
有一个非常低效但安全的解决方案:假设您有一个通用的多边形联合算法(例如 http://gvu.gatech.edu/~jarek/graphics/papers/04PolygonBooleansMargalit.pdf);您将逐条添加每条边的膨胀版本(每次一个矩形和两个由多边形近似的半圆盘),以及闭合形状的原始多边形。
为了提高效率,您可以设计一种“扫描线”算法,该算法的工作原理是在每个“事件点”(即线段/圆弧端点和圆弧顶点)处用水平线对平面进行切片,从而使每个切片中的配置更加简单。你明白我的意思吗?
顺便说一句,你所说的“跨轨距离”是什么?
In the general setting, this problem is quite difficult because it is a global one (you cannot just solve locally, at each polygon vertex but just handling the two incoming edges). And also uneasy because it involves circular arcs.
There is a solution which is quite unefficient but safe: assume you have a general polygon union algorithm (like http://gvu.gatech.edu/~jarek/graphics/papers/04PolygonBooleansMargalit.pdf); you will add inflated versions of every edge one by one (every time a rectangle and two half-disks approximated by polygons), together with the original polygon for closed shapes.
For the sake of efficiency, you can design a "sweepline" algorithm that works by slicing the plane with horizontal lines at every "event point", i.e. segment/arc endpoints and arc apexes, so that the configuration in every slice is simpler. Do you see what I mean ?
BTW, what do you call the "cross-track distance" ?