Відстань між центроїдом та найдальшою точкою багатокутника


12

Я маю сільський багатокутник, який налічує понад 6,00 000 записів. Я підрахував центроїд кожного села. Я хочу знайти відстань між центроїдом та найдальшім вузлом кожного багатокутника. Перегляньте зображення нижче для довідок. Чорні лінії - це межі багатокутника. введіть тут опис зображення

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

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


цікаво ... Я щойно робив цю п’ятницю разом із постгітами, щоб створити коло навколо багатокутника. Мені потрібно кілька хвилин, щоб шукати код, який я використав .. i.stack.imgur.com/EKnkg.png
kttii

1
Спочатку нам може знадобитися знати, які програми у вас є. Крім того, як ви створили центроїди та вузли тозів? (Навіть якщо вам здається трохи очевидним, що вузли на багатокутниках - це ті, які використовуються для встановлення меж ваших фігур, але чи додали ви додаткову точку вгорі тіл?)
Моро Колін

Чи важливо розташування центроїда? Як ви їх створили?
GISGe

Можливий дублікат - gis.stackexchange.com/questions/133099/…
klewis

Якщо центроїд справді є центральним, то це радіус найменшого кола, зосередженого на тій точці, що відповідає полігону ( en.wikipedia.org/wiki/Smallest-circle_problem )
Марк Ірландія

Відповіді:



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 Я не знаю, як користуватися PostGIS. Чи можете ви надати більш просте рішення, по дузі чи картіінфо або qgis
Divya

@kttii Отже, я встановив Postgresql. Я скопіював цей точний запит, але він дав помилку: стовпець "the_geom" не існує. Що мені робити?
Дівія

the_geom слід замінити назвою поля геометрії. Вам також доведеться вводити свої дані в PostgreSQL. PostgreSQL - це база даних, як MSSQL. PostGIS - це розширення, щоб зробити базу даних просторово обізнаною та забезпечити всі функції ST_.
kttii

@kttii Я оновив ім'я поля з the_geom на "gid" у своїй базі даних. Після повторного запуску запиту я отримав цю ПОМИЛУ: функції st_convexhull (ціле число) не існує
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 також було надруковано індекс функції, індекс точки в характеристиці, де відстань від центроїда - максимальне і, нарешті, максимальна відстань.

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


Я не знаю, як користуватися PyQGIS. Чи можете ви надати більш просте рішення, по дузі чи картіінфо або qgis
Divya

1
Спробуйте це посилання для допомоги з початку роботи з PyQgis spatialgalaxy.net/2014/10/09 / ...
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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.