Sunday 30 December 2018

QGIS plugin: PointByPolarCoord



In this post I will create QGIS plugin that allows you to easily create point which is defined in 'polar coordinates' way, that means: by distance and bearing against reference point with known coordinates and magnetic variation. This is also the first post of post series that are related to 'local coordinates' issue', quite common used in aviation data publication


Saturday 29 December 2018

aviation_gis_tools: Point given at offset against polar coordinates

Another way of giving location of point of interest in aviation (e. g. obstacles) is providing information about:
  • reference point (aerodrome referenc epoint, navaid, runway threshold)
  • bearing of reference line (note: it can be given directly or as 'extende line of center line of rwy XX'
  • side on which point is located (left, right) against reference line
  • offset against reference line

Wednesday 26 December 2018

aviation_gis_tools: Polar coordinates

First, we need import classes that will be useful:


from aviation_ellipsoid_calc_tools import vincenty_direct_solution
from aviation_bearing_tools import MagVar, Bearing
from aviation_coordinate_tools import CoordinatesPair

Constructor of LocalOriginPoint class:

class LocalOriginPoint(CoordinatesPair):
    def __init__(self, src_lat, src_lon, src_mag_var, origin_id='', origin_name=''):
        CoordinatesPair.__init__(self, src_lat, src_lon)
        self.mag_var = MagVar(src_mag_var)
        self.origin_id = origin_id
        self.origin_name = origin_name
        self.check_init_data()

Monday 17 December 2018

QGIS: customized attribute dialog

The skill to customize the attribute dialog box to current need can be very useful when you want to safe time and avoid mistakes in attribute entry during digitization.

Sunday 16 December 2018

If you use plugins from series of post about 'circle based plugins' (CreateCircle, CreateCircleSector, CreateCircleSegment etc.) or you look at source code - you will spot some drawbacks:
  • new features (polygons) might be added to layer that is in Layer Panel
  • duplication of code:
    • creating inner and outer arc - it can be done in function
    • calculation points (start and end of arc) can be done simpler (function, class)
  • lack of some precondition checking:
    • missing validation if radius is greater then 0, 
    • missing validation if outer radius is greater then inner radius 
    • missing validation if bearings from and to are not equal
  •  if we have to create a lot of such polygons it would be convenient to create them in one layer and using one plugins, in which we could choose what kind of polygon we need

Saturday 15 December 2018

QGIS Plugin: Circle ring sector

This plugins creates polygon that is sector of circle ring as name suggests. But how can it be use in aviation? Sometimes lateral limit of airspace is defined as arcs between bearings (clockwise and anti-clockwise), strait lines between between bearings at given radius.

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.

Monday 10 December 2018

QGIS Plugin: Circle sector polygon

This plugins creates circle sector polygon. Input data is: center of circle coordinates, bearing from and baring to values and radius of circle.

Saturday 8 December 2018

Airspaces - grouping by shape

In terms of GIS - airspace is a polygon with certain atributes. Polygon shape, as we know, is described by pairs of coordinates (lon, lat). Let's look at some description of airspace, which you can find i aeronautical publications:

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:

Tuesday 4 December 2018

Coordinates (5): coordinate_tool module

So far we know how to deal with coordinates: how to check if the input is valid - and if it is - how to convert input into decimal degrees format. We have wrote a few functions, but use them might be not as convenient as we expect. Because latitude and longitude input will be very often use while dealing with aviation content, and some data such as: original input from source, information if input is valid coordinate, DD equivalent if input is valid or information about what is wrong with input, etc. will be useful in further processing a good idea is to write class which will deal with all the stuff I mention above.

Sunday 2 December 2018

QGIS Plugin to convert DOF (Digital Obstacle File) data


To use FAA DOF in GIS systems  effectively, we need to store them in format wchich is more friemdly for GIS purposes such as:

Thursday 29 November 2018

Challenge: QGIS plugin to create circle (based on aviation-like data)


Unsurprisingly, circle polygon in aviation world is also defined by center and radius, for example:
Wouldn't be convenient to create circle by passing center latitude and longitude and radius as it they are given in source - in terms of coordinate format and unit of measure?

Tuesday 27 November 2018

Coordinates (4): way if you hate regex

If we don't want to use regular expression, we need to change our approach to solve the 'variety of coordinates format' problem.

This time we will
  • 'normalize' input into more friendly format (e. g. replace all kind of separators (delimiters) with space)
  • parse output sequentially - decision what to do next depends on what you get from previous step, e.g if you split intermediate result into list and get 3 items - it means that the first are degrees, second - minutes, third - seconds (to be more precise - we make such assumption) and validate them to check if it make sense
Let's create a function that will convert coordinates into DD which takes 2 arguments:


def coord2dd(coord_input, c_type):

coord_input: input coordinate to be converted (it also might be DD format!)
c_type: coordinate type (latitude, longitude) to make sure that coordinate is within appropriate range

Definition of c_type constants:

C_LAT = 'C_LAT'
C_LON = 'C_LON'

First we 'normalize input':


coord_norm = coord_input.strip()
coord_norm = coord_norm.upper()
coord_norm = coord_norm.replace(',', '.')  

Monday 26 November 2018

Challenge: importing FAA digital obstacle file content into PostGIS database

plus bonus: browsing data using QGIS.

What FAA Digital Obstacle File (DOF) is and how to model it using PostGIS database - refer to post
Now, it's time to load some data into our database using Python script.

First we need to populate tables such as ctry_state, hacc, lighting because primary keys of this tables are foreign keys in main table obstruction.

To insert data into hacc (horizontal accuracy) table execute following DML statement:

INSERT INTO hacc VALUES
('1', 20, 'FEET'),
('2', 50, 'FEET'),
('3', 100, 'FEET'),
('4', 250, 'FEET'),
('5', 500, 'FEET'),
('6', 1000, 'FEET'),
('7', 0.5, 'NM'),
('8', 1, 'NM'),
('9', -1, 'UNKNOWN'),
('N', -1, 'NO DATA');

Sunday 25 November 2018

aviation_gis_tools: bearings, magnetic variation

In this post we will discuss another indispensable 'item' when we deal with aviation content:  bearings (true and magnetic) and magnetic variations.

Many times in aeronautical publications you will see:
  • position of points are defined as magnetic bearing from specified point (e. g. aerodrome reference point), and magnetic variation for this point is known, we are interesting in  geographic position of obstacle  not magnetic
  • boundary of airspace (a good example that comes to my mind are airspaces on minimum radar vectoring chart) are defined as arcs and 'strait' lines by points, which are defined by radials and distances against point with specified position and magnetic variation; by definition radial are expressed in magnetic bearing - and again we would like to know geographic position of vertices that create the shape of airspace not magnetic.
As you can see - if we do not have a tool that can check if input is correct bearing, magnetic variation and calculate true bearing little can be done.

Because bearing and magnetic variation are types of angles (as well as latitude and longitude) and might be given in various formats let's create basic class Angle.
Angle class will cover common tasks as validating input, range and so on.
Class definition will start with constructor:


class Angle:
    def __init__(self, src_value):
        self.src_value = src_value
        self._is_valid = None
        self._dd_value = None
        self._err_msg = ''

Saturday 24 November 2018

aviation_gis_tools: calculation on ellipsoid

The common issue in aviation is:
Some point of interest (e. g. location of fixes, obstacles, airspace boundary definition) are not given directly as pair of coordinates but their location is defined as combinations of distance (in various units), direction (true or magnetic) against specified point (waypoint, navigation aid, runway threshold) with defined latitude and longitude.

Friday 23 November 2018

Coordinates (3): way of regular expressions (continued)

In second post related to coordinates only one format of DMS has been covered. As I pointed to cover more possible format we have to write more regular expression or write complex regular expression in that way that it will match all combination of coordinate format that we want.

In this post I am going to share how to convert coordinate in various format (DMSH, HDMS) with different separators (space, hyphen, no separator) and get format of coordinate.

Let's start with defining constants to describe various coordinate formats:

# Hemisphere prefix degrees, minutes, seconds separated
F_HDMS_SEP_HYPHEN = 'F_HDMS_SEP_HYPHEN'  # hyphen separator
F_HDMS_SEP_SPACE = 'F_HDMS_SEP_SPACE'  # space separator
F_HDMS_SEP_WORD = 'F_HDMS_SEP_WORD'  # word DEG, MIN SEC separator
F_HDMS_SEP_LETTER = 'F_HDMS_SEP_LETTER'  # letter D, M, S separator

# Hemisphere suffix degrees, minutes, seconds separated
F_DMSH_SEP_HYPHEN = 'F_DMSH_SEP_HYPHEN'  # hyphen separator
F_DMSH_SEP_SPACE = 'F_DMSH_SEP_SPACE'  # space separator
F_DMSH_SEP_WORD = 'F_DMSH_SEP_WORD'  # word DEG, MIN SEC separator
F_DMSH_SEP_LETTER = 'F_DMSH_SEP_LETTER'  # letter D, M, S separator

# Degrees, minutes, seconds compacted
F_HDMS_COMP = 'F_HDMS_COMP'  # Hemisphere prefix DMS compacted
F_DMSH_COMP = 'F_DMSH_COMP'  # Hemisphere suffix DMS compacted

Thursday 22 November 2018

Challenge: FAA Digital Obstacle File into CSV format

If we want to visualize or work DOF we need to import it into our GIS application. If we don't have a customized function that import DOF in dat format, probably the easiest way is to convert dat file into CSV file, simultaneously calculating coordinates in DD format.

First, let's define fields in our output CSV file:

cvs_field_names = ['oas_code', 'obs_number', 'verif_stat', 'country_id', 'state_id',
                       'city_name', 'lat_dms', 'lon_dms', 'obs_type', 'quantity', 'agl_height',
                       'ams_height', 'lighting', 'hor_acc', 'vert_acc', 'mar_indicator', 'faa_study_number',
                       'action', 'jdate', 'lat_dd', 'lon_dd']

Script will read line of input file, parse this line and assign values to appropriate fields of output csv file. So we need to open input file and 'open' output csv file:

with open(in_file, 'r') as dof_file:
        with open(output_file, 'w', newline='') as csv_file:

Wednesday 21 November 2018

PostGIS database for storing FAA Digital Obstacle File

FAA - Federal Aviation Administration - United States authority to regulate civil aviation issues DOF (Digital Obstacle File) with obstacles of interest to aviation users in the United States, with limited coverage of selected region and countries.

To get more information about DOF and to download data visit:
FAA Digital Obstacle File web page
To understand format of data refer to:
DOF description

If you download a DOF.dat (main file with all records) you will see that file contains information about 450 000 obstacles. This might be pretty impressive number of records, which will be more efficient to use (select large amount of data) in database. Needless to say each obstacle has information about its location. Using of PostGIS - spatial extension for PostgreSQL will be a good choice to deal with this content.

Monday 19 November 2018

Coordinates (2): way of regular expressions

In the second part I will show how to check if latitude or longitude is valid using regular expressions.

First, let's look at example of latitude and longitude in DMSH format, space delimited:
                      52 22 33.47N 015 42 33.44E
We can write is in general form as:
                       DD MM SS.ss H DDD MM SS.ss H
and the following must be true:
  • DD is between <-90, 90> for latitude and <-180, 180> for longitude
  • MM is between <0, 59>
  • SS.ss is between equal or grater than 0 and less then 60
and in general format:
                      ddsddsdd.ddL dddsddsdd.ddL
where d is digit, s is space and L is hemisphere letter (N, S, E, W).

 We will take into account that latitude can be without 'leading zeros' in our further deliberations:
                       1 1 1.44N instead of 01 01 01.44N
There are two options here:
1. To write quite complex regular expression that will take into account all combinations of deg, min, sec e. g.:
  • for latitude: if deg is equal 90, min, sec must be equal 0 (90 05 05.55N is not valid latitude)
  • for latitude: if deg is between  <-90, 90> min might take integer values <0, 59>, sec integer values <0, 59> or float values <0, 60)
