Thursday 13 December 2018

Challenge: Circle segment polygon (QGIS plugin)

If airspace has shape of circle segment (circular segment), e. g.:
"From point at bearing 75 degrees, clockwise arc radius 7.5 NM at center 244521N0935318E to point of bearing 305 from center of arc, then strait line to start point"
to avoid of calculating two points, we can create plugin that creates polygon defined in such way.

In other words, we create polygon that is combined by:
begining of arc, vertices that forms arc, end of arc, and strait line (geodsic line to be precise) from end of arc to begining  of arc.
Input data is very much the same as in ,  hence I use the same Qt widgets and the way to check and get input data is the same.

Part when list of vertices is created is the only difference (compared with CreateCircleSector plugin): there is no need to use arc center vertex (point).

poly_vertices: list of polygon vertices (QgsPointXY objects)
List of vertices contain:
from_vertex: where arc begins (and polygon 'ends')
arc_vertex: part of arc, it is calculated in loop and appended to list of vertices
to_vertex: where arc ends
and strait (to be precise: geodesic line) from end of arc to begin of arc

Note: Geodesic lines issue will be covered in later post.

The way to create polygon is similar to that in CreateCircleSector: we need to calculate vertices from (begin of arc) and to (end of arc). The difference is that polygon doesn't pass thorough circle center, so list of vertices is created in order: vertex from, vertices on arc, vertex to:

poly_vertices = []
from_vertex = QgsPointXY(self.point_from.dd_lon, self.point_from.dd_lat)  # Point from
to_vertex = QgsPointXY(self.point_to.dd_lon, self.point_to.dd_lat)  # Point to

poly_vertices.append(from_vertex)

# Create arc parts
# Calculate arc angle
arc_angle = math.floor(self.brng_to.dd_tbrng) - math.ceil(self.brng_from.dd_tbrng)
if arc_angle < 0:
    arc_angle += 360
elif arc_angle > 360:
    arc_angle -= 360

for i in range(0, arc_angle):
    vertex_lat, vertex_lon = ct.vincenty_direct_solution(self.circ_center.dd_lat,
                                                         self.circ_center.dd_lon,
                                                         math.ceil(self.brng_from.dd_tbrng) + i,
                                                         self.radius_m,
                                                         ct.WGS84_A,
                                                         ct.WGS84_B,
                                                         ct.WGS84_F)

    poly_vertex = QgsPointXY(vertex_lon, vertex_lat)
    poly_vertices.append(poly_vertex)

poly_vertices.append(to_vertex)
poly_vertices.append(from_vertex)

Source code and plugin can be download from: https://github.com/strpaw/QGIS3-CreateCircleSegment-plugin

No comments:

Post a Comment