TransWikia.com

QGIS define hexagon area around mapped points

Geographic Information Systems Asked by Al Biruni on April 23, 2021

I am using QGIS to map a number of radio antennas (for mobile network).
Once I have the layer of the sites (done), I would like to assign to each site a coverage area (envelope). I could achieve that using the “fixed distance buffer” function of fTools

However, I couldn’t make the envelope have a Hexagon shape.

When I specify the number of segments:
1: I obtain a square
2: I obtain an octagon …

How can I do to have a Hexagon?

Thank you

2 Answers

As MappaGnosis indicated, you could write a little script for this. Here's one called polygonbuffer which takes three arguments: The output file name, the radius of your buffer, and the number of corners of the polygons.

Open a Python console in QGIS, paste the script and press enter to define the function, then call using something like polygonbuffer("polygons.shp",50,6) to get hexagons with a radius of 50 map units:

import numpy as np
def polygonbuffer(outputFilename, bufferLength, polygonSides=6):
 layer = qgis.utils.iface.activeLayer()
 provider = layer.dataProvider()
 fields = provider.fields()
 writer = QgsVectorFileWriter(outputFilename, "CP1250", fields, QGis.WKBPolygon, provider.crs(), "ESRI Shapefile")
 inFeat = QgsFeature()
 outFeat = QgsFeature()
 inGeom = QgsGeometry()
 provider.select( provider.attributeIndexes() )
 while provider.nextFeature(inFeat):
  point = inFeat.geometry().asPoint()
  inGeom = inFeat.geometry()
  outFeat.setGeometry(QgsGeometry.fromPolygon(
   [[QgsPoint(point[0]+np.sin(angle)*bufferLength, point[1]+np.cos(angle)*bufferLength)
     for angle in np.linspace(0,2*np.pi,polygonSides, endpoint=False)]]))
  outFeat.setAttributeMap( inFeat.attributeMap() )
  writer.addFeature( outFeat )
 del writer
 newlayer = QgsVectorLayer(outputFilename, "Polygons", "ogr")
 QgsMapLayerRegistry.instance().addMapLayer(newlayer)

Answered by Jake on April 23, 2021

Here is @Jake's script adapted to PyQGIS 3 and some extras:

# Settings:
inputlayer = iface.activeLayer()
polygonSides = 6
bufferLength = 100 # in CRS units

# No changes needed below #
import numpy as np
if inputlayer.wkbType() != QgsWkbTypes.Point: # Only execute script if selected layer is of type point
    print("Error: Selected layer is not of type Point! - Script wont work with other geometry types or MultiPoints!")
else: # run script
    if polygonSides == 6: # set name of new layer to Hexagons if 6 sides were chosen
        layername = "Hexagons"
    else: # else set layername to generic "polygons"
        layername = "Polygons"
    newlayer = QgsVectorLayer("Polygon", layername, "memory") # Create the new outputlayer
    newlayer.setCrs(inputlayer.crs()) # Set new layers CRS to inputlayers crs
    with edit(newlayer): # edit new layer
        newlayer.dataProvider().addAttributes(inputlayer.fields()) # copy fields from input layer to new layer
        for feat in inputlayer.getFeatures(): # iterate over inputlayer
            point = feat.geometry().asPoint() # get geometry of inputpoint
            geom = [QgsPointXY(point[0]+np.sin(angle)*bufferLength, point[1]+np.cos(angle)*bufferLength)
             for angle in np.linspace(0,2*np.pi,polygonSides, endpoint=False)] # create the vertices of hexagon polygon
            outFeat = QgsFeature() # create new feature
            outFeat.setAttributes(feat.attributes()) # copy attributes of inputfeature to outputfeature
            outFeat.setGeometry(QgsGeometry.fromPolygonXY([geom])) # set new features geometry from vertices-pointlist
            newlayer.dataProvider().addFeature(outFeat) # add the feature
            newlayer.updateFeature(outFeat) # and update it
    QgsProject.instance().addMapLayer(newlayer) # add new layer to canvas

Answered by MrXsquared on April 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP