PyQGIS – Script to Extract Start and End of Polyline Coordinates

geometrypyqgis

I am writing a plugin and I need to extract the x1,y1,x2,y2 coordinates for a chosen Polyline.
The GUI loads all the available layers, the user selects the layer and the GUI is populated with the features (lines) for that layer. The user then selects the desired feature.
What I want to do is get all 4, separate, line coordinates for that chosen feature.

def select_line(self):
    #Load lines from chosen layer and populate LineCB
    global selectedLayer
    selectedLayer = self.dlg.mMapLayerComboBox.currentLayer()
    self.dlg.LineCB.clear()
    L_names=[]
    ##get the names and add to the list
    for l in selectedLayer.getFeatures():
        L_names.append(l['Name'])
    self.dlg.LineCB.addItems(L_names) #Populate the ComboBox
    self.dlg.LineCB.currentIndexChanged.connect(self.get_coords) 

def get_coords(self): #extract x1,y1,x2,y2 from feature
    selectedLine=self.dlg.LineCB.currentIndex()
    request=QgsFeatureRequest().setFilterFid(selectedLine)
    
    feats=selectedLayer.getFeatures(request)
    for feat in feats:
        geom=feat.geometry()
        x=geom.asPolyline()
   
    print(x)
    SOL=[x[0]]
    EOL=[x[1]]
    print("SOL",SOL)
    print("EOL",EOL)

    #SOLE=[SOL.x()]
    #SOLN=[SOL.y()]
    #print(SOLE)
    #print(SOLN)

The print outputs are:

[<QgsPointXY: POINT(523137.37099999998463318 6766813.40000000037252903)>, <QgsPointXY: POINT(529084.65800000005401671 6770211.84999999962747097)>]
SOL [<QgsPointXY: POINT(523137.37099999998463318 6766813.40000000037252903)>]
EOL [<QgsPointXY: POINT(529084.65800000005401671 6770211.84999999962747097)>]

I can split the output into an x1,y1 and x2,y2 couples, but can't extract the 4 individual elements.
I also managed to extract it as a single LinestringXY, but this didn't help (and I now can't remember how I did it).

My experiments with geomtery.x() produced error messages because its not Point coordinates, and where I have got to now, I think I've lost the .x() functionality.

Do I need to extract the geometry as a 'string' like I'm doing now, or is there a way to access each coordinate part earlier in the process?

Best Answer

There are some things that are not clear to me, but if i understand this is the solution.

If you have a LineString in a QgsGeometry object then you can use the asPolyline() function to get a list of points, now it's just to take one of this points an apply the x() and y() functions. Try this:

def get_coords(self): #extract x1,y1,x2,y2 from feature
    selectedLine=self.dlg.LineCB.currentIndex()
    request=QgsFeatureRequest().setFilterFid(selectedLine)
    
    feats=selectedLayer.getFeatures(request)
    for feat in feats:
        geom=feat.geometry()
        line=geom.asPolyline()
   
    # print(line)
    SOL=line[0]
    EOL=line[-1]
    print("SOL",SOL.x(), SOL.y())
    print("EOL", EOL.x(), EOL.y())
Related Question