def remove_geo_db(): """ Remove the db """ remove_all_sectors() remove_all_airports() remove_all_user_defined_sectors() tear_down()
def test_find_standard_sector_intersections(self): connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT # Start with no sectors remove_all_sectors() # Add the simple sector ok, sector_1_id = add_airspace_geometry(self.sector_1, context, connection) self.assertTrue(ok) # Flight terminates in the sector terminates = find_horizontal_sector_intersections( *self.TERMINATES_FLIGHT) terminates_lats = terminates[0] terminates_lons = terminates[1] terminates_ids = terminates[2] self.assertEqual(1, len(terminates_lats)) self.assertEqual(1, len(terminates_lons)) self.assertEqual(1, len(terminates_ids)) sectors = find_airspace_by_database_ID(str(terminates_ids[0]), context, connection) self.assertEqual(1, len(sectors)) self.assertEqual(sectors[0][6], 'Made Up Sector') # Flight transits the sector transits = find_horizontal_sector_intersections(*self.TRANSIT_FLIGHT) transit_lats = transits[0] transit_lons = transits[1] transit_ids = transits[2] self.assertEquals(2, len(transit_lats)) self.assertEquals(2, len(transit_lons)) self.assertEquals(2, len(transit_ids)) # Flight transits the sector above the sector transits = find_horizontal_sector_intersections( *self.TRANSIT_TOO_HIGH_FLIGHT) transit_lats = transits[0] transit_lons = transits[1] transit_ids = transits[2] self.assertEquals(0, len(transit_lats)) self.assertEquals(0, len(transit_lons)) self.assertEquals(0, len(transit_ids)) # Flight originates in the sector originates = find_horizontal_sector_intersections( *self.ORIGINATES_FLIGHT) originates_lats = originates[0] originates_lons = originates[1] originates_ids = originates[2] self.assertEquals(2, len(originates_lats)) self.assertEquals(2, len(originates_lons)) self.assertEquals(2, len(originates_ids))
def test_find_standard_sector_intersections_with_segments(self): """ A more complex sector shape. A combe with three legs. """ connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT # Start with no sectors remove_all_sectors() # Add combe like sector to the sectors database ok, sector_2_id = add_airspace_geometry(self.sector_2, context, connection) self.assertTrue(ok) # Terminates in the sector terminates = find_horizontal_sector_intersections( *self.TERMINATES_IN_COMBE_FLIGHT) terminates_lats = terminates[0] terminates_lons = terminates[1] terminates_ids = terminates[2] self.assertEquals(5, len(terminates_lats)) self.assertEquals(5, len(terminates_lons)) self.assertEquals(5, len(terminates_ids)) # Transits the sector transits = find_horizontal_sector_intersections( *self.TRANSITS_COMBE_FLIGHT) transit_lats = transits[0] transit_lons = transits[1] transit_ids = transits[2] self.assertEquals(6, len(transit_lats)) self.assertEquals(6, len(transit_lons)) self.assertEquals(6, len(transit_ids)) # Originates in the sector, should be an even number as we add in the # position if we originate originates = find_horizontal_sector_intersections( *self.ORIGINATES_IN_COMBE_FLIGHT) origin_lats = originates[0] origin_lons = originates[1] origin_sector_ids = originates[2] self.assertEquals(6, len(origin_lats)) self.assertEquals(6, len(origin_lons)) self.assertEquals(6, len(origin_sector_ids))
def initialise_airspace(sector_file_path, reset=False): """ Uses the provided file path to load the sectors file, may be csv or geojson. If no sectors file is found we return false. Reset=True Remove all and replace with this file. Reset=False Add these sectors to the sectors table. Note, this is not an update. return True if we succeeded A tuple of (False, message) if we fail """ connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT if os.path.exists(sector_file_path): if reset: remove_all_sectors() load_airspace(sector_file_path, context, connection) return True else: return (False, "Path not found " + sector_file_path)
def test_find_user_cylinder_intersections(self): connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT remove_all_sectors() # Define a trajectory FLIGHT_ID_1 = "test-id-1" MIN_ALT_1 = 10090 MAX_ALT_1 = 20090 LATS_1 = [ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ] LONS_1 = [-10.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 10.5] # This one is above our test sector FLIGHT_ID_2 = "test-id-2" MIN_ALT_2 = 30000 MAX_ALT_2 = 60000 LATS_2 = [ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ] LONS_2 = [-10.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 10.5] # Define a custom sector ORG_ID = "PRU" USER_ID = "user-name-1" SECTOR_ID = "test-cylinder_user_sector-1-poly" MIN_FL = 10 MAX_FL = 150 LAT = 50.0 LON = 0.0 RADIUS = 20 IS_CYLINDER = "True" USER_SECTOR_1_WKT = "" user_cylinder_sector_1 = \ [ORG_ID, USER_ID, SECTOR_ID, LAT, LON, RADIUS, MIN_FL, MAX_FL, IS_CYLINDER, USER_SECTOR_1_WKT] # Add a custom sector to the user sectors ok, sector_1_id = add_user_sector(user_cylinder_sector_1, context, connection) self.assertTrue(ok) # Find known intersecting trajectory intersections res1 = find_horizontal_user_airspace_intersections( FLIGHT_ID_1, LATS_1, LONS_1, MIN_ALT_1, MAX_ALT_1) self.assertTrue(res1) # There should be at least one intersection with our artifical sector self.assertTrue(str(sector_1_id) in res1[2]) # Find the sector descriptive name self.assertEquals("PRU/user-name-1/test-cylinder_user_sector-1-poly", get_user_sector_name(sector_1_id)) # Find the sector altitude range self.assertEquals((1000, 15000), get_user_sector_altitude_range(sector_1_id)) # Find known non-intersecting trajectory intersections res2 = find_horizontal_user_airspace_intersections( FLIGHT_ID_2, LATS_2, LONS_2, MIN_ALT_2, MAX_ALT_2) # There should be no intersections with our artificial sector self.assertFalse(str(sector_1_id) in res2[2]) connection.close()
def test_find_user_sector_intersections_non_cylinder(self): connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT remove_all_sectors() # Define a trajectory FLIGHT_ID_1 = "test-id-1" MIN_ALT_1 = 1009 MAX_ALT_1 = 2009 LATS_1 = [ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ] LONS_1 = [-0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5] FLIGHT_ID_2 = "test-id-2" MIN_ALT_2 = 300 MAX_ALT_2 = 500 LATS_2 = [ 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0 ] LONS_2 = [-0.5, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, 0.5] # Define a custom sector ORG_ID = "PRU" USER_ID = "user-name-1" SECTOR_ID = "test-sector-1-poly" MIN_FL = 10 MAX_FL = 150 LAT = None LON = None RADIUS = 0 IS_CYLINDER = False USER_SECTOR_1_WKT = "POLYGON ((-0.3 50.5, 0.3 50.5, 0.3 49.5, -0.3 49.5, -0.3 50.5))" user_sector_1 = [ ORG_ID, USER_ID, SECTOR_ID, LAT, LON, RADIUS, MIN_FL, MAX_FL, IS_CYLINDER, USER_SECTOR_1_WKT ] # Add a custom sector to the user sectors ok, sector_1_id = add_user_sector(user_sector_1, context, connection) self.assertTrue(ok) # Find known intersecting trajectory intersections res1 = find_horizontal_user_airspace_intersections( FLIGHT_ID_1, LATS_1, LONS_1, MIN_ALT_1, MAX_ALT_1) self.assertTrue(res1) # There should be at least one intersection with our artifical sector self.assertTrue(str(sector_1_id) in res1[2]) # recover the sector ids recovered_sector_id_1 = [ id for id in res1[2] if str(sector_1_id) == id ][0] recovered_sector_id_2 = [ id for id in res1[2] if str(sector_1_id) == id ][1] # Find the sector descriptive name self.assertEquals("PRU/user-name-1/test-sector-1-poly", get_user_sector_name(recovered_sector_id_1)) self.assertEquals("PRU/user-name-1/test-sector-1-poly", get_user_sector_name(recovered_sector_id_2)) # Find the sector altitude ranges self.assertEquals( (1000, 15000), get_user_sector_altitude_range(recovered_sector_id_1)) self.assertEquals( (1000, 15000), get_user_sector_altitude_range(recovered_sector_id_2)) # Find known non-intersecting trajectory intersections res2 = find_horizontal_user_airspace_intersections( FLIGHT_ID_2, LATS_2, LONS_2, MIN_ALT_2, MAX_ALT_2) # There should be no intersections with our artificial sector self.assertFalse(str(sector_1_id) in res2[2]) connection.close()
def test_find_qudrant_intersections(self): """ Test against a four section (quadrants) airspace. See Trajectories Production Airspace Intersections Report Test Sectors, page 18. """ AC_ID_A1 = "990" AV_AIRSPACE_ID_A1 = "SYNTHA1" AV_ICAO_STATE_ID_A1 = "CS" MIN_FLIGHT_LEVEL_A1 = "0" MAX_FLIGHT_LEVEL_A1 = "200" AV_NAME_A1 = "Square A1" SECTOR_TYPE_A1 = "ES" OBJECT_ID_A1 = 2399999 SECTOR_A1_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "1.00000000 0.00000000 0.00000000, " + \ "1.00000000 1.00000000 0.00000000, " + \ "0.00000000 1.000000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_A2 = "989" AV_AIRSPACE_ID_A2 = "SYNTHA2" AV_ICAO_STATE_ID_A2 = "CS" MIN_FLIGHT_LEVEL_A2 = "0" MAX_FLIGHT_LEVEL_A2 = "200" AV_NAME_A2 = "Square A2" SECTOR_TYPE_A2 = "ES" OBJECT_ID_A2 = 2399999 SECTOR_A2_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "-1.000000000 0.000000000 0.00000000, " + \ "-1.00000000 1.00000000 0.00000000, " + \ "0.000000000 1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_A3 = "979" AV_AIRSPACE_ID_A3 = "SYNTHA3" AV_ICAO_STATE_ID_A3 = "CS" MIN_FLIGHT_LEVEL_A3 = "0" MAX_FLIGHT_LEVEL_A3 = "200" AV_NAME_A3 = "Square A3" SECTOR_TYPE_A3 = "ES" OBJECT_ID_A3 = 2399999 SECTOR_A3_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "-1.000000000 0.000000000 0.00000000, " + \ "-1.00000000 -1.00000000 0.00000000, " + \ "0.000000000 -1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_A4 = "969" AV_AIRSPACE_ID_A4 = "SYNTHA4" AV_ICAO_STATE_ID_A4 = "CS" MIN_FLIGHT_LEVEL_A4 = "0" MAX_FLIGHT_LEVEL_A4 = "200" AV_NAME_A4 = "Square A3" SECTOR_TYPE_A4 = "ES" OBJECT_ID_A4 = 2399999 SECTOR_A4_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "1.000000000 0.000000000 0.00000000, " + \ "1.00000000 -1.00000000 0.00000000, " + \ "0.000000000 -1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" sector_A1 = [ AC_ID_A1, AV_AIRSPACE_ID_A1, AV_ICAO_STATE_ID_A1, MIN_FLIGHT_LEVEL_A1, MAX_FLIGHT_LEVEL_A1, AV_NAME_A1, SECTOR_TYPE_A1, OBJECT_ID_A1, SECTOR_A1_WKT ] sector_A2 = [ AC_ID_A2, AV_AIRSPACE_ID_A2, AV_ICAO_STATE_ID_A2, MIN_FLIGHT_LEVEL_A2, MAX_FLIGHT_LEVEL_A2, AV_NAME_A2, SECTOR_TYPE_A2, OBJECT_ID_A2, SECTOR_A2_WKT ] sector_A3 = [ AC_ID_A3, AV_AIRSPACE_ID_A3, AV_ICAO_STATE_ID_A3, MIN_FLIGHT_LEVEL_A3, MAX_FLIGHT_LEVEL_A3, AV_NAME_A3, SECTOR_TYPE_A3, OBJECT_ID_A3, SECTOR_A3_WKT ] sector_A4 = [ AC_ID_A4, AV_AIRSPACE_ID_A4, AV_ICAO_STATE_ID_A4, MIN_FLIGHT_LEVEL_A4, MAX_FLIGHT_LEVEL_A4, AV_NAME_A4, SECTOR_TYPE_A4, OBJECT_ID_A4, SECTOR_A4_WKT ] AC_ID_B1 = "990" AV_AIRSPACE_ID_B1 = "SYNTHB1" AV_ICAO_STATE_ID_1 = "CS" MIN_FLIGHT_LEVEL_1 = "0" MAX_FLIGHT_LEVEL_1 = "200" AV_NAME_1 = "Square B1" SECTOR_TYPE_1 = "ES" OBJECT_ID_1 = 2399999 SECTOR_B1_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "1.00000000 0.00000000 0.00000000, " + \ "1.00000000 1.00000000 0.00000000, " + \ "0.00000000 1.000000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_B2 = "989" AV_AIRSPACE_ID_B2 = "SYNTHB2" AV_ICAO_STATE_ID_2 = "CS" MIN_FLIGHT_LEVEL_2 = "0" MAX_FLIGHT_LEVEL_2 = "200" AV_NAME_2 = "Square B2" SECTOR_TYPE_2 = "ES" OBJECT_ID_2 = 2399999 SECTOR_B2_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "-1.000000000 0.000000000 0.00000000, " + \ "-1.00000000 1.00000000 0.00000000, " + \ "0.000000000 1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_B3 = "979" AV_AIRSPACE_ID_B3 = "SYNTHB3" AV_ICAO_STATE_ID_3 = "CS" MIN_FLIGHT_LEVEL_3 = "0" MAX_FLIGHT_LEVEL_3 = "200" AV_NAME_3 = "Square B3" SECTOR_TYPE_3 = "ES" OBJECT_ID_3 = 2399999 SECTOR_B3_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "-1.000000000 0.000000000 0.00000000, " + \ "-1.00000000 -1.00000000 0.00000000, " + \ "0.000000000 -1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" AC_ID_B4 = "969" AV_AIRSPACE_ID_B4 = "SYNTHB4" AV_ICAO_STATE_ID_4 = "CS" MIN_FLIGHT_LEVEL_4 = "0" MAX_FLIGHT_LEVEL_4 = "200" AV_NAME_4 = "Square B4" SECTOR_TYPE_4 = "ES" OBJECT_ID_4 = 2399999 SECTOR_B4_WKT = "POLYGON Z (( 0.00000000 0.00000000 0.00000000, " + \ "1.000000000 0.000000000 0.00000000, " + \ "1.00000000 -1.00000000 0.00000000, " + \ "0.000000000 -1.00000000 0.00000000, " + \ "0.00000000 0.00000000 0.00000000))" sector_B1 = [ AC_ID_B1, AV_AIRSPACE_ID_B1, AV_ICAO_STATE_ID_1, MIN_FLIGHT_LEVEL_1, MAX_FLIGHT_LEVEL_1, AV_NAME_1, SECTOR_TYPE_1, OBJECT_ID_1, SECTOR_B1_WKT ] sector_B2 = [ AC_ID_B2, AV_AIRSPACE_ID_B2, AV_ICAO_STATE_ID_2, MIN_FLIGHT_LEVEL_2, MAX_FLIGHT_LEVEL_2, AV_NAME_2, SECTOR_TYPE_2, OBJECT_ID_2, SECTOR_B2_WKT ] sector_B3 = [ AC_ID_B3, AV_AIRSPACE_ID_B3, AV_ICAO_STATE_ID_3, MIN_FLIGHT_LEVEL_3, MAX_FLIGHT_LEVEL_3, AV_NAME_3, SECTOR_TYPE_3, OBJECT_ID_3, SECTOR_B3_WKT ] sector_B4 = [ AC_ID_B4, AV_AIRSPACE_ID_B4, AV_ICAO_STATE_ID_4, MIN_FLIGHT_LEVEL_4, MAX_FLIGHT_LEVEL_4, AV_NAME_4, SECTOR_TYPE_4, OBJECT_ID_4, SECTOR_B4_WKT ] # test trajectory, southwest to north east FLIGHT_ID_1 = "sw-ne" MIN_ALT_1 = 0 MAX_ALT_1 = 600 LATS_1 = [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5] LONS_1 = [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5] FLIGHT_SW_NE = (FLIGHT_ID_1, LATS_1, LONS_1, MIN_ALT_1, MAX_ALT_1) # test trajectory, south to north FLIGHT_ID_2 = "s-n" MIN_ALT_2 = 0 MAX_ALT_2 = 600 LATS_2 = [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5] LONS_2 = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5] FLIGHT_S_N = (FLIGHT_ID_2, LATS_2, LONS_2, MIN_ALT_2, MAX_ALT_2) connection = ctx.get_connection(ctx.CONTEXT, ctx.DB_USER) context = ctx.CONTEXT # Start with no sectors remove_all_sectors() ok1, sector_1_id = add_airspace_geometry(sector_B1, context, connection) self.assertTrue(ok1) ok2, sector_2_id = add_airspace_geometry(sector_B2, context, connection) self.assertTrue(ok2) ok3, sector_3_id = add_airspace_geometry(sector_B3, context, connection) self.assertTrue(ok3) ok4, sector_4_id = add_airspace_geometry(sector_B4, context, connection) self.assertTrue(ok4) quad_sectors = [sector_1_id, sector_2_id, sector_3_id, sector_4_id] sector_b_sw_ne_intersections = find_horizontal_sector_intersections( *FLIGHT_SW_NE) # We should find six points of intersection, 1 at the sw corner, 4 in # the middle and 1 at the ne corner. self.assertEquals(6, len(sector_b_sw_ne_intersections[0])) sector_b_s_n_intersections = find_horizontal_sector_intersections( *FLIGHT_S_N) # Should find 4 intersections, 1 at southern boundary, # 2 in the common boundary and 1 at the northern boundary. self.assertEquals(4, len(sector_b_s_n_intersections[0]))