Esempio n. 1
0
def get_elevations_for_flight(flight):
    cached_elevations = cache.get("elevations_" + flight.__repr__())
    if cached_elevations:
        return cached_elevations

    """
    WITH src AS
        (SELECT ST_DumpPoints(flights.locations) AS location,
                flights.timestamps AS timestamps,
                flights.locations AS locations
        FROM flights
        WHERE flights.id = 30000)
    SELECT timestamps[(src.location).path[1]] AS timestamp,
           ST_Value(elevations.rast, (src.location).geom) AS elevation
    FROM elevations, src
    WHERE src.locations && elevations.rast AND (src.location).geom && elevations.rast;
    """

    # Prepare column expressions
    location = Flight.locations.ST_DumpPoints()

    # Prepare cte
    cte = (
        db.session.query(
            location.label("location"), Flight.locations.label("locations"), Flight.timestamps.label("timestamps")
        )
        .filter(Flight.id == flight.id)
        .cte()
    )

    # Prepare column expressions
    timestamp = literal_column("timestamps[(location).path[1]]")
    elevation = Elevation.rast.ST_Value(cte.c.location.geom)

    # Prepare main query
    q = (
        db.session.query(timestamp.label("timestamp"), elevation.label("elevation"))
        .filter(and_(cte.c.locations.intersects(Elevation.rast), cte.c.location.geom.intersects(Elevation.rast)))
        .all()
    )

    if len(q) == 0:
        return []

    start_time = q[0][0]
    start_midnight = start_time.replace(hour=0, minute=0, second=0, microsecond=0)

    elevations = []
    for time, elevation in q:
        if elevation is None:
            continue

        time_delta = time - start_midnight
        time = time_delta.days * 86400 + time_delta.seconds

        elevations.append((time, elevation))

    cache.set("elevations_" + flight.__repr__(), elevations, timeout=3600 * 24)

    return elevations
Esempio n. 2
0
def get_elevations_for_flight(flight):
    cached_elevations = cache.get('elevations_' + flight.__repr__())
    if cached_elevations:
        return cached_elevations
    '''
    WITH src AS
        (SELECT ST_DumpPoints(flights.locations) AS location,
                flights.timestamps AS timestamps,
                flights.locations AS locations
        FROM flights
        WHERE flights.id = 30000)
    SELECT timestamps[(src.location).path[1]] AS timestamp,
           ST_Value(elevations.rast, (src.location).geom) AS elevation
    FROM elevations, src
    WHERE src.locations && elevations.rast AND (src.location).geom && elevations.rast;
    '''

    # Prepare column expressions
    location = Flight.locations.ST_DumpPoints()

    # Prepare cte
    cte = db.session.query(location.label('location'),
                           Flight.locations.label('locations'),
                           Flight.timestamps.label('timestamps')) \
        .filter(Flight.id == flight.id).cte()

    # Prepare column expressions
    timestamp = literal_column('timestamps[(location).path[1]]')
    elevation = Elevation.rast.ST_Value(cte.c.location.geom)

    # Prepare main query
    q = db.session.query(timestamp.label('timestamp'),
                         elevation.label('elevation')) \
        .filter(and_(cte.c.locations.intersects(Elevation.rast),
                     cte.c.location.geom.intersects(Elevation.rast))).all()

    if len(q) == 0:
        return []

    start_time = q[0][0]
    start_midnight = start_time.replace(hour=0,
                                        minute=0,
                                        second=0,
                                        microsecond=0)

    elevations = []
    for time, elevation in q:
        if elevation is None:
            continue

        time_delta = time - start_midnight
        time = time_delta.days * 86400 + time_delta.seconds

        elevations.append((time, elevation))

    cache.set('elevations_' + flight.__repr__(), elevations, timeout=3600 * 24)

    return elevations
