merge exporting zones from "exports" page
This commit is contained in:
parent
c41aa3f6a0
commit
6d35001f8d
|
@ -4,6 +4,7 @@ from contextlib import contextmanager
|
||||||
import zipfile
|
import zipfile
|
||||||
import io
|
import io
|
||||||
import re
|
import re
|
||||||
|
import math
|
||||||
from sqlite3 import connect
|
from sqlite3 import connect
|
||||||
|
|
||||||
import shapefile
|
import shapefile
|
||||||
|
@ -15,6 +16,9 @@ from sanic.exceptions import InvalidUsage
|
||||||
from obs.api.app import api, json as json_response
|
from obs.api.app import api, json as json_response
|
||||||
from obs.api.utils import use_request_semaphore
|
from obs.api.utils import use_request_semaphore
|
||||||
|
|
||||||
|
import logging
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ExportFormat(str, Enum):
|
class ExportFormat(str, Enum):
|
||||||
SHAPEFILE = "shapefile"
|
SHAPEFILE = "shapefile"
|
||||||
|
@ -64,13 +68,13 @@ def shapefile_zip(shape_type=shapefile.POINT, basename="events"):
|
||||||
async def export_events(req):
|
async def export_events(req):
|
||||||
async with use_request_semaphore(req, "export_semaphore", timeout=30):
|
async with use_request_semaphore(req, "export_semaphore", timeout=30):
|
||||||
bbox = req.ctx.get_single_arg(
|
bbox = req.ctx.get_single_arg(
|
||||||
"bbox", default="-180,-90,180,90", convert=parse_bounding_box
|
"bbox", default="-180,-90,180,90"
|
||||||
)
|
)
|
||||||
fmt = req.ctx.get_single_arg("fmt", convert=ExportFormat)
|
fmt = req.ctx.get_single_arg("fmt", convert=ExportFormat)
|
||||||
|
|
||||||
events = await req.ctx.db.stream_scalars(
|
events = await req.ctx.db.stream(
|
||||||
select(OvertakingEvent).where(
|
text(
|
||||||
OvertakingEvent.geometry.bool_op("&&")(func.ST_Transform(bbox, 3857))
|
f"select ST_AsGeoJSON(ST_Transform(geometry,4326)) AS geometry,distance_overtaker,distance_stationary,way_id,direction,speed,time_stamp,course,zone from layer_obs_events(ST_Transform(ST_MakeEnvelope({bbox},4326),3857),19,NULL,'1900-01-01'::timestamp,'2100-01-01'::timestamp) "
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -82,16 +86,19 @@ async def export_events(req):
|
||||||
writer.field("direction", "N", decimal=0)
|
writer.field("direction", "N", decimal=0)
|
||||||
writer.field("course", "N", decimal=4)
|
writer.field("course", "N", decimal=4)
|
||||||
writer.field("speed", "N", decimal=4)
|
writer.field("speed", "N", decimal=4)
|
||||||
|
writer.field("zone", "C")
|
||||||
|
|
||||||
async for event in events:
|
async for event in events:
|
||||||
writer.point(event.longitude, event.latitude)
|
coords = json.loads(event.geometry)['coordinates']
|
||||||
|
writer.point(*coords)
|
||||||
writer.record(
|
writer.record(
|
||||||
distance_overtaker=event.distance_overtaker,
|
distance_overtaker=event.distance_overtaker,
|
||||||
distance_stationary=event.distance_stationary,
|
distance_stationary=event.distance_stationary,
|
||||||
direction=-1 if event.direction_reversed else 1,
|
direction=event.direction,
|
||||||
way_id=event.way_id,
|
way_id=event.way_id,
|
||||||
course=event.course,
|
course=event.course,
|
||||||
speed=event.speed,
|
speed=event.speed,
|
||||||
|
zone=event.zone
|
||||||
# "time"=event.time,
|
# "time"=event.time,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -100,19 +107,22 @@ async def export_events(req):
|
||||||
if fmt == ExportFormat.GEOJSON:
|
if fmt == ExportFormat.GEOJSON:
|
||||||
features = []
|
features = []
|
||||||
async for event in events:
|
async for event in events:
|
||||||
|
geom = json.loads(event.geometry)
|
||||||
features.append(
|
features.append(
|
||||||
{
|
{
|
||||||
"type": "Feature",
|
"type": "Feature",
|
||||||
"geometry": json.loads(event.geometry),
|
"geometry": geom,
|
||||||
"properties": {
|
"properties": {
|
||||||
"distance_overtaker": event.distance_overtaker,
|
"distance_overtaker": event.distance_overtaker if event.distance_overtaker is not None and not math.isnan(event.distance_overtaker) else None,
|
||||||
"distance_stationary": event.distance_stationary,
|
"distance_stationary": event.distance_stationary if event.distance_stationary is not None and not math.isnan(event.distance_stationary) else None,
|
||||||
"direction": -1 if event.direction_reversed else 1,
|
"direction": event.direction if event.direction is not None and not math.isnan(event.direction) else None,
|
||||||
"way_id": event.way_id,
|
"way_id": event.way_id,
|
||||||
"course": event.course,
|
"course": event.course if event.course is not None and not math.isnan(event.course) else None,
|
||||||
"speed": event.speed,
|
"speed": event.speed if event.speed is not None and not math.isnan(event.speed) else None,
|
||||||
"time": event.time,
|
"time": event.time_stamp,
|
||||||
|
"zone": event.zone
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
DROP FUNCTION IF EXISTS layer_obs_events;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION layer_obs_events(bbox geometry, zoom_level int, user_id integer, min_time timestamp, max_time timestamp)
|
CREATE OR REPLACE FUNCTION layer_obs_events(bbox geometry, zoom_level int, user_id integer, min_time timestamp, max_time timestamp)
|
||||||
RETURNS TABLE(event_id bigint, geometry geometry, distance_overtaker float, distance_stationary float, direction int, course float, speed float, zone zone_type, way_id bigint) AS $$
|
RETURNS TABLE(event_id bigint, geometry geometry, distance_overtaker float, distance_stationary float, direction int, course float, speed float, time_stamp timestamp, zone zone_type, way_id bigint) AS $$
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
overtaking_event.id::bigint as event_id,
|
overtaking_event.id::bigint as event_id,
|
||||||
|
@ -9,6 +11,7 @@ RETURNS TABLE(event_id bigint, geometry geometry, distance_overtaker float, dist
|
||||||
(case when direction_reversed then -1 else 1 end)::int as direction,
|
(case when direction_reversed then -1 else 1 end)::int as direction,
|
||||||
course,
|
course,
|
||||||
speed,
|
speed,
|
||||||
|
time as time_stamp,
|
||||||
CASE WHEN road.zone IS NULL THEN 'urban' else road.zone END as zone,
|
CASE WHEN road.zone IS NULL THEN 'urban' else road.zone END as zone,
|
||||||
overtaking_event.way_id::bigint as way_id
|
overtaking_event.way_id::bigint as way_id
|
||||||
FROM overtaking_event
|
FROM overtaking_event
|
||||||
|
|
|
@ -16,6 +16,8 @@ layer:
|
||||||
Direction of travel, as reported by GPS, in degree from North.
|
Direction of travel, as reported by GPS, in degree from North.
|
||||||
speed: |
|
speed: |
|
||||||
Speed of travel, as reported by GPS, in meters per second (?).
|
Speed of travel, as reported by GPS, in meters per second (?).
|
||||||
|
time_stamp: |
|
||||||
|
the time of the overtaking
|
||||||
zone: |
|
zone: |
|
||||||
rural or urban
|
rural or urban
|
||||||
defaults:
|
defaults:
|
||||||
|
|
Loading…
Reference in a new issue