Eine der effizientesten Methoden, um die minimale Wandstärke (Wert und Position) eines komplexen, nicht konvexen Polygonbereichs einschließlich Löchern zu ermitteln, könnte die Verwendung einer regelmäßig beabstandeten Schicht (oder zufälligen) von Punkten zur Bestimmung des ersten nächstgelegenen Segments sein mit Kontext für jeden Punkt und als nächstes den Schnittpunkt zwischen dem inkrementellen Segment und dem Polygon der gegenüberliegenden Seite; basiert auf Direktoren Cosinus.
Inkrementelle Abstände können verwendet werden, bis das erste Segment ein Seitenpolygon (die minimale Wandstärke) erreicht und schneidet.
Um meinen Ansatz auszuprobieren, habe ich Ihr Polygon mit Löchern geklont und eine zufällige Punktebene innerhalb des Polygons mit 100 Punkten erstellt. wie es auf folgendem Bild zu sehen ist:
Der von PyQGIS verwendete Code sieht wie folgt aus:
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
und es erzeugt eine Speicherschicht mit inkrementellen Abständen (nur zu Visualisierungszwecken) und druckt eine minimale Wandstärke im WKT-Format.
Nachdem ich den Code in der Python Console von QGIS ausgeführt habe, habe ich das folgende Bild erhalten:
Es kann beobachtet werden, dass nur ein inkrementeller Abstand zuerst die gegenüberliegende Seite im erwarteten Bereich erreichte.
Das gedruckte WKT-Format (für minimale Wandstärke) wird mit dem QuickWKT-Plugin von QGIS verwendet, um dieses Segment in der folgenden Abbildung zu visualisieren:
Die leichte Neigung wurde erzeugt, weil "engstes Segment mit Kontext" mit einem Scheitelpunkt verbunden war; stattdessen Seitenpolygon. Dies kann jedoch mit einer Code-Ausnahme oder mehr Punkten vermieden werden.