6,00.000'den fazla kaydı olan bir köy çokgen katmanım var. Her köyün sentroidini hesapladım. Her çokgenin centroid ve en uzak düğümü arasındaki mesafeyi bulmak istiyorum. Referans için aşağıdaki resme bakın. Siyah çizgiler çokgen sınırlardır.
6,00.000'den fazla kaydı olan bir köy çokgen katmanım var. Her köyün sentroidini hesapladım. Her çokgenin centroid ve en uzak düğümü arasındaki mesafeyi bulmak istiyorum. Referans için aşağıdaki resme bakın. Siyah çizgiler çokgen sınırlardır.
Yanıtlar:
MapInfo ile çalıştığınız anlaşılıyor. "Mesafe Hesaplama" (araç yöneticisi bulmak) birçok seçenek vardır ve ben de bu görevi de halledebilir düşünüyorum. Burada bir makale var: http://web.pb.com/mapinfopro-jul-2013/Toolbox-Distance-Calculator
PostGIS kullanarak, daha hızlı bir sonuç için çokgeni basitleştirmek için ST_ConvexHull kullandım:
En uzak noktayı alın:
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;
Ve eğer sentroidden bir Çember oluşturmak istiyorsanız:
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;
Sonraki PyQGIS kodunu kullanarak :
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)
ve bu şekil dosyası (11 özellikli):
Polinillerin her bir çokgenin (özellik) centroid ve en uzak noktası arasındaki mesafe olduğu bir bellek katmanım var; bir sonraki resimde görülebileceği için:
QGIS Python Konsolu'nda, özellik indeksi, sentroidden uzaklığın maksimum ve son olarak maksimum mesafe olduğu özellikteki nokta indeksi de yazdırıldı.
MapInfo kullandığınız gibi, işte çalıştığım bir şirket içi araç için bir süre önce yazdığım bir MapBasic işlevi. Bir kaynak düğümü (sentroid noktanız) ve bir bölge nesnesini (çokgen) bağımsız değişken olarak alır ve çokgendeki en uzak düğümde kaynak noktasından bir nokta nesnesi döndürür.
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