Jarak antara titik tengah dan titik terjauh poligon

12

Saya memiliki lapisan poligon desa yang memiliki lebih dari 6.00.000 catatan. Saya telah menghitung centroid dari setiap desa. Saya ingin mencari jarak antara centroid dan simpul terjauh dari setiap poligon. Periksa gambar di bawah ini untuk referensi. Garis hitam adalah batas poligon. masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Divya
sumber
menarik ... Saya baru saja melakukan hari Jumat ini dengan postgis untuk menghasilkan lingkaran di sekitar poligon. Saya perlu beberapa menit untuk mencari kode yang saya gunakan .. i.stack.imgur.com/EKnkg.png
kttii
1
Pertama, kita mungkin perlu tahu program mana yang Anda miliki. Juga bagaimana Anda membuat centroid dan node mereka? (Bahkan jika tampak agak jelas bahwa simpul pada poligon adalah yang digunakan untuk mengatur batas bentuk Anda, tetapi apakah Anda menambahkan titik aditionnal di atas thoses?)
Moreau Colin
Apakah lokasi centroid itu penting? Bagaimana Anda membuatnya?
GISGe
Kemungkinan rangkap - gis.stackexchange.com/questions/133099/...
klewis
Jika centroid benar-benar pusat, maka itu adalah jari-jari lingkaran terkecil yang berpusat pada titik itu yang sesuai dengan poligon ( en.wikipedia.org/wiki/Smallest-circle_problem )
Mark Ireland

Jawaban:

15

Menggunakan PostGIS, saya menggunakan ST_ConvexHull untuk menyederhanakan poligon untuk hasil yang lebih cepat:

Dapatkan Poin Terjauh:

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;

Dan jika Anda tertarik untuk membuat Lingkaran dari pusat massa:

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;

masukkan deskripsi gambar di sini

kttii
sumber
Sederhana, cepat, efisien. Terima kasih telah memposting ini karena ini akan membantu saya juga dalam apa yang saya kerjakan sekarang.
Moreau Colin
@ kttii Saya tidak tahu cara menggunakan PostGIS. Bisakah Anda memberikan solusi yang lebih sederhana, dalam arc atau mapinfo atau qgis
Divya
@kttii Jadi saya menginstal Postgresql. Saya salin-tempel kueri persis ini tetapi memberikan ERROR: kolom "the_geom" tidak ada. Apa yang saya lakukan?
Divya
the_geom harus diganti dengan nama bidang geometri Anda. Anda harus memasukkan data Anda ke dalam PostgreSQL juga. PostgreSQL adalah database seperti MSSQL. PostGIS adalah ekstensi untuk membuat basis data sadar dan menyediakan semua fungsi ST_ secara spasial.
kttii
@ kttii Saya memperbarui nama bidang dari the_geom ke "gid" di database saya. Setelah menjalankan kueri lagi, saya mendapatkan ERROR ini: function st_convexhull (integer) tidak ada
Divya
4

Menggunakan kode PyQGIS berikutnya :

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)

dan shapefile ini (dengan 11 fitur):

masukkan deskripsi gambar di sini

Saya mendapatkan lapisan memori di mana polyline adalah jarak antara centroid dan titik terjauh dari setiap poligon (fitur); karena dapat diamati pada gambar berikutnya:

masukkan deskripsi gambar di sini

Di Python Console dari QGIS, itu juga dicetak indeks fitur, indeks titik dalam fitur di mana jarak dari centroid adalah maksimum dan, akhirnya, jarak maksimum.

masukkan deskripsi gambar di sini

xunilk
sumber
Saya tidak tahu cara menggunakan PyQGIS. Bisakah Anda memberikan solusi yang lebih sederhana, dalam arc atau mapinfo atau qgis
Divya
1
Coba tautan ini untuk bantuan memulai PyQgis spatialgalaxy.net/2014/10/09/…
kttii
0

Karena sepertinya Anda menggunakan MapInfo, berikut adalah fungsi MapBasic yang saya tulis beberapa waktu lalu untuk alat internal yang sedang saya kerjakan. Dibutuhkan node sumber (titik centroid Anda) dan objek wilayah (poligon) sebagai argumen dan mengembalikan objek titik pada simpul terjauh dalam poligon dari titik sumber.

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
sumber