Wednesday 2 January 2019

QGIS plugin: PointByPolarCoordCSV (multipoint mode)

This is version of PointByPolarCoord plugin if we have many points for which bearings, distances and reference point is given.


This plugin can be helpful if you need to get location (latitude, longitude) point and you have their location in 'local polar coordinate system': reference point latitude, longitude, magnetic variation (optional), and bearings (magnetic or true) and distances of points.
To test this plugin I have created CSV file in format with header P_NAME;BRNG;DIST with ranfom data for bearing and distance. Here is sample of test  data:

P_NAME;BRNG;DIST
1;157;0.168891584
2;137;9.546522759
3;164;3.228576728
4;245;5.93489517
5;175;6.992273999
6;104;4.240081055

The results has the same attributes as PointByPolarCoord as an example shows:

The major difference is in the points calcualation part of plugin source:

if self.check_csv_points_input():
    true_mag = 'MAG'
    if self.ref_point.mag_var.src_value == '':
        true_mag = 'TRUE'

    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 = lct.get_tmp_name()

    if self.mlyr_name not in layers_list:
        self.create_mem_lyr(self.mlyr_name)

    out_lyr = self.iface.activeLayer()
    out_lyr.startEditing()
    out_prov = out_lyr.dataProvider()
    feat = QgsFeature()

    out_csv_fnames = ['P_NAME', 'BRNG', 'DIST', 'LAT_DMS', 'LON_DMS', 'POLAR_COOR', 'NOTES']
    with open(self.input_file, 'r') as inCSV:
        with open(self.output_file, 'w') as outCSV:
            reader = csv.DictReader(inCSV, delimiter=';')
            writer = csv.DictWriter(outCSV, fieldnames=out_csv_fnames, delimiter=';')
            for row in reader:
                valid_azm_dist, notes = lct.check_azm_dist(row['BRNG'], row['DIST'])
                if valid_azm_dist:  # azimuth or brng and distance are valid
                    csv_points_uom = self.get_csv_points_uom()
                    dist_m = lct.to_meters(float(row['DIST']), csv_points_uom)
                    pp_brng = lct.Bearing(row['BRNG'])
                    polar_point = lct.PolarCoordPoint(self.ref_point, pp_brng, dist_m)
                    pp_name = row['P_NAME']
                    pp_def = 'Ref point: {} Bearing {} {} Distance: {} {}'.format(self.ref_point.origin_id,
                                                                                  pp_brng.src_value,
                                                                                  true_mag,
                                                                                  row['DIST'],
                                                                                  csv_points_uom)
                    # Write result to output file
                    writer.writerow({'P_NAME': row['P_NAME'],
                                     'BRNG': row['BRNG'],
                                     'DIST': row['DIST'],
                                     'LAT_DMS': str(polar_point.ep_lat_dd),
                                     'LON_DMS': str(polar_point.ep_lon_dd),
                                     'POLAR_COOR': pp_def,
                                     'NOTES': ''})
                    # Write result to temporary layer
                    pp_qgs_point = QgsPointXY(polar_point.ep_lon_dd, polar_point.ep_lat_dd)
                    pp_attributes = [self.ref_point.origin_id,
                                     self.ref_point.src_lat,
                                     self.ref_point.src_lon,
                                     pp_name,
                                     polar_point.ep_lat_dd,
                                     polar_point.ep_lon_dd,
                                     pp_def]
                    feat.setGeometry(QgsGeometry.fromPointXY(pp_qgs_point))
                    feat.setAttributes(pp_attributes)
                    out_prov.addFeatures([feat])
                else:
                    pass

    out_lyr.commitChanges()
    out_lyr.updateExtents()
    self.iface.mapCanvas().setExtent(out_lyr.extent())
    self.iface.mapCanvas().refresh()

No comments:

Post a Comment