Merge pull request #52 from Meisterschueler/feature/relationships

Feature/relationships
pull/55/head
Meisterschueler 2016-06-16 12:30:31 +02:00 zatwierdzone przez GitHub
commit 0529013f87
28 zmienionych plików z 57845 dodań i 1160 usunięć

Wyświetl plik

@ -1,6 +1,15 @@
# CHANGELOG
## Unreleased
- Moved to PostGIS, PostgreSQL is now mandantory
- Changed database schema (added airport, added relations, added aircraft_type, removed unused fields)
- Added Airport manager with command line option `db.import_airports`,
default is WELT2000
- Logbook: instead of lat, lon and name of the airport just pass the name
- Logbook: optional utc offset, optional single day selection
- Logbook: remark if different airport is used for takeoff or landing
- Logbook: several accuracy and speed improvements
- DDB: consider aircraft_type
- Moved exceptions from `ogn.exceptions` to `ogn.parser.exceptions`
- Moved parsing from `ogn.model.*` to `ogn.parser`

Wyświetl plik

@ -10,8 +10,7 @@
A database backend for the [Open Glider Network](http://wiki.glidernet.org/).
The ogn-python module saves all received beacons into a database with [SQLAlchemy](http://www.sqlalchemy.org/).
It connects to the OGN aprs servers with [python-ogn-client](https://github.com/glidernet/python-ogn-client).
For simple tests a [sqlite](https://www.sqlite.org/)-backend is sufficient,
but some tasks (e.g. logbook generation) require a proper database backend like [postgresql](http://www.postgresql.org/).
It requires [PostgreSQL](http://www.postgresql.org/) and [PostGIS](http://www.postgis.net/).
[Examples](https://github.com/glidernet/ogn-python/wiki/Examples)
@ -28,14 +27,17 @@ but some tasks (e.g. logbook generation) require a proper database backend like
```
pip install -r requirements.txt
```
3. Install [PostgreSQL](http://www.postgresql.org/) with [PostGIS](http://www.postgis.net/) Extension.
Create a database (use "ogn" as default, otherwise you have to modify the configuration, see below)
3. Install redis for asynchronous tasks (like takeoff/landing-detection)
4. Optional: Install redis for asynchronous tasks (like takeoff/landing-detection)
```
apt-get install redis-server
```
4. Create database
5. Create database
```
./manage.py db.init
@ -103,6 +105,9 @@ available commands:
compute Compute takeoffs and landings.
show Show a logbook for <airport_name>.
[show.airport]
list_all Show a list of all airports.
[show.devices]
stats Show some stats on registered devices.
@ -119,9 +124,8 @@ Only the command `logbook.compute` requires a running task server (celery) at th
- `ogn.collect.database.import_ddb` - Import registered devices from the ddb
- `ogn.collect.database.import_file` - Import registered devices from a local file
- `ogn.collect.heatmap.update_beacon_receiver_distance_all` - Calculate the distance between aircraft and receiver for the last aircraft beacons
- `ogn.collect.receiver.update_receivers` - Populate/update receiver table (requires postgresql-backend)
- `ogn.collect.logbook.compute_takeoff_and_landing` - Generate TakeoffLanding table (requires postgresql-backend)
- `ogn.collect.receiver.update_receivers` - Populate/update receiver table
- `ogn.collect.logbook.compute_takeoff_and_landing` - Generate TakeoffLanding table
If the task server is up and running, tasks could be started manually.

Wyświetl plik

@ -0,0 +1,26 @@
"""remove unused fields from takeoff_landing
Revision ID: 163f6213d3f
Revises: 258a3f6bbdc
Create Date: 2016-06-03 20:05:20.749369
"""
# revision identifiers, used by Alembic.
revision = '163f6213d3f'
down_revision = '258a3f6bbdc'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.drop_column('takeoff_landing', 'altitude')
op.drop_column('takeoff_landing', 'ground_speed')
def downgrade():
op.add_column('takeoff_landing', sa.Column('altitude', sa.Integer))
op.add_column('takeoff_landing', sa.Column('ground_speed', sa.Float))

Wyświetl plik

@ -0,0 +1,28 @@
"""add aircraft_type to device
Revision ID: 258a3f6bbdc
Revises: 7585491482
Create Date: 2016-05-25 20:16:57.990249
"""
# revision identifiers, used by Alembic.
revision = '258a3f6bbdc'
down_revision = '7585491482'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('device', sa.Column('aircraft_type', sa.Integer))
op.create_index('ix_device_aircraft_type', 'device', ['aircraft_type'])
op.create_index('ix_aircraft_beacon_aircraft_type', 'aircraft_beacon', ['aircraft_type'])
def downgrade():
op.drop_index('ix_aircraft_beacon_aircraft_type', 'aircraft_beacon')
op.drop_index('ix_device_aircraft_type', 'device')
op.drop_column('device', 'aircraft_type')

Wyświetl plik

@ -0,0 +1,83 @@
"""Create relations
Revision ID: 46d818bc09b
Revises: 2004ce1566c
Create Date: 2016-05-18 21:00:24.832298
"""
# revision identifiers, used by Alembic.
revision = '46d818bc09b'
down_revision = '2004ce1566c'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
import geoalchemy2 as ga
def upgrade():
op.add_column('aircraft_beacon', sa.Column('device_id', sa.Integer))
op.create_foreign_key("aircraft_beacon_device_id_fkey", "aircraft_beacon", "device", ["device_id"], ["id"], ondelete="SET NULL")
op.create_index('ix_aircraft_beacon_device_id', 'aircraft_beacon', ['device_id'])
op.add_column('aircraft_beacon', sa.Column('receiver_id', sa.Integer))
op.create_foreign_key("aircraft_beacon_receiver_id_fkey", "aircraft_beacon", "receiver", ["receiver_id"], ["id"], ondelete="SET NULL")
op.create_index('ix_aircraft_beacon_receiver_id', 'aircraft_beacon', ['receiver_id'])
op.drop_index('ix_aircraft_beacon_address', 'aircraft_beacon')
op.add_column('receiver_beacon', sa.Column('receiver_id', sa.Integer))
op.create_foreign_key("receiver_beacon_receiver_id_fkey", "receiver_beacon", "receiver", ["receiver_id"], ["id"], ondelete="SET NULL")
op.create_index('ix_receiver_beacon_receiver_id', 'receiver_beacon', ['receiver_id'])
op.add_column('takeoff_landing', sa.Column('airport_id', sa.Integer))
op.create_foreign_key("takeoff_landing_airport_id_fkey", "takeoff_landing", "airport", ["airport_id"], ["id"], ondelete="SET NULL")
op.create_index('ix_takeoff_landing_airport_id', 'takeoff_landing', ['airport_id'])
op.add_column('takeoff_landing', sa.Column('device_id', sa.Integer))
op.create_foreign_key('takeoff_landing_device_id_fkey', 'takeoff_landing', 'device', ['device_id'], ['id'], ondelete="SET NULL")
op.create_index('ix_takeoff_landing_device_id', 'takeoff_landing', ['device_id'])
op.drop_index('ix_takeoff_landing_address', 'takeoff_landing')
op.drop_index('idx_takeoff_landing_location', 'takeoff_landing')
op.drop_column('takeoff_landing', 'address')
op.drop_column('takeoff_landing', 'name')
op.drop_column('takeoff_landing', 'receiver_name')
op.drop_column('takeoff_landing', 'location')
def downgrade():
op.drop_index('ix_aircraft_beacon_device_id', 'aircraft_beacon')
op.drop_foreign_key("aircraft_beacon_device_id_fkey", "aircraft_beacon")
op.drop_column('aircraft_beacon', 'device_id')
op.drop_index('ix_aircraft_beacon_receiver_id', 'aircraft_beacon')
op.drop_foreign_key("aircraft_beacon_receiver_id_fkey", "aircraft_beacon")
op.drop_column('aircraft_beacon', 'receiver_id')
op.create_index('ix_aircraft_beacon_address', sa.Column('address', sa.String))
op.drop_index('ix_receiver_beacon_receiver_id', 'receiver_beacon')
op.drop_foreign_key("ix_receiver_beacon_receiver_id", "receiver_beacon")
op.drop_column('receiver_beacon', 'receiver_id')
op.drop_index('ix_takeoff_landing_airport_id', 'takeoff_landing')
op.drop_foreign_key("takeoff_landing_airport_id_fkey", "takeoff_landing")
op.drop_column('takeoff_landing', 'airport_id')
op.drop_index('ix_takeoff_landing_device_id', 'takeoff_landing')
op.drop_foreign_key("takeoff_landing_device_id_fkey", "takeoff_landing")
op.drop_column('takeoff_landing', 'device_id')
op.add_column('takeoff_landing', sa.Column('name', sa.String))
op.add_column('takeoff_landing', sa.Column('receiver_name', sa.String(9)))
op.add_column('takeoff_landing', sa.Column('address', sa.String(6)))
op.add_column('takeoff_landing', sa.Column('location', ga.Geometry('POINT', srid=4326)))
op.create_index('ix_takeoff_landing_address', 'takeoff_landing', ['address'])
op.create_index('idx_takeoff_landing_location', 'takeoff_landing', ['location'])

Wyświetl plik

@ -0,0 +1,24 @@
"""correct airport scheme
Revision ID: 7585491482
Revises: 46d818bc09b
Create Date: 2016-05-21 20:19:24.865915
"""
# revision identifiers, used by Alembic.
revision = '7585491482'
down_revision = '46d818bc09b'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.execute('ALTER TABLE airport ALTER COLUMN code TYPE varchar(6)')
def downgrade():
op.execute('ALTER TABLE airport ALTER COLUMN code TYPE varchar(5)')

Wyświetl plik

@ -1,4 +1,4 @@
SQLALCHEMY_DATABASE_URI = 'sqlite:///beacons.db'
SQLALCHEMY_DATABASE_URI = 'postgresql://postgres@localhost:5432/ogn'
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'

Wyświetl plik

@ -1,3 +1,5 @@
from sqlalchemy.sql import null
from celery.utils.log import get_task_logger
from ogn.model import Device, AddressOrigin
@ -8,13 +10,42 @@ from ogn.collect.celery import app
logger = get_task_logger(__name__)
temp_address_origin = 7
def add_devices(session, origin):
before_sq = session.query(Device.address) \
.filter(Device.address_origin == origin) \
.subquery()
add_query = session.query(Device) \
.filter(Device.address_origin == temp_address_origin) \
.filter(~Device.address.in_(before_sq))
result = add_query.update({Device.address_origin: origin},
synchronize_session='fetch')
return result
def update_devices(session, origin, devices):
session.query(Device) \
.filter(Device.address_origin == origin) \
.filter(Device.address_origin == temp_address_origin) \
.delete()
session.bulk_save_objects(devices)
# mark temporary added devices
session.query(Device) \
.filter(Device.address_origin == null()) \
.update({Device.address_origin: temp_address_origin})
logger.info('Added {} devices'.format(add_devices(session, origin)))
# delete temporary added devices
session.query(Device) \
.filter(Device.address_origin == temp_address_origin) \
.delete()
session.commit()
return len(devices)

Wyświetl plik

@ -4,10 +4,10 @@ from celery.utils.log import get_task_logger
from ogn.collect.celery import app
from sqlalchemy.sql import func
from sqlalchemy import and_, or_, insert
from sqlalchemy import and_, or_, insert, between
from sqlalchemy.sql.expression import case
from ogn.model import AircraftBeacon, TakeoffLanding
from ogn.model import AircraftBeacon, TakeoffLanding, Airport
logger = get_task_logger(__name__)
@ -22,7 +22,11 @@ def compute_takeoff_and_landing():
duration = 100 # the points must not exceed this duration
radius = 0.05 # the points must not exceed this radius (degree!) around the 2nd point
# calculate the time where the computation starts
# takeoff / landing has to be near an airport
airport_radius = 0.025 # takeoff / landing must not exceed this radius (degree!) around the airport
airport_delta = 100 # takeoff / landing must not exceed this altitude offset above/below the airport
# calculate the start (and stop) timestamp for the computatio
last_takeoff_landing_query = app.session.query(func.max(TakeoffLanding.timestamp))
begin_computation = last_takeoff_landing_query.one()[0]
if begin_computation is None:
@ -37,55 +41,48 @@ def compute_takeoff_and_landing():
app.session.query(TakeoffLanding) \
.filter(TakeoffLanding.timestamp >= begin_computation) \
.delete()
end_computation = begin_computation + timedelta(days=30)
end_computation = begin_computation + timedelta(days=5)
logger.debug("Calculate takeoffs and landings between {} and {}"
.format(begin_computation, end_computation))
# make a query with current, previous and next position
sq = app.session.query(
AircraftBeacon.address,
func.lag(AircraftBeacon.address).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('address_prev'),
func.lead(AircraftBeacon.address).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('address_next'),
AircraftBeacon.timestamp,
func.lag(AircraftBeacon.timestamp).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('timestamp_prev'),
func.lead(AircraftBeacon.timestamp).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('timestamp_next'),
AircraftBeacon.name,
func.lag(AircraftBeacon.name).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('name_prev'),
func.lead(AircraftBeacon.name).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('name_next'),
AircraftBeacon.receiver_name,
func.lag(AircraftBeacon.receiver_name).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('receiver_name_prev'),
func.lead(AircraftBeacon.receiver_name).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('receiver_name_next'),
func.lag(AircraftBeacon.timestamp).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('timestamp_prev'),
func.lead(AircraftBeacon.timestamp).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('timestamp_next'),
AircraftBeacon.location_wkt,
func.lag(AircraftBeacon.location_wkt).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('location_wkt_prev'),
func.lead(AircraftBeacon.location_wkt).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('location_wkt_next'),
func.lag(AircraftBeacon.location_wkt).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('location_wkt_prev'),
func.lead(AircraftBeacon.location_wkt).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('location_wkt_next'),
AircraftBeacon.track,
func.lag(AircraftBeacon.track).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('track_prev'),
func.lead(AircraftBeacon.track).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('track_next'),
func.lag(AircraftBeacon.track).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('track_prev'),
func.lead(AircraftBeacon.track).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('track_next'),
AircraftBeacon.ground_speed,
func.lag(AircraftBeacon.ground_speed).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('ground_speed_prev'),
func.lead(AircraftBeacon.ground_speed).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('ground_speed_next'),
func.lag(AircraftBeacon.ground_speed).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('ground_speed_prev'),
func.lead(AircraftBeacon.ground_speed).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('ground_speed_next'),
AircraftBeacon.altitude,
func.lag(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_prev'),
func.lead(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.address, AircraftBeacon.timestamp)).label('altitude_next')) \
func.lag(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('altitude_prev'),
func.lead(AircraftBeacon.altitude).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('altitude_next'),
AircraftBeacon.device_id,
func.lag(AircraftBeacon.device_id).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('device_id_prev'),
func.lead(AircraftBeacon.device_id).over(order_by=and_(AircraftBeacon.device_id, AircraftBeacon.timestamp)).label('device_id_next')) \
.filter(AircraftBeacon.timestamp >= begin_computation) \
.filter(AircraftBeacon.timestamp <= end_computation) \
.order_by(func.date(AircraftBeacon.timestamp), AircraftBeacon.address, AircraftBeacon.timestamp) \
.subquery()
# find takeoffs and landings
takeoff_landing_query = app.session.query(
sq.c.address,
sq.c.name,
sq.c.receiver_name,
# find possible takeoffs and landings
sq2 = app.session.query(
sq.c.timestamp,
sq.c.location,
sq.c.track,
case([(sq.c.ground_speed > takeoff_speed, sq.c.location_wkt_prev), # on takeoff we take the location from the previous fix because it is nearer to the airport
(sq.c.ground_speed < landing_speed, sq.c.location)]).label('location'),
case([(sq.c.ground_speed > takeoff_speed, sq.c.track),
(sq.c.ground_speed < landing_speed, sq.c.track_prev)]).label('track'), # on landing we take the track from the previous fix because gliders tend to leave the runway quickly
sq.c.ground_speed,
sq.c.altitude,
case([(sq.c.ground_speed > takeoff_speed, True),
(sq.c.ground_speed < landing_speed, False)]).label('is_takeoff')) \
.filter(sq.c.address_prev == sq.c.address == sq.c.address_next) \
(sq.c.ground_speed < landing_speed, False)]).label('is_takeoff'),
sq.c.device_id) \
.filter(sq.c.device_id_prev == sq.c.device_id == sq.c.device_id_next) \
.filter(or_(and_(sq.c.ground_speed_prev < takeoff_speed, # takeoff
sq.c.ground_speed > takeoff_speed,
sq.c.ground_speed_next > takeoff_speed),
@ -95,10 +92,26 @@ def compute_takeoff_and_landing():
.filter(sq.c.timestamp_next - sq.c.timestamp_prev < timedelta(seconds=duration)) \
.filter(and_(func.ST_DFullyWithin(sq.c.location, sq.c.location_wkt_prev, radius),
func.ST_DFullyWithin(sq.c.location, sq.c.location_wkt_next, radius))) \
.order_by(func.date(sq.c.timestamp), sq.c.timestamp)
.subquery()
# consider them if they are near a airport
takeoff_landing_query = app.session.query(
sq2.c.timestamp,
sq2.c.track,
sq2.c.is_takeoff,
sq2.c.device_id,
Airport.id) \
.filter(and_(func.ST_DFullyWithin(sq2.c.location, Airport.location_wkt, airport_radius),
between(sq2.c.altitude, Airport.altitude - airport_delta, Airport.altitude + airport_delta))) \
.filter(between(Airport.style, 2, 5))
# ... and save them
ins = insert(TakeoffLanding).from_select((TakeoffLanding.address, TakeoffLanding.name, TakeoffLanding.receiver_name, TakeoffLanding.timestamp, TakeoffLanding.location_wkt, TakeoffLanding.track, TakeoffLanding.ground_speed, TakeoffLanding.altitude, TakeoffLanding.is_takeoff), takeoff_landing_query)
ins = insert(TakeoffLanding).from_select((TakeoffLanding.timestamp,
TakeoffLanding.track,
TakeoffLanding.is_takeoff,
TakeoffLanding.device_id,
TakeoffLanding.airport_id),
takeoff_landing_query)
result = app.session.execute(ins)
counter = result.rowcount
app.session.commit()

Wyświetl plik

@ -1,6 +1,6 @@
from sqlalchemy.sql import func, null
from sqlalchemy.sql.functions import coalesce
from sqlalchemy import and_, not_
from sqlalchemy import and_, not_, or_
from celery.utils.log import get_task_logger
@ -25,6 +25,7 @@ def update_receivers():
.group_by(ReceiverBeacon.name) \
.subquery()
# update receivers
receivers_to_update = app.session.query(ReceiverBeacon.name,
ReceiverBeacon.location_wkt,
ReceiverBeacon.altitude,
@ -35,25 +36,23 @@ def update_receivers():
ReceiverBeacon.timestamp == last_receiver_beacon_sq.columns.lastseen)) \
.subquery()
# set country code to None if lat or lon changed
count = app.session.query(Receiver) \
.filter(and_(Receiver.name == receivers_to_update.columns.name,
not_(func.ST_Equals(Receiver.location_wkt, receivers_to_update.columns.location)))) \
# ... set country code to None if lat or lon changed
changed_count = app.session.query(Receiver) \
.filter(Receiver.name == receivers_to_update.columns.name) \
.filter(or_(not_(func.ST_Equals(Receiver.location_wkt, receivers_to_update.columns.location)),
and_(Receiver.location_wkt == null(),
receivers_to_update.columns.location != null()))) \
.update({"location_wkt": receivers_to_update.columns.location,
"country_code": null()},
synchronize_session=False)
logger.info("Count of receivers who changed lat or lon: {}".format(count))
# update lastseen of known receivers
count = app.session.query(Receiver) \
.filter(Receiver.name == receivers_to_update.columns.name) \
.update({"altitude": receivers_to_update.columns.altitude,
"lastseen": receivers_to_update.columns.lastseen,
"version": receivers_to_update.columns.version,
"platform": receivers_to_update.columns.platform})
logger.info("Count of receivers who where updated: {}".format(count))
# ... and update altitude, lastseen, version and platform
update_count = app.session.query(Receiver) \
.filter(Receiver.name == receivers_to_update.columns.name) \
.update({"altitude": receivers_to_update.columns.altitude,
"lastseen": receivers_to_update.columns.lastseen,
"version": receivers_to_update.columns.version,
"platform": receivers_to_update.columns.platform})
# add new receivers
empty_sq = app.session.query(ReceiverBeacon.name,
@ -88,20 +87,25 @@ def update_receivers():
.group_by(Receiver.name) \
.subquery()
count = app.session.query(Receiver) \
.filter(Receiver.name == firstseen_null_query.columns.name) \
.update({'firstseen': firstseen_null_query.columns.firstseen})
logger.info("Total: {} receivers added".format(count))
added_count = app.session.query(Receiver) \
.filter(Receiver.name == firstseen_null_query.columns.name) \
.update({'firstseen': firstseen_null_query.columns.firstseen})
# update country code if None
unknown_country_query = app.session.query(Receiver) \
.filter(Receiver.country_code == null()) \
.filter(Receiver.location_wkt != null()) \
.order_by(Receiver.name)
for receiver in unknown_country_query.all():
location = receiver.location
receiver.country_code = get_country_code(location.latitude, location.longitude)
if receiver.country_code is not None:
country_code = get_country_code(location.latitude, location.longitude)
if country_code is not None:
receiver.country_code = country_code
logger.info("Updated country_code for {} to {}".format(receiver.name, receiver.country_code))
logger.info("Added: {}, location changed: {}".format(added_count, changed_count))
app.session.commit()
return update_count

Wyświetl plik

@ -1,4 +1,5 @@
from .database import manager as database_manager
from .showairport import manager as show_airport_manager
from .showreceiver import manager as show_receiver_manager
from .showdevices import manager as show_devices_manager
from .logbook import manager as logbook_manager
@ -8,6 +9,7 @@ from manager import Manager
manager = Manager()
manager.merge(database_manager, namespace='db')
manager.merge(show_airport_manager, namespace='show.airport')
manager.merge(show_receiver_manager, namespace='show.receiver')
manager.merge(show_devices_manager, namespace='show.devices')
manager.merge(logbook_manager, namespace='logbook')

Wyświetl plik

@ -16,6 +16,8 @@ def init():
from alembic.config import Config
from alembic import command
session.execute('CREATE EXTENSION IF NOT EXISTS postgis;')
session.commit()
Base.metadata.create_all(engine)
alembic_cfg = Config(ALEMBIC_CONFIG_FILE)
command.stamp(alembic_cfg, "head")
@ -64,7 +66,7 @@ def import_file(path='tests/custom_ddb.txt'):
@manager.command
def import_airports(path='tests/Germany.cup'):
def import_airports(path='tests/SeeYou.cup'):
"""Import airports from a ".cup" file"""
print("Import airports from '{}'...".format(path))

Wyświetl plik

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from datetime import timedelta
from datetime import timedelta, datetime
from sqlalchemy.sql import func, null
from sqlalchemy import and_, or_
from sqlalchemy.sql.expression import true, false, label
from sqlalchemy.orm import aliased
from ogn.model import Device, TakeoffLanding, Airport
@ -24,8 +25,10 @@ def compute():
print("New/recalculated takeoffs/landings: {}".format(counter))
@manager.arg('date', help='date (format: yyyy-mm-dd')
@manager.arg('utc_delta_hours', help='delta hours to utc (for local time logs)')
@manager.command
def show(airport_name):
def show(airport_name, utc_delta_hours=0, date=None):
"""Show a logbook for <airport_name>."""
airport = session.query(Airport) \
.filter(Airport.name == airport_name) \
@ -35,110 +38,152 @@ def show(airport_name):
print('Airport "{}" not found.'.format(airport_name))
return
delta_altitude = 200
delta_radius = 0.01 # degree!
utc_timedelta = timedelta(hours=utc_delta_hours)
or_args = []
if date is not None:
date = datetime.strptime(date, "%Y-%m-%d")
or_args = [and_(TakeoffLanding.timestamp >= date + utc_timedelta,
TakeoffLanding.timestamp < date + timedelta(hours=24) + utc_timedelta)]
# make a query with current, previous and next "takeoff_landing" event, so we can find complete flights
sq = session.query(
TakeoffLanding.address,
func.lag(TakeoffLanding.address)
.over(
order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('address_prev'),
func.lead(TakeoffLanding.address)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('address_next'),
TakeoffLanding.timestamp,
TakeoffLanding.device_id,
func.lag(TakeoffLanding.device_id)
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('device_id_prev'),
func.lead(TakeoffLanding.device_id)
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('device_id_next'),
(TakeoffLanding.timestamp + utc_timedelta).label('timestamp'),
func.lag(TakeoffLanding.timestamp)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('timestamp_prev'),
func.lead(TakeoffLanding.timestamp)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('timestamp_next'),
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('timestamp_prev'),
func.lead(TakeoffLanding.timestamp + utc_timedelta)
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('timestamp_next'),
TakeoffLanding.track,
func.lag(TakeoffLanding.track)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('track_prev'),
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('track_prev'),
func.lead(TakeoffLanding.track)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('track_next'),
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('track_next'),
TakeoffLanding.is_takeoff,
func.lag(TakeoffLanding.is_takeoff)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('is_takeoff_prev'),
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('is_takeoff_prev'),
func.lead(TakeoffLanding.is_takeoff)
.over(order_by=and_(func.date(TakeoffLanding.timestamp),
TakeoffLanding.address,
TakeoffLanding.timestamp))
.label('is_takeoff_next')) \
.filter(func.ST_DFullyWithin(TakeoffLanding.location_wkt, Airport.location_wkt, delta_radius)) \
.filter(TakeoffLanding.altitude < Airport.altitude + delta_altitude) \
.filter(Airport.name == airport.name) \
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('is_takeoff_next'),
TakeoffLanding.airport_id,
func.lag(TakeoffLanding.airport_id)
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('airport_id_prev'),
func.lead(TakeoffLanding.airport_id)
.over(order_by=and_(func.date(TakeoffLanding.timestamp + utc_timedelta),
TakeoffLanding.device_id,
TakeoffLanding.timestamp + utc_timedelta))
.label('airport_id_next')) \
.filter(*or_args) \
.subquery()
# find complete flights (with takeoff and landing) with duration < 1 day
complete_flight_query = session.query(sq.c.timestamp.label('reftime'), sq.c.address.label('address'), sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), sq.c.timestamp_next.label('landing'), sq.c.track_next.label('landing_track'), label('duration', sq.c.timestamp_next - sq.c.timestamp)) \
# find complete flights (with takeoff and landing on the same day)
complete_flight_query = session.query(sq.c.timestamp.label('reftime'),
sq.c.device_id.label('device_id'),
sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), sq.c.airport_id.label('takeoff_airport_id'),
sq.c.timestamp_next.label('landing'), sq.c.track_next.label('landing_track'), sq.c.airport_id_next.label('landing_airport_id'),
label('duration', sq.c.timestamp_next - sq.c.timestamp)) \
.filter(and_(sq.c.is_takeoff == true(), sq.c.is_takeoff_next == false())) \
.filter(sq.c.address == sq.c.address_next) \
.filter(sq.c.timestamp_next - sq.c.timestamp < timedelta(days=1))
.filter(sq.c.device_id == sq.c.device_id_next) \
.filter(func.date(sq.c.timestamp_next) == func.date(sq.c.timestamp)) \
.filter(or_(sq.c.airport_id == airport.id,
sq.c.airport_id_next == airport.id))
# split complete flights (with takeoff and landing) with duration > 1 day into one takeoff and one landing
split_start_query = session.query(sq.c.timestamp.label('reftime'), sq.c.address.label('address'), sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), null().label('landing'), null().label('landing_track'), null().label('duration')) \
# split complete flights (with takeoff and landing on different days) into one takeoff and one landing
split_start_query = session.query(sq.c.timestamp.label('reftime'),
sq.c.device_id.label('device_id'),
sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), sq.c.airport_id.label('takeoff_airport_id'),
null().label('landing'), null().label('landing_track'), null().label('landing_airport_id'),
null().label('duration')) \
.filter(and_(sq.c.is_takeoff == true(), sq.c.is_takeoff_next == false())) \
.filter(sq.c.address == sq.c.address_next) \
.filter(sq.c.timestamp_next - sq.c.timestamp >= timedelta(days=1))
.filter(sq.c.device_id == sq.c.device_id_next) \
.filter(func.date(sq.c.timestamp_next) != func.date(sq.c.timestamp)) \
.filter(and_(sq.c.airport_id == airport.id,
sq.c.airport_id_next == airport.id))
split_landing_query = session.query(sq.c.timestamp_next.label('reftime'), sq.c.address.label('address'), null().label('takeoff'), null().label('takeoff_track'), sq.c.timestamp_next.label('landing'), sq.c.track_next.label('landing_track'), null().label('duration')) \
split_landing_query = session.query(sq.c.timestamp_next.label('reftime'),
sq.c.device_id.label('device_id'),
null().label('takeoff'), null().label('takeoff_track'), null().label('takeoff_airport_id'),
sq.c.timestamp_next.label('landing'), sq.c.track_next.label('landing_track'), sq.c.airport_id_next.label('landing_airport_id'),
null().label('duration')) \
.filter(and_(sq.c.is_takeoff == true(), sq.c.is_takeoff_next == false())) \
.filter(sq.c.address == sq.c.address_next) \
.filter(sq.c.timestamp_next - sq.c.timestamp >= timedelta(days=1))
.filter(sq.c.device_id == sq.c.device_id_next) \
.filter(func.date(sq.c.timestamp_next) != func.date(sq.c.timestamp)) \
.filter(and_(sq.c.airport_id == airport.id,
sq.c.airport_id_next == airport.id))
# find landings without start
only_landings_query = session.query(sq.c.timestamp.label('reftime'), sq.c.address.label('address'), null().label('takeoff'), null().label('takeoff_track'), sq.c.timestamp.label('landing'), sq.c.track_next.label('landing_track'), null().label('duration')) \
only_landings_query = session.query(sq.c.timestamp.label('reftime'),
sq.c.device_id.label('device_id'),
null().label('takeoff'), null().label('takeoff_track'), null().label('takeoff_airport_id'),
sq.c.timestamp.label('landing'), sq.c.track_next.label('landing_track'), sq.c.airport_id_next.label('landing_airport_id'),
null().label('duration')) \
.filter(sq.c.is_takeoff == false()) \
.filter(or_(sq.c.address != sq.c.address_prev,
sq.c.is_takeoff_prev == false()))
.filter(or_(sq.c.device_id != sq.c.device_id_prev,
sq.c.is_takeoff_prev == false())) \
.filter(sq.c.airport_id_next == airport.id)
# find starts without landing
only_starts_query = session.query(sq.c.timestamp.label('reftime'), sq.c.address.label('address'), sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), null().label('landing'), null().label('landing_track'), null().label('duration')) \
only_starts_query = session.query(sq.c.timestamp.label('reftime'),
sq.c.device_id.label('device_id'),
sq.c.timestamp.label('takeoff'), sq.c.track.label('takeoff_track'), sq.c.airport_id.label('takeoff_airport_id'),
null().label('landing'), null().label('landing_track'), null().label('landing_airport_id'),
null().label('duration')) \
.filter(sq.c.is_takeoff == true()) \
.filter(or_(sq.c.address != sq.c.address_next,
sq.c.is_takeoff_next == true()))
.filter(or_(sq.c.device_id != sq.c.device_id_next,
sq.c.is_takeoff_next == true())) \
.filter(sq.c.airport_id == airport.id)
# unite all
union_query = complete_flight_query.union(
split_start_query,
split_landing_query,
only_landings_query,
only_starts_query) \
union_query = complete_flight_query.union(split_start_query,
split_landing_query,
only_landings_query,
only_starts_query) \
.subquery()
# get aircraft informations and sort all entries by the reference time
logbook_query = session.query(
union_query.c.reftime,
union_query.c.address,
union_query.c.takeoff,
union_query.c.takeoff_track,
union_query.c.landing,
union_query.c.landing_track,
union_query.c.duration,
Device.registration,
Device.aircraft) \
.outerjoin(Device, union_query.c.address == Device.address) \
# get aircraft and airport informations and sort all entries by the reference time
takeoff_airport = aliased(Airport, name='takeoff_airport')
landing_airport = aliased(Airport, name='landing_airport')
logbook_query = session.query(union_query.c.reftime,
union_query.c.takeoff,
union_query.c.takeoff_track,
takeoff_airport,
union_query.c.landing,
union_query.c.landing_track,
landing_airport,
union_query.c.duration,
Device) \
.outerjoin(Device, union_query.c.device_id == Device.id) \
.outerjoin(takeoff_airport, union_query.c.takeoff_airport_id == takeoff_airport.id) \
.outerjoin(landing_airport, union_query.c.landing_airport_id == landing_airport.id) \
.order_by(union_query.c.reftime)
print('--- Logbook ({}) ---'.format(airport_name))
@ -152,19 +197,28 @@ def show(airport_name):
def none_timedelta_replacer(timedelta_object):
return '--:--:--' if timedelta_object is None else timedelta_object
def none_registration_replacer(registration_object, address):
return '[' + address + ']' if registration_object is None else registration_object
def none_registration_replacer(device_object):
return '[' + device_object.address + ']' if device_object.registration is None else device_object.registration
def none_aircraft_replacer(aircraft_object):
return '(unknown)' if aircraft_object is None else aircraft_object
def none_aircraft_replacer(device_object):
return '(unknown)' if device_object.aircraft is None else device_object.aircraft
for [reftime, address, takeoff, takeoff_track, landing, landing_track, duration, registration, aircraft] in logbook_query.all():
print('%10s %8s (%2s) %8s (%2s) %8s %8s %s' % (
def airport_marker(takeoff_airport_object, landing_airport_object):
if takeoff_airport_object is not None and takeoff_airport_object.name is not airport.name:
return ('FROM: {}'.format(takeoff_airport_object.name))
elif landing_airport_object is not None and landing_airport_object.name is not airport.name:
return ('TO: {}'.format(landing_airport_object.name))
else:
return ('')
for [reftime, takeoff, takeoff_track, takeoff_airport, landing, landing_track, landing_airport, duration, device] in logbook_query.all():
print('%10s %8s (%2s) %8s (%2s) %8s %8s %17s %20s' % (
reftime.date(),
none_datetime_replacer(takeoff),
none_track_replacer(takeoff_track),
none_datetime_replacer(landing),
none_track_replacer(landing_track),
none_timedelta_replacer(duration),
none_registration_replacer(registration, address),
none_aircraft_replacer(aircraft)))
none_registration_replacer(device),
none_aircraft_replacer(device),
airport_marker(takeoff_airport, landing_airport)))

Wyświetl plik

@ -0,0 +1,16 @@
from ogn.model import Airport
from ogn.commands.dbutils import session
from manager import Manager
manager = Manager()
@manager.command
def list_all():
"""Show a list of all airports."""
query = session.query(Airport) \
.order_by(Airport.name)
print('--- Airports ---')
for airport in query.all():
print(airport.name)

Wyświetl plik

@ -1,7 +1,8 @@
import logging
from ogn.commands.dbutils import session
from ogn.model import AircraftBeacon, ReceiverBeacon, Location
from ogn.model import AircraftBeacon, ReceiverBeacon, Device, Receiver, Location
from ogn.parser import parse_aprs, parse_ogn_receiver_beacon, parse_ogn_aircraft_beacon, ParseError
from ogn.model.address_origin import AddressOrigin
logger = logging.getLogger(__name__)
@ -32,13 +33,48 @@ def process_beacon(raw_message):
# /z: ?
# /o: ?
if message['symboltable'] == "I" and message['symbolcode'] == '&':
# ... we have a receiver_beacon
message.update(parse_ogn_receiver_beacon(message['comment']))
message = replace_lonlat_with_wkt(message)
beacon = ReceiverBeacon(**message)
# connect beacon with receiver
receiver = session.query(Receiver.id) \
.filter(Receiver.name == beacon.name) \
.first()
if receiver is None:
receiver = Receiver()
receiver.name = beacon.name
session.add(receiver)
beacon.receiver_id = receiver.id
else:
# ... we have a aircraft_beacon
message.update(parse_ogn_aircraft_beacon(message['comment']))
message = replace_lonlat_with_wkt(message)
beacon = AircraftBeacon(**message)
# connect beacon with device
device = session.query(Device.id) \
.filter(Device.address == beacon.address) \
.order_by(Device.address_origin) \
.first()
if device is None:
device = Device()
device.address = beacon.address
device.address_origin = AddressOrigin.seen
session.add(device)
beacon.device_id = device.id
# connect beacon with receiver
receiver = session.query(Receiver.id) \
.filter(Receiver.name == beacon.receiver_name) \
.first()
if receiver is None:
receiver = Receiver()
receiver.name = beacon.receiver_name
session.add(receiver)
beacon.receiver_id = receiver.id
session.add(beacon)
session.commit()
logger.debug('Received message: {}'.format(raw_message))

Wyświetl plik

@ -2,9 +2,10 @@ class AddressOrigin:
ogn_ddb = 1
flarmnet = 2
user_defined = 3
seen = 4
def __init__(self, origin):
if origin in [1, 2, 3]:
if origin in [1, 2, 3, 4]:
self.origin = origin
else:
raise ValueError('no address origin with id {} known'.format(origin))
@ -16,4 +17,6 @@ class AddressOrigin:
return 'FlarmNet'
elif self.origin == self.user_defined:
return 'user-defined'
elif self.origin == self.seen:
return 'seen'
return ''

Wyświetl plik

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Float, Boolean, SmallInteger
from sqlalchemy import Column, String, Integer, Float, Boolean, SmallInteger, ForeignKey
from sqlalchemy.orm import relationship
from .beacon import Beacon
@ -8,9 +9,9 @@ class AircraftBeacon(Beacon):
# Flarm specific data
address_type = Column(SmallInteger)
aircraft_type = Column(SmallInteger)
aircraft_type = Column(SmallInteger, index=True)
stealth = Column(Boolean)
address = Column(String(6), index=True)
address = Column(String(6))
climb_rate = Column(Float)
turn_rate = Column(Float)
signal_strength = Column(Float)
@ -24,6 +25,13 @@ class AircraftBeacon(Beacon):
flightlevel = Column(Float)
# Relations
receiver_id = Column(Integer, ForeignKey('receiver.id', ondelete='SET NULL'), index=True)
receiver = relationship('Receiver', foreign_keys=[receiver_id])
device_id = Column(Integer, ForeignKey('device.id', ondelete='SET NULL'), index=True)
device = relationship('Device', foreign_keys=[device_id])
def __repr__(self):
return "<AircraftBeacon %s: %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s>" % (
self.name,

Wyświetl plik

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Float, SmallInteger
from sqlalchemy.orm import relationship
from geoalchemy2.types import Geometry
from .base import Base
@ -13,7 +14,7 @@ class Airport(Base):
altitude = Column(Integer)
name = Column(String, index=True)
code = Column(String(5))
code = Column(String(6))
country_code = Column(String(2))
style = Column(SmallInteger)
description = Column(String)
@ -21,6 +22,9 @@ class Airport(Base):
runway_length = Column(Integer)
frequency = Column(Float)
# Relations
takeoff_landings = relationship('TakeoffLanding')
def __repr__(self):
return "<Airport %s: %s,%s,%s,%s,%s,%s,%s,%s,%s,% s>" % (
self.name,

Wyświetl plik

@ -1,4 +1,5 @@
from sqlalchemy import Column, Integer, String, Unicode, Boolean, SmallInteger
from sqlalchemy.orm import relationship
from .base import Base
@ -17,9 +18,13 @@ class Device(Base):
frequency = Column(String)
tracked = Column(Boolean)
identified = Column(Boolean)
aircraft_type = Column(SmallInteger, index=True)
address_origin = Column(SmallInteger)
# Relations
aircraft_beacons = relationship('AircraftBeacon')
def __repr__(self):
return "<Device: %s,%s,%s,%s,%s,%s,%s,%s,%s,%s>" % (
self.address_type,

Wyświetl plik

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, DateTime
from sqlalchemy.orm import relationship
from geoalchemy2.types import Geometry
from geoalchemy2.shape import to_shape
@ -21,6 +22,10 @@ class Receiver(Base):
version = Column(String)
platform = Column(String)
# Relations
aircraft_beacons = relationship('AircraftBeacon')
receiver_beacons = relationship('ReceiverBeacon')
@property
def location(self):
if self.location_wkt is None:

Wyświetl plik

@ -1,4 +1,5 @@
from sqlalchemy import Column, Float, String
from sqlalchemy import Column, Float, String, Integer, ForeignKey
from sqlalchemy.orm import relationship
from .beacon import Beacon
@ -20,5 +21,9 @@ class ReceiverBeacon(Beacon):
rec_crystal_correction_fine = 0 # obsolete since 0.2.0
rec_input_noise = Column(Float)
# Relations
receiver_id = Column(Integer, ForeignKey('receiver.id', ondelete='SET NULL'), index=True)
receiver = relationship('Receiver', foreign_keys=[receiver_id])
def __repr__(self):
return "<ReceiverBeacon %s: %s>" % (self.name, self.version)

Wyświetl plik

@ -1,10 +1,21 @@
from sqlalchemy import Column, String, Boolean
from sqlalchemy import Boolean, Column, Integer, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from .beacon import Beacon
from .base import Base
class TakeoffLanding(Beacon):
class TakeoffLanding(Base):
__tablename__ = 'takeoff_landing'
address = Column(String(6), index=True)
id = Column(Integer, primary_key=True)
timestamp = Column(DateTime, index=True)
track = Column(Integer)
is_takeoff = Column(Boolean)
# Relations
airport_id = Column(Integer, ForeignKey('airport.id', ondelete='SET NULL'), index=True)
airport = relationship('Airport', foreign_keys=[airport_id])
device_id = Column(Integer, ForeignKey('device.id', ondelete='SET NULL'), index=True)
device = relationship('Device', foreign_keys=[device_id])

Wyświetl plik

@ -2,7 +2,7 @@ import requests
import csv
from io import StringIO
from .model import Device, AddressOrigin, Airport, Location
from .model import Device, Airport, Location
from geopy.geocoders import Nominatim
from geopy.exc import GeopyError
@ -10,7 +10,7 @@ from geopy.exc import GeopyError
from aerofiles.seeyou import Reader
from ogn.parser.utils import feet2m
DDB_URL = "http://ddb.glidernet.org/download"
DDB_URL = "http://ddb.glidernet.org/download/?t=1"
address_prefixes = {'F': 'FLR',
@ -25,28 +25,25 @@ def get_ddb(csvfile=None):
if csvfile is None:
r = requests.get(DDB_URL)
rows = '\n'.join(i for i in r.text.splitlines() if i[0] != '#')
address_origin = AddressOrigin.ogn_ddb
else:
r = open(csvfile, 'r')
rows = ''.join(i for i in r.readlines() if i[0] != '#')
address_origin = AddressOrigin.user_defined
data = csv.reader(StringIO(rows), quotechar="'", quoting=csv.QUOTE_ALL)
devices = list()
for row in data:
flarm = Device()
flarm.address_type = row[0]
flarm.address = row[1]
flarm.aircraft = row[2]
flarm.registration = row[3]
flarm.competition = row[4]
flarm.tracked = row[5] == 'Y'
flarm.identified = row[6] == 'Y'
device = Device()
device.address_type = row[0]
device.address = row[1]
device.aircraft = row[2]
device.registration = row[3]
device.competition = row[4]
device.tracked = row[5] == 'Y'
device.identified = row[6] == 'Y'
device.aircraft_type = int(row[7])
flarm.address_origin = address_origin
devices.append(flarm)
devices.append(device)
return devices
@ -77,6 +74,9 @@ def get_airports(cupfile):
for line in f:
try:
for waypoint in Reader([line]):
if waypoint['style'] > 5: # reject unlandable places
continue
airport = Airport()
airport.name = waypoint['name']
airport.code = waypoint['code']

Wyświetl plik

@ -40,16 +40,14 @@ setup(
'aerofiles==0.3',
'geoalchemy2==0.3.0',
'shapely==1.5.15',
'ogn-client==0.3.0'
'ogn-client==0.3.0',
'psycopg2==2.6.1'
],
extras_require={
'dev': [
'nose==1.3.7',
'coveralls==0.4.4',
'flake8==2.5.0'
],
'postgresql': [
'psycopg2==2.6.1'
]
},
zip_safe=False

Wyświetl plik

@ -1,966 +0,0 @@
"Aachen Merzbruck",,DE,5049.383N,00611.183E,189.0m,5,080,520.0m,122.875,"Flugplatz"
"Aalen Heidenheim",,DE,4846.667N,01015.883E,585.0m,5,090,1000.0m,121.400,"Flugplatz"
"Achmer",,DE,5222.633N,00754.800E,53.0m,2,070,940.0m,123.050,"Flugplatz"
"Achterstedt Prv",,DE,5323.850N,00819.783E,1.0m,2,080,460.0m,123.425,"Flugplatz"
"Agathazeller Moo",,DE,4733.300N,01016.367E,727.0m,5,180,450.0m,123.350,"Flugplatz"
"Ahlen Nord Heli",,DE,5147.083N,00754.750E,88.0m,2,070,1060.0m,130.075,"Flugplatz"
"Ahlhorn",,DE,5253.333N,00813.950E,47.0m,5,090,2100.0m,122.100,"Flugplatz"
"Ahrenlohe",,DE,5342.000N,00944.483E,7.0m,5,050,600.0m,122.600,"Flugplatz"
"Aichach",,DE,4828.400N,01108.133E,439.0m,4,020,430.0m,122.300,"Flugplatz"
"Aichelberg X",,DE,4839.967N,00831.183E,798.0m,3,310,250.0m,,"Landefeld"
"Aichhalden",,DE,4838.667N,00832.717E,755.0m,3,020,300.0m,,"Landefeld"
"Ailertchen",,DE,5035.550N,00756.667E,469.0m,2,040,550.0m,123.050,"Flugplatz"
"Albstadt Deger",,DE,4814.983N,00903.833E,891.0m,2,090,960.0m,125.100,"Flugplatz"
"Allendorf",,DE,5102.100N,00840.850E,354.0m,5,110,1240.0m,118.175,"Flugplatz"
"Allstedt",,DE,5122.833N,01126.800E,284.0m,5,070,1200.0m,122.000,"Flugplatz"
"Alsfeld",,DE,5045.033N,00914.917E,292.0m,4,060,650.0m,123.500,"Flugplatz"
"Altenbachtal",,DE,4955.367N,00909.483E,130.0m,4,070,600.0m,126.500,"Segelflug"
"Altdorf Hagenhau",,DE,4923.217N,01125.267E,538.0m,4,050,500.0m,129.975,"Flugplatz"
"Altdorf Wallburg",,DE,4816.200N,00750.533E,194.0m,2,070,840.0m,127.150,"Flugplatz"
"Alte Ems Herbrum",,DE,5301.850N,00718.333E,1.0m,4,100,720.0m,123.150,"Segelflug"
"Altena Hegensche",,DE,5118.783N,00742.217E,473.0m,2,060,600.0m,122.200,"Flugplatz"
"Leipzig-Altenbur",,DE,5058.917N,01230.383E,195.0m,5,040,2230.0m,123.575,"Flugplatz"
"Altenstadt Mil",,DE,4750.133N,01052.267E,741.0m,2,090,680.0m,122.100,"Flugplatz"
"Altfeld",,DE,4949.917N,00932.233E,354.0m,5,100,560.0m,130.125,"Flugplatz"
"Altomuenster Ul",,DE,4822.900N,01116.383E,496.0m,3,020,200.0m,123.425,"Landefeld"
"Altoetting",,DE,4812.967N,01238.900E,398.0m,4,090,540.0m,123.500,"Flugplatz"
"Amberg 29 Rwy",,DE,4926.383N,01148.750E,391.0m,3,290,280.0m,123.350,"Landefeld"
"Amberg Rammerts",,DE,4926.350N,01148.383E,388.0m,4,080,710.0m,123.350,"Flugplatz"
"Am Deister Lauen",,DE,5217.650N,00922.667E,116.0m,3,090,350.0m,123.425,"Landefeld"
"Amoeneburg",,DE,5047.433N,00854.483E,230.0m,4,050,620.0m,122.475,"Flugplatz"
"Ampfing Waldkra",,DE,4815.800N,01224.733E,415.0m,2,090,890.0m,123.600,"Flugplatz"
"Am Salzgittersee",,DE,5210.217N,01018.950E,81.0m,4,050,720.0m,130.125,"Flugplatz"
"Am Stauffenberg",,DE,5121.717N,00937.767E,369.0m,4,090,330.0m,123.500,"Flugplatz"
"Anklam",,DE,5349.967N,01340.133E,6.0m,5,090,1000.0m,122.650,"Flugplatz"
"Ansbach Petersdo",,DE,4921.650N,01040.100E,418.0m,2,090,780.0m,123.650,"Flugplatz"
"Ansbach Mil Heli",,DE,4918.483N,01038.317E,466.0m,5,080,370.0m,122.100,"Flugplatz"
"An Den 7 Bergen",,DE,5203.450N,00948.633E,135.0m,4,080,570.0m,123.500,"Flugplatz"
"Anspach Taunus",,DE,5017.333N,00832.117E,335.0m,2,060,580.0m,121.025,"Flugplatz"
"Antdorf",,DE,4745.600N,01118.267E,615.0m,3,080,480.0m,,"Landefeld"
"Antersberg",,DE,4757.767N,01159.767E,498.0m,4,130,980.0m,123.350,"Flugplatz"
"Argenbuehl Eisen",,DE,4741.483N,00957.783E,684.0m,3,080,400.0m,123.425,"Landefeld"
"Arnbruck",,DE,4907.533N,01259.117E,524.0m,5,160,610.0m,118.550,"Flugplatz"
"Arnsberg Ruhrwie",,DE,5123.250N,00803.633E,185.0m,4,170,850.0m,123.400,"Flugplatz"
"Arnsberg-Menden",,DE,5129.017N,00753.883E,241.0m,5,050,920.0m,123.025,"Flugplatz"
"Arnschwang Ul",,DE,4916.300N,01246.700E,414.0m,3,050,400.0m,123.425,"Landefeld"
"Arnstadt Alkersl",,DE,5050.517N,01104.200E,351.0m,5,090,870.0m,123.000,"Flugplatz"
"Aschaffenburg",,DE,4956.333N,00903.750E,125.0m,5,080,840.0m,132.425,"Flugplatz"
"Aschersleben",,DE,5146.017N,01129.933E,162.0m,2,110,1050.0m,123.375,"Flugplatz"
"Asslarer Huette",,DE,5035.983N,00826.633E,232.0m,4,170,590.0m,129.975,"Flugplatz"
"Attendorn Finnen",,DE,5108.750N,00756.183E,317.0m,2,030,560.0m,121.400,"Flugplatz"
"Aue Bei Hattorf",,DE,5138.000N,01015.283E,190.0m,4,100,1050.0m,122.200,"Flugplatz"
"Auerbach",,DE,5029.833N,01222.683E,573.0m,5,010,800.0m,122.700,"Flugplatz"
"Augsburg",,DE,4825.517N,01055.900E,463.0m,5,070,1590.0m,124.975,"Flugplatz"
"Aukrug",,DE,5403.883N,00947.900E,17.0m,4,110,1000.0m,123.350,"Flugplatz"
"Aurach",,DE,4742.000N,01155.450E,808.0m,3,180,310.0m,,"Landefeld"
"Aventoft",,DE,5453.767N,00849.233E,2.0m,4,090,970.0m,122.400,"Flugplatz"
"Babenhausen",,DE,4957.167N,00858.150E,133.0m,5,060,670.0m,123.200,"Flugplatz"
"Bad Bibra Ul",,DE,5112.133N,01129.867E,298.0m,3,090,600.0m,123.425,"Landefeld"
"Bad Berka",,DE,5054.233N,01115.517E,305.0m,2,070,700.0m,123.650,"Flugplatz"
"Bad Buchau Feder",,DE,4803.300N,00938.383E,579.0m,4,080,500.0m,123.150,"Flugplatz"
"Backnang Heinin",,DE,4855.200N,00927.300E,297.0m,2,110,500.0m,126.500,"Flugplatz"
"Bad Brueckenau",,DE,5016.317N,00949.417E,402.0m,4,130,550.0m,123.500,"Flugplatz"
"Bad Ditzenbach",,DE,4833.767N,00943.733E,730.0m,2,160,600.0m,122.350,"Flugplatz"
"Bad Duerkheim",,DE,4928.383N,00811.783E,107.0m,5,080,600.0m,122.400,"Flugplatz"
"Bad Endorf Jolli",,DE,4755.617N,01217.233E,514.0m,2,170,770.0m,122.500,"Flugplatz"
"Baden Oos",,DE,4847.450N,00811.050E,125.0m,2,030,790.0m,121.000,"Flugplatz"
"Bad Frankenhause",,DE,5122.367N,01108.583E,241.0m,2,080,650.0m,122.600,"Flugplatz"
"Bad Gandersheim",,DE,5151.150N,01001.567E,239.0m,2,170,720.0m,123.000,"Flugplatz"
"Bad Hersfeld",,DE,5050.667N,00942.433E,239.0m,5,010,670.0m,124.000,"Flugplatz"
"Bad Kissingen",,DE,5012.633N,01004.167E,198.0m,2,170,800.0m,122.000,"Flugplatz"
"Bad Koenigshofen",,DE,5017.250N,01025.317E,313.0m,4,070,700.0m,130.125,"Flugplatz"
"Bad Langensalza",,DE,5107.750N,01037.300E,199.0m,2,090,800.0m,130.125,"Flugplatz"
"Bad Marienberg",,DE,5039.650N,00801.717E,544.0m,4,110,860.0m,129.975,"Flugplatz"
"Bad Neuenahr Ahr",,DE,5033.467N,00708.233E,204.0m,5,100,500.0m,122.350,"Flugplatz"
"Bad Neustadt/Saa",,DE,5018.367N,01013.633E,303.0m,5,130,600.0m,123.650,"Flugplatz"
"Bad Rotenfels",,DE,4849.450N,00817.433E,129.0m,3,140,260.0m,,"Landefeld"
"Bad Sobernheim",,DE,4947.483N,00740.000E,244.0m,2,040,680.0m,118.925,"Flugplatz"
"Bad Waldsee Reu",,DE,4754.900N,00942.600E,577.0m,2,150,660.0m,123.000,"Flugplatz"
"Bad Windsheim",,DE,4930.617N,01021.967E,370.0m,2,080,690.0m,118.275,"Flugplatz"
"Bad Worishofen-N",,DE,4800.983N,01036.900E,619.0m,2,080,800.0m,122.600,"Flugplatz"
"Bad Zwischenahn",,DE,5312.617N,00759.317E,9.0m,4,090,900.0m,123.500,"Flugplatz"
"Baerental",,DE,4752.700N,00806.717E,906.0m,3,050,250.0m,,"Landefeld"
"Baiersbron Cls",,DE,4832.283N,00823.900E,507.0m,3,170,230.0m,,"Landefeld"
"Baiersbronn",,DE,4830.933N,00822.400E,574.0m,3,050,220.0m,,"Landefeld"
"Ballenstedt",,DE,5144.750N,01113.750E,153.0m,5,090,680.0m,122.700,"Flugplatz"
"Baltrum",,DE,5343.517N,00722.333E,3.0m,5,100,360.0m,123.050,"Flugplatz"
"Bamberg",,DE,4955.233N,01054.850E,250.0m,5,040,1140.0m,120.175,"Flugplatz"
"Barssel",,DE,5309.867N,00747.650E,3.0m,2,120,770.0m,122.000,"Flugplatz"
"Bartholoma Amali",,DE,4844.800N,01000.300E,637.0m,2,160,900.0m,122.200,"Flugplatz"
"Barth",,DE,5420.300N,01242.617E,6.0m,5,090,1200.0m,118.075,"Flugplatz"
"Bad Salzungen Ul",,DE,5049.017N,01013.083E,236.0m,3,090,500.0m,123.425,"Landefeld"
"Basepohl Mil Cls",,DE,5344.717N,01257.133E,50.0m,3,110,500.0m,122.100,"Landefeld"
"Baumerlenbach",,DE,4913.833N,00925.150E,236.0m,5,080,420.0m,123.150,"Flugplatz"
"Baumholder Mil",,DE,4939.100N,00718.433E,442.0m,5,070,550.0m,122.100,"Flugplatz"
"Bautzen",,DE,5111.617N,01431.183E,174.0m,5,070,2200.0m,120.600,"Flugplatz"
"Bad Wildungen",,DE,5105.633N,00908.900E,332.0m,4,010,980.0m,123.350,"Flugplatz"
"Bayreuth",,DE,4959.117N,01138.467E,482.0m,5,060,1080.0m,127.525,"Flugplatz"
"Bayrischzll",,DE,4740.083N,01201.100E,797.0m,3,170,300.0m,,"Landefeld"
"Becherbach Ul",,DE,4938.567N,00741.033E,421.0m,3,060,400.0m,123.425,"Landefeld"
"Beelen",,DE,5155.900N,00804.900E,59.0m,2,090,450.0m,123.500,"Flugplatz"
"Beilngries",,DE,4901.267N,01129.083E,365.0m,2,100,600.0m,118.350,"Flugplatz"
"Bell Hundheim",,DE,5001.650N,00725.317E,445.0m,3,040,360.0m,120.975,"Landefeld"
"Benediktbeuren",,DE,4742.950N,01123.433E,609.0m,4,090,750.0m,123.500,"Flugplatz"
"Bensheimer Stadt",,DE,4941.517N,00834.967E,93.0m,4,140,620.0m,123.375,"Flugplatz"
"Berg Ravensburg",,DE,4749.967N,00932.500E,594.0m,3,030,270.0m,120.975,"Landefeld"
"Berching",,DE,4907.900N,01126.617E,390.0m,2,020,850.0m,123.350,"Flugplatz"
"Bergheim",,DE,5058.617N,00636.500E,70.0m,4,140,1100.0m,130.125,"Flugplatz"
"Bergneustadt",,DE,5103.117N,00742.433E,481.0m,2,040,600.0m,123.650,"Flugplatz"
"Berliner Heide",,DE,5240.183N,01022.233E,69.0m,4,030,1070.0m,123.500,"Flugplatz"
"Berlin Tegel",,DE,5233.583N,01317.267E,37.0m,5,080,3020.0m,124.525,"Flugplatz"
"Berneck",,DE,4834.383N,00943.783E,746.0m,4,160,840.0m,123.475,"Flugplatz"
"Berlin Schonfeld",,DE,5222.717N,01331.233E,49.0m,5,070,3600.0m,119.575,"Flugplatz"
"Bernau",,DE,4748.283N,00801.783E,921.0m,3,100,250.0m,,"Landefeld"
"Besenbfeldn",,DE,4835.950N,00824.767E,818.0m,3,320,450.0m,,"Landefeld"
"Besenbfelds",,DE,4835.267N,00825.300E,790.0m,3,040,350.0m,,"Landefeld"
"Betzdorf Kirchen",,DE,5049.017N,00749.817E,351.0m,2,080,500.0m,122.750,"Flugplatz"
"Biberach Riss",,DE,4806.700N,00945.800E,580.0m,5,040,980.0m,122.750,"Flugplatz"
"Bielefeld",,DE,5157.883N,00832.683E,137.0m,5,110,1250.0m,118.350,"Flugplatz"
"Bienenfarm",,DE,5239.733N,01244.717E,27.0m,2,120,850.0m,122.850,"Flugplatz"
"Binningen",,DE,4747.967N,00843.217E,489.0m,2,060,860.0m,130.600,"Flugplatz"
"Bischofsberg",,DE,5025.933N,01017.000E,342.0m,4,080,900.0m,122.200,"Flugplatz"
"Bisperode West",,DE,5204.733N,00928.567E,194.0m,4,060,1130.0m,123.150,"Flugplatz"
"Bitburg",,DE,4956.717N,00633.900E,372.0m,5,050,3050.0m,118.700,"Flugplatz"
"Blaubeuren",,DE,4825.183N,00947.850E,677.0m,2,100,870.0m,130.600,"Flugplatz"
"BleXEn",,DE,5332.350N,00832.367E,3.0m,2,090,1000.0m,120.600,"Flugplatz"
"Blomberg Borkhau",,DE,5155.033N,00906.667E,182.0m,2,060,590.0m,118.925,"Flugplatz"
"Blumberg",,DE,4750.667N,00833.917E,701.0m,2,070,780.0m,123.050,"Flugplatz"
"Boberg",,DE,5330.883N,01008.650E,2.0m,4,120,1240.0m,133.500,"Flugplatz"
"Bobzin Scharbow",,DE,5329.167N,01110.100E,49.0m,5,100,600.0m,123.425,"Flugplatz"
"Boehlen",,DE,5112.967N,01222.100E,131.0m,2,060,950.0m,123.000,"Flugplatz"
"Boesingen Ul",,DE,4813.667N,00832.083E,694.0m,3,090,410.0m,123.425,"Landefeld"
"Bohlenberger Fel",,DE,5325.100N,00754.250E,6.0m,4,060,950.0m,129.500,"Flugplatz"
"Bohlhof",,DE,4739.050N,00823.200E,558.0m,4,040,800.0m,129.975,"Flugplatz"
"Bohmte Bad Essen",,DE,5221.067N,00819.683E,45.0m,2,100,580.0m,122.500,"Flugplatz"
"Bohlsbach",,DE,4830.117N,00756.933E,151.0m,3,100,330.0m,,"Landefeld"
"Bonn Hangelar",,DE,5046.133N,00709.767E,61.0m,5,110,800.0m,135.150,"Flugplatz"
"Bopfingen",,DE,4850.900N,01020.050E,619.0m,5,070,930.0m,122.850,"Flugplatz"
"Borghorst Fuecht",,DE,5209.017N,00727.117E,47.0m,4,060,460.0m,123.350,"Flugplatz"
"Borkheide",,DE,5214.033N,01250.833E,62.0m,3,170,820.0m,,"Landefeld"
"Borkenberge",,DE,5146.800N,00717.283E,49.0m,5,080,670.0m,135.000,"Flugplatz"
"Borken HoXFeld",,DE,5151.183N,00648.917E,49.0m,2,120,740.0m,122.925,"Flugplatz"
"Borkum",,DE,5335.650N,00642.967E,1.0m,5,130,1000.0m,123.000,"Flugplatz"
"Boschhof",,DE,4749.000N,01125.000E,597.0m,3,020,400.0m,,"Landefeld"
"Bottenhorn",,DE,5047.683N,00827.650E,516.0m,2,110,520.0m,123.800,"Flugplatz"
"Brannenburg",,DE,4744.333N,01206.967E,467.0m,4,170,400.0m,122.500,"Flugplatz"
"Brandis Wald Cls",,DE,5119.683N,01239.350E,165.0m,3,080,1380.0m,129.250,"Landefeld"
"Brakel Ul 25M",,DE,5144.333N,00912.150E,164.0m,3,080,300.0m,123.425,"Landefeld"
"Brandenburg Mue",,DE,5226.217N,01235.583E,28.0m,2,100,730.0m,118.625,"Flugplatz"
"Braunfels",,DE,5031.533N,00823.583E,240.0m,4,070,430.0m,123.150,"Flugplatz"
"Braunschweig",,DE,5219.150N,01033.267E,92.0m,5,080,2300.0m,120.050,"Flugplatz"
"Bredstedt",,DE,5438.000N,00859.133E,7.0m,3,010,420.0m,122.800,"Landefeld"
"Breitscheid",,DE,5040.617N,00810.183E,562.0m,5,070,780.0m,122.600,"Flugplatz"
"Bremen",,DE,5302.850N,00847.217E,3.0m,5,090,2040.0m,120.325,"Flugplatz"
"Bremgarten",,DE,4754.200N,00737.050E,213.0m,5,050,1660.0m,122.000,"Flugplatz"
"Bremerhaven",,DE,5330.417N,00834.383E,3.0m,5,160,1200.0m,129.050,"Flugplatz"
"Briesen Brand",,DE,5203.183N,01345.950E,70.0m,3,100,1000.0m,,"Landefeld"
"Brilon",,DE,5124.150N,00838.517E,460.0m,5,070,750.0m,129.375,"Flugplatz"
"Brauna Kamenz",,DE,5117.000N,01403.517E,190.0m,3,080,380.0m,122.475,"Landefeld"
"Brockzetel",,DE,5328.883N,00739.100E,9.0m,4,110,1060.0m,123.500,"Flugplatz"
"Brodau Delitzsch",,DE,5129.883N,01219.783E,101.0m,3,010,270.0m,120.975,"Landefeld"
"Bronkow",,DE,5140.317N,01357.817E,128.0m,2,120,900.0m,130.325,"Flugplatz"
"Bruchsal",,DE,4908.117N,00833.817E,113.0m,2,120,500.0m,128.375,"Flugplatz"
"Buechig Ostheim",,DE,5026.900N,01015.150E,388.0m,4,100,550.0m,123.375,"Flugplatz"
"Buechel Mil",,DE,5010.433N,00703.800E,479.0m,5,030,2510.0m,122.100,"Flugplatz"
"Bueckeburg Wein",,DE,5215.050N,00901.067E,77.0m,4,110,1130.0m,129.975,"Flugplatz"
"Bueckeburg Mil",,DE,5216.700N,00904.933E,70.0m,5,080,1840.0m,122.100,"Flugplatz"
"Bueckeburg Nord",,DE,5215.217N,00900.850E,74.0m,4,110,1130.0m,129.975,"Flugplatz"
"Bueren Schwalnbr",,DE,5132.567N,00834.833E,265.0m,4,070,710.0m,123.350,"Flugplatz"
"Buhlbach X Wiese",,DE,4831.500N,00815.600E,649.0m,3,240,200.0m,,"Landefeld"
"Bundenthal Rumbc",,DE,4905.633N,00747.633E,308.0m,4,180,570.0m,123.350,"Flugplatz"
"Burg",,DE,5214.500N,01151.367E,52.0m,2,090,850.0m,122.050,"Flugplatz"
"Burg Feuerstein",,DE,4947.650N,01108.033E,501.0m,5,080,970.0m,130.775,"Flugplatz"
"Burgstaedt Ul ?",,DE,5054.733N,01249.350E,335.0m,3,060,180.0m,123.600,"Landefeld"
"Burgheim",,DE,4841.517N,01102.017E,406.0m,2,140,660.0m,123.350,"Flugplatz"
"Burgebrach Ul",,DE,4950.300N,01046.733E,282.0m,3,100,280.0m,123.425,"Landefeld"
"Butzbach Pfingst",,DE,5026.150N,00837.167E,340.0m,5,100,510.0m,133.500,"Flugplatz"
"Celle Arloh",,DE,5241.267N,01006.733E,64.0m,2,040,900.0m,123.650,"Flugplatz"
"Celle Mil",,DE,5235.467N,01001.333E,40.0m,5,080,1840.0m,122.100,"Flugplatz"
"Cham Janahof",,DE,4912.700N,01239.400E,364.0m,5,100,560.0m,130.125,"Flugplatz"
"Chemnitz Jahns",,DE,5044.850N,01250.233E,370.0m,5,070,900.0m,122.500,"Flugplatz"
"Coburg Brandstn",,DE,5015.750N,01059.750E,449.0m,5,120,630.0m,128.675,"Flugplatz"
"Coburg Steinrue",,DE,5013.833N,01059.717E,356.0m,2,070,700.0m,129.800,"Flugplatz"
"Coleman Mil",,DE,4933.817N,00827.800E,95.0m,5,050,920.0m,122.100,"Flugplatz"
"Cottbus Mil Cls",,DE,5146.083N,01417.517E,70.0m,3,080,2360.0m,,"Landefeld"
"Cottbus Drewitz",,DE,5153.367N,01431.917E,82.0m,5,070,2480.0m,118.125,"Flugplatz"
"Crawinkel Ul",,DE,5046.700N,01049.000E,473.0m,3,050,510.0m,123.425,"Landefeld"
"Crussow Ul",,DE,5300.883N,01404.133E,53.0m,3,140,300.0m,123.425,"Landefeld"
"Dachau Groebenr",,DE,4813.717N,01125.367E,489.0m,2,100,620.0m,118.425,"Flugplatz"
"Dahlemer Binz",,DE,5024.333N,00631.733E,579.0m,5,060,1070.0m,122.375,"Flugplatz"
"Damgarten Cls",,DE,5415.850N,01226.667E,5.0m,3,070,2000.0m,121.500,"Landefeld"
"Damme",,DE,5229.250N,00811.100E,46.0m,5,100,700.0m,133.300,"Flugplatz"
"Dankern Haren Ul",,DE,5248.150N,00709.617E,11.0m,3,100,360.0m,120.975,"Landefeld"
"Dauborn",,DE,5019.300N,00811.633E,164.0m,2,120,330.0m,123.500,"Flugplatz"
"Daun Senheld",,DE,5010.550N,00651.467E,526.0m,5,080,420.0m,123.150,"Flugplatz"
"Deckenpfronn Ege",,DE,4838.300N,00849.050E,578.0m,4,070,800.0m,130.125,"Flugplatz"
"Deggendorf",,DE,4849.817N,01252.783E,314.0m,5,090,550.0m,122.025,"Flugplatz"
"Degmarn",,DE,4915.467N,00916.467E,169.0m,4,080,700.0m,123.500,"Flugplatz"
"Dehausen Diemels",,DE,5127.800N,00902.967E,305.0m,4,160,650.0m,123.150,"Flugplatz"
"Der Dingel Huemm",,DE,5132.167N,00922.783E,220.0m,4,050,870.0m,123.500,"Flugplatz"
"Der Ring Schwalm",,DE,5054.183N,00914.433E,212.0m,4,030,660.0m,123.375,"Flugplatz"
"Dessau",,DE,5149.900N,01211.067E,56.0m,5,090,1000.0m,118.175,"Flugplatz"
"Dettingen 09 Rwy",,DE,4836.567N,00928.267E,374.0m,3,090,220.0m,122.175,"Landefeld"
"Detmold",,DE,5156.450N,00854.250E,189.0m,5,090,510.0m,122.750,"Flugplatz"
"Dettingen Teck",,DE,4836.500N,00928.533E,386.0m,4,130,490.0m,122.175,"Flugplatz"
"Diepholz Mil",,DE,5235.133N,00820.467E,40.0m,5,080,1280.0m,122.100,"Flugplatz"
"Dierdorf Wienau",,DE,5033.950N,00739.150E,291.0m,5,070,580.0m,128.925,"Flugplatz"
"Dillingen",,DE,4923.167N,00644.917E,239.0m,4,060,680.0m,130.125,"Flugplatz"
"Dingelstedt Ul",,DE,5159.183N,01058.033E,122.0m,3,100,330.0m,123.425,"Landefeld"
"Dingolfing",,DE,4839.400N,01229.933E,352.0m,2,080,660.0m,123.600,"Flugplatz"
"Dinkelsbuehl",,DE,4903.900N,01024.150E,488.0m,2,090,700.0m,118.425,"Flugplatz"
"Dinslaken Schwa",,DE,5136.967N,00651.933E,65.0m,5,080,1500.0m,122.700,"Flugplatz"
"Dobenreuth",,DE,4941.817N,01108.600E,338.0m,4,100,470.0m,123.350,"Flugplatz"
"Doebbersen",,DE,5333.567N,01103.050E,42.0m,3,160,250.0m,,"Landefeld"
"Doernberg Rwy21",,DE,5122.017N,00920.200E,439.0m,3,210,320.0m,122.300,"Landefeld"
"Doerzbach Hoheba",,DE,4921.050N,00942.883E,404.0m,3,150,270.0m,123.425,"Landefeld"
"Dolmar Kuendorf",,DE,5036.733N,01028.350E,515.0m,3,040,400.0m,123.425,"Landefeld"
"Donaueschingen",,DE,4758.417N,00831.333E,680.0m,5,180,1290.0m,124.250,"Flugplatz"
"Donauwoerth",,DE,4842.183N,01051.133E,399.0m,5,090,700.0m,134.125,"Flugplatz"
"Donstorf Ul",,DE,5239.300N,00833.417E,33.0m,3,170,310.0m,123.425,"Landefeld"
"Donzdorf Messe",,DE,4840.717N,00950.750E,690.0m,5,090,600.0m,122.600,"Flugplatz"
"Dorsten Kanal",,DE,5139.733N,00659.100E,32.0m,4,090,600.0m,123.350,"Flugplatz"
"Dortmund Wickede",,DE,5131.150N,00736.867E,128.0m,5,060,2000.0m,134.175,"Flugplatz"
"Drensteinfurt",,DE,5146.050N,00744.817E,69.0m,3,030,310.0m,123.425,"Landefeld"
"Dresden",,DE,5108.067N,01346.083E,229.0m,5,040,2850.0m,122.925,"Flugplatz"
"Drosa Bobbe Ul",,DE,5149.517N,01153.800E,72.0m,3,100,660.0m,123.425,"Landefeld"
"Duerabuch Cls",,DE,4815.733N,01112.583E,537.0m,4,080,850.0m,123.500,"Flugplatz"
"Duernbach",,DE,4745.933N,01143.933E,751.0m,3,160,500.0m,,"Landefeld"
"Dueren Huertgen",,DE,5041.633N,00625.100E,360.0m,4,060,770.0m,123.150,"Flugplatz"
"Duesseldorf",,DE,5117.267N,00646.150E,37.0m,5,050,3000.0m,118.300,"Flugplatz"
"Duesseld Wolfsaa",,DE,5115.883N,00651.217E,113.0m,4,070,800.0m,123.150,"Flugplatz"
"Durrweiler Hesel",,DE,4831.500N,00832.433E,650.0m,3,150,350.0m,123.425,"Landefeld"
"Ebern Sendelbach",,DE,5002.383N,01049.367E,253.0m,2,140,520.0m,122.500,"Flugplatz"
"Eberswalde Finow",,DE,5249.633N,01341.617E,37.0m,5,100,1480.0m,119.050,"Flugplatz"
"Edling",,DE,4804.300N,01208.150E,493.0m,3,110,340.0m,,"Landefeld"
"Egelsbach",,DE,4957.650N,00838.483E,119.0m,5,090,1400.0m,118.400,"Flugplatz"
"Eggenfelden",,DE,4823.767N,01243.283E,407.0m,5,080,1160.0m,120.300,"Flugplatz"
"Eggersdorf",,DE,5228.967N,01405.450E,67.0m,2,060,1200.0m,123.000,"Flugplatz"
"Ehlershausen Gr",,DE,5232.150N,01001.183E,45.0m,4,100,1010.0m,122.200,"Flugplatz"
"Eichstaett",,DE,4852.617N,01110.900E,524.0m,2,110,710.0m,123.000,"Flugplatz"
"Eisenhuettenstad",,DE,5211.833N,01435.133E,46.0m,5,110,1170.0m,122.000,"Flugplatz"
"Eisenach Kindel",,DE,5059.533N,01028.567E,335.0m,5,100,1720.0m,119.750,"Flugplatz"
"Ellwangen",,DE,4857.683N,01014.083E,503.0m,2,120,780.0m,122.000,"Flugplatz"
"Elsenthal Grafen",,DE,4849.350N,01322.050E,485.0m,2,160,460.0m,122.500,"Flugplatz"
"Elz",,DE,5025.600N,00800.600E,213.0m,2,070,750.0m,123.600,"Flugplatz"
"Emden",,DE,5323.467N,00713.533E,1.0m,5,070,1300.0m,118.600,"Flugplatz"
"Emmerich",,DE,5149.333N,00616.467E,13.0m,4,130,990.0m,123.350,"Flugplatz"
"Engelbrand",,DE,4849.900N,00838.150E,571.0m,3,060,450.0m,,"Landefeld"
"Enzloesterle",,DE,4839.800N,00827.967E,599.0m,3,040,260.0m,,"Landefeld"
"Epfenbach Ul",,DE,4919.250N,00855.017E,219.0m,3,070,220.0m,123.425,"Landefeld"
"Erbach",,DE,4820.517N,00955.000E,476.0m,2,030,650.0m,118.275,"Flugplatz"
"Erbendorf Schwei",,DE,4950.633N,01204.017E,494.0m,5,120,630.0m,123.350,"Flugplatz"
"Erding Mil",,DE,4819.333N,01156.917E,463.0m,5,080,2510.0m,120.200,"Flugplatz"
"Erfurt",,DE,5058.783N,01057.483E,317.0m,5,100,2600.0m,121.150,"Flugplatz"
"Erkelenz Kueckho",,DE,5103.900N,00621.583E,85.0m,3,160,450.0m,120.975,"Landefeld"
"Ernzen Ul",,DE,4949.733N,00626.133E,345.0m,3,050,450.0m,123.425,"Landefeld"
"Erpetshof Ul ?",,DE,4939.433N,01217.783E,497.0m,3,100,300.0m,123.425,"Landefeld"
"Eschelbach Ul",,DE,4834.183N,01136.533E,459.0m,3,110,380.0m,123.450,"Landefeld"
"Essen Muelheim",,DE,5124.133N,00656.233E,128.0m,5,070,1530.0m,119.750,"Flugplatz"
"Esslingen Jaege",,DE,4845.733N,00920.033E,496.0m,4,120,730.0m,122.475,"Flugplatz"
"Essweiler",,DE,4933.733N,00734.800E,409.0m,4,050,820.0m,129.975,"Flugplatz"
"Etting Adelmanns",,DE,4848.617N,01125.267E,382.0m,4,100,720.0m,123.500,"Flugplatz"
"Eudenbach",,DE,5040.333N,00721.917E,300.0m,4,090,800.0m,118.425,"Flugplatz"
"Eutingen",,DE,4829.133N,00846.700E,497.0m,4,060,710.0m,129.975,"Flugplatz"
"Falkenberg Loen",,DE,5132.867N,01313.683E,85.0m,5,080,1200.0m,130.125,"Flugplatz"
"Fall Sylvenstein",,DE,4734.167N,01132.983E,780.0m,3,160,470.0m,,"Landefeld"
"Farchant N",,DE,4732.417N,01106.483E,665.0m,3,030,350.0m,,"Landefeld"
"Farchant S",,DE,4731.417N,01106.483E,679.0m,3,020,300.0m,,"Landefeld"
"Farrenberg",,DE,4823.133N,00904.600E,794.0m,4,100,750.0m,123.475,"Flugplatz"
"Fassberg Mil",,DE,5255.150N,01011.033E,70.0m,5,090,2170.0m,122.100,"Flugplatz"
"Faulenfuerst1",,DE,4748.450N,00813.033E,1032.0m,3,130,250.0m,,"Landefeld"
"Faulenfuers3",,DE,4748.317N,00813.183E,1025.0m,3,130,280.0m,,"Landefeld"
"Fichtelbrunn",,DE,4929.883N,01139.567E,498.0m,4,090,360.0m,122.300,"Flugplatz"
"Finsterw Heinric",,DE,5138.067N,01340.317E,127.0m,2,080,1000.0m,123.500,"Flugplatz"
"Finsterw Schacks",,DE,5136.450N,01344.283E,122.0m,5,090,1200.0m,123.050,"Flugplatz"
"Fischbek",,DE,5327.350N,00949.783E,64.0m,4,120,910.0m,129.975,"Flugplatz"
"Fischbachau",,DE,4743.350N,01155.983E,754.0m,3,090,300.0m,,"Landefeld"
"Fischhausen",,DE,4742.550N,01152.117E,801.0m,3,140,400.0m,,"Landefeld"
"Flensburg",,DE,5446.400N,00922.733E,40.0m,5,110,1220.0m,122.850,"Flugplatz"
"Flintsbach",,DE,4743.350N,01206.850E,489.0m,4,090,430.0m,122.500,"Flugplatz"
"Frankfurt Hahn",,DE,4956.917N,00715.833E,503.0m,5,030,3800.0m,119.650,"Flugplatz"
"Frankfurt Main",,DE,5002.000N,00834.233E,110.0m,5,070,4000.0m,119.900,"Flugplatz"
"Freiburg",,DE,4801.367N,00749.967E,242.0m,5,160,1400.0m,118.250,"Flugplatz"
"Friedersdorf",,DE,5216.917N,01348.133E,33.0m,2,110,950.0m,122.200,"Flugplatz"
"Friedrichshafen",,DE,4740.283N,00930.683E,418.0m,5,060,2350.0m,120.075,"Flugplatz"
"Fritzlar Mil",,DE,5106.883N,00917.150E,174.0m,5,120,1040.0m,122.100,"Flugplatz"
"Friesoythe Ul",,DE,5301.767N,00748.000E,6.0m,3,080,340.0m,124.000,"Landefeld"
"Friesener Warte",,DE,4950.183N,01102.800E,517.0m,4,010,640.0m,122.200,"Flugplatz"
"Fuenftbronn",,DE,4836.667N,00829.417E,740.0m,3,050,350.0m,,"Landefeld"
"Furstenfeldb Cls",,DE,4812.333N,01116.033E,518.0m,5,090,2750.0m,123.700,"Flugplatz"
"Furth Seckendorf",,DE,4928.883N,01051.517E,334.0m,4,090,620.0m,123.475,"Flugplatz"
"Fuerstenzell",,DE,4831.083N,01320.767E,412.0m,5,150,480.0m,122.000,"Flugplatz"
"Fuessen",,DE,4735.000N,01041.450E,787.0m,4,080,1030.0m,123.350,"Flugplatz"
"Fulda Jossa",,DE,5028.517N,00926.533E,471.0m,2,080,580.0m,122.400,"Flugplatz"
"Further Drachenh",,DE,4917.817N,01252.200E,412.0m,3,120,230.0m,,"Landefeld"
"Gaggenau",,DE,4847.850N,00819.083E,165.0m,3,190,300.0m,,"Landefeld"
"Gammelsdorf",,DE,4834.067N,01155.950E,495.0m,4,180,770.0m,129.975,"Flugplatz"
"Ganderkesee",,DE,5302.167N,00830.317E,31.0m,5,080,830.0m,118.625,"Flugplatz"
"Garbenheimer Wie",,DE,5034.500N,00831.917E,151.0m,4,080,800.0m,122.300,"Flugplatz"
"Gardelegen",,DE,5231.833N,01121.217E,73.0m,2,080,550.0m,122.850,"Flugplatz"
"Garmisch O",,DE,4729.000N,01105.933E,731.0m,3,180,300.0m,,"Landefeld"
"Garmisch W",,DE,4728.300N,01103.283E,743.0m,3,040,250.0m,,"Landefeld"
"Gedern",,DE,5025.950N,00911.667E,371.0m,4,040,700.0m,123.475,"Flugplatz"
"Geesthacht Wiese",,DE,5326.933N,01020.350E,4.0m,3,120,410.0m,133.500,"Landefeld"
"Geilenkirche Mil",,DE,5057.650N,00602.550E,92.0m,5,090,3060.0m,120.050,"Flugplatz"
"Geitau",,DE,4740.767N,01157.733E,818.0m,4,160,550.0m,123.400,"Flugplatz"
"Gelnhausen",,DE,5011.783N,00910.067E,126.0m,2,070,840.0m,123.050,"Flugplatz"
"Gera Leumnitz",,DE,5052.883N,01208.133E,307.0m,5,060,750.0m,118.075,"Flugplatz"
"Geratshof",,DE,4759.583N,01050.617E,634.0m,4,080,250.0m,123.500,"Flugplatz"
"Gernsbach X",,DE,4846.417N,00820.283E,160.0m,3,030,220.0m,,"Landefeld"
"Gerstetten",,DE,4837.233N,01003.667E,599.0m,2,080,530.0m,123.000,"Flugplatz"
"Giebelstadt",,DE,4938.900N,00957.983E,299.0m,5,080,1980.0m,122.500,"Flugplatz"
"Giengen Brenz",,DE,4838.033N,01013.000E,518.0m,5,170,560.0m,122.350,"Flugplatz"
"Giessen Reiskir",,DE,5034.000N,00852.183E,213.0m,2,040,430.0m,123.650,"Flugplatz"
"Giessen Lutzell",,DE,5032.667N,00835.450E,232.0m,5,070,710.0m,122.500,"Flugplatz"
"Giessen Wieseck",,DE,5036.250N,00843.717E,165.0m,4,080,920.0m,122.000,"Flugplatz"
"Glasewitz Eh Fpl",,DE,5350.050N,01218.583E,47.0m,3,070,1100.0m,,"Landefeld"
"Goch Asperden",,DE,5141.450N,00606.233E,16.0m,2,100,750.0m,118.450,"Flugplatz"
"Goeppingen Betzg",,DE,4839.517N,00937.450E,374.0m,2,140,320.0m,,"Flugplatz"
"Goepfersdorf",,DE,5054.817N,01236.700E,291.0m,4,070,700.0m,123.475,"Flugplatz"
"Goerlitz",,DE,5109.533N,01457.017E,238.0m,2,060,740.0m,122.000,"Flugplatz"
"Goettingen Heili",,DE,5124.450N,01008.683E,363.0m,2,060,700.0m,122.200,"Flugplatz"
"Goettelfingen",,DE,4834.350N,00827.933E,776.0m,3,160,510.0m,,"Landefeld"
"Goeppingen Cls",,DE,4842.450N,00941.383E,371.0m,3,070,600.0m,122.100,"Landefeld"
"Goslar Bollrich",,DE,5154.283N,01027.550E,295.0m,4,060,540.0m,123.475,"Flugplatz"
"Gotha Ost",,DE,5058.217N,01043.750E,305.0m,2,080,550.0m,122.500,"Flugplatz"
"Grafenhausen1",,DE,4747.383N,00814.933E,962.0m,3,130,300.0m,,"Landefeld"
"Grafenhause3",,DE,4747.067N,00814.967E,959.0m,3,180,250.0m,,"Landefeld"
"Grabenstetten",,DE,4832.167N,00926.233E,710.0m,2,120,1110.0m,130.125,"Flugplatz"
"Grafenwoehr Mil",,DE,4941.917N,01156.417E,415.0m,5,140,1010.0m,122.100,"Flugplatz"
"Grambeker Heide",,DE,5335.000N,01041.917E,48.0m,4,090,860.0m,123.150,"Flugplatz"
"Gransee",,DE,5300.400N,01312.117E,51.0m,2,110,880.0m,126.725,"Flugplatz"
"Grabenstaett",,DE,4751.167N,01233.067E,537.0m,2,080,480.0m,129.975,"Flugplatz"
"Greding",,DE,4903.733N,01117.517E,525.0m,4,110,650.0m,122.500,"Flugplatz"
"Grefrath Niersho",,DE,5120.050N,00621.583E,31.0m,2,070,670.0m,123.625,"Flugplatz"
"Greiling B Toelz",,DE,4745.917N,01135.717E,713.0m,5,030,1250.0m,123.350,"Flugplatz"
"Greiz Obergroch",,DE,5038.650N,01210.500E,387.0m,2,050,740.0m,122.000,"Flugplatz"
"Griesau",,DE,4857.250N,01225.283E,321.0m,2,150,410.0m,122.600,"Flugplatz"
"Grifte Edermuend",,DE,5113.267N,00926.867E,202.0m,4,050,780.0m,123.500,"Flugplatz"
"Gross Garz Cls",,DE,5257.050N,01135.550E,18.0m,3,020,300.0m,123.425,"Landefeld"
"Grosse Hoehe",,DE,5259.183N,00834.333E,20.0m,4,040,920.0m,123.375,"Flugplatz"
"Gronenfelde Ul",,DE,5221.833N,01429.717E,63.0m,3,120,490.0m,120.975,"Landefeld"
"Grossrueckerswa",,DE,5038.650N,01307.717E,671.0m,2,110,1000.0m,123.000,"Flugplatz"
"Grossenhain",,DE,5118.483N,01333.333E,128.0m,5,110,2400.0m,122.700,"Flugplatz"
"Grosse Wiese",,DE,5208.233N,01034.250E,78.0m,4,070,760.0m,123.350,"Flugplatz"
"Grube",,DE,5414.667N,01101.433E,3.0m,2,090,500.0m,122.600,"Flugplatz"
"Gruenstadt Quirn",,DE,4935.133N,00808.367E,316.0m,4,180,900.0m,122.300,"Flugplatz"
"Gruibingen Norte",,DE,4837.267N,00939.317E,706.0m,4,080,520.0m,129.975,"Flugplatz"
"Guenching Ul",,DE,4916.067N,01134.383E,557.0m,3,060,440.0m,123.500,"Landefeld"
"Gunzburg Donau",,DE,4829.183N,01016.950E,445.0m,2,060,580.0m,118.125,"Flugplatz"
"Guestrow",,DE,5348.333N,01213.800E,14.0m,2,090,700.0m,122.000,"Flugplatz"
"Guetersloh Mil",,DE,5155.383N,00818.383E,73.0m,5,090,2240.0m,130.500,"Flugplatz"
"Gundelfingen",,DE,4834.167N,01021.517E,440.0m,2,100,580.0m,122.500,"Flugplatz"
"Gundelsheim Ul",,DE,4917.450N,00910.367E,273.0m,3,090,350.0m,123.425,"Landefeld"
"Gunzenhausen Re",,DE,4906.733N,01046.917E,485.0m,5,060,720.0m,118.550,"Flugplatz"
"Gustorfer Hoehe",,DE,5104.617N,00632.867E,89.0m,4,090,1030.0m,122.050,"Flugplatz"
"Hagen Hof",,DE,5118.433N,00725.617E,394.0m,4,100,410.0m,129.975,"Flugplatz"
"Hahnweide",,DE,4837.917N,00925.750E,352.0m,2,130,640.0m,123.250,"Flugplatz"
"Hain Modell 40M",,DE,5126.333N,01046.083E,266.0m,3,110,400.0m,123.425,"Landefeld"
"Hain Ul",,DE,5126.250N,01046.467E,268.0m,3,110,540.0m,123.425,"Landefeld"
"Haiterbach Nagol",,DE,4831.917N,00840.667E,596.0m,4,070,470.0m,123.350,"Flugplatz"
"Halbmeil X",,DE,4817.767N,00815.417E,291.0m,3,140,160.0m,,"Landefeld"
"Halle Oppin",,DE,5133.133N,01203.233E,107.0m,5,110,1120.0m,135.150,"Flugplatz"
"Hallertau",,DE,4838.967N,01135.783E,386.0m,4,030,770.0m,123.350,"Flugplatz"
"Hamburg Finkenw",,DE,5332.117N,00950.133E,6.0m,5,050,3180.0m,123.250,"Flugplatz"
"Hamburg Fuhlsbu",,DE,5337.833N,00959.300E,15.0m,5,150,3660.0m,121.275,"Flugplatz"
"Hameln Pyrmont",,DE,5157.967N,00917.450E,360.0m,5,040,600.0m,121.175,"Flugplatz"
"Hamm Lippewiesen",,DE,5141.417N,00749.067E,58.0m,5,060,900.0m,134.050,"Flugplatz"
"Hangensteinerhof",,DE,4855.967N,00848.917E,299.0m,4,070,550.0m,123.150,"Flugplatz"
"Hannover",,DE,5227.617N,00941.017E,55.0m,5,090,3800.0m,120.175,"Flugplatz"
"Harle",,DE,5342.400N,00749.217E,3.0m,5,090,510.0m,122.400,"Flugplatz"
"Hartenholm",,DE,5354.867N,01002.100E,37.0m,5,050,760.0m,118.125,"Flugplatz"
"Hartenstein Thie",,DE,5040.550N,01240.733E,408.0m,3,090,370.0m,120.975,"Landefeld"
"Haslach",,DE,4817.267N,00804.167E,207.0m,3,140,500.0m,,"Landefeld"
"Hassloch Pfalz",,DE,4921.317N,00817.417E,108.0m,4,080,920.0m,123.500,"Flugplatz"
"Hassfurt",,DE,5001.083N,01031.767E,220.0m,5,110,1100.0m,119.800,"Flugplatz"
"Hausach",,DE,4817.083N,00809.767E,235.0m,3,090,440.0m,,"Landefeld"
"Hausen",,DE,4740.433N,00750.483E,393.0m,3,020,400.0m,,"Landefeld"
"Hausham",,DE,4744.800N,01151.150E,781.0m,3,100,300.0m,,"Landefeld"
"Hayingen",,DE,4817.083N,00927.933E,703.0m,4,140,810.0m,123.500,"Flugplatz"
"Heilbronn Boecki",,DE,4907.300N,00910.767E,159.0m,4,070,760.0m,123.500,"Flugplatz"
"Heide Buesum",,DE,5409.200N,00854.100E,3.0m,5,110,720.0m,122.600,"Flugplatz"
"Heiligenberg",,DE,4750.000N,00918.067E,759.0m,4,180,500.0m,123.500,"Flugplatz"
"Heinsberg Aphov",,DE,5103.033N,00603.250E,65.0m,3,140,260.0m,123.425,"Landefeld"
"Heldburg",,DE,5016.200N,01044.067E,286.0m,3,160,600.0m,123.425,"Landefeld"
"Helgoland Duene",,DE,5411.117N,00754.950E,3.0m,5,150,480.0m,122.450,"Flugplatz"
"Hellenhagen",,DE,5201.517N,00933.883E,181.0m,4,100,260.0m,123.150,"Flugplatz"
"Helmstedt Rote",,DE,5214.033N,01058.700E,111.0m,4,080,940.0m,122.475,"Flugplatz"
"Hellingst",,DE,5322.500N,00851.000E,20.0m,4,130,1000.0m,123.500,"Flugplatz"
"Helm Unterthal",,DE,5009.367N,00952.683E,272.0m,3,170,330.0m,,"Landefeld"
"Hengsen Opherdic",,DE,5128.400N,00738.700E,132.0m,4,080,540.0m,123.450,"Flugplatz"
"Heppenheim",,DE,4937.283N,00837.500E,98.0m,2,150,1110.0m,122.475,"Flugplatz"
"Heringsdorf",,DE,5352.717N,01409.133E,28.0m,5,100,2300.0m,132.825,"Flugplatz"
"Hermuthausen",,DE,4918.867N,00944.717E,410.0m,4,080,990.0m,123.500,"Flugplatz"
"Herrenteich",,DE,4920.750N,00829.300E,91.0m,2,040,630.0m,132.050,"Flugplatz"
"Herrischried",,DE,4740.517N,00800.450E,904.0m,3,120,250.0m,,"Landefeld"
"Hersbruck",,DE,4930.450N,01126.617E,335.0m,4,090,470.0m,122.050,"Flugplatz"
"Herten Rheinfld",,DE,4733.600N,00744.900E,284.0m,2,060,730.0m,123.250,"Flugplatz"
"Herzogenaurach",,DE,4934.967N,01052.700E,324.0m,5,080,700.0m,122.850,"Flugplatz"
"Hessisch Lichten",,DE,5111.333N,00944.567E,411.0m,4,090,800.0m,123.500,"Flugplatz"
"Hettstadt",,DE,4947.917N,00950.217E,320.0m,2,090,550.0m,122.425,"Flugplatz"
"Hetzleser Berg",,DE,4938.533N,01109.750E,528.0m,5,080,600.0m,123.600,"Flugplatz"
"Heubach",,DE,4848.183N,00955.667E,433.0m,5,070,750.0m,123.025,"Flugplatz"
"Hienheim",,DE,4852.683N,01145.633E,397.0m,4,110,540.0m,123.500,"Flugplatz"
"Hildesheim",,DE,5210.783N,00956.733E,88.0m,5,070,1220.0m,118.300,"Flugplatz"
"Hilzingen",,DE,4745.633N,00846.050E,459.0m,4,090,820.0m,123.375,"Flugplatz"
"Hinterweiler",,DE,5014.700N,00645.317E,598.0m,3,060,270.0m,123.425,"Landefeld"
"Hirzenhain",,DE,5047.267N,00823.550E,528.0m,2,110,650.0m,118.325,"Flugplatz"
"Hirzenhain Nw-Ha",,DE,5048.100N,00822.667E,544.0m,4,310,150.0m,118.325,"Flugplatz"
"Hockenheim",,DE,4919.483N,00831.667E,93.0m,2,140,840.0m,123.650,"Flugplatz"
"Hodenhagen",,DE,5245.750N,00936.733E,22.0m,2,030,900.0m,119.000,"Flugplatz"
"Hoechenschwand1",,DE,4743.633N,00810.717E,969.0m,3,110,300.0m,,"Landefeld"
"Hoechenschw3",,DE,4744.000N,00809.617E,1016.0m,3,180,250.0m,,"Landefeld"
"Hoelleberg",,DE,5136.650N,00923.917E,257.0m,2,080,520.0m,122.000,"Flugplatz"
"Hoepen",,DE,5308.833N,00947.800E,85.0m,4,100,920.0m,122.475,"Flugplatz"
"Hoerbach",,DE,5040.100N,00815.633E,330.0m,4,050,310.0m,130.125,"Flugplatz"
"HoeXTer Holzmin",,DE,5148.383N,00922.700E,284.0m,5,140,810.0m,123.625,"Flugplatz"
"Hof-Plauen",,DE,5017.317N,01151.200E,598.0m,5,090,1480.0m,124.350,"Flugplatz"
"Hohenfels Mil",,DE,4913.000N,01150.150E,445.0m,5,090,670.0m,122.100,"Flugplatz"
"Hoherodskopf",,DE,5030.100N,00913.350E,674.0m,4,070,860.0m,123.500,"Flugplatz"
"Hohn Mil",,DE,5418.733N,00932.300E,12.0m,5,080,2450.0m,122.100,"Flugplatz"
"Hohentann Lands",,DE,4839.767N,01203.533E,471.0m,3,070,320.0m,123.425,"Landefeld"
"Holtorfsloh",,DE,5319.333N,01004.467E,55.0m,4,150,690.0m,123.350,"Flugplatz"
"Holzdorf Mil",,DE,5146.083N,01310.050E,82.0m,5,090,2420.0m,122.100,"Flugplatz"
"Homberg Ohm",,DE,5044.833N,00901.183E,349.0m,4,040,700.0m,123.500,"Flugplatz"
"Hoppensen Einbec",,DE,5147.183N,00945.317E,180.0m,3,070,380.0m,123.425,"Landefeld"
"Hoppstaedten We",,DE,4936.650N,00711.200E,332.0m,5,060,670.0m,130.650,"Flugplatz"
"Hornberg",,DE,4844.683N,00951.750E,682.0m,4,170,650.0m,122.025,"Flugplatz"
"Hoya",,DE,5248.717N,00909.833E,15.0m,4,120,680.0m,122.475,"Flugplatz"
"Hoym Ul",,DE,5146.683N,01117.117E,144.0m,3,100,350.0m,123.425,"Landefeld"
"Huelben",,DE,4831.750N,00923.867E,718.0m,4,090,660.0m,133.500,"Flugplatz"
"Huensborn",,DE,5055.717N,00753.950E,421.0m,2,090,950.0m,130.125,"Flugplatz"
"Hutten Hotzenwal",,DE,4737.983N,00756.483E,873.0m,4,110,710.0m,130.125,"Flugplatz"
"Huettenbusch",,DE,5317.200N,00856.900E,3.0m,2,090,450.0m,122.850,"Flugplatz"
"Huhnrain As",,DE,5029.400N,00950.833E,434.0m,5,080,500.0m,133.425,"Flugplatz"
"Husum",,DE,5430.600N,00908.300E,18.0m,5,030,1450.0m,122.050,"Flugplatz"
"Ibach",,DE,4743.617N,00803.867E,926.0m,3,170,250.0m,,"Landefeld"
"Ibach X",,DE,4826.700N,00810.100E,326.0m,3,160,250.0m,,"Landefeld"
"Idar Oberstein",,DE,4943.933N,00720.167E,475.0m,2,060,650.0m,122.850,"Flugplatz"
"Igelsloch",,DE,4844.867N,00839.233E,680.0m,3,110,250.0m,,"Landefeld"
"Igelsberg",,DE,4832.250N,00826.133E,749.0m,3,060,300.0m,,"Landefeld"
"Illertissen",,DE,4814.117N,01008.267E,512.0m,2,070,540.0m,118.525,"Flugplatz"
"Illeshe Mil Heli",,DE,4928.433N,01023.283E,329.0m,2,060,1500.0m,122.100,"Flugplatz"
"Imsweiler Donne",,DE,4936.367N,00747.617E,289.0m,3,060,280.0m,123.425,"Landefeld"
"Ingelfingen Bueh",,DE,4919.300N,00939.817E,421.0m,5,070,480.0m,130.600,"Flugplatz"
"Ingolstadt Manch",,DE,4842.933N,01132.033E,366.0m,5,070,2940.0m,122.100,"Flugplatz"
"Ippesheim Ul",,DE,4936.583N,01013.533E,297.0m,3,100,350.0m,120.975,"Landefeld"
"Irsingen",,DE,4902.300N,01030.183E,466.0m,4,260,560.0m,122.475,"Flugplatz"
"Iserlohn Rheiner",,DE,5125.817N,00738.650E,191.0m,4,070,800.0m,123.500,"Flugplatz"
"Iserlohn Suemmer",,DE,5126.250N,00742.100E,157.0m,4,040,440.0m,122.425,"Flugplatz"
"Isny Rotmoos",,DE,4742.017N,01001.233E,689.0m,4,080,450.0m,123.500,"Flugplatz"
"Ithwiesen",,DE,5157.067N,00939.767E,375.0m,2,320,850.0m,122.375,"Flugplatz"
"Itzehoe",,DE,5359.667N,00934.717E,24.0m,5,030,1040.0m,123.375,"Flugplatz"
"Jachenau Hoefen?",,DE,4736.483N,01129.500E,734.0m,3,070,300.0m,,"Landefeld"
"Jena Schongleina",,DE,5054.933N,01142.850E,375.0m,5,020,1170.0m,122.050,"Flugplatz"
"Jesenwang",,DE,4810.467N,01107.517E,565.0m,5,070,410.0m,120.050,"Flugplatz"
"Jever Mil",,DE,5332.017N,00753.317E,6.0m,5,100,2480.0m,118.725,"Flugplatz"
"Johannisau",,DE,5032.217N,00939.750E,265.0m,4,060,300.0m,122.300,"Flugplatz"
"Jueterbog Altes",,DE,5159.800N,01258.017E,94.0m,3,100,480.0m,123.425,"Landefeld"
"Juist",,DE,5340.883N,00703.400E,3.0m,5,080,700.0m,120.500,"Flugplatz"
"Kaelberbronn",,DE,4831.917N,00829.750E,706.0m,3,230,210.0m,,"Landefeld"
"Kalkhorst Agrar",,DE,5358.500N,01101.350E,22.0m,3,060,320.0m,,"Landefeld"
"Kamen Heeren",,DE,5135.417N,00742.600E,63.0m,4,110,970.0m,129.975,"Flugplatz"
"Kamenz",,DE,5117.817N,01407.650E,153.0m,5,030,1100.0m,122.050,"Flugplatz"
"Kammermark",,DE,5311.717N,01209.850E,84.0m,4,080,1040.0m,123.500,"Flugplatz"
"Kamp-Lintfort",,DE,5131.767N,00632.217E,21.0m,2,070,790.0m,123.000,"Flugplatz"
"Karbach",,DE,4952.400N,00940.083E,256.0m,3,090,180.0m,,"Landefeld"
"Karlsruhe Baden",,DE,4846.750N,00804.833E,125.0m,5,030,3000.0m,134.100,"Flugplatz"
"Karlshoefen",,DE,5319.967N,00901.717E,6.0m,5,120,700.0m,118.925,"Flugplatz"
"Karlstadt Saupur",,DE,4958.283N,00947.483E,248.0m,4,090,540.0m,123.475,"Flugplatz"
"Kassel Calden",,DE,5125.250N,00923.533E,250.0m,5,090,2500.0m,118.100,"Flugplatz"
"Kaufbeuren",,DE,4751.683N,01036.850E,726.0m,5,020,1830.0m,122.200,"Flugplatz"
"Kehl Sundheim",,DE,4833.683N,00750.633E,137.0m,2,030,680.0m,122.750,"Flugplatz"
"Kell",,DE,4937.300N,00650.417E,559.0m,4,050,820.0m,123.150,"Flugplatz"
"Kemmen Ul 30M",,DE,5247.733N,01306.283E,35.0m,3,140,360.0m,123.425,"Landefeld"
"Kempten Durach",,DE,4741.467N,01020.283E,710.0m,2,170,900.0m,122.000,"Flugplatz"
"Kerken",,DE,5126.317N,00626.733E,32.0m,3,020,250.0m,123.425,"Landefeld"
"Kiel Holtenau",,DE,5422.767N,01008.717E,31.0m,5,080,1260.0m,119.975,"Flugplatz"
"Kirchzarten",,DE,4757.050N,00757.350E,415.0m,4,180,1170.0m,122.475,"Flugplatz"
"Kirchdorf Inn",,DE,4814.300N,01258.617E,340.0m,2,040,670.0m,118.625,"Flugplatz"
"Kirn",,DE,4946.433N,00731.300E,429.0m,4,140,590.0m,123.375,"Flugplatz"
"Kitzingen",,DE,4944.517N,01012.117E,202.0m,5,070,800.0m,123.150,"Flugplatz"
"Kleinkoschen Ul",,DE,5130.600N,01404.983E,106.0m,3,150,410.0m,122.300,"Landefeld"
"Klein Muehlingen",,DE,5156.850N,01146.183E,53.0m,2,090,470.0m,122.000,"Flugplatz"
"Kleve Wisseler D",,DE,5146.167N,00617.950E,18.0m,4,070,510.0m,123.150,"Flugplatz"
"Kleinhartpenning",,DE,4751.100N,01139.967E,720.0m,3,070,300.0m,,"Landefeld"
"Klietz Scharlibb",,DE,5242.600N,01204.383E,26.0m,2,170,710.0m,122.375,"Flugplatz"
"Klippeneck Feld",,DE,4806.333N,00843.167E,685.0m,3,070,300.0m,,"Landefeld"
"Klippeneck",,DE,4806.467N,00845.750E,962.0m,4,050,1040.0m,122.175,"Flugplatz"
"KliX",,DE,5116.433N,01430.417E,145.0m,2,100,900.0m,118.600,"Flugplatz"
"Kniebis",,DE,4828.350N,00817.650E,920.0m,3,060,250.0m,,"Landefeld"
"Koblenz Winninge",,DE,5019.517N,00731.683E,195.0m,5,060,1170.0m,122.650,"Flugplatz"
"Kochel",,DE,4740.250N,01121.167E,599.0m,3,130,400.0m,,"Landefeld"
"Koln-Bonn",,DE,5051.950N,00708.567E,92.0m,5,140,3810.0m,124.975,"Flugplatz"
"Koenigsdorf",,DE,4749.717N,01127.967E,600.0m,5,100,740.0m,118.275,"Flugplatz"
"Kothen",,DE,5143.417N,01156.883E,93.0m,5,070,800.0m,123.650,"Flugplatz"
"Kohlenbissen Mil",,DE,5259.450N,01009.417E,80.0m,3,070,450.0m,121.500,"Landefeld"
"Konstanz",,DE,4740.900N,00908.283E,396.0m,2,120,760.0m,124.350,"Flugplatz"
"Konz Koenen",,DE,4940.533N,00632.567E,217.0m,4,020,780.0m,123.350,"Flugplatz"
"Korbach",,DE,5115.150N,00852.400E,390.0m,2,030,600.0m,119.975,"Flugplatz"
"Krefeld Egelsber",,DE,5123.083N,00635.267E,43.0m,2,060,640.0m,120.675,"Flugplatz"
"Kronach",,DE,5014.617N,01121.533E,466.0m,4,120,650.0m,123.350,"Flugplatz"
"Kruen",,DE,4730.600N,01116.000E,889.0m,3,070,500.0m,,"Landefeld"
"Kuehrstedt Beder",,DE,5334.083N,00847.367E,9.0m,2,120,580.0m,135.000,"Flugplatz"
"Kulmbach",,DE,5008.100N,01127.550E,506.0m,5,090,710.0m,118.525,"Flugplatz"
"Kunrau Ul 30M",,DE,5234.050N,01059.667E,65.0m,3,080,350.0m,123.425,"Landefeld"
"Kusel Langenbach",,DE,4928.683N,00718.533E,457.0m,4,100,520.0m,123.350,"Flugplatz"
"Kyritz",,DE,5255.133N,01225.517E,40.0m,5,140,1000.0m,122.725,"Flugplatz"
"Laage Mil",,DE,5355.083N,01216.700E,43.0m,5,100,2520.0m,118.425,"Flugplatz"
"Lachen Speyerdo",,DE,4919.800N,00812.767E,118.0m,2,110,1000.0m,118.175,"Flugplatz"
"Lager Hammelbur",,DE,5005.917N,00953.033E,342.0m,2,100,550.0m,118.425,"Flugplatz"
"Lahr",,DE,4822.150N,00749.667E,156.0m,5,030,3000.0m,125.175,"Flugplatz"
"Laichingen",,DE,4829.817N,00938.417E,746.0m,5,070,730.0m,127.700,"Flugplatz"
"Langenberg 36",,DE,5047.617N,00933.683E,360.0m,3,360,250.0m,123.500,"Landefeld"
"Landau Ebenberg",,DE,4910.583N,00808.167E,162.0m,4,100,590.0m,123.375,"Flugplatz"
"Landshut",,DE,4830.700N,01202.000E,399.0m,5,070,900.0m,129.800,"Flugplatz"
"Landsberg Mil",,DE,4804.233N,01054.367E,622.0m,5,070,2050.0m,122.100,"Flugplatz"
"Langenberg Hatte",,DE,5047.850N,00933.800E,350.0m,4,200,880.0m,123.500,"Flugplatz"
"Langeoog",,DE,5344.567N,00729.917E,3.0m,5,050,600.0m,122.025,"Flugplatz"
"Langhennersdorf",,DE,5056.917N,01315.717E,390.0m,2,050,900.0m,122.300,"Flugplatz"
"Langenlonsheim",,DE,4954.500N,00754.467E,92.0m,2,010,450.0m,122.875,"Flugplatz"
"Langenselbold",,DE,5010.617N,00904.000E,118.0m,4,070,400.0m,129.975,"Flugplatz"
"Langenfeld Wiesc",,DE,5108.450N,00659.117E,86.0m,4,070,620.0m,122.475,"Flugplatz"
"Langenbrand",,DE,4848.383N,00837.517E,702.0m,3,330,400.0m,,"Landefeld"
"Laucha",,DE,5114.767N,01141.617E,226.0m,2,090,720.0m,122.475,"Flugplatz"
"Lauda Landefeld",,DE,4934.483N,00942.583E,185.0m,3,160,370.0m,,"Landefeld"
"Lauenbrueck",,DE,5312.467N,00934.400E,29.0m,2,110,600.0m,123.650,"Flugplatz"
"Laufenselden",,DE,5013.300N,00759.917E,400.0m,4,050,510.0m,122.475,"Flugplatz"
"Lauf Lillinghof",,DE,4936.317N,01117.017E,544.0m,5,070,450.0m,133.500,"Flugplatz"
"Laupheim Mil",,DE,4813.200N,00954.617E,540.0m,5,090,1660.0m,122.100,"Flugplatz"
"Lauterbach",,DE,5041.017N,00924.683E,364.0m,2,060,600.0m,122.175,"Flugplatz"
"Leibertingen",,DE,4802.683N,00901.833E,833.0m,4,100,940.0m,129.975,"Flugplatz"
"Lechfeld Mil",,DE,4811.133N,01051.667E,555.0m,5,030,2660.0m,122.100,"Flugplatz"
"Leck",,DE,5447.400N,00857.683E,6.0m,2,120,820.0m,122.600,"Flugplatz"
"Leer Papenburg",,DE,5316.317N,00726.517E,1.0m,5,080,1200.0m,130.775,"Flugplatz"
"Leipheim",,DE,4826.450N,01014.283E,473.0m,5,060,610.0m,122.500,"Flugplatz"
"Leipzig",,DE,5125.433N,01214.183E,143.0m,5,080,3600.0m,121.100,"Flugplatz"
"Lengries1",,DE,4740.850N,01133.600E,698.0m,3,260,400.0m,,"Landefeld"
"Lengries3",,DE,4740.000N,01134.000E,716.0m,3,090,400.0m,,"Landefeld"
"Lenzkirch",,DE,4752.100N,00811.367E,834.0m,3,090,300.0m,,"Landefeld"
"Leutkirch Unterz",,DE,4751.533N,01000.867E,640.0m,5,060,1020.0m,122.875,"Flugplatz"
"Leuzendorf",,DE,4921.100N,01004.467E,463.0m,4,080,400.0m,123.500,"Flugplatz"
"Leverkusen",,DE,5100.917N,00700.367E,49.0m,2,150,920.0m,122.425,"Flugplatz"
"Lichtenfels",,DE,5008.867N,01102.817E,259.0m,2,040,700.0m,123.000,"Flugplatz"
"Lindlar",,DE,5059.817N,00722.600E,327.0m,4,050,900.0m,129.975,"Flugplatz"
"Linkenheim",,DE,4908.500N,00823.667E,97.0m,2,050,740.0m,122.600,"Flugplatz"
"Linnich Ul",,DE,5057.767N,00620.283E,103.0m,3,070,280.0m,123.425,"Landefeld"
"Lombach",,DE,4825.617N,00827.867E,657.0m,3,100,280.0m,,"Landefeld"
"Locktow Ul",,DE,5207.000N,01242.567E,65.0m,3,110,420.0m,126.500,"Landefeld"
"Loechgau",,DE,4900.067N,00904.917E,272.0m,4,110,600.0m,123.475,"Flugplatz"
"Ludwigshafen Dan",,DE,4924.717N,00820.983E,96.0m,4,050,1000.0m,130.125,"Flugplatz"
"Lubeck",,DE,5348.317N,01043.150E,15.0m,5,070,2100.0m,128.700,"Flugplatz"
"Luchow Rehbeck",,DE,5301.033N,01108.683E,10.0m,5,150,650.0m,122.500,"Flugplatz"
"Lunen Lippeweide",,DE,5137.017N,00730.083E,50.0m,4,090,1030.0m,123.500,"Flugplatz"
"Lueneburg",,DE,5314.900N,01027.483E,49.0m,2,070,980.0m,122.175,"Flugplatz"
"Luesse",,DE,5208.600N,01240.217E,64.0m,2,060,1020.0m,129.975,"Flugplatz"
"Magdeburg Cochst",,DE,5151.367N,01125.083E,183.0m,5,080,2500.0m,131.125,"Flugplatz"
"Magdeburg-City",,DE,5204.417N,01137.617E,82.0m,5,090,1000.0m,119.300,"Flugplatz"
"Mainbullau",,DE,4941.700N,00910.950E,455.0m,5,050,700.0m,122.375,"Flugplatz"
"Mainz Finthen",,DE,4958.150N,00808.867E,232.0m,5,080,1000.0m,122.925,"Flugplatz"
"Malmsheim",,DE,4847.083N,00855.050E,451.0m,4,080,710.0m,122.200,"Flugplatz"
"Malsch",,DE,4914.250N,00840.700E,133.0m,4,070,920.0m,129.975,"Flugplatz"
"Mannheim City",,DE,4928.367N,00830.783E,95.0m,5,090,1060.0m,129.775,"Flugplatz"
"Marburg Schoen",,DE,5052.450N,00848.900E,251.0m,2,040,750.0m,123.000,"Flugplatz"
"Markdorf",,DE,4742.567N,00923.350E,431.0m,4,130,600.0m,123.350,"Flugplatz"
"Marl Loemuehle",,DE,5138.817N,00709.817E,73.0m,5,070,830.0m,122.000,"Flugplatz"
"Marpingen",,DE,4927.167N,00702.367E,351.0m,4,100,780.0m,123.475,"Flugplatz"
"Meiersberg",,DE,5117.983N,00657.383E,164.0m,4,130,800.0m,130.125,"Flugplatz"
"Meinerzhagen",,DE,5106.000N,00735.967E,472.0m,5,070,1170.0m,130.600,"Flugplatz"
"Meistern",,DE,4841.583N,00832.700E,772.0m,3,260,260.0m,,"Landefeld"
"Melle Groenegau",,DE,5212.050N,00822.833E,73.0m,5,090,760.0m,122.400,"Flugplatz"
"Mellenthin Ul",,DE,5355.050N,01401.950E,19.0m,3,120,600.0m,123.425,"Landefeld"
"Memmingen",,DE,4759.333N,01014.367E,628.0m,5,060,2400.0m,126.850,"Flugplatz"
"Menden Barge",,DE,5127.583N,00750.167E,207.0m,4,240,920.0m,123.500,"Flugplatz"
"Mendig",,DE,5021.950N,00718.917E,174.0m,5,080,1610.0m,123.475,"Flugplatz"
"Mengen Hohenteng",,DE,4803.233N,00922.367E,555.0m,5,080,1560.0m,135.175,"Flugplatz"
"Mengeringhausen",,DE,5122.583N,00858.867E,363.0m,2,120,540.0m,121.025,"Flugplatz"
"Meppen Mil",,DE,5243.400N,00719.583E,21.0m,2,060,590.0m,122.100,"Flugplatz"
"Merseburg",,DE,5121.750N,01156.467E,104.0m,5,080,1140.0m,122.900,"Flugplatz"
"Meschede Schuren",,DE,5118.167N,00814.367E,439.0m,5,040,900.0m,122.050,"Flugplatz"
"Michelbach Am As",,DE,5013.900N,00804.617E,301.0m,4,070,600.0m,123.375,"Flugplatz"
"Michelstadt",,DE,4940.717N,00858.300E,349.0m,5,080,600.0m,123.650,"Flugplatz"
"Mindelheim Matts",,DE,4806.467N,01031.483E,567.0m,5,150,1140.0m,122.975,"Flugplatz"
"Mitteltal",,DE,4831.350N,00819.617E,589.0m,3,040,160.0m,,"Landefeld"
"Mittelfischach",,DE,4902.133N,00952.233E,385.0m,3,150,500.0m,123.425,"Landefeld"
"Mittenwald",,DE,4725.100N,01115.533E,934.0m,3,010,300.0m,,"Landefeld"
"Moeckmuehl Korb",,DE,4920.650N,00924.017E,354.0m,4,080,670.0m,129.975,"Flugplatz"
"Moeckern Tryppeh",,DE,5210.667N,01155.700E,71.0m,3,170,760.0m,120.975,"Landefeld"
"Moenchengladbach",,DE,5113.817N,00630.267E,40.0m,5,130,1200.0m,120.450,"Flugplatz"
"Moenchsheide",,DE,5030.483N,00715.333E,213.0m,4,100,690.0m,122.000,"Flugplatz"
"Mohorn",,DE,5059.883N,01326.783E,356.0m,3,040,340.0m,123.425,"Landefeld"
"Mohrdorf",,DE,5422.983N,01254.733E,3.0m,5,130,2300.0m,118.625,"Flugplatz"
"Montabaur",,DE,5025.433N,00749.800E,265.0m,4,050,580.0m,123.350,"Flugplatz"
"Moosburg Auf Kip",,DE,4827.400N,01156.500E,421.0m,2,040,650.0m,123.650,"Flugplatz"
"Morbach Ul",,DE,4902.017N,00935.467E,495.0m,3,090,430.0m,123.425,"Landefeld"
"Morschenich",,DE,5052.400N,00633.150E,104.0m,3,070,350.0m,123.425,"Landefeld"
"Mortitz Cls",,DE,5030.450N,01240.900E,100.0m,3,070,640.0m,,"Landefeld"
"Mosbach Lohrbach",,DE,4923.967N,00907.417E,332.0m,5,150,610.0m,122.850,"Flugplatz"
"Mosenberg",,DE,5103.767N,00925.317E,402.0m,2,070,510.0m,123.050,"Flugplatz"
"Muelben",,DE,4927.300N,00906.283E,519.0m,4,340,750.0m,130.125,"Flugplatz"
"Muehldorf",,DE,4816.783N,01230.017E,406.0m,5,080,850.0m,119.775,"Flugplatz"
"Muehlhausen",,DE,5112.783N,01032.967E,247.0m,2,080,900.0m,122.850,"Flugplatz"
"Muellheim",,DE,4749.450N,00738.383E,292.0m,4,160,700.0m,129.975,"Flugplatz"
"Munchen",,DE,4821.233N,01147.167E,454.0m,5,080,4000.0m,118.700,"Flugplatz"
"Munsingen Eisber",,DE,4824.550N,00926.550E,725.0m,4,080,450.0m,123.500,"Flugplatz"
"Munster Osnabruc",,DE,5208.083N,00741.083E,49.0m,5,070,2170.0m,129.800,"Flugplatz"
"Muenster Telgte",,DE,5156.667N,00746.417E,55.0m,5,100,850.0m,122.850,"Flugplatz"
"Mueritz Airpark",,DE,5318.383N,01245.150E,63.0m,5,070,2380.0m,129.975,"Flugplatz"
"Musbach",,DE,4830.167N,00828.717E,697.0m,4,170,1000.0m,130.125,"Flugplatz"
"Nabern Teck",,DE,4836.750N,00928.633E,372.0m,2,140,570.0m,118.325,"Flugplatz"
"Nannhausen",,DE,4958.217N,00728.733E,381.0m,2,060,560.0m,130.600,"Flugplatz"
"Nardt",,DE,5127.100N,01412.150E,117.0m,2,080,950.0m,123.000,"Flugplatz"
"Nastaetten",,DE,5011.883N,00753.333E,363.0m,4,080,1020.0m,126.500,"Flugplatz"
"Nauen Cls",,DE,5237.600N,01254.833E,28.0m,3,100,850.0m,,"Landefeld"
"Naunheim Maifeld",,DE,5015.500N,00719.933E,195.0m,3,060,180.0m,123.425,"Landefeld"
"Neresheim",,DE,4844.500N,01019.667E,538.0m,4,080,750.0m,130.125,"Flugplatz"
"Neuweiler Wiese",,DE,4839.300N,00836.500E,654.0m,3,080,250.0m,,"Landefeld"
"Neubiberg Cls",,DE,4804.383N,01138.283E,576.0m,3,070,2140.0m,,"Landefeld"
"Neubrandenbu Mil",,DE,5336.133N,01318.367E,70.0m,5,090,2290.0m,119.175,"Flugplatz"
"Neuburg Egweil",,DE,4846.917N,01112.917E,412.0m,2,080,640.0m,123.475,"Flugplatz"
"Neuburg Mil",,DE,4842.667N,01112.700E,381.0m,5,090,2450.0m,122.100,"Flugplatz"
"Neuhausen Ob Eck",,DE,4758.600N,00854.250E,806.0m,5,090,1240.0m,119.600,"Flugplatz"
"Neuenstadt A Koc",,DE,4914.567N,00919.033E,168.0m,3,100,250.0m,123.425,"Landefeld"
"Neu Guelze",,DE,5322.867N,01048.250E,12.0m,4,070,800.0m,123.500,"Flugplatz"
"Neuhardenberg",,DE,5236.783N,01414.567E,12.0m,5,080,2400.0m,119.125,"Flugplatz"
"Neuhausen",,DE,5141.083N,01425.383E,85.0m,2,110,1080.0m,122.725,"Flugplatz"
"Neuhaus Sumte",,DE,5317.383N,01054.267E,8.0m,3,130,300.0m,,"Landefeld"
"Neujellingsdorf",,DE,5427.350N,01106.567E,7.0m,2,110,590.0m,122.050,"Flugplatz"
"Neumagen Dhron",,DE,4950.567N,00654.967E,268.0m,2,090,750.0m,118.175,"Flugplatz"
"Neumarkt Oberpfa",,DE,4917.133N,01126.617E,424.0m,5,090,710.0m,119.975,"Flugplatz"
"Neumuenster",,DE,5404.767N,00956.517E,21.0m,5,080,600.0m,123.000,"Flugplatz"
"Neunkirchen BeXB",,DE,4920.400N,00715.200E,272.0m,2,060,450.0m,123.050,"Flugplatz"
"Neuruppin",,DE,5256.567N,01246.767E,43.0m,4,100,1260.0m,123.350,"Flugplatz"
"Neustadt Aisch",,DE,4935.250N,01034.667E,363.0m,5,090,600.0m,118.925,"Flugplatz"
"Neustadt Glewe",,DE,5321.717N,01136.867E,37.0m,2,090,1200.0m,123.375,"Flugplatz"
"Nidda A D Helm",,DE,5024.317N,00859.267E,176.0m,4,040,770.0m,123.375,"Flugplatz"
"Niederrhein",,DE,5136.150N,00608.533E,34.0m,5,090,2440.0m,129.400,"Flugplatz"
"Niederstetten",,DE,4923.517N,00957.500E,469.0m,5,070,1310.0m,122.100,"Flugplatz"
"Nienburg Holzbal",,DE,5242.583N,00909.733E,24.0m,2,080,850.0m,122.000,"Flugplatz"
"Niederwillingen",,DE,5046.817N,01103.117E,395.0m,3,060,350.0m,120.975,"Landefeld"
"Nittenau Bruck",,DE,4913.333N,01217.800E,357.0m,5,010,550.0m,118.925,"Flugplatz"
"Noerdlingen",,DE,4852.217N,01030.283E,421.0m,5,040,750.0m,133.075,"Flugplatz"
"Noervenich Mil",,DE,5049.867N,00639.483E,119.0m,5,070,2450.0m,122.100,"Flugplatz"
"Nordenbeck",,DE,5114.100N,00849.017E,452.0m,2,080,600.0m,122.500,"Flugplatz"
"Norddoellen Vis",,DE,5248.317N,00819.483E,49.0m,3,070,200.0m,123.425,"Landefeld"
"Norderney",,DE,5342.400N,00713.800E,3.0m,5,080,1000.0m,122.600,"Flugplatz"
"Nordhausen",,DE,5129.567N,01050.267E,210.0m,2,100,890.0m,118.625,"Flugplatz"
"Nordhorn Lingen",,DE,5227.467N,00710.950E,28.0m,5,060,900.0m,122.650,"Flugplatz"
"Nordholz Mil",,DE,5346.050N,00839.500E,21.0m,5,080,2430.0m,131.250,"Flugplatz"
"Norden Nordeich",,DE,5337.983N,00711.400E,1.0m,5,160,720.0m,121.400,"Flugplatz"
"Nordholz Spieka",,DE,5346.017N,00838.617E,21.0m,2,080,870.0m,121.025,"Flugplatz"
"Northeim",,DE,5142.383N,01002.383E,122.0m,2,110,680.0m,118.700,"Flugplatz"
"Nuernberg",,DE,4929.933N,01104.633E,314.0m,5,100,2700.0m,118.300,"Flugplatz"
"Nussbach",,DE,4832.300N,00802.283E,173.0m,3,120,200.0m,,"Landefeld"
"Oberems",,DE,5014.500N,00823.933E,403.0m,4,130,710.0m,123.350,"Flugplatz"
"Oberhinkofen",,DE,4857.100N,01208.800E,396.0m,4,050,540.0m,122.300,"Flugplatz"
"Ober Moerlen",,DE,5021.717N,00842.683E,247.0m,2,050,800.0m,122.850,"Flugplatz"
"Oberpfaffenhofen",,DE,4804.883N,01116.983E,594.0m,5,040,2280.0m,119.550,"Flugplatz"
"Oberrissdorf",,DE,5132.600N,01135.683E,224.0m,2,140,500.0m,122.200,"Flugplatz"
"Oberrot Glashofe",,DE,4900.600N,00938.333E,488.0m,3,100,250.0m,123.425,"Landefeld"
"Oberschleissheim",,DE,4814.350N,01133.550E,485.0m,5,080,800.0m,129.400,"Flugplatz"
"Obersoellbach",,DE,4911.000N,00933.550E,287.0m,3,150,260.0m,123.425,"Landefeld"
"Oberhamersbach",,DE,4821.967N,00807.033E,290.0m,3,050,250.0m,,"Landefeld"
"Oberkirch",,DE,4832.000N,00803.783E,180.0m,3,130,300.0m,,"Landefeld"
"Oberkollwangen",,DE,4840.850N,00836.917E,683.0m,3,340,260.0m,,"Landefeld"
"Obermehler Schlo",,DE,5116.067N,01038.083E,277.0m,5,110,1450.0m,122.900,"Flugplatz"
"Ochsenfurt",,DE,4940.417N,01004.267E,248.0m,2,100,510.0m,123.000,"Flugplatz"
"Ochsenhausen",,DE,4803.200N,00954.950E,650.0m,4,080,320.0m,123.500,"Flugplatz"
"Oedheim Heli Mil",,DE,4914.483N,00914.067E,156.0m,3,180,420.0m,122.000,"Landefeld"
"Oehna",,DE,5153.983N,01303.183E,85.0m,5,080,850.0m,122.500,"Flugplatz"
"Oelde Bergeler",,DE,5149.833N,00810.483E,82.0m,2,060,550.0m,122.800,"Flugplatz"
"Oerlinghausen",,DE,5155.950N,00839.717E,171.0m,5,040,800.0m,122.175,"Flugplatz"
"Oeventrop Ruhrwi",,DE,5123.767N,00808.667E,241.0m,4,120,440.0m,123.350,"Flugplatz"
"Offenbuettel Ul",,DE,5410.550N,00922.683E,3.0m,3,140,310.0m,123.425,"Landefeld"
"Offenburg",,DE,4826.883N,00755.417E,153.0m,5,020,910.0m,119.750,"Flugplatz"
"Ohlstadt",,DE,4739.467N,01114.033E,655.0m,5,040,880.0m,130.125,"Flugplatz"
"Oldenburg Hatten",,DE,5304.117N,00818.750E,9.0m,2,060,770.0m,118.175,"Flugplatz"
"Oldenburg Cls",,DE,5310.800N,00809.667E,8.0m,3,100,2110.0m,122.100,"Landefeld"
"Oppenheim",,DE,4950.467N,00822.550E,86.0m,2,020,800.0m,122.000,"Flugplatz"
"Oppershausen",,DE,5235.733N,01013.383E,43.0m,4,100,1090.0m,122.475,"Flugplatz"
"Oppingen Au",,DE,4833.400N,00949.333E,681.0m,4,100,690.0m,123.150,"Flugplatz"
"Ortenberg",,DE,4826.533N,00757.667E,159.0m,3,150,400.0m,,"Landefeld"
"Oschatz",,DE,5117.817N,01304.783E,156.0m,2,080,830.0m,122.200,"Flugplatz"
"Oschersleben",,DE,5202.283N,01112.333E,104.0m,2,110,600.0m,129.400,"Flugplatz"
"Osnabruck Atterh",,DE,5217.200N,00758.183E,83.0m,5,090,800.0m,118.675,"Flugplatz"
"Osterholz Scharm",,DE,5312.817N,00848.617E,2.0m,4,130,820.0m,130.125,"Flugplatz"
"Ottengruner Heid",,DE,5013.550N,01143.883E,575.0m,2,100,650.0m,123.000,"Flugplatz"
"Ottenberg Pilsac",,DE,4919.717N,01128.783E,552.0m,4,160,750.0m,122.200,"Flugplatz"
"Paderborn Lippst",,DE,5136.833N,00836.950E,213.0m,5,060,2180.0m,133.375,"Flugplatz"
"Paderborn HaXTer",,DE,5141.317N,00846.550E,241.0m,5,060,1190.0m,125.275,"Flugplatz"
"Paradiek Ul",,DE,5240.083N,00819.283E,39.0m,3,090,620.0m,120.975,"Landefeld"
"Parchim Kl Platz",,DE,5325.117N,01148.100E,44.0m,4,070,750.0m,123.500,"Flugplatz"
"Pasewalk",,DE,5330.317N,01356.900E,23.0m,5,090,900.0m,123.650,"Flugplatz"
"Paterzell",,DE,4750.750N,01103.667E,595.0m,5,180,480.0m,123.500,"Flugplatz"
"Pattonville",,DE,4851.850N,00913.483E,278.0m,5,100,670.0m,123.650,"Flugplatz"
"Peenemuende",,DE,5409.533N,01346.383E,3.0m,5,130,2400.0m,122.475,"Flugplatz"
"Pegnitz Zipser",,DE,4945.733N,01134.467E,543.0m,2,080,880.0m,132.025,"Flugplatz"
"Peine Glindbruch",,DE,5219.417N,01010.900E,68.0m,4,090,640.0m,123.350,"Flugplatz"
"Peissenberg Cls",,DE,4749.967N,01104.000E,606.0m,3,010,850.0m,123.500,"Landefeld"
"Peiting",,DE,4745.500N,01054.500E,745.0m,3,060,300.0m,,"Landefeld"
"Pellworm",,DE,5432.200N,00840.800E,1.0m,2,110,680.0m,123.000,"Flugplatz"
"Pennewitz",,DE,5040.167N,01103.050E,457.0m,2,060,900.0m,123.050,"Flugplatz"
"Perleberg",,DE,5304.233N,01149.083E,31.0m,4,110,1110.0m,122.300,"Flugplatz"
"Pfarrkirchen",,DE,4825.217N,01251.883E,387.0m,2,070,700.0m,119.975,"Flugplatz"
"Pfullendorf",,DE,4754.567N,00915.050E,699.0m,2,010,600.0m,123.250,"Flugplatz"
"Pieverstorf 25M",,DE,5349.100N,01108.683E,27.0m,3,080,320.0m,,"Landefeld"
"Pinnow",,DE,5336.950N,01133.767E,43.0m,2,010,800.0m,122.500,"Flugplatz"
"Pirmasens",,DE,4915.867N,00729.300E,381.0m,5,050,800.0m,122.350,"Flugplatz"
"Pirna Pratzschwi",,DE,5058.783N,01354.517E,122.0m,2,120,900.0m,118.625,"Flugplatz"
"Plaetzer Huenfel",,DE,5042.567N,00944.350E,350.0m,4,160,540.0m,122.200,"Flugplatz"
"Pleidelsheim",,DE,4857.400N,00911.517E,190.0m,4,020,480.0m,123.500,"Flugplatz"
"Plettenberg",,DE,5111.533N,00747.383E,307.0m,2,100,430.0m,122.925,"Flugplatz"
"Ploetzin Ul",,DE,5221.333N,01249.500E,50.0m,3,080,330.0m,123.425,"Landefeld"
"Poel Agrar",,DE,5400.200N,01127.750E,14.0m,3,070,300.0m,,"Landefeld"
"Pohlheim Viehhei",,DE,5031.933N,00844.033E,237.0m,4,080,870.0m,122.150,"Flugplatz"
"Poltringen",,DE,4832.817N,00856.750E,404.0m,5,170,400.0m,123.050,"Flugplatz"
"Porta Westfalica",,DE,5213.267N,00851.583E,44.0m,5,050,860.0m,122.375,"Flugplatz"
"Porta W Gras Gld",,DE,5213.333N,00851.567E,45.0m,3,060,1000.0m,122.500,"Landefeld"
"Pretzschendorf",,DE,5053.033N,01331.850E,490.0m,3,060,780.0m,123.425,"Landefeld"
"Pritzwalk Sommer",,DE,5310.800N,01211.067E,88.0m,2,080,830.0m,122.600,"Flugplatz"
"Preschen Cls",,DE,5139.817N,01438.050E,101.0m,3,060,2400.0m,,"Landefeld"
"Purkshof",,DE,5409.717N,01214.867E,21.0m,2,040,1100.0m,122.400,"Flugplatz"
"Quakenbrueck",,DE,5239.783N,00755.583E,24.0m,4,100,540.0m,122.300,"Flugplatz"
"Radevormwald Ley",,DE,5112.983N,00722.933E,390.0m,4,090,350.0m,123.475,"Flugplatz"
"Radolfzell-Stahr",,DE,4748.167N,00858.767E,421.0m,2,010,710.0m,130.125,"Flugplatz"
"Ramstein Mil",,DE,4926.217N,00736.017E,238.0m,5,080,3200.0m,133.200,"Flugplatz"
"Rastatt Baldenau",,DE,4852.467N,00812.783E,113.0m,4,050,900.0m,122.475,"Flugplatz"
"Regensburg",,DE,4908.517N,01204.917E,396.0m,5,100,640.0m,120.425,"Flugplatz"
"Reichelsheim",,DE,5020.317N,00852.717E,121.0m,5,180,1300.0m,120.425,"Flugplatz"
"Reinheim",,DE,4950.367N,00851.033E,155.0m,4,010,720.0m,124.000,"Flugplatz"
"Reinsdorf",,DE,5154.050N,01311.767E,102.0m,2,100,1280.0m,122.850,"Flugplatz"
"Reiselfingen",,DE,4751.100N,00822.283E,746.0m,4,070,610.0m,123.000,"Flugplatz"
"Reit I Winkel",,DE,4740.417N,01228.700E,689.0m,3,010,250.0m,,"Landefeld"
"Rendsburg Schach",,DE,5413.267N,00936.050E,6.0m,5,030,990.0m,123.650,"Flugplatz"
"Renneritz",,DE,5135.683N,01214.250E,91.0m,2,070,1100.0m,123.475,"Flugplatz"
"Rerik Zweedorf",,DE,5404.917N,01138.933E,9.0m,2,080,640.0m,126.500,"Flugplatz"
"Rheine Bentl Mil",,DE,5217.467N,00723.233E,40.0m,5,090,500.0m,122.100,"Flugplatz"
"Rheine Eschendor",,DE,5216.600N,00729.533E,41.0m,2,110,920.0m,122.050,"Flugplatz"
"Rheinstetten",,DE,4858.667N,00820.550E,116.0m,4,020,1030.0m,123.350,"Flugplatz"
"Riedelbach",,DE,5018.133N,00823.083E,508.0m,4,060,710.0m,130.125,"Flugplatz"
"Riedlingen",,DE,4808.667N,00928.000E,529.0m,4,040,520.0m,129.975,"Flugplatz"
"Riesa Goehlis",,DE,5117.583N,01321.433E,98.0m,5,120,1000.0m,122.600,"Flugplatz"
"Riesa Canitz",,DE,5118.183N,01313.667E,123.0m,4,090,1050.0m,123.500,"Flugplatz"
"Rinteln",,DE,5210.517N,00903.200E,55.0m,5,110,600.0m,122.925,"Flugplatz"
"Roggenhagen Ul",,DE,5340.250N,01323.983E,47.0m,3,110,550.0m,123.425,"Landefeld"
"Roitzschjora",,DE,5134.617N,01229.650E,88.0m,2,100,1200.0m,122.000,"Flugplatz"
"Rosenthal Field",,DE,4951.800N,01147.283E,457.0m,5,090,750.0m,127.450,"Flugplatz"
"Rossfeld",,DE,4830.817N,00920.067E,803.0m,4,070,420.0m,122.475,"Flugplatz"
"Rotenburg Wumme",,DE,5307.700N,00920.917E,27.0m,5,080,800.0m,122.050,"Flugplatz"
"Rothenberg",,DE,4929.150N,00856.167E,479.0m,4,090,640.0m,123.500,"Flugplatz"
"Rothenburg O D T",,DE,4923.300N,01013.100E,399.0m,5,030,950.0m,118.175,"Flugplatz"
"Roth Mil",,DE,4913.050N,01106.000E,387.0m,5,090,530.0m,122.100,"Flugplatz"
"Rothenburg Goerl",,DE,5121.833N,01457.067E,159.0m,5,180,2500.0m,123.250,"Flugplatz"
"Rottach",,DE,4740.950N,01148.150E,761.0m,3,110,260.0m,,"Landefeld"
"Rottweil Zepfenh",,DE,4811.200N,00843.383E,738.0m,5,080,800.0m,129.500,"Flugplatz"
"Rudolstadt Gros",,DE,5043.967N,01114.167E,470.0m,2,070,800.0m,118.325,"Flugplatz"
"Rudesheim",,DE,5001.017N,00753.567E,405.0m,4,360,420.0m,123.500,"Flugplatz"
"Rugen",,DE,5423.000N,01319.533E,21.0m,5,090,900.0m,123.000,"Flugplatz"
"Ruppiner Land",,DE,5247.600N,01245.650E,43.0m,5,110,900.0m,122.500,"Flugplatz"
"Saal Kreuzberg",,DE,5018.533N,01022.400E,266.0m,4,120,590.0m,122.475,"Flugplatz"
"Saarbrucken",,DE,4912.883N,00706.567E,323.0m,5,090,1990.0m,118.350,"Flugplatz"
"Saarlouis Dueren",,DE,4918.750N,00640.450E,341.0m,5,070,800.0m,122.600,"Flugplatz"
"Salzwedel",,DE,5249.683N,01118.983E,33.0m,4,090,810.0m,122.200,"Flugplatz"
"Salzgitter Drutt",,DE,5209.267N,01025.583E,98.0m,5,070,630.0m,122.850,"Flugplatz"
"Salzgitter Schaf",,DE,5201.833N,01021.783E,203.0m,2,110,950.0m,122.500,"Flugplatz"
"Saarmund",,DE,5218.500N,01306.033E,52.0m,2,090,1000.0m,123.650,"Flugplatz"
"Sauldorf Boll",,DE,4757.383N,00902.000E,650.0m,3,020,300.0m,120.975,"Landefeld"
"Saulgau",,DE,4801.767N,00930.433E,582.0m,5,120,450.0m,123.600,"Flugplatz"
"Schoenau3",,DE,4747.150N,00753.983E,536.0m,3,040,400.0m,,"Landefeld"
"Schaefhalde Stei",,DE,4841.550N,01006.017E,628.0m,4,040,770.0m,123.500,"Flugplatz"
"Schameder",,DE,5100.017N,00818.550E,550.0m,2,100,750.0m,122.025,"Flugplatz"
"Scharling",,DE,4740.150N,01144.767E,778.0m,3,090,300.0m,,"Landefeld"
"Schwann Connweil",,DE,4850.300N,00832.583E,480.0m,4,070,330.0m,122.300,"Flugplatz"
"Scheuen Celle",,DE,5240.167N,01005.333E,55.0m,4,080,1120.0m,122.200,"Flugplatz"
"Schlechtenfeld",,DE,4817.083N,00940.400E,562.0m,4,330,300.0m,123.350,"Flugplatz"
"Schleswig Kropp",,DE,5425.533N,00932.517E,15.0m,2,090,820.0m,118.675,"Flugplatz"
"Schlierstadt Sel",,DE,4926.567N,00921.750E,344.0m,2,180,580.0m,122.050,"Flugplatz"
"Schleswig Mil",,DE,5427.567N,00930.983E,21.0m,5,050,2450.0m,122.100,"Flugplatz"
"Schmallenberg",,DE,5109.700N,00815.700E,467.0m,2,090,900.0m,122.425,"Flugplatz"
"Schmidgaden",,DE,4925.767N,01205.883E,380.0m,2,120,520.0m,123.000,"Flugplatz"
"Schmoldow",,DE,5358.367N,01320.583E,24.0m,2,150,900.0m,122.850,"Flugplatz"
"Schnuckenhei Rep",,DE,5242.967N,01032.000E,106.0m,4,110,980.0m,123.475,"Flugplatz"
"Schoenhagen",,DE,5212.217N,01309.500E,40.0m,5,070,1510.0m,131.150,"Flugplatz"
"Schoenberg",,DE,4802.867N,01230.033E,543.0m,2,080,450.0m,118.550,"Flugplatz"
"Schonebeck Zackm",,DE,5159.783N,01147.383E,52.0m,2,070,800.0m,123.000,"Flugplatz"
"Schreckhof Mosba",,DE,4921.050N,00907.267E,270.0m,4,160,300.0m,123.500,"Flugplatz"
"Schwedenstebelul",,DE,5249.350N,01002.400E,71.0m,3,110,290.0m,120.975,"Landefeld"
"Schotten",,DE,5032.083N,00908.733E,500.0m,4,050,380.0m,123.500,"Flugplatz"
"Schwarzenbach So",,DE,4935.517N,00701.900E,493.0m,3,050,380.0m,123.425,"Landefeld"
"Schwarzheide",,DE,5129.383N,01352.733E,101.0m,2,080,850.0m,129.975,"Flugplatz"
"Schwaigern Stet",,DE,4908.500N,00859.250E,237.0m,3,080,350.0m,123.425,"Landefeld"
"Schwandorf",,DE,4920.433N,01211.083E,387.0m,2,110,840.0m,121.200,"Flugplatz"
"Schwerin Parchim",,DE,5325.617N,01147.000E,52.0m,5,060,3000.0m,128.900,"Flugplatz"
"Schwaebisch Hall",,DE,4907.100N,00947.033E,399.0m,5,100,1540.0m,129.225,"Flugplatz"
"Schwabmuenchen",,DE,4810.750N,01042.183E,550.0m,2,080,850.0m,122.500,"Flugplatz"
"Schwenningen A N",,DE,4803.933N,00834.267E,667.0m,5,040,800.0m,122.850,"Flugplatz"
"Schweinfurt-Sud",,DE,5000.633N,01015.083E,210.0m,2,100,980.0m,119.975,"Flugplatz"
"Schwein Mil Heli",,DE,5002.933N,01010.200E,241.0m,5,090,680.0m,122.100,"Flugplatz"
"Schwabisch-H Wec",,DE,4907.450N,00946.867E,399.0m,2,080,550.0m,129.225,"Flugplatz"
"Schoemberg",,DE,4823.550N,00824.783E,723.0m,3,130,400.0m,,"Landefeld"
"Schiltach X",,DE,4817.917N,00821.350E,336.0m,3,040,210.0m,,"Landefeld"
"Schwabach Buchen",,DE,4916.117N,01100.600E,359.0m,5,100,530.0m,135.425,"Flugplatz"
"Schwarzenbrg X",,DE,4836.167N,00822.833E,563.0m,3,060,190.0m,,"Landefeld"
"Schweighofen",,DE,4901.900N,00759.400E,149.0m,2,080,620.0m,123.000,"Flugplatz"
"Schernbach",,DE,4833.800N,00829.617E,675.0m,3,040,430.0m,,"Landefeld"
"Seedorf",,DE,5320.117N,00915.583E,17.0m,2,060,450.0m,119.650,"Flugplatz"
"Segeletz",,DE,5249.600N,01232.550E,39.0m,2,100,920.0m,123.500,"Flugplatz"
"Seissen",,DE,4824.783N,00945.983E,692.0m,4,110,540.0m,123.425,"Flugplatz"
"Sengenthal Ul",,DE,4912.917N,01124.050E,437.0m,3,120,250.0m,123.425,"Landefeld"
"Seussling Prv Ul",,DE,4947.483N,01058.233E,336.0m,3,060,260.0m,123.425,"Landefeld"
"Siegen Eisernhar",,DE,5050.250N,00800.850E,390.0m,4,090,720.0m,123.375,"Flugplatz"
"Siegerland",,DE,5042.467N,00804.983E,601.0m,5,130,1620.0m,120.375,"Flugplatz"
"Sierksdorf Hof A",,DE,5404.033N,01044.567E,28.0m,2,030,500.0m,122.000,"Flugplatz"
"Siewisch Ul",,DE,5141.250N,01412.517E,89.0m,2,080,510.0m,123.425,"Flugplatz"
"Singhofen",,DE,5016.217N,00751.217E,302.0m,4,040,800.0m,123.150,"Flugplatz"
"Sinsheim",,DE,4914.833N,00853.633E,159.0m,2,120,1020.0m,122.475,"Flugplatz"
"Sommerda",,DE,5111.917N,01111.467E,137.0m,2,070,920.0m,124.000,"Flugplatz"
"Soest Bad Sassen",,DE,5134.683N,00812.850E,120.0m,2,070,820.0m,122.600,"Flugplatz"
"Sonnen",,DE,4840.950N,01341.683E,824.0m,5,020,650.0m,122.050,"Flugplatz"
"Sontra Dornberg",,DE,5105.250N,00954.933E,403.0m,4,120,500.0m,123.500,"Flugplatz"
"Spangdahlem Mil",,DE,4958.567N,00641.867E,362.0m,5,050,3180.0m,122.200,"Flugplatz"
"Sperenberg Cls",,DE,5208.233N,01318.100E,46.0m,3,090,1240.0m,,"Landefeld"
"Speyer",,DE,4918.283N,00827.100E,95.0m,5,160,1670.0m,118.075,"Flugplatz"
"Spitzingsee",,DE,4739.150N,01153.400E,1051.0m,3,130,300.0m,,"Landefeld"
"Spremberg Welzow",,DE,5134.617N,01408.217E,116.0m,5,030,2000.0m,134.850,"Flugplatz"
"Sprossen",,DE,5102.600N,01213.983E,206.0m,2,090,740.0m,120.975,"Flugplatz"
"Steinberg 0725",,DE,5257.333N,00733.717E,28.0m,3,070,250.0m,123.500,"Landefeld"
"Stade",,DE,5333.667N,00929.917E,19.0m,5,110,650.0m,123.000,"Flugplatz"
"Stadtlohn Vreden",,DE,5159.750N,00650.433E,49.0m,5,110,1240.0m,119.200,"Flugplatz"
"Stauffenbuehl",,DE,5109.550N,01002.833E,277.0m,4,020,820.0m,123.500,"Flugplatz"
"St Blasien",,DE,4746.517N,00806.733E,801.0m,3,140,250.0m,,"Landefeld"
"Stechow Ferchesa",,DE,5239.050N,01229.283E,42.0m,2,040,610.0m,122.200,"Flugplatz"
"Steinberg Wessel",,DE,5205.017N,01001.100E,180.0m,4,090,720.0m,123.500,"Flugplatz"
"Stendal Borstel",,DE,5237.733N,01149.200E,55.0m,5,080,1990.0m,122.400,"Flugplatz"
"Steinberg Surwol",,DE,5257.383N,00733.417E,29.0m,4,090,860.0m,123.500,"Flugplatz"
"Stillberghof",,DE,4843.850N,01050.117E,510.0m,4,090,710.0m,123.475,"Flugplatz"
"St Michaelisdon",,DE,5358.700N,00908.733E,37.0m,5,070,700.0m,122.500,"Flugplatz"
"Stoelln Rhinow",,DE,5244.450N,01223.467E,40.0m,2,080,840.0m,122.000,"Flugplatz"
"Stolberg Diepenl",,DE,5046.233N,00616.917E,259.0m,4,030,770.0m,123.500,"Flugplatz"
"St Peter Ording",,DE,5418.533N,00841.200E,3.0m,5,070,670.0m,129.775,"Flugplatz"
"Stralsund",,DE,5420.150N,01302.617E,15.0m,2,050,900.0m,118.625,"Flugplatz"
"Strausberg",,DE,5234.800N,01354.933E,78.0m,5,050,1200.0m,123.050,"Flugplatz"
"Straubing",,DE,4854.050N,01231.033E,320.0m,5,090,1350.0m,127.150,"Flugplatz"
"Strassham Ul",,DE,4810.800N,01155.633E,514.0m,3,030,400.0m,123.425,"Landefeld"
"Stude Bernsteins",,DE,5233.817N,01041.050E,73.0m,4,110,920.0m,123.150,"Flugplatz"
"Stuttgart",,DE,4841.400N,00913.317E,390.0m,5,070,3340.0m,119.050,"Flugplatz"
"Suhl Goldlauter",,DE,5037.933N,01043.550E,588.0m,2,100,570.0m,124.550,"Flugplatz"
"Sultmer Berg",,DE,5143.767N,00959.533E,222.0m,4,180,550.0m,123.150,"Flugplatz"
"Sulz Ul",,DE,4820.700N,00838.200E,536.0m,3,040,310.0m,123.425,"Landefeld"
"Sylt",,DE,5454.700N,00820.550E,15.0m,5,140,2120.0m,119.750,"Flugplatz"
"Tannheim",,DE,4800.600N,01005.950E,561.0m,2,090,1020.0m,122.825,"Flugplatz"
"Tarmstedt",,DE,5315.083N,00906.517E,41.0m,4,060,700.0m,123.150,"Flugplatz"
"Tauberbischofshe",,DE,4938.867N,00937.967E,285.0m,4,120,740.0m,122.200,"Flugplatz"
"Tauberbisch Wies",,DE,4939.000N,00938.683E,171.0m,3,150,360.0m,,"Landefeld"
"Taucha",,DE,5123.717N,01232.283E,149.0m,2,070,600.0m,122.400,"Flugplatz"
"Teisendorf Pank",,DE,4749.583N,01250.700E,578.0m,4,150,250.0m,123.500,"Flugplatz"
"Teldau Ul",,DE,5319.700N,01049.983E,5.0m,3,040,320.0m,123.425,"Landefeld"
"Thalmaessing Wai",,DE,4903.850N,01112.567E,577.0m,2,170,410.0m,123.650,"Flugplatz"
"Thannhausen",,DE,4817.400N,01026.517E,491.0m,2,080,500.0m,118.175,"Flugplatz"
"Tirschenreuth",,DE,4952.417N,01219.450E,499.0m,4,080,520.0m,123.500,"Flugplatz"
"Titschendor2 Rwy",,DE,5023.550N,01131.317E,638.0m,3,180,600.0m,122.300,"Landefeld"
"Titisee",,DE,4754.017N,00809.717E,857.0m,3,060,200.0m,,"Landefeld"
"Titschendorf",,DE,5023.833N,01131.367E,650.0m,4,010,480.0m,122.300,"Flugplatz"
"Torgau Beilrode",,DE,5134.267N,01303.133E,82.0m,2,080,800.0m,122.300,"Flugplatz"
"Traben Trarbach",,DE,4958.067N,00706.700E,275.0m,2,180,750.0m,123.000,"Flugplatz"
"Treuchtlingen Bu",,DE,4859.750N,01053.100E,412.0m,2,150,640.0m,122.600,"Flugplatz"
"Trier Foehren",,DE,4951.850N,00647.267E,204.0m,5,040,1200.0m,122.050,"Flugplatz"
"Troestau",,DE,5001.200N,01155.867E,561.0m,4,130,400.0m,123.150,"Flugplatz"
"Trollenberg",,DE,4821.617N,00827.000E,653.0m,3,110,400.0m,,"Landefeld"
"Tutow",,DE,5355.317N,01313.133E,6.0m,5,170,1200.0m,130.125,"Flugplatz"
"Uebersberg",,DE,4827.483N,00917.800E,784.0m,4,080,950.0m,123.150,"Flugplatz"
"Uehrde Ul",,DE,5206.417N,01045.333E,153.0m,3,130,500.0m,123.425,"Landefeld"
"Uelzen",,DE,5259.017N,01027.933E,75.0m,5,080,800.0m,130.900,"Flugplatz"
"Uetersen Heist",,DE,5338.800N,00942.233E,5.0m,2,090,1100.0m,122.700,"Flugplatz"
"Uetersen Segelfl",,DE,5338.967N,00942.350E,5.0m,4,090,1140.0m,123.475,"Flugplatz"
"Ummern",,DE,5237.200N,01024.617E,71.0m,4,130,560.0m,123.500,"Flugplatz"
"Unterbuchen",,DE,4747.017N,01129.133E,635.0m,3,040,300.0m,,"Landefeld"
"Unterwoessen",,DE,4743.783N,01226.283E,565.0m,5,060,800.0m,122.300,"Flugplatz"
"Unterschuepf",,DE,4930.950N,00940.150E,346.0m,2,080,670.0m,122.600,"Flugplatz"
"Unterschwaningen",,DE,4905.167N,01038.083E,476.0m,3,080,300.0m,120.975,"Landefeld"
"Urspring",,DE,4833.233N,00954.167E,642.0m,4,150,610.0m,123.500,"Flugplatz"
"Uslar",,DE,5139.733N,00936.317E,260.0m,4,070,550.0m,129.975,"Flugplatz"
"Utscheid",,DE,4959.867N,00620.583E,421.0m,4,060,720.0m,123.350,"Flugplatz"
"Vaihingen",,DE,4856.183N,00858.817E,312.0m,4,090,1000.0m,129.400,"Flugplatz"
"Varrelbusch",,DE,5254.500N,00802.600E,37.0m,2,090,850.0m,123.000,"Flugplatz"
"Verden Scharnh",,DE,5257.917N,00916.967E,42.0m,2,130,510.0m,122.400,"Flugplatz"
"Vettweiss Soller",,DE,5044.850N,00634.033E,159.0m,3,150,380.0m,120.975,"Landefeld"
"Vielbrunn",,DE,4943.183N,00904.933E,459.0m,4,170,680.0m,123.150,"Flugplatz"
"Vilsbiburg",,DE,4825.583N,01220.733E,442.0m,2,030,450.0m,123.000,"Flugplatz"
"Vilseck Mil",,DE,4938.017N,01146.033E,412.0m,5,100,1080.0m,122.100,"Flugplatz"
"Vilshofen",,DE,4838.083N,01311.800E,302.0m,5,120,1130.0m,119.175,"Flugplatz"
"Vinsebeck Frankn",,DE,5150.683N,00900.817E,247.0m,4,180,510.0m,122.200,"Flugplatz"
"Volkleshofen",,DE,4900.567N,00921.267E,396.0m,4,080,680.0m,130.125,"Flugplatz"
"Vogelsberg Wiese",,DE,4823.750N,00826.950E,680.0m,3,290,250.0m,,"Landefeld"
"Vogtareuth",,DE,4756.767N,01212.283E,471.0m,5,060,590.0m,121.025,"Flugplatz"
"Vorderriss",,DE,4733.550N,01126.267E,810.0m,3,170,300.0m,,"Landefeld"
"Wackersberg",,DE,4744.100N,01133.100E,731.0m,3,100,400.0m,,"Landefeld"
"Wachtersberg Hub",,DE,4836.900N,00845.333E,591.0m,4,070,600.0m,123.475,"Flugplatz"
"Wahlstedt",,DE,5358.167N,01013.300E,40.0m,2,110,800.0m,121.025,"Flugplatz"
"Wasserkuppe",,DE,5029.933N,00957.217E,898.0m,5,060,670.0m,118.650,"Flugplatz"
"Waldeck",,DE,5113.550N,00903.317E,405.0m,4,010,560.0m,123.475,"Flugplatz"
"Walldorf",,DE,4918.283N,00839.550E,103.0m,2,180,500.0m,118.275,"Flugplatz"
"Wallduern",,DE,4934.900N,00924.133E,402.0m,5,060,820.0m,122.750,"Flugplatz"
"Walldorf Ul",,DE,5036.867N,01021.933E,361.0m,3,040,700.0m,123.425,"Landefeld"
"Walsrode Luisenh",,DE,5253.300N,00936.050E,57.0m,4,080,640.0m,123.500,"Flugplatz"
"Waltrop Ul",,DE,5138.400N,00725.567E,50.0m,3,120,370.0m,123.425,"Landefeld"
"WalXHeim Untersc",,DE,4857.217N,01019.517E,509.0m,3,090,300.0m,120.975,"Landefeld"
"Wangerooge",,DE,5346.867N,00755.233E,3.0m,5,100,850.0m,122.400,"Flugplatz"
"Wangen Kissleg",,DE,4745.400N,00951.367E,640.0m,4,120,770.0m,123.500,"Flugplatz"
"Wanlo Niersquell",,DE,5106.067N,00623.617E,74.0m,4,080,540.0m,121.175,"Flugplatz"
"Warburg Heinber",,DE,5129.833N,00905.250E,172.0m,4,130,900.0m,123.500,"Flugplatz"
"Waren Vielist",,DE,5334.067N,01239.117E,85.0m,2,040,800.0m,130.325,"Flugplatz"
"Warbelow Cls",,DE,5359.717N,01242.633E,20.0m,3,070,700.0m,122.100,"Landefeld"
"Warngau Tannried",,DE,4749.467N,01142.250E,723.0m,5,020,550.0m,123.050,"Flugplatz"
"Wasentegernbach",,DE,4816.400N,01213.117E,463.0m,3,060,260.0m,120.975,"Landefeld"
"Wegscheid",,DE,4739.833N,01134.233E,711.0m,3,080,300.0m,,"Landefeld"
"Wehr",,DE,4738.633N,00754.550E,392.0m,3,020,250.0m,,"Landefeld"
"Weidberg Kaltenw",,DE,5036.550N,01005.283E,619.0m,3,140,400.0m,123.425,"Landefeld"
"Weiden Opf",,DE,4940.733N,01207.000E,405.0m,5,140,570.0m,120.250,"Flugplatz"
"Weimar Umpferst",,DE,5057.900N,01124.000E,299.0m,2,100,670.0m,122.400,"Flugplatz"
"Weinheim Bergst",,DE,4934.017N,00836.650E,96.0m,2,170,770.0m,123.600,"Flugplatz"
"Weipertshofen",,DE,4905.183N,01007.483E,440.0m,4,110,470.0m,123.350,"Flugplatz"
"Weissenhorn",,DE,4817.367N,01008.417E,500.0m,2,080,650.0m,119.425,"Flugplatz"
"Weissenburg Wuel",,DE,4901.550N,01101.117E,615.0m,5,050,590.0m,123.050,"Flugplatz"
"Weilerswist",,DE,5043.200N,00651.033E,137.0m,3,040,320.0m,123.425,"Landefeld"
"Welzheim",,DE,4852.583N,00939.217E,518.0m,4,080,520.0m,123.150,"Flugplatz"
"Wenzendorf",,DE,5320.183N,00946.700E,66.0m,4,040,390.0m,123.500,"Flugplatz"
"Weper",,DE,5142.750N,00948.167E,360.0m,4,350,450.0m,123.500,"Flugplatz"
"Werdohl Kuentrop",,DE,5117.817N,00749.050E,307.0m,2,070,810.0m,118.000,"Flugplatz"
"Werneuchen",,DE,5237.917N,01346.467E,79.0m,5,080,1490.0m,122.600,"Flugplatz"
"Werneck Ul",,DE,4959.300N,01000.583E,281.0m,3,070,210.0m,120.975,"Landefeld"
"Wershofen Eifel",,DE,5027.100N,00647.067E,476.0m,2,070,630.0m,122.400,"Flugplatz"
"Wertheim Ul",,DE,4943.550N,00930.367E,304.0m,3,070,260.0m,120.975,"Landefeld"
"Wesel Romerwardt",,DE,5139.767N,00635.750E,21.0m,2,090,720.0m,122.025,"Flugplatz"
"Weser Wuemme",,DE,5303.233N,00912.517E,18.0m,2,180,850.0m,122.600,"Flugplatz"
"Westhausen",,DE,5018.250N,01040.817E,301.0m,3,140,300.0m,,"Landefeld"
"Westerstede Feld",,DE,5317.317N,00755.850E,8.0m,5,060,570.0m,123.650,"Flugplatz"
"Wiefelstede Conn",,DE,5319.283N,00804.400E,7.0m,2,120,600.0m,126.500,"Flugplatz"
"Wiesbaden Mil",,DE,5002.983N,00819.517E,140.0m,5,070,2140.0m,122.100,"Flugplatz"
"Wildberg Bodense",,DE,4736.017N,00944.517E,520.0m,4,030,490.0m,118.550,"Flugplatz"
"Wilhelmshavn Ma",,DE,5330.133N,00803.133E,6.0m,5,020,1450.0m,129.250,"Flugplatz"
"Wildbergkengel",,DE,4838.200N,00843.833E,509.0m,4,080,600.0m,123.000,"Flugplatz"
"Wilsche",,DE,5231.483N,01027.683E,60.0m,2,090,500.0m,129.975,"Flugplatz"
"Winzeln Schrambe",,DE,4816.750N,00825.700E,670.0m,5,140,700.0m,123.650,"Flugplatz"
"Wipperfurth Neye",,DE,5107.483N,00722.333E,265.0m,2,100,600.0m,122.400,"Flugplatz"
"Wismar",,DE,5354.883N,01130.083E,12.0m,2,080,640.0m,123.050,"Flugplatz"
"Wittstock Berlin",,DE,5313.550N,01234.067E,79.0m,4,050,700.0m,122.200,"Flugplatz"
"Wittstock Cls",,DE,5312.150N,01231.367E,71.0m,3,080,2400.0m,,"Landefeld"
"Wittmundhafe Mil",,DE,5332.867N,00740.050E,9.0m,5,080,2450.0m,118.725,"Flugplatz"
"Witzenhausen",,DE,5121.000N,00949.483E,204.0m,4,350,400.0m,123.500,"Flugplatz"
"Woermlitz Ul",,DE,5210.200N,01149.667E,72.0m,3,080,580.0m,123.425,"Landefeld"
"Worishofen",,DE,4801.617N,01036.133E,616.0m,4,080,630.0m,123.350,"Flugplatz"
"Wolfhagen Graner",,DE,5118.433N,00910.517E,314.0m,2,150,500.0m,127.450,"Flugplatz"
"Worms",,DE,4936.383N,00822.100E,91.0m,5,060,800.0m,124.600,"Flugplatz"
"Wurzburg",,DE,4949.067N,00953.850E,297.0m,5,110,670.0m,122.175,"Flugplatz"
"Wuerzbach",,DE,4843.117N,00838.283E,684.0m,3,050,400.0m,,"Landefeld"
"Wunstorf Mil",,DE,5227.433N,00925.633E,58.0m,5,080,1870.0m,122.100,"Flugplatz"
"Wustweiler Cls",,DE,4924.633N,00703.300E,368.0m,3,070,360.0m,122.475,"Landefeld"
"Wyk Auf Foehr",,DE,5441.117N,00831.917E,9.0m,2,020,660.0m,118.250,"Flugplatz"
"Zellhausen",,DE,5001.233N,00859.017E,113.0m,4,170,860.0m,122.300,"Flugplatz"
"Zell Haidberg",,DE,5008.217N,01147.667E,583.0m,2,060,800.0m,123.375,"Flugplatz"
"Zerbst",,DE,5200.133N,01209.167E,80.0m,5,070,750.0m,123.050,"Flugplatz"
"Zierenberg Dornb",,DE,5121.750N,00920.383E,423.0m,4,170,380.0m,122.300,"Flugplatz"
"Zschorna",,DE,5123.783N,01249.400E,132.0m,3,160,280.0m,123.425,"Landefeld"
"Zweibruecken",,DE,4912.567N,00724.033E,345.0m,5,030,2670.0m,123.825,"Flugplatz"
"Zwickau",,DE,5042.067N,01227.167E,316.0m,2,060,800.0m,122.900,"Flugplatz"

57281
tests/SeeYou.cup 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,7 +1,7 @@
#DEVICE_TYPE,DEVICE_ID,AIRCRAFT_MODEL,REGISTRATION,CN,TRACKED,IDENTIFIED
'F','DD4711','HK36 TTC','D-EULE','CU','Y','Y'
'F','DD0815','Ventus 2cxM','D-1234','','Y','N'
'F','DD1234','LS 8 18m','D-8654','12','N','Y'
'F','DD3141','Arcus T','OE-4321','','N','N'
'O','DEADBE','Baloon','OE-ABC','','Y','Y'
'I','999999','A380','G-XXXL','XXL','Y','Y'
#DEVICE_TYPE,DEVICE_ID,AIRCRAFT_MODEL,REGISTRATION,CN,TRACKED,IDENTIFIED,AIRCRAFT_TYPE
'F','DD4711','HK36 TTC','D-EULE','CU','Y','Y','1'
'F','DD0815','Ventus 2cxM','D-1234','','Y','N','1'
'F','DD1234','LS 8 18m','D-8654','12','N','Y','1'
'F','DD3141','Arcus T','OE-4321','','N','N','1'
'O','DEADBE','Baloon','OE-ABC','','Y','Y','11'
'I','999999','A380','G-XXXL','XXL','Y','Y','9'

Wyświetl plik

@ -2,7 +2,7 @@ import unittest
import unittest.mock as mock
from ogn.utils import get_ddb, get_trackable, get_country_code
from ogn.model import AddressOrigin
from ogn.model import AircraftType
class TestStringMethods(unittest.TestCase):
@ -21,8 +21,7 @@ class TestStringMethods(unittest.TestCase):
self.assertEqual(device.competition, 'CU')
self.assertTrue(device.tracked)
self.assertTrue(device.identified)
self.assertEqual(device.address_origin, AddressOrigin.user_defined)
self.assertEqual(device.aircraft_type, AircraftType.glider_or_motor_glider)
def test_get_trackable(self):
devices = get_ddb('tests/custom_ddb.txt')