Friday 7 December 2018

Challenge: QGIS plugin to create circle - center defined by bearing and distance


Sometimes airspace has circle shape with center defined by bearing (true or magnetic) and distance.
We can solve this problem in (obvious) steps:


  1. Calculate latitude and longitude of center
  2. Create circle shape (you can use plugin   created in this post Chellange: QGIS plugin to create circle (based on aviation-like data)
We can also 'hidden'  step (1) and 'force' plugin to do this work: 'power of python scripting in the service of aviation'

The easiest way to create this plugin is probably to extend functionality CreateCircle plugin by adding QWidgets that will capture data about circle center (bearing to center, distance to center and distance unit of measure) and add behaviour of this QWidgets.

If checkButton 'Circle center defined by:' is checked, circle center is calculated, if not - circle center is considered as reference point:


if self.dlg.checkBoxCenterDef.isChecked():  # Calculate circle center
    # Calculate true bearing
    brng.calc_tbrng(mag_var.dd_value)
    # Calculate distance to center in m
    dist_m = ct.to_meters(center_dist_check, self.get_center_dist_uom())
    # Calculate latitude and longitude of circle center
    lat_center, lon_center = ct.vincenty_direct_solution(ref_point.dd_lat,
                                                         ref_point.dd_lon,
                                                         brng.dd_tbrng,
                                                         dist_m,
                                                         ct.WGS84_A,
                                                         ct.WGS84_B,
                                                         ct.WGS84_F)
    self.circ_center = ct.CoordinatesPair(lat_center, lon_center)
elif not self.dlg.checkBoxCenterDef.isChecked():
    self.circ_center = ref_point

And actually this is major change. Vertices calculation, creation new memory layer and adding polygon to layer very much the same as in the plugin CreateCircle plugin:


def add_circle(self):
    if self.check_input():

        # Create circle polygon
        poly_vertices = []
        for i in range(0, 360):
            vertex_lat, vertex_lon = ct.vincenty_direct_solution(self.circ_center.dd_lat,
                                                                 self.circ_center.dd_lon,
                                                                 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)

        layers = QgsProject.instance().layerTreeRoot().children()
        layers_list = []  # List of layers in current (opened) QGIS project
        for layer in layers:
            layers_list.append(layer.name())

        if self.mlyr_name == '':
            self.mlyr_name = ct.get_tmp_name()
        self.polygon_name = self.dlg.lineEditPolyName.text()

        if self.mlyr_name not in layers_list:
            self.create_mem_lyr(self.mlyr_name)
            self.add_feature_to_layer(poly_vertices)
        else:
            self.add_feature_to_layer(poly_vertices)

Complete source code with plugin can be download from here: https://github.com/strpaw/QGIS3-CreateCircle2-plugin

No comments:

Post a Comment