2

In QGIS, I can add a new line by using the Add line Feature tool. I can also use the Advanced Digiting tool which is helpful.

I want to add two line and a point in the middle of the two lines like the picture below. I can add them one by one.

Is there a way in QGIS to add them the way we use 'Add line Feature' by choosing the two points of the line to make a straight line consisting of two lines and one point, and also be able to use the Advanced Digiting tool?

enter image description here

9
  • For questions about PyQGIS a code attempt should be included. Consequently, I've focused your question on whether this can be done using the QGIS GUI.
    – PolyGeo
    Dec 27, 2021 at 10:59
  • @PolyGeo The main goal is to use it in PyQGIS. But knowing if and how it's possible to do it by GUI helps.
    – RandyO
    Dec 27, 2021 at 11:03
  • 1
    Sorry, the question is quite confusing. I simply don't understand what you want to achieve in which order. Be clear - e.g. saying "same layers or different" does not help understanding your task. You want one straigth line consisting of two segments (3 vertices?). Or indeed two different geometries (line features), each with 2 vertices, where end-point of line 1 = start-point of line 2?
    – Babel
    Dec 27, 2021 at 11:23
  • 1
    I read your question and your comments several times. And I still don't understand what you want to do exactly. In GIS-realm, you cannot draw a point and a line at once. Normally, you add a line to a line layer, then add a point to a point layer, then add a line to the line layer. As @Babel mentioned, the question is so confusing. I can't match what QGIS can do with what you need. Dec 27, 2021 at 16:57
  • 1
    Could you describe in detail how you add them one by one in QGIS manually. How do you draw a line, how do you get start and end points of the line, how do you add (and where) the point? If we understand the manual way then we can offer a solution. Dec 27, 2021 at 17:00

1 Answer 1

1

The workflow

  1. Draw a line clicking for start and endpoint.

  2. Run Menu Vector / Geometry tools / Centroids to get the point in the middle of the line as a separate point layer.

  3. Split the line in the middle in two different line features: Menu Processing / Toolbox / Split lines by maximum length. For Maximum line length got to data driven override and use the expression length($geometry)/2.

    If you use $length/2, you get ellipsoidal length: this will not work for geographic CRS, so better use the first variant that calculates planar length.

Variant

In step 3, instead of splitting the line at half of its total length, you can define an expression that it should be split exactly where the point (centroid) is placed. Use this expression:

line_locate_point( 
    $geometry, 
    geometry (get_feature_by_id ('Centroids',1))
)

Workflow as PyQGIS skript

I created a model from the workflow above (steps 2 and 3) and saved it as Python skript. Save the following code as skript, draw a line (click two points) and run it from the toolbox:

"""
Model exported as python.
Name : split
Group : 
With QGIS : 32201
"""

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterFeatureSink
from qgis.core import QgsProperty
import processing


class Split(QgsProcessingAlgorithm):

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterVectorLayer('loadline', 'loadline', types=[QgsProcessing.TypeVectorLine], defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Centroid', 'centroid', type=QgsProcessing.TypeVectorPoint, createByDefault=True, supportsAppend=True, defaultValue=None))
        self.addParameter(QgsProcessingParameterFeatureSink('Splitted', 'splitted', type=QgsProcessing.TypeVectorLine, createByDefault=True, supportsAppend=True, defaultValue=None))

    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(2, model_feedback)
        results = {}
        outputs = {}

        # Centroids
        alg_params = {
            'ALL_PARTS': False,
            'INPUT': parameters['loadline'],
            'OUTPUT': parameters['Centroid']
        }
        outputs['Centroids'] = processing.run('native:centroids', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Centroid'] = outputs['Centroids']['OUTPUT']

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # splitline
        alg_params = {
            'INPUT': parameters['loadline'],
            'LENGTH': QgsProperty.fromExpression('length($geometry)/2'),
            'OUTPUT': parameters['Splitted']
        }
        outputs['Splitline'] = processing.run('native:splitlinesbylength', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
        results['Splitted'] = outputs['Splitline']['OUTPUT']
        return results

    def name(self):
        return 'split'

    def displayName(self):
        return 'split'

    def group(self):
        return ''

    def groupId(self):
        return ''

    def createInstance(self):
        return Split()

10
  • This process makes it very complicated. It's easier if the user draw them by one by one. I want it to be as simple as two clicks. Maybe use PyQGIS if possible. For example, get a line geometry by drawing and then extract the line and point geometry and add them to their layers. So one line drawing without associating it to any layers and just for using it to get our lines and point.
    – RandyO
    Dec 27, 2021 at 14:04
  • You can convert the workflow to PyQGIS with the necessary programming skills. But the workflow as such is what you want to do? Still not clear what you exactly mean by "draw them by one by one". To which layer you want to add them? You want to add the split up lines to the initial line layer (and delete the unsplit line)? The point must be on another layer, as line layers cannot contain point geometries.
    – Babel
    Dec 27, 2021 at 14:08
  • In PyQGIS, how can I let the user to just draw a line and then get its two points? (The line being drawn is just for getting the points and is not associated with any layers and will be temporarily)
    – RandyO
    Dec 27, 2021 at 14:16
  • You don't want the line? You want just start- and endpoints? Sorry, your question mentioned otherwise... I advice you to revise your question in a way it becomes clear what you want to do. See also the comment by @PolyGeo: "For questions about PyQGIS a code attempt should be included". As a start, you might state up to which point the solution here does what you want and where it does not. Otherwise, its difficult to help.
    – Babel
    Dec 27, 2021 at 14:24
  • 1
    That was exactly my initial idea. If you want to draw a line, it must be on a layer. Digitizing, not Digiting: docs.qgis.org/3.16/en/docs/documentation_guidelines/…
    – Babel
    Dec 27, 2021 at 15:13

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.