5

I have transverse shapefile lines (blue line) with a fixed length and I would like to extend them (orange line) using another reference layer (green polygon) that has a variable shape.

The 'extend' command built into QGIS 3.22 does this function, however it stretches the line with uniform sizes, however in my case each cross line will have a different size according to the reference layer (green polygon).

enter image description here

In QGIS 3.22 (or other versions) is there something that solves this problem?

Update: i add my files problem

https://github.com/wesleysc352/wesleysc352.github.io/blob/master/files.zip

2
  • the blue line layer is a real line layer or points styled as lines? Commented Dec 17, 2022 at 23:38
  • Hi Bernd Logge, blue line is real shapefile Commented Dec 17, 2022 at 23:39

2 Answers 2

5

You could use the said extend lines function, use a huge number for extending the lines to ensure they are all completely within the polygon and then clip the too long lines to the polygon. That's just two processing steps.

In case you end up with lines having two or more parts in the polygon you can run multiparts to singleparts on the lines and delete the parts that disjoin the small red line from your screenshot, e.g. by using extract by location, extracting the parts that intersect with the red line.

5
  • Hello MrXsquared, I did this using the reference layer (green polygon) to cut the extended lines. However, as my reference layer is very sinuous, some lines ended up crossing the reference layer twice, which I didn't like. Commented Dec 18, 2022 at 0:06
  • 2
    @wesleysc352 Could be done with two additional steps, see update.
    – MrXsquared
    Commented Dec 18, 2022 at 0:45
  • Your idea is very interesting, now I understand, however these steps would require me to delete them manually, something very laborious, but it is an alternative for simple situations Commented Dec 18, 2022 at 1:04
  • additionally would it be possible to filter the singleparts based on the position of the original transverse lines? Commented Dec 18, 2022 at 1:08
  • 4
    No, you dont need to do it manually. Just use extract by location and get those line parts intersecting with the red line.
    – MrXsquared
    Commented Dec 18, 2022 at 1:11
5

Some small python script you can use:

  1. Access the layers
  2. Set a threshold (your source layers need to be in the same unit). The value needs to be big enough.
  3. Extend lines using native:extendlines
  4. Clip the overlapping using native:clip
  5. Add the layer to the map
  6. Filter all multipart segments which may intersect a second time with the polygon
from qgis import processing

# Load layers
blue_lines = QgsProject.instance().mapLayersByName("blue_lines")[0]
green_polygon = QgsProject.instance().mapLayersByName("green_polygon")[0]

# Set distance value
distance = 5000

# Extend Lines 
temp_layer1 = processing.run("native:extendlines", {
    'INPUT' : blue_lines, 
    'OUTPUT' : 'TEMPORARY_OUTPUT', 
    'START_DISTANCE' : distance,
    'END_DISTANCE' : distance
})['OUTPUT']

# Clip
resultLayer = processing.run("native:clip", {
    'INPUT' : temp_layer1, 
    'OUTPUT' : 'TEMPORARY_OUTPUT', 
    'OVERLAY' : green_polygon
})['OUTPUT']

# Iterate over all features and remove multiparts
resultLayer.startEditing()
for feature in resultLayer.getFeatures():
    
    # Create a multi_polyline from the geometry of each feature
    multi_polyline = feature.geometry().asMultiPolyline()
    
    # Iterate over each multi polyline segment so we can find the correct ones
    for polyline in multi_polyline:
        
        # Create a temorary geometry
        geom = QgsGeometry.fromPolyline([QgsPoint(x) for x in polyline])
        
        # Iterate over all blue line features 
        for blue_lines_feature in blue_lines.getFeatures():
            
            # Create a small buffer around the segment 
            # and see if any of the blue line geometries is totaly within
            if blue_lines_feature.geometry().within(geom.buffer(1,5)):
                
                # If it is within update the geometry
                resultLayer.dataProvider().changeGeometryValues({feature.id(): geom}) 
                
                
resultLayer.commitChanges()

QgsProject.instance().addMapLayer(resultLayer)

Update: If your polygon has sharp turns it's better to identify the correct multipart element by creating a small buffer around the extended lines so we can check which blue lines are 100% within those buffers. Those segments are kept within the result layer.

enter image description here

9
  • 1
    Nice all-in-one solution, though you will need to add the intersect operation that @MrXsquared mentions in the last line of their answer, else there will be 'floating' clipped lines in the situation described in wesleysc352's first comment on that answer. As an aside, your numpy import is not needed in this case :)
    – Matt
    Commented Dec 18, 2022 at 12:32
  • Updated my answer. The problem with the solution of @MrXsquared would be that it could be that the middle line would also intersect the extended lines. So extract by location wouldn't work all the time. Therefore iterating over the MultiPolyline and only keeping the first element is the most sufficient way. Commented Dec 18, 2022 at 13:55
  • @Matt Nice, though. :D Commented Dec 18, 2022 at 13:58
  • Updated once more as the reversing didn't work that well. using a small buffer and checking which initial blue lines are 100% within the buffer is a better solution Commented Dec 18, 2022 at 14:21
  • Hi Bernad, how can i apply this code in my situation i have no experience with coding in qgis. is there any console inside the gis? Commented Dec 19, 2022 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.