diff --git a/ogn/collect/ognrange.py b/ogn/collect/ognrange.py index 043b933..386aee2 100644 --- a/ogn/collect/ognrange.py +++ b/ogn/collect/ognrange.py @@ -27,20 +27,20 @@ def create_receiver_coverage(session=None, date=None): else: (start, end) = date_to_timestamps(date) - # Filter aircraft beacons and shrink precision of MGRS from 1m to 1km resolution: 30UXC 00061 18429 -> 30UXC 00 18 - sq = session.query((func.left(AircraftBeacon.location_mgrs, 5, type_=String) + func.substring(AircraftBeacon.location_mgrs, 6, 2, type_=String) + func.substring(AircraftBeacon.location_mgrs, 11, 2, type_=String)).label('reduced_mgrs'), + # Filter aircraft beacons + sq = session.query(AircraftBeacon.location_mgrs_short.label('location_mgrs'), AircraftBeacon.receiver_id, AircraftBeacon.signal_quality, AircraftBeacon.altitude, AircraftBeacon.device_id) \ .filter(and_(between(AircraftBeacon.timestamp, start, end), - AircraftBeacon.location_mgrs != null(), + AircraftBeacon.location_mgrs_short != null(), AircraftBeacon.receiver_id != null(), AircraftBeacon.device_id != null())) \ .subquery() # ... and group them by reduced MGRS, receiver and date - query = session.query(sq.c.reduced_mgrs, + query = session.query(sq.c.location_mgrs, sq.c.receiver_id, func.cast(date, Date).label('date'), func.max(sq.c.signal_quality).label('max_signal_quality'), @@ -54,7 +54,7 @@ def create_receiver_coverage(session=None, date=None): # if a receiver coverage entry exist --> update it upd = update(ReceiverCoverage) \ - .where(and_(ReceiverCoverage.location_mgrs == query.c.reduced_mgrs, + .where(and_(ReceiverCoverage.location_mgrs == query.c.location_mgrs, ReceiverCoverage.receiver_id == query.c.receiver_id, ReceiverCoverage.date == date)) \ .values({"max_signal_quality": query.c.max_signal_quality, diff --git a/ogn/commands/bulkimport.py b/ogn/commands/bulkimport.py index 088d313..442c5ca 100644 --- a/ogn/commands/bulkimport.py +++ b/ogn/commands/bulkimport.py @@ -92,6 +92,7 @@ class LogfileDbSaver(): radial smallint, quality real, location_mgrs character varying(15), + location_mgrs_short character varying(9), receiver_id int, device_id int); @@ -246,6 +247,7 @@ class LogfileDbSaver(): ab.frequency_offset, ab.gps_quality_horizontal, ab.gps_quality_vertical, ab.software_version, ab.hardware_version, ab.real_address, ab.signal_power, ab.location_mgrs, + ab.location_mgrs_short, d.id AS device_id, r.id AS receiver_id, @@ -302,6 +304,7 @@ class LogfileDbSaver(): CAST(MAX(quality) AS REAL) AS quality, CAST(MAX(agl) AS REAL) AS agl, MAX(location_mgrs) AS location_mgrs, + MAX(location_mgrs_short) AS location_mgrs_short, MAX(receiver_id) AS receiver_id, MAX(device_id) AS device_id @@ -362,7 +365,7 @@ class LogfileDbSaver(): query = """ INSERT INTO aircraft_beacons(location, altitude, name, dstcall, relay, receiver_name, timestamp, track, ground_speed, address_type, aircraft_type, stealth, address, climb_rate, turn_rate, signal_quality, error_count, frequency_offset, gps_quality_horizontal, gps_quality_vertical, software_version, hardware_version, real_address, signal_power, - distance, radial, quality, agl, location_mgrs, + distance, radial, quality, agl, location_mgrs, location_mgrs_short, receiver_id, device_id) {} ON CONFLICT DO NOTHING; @@ -515,7 +518,7 @@ def convert(sourcefile, datestr, saver): if message['beacon_type'] in AIRCRAFT_TYPES: message = dictfilt(message, ('beacon_type', 'aprs_type', 'location_wkt', 'altitude', 'name', 'dstcall', 'relay', 'receiver_name', 'timestamp', 'track', 'ground_speed', 'address_type', 'aircraft_type', 'stealth', 'address', 'climb_rate', 'turn_rate', 'signal_quality', 'error_count', 'frequency_offset', 'gps_quality_horizontal', 'gps_quality_vertical', 'software_version', 'hardware_version', 'real_address', 'signal_power', - 'distance', 'radial', 'quality', 'agl', 'location_mgrs', + 'distance', 'radial', 'quality', 'agl', 'location_mgrs', 'location_mgrs_short', 'receiver_id', 'device_id')) beacon = AircraftBeacon(**message) diff --git a/ogn/gateway/process.py b/ogn/gateway/process.py index 8986efa..2f105d8 100644 --- a/ogn/gateway/process.py +++ b/ogn/gateway/process.py @@ -18,7 +18,9 @@ def _replace_lonlat_with_wkt(message): location = Location(longitude, latitude) message['location_wkt'] = location.to_wkt() - message['location_mgrs'] = myMGRS.toMGRS(latitude, longitude).decode('utf-8') + location_mgrs = myMGRS.toMGRS(latitude, longitude).decode('utf-8') + message['location_mgrs'] = location_mgrs + message['location_mgrs_short'] = location_mgrs[0:5] + location_mgrs[5:7] + location_mgrs[10:12] del message['latitude'] del message['longitude'] return message diff --git a/ogn/model/aircraft_beacon.py b/ogn/model/aircraft_beacon.py index a52f2e7..4360ec2 100644 --- a/ogn/model/aircraft_beacon.py +++ b/ogn/model/aircraft_beacon.py @@ -29,7 +29,8 @@ class AircraftBeacon(Beacon): distance = Column(Float(precision=2)) radial = Column(SmallInteger) quality = Column(Float(precision=2)) # signal quality normalized to 10km - location_mgrs = Column(String(15)) + location_mgrs = Column(String(15)) # full mgrs (15 chars) + location_mgrs_short = Column(String(9)) # reduced mgrs (9 chars), e.g. used for melissas range tool agl = Column(Float(precision=2)) # Relations @@ -44,7 +45,7 @@ class AircraftBeacon(Beacon): Index('ix_aircraft_beacons_device_id_timestamp', 'device_id', 'timestamp') def __repr__(self): - return "" % ( + return "" % ( self.address_type, self.aircraft_type, self.stealth, @@ -64,7 +65,8 @@ class AircraftBeacon(Beacon): self.distance, self.radial, self.quality, - self.location_mgrs) + self.location_mgrs, + self.location_mgrs_short) @classmethod def get_columns(self): @@ -100,7 +102,8 @@ class AircraftBeacon(Beacon): 'distance', 'radial', 'quality', - 'location_mgrs'] + 'location_mgrs', + 'location_mgrs_short'] def get_values(self): return [ @@ -136,7 +139,8 @@ class AircraftBeacon(Beacon): self.distance, self.radial, self.quality, - self.location_mgrs] + self.location_mgrs, + self.location_mgrs_short] Index('ix_aircraft_beacons_date_device_id_address', func.date(AircraftBeacon.timestamp), AircraftBeacon.device_id, AircraftBeacon.address) diff --git a/tests/collect/test_ognrange.py b/tests/collect/test_ognrange.py index b7ddd11..03e8fd5 100644 --- a/tests/collect/test_ognrange.py +++ b/tests/collect/test_ognrange.py @@ -35,8 +35,8 @@ class TestDB(unittest.TestCase): session.commit() # Create beacons and insert - self.ab01 = AircraftBeacon(name='FLRDD0815', receiver_name='Koenigsdf', device_id=self.dd0815.id, receiver_id=self.r01.id, timestamp='2017-12-10 10:00:00', location_mgrs='89ABC1234567890', altitude=800) - self.ab02 = AircraftBeacon(name='FLRDD0815', receiver_name='Koenigsdf', device_id=self.dd0815.id, receiver_id=self.r01.id, timestamp='2017-12-10 10:00:01', location_mgrs='89ABC1299967999', altitude=850) + self.ab01 = AircraftBeacon(name='FLRDD0815', receiver_name='Koenigsdf', device_id=self.dd0815.id, receiver_id=self.r01.id, timestamp='2017-12-10 10:00:00', location_mgrs_short='89ABC1267', altitude=800) + self.ab02 = AircraftBeacon(name='FLRDD0815', receiver_name='Koenigsdf', device_id=self.dd0815.id, receiver_id=self.r01.id, timestamp='2017-12-10 10:00:01', location_mgrs_short='89ABC1267', altitude=850) session.add(self.ab01) session.add(self.ab02) session.commit()