2. To write much simpler regular expression that will take into account only general conditions, and if input matches regular expression check if deg, min, sec meet further conditions.

Regular expression to match coordinate in DMSH format, space separated looks like:

regex_dmsh = re.compile(r'''(?P<deg>^\d{1,3})  # Degrees
                            (\s)
                            (?P<min>\d{1,2})  # Minutes
                            (\s)
                            (?P<sec>\d{1,2}(\.\d+)?)  # Seconds
                            (?P<hem>[NSEW]$)
                         ''', re.VERBOSE)

Thursday 15 November 2018

Challenge: QGIS Plugin to create polygon from text

This is the first post from series Challenge - where you can find how to automate repetitive task to save time and money.

Let's assume that you have to create vector data based on textual description of polygons, e. g.:

585200N0312800E-584700N0312700E-583500N0311700E-583200N0312700E-
583200N0313300E-582900N0313800E-582800N0314400E-
582500N0314500E-585200N0312800E.

It is not a big problem, when you have to enter into system 1, 2, 5 or even 10 such polygons that are have not too many vertices.
But what if you have many of them and deadline is coming?

We can write plugin for QGIS which will create polygons.


Wednesday 14 November 2018

Coordinates (1): variety of coordinate formats

A glance at variety of coordinate formats which you can find in aeronautical publications (AIP, NOTAMS, other documents) might give you a serious headache:
  • Poland: 520932.8N 0205905.6E
  • Senegal: 14DEG40'30''N 017DEG25'59''W
  • India: 130000N 0781015E
  • Australia: 12 25 24S 130 54 23E, S 18 16 31.28 E 143 35 19.30, S24 00.0 E152 12.5
  • USA: 30 15 01.00N 088 04 45.00W, lat. 38°38'19"N., long. 104°52'02"W
  • Pacific Organised Track System (PACOTS): 41N160E 44N170E
