Salah satu metode yang paling efisien untuk menemukan ketebalan dinding minimal (nilai dan lokasi) dari area poligon kompleks, non-cembung termasuk lubang, bisa dengan menggunakan lapisan yang diberi spasi secara teratur (atau acak) dari titik-titik untuk menentukan, pertama, segmen terdekat dengan konteks untuk setiap titik dan, selanjutnya, titik untuk persimpangan antara segmen tambahan dan poligon sisi yang berlawanan; berbasis di cosinus direktur.
Jarak inkremental dapat digunakan sampai segmen pertama mencapai dan memotong beberapa poligon samping (ketebalan dinding minimal).
Untuk mencoba pendekatan saya, saya mengkloning poligon Anda dengan lubang dan membuat layer poin acak di dalam poligon dengan 100 poin; karena dapat diamati pada gambar berikut:
Kode yang digunakan PyQGIS terlihat sebagai berikut:
import math
def azimuth(point1, point2):
return point1.azimuth(point2) #in degrees
def cosdir_azim(azim):
azim = math.radians(azim)
cosa = math.sin(azim)
cosb = math.cos(azim)
return cosa,cosb
registry = QgsMapLayerRegistry.instance()
polygon = registry.mapLayersByName('polygon_with_holes')
point_layer = registry.mapLayersByName('Random_points')
points = [ feat.geometry().asPoint() for feat in point_layer[0].getFeatures() ]
feat_polygon = polygon[0].getFeatures().next()
#producing rings polygons
rings_polygon = feat_polygon.geometry().asPolygon()
segments = []
epsg = point_layer[0].crs().authid()
uri = "LineString?crs=" + epsg + "&field=id:integer""&index=yes"
mem_layer = QgsVectorLayer(uri,
'increasing_segments',
'memory')
prov = mem_layer.dataProvider()
length = 10
pt2 = 0
k = 0
while pt2 == 0:
for i, point in enumerate(points):
#determining closest distance to vertex or side polygon
dist1 = feat_polygon.geometry().closestSegmentWithContext(point)[0]
#determining point with closest distance to vertex or side polygon
pt = feat_polygon.geometry().closestSegmentWithContext(point)[1]
cosa, cosb = cosdir_azim(azimuth(pt, point))
#extending segment in opposite direction based in director cosine and length
op_pt = QgsPoint(point.x() + (length*cosa), point.y() + (length*cosb))
segments.append([pt,op_pt])
geom = QgsGeometry.fromPolyline([point,op_pt])
for ring in rings_polygon:
geom_ring = QgsGeometry.fromPolyline(ring)
if geom.intersects(geom_ring):
pt3 = geom.intersection(geom_ring)
pt2 = pt3.distance(QgsGeometry.fromPoint(point))
ms = [pt3.asPoint(), pt]
length += 100
k += 1
new_segments = segments[len(segments) -1 - len(segments)/k: len(segments) - 1]
feats = [ QgsFeature() for i in range(len(new_segments)) ]
for i,feat in enumerate(feats):
feat.setAttributes([i])
geom = QgsGeometry.fromPolyline(new_segments[i])
feat.setGeometry(geom)
prov.addFeatures(feats)
QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
minimum_segment = QgsGeometry().fromPolyline(ms).exportToWkt()
print minimum_segment, k
dan itu menghasilkan lapisan memori jarak inkremental (hanya untuk tujuan visualisasi) dan mencetak ketebalan dinding minimal dalam format WKT.
Setelah menjalankan kode di Python Console dari QGIS saya mendapat hasil gambar berikut:
Dapat diamati bahwa hanya satu jarak tambahan mencapai sisi yang berlawanan pertama di daerah yang diharapkan.
Format WKT tercetak (untuk ketebalan dinding minimal) digunakan dengan plugin QuickWKT dari QGIS untuk memvisualisasikan segmen tersebut pada gambar berikut:
Kecenderungan sedikit dihasilkan karena "segmen terdekat dengan konteks" digabungkan ke sebuah titik; alih-alih poligon samping. Namun, itu bisa dihindari dengan pengecualian kode atau lebih banyak poin.