I am trying to create some polygons where some of the sections correspond to curves/arcs. I have been provided with start point, end point, centre point, radius and direction (clockwise/ anti-clockwise) to create these curved sections. See below for reference:
I have seen this post that has helped massively but unfortunately I do not know how to derive my arc midpoint from the values I have been given (centre point and radius).
I would like to do this programmatically using Python/PyQGIS but somehow, I am unable to find a solution. So far, I have managed to manually trace the midpoint section for the curve and used it to create my lineString layer.
Is there a pythonic way to achieve this and convert to polygon?
This is my code so far:
# Import modules
from qgis.core import *
from qgis.utils import *
# coord for curved section
start_lat, start_lon = 39.08626748, -2.66563606
end_lat, end_lon = 39.20366816, -2.51489454
# This mid point has been traced manually to recreate the curve
mid_curv_lat, mid_curv_lon = 39.20366816, -2.65091330
# coord for squared section
point3_lat, point3_lon = 39.11293834, -2.41907255
point4_lat, point4_lon = 38.98554723, -2.55822285
# coord and radius
centre_lat, centre_lon = 39.13921171, -2.58290392
radius_km = 9.26
# Begin a new project
iface.newProject()
# Create a QgsCircularString
circularRing = QgsCircularString()
# Set first point, intermediate point for curvature and end point
circularRing.setPoints([
QgsPoint(start_lon, start_lat),
QgsPoint(mid_curv_lon, mid_curv_lat),
QgsPoint(end_lon, end_lat)]
)
# Create geometry using the instance of QgsCircularString
curve = QgsGeometry(circularRing)
# Create a QgsLineString
lineString = QgsGeometry.fromPolyline([QgsPoint(end_lon, end_lat),
QgsPoint(point3_lon, point3_lat),
QgsPoint(point4_lon, point4_lat),
QgsPoint(start_lon, start_lat)]
)
# Create curve and line features
fet_curve = QgsFeature()
fet_curve.setGeometry(curve)
fet_line = QgsFeature()
fet_line.setGeometry(lineString)
# Create a memory layer
layer = QgsVectorLayer(
"LineString?crs=epsg:4326&field=id:integer&field=name:string(20)&index=yes",
"temporary_points",
"memory"
)
# Add the layer
QgsProject.instance().addMapLayer(layer)
# Add the feature to the layer provider
pr = layer.dataProvider()
pr.addFeatures([fet_curve, fet_line])
# Update extent
layer.updateExtents()
# Zoom to extent
iface.mapCanvas().setExtent(layer.extent())
iface.mapCanvas().refresh()
EDIT: data sample
|Label|Position|Order|CoordPair |Orientation|Radius_Km|
|-----|--------|-----|------------------|-----------|---------|
|C | |1 |39.08627, -2.66564| | |
|C | |2 |39.20367, -2.51489| | |
|C | |3 |39.11294, -2.41907| | |
|C | |4 |38.98555, -2.55822| | |
|C |Centre | |39.13921, -2.5829 |1 |9.26 |
|A | |5 |38.91119, -2.25953| | |
|A | |1 |38.99365, -2.21096| | |
|A | |2 |38.94734, -2.09687| | |
|A | |3 |38.89763, -2.10139| | |
|A | |4 |38.86149, -2.18385| | |
|A |Centre | |38.927, -2.11607 |1 |9.26 |
|B | |2 |38.74627, -2.41767| | |
|B | |3 |38.74062, -2.26179| | |
|B | |4 |38.68866, -2.25953| | |
|B | |1 |38.69769, -2.42445| | |
|B |Centre1 | |38.72367, -2.44253|1 |9.26 |
|B |Centre2 | |38.71464, -2.25388|1 |9.26 |
Best Answer
I believe
QgsCircularString.fromTwoPointsAndCenter()
is a method that could help you construct those arcs. It creates a circular string consisting of a single arc which represents the curve from one point to another with a specified center point.I've updated your example using the mentioned method and also addressed your problem of converting the exterior line to a polygon.