2

I am using Polygons Centroids feature in QGIS and it does an amazing job. My goal though is to set the points on the left side of the polygon and not in the center. Is there a way to control the alignment of this feature? The polygons look like those in the images. The polygons come in different angles.

In the following, I would line the points to be on the left:

enter image description here

enter image description here

  • Is this example all you need to solve or do you have more complex polygons as well? – underdark Jun 18 '17 at 12:38
  • @underdark just polygons like in this example, but with different angles – Guy Jun 18 '17 at 12:39
  • Please Edit the question in response to requests for clarification. It's not fair to those who would answer to need to mine the comments for critical information. Please include an example of polygons with "different angles". – Vince Jun 18 '17 at 13:38
  • Please, see my answer. Don't worry about the using of coding, you don't need to do anything for get it working! Let me know if you need any assistance for it. – mgri Jun 18 '17 at 18:36
3

A creative approach (using a bit of PyQGIS) would be storing all the vertices of your features and then choosing the elements that are on the most left side of the current feature.

You may run this simple code from the Python Console (after having loaded your layer of interest in the Layers Panel):

from math import radians, cos, sin

layer = iface.activeLayer() # load the layer as you want

# Create the output layer
crs = layer.crs().toWkt()
outLayer = QgsVectorLayer('Point?crs='+ crs, 'final_points' , 'memory')
prov = outLayer.dataProvider()
fields = layer.pendingFields() # Fields from the input layer
prov.addAttributes(fields) # Add input layer fields to the outLayer
outLayer.updateFields()

for feature in layer.getFeatures():
    attrs = feature.attributes()
    points = []
    multi_geom = feature.geometry().asPolygon()
    for i in multi_geom:
        points.extend(i)
    del points[-1]
    sorted_points = sorted(points, key=lambda vtx: vtx[0])

    first_point = sorted_points[0]
    if sorted_points[1][1] != sorted_points[0][1]:
        second_point = sorted_points[1]
    else:
        second_point = sorted_points[2]

    tmpGeom = QgsFeature()
    tmpGeom.setGeometry(QgsGeometry.fromPolyline([first_point, second_point]))
    semi_len = (tmpGeom.geometry().length())/2
    tmp_azim = first_point.azimuth(second_point)
    dist_x, dist_y = (semi_len * cos(radians(90 - tmp_azim)), semi_len * sin(radians(90 - tmp_azim)))
    final_point = QgsPoint(first_point[0] + dist_x, first_point[1] + dist_y)

    outGeom = QgsFeature()
    outGeom.setAttributes(attrs)
    outGeom.setGeometry(QgsGeometry.fromPoint(final_point))
    prov.addFeatures([outGeom])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

and you will obtain the desired result:

enter image description here

I tested the above code on some simple situations that are similar to the ones you attached as examples and I didn't encounter any problem.


Note At the beginning of the code, I wrote:

layer = iface.activeLayer() # load the layer as you want

If you want to find other ways for loading the layer, you may probably find useful this post I recently wrote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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