लाइनों पर आगे बढ़ना (~ पड़ोस)


14

मेरे पास दो वेक्टर लेयर हैं, जिनमें से एक रिमोट सेंसिंग द्वारा "इवेंट्स" पर आधारित एक पॉइंट लेयर है और दूसरा लोकल रिसर्च से एक लाइन लेयर है।

मेरे मामले में ये भूकंप और विवर्तनिक दोष हैं, लेकिन मुझे लगता है कि एक व्यक्ति "कार-दुर्घटना और सड़कों" को एक सामान्य उदाहरण के रूप में चुन सकता है।

तो मैं जो करना चाहता हूं, वह लाइनों के निकटतम बिंदु पर बिंदुओं को कॉपी / कॉपी करना है, जब तक कि एक सहिष्णुता दूरी (1-2 किमी या 0.0xx ° कहो) के भीतर, नई बिंदु परत के साथ (+ attr स्थानांतरित) Y n)।

कोई विचार ?

लिनक्स, QGIS 1.8



क्या आप ऐसा करने के लिए पूरी तरह से स्वचालित फ़ंक्शन की तलाश कर रहे हैं, या किसी प्रकार के स्निपिंग टूल को हाथ से करना ठीक होगा?
Simbamangu

मैंने एक समान प्रश्न पूछा, मैं बिंदुओं के लिए लाइन स्नैप करने की कोशिश कर रहा था लेकिन कभी भी एक आसान समाधान नहीं मिला। gis.stackexchange.com/questions/52232/…
ग्रेहाउ

त्रिकोणासन और दूरी मिलान के बारे में क्या?
हुक्फिन

मुझे यह सवाल एक विधि के बारे में मिला जो आर्कगिस में नियर का उपयोग करता है। QGIS के समीप खोज के लिए गए और इस मंच पोस्ट को देखा जहां किसी ने GRASS v.distance का सुझाव दिया था। मुझे इस ट्यूटोरियल की ओर ले जाता है जो एक विधि की पहचान कर सकता है। शायद कहीं पर किसी ने अब तक एक प्लगइन लिखा है?
क्रिस

जवाबों:


13

एक कोड स्निपेट (अजगर के कंसोल में परीक्षण किया गया) को पोस्ट करें जो नीचे दिया गया है

  1. एक बिंदु के लिए निकटतम लाइन सुविधा खोजने के लिए QgsSpatialIndex का उपयोग करें
  2. इस रेखा पर निकटतम बिंदु का पता लगाएं। मैंने इसके लिए शॉर्टकट के रूप में सुडौल पैकेज का उपयोग किया। मैंने इसके लिए QGis विधियों को अपर्याप्त माना (या शायद मैं उन्हें ठीक से नहीं समझता)
  3. स्नैप स्थानों पर रबरबैंड जोड़े
from shapely.wkt import *
from shapely.geometry import *
from qgis.gui import *
from PyQt4.QtCore import Qt
lineLayer = iface.mapCanvas().layer(0)
pointLayer =  iface.mapCanvas().layer(1)
canvas =  iface.mapCanvas()
spIndex = QgsSpatialIndex() #create spatial index object
lineIter =  lineLayer.getFeatures()
for lineFeature in lineIter:
    spIndex.insertFeature(lineFeature)        
pointIter =  pointLayer.getFeatures()
for feature in pointIter:
    ptGeom = feature.geometry()
    pt = feature.geometry().asPoint()
    nearestIds = spIndex.nearestNeighbor(pt,1) # we need only one neighbour
    featureId = nearestIds[0]
    nearestIterator = lineLayer.getFeatures(QgsFeatureRequest().setFilterFid(featureId))
    nearFeature = QgsFeature()
    nearestIterator.nextFeature(nearFeature)
    shplyLineString = shapely.wkt.loads(nearFeature.geometry().exportToWkt())
    shplyPoint = shapely.wkt.loads(ptGeom.exportToWkt())
    #nearest distance from point to line
    dist = shplyLineString.distance(shplyPoint)
    print dist
    #the point on the road where the point should snap
    shplySnapPoint = shplyLineString.interpolate(shplyLineString.project(shplyPoint))
    #add rubber bands to the new points
    snapGeometry = QgsGeometry.fromWkt(shapely.wkt.dumps(shplySnapPoint))
    r = QgsRubberBand(canvas,QGis.Point)
    r.setColor(Qt.red)
    r.setToGeometry(snapGeometry,pointLayer)

संपादित करें: बस अब पाया गया कि @Sadxx विधि का उपयोग करते हुए निकटतम वर्डवैक्यू कोड का उपयोग कोड की कम लाइनों में समान परिणाम देता है। मुझे आश्चर्य है कि वे इस अजीब विधि नाम के साथ क्यों आए? समीपवर्तीऑनगोमेट्री जैसा कुछ होना चाहिए था।

तो हम सुडौल से बच सकते हैं और पसंद करते हैं,

nearFeature = QgsFeature()
nearestIterator.nextFeature(nearFeature)   

closeSegResult = nearFeature.geometry().closestSegmentWithContext(ptGeom.asPoint())
closePoint = closeSegResult[1]
snapGeometry = QgsGeometry.fromPoint(QgsPoint(closePoint[0],closePoint[1])) 

p1 = ptGeom.asPoint()
p2 = snapGeometry.asPoint()

dist = math.hypot(p2.x() - p1.x(), p2.y() - p1.y())
print dist

1
इस अजगर कोड को प्रारूपित करने की कोशिश कर दुःस्वप्न में दौड़ रहा है .. !!
विनयन

5

यहाँ एक छद्म कोड है जिसे शुरू करना है। मुझे उम्मीद है कि यह मदद करता है और किसी के पास पूर्ण कोड प्रदान करने का समय होगा (फिलहाल मेरे पास नहीं है)

पहली बात यह है कि बिंदु पर लूप करें और उन रेखाओं का चयन करें जो प्रत्येक बिंदु पर थ्रेसहोल्ड दूरी के भीतर स्थित हैं। 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.