are among the most common ones.

Tuesday 13 November 2018

QGIS Plugin: DistanceUnitConverter


There are plenty of online tools that allows you to convert distance given in one unit of measure into another one. Every GIS software has 'measure' functionality which calculates distance in unit you choose.

But, what if you are working on your task and you need to convert distance between two units without searching on the internet? Maybe plugin is a good answer.

Plugin that allows you to convert distance among various units: meters, kilometers, nautical miles, feet and statue miles.

Monday 12 November 2018

aviation_gis_tools: dealing with distance

Let's start building aviation tools from something which is quite simple and very basic: dealing with distances.

There are many units of measure for distance that are used in aviation industry: meters, feet, nautical miles and statue miles. Definition of unit of measure that will be used in our tools:
UOM_M = 'M'  # meters
UOM_KM = 'KM'  # kilometers
UOM_NM = 'NM'  # nautical miles
UOM_FEET = 'FEET'  # feet
UOM_SM = 'SM'  # statue miles

Sunday 11 November 2018

aviation_gis_tools is upcoming! (and note about reinventing the wheel)

As I wrote in the introductory post, you can learn here how to make your work more efficient, comfortable and even enjoyable while dealing with aviation content. Needless to say, we need some tools to do such things. Luckily, there is a bunch of tools available on the market: plugins and extension for free, open source and proprietary GIS software. Furthermore, some of this applications share their API which allows us to extend their capability by adding specified, problem oriented and highly customized tools. Hence, we are able to build a new functionality using built-in, optimized functions, the same that we use while using user interface.
But,  here I am going to write some tools from scratch…
So, you may ask: What is the purpose of creating and likely duplicating existing code?

Thursday 8 November 2018

Welcome!

Welcome to the Aviation GIS Applications blog. This is a blog about wide range of uses GIS, including a lot of Python scripting, to deal with aviation content, unsurprisingly in aviation industry.

But don’t worry – if you are not particularly interested in aviation and related issues but you are eager to learn, or just need to know how to: