यहाँ एक छद्म कोड है जिसे शुरू करना है। मुझे उम्मीद है कि यह मदद करता है और किसी के पास पूर्ण कोड प्रदान करने का समय होगा (फिलहाल मेरे पास नहीं है)
पहली बात यह है कि बिंदु पर लूप करें और उन रेखाओं का चयन करें जो प्रत्येक बिंदु पर थ्रेसहोल्ड दूरी के भीतर स्थित हैं। Thi QgsSpatialIndex के साथ किया जा सकता है
पहले लूप के भीतर, दूसरी बात यह है कि चयनित लाइनों पर लूप करें और लाइन पर निकटतम बिंदु ढूंढें। यह सीधे QgsGeometry :: closeSegmentWithContext के आधार पर किया जा सकता है
डबल QgsGeometry :: निकटतमसुविधाWithContext (const QgsPoint और बिंदु, QgsPoint और minDistPoint, int और afterVertex, डबल * leftOf = 0, डबल एप्सिलॉन = DEULTULT_SEGMENT_EPSILON)
दिए गए बिंदु पर ज्यामिति के निकटतम खंड की खोज करता है।
पैरामीटर बिंदु खोज के लिए बिंदु निर्दिष्ट करता है
minDistPoint Receives the nearest point on the segment
afterVertex Receives index of the vertex after the closest segment. The vertex before the closest segment is always afterVertex -
1 बायाँ आउट: रिटर्न यदि बिंदु खंड के दाईं ओर बाईं ओर स्थित है (<0 का अर्थ है बाएँ,> 0 का अर्थ है सही) खंड के लिए एप्सिलॉन एप्सिलॉन (1.8 में जोड़ा गया)
तीसरा चरण (पहले लूप के भीतर) न्यूनतम दूरी के साथ minDistPoint की ज्यामिति के साथ बिंदु की ज्यामिति को अद्यतन करने में शामिल होगा
कुछ कोड के साथ अद्यतन (QGIS3 पर)
pointlayer = QgsProject.instance().mapLayersByName('point')[0] #iface.mapCanvas().layer(0)
lineLayer = QgsProject.instance().mapLayersByName('lines')[0] # iface.mapCanvas().layer(1)
epsg = pointlayer.crs().postgisSrid()
uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer&field=distance:double(20,2)&field=left:integer&index=yes"
snapped = QgsVectorLayer(uri,'snapped', 'memory')
prov = snapped.dataProvider()
testIndex = QgsSpatialIndex(lineLayer)
i=0
feats=[]
for p in pointlayer.getFeatures():
i+=1
mindist = 10000.
near_ids = testIndex.nearestNeighbor(p.geometry().asPoint(),4) #nearest neighbor works with bounding boxes, so I need to take more than one closest results and further check all of them.
features = lineLayer.getFeatures(QgsFeatureRequest().setFilterFids(near_ids))
for tline in features:
closeSegResult = tline.geometry().closestSegmentWithContext(p.geometry().asPoint())
if mindist > closeSegResult[0]:
closePoint = closeSegResult[1]
mindist = closeSegResult[0]
side = closeSegResult[3]
feat = QgsFeature()
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(closePoint[0],closePoint[1])))
feat.setAttributes([i,mindist,side])
feats.append(feat)
prov.addFeatures(feats)
QgsProject.instance().addMapLayer(snapped)