Esempio n. 3
0
def airspace_image(cache_key, airspace_id):
    if not mapscript_available:
        abort(404)

    # get information from cache...
    infringements = cache.get('upload_airspace_infringements_' + cache_key)
    flight_path = cache.get('upload_airspace_flight_path_' + cache_key)

    # abort if invalid cache key
    if not infringements \
       or not flight_path:
        abort(404)

    # Convert the coordinate into a list of tuples
    coordinates = [(c.location['longitude'], c.location['latitude'])
                   for c in flight_path]
    # Create a shapely LineString object from the coordinates
    linestring = LineString(coordinates)
    # Save the new path as WKB
    locations = from_shape(linestring, srid=4326)

    highlight_locations = []
    extent_epsg4326 = [180, 85.05112878, -180, -85.05112878]

    for period in infringements[airspace_id]:
        # Convert the coordinate into a list of tuples
        coordinates = [(c['location']['longitude'], c['location']['latitude'])
                       for c in period]

        # Create a shapely LineString object from the coordinates
        if len(coordinates) == 1:
            # a LineString must contain at least two points...
            linestring = LineString([coordinates[0], coordinates[0]])
        else:
            linestring = LineString(coordinates)

        highlight_locations.append(linestring)

        # gather extent
        (minx, miny, maxx, maxy) = linestring.bounds

        extent_epsg4326[0] = min(extent_epsg4326[0], minx)
        extent_epsg4326[1] = min(extent_epsg4326[1], miny)
        extent_epsg4326[2] = max(extent_epsg4326[2], maxx)
        extent_epsg4326[3] = max(extent_epsg4326[3], maxy)

    # Save the new path as WKB
    highlight_multilinestring = from_shape(
        MultiLineString(highlight_locations), srid=4326)

    # increase extent by factor 1.05
    width = abs(extent_epsg4326[0] - extent_epsg4326[2])
    height = abs(extent_epsg4326[1] - extent_epsg4326[3])

    center_x = (extent_epsg4326[0] + extent_epsg4326[2]) / 2
    center_y = (extent_epsg4326[1] + extent_epsg4326[3]) / 2

    extent_epsg4326[0] = center_x - width / 2 * 1.05
    extent_epsg4326[1] = center_y - height / 2 * 1.05
    extent_epsg4326[2] = center_x + width / 2 * 1.05
    extent_epsg4326[3] = center_y + height / 2 * 1.05

    # minimum extent should be 0.3 deg
    width = abs(extent_epsg4326[0] - extent_epsg4326[2])
    height = abs(extent_epsg4326[1] - extent_epsg4326[3])

    if width < 0.3:
        extent_epsg4326[0] = center_x - 0.15
        extent_epsg4326[2] = center_x + 0.15

    if height < 0.3:
        extent_epsg4326[1] = center_y - 0.15
        extent_epsg4326[3] = center_y + 0.15

    # convert extent from EPSG4326 to EPSG3857
    epsg4326 = pyproj.Proj(init='epsg:4326')
    epsg3857 = pyproj.Proj(init='epsg:3857')

    x1, y1 = pyproj.transform(epsg4326, epsg3857, extent_epsg4326[0],
                              extent_epsg4326[1])
    x2, y2 = pyproj.transform(epsg4326, epsg3857, extent_epsg4326[2],
                              extent_epsg4326[3])

    extent_epsg3857 = [x1, y1, x2, y2]

    # load basemap and set size + extent
    basemap_path = os.path.join(
        current_app.config.get('SKYLINES_MAPSERVER_PATH'), 'basemap.map')
    map_object = mapscript.mapObj(basemap_path)
    map_object.setSize(400, 400)
    map_object.setExtent(extent_epsg3857[0], extent_epsg3857[1],
                         extent_epsg3857[2], extent_epsg3857[3])

    # enable airspace and airports layers
    num_layers = map_object.numlayers
    for i in range(num_layers):
        layer = map_object.getLayer(i)

        if layer.group == 'Airports':
            layer.status = mapscript.MS_ON

        if layer.group == 'Airspace':
            layer.status = mapscript.MS_ON

    # get flights layer
    flights_layer = map_object.getLayerByName('Flights')
    highlight_layer = map_object.getLayerByName('Flights_Highlight')

    # set sql query for blue flight
    one = literal_column('1 as flight_id')
    flight_query = db.session.query(locations.label('flight_geometry'), one)

    flights_layer.data = 'flight_geometry FROM (' + query_to_sql(flight_query) + ')' + \
                         ' AS foo USING UNIQUE flight_id USING SRID=4326'

    # set sql query for highlighted linestrings
    highlighted_query = db.session.query(
        highlight_multilinestring.label('flight_geometry'), one)

    highlight_layer.data = 'flight_geometry FROM (' + query_to_sql(highlighted_query) + ')' + \
                           ' AS foo USING UNIQUE flight_id USING SRID=4326'

    highlight_layer.status = mapscript.MS_ON

    # get osm layer and set WMS url
    osm_layer = map_object.getLayerByName('OSM')
    osm_layer.connection = current_app.config.get('SKYLINES_MAP_TILE_URL') + \
        '/service?'

    # draw map
    map_image = map_object.draw()

    # get image
    mapscript.msIO_installStdoutToBuffer()
    map_image.write()
    content = mapscript.msIO_getStdoutBufferBytes()

    # return to client
    resp = make_response(content)
    resp.headers['Content-type'] = map_image.format.mimetype
    return resp
