Расстояние между центроидом и самой дальней точкой многоугольника

12

У меня есть слой многоугольника села, в котором более 60000 записей. Я рассчитал центр тяжести каждой деревни. Я хочу найти расстояние между центроидом и самым дальним узлом каждого многоугольника. Проверьте изображение ниже для справки. Черные линии - это границы многоугольника. введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Дивья
источник
интересно ... Я только что сделал эту пятницу с Postgis, чтобы создать круг вокруг многоугольника. Мне нужно несколько минут, чтобы найти код, который я использовал .. i.stack.imgur.com/EKnkg.png
kttii
1
Сначала нам может понадобиться узнать, какие программы у вас есть в вашем распоряжении. Кроме того, как вы создали эти центроиды и узлы? (Даже если кажется немного очевидным, что узлы на многоугольниках - это те, которые используются для установки границ ваших фигур, но вы добавили дополнительную точку над этими цифрами?)
Моро Колин
Важно ли расположение центроида? Как вы их создали?
GISGe
Возможный дубликат - gis.stackexchange.com/questions/133099/…
klewis
Если центроид действительно является центральным, то это радиус наименьшего круга с центром в этой точке, который соответствует многоугольнику ( en.wikipedia.org/wiki/Smallest-circle_problem )
Марк Ирландия,

Ответы:

3

Похоже, вы работаете с MapInfo. «Калькулятор расстояний» (найдите его в диспетчере инструментов) имеет много опций, и я думаю, что он тоже справится с этой задачей. Есть статья об этом здесь: http://web.pb.com/mapinfopro-jul-2013/Toolbox-Distance-Calculator

Уффе Кусгаард
источник
15

Используя PostGIS, я использовал ST_ConvexHull, чтобы упростить полигон для более быстрого результата:

Получите самый дальний пункт:

SELECT Villages_v4_Trial_region.geom as FarPoint from (
SELECT ST_PointN(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom)),
generate_series(1, ST_NPoints(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom))))) as points, 
geom
FROM Villages_v4_Trial_region
ORDER BY ST_MaxDistance(points,ST_Centroid(Villages_v4_Trial_region.geom)) DESC
LIMIT 1;

И если вы заинтересованы в создании круга из центроида:

SELECT ST_Buffer(Center,ST_Distance(Center,FarPoint)) as Circle
FROM (
SELECT Villages_v4_Trial_region.geom as FarPoint, Center from (
    SELECT ST_PointN(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom)),
    generate_series(1, ST_NPoints(ST_ExteriorRing(ST_ConvexHull(Villages_v4_Trial_region.geom))))) as points,
    ST_Centroid(Villages_v4_Trial_region.geom) as Center, 
    geom
    FROM Villages_v4_Trial_region
    ) as Villages_v4_Trial_region
    ORDER BY ST_MaxDistance(points,Center) DESC
    LIMIT 1) as foo;

введите описание изображения здесь

kttii
источник
Просто, быстро, эффективно. Спасибо, что опубликовали это, потому что это тоже поможет мне в том, над чем я сейчас работаю.
Моро Колин
@kttii Я не знаю, как использовать PostGIS. Можете ли вы предоставить более простое решение, в arc или mapinfo или qgis
Divya
@kttii Итак, я установил Postgresql. Я скопировал этот точный запрос, но он дал ОШИБКУ: столбец "the_geom" не существует. Что мне делать?
Divya
the_geom должен быть заменен вашим именем поля геометрии. Вам также необходимо поместить свои данные в PostgreSQL. PostgreSQL - это база данных, подобная MSSQL. PostGIS - это расширение для пространственной осведомленности базы данных и обеспечения всех функций ST_.
kttii
@kttii Я обновил имя поля с the_geom до «gid» в моей базе данных. После повторного выполнения запроса я получил эту ОШИБКУ: функция st_convexhull (integer) не существует
Divya
4

Используя следующий код PyQGIS :

from math import sqrt

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

n = len(feats)

centroids = [ feat.geometry().centroid().asPoint() for feat in feats ]
polygons = [ feat.geometry().asPolygon()[0] for feat in feats ]

lengths = []

for i, pol in enumerate(polygons):
    max_dist = 0
    idx_j = 0
    for j, point in enumerate(pol):
        dist = sqrt(centroids[i].sqrDist(point))
        if dist > max_dist:
            max_dist = dist
            idx_j = j
    print i, idx_j, max_dist
    lengths.append([centroids[i], pol[idx_j]])

crs = layer.crs()
epsg = crs.postgisSrid()

uri = "LineString?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'max_distance',
                           'memory')

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(n) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromPolyline(lengths[i]))

prov.addFeatures(feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

и этот шейп-файл (с 11 функциями):

введите описание изображения здесь

Я получил слой памяти, где полилинии были расстоянием между центроидом и самой дальней точкой каждого многоугольника (особенность); как это можно увидеть на следующем изображении:

введите описание изображения здесь

На консоли Python QGIS также был напечатан индекс объекта, индекс точки объекта, где расстояние от центроида является максимальным и, наконец, максимальное расстояние.

введите описание изображения здесь

xunilk
источник
Я не знаю, как использовать PyQGIS. Можете ли вы предоставить более простое решение, в arc или mapinfo или qgis
Divya
1
Попробуйте эту ссылку, чтобы получить помощь по началу работы
kttii
0

Похоже, что вы используете MapInfo, вот функция MapBasic, которую я написал некоторое время назад для внутреннего инструмента, над которым я работал. Он принимает исходный узел (вашу точку центроида) и объект области (многоугольник) в качестве аргументов и возвращает точечный объект в самом дальнем узле многоугольника из исходной точки.

Function GetFurthest(ByVal oNode1 as Object, ByVal oObj as Object) as Object

Dim sourceE,sourceN,East,North,Longest,Dist as Float,
    nNodes,nPolys,i,j as SmallInt,
    oNode2 as Object

    sourceE = CentroidX(oNode1)
    sourceN = CentroidY(oNode1)
    Longest = 0

    nPolys = ObjectInfo(oObj,OBJ_INFO_NPOLYGONS)
    For i = 1 to nPolys
        nNodes = ObjectInfo(oObj,OBJ_INFO_NPOLYGONS+nPolys)
        For j = 1 to nNodes
            East = ObjectNodeX(oObj,i,j)
            North = ObjectNodeY(oObj,i,j)
            Dist = Distance(sourceE,sourceN,East,North,"m")
            If Dist > Longest then
                Longest = Dist
                oNode2 = CreatePoint(East,North)
            End if
        Next
    Next

    GetFurthest = oNode2

End Function
T_Bacon
источник