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
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP