找到坐标/多边形的最佳标签位置组

时间:2014-10-02 13:54:13

标签: .net vb.net algorithm math polygon

我有一个坐姿,我想在地图上放置一个指针。 问题是如何在vb.Net中计算该指针的位置。

我可以有3个坐席:

  1. 单点
  2. 一个方式点,2个或更多点
  3. 多边形,多个点
  4. 所有点都是纬度和经度。现在我想为这些情况设置一个标记。

    1. 很简单,标记位置是点
    2. 标记应位于行的中间
    3. 多边形是最难的。我可以找到它的质心(重心),但它可以在多边形之外。所以这对标记没用。
    4. 我不知道如何计算这些点(exept for nr.1; - ))

2 个答案:

答案 0 :(得分:0)

假设多边形不会自相交,您可以:

  1. 以某种方式对多边形进行三角测量。 This can be done in O(n log n) time.
  2. 选择其中一个三角形作为"代表"。我的建议:面积最大的三角形,或最小角度最大的三角形,或质心最接近点的质心的三角形。
  3. 使用此三角形的质心,该三角形必须位于三角形内部,因此必须位于多边形内部。

答案 1 :(得分:0)

我找到了一个可以完成所有魔法的图书馆:NetTopologySuite 您可以将其安装为Nuget包,文档为here 获得包装后很简单。

多边形内的中心:

首先通过将所有纬度和经度添加到坐标数组来创建多边形。

'The first point needs to be the last point so it becomes a closed shape
'Becouse I loop through all my coordinates I set a flag for the first point
'so I can add it at the end
Dim firstPoint As GeoAPI.Geometries.Coordinate = Nothing

'create an coordinatearray
Dim coordinates() As GeoAPI.Geometries.Coordinate = {}

 'Loop trough all the coordinates you have (you can do a dataset loop etc)
 'For the example the coordinates are in a pointF array
 For Each Point As PointF In points

     'Save the first point so we can add it in the end
     If firstPoint Is Nothing Then
          firstPoint = New GeoAPI.Geometries.Coordinate(Point.X, Point.Y)
     End If

     'Create a coordinate so we can add it to the coordinate array
     Dim coordinate As New GeoAPI.Geometries.Coordinate(Point.X, Point.Y)

     'Adding it to the array
     Array.Resize(coordinates, coordinates.Length + 1)
     coordinates(coordinates.Length - 1) = coordinate
 Next

 'Now all the coordinates are in the array we need to add the first one at the end
 Array.Resize(coordinates, coordinates.Length + 1)
 coordinates(coordinates.Length - 1) = firstPoint


 'Now we create a linearRing with these coordinates
 Dim ring As New NetTopologySuite.Geometries.LinearRing(coordinates)

 'And use the ring to get a center point inside it
 Dim insidePoint As IPoint = ring.InteriorPoint

 'If you want a centroid you can do the following
 Dim polygon As New NetTopologySuite.Geometries.Polygon(ring)
 Dim centroidPoint As IPoint = polygon.centroid