穴を含む複雑な非凸多角形領域の最小壁厚(値と位置)を見つける最も効率的な方法の1つは、最初に最も近いセグメントを決定するために、点の等間隔のレイヤー(またはランダム)を使用することです。各ポイントのコンテキスト、次にインクリメンタルセグメントと反対側のポリゴンの間の交点。監督コサインに基づいています。
増分距離は、最初のセグメントが一部の側面ポリゴンに到達して交差するまで使用できます(最小の壁の厚さ)。
私のアプローチを試すために、穴のあるポリゴンを複製し、100ポイントのポリゴン内にランダムポイントレイヤーを作成しました。次の画像で確認できるように:
PyQGISで使用されるコードは次のようになります。
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
また、増分距離のメモリレイヤーを作成し(視覚化の目的のみ)、WKT形式で最小の壁厚を印刷します。
QGISのPythonコンソールでコードを実行した後、次の画像の結果が得られました。
予想される領域では、最初に反対側に到達した距離が1つだけ増加したことがわかります。
印刷されたWKT形式(最小の壁厚のため)は、QGISのQuickWKTプラグインで使用され、次の画像でそのセグメントを視覚化します。
「コンテキストに最も近いセグメント」が頂点に結合されたため、わずかな傾きが生じました。代わりにサイドポリゴン。ただし、コード例外またはより多くのポイントで回避できます。