Esempio n. 1
0
    def decode_waypoint(self, fields, headers):

        # Ignore empty lines
        num_fields = len(fields)
        if num_fields == 0:
            return

        # Ignore comments
        if fields[0].startswith("*"):
            return

        if num_fields < len(BASE_HEADERS):
            raise ParserError(
                "Not enough fields provided. Expecting at minimum following fields: \nname, code, country, lat, lon, elev, style"
            )

        if num_fields > len(BASE_HEADERS) + len(PLUS_HEADERS):
            raise ParserError(
                "Too many fields provided. Expecting at maximum following 14 fields"
            )

        return {
            MAPPING[h]: getattr(self, "decode_%s" % MAPPING[h])(field.strip())
            for h, field in zip(headers, fields) if MAPPING.get(h)
        }
Esempio n. 2
0
    def decode_style(self, style):
        try:
            style = int(style)
        except ValueError:
            raise ParserError('Reading style failed')

        if not (1 <= style <= 17):
            raise ParserError('Unknown waypoint style')

        return style
Esempio n. 3
0
    def decode_longitude(self, longitude):
        match = RE_LONGITUDE.match(longitude)
        if not match:
            raise ParserError('Reading longitude failed')

        longitude = int(match.group(1)) + float(match.group(2)) / 60.

        if not (0 <= longitude <= 180):
            raise ParserError('Longitude out of bounds')

        if match.group(3).upper() == 'W':
            longitude = -longitude

        return longitude
Esempio n. 4
0
    def decode_latitude(self, latitude):
        match = RE_LATITUDE.match(latitude)
        if not match:
            raise ParserError('Reading latitude failed')

        latitude = int(match.group(1)) + float(match.group(2)) / 60.

        if not (0 <= latitude <= 90):
            raise ParserError('Latitude out of bounds')

        if match.group(3).upper() == 'S':
            latitude = -latitude

        return latitude
Esempio n. 5
0
    def decode_longitude(self, line):
        match = RE_LONGITUDE.match(line[52:60])
        if not match:
            raise ParserError('Reading longitude failed')

        lon = (int(match.group(2)) + int(match.group(3)) / 60. +
               int(match.group(4)) / 3600.)

        if not (0 <= lon <= 180):
            raise ParserError('Longitude out of bounds')

        if match.group(1) == 'W':
            lon = -lon

        return lon
Esempio n. 6
0
    def decode_latitude(self, line):
        match = RE_LATITUDE.match(line[45:52])
        if not match:
            raise ParserError('Reading latitude failed')

        lat = (int(match.group(2)) + int(match.group(3)) / 60. +
               int(match.group(4)) / 3600.)

        if not (0 <= lat <= 90):
            raise ParserError('Latitude out of bounds')

        if match.group(1) == 'S':
            lat = -lat

        return lat
Esempio n. 7
0
    def decode_waypoint(self, fields):
        # Ignore header line
        if fields == ['name', 'code', 'country', 'lat', 'lon', 'elev',
                      'style', 'rwdir', 'rwlen', 'freq', 'desc']:
            return

        # Ignore empty lines
        num_fields = len(fields)
        if num_fields == 0:
            return

        # Ignore comments
        if fields[0].startswith('*'):
            return

        if num_fields != 11:
            raise ParserError('Fields are missing')

        fields = [field.strip() for field in fields]

        return {
            'name': self.decode_name(fields[0]),
            'code': self.decode_code(fields[1]),
            'country': self.decode_country(fields[2]),
            'latitude': self.decode_latitude(fields[3]),
            'longitude': self.decode_longitude(fields[4]),
            'elevation': self.decode_elevation(fields[5]),
            'style': self.decode_style(fields[6]),
            'runway_direction': self.decode_runway_direction(fields[7]),
            'runway_length': self.decode_runway_length(fields[8]),
            'frequency': self.decode_frequency(fields[9]),
            'description': self.decode_description(fields[10]),
        }