Esempio n. 4
0
def airspace_image(cache_key, airspace_id):
    if not mapscript_available:
        abort(404)

    # get information from cache...
    infringements = cache.get('upload_airspace_infringements_' + cache_key)
    flight_path = cache.get('upload_airspace_flight_path_' + cache_key)

    # abort if invalid cache key
    if not infringements \
       or not flight_path:
        abort(404)

    # Convert the coordinate into a list of tuples
    coordinates = [(c.location['longitude'], c.location['latitude']) for c in flight_path]
    # Create a shapely LineString object from the coordinates
    linestring = LineString(coordinates)
    # Save the new path as WKB
    locations = from_shape(linestring, srid=4326)

    highlight_locations = []
    extent_epsg4326 = [180, 85.05112878, -180, -85.05112878]

    for period in infringements[airspace_id]:
        # Convert the coordinate into a list of tuples
        coordinates = [(c['location']['longitude'], c['location']['latitude']) for c in period]

        # Create a shapely LineString object from the coordinates
        if len(coordinates) == 1:
            # a LineString must contain at least two points...
            linestring = LineString([coordinates[0], coordinates[0]])
        else:
            linestring = LineString(coordinates)

        highlight_locations.append(linestring)

        # gather extent
        (minx, miny, maxx, maxy) = linestring.bounds

        extent_epsg4326[0] = min(extent_epsg4326[0], minx)
        extent_epsg4326[1] = min(extent_epsg4326[1], miny)
        extent_epsg4326[2] = max(extent_epsg4326[2], maxx)
        extent_epsg4326[3] = max(extent_epsg4326[3], maxy)

    # Save the new path as WKB
    highlight_multilinestring = from_shape(MultiLineString(highlight_locations), srid=4326)

    # increase extent by factor 1.05
    width = abs(extent_epsg4326[0] - extent_epsg4326[2])
    height = abs(extent_epsg4326[1] - extent_epsg4326[3])

    center_x = (extent_epsg4326[0] + extent_epsg4326[2]) / 2
    center_y = (extent_epsg4326[1] + extent_epsg4326[3]) / 2

    extent_epsg4326[0] = center_x - width / 2 * 1.05
    extent_epsg4326[1] = center_y - height / 2 * 1.05
    extent_epsg4326[2] = center_x + width / 2 * 1.05
    extent_epsg4326[3] = center_y + height / 2 * 1.05

    # minimum extent should be 0.3 deg
    width = abs(extent_epsg4326[0] - extent_epsg4326[2])
    height = abs(extent_epsg4326[1] - extent_epsg4326[3])

    if width < 0.3:
        extent_epsg4326[0] = center_x - 0.15
        extent_epsg4326[2] = center_x + 0.15

    if height < 0.3:
        extent_epsg4326[1] = center_y - 0.15
        extent_epsg4326[3] = center_y + 0.15

    # convert extent from EPSG4326 to EPSG3857
    epsg4326 = pyproj.Proj(init='epsg:4326')
    epsg3857 = pyproj.Proj(init='epsg:3857')

    x1, y1 = pyproj.transform(epsg4326, epsg3857, extent_epsg4326[0], extent_epsg4326[1])
    x2, y2 = pyproj.transform(epsg4326, epsg3857, extent_epsg4326[2], extent_epsg4326[3])

    extent_epsg3857 = [x1, y1, x2, y2]

    # load basemap and set size + extent
    basemap_path = os.path.join(current_app.config.get('SKYLINES_MAPSERVER_PATH'), 'basemap.map')
    map_object = mapscript.mapObj(basemap_path)
    map_object.setSize(400, 400)
    map_object.setExtent(extent_epsg3857[0], extent_epsg3857[1], extent_epsg3857[2], extent_epsg3857[3])

    # enable airspace and airports layers
    num_layers = map_object.numlayers
    for i in range(num_layers):
        layer = map_object.getLayer(i)

        if layer.group == 'Airports':
            layer.status = mapscript.MS_ON

        if layer.group == 'Airspace':
            layer.status = mapscript.MS_ON

    # get flights layer
    flights_layer = map_object.getLayerByName('Flights')
    highlight_layer = map_object.getLayerByName('Flights_Highlight')

    # set sql query for blue flight
    one = literal_column('1 as flight_id')
    flight_query = db.session.query(locations.label('flight_geometry'), one)

    flights_layer.data = 'flight_geometry FROM (' + query_to_sql(flight_query) + ')' + \
                         ' AS foo USING UNIQUE flight_id USING SRID=4326'

    # set sql query for highlighted linestrings
    highlighted_query = db.session.query(highlight_multilinestring.label('flight_geometry'), one)

    highlight_layer.data = 'flight_geometry FROM (' + query_to_sql(highlighted_query) + ')' + \
                           ' AS foo USING UNIQUE flight_id USING SRID=4326'

    highlight_layer.status = mapscript.MS_ON

    # get osm layer and set WMS url
    osm_layer = map_object.getLayerByName('OSM')
    osm_layer.connection = current_app.config.get('SKYLINES_MAP_TILE_URL') + \
        '/service?'

    # draw map
    map_image = map_object.draw()

    # get image
    mapscript.msIO_installStdoutToBuffer()
    map_image.write()
    content = mapscript.msIO_getStdoutBufferBytes()

    # return to client
    resp = make_response(content)
    resp.headers['Content-type'] = map_image.format.mimetype
    return resp