Esempio n. 8
0
    def convert_waypoint(self, old):
        waypoint = {}

        waypoint['name'] = old['name']
        waypoint['shortname'] = old['code']
        waypoint['country'] = old['country']
        waypoint['description'] = old['description']

        waypoint['latitude'] = old['latitude']
        waypoint['longitude'] = old['longitude']

        waypoint['elevation'] = self.convert_elevation(old['elevation'])

        if old['style'] not in WAYPOINT_STYLE_MAPPING:
            raise ParserError('Unknown waypoint style')

        waypoint['classifiers'] = set(WAYPOINT_STYLE_MAPPING[old['style']])

        if 'landable' in waypoint['classifiers']:
            waypoint['icao'] = None
            waypoint['runways'] = self.convert_runways(old['style'],
                                                       old['runway_direction'],
                                                       old['runway_length'])
            waypoint['frequencies'] = self.convert_frequencies(
                old['frequency'])

        return waypoint
Esempio n. 9
0
    def decode_waypoint(self, line):
        line = line.strip()

        if not line or line.startswith('$'):
            return

        # Check valid line length
        if len(line) != 64:
            raise ParserError('Line length does not match 64')

        return {
            'shortform': self.decode_shortform(line),
            'is_airfield': self.decode_is_airfield(line),
            'is_unclear': self.decode_is_unclear(line),
            'is_outlanding': self.decode_is_outlanding(line),
            'shortform_zander': self.decode_shortform_zander(line),
            'text': self.decode_text(line),
            'icao': self.decode_icao(line),
            'is_ulm': self.decode_is_ulm(line),
            'field_number': self.decode_field_number(line),
            'is_glidersite': self.decode_is_glidersite(line),
            'runway_surface': self.decode_runway_surface(line),
            'runway_length': self.decode_runway_length(line),
            'runway_directions': self.decode_runway_directions(line),
            'frequency': self.decode_frequency(line),
            'elevation': self.decode_elevation(line),
            'elevation_proved': self.decode_elevation_proved(line),
            'latitude': self.decode_latitude(line),
            'longitude': self.decode_longitude(line),
            'ground_check_necessary': self.decode_ground_check_necessary(line),
            'better_coordinates': self.decode_better_coordinates(line),
            'country': self.decode_country(line),
            'year_code': self.decode_year_code(line),
            'source_code': self.decode_source_code(line),
        }
Esempio n. 10
0
    def decode_frequency(self, frequency):
        if not frequency:
            return None

        if not RE_FREQUENCY.match(frequency):
            raise ParserError('Reading frequency failed')

        return frequency
Esempio n. 11
0
    def decode_elevation(self, elevation):
        match = RE_ELEVATION.match(elevation)
        if not match:
            raise ParserError('Reading elevation failed')

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ('m', 'ft'):
            raise ParserError('Unknown elevation unit')

        return {
            'value': value,
            'unit': unit,
        }
Esempio n. 12
0
    def decode_elevation(self, elevation):
        match = RE_ELEVATION.match(elevation)
        if not match:
            raise ParserError("Reading elevation failed")

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ("m", "ft"):
            raise ParserError("Unknown elevation unit")

        return {
            "value": value,
            "unit": unit,
        }
Esempio n. 13
0
    def decode_runway_direction(self, runway_direction):
        if not runway_direction:
            return None

        try:
            runway_direction = int(runway_direction)
        except ValueError:
            raise ParserError('Reading runway direction failed')

        return runway_direction
Esempio n. 14
0
    def decode_waypoint(self, fields):
        # Ignore header line
        if fields == [
                'name', 'code', 'country', 'lat', 'lon', 'elev', 'style',
                'rwdir', 'rwlen', 'freq', 'desc'
        ]:
            return

        # Ignore empty lines
        num_fields = len(fields)
        if num_fields == 0:
            return

        # Ignore comments
        if fields[0].startswith('*'):
            return

        if num_fields < 11:
            raise ParserError(
                'Not enough fields provided. Expecting at minimum following 11 fileds:\nname,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc'
            )

        if num_fields > 13:
            raise ParserError(
                'Too many fields provided. Expecting at maximum following 13 fileds:\nname,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc,userdata,pics'
            )

        fields = [field.strip() for field in fields]

        return {
            'name': self.decode_name(fields[0]),
            'code': self.decode_code(fields[1]),
            'country': self.decode_country(fields[2]),
            'latitude': self.decode_latitude(fields[3]),
            'longitude': self.decode_longitude(fields[4]),
            'elevation': self.decode_elevation(fields[5]),
            'style': self.decode_style(fields[6]),
            'runway_direction': self.decode_runway_direction(fields[7]),
            'runway_length': self.decode_runway_length(fields[8]),
            'frequency': self.decode_frequency(fields[9]),
            'description': self.decode_description(fields[10]),
        }
Esempio n. 15
0
    def decode_distance(self, distance_str):
        if not distance_str:
            return {
                "value": None,
                "unit": None,
            }

        match = RE_DISTANCE.match(distance_str)
        if not match:
            raise ParserError("Reading neardis failed")

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ("m", "ft", "km", "ml", "nm"):
            raise ParserError("Unknown distance unit")
        return {
            "value": value,
            "unit": unit,
        }
Esempio n. 16
0
    def decode_distance(self, distance_str):
        if not distance_str:
            return {
                'value': None,
                'unit': None,
            }

        match = RE_DISTANCE.match(distance_str)
        if not match:
            raise ParserError('Reading neardis failed')

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ('m', 'ft', 'km', 'ml', 'nm'):
            raise ParserError('Unknown distance unit')
        return {
            'value': value,
            'unit': unit,
        }
Esempio n. 17
0
    def decode_runway_width(self, runway_width):
        if not runway_width:
            return {
                "value": None,
                "unit": None,
            }

        match = RE_RUNWAY_WIDTH.match(runway_width)
        if not match:
            raise ParserError("Reading runway width failed")

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ("m", "nm", "ml"):
            raise ParserError("Unknown runway width unit")

        return {
            "value": value,
            "unit": unit,
        }
Esempio n. 18
0
    def decode_runway_length(self, runway_length):
        if not runway_length:
            return {
                'value': None,
                'unit': None,
            }

        match = RE_RUNWAY_LENGTH.match(runway_length)
        if not match:
            raise ParserError('Reading runway length failed')

        try:
            value = float(match.group(1))
        except ValueError:
            value = None

        unit = match.group(2)
        if unit and unit.lower() not in ('m', 'nm', 'ml'):
            raise ParserError('Unknown runway length unit')

        return {
            'value': value,
            'unit': unit,
        }
Esempio n. 19
0
    def read(self, fp):
        waypoints = []
        tasks = []
        task_information = False
        reader = csv.reader(fp)
        headers = next(reader, [])
        if not all(h in headers for h in BASE_HEADERS):
            raise ParserError(
                "Headers must include at least include name, code, country, lat, lon, elev, style"
            )

        for fields in reader:
            if fields == ["-----Related Tasks-----"]:
                task_information = True
                continue
            if task_information:
                if fields[0] == "Options":
                    tasks[-1]["Options"] = self.decode_task_options(fields)
                elif fields[0].startswith("ObsZone"):
                    tasks[-1]["obs_zones"].append(
                        self.decode_task_obs_zone(fields))
                else:
                    tasks.append({
                        "name":
                        self.decode_task_name(fields),
                        "waypoints":
                        self.decode_task_waypoints(fields),
                        "options":
                        None,
                        "obs_zones": [],
                    })
            else:
                waypoint = self.decode_waypoint(fields, headers)
                if waypoint:
                    waypoints.append(waypoint)

        return dict(waypoints=waypoints, tasks=tasks)
Esempio n. 20
0
    def decode_name(self, name):
        if not name:
            raise ParserError('Name field must not be empty')

        return name
Esempio n. 21
0
 def decode_country(self, country):
     if RE_COUNTRY.match(country):
         return country
     else:
         raise ParserError('Invalid country code')