simplify serialize calls some more in routing etec

This commit is contained in:
Laura Klünder 2024-12-04 15:43:03 +01:00
parent f2f67a1cbb
commit 9f609d9205
5 changed files with 37 additions and 25 deletions

View file

@ -21,6 +21,7 @@ from c3nav.mapdata.render.engines import ImageRenderEngine
from c3nav.mapdata.render.engines.base import FillAttribs, StrokeAttribs from c3nav.mapdata.render.engines.base import FillAttribs, StrokeAttribs
from c3nav.mapdata.render.renderer import MapRenderer from c3nav.mapdata.render.renderer import MapRenderer
from c3nav.mapdata.utils.cache import CachePackage, MapHistory from c3nav.mapdata.utils.cache import CachePackage, MapHistory
from c3nav.mapdata.utils.locations import visible_locations_for_request
from c3nav.mapdata.utils.tiles import (build_access_cache_key, build_base_cache_key, build_tile_access_cookie, from c3nav.mapdata.utils.tiles import (build_access_cache_key, build_base_cache_key, build_tile_access_cookie,
build_tile_etag, get_tile_bounds, parse_tile_access_cookie) build_tile_etag, get_tile_bounds, parse_tile_access_cookie)
@ -219,11 +220,13 @@ def preview_route(request, slug, slug2):
from c3nav.mapdata.utils.geometry import unwrap_geom from c3nav.mapdata.utils.geometry import unwrap_geom
origin = check_location(slug, None) origin = check_location(slug, None)
destination = check_location(slug2, None) destination = check_location(slug2, None)
visible_locations = visible_locations_for_request(request)
try: try:
route = Router.load().get_route(origin=origin, route = Router.load().get_route(origin=origin,
destination=destination, destination=destination,
permissions=set(), permissions=set(),
options=RouteOptions()) options=RouteOptions(),
visible_locations=visible_locations)
except NotYetRoutable: except NotYetRoutable:
raise Http404() raise Http404()
except LocationUnreachable: except LocationUnreachable:

View file

@ -52,7 +52,7 @@ def get_position(request, parameters: LocateRequestSchema):
raise raise
return { return {
"location": location.serialize(simple_geometry=True) if location else None, "location": location
} }
@ -94,7 +94,7 @@ def locate_test(request):
return { return {
"ranges": msg.parsed.model_dump(mode="json")["ranges"], "ranges": msg.parsed.model_dump(mode="json")["ranges"],
"datetime": msg.datetime, "datetime": msg.datetime,
"location": location.serialize(simple_geometry=True) if location else None "location": location
} }

View file

@ -3,6 +3,7 @@ from typing import Annotated, Any, Optional, Union
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.conf import settings from django.conf import settings
from django.db.models import Model
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from ninja import Field as APIField from ninja import Field as APIField
@ -212,11 +213,14 @@ def get_route(request, parameters: RouteParametersSchema):
if parameters.options_override is not None: if parameters.options_override is not None:
_new_update_route_options(options, parameters.options_override) _new_update_route_options(options, parameters.options_override)
visible_locations = visible_locations_for_request(request)
try: try:
route = Router.load().get_route(origin=form.cleaned_data['origin'], route = Router.load().get_route(origin=form.cleaned_data['origin'],
destination=form.cleaned_data['destination'], destination=form.cleaned_data['destination'],
permissions=AccessPermission.get_for_request(request), permissions=AccessPermission.get_for_request(request),
options=options) options=options,
visible_locations=visible_locations)
except NotYetRoutable: except NotYetRoutable:
return NoRouteResponse( return NoRouteResponse(
request=parameters, request=parameters,
@ -256,7 +260,7 @@ def get_route(request, parameters: RouteParametersSchema):
'destination': parameters.destination, 'destination': parameters.destination,
'options': options.serialize_string(), 'options': options.serialize_string(),
}), }),
result=route.serialize(locations=visible_locations_for_request(request)), result=route.serialize(),
) )

View file

@ -21,7 +21,8 @@ def describe_location(location, locations):
class Route: class Route:
def __init__(self, router, origin, destination, path_nodes, options, def __init__(self, router, origin, destination, path_nodes, options,
origin_addition, destination_addition, origin_xyz, destination_xyz): origin_addition, destination_addition, origin_xyz, destination_xyz,
visible_locations):
self.router = router self.router = router
self.origin = origin self.origin = origin
self.destination = destination self.destination = destination
@ -31,8 +32,9 @@ class Route:
self.destination_addition = destination_addition self.destination_addition = destination_addition
self.origin_xyz = origin_xyz self.origin_xyz = origin_xyz
self.destination_xyz = destination_xyz self.destination_xyz = destination_xyz
self.visible_locations = visible_locations
def serialize(self, locations): def serialize(self): # todo: move this into schema
nodes = [[node, None] for node in self.path_nodes] nodes = [[node, None] for node in self.path_nodes]
if self.origin_addition and any(self.origin_addition): if self.origin_addition and any(self.origin_addition):
nodes.insert(0, (self.origin_addition[0], None)) nodes.insert(0, (self.origin_addition[0], None))
@ -161,6 +163,20 @@ class Route:
distance_str = '%d m' % distance distance_str = '%d m' % distance
summary = '%s (%s)' % (duration_str, distance_str) summary = '%s (%s)' % (duration_str, distance_str)
return OrderedDict((
('origin', describe_location(self.origin, self.visible_locations)),
('destination', describe_location(self.destination, self.visible_locations)),
('distance', round(distance, 2)),
('duration', round(duration)),
('distance_str', distance_str),
('duration_str', duration_str),
('summary', summary),
('options_summary', self.options_summary),
('items', tuple(item.serialize(locations=self.visible_locations) for item in items)),
))
@property
def options_summary(self):
options_summary = [ options_summary = [
{ {
'fastest': _('fastest route'), 'fastest': _('fastest route'),
@ -183,19 +199,7 @@ class Route:
if len(options_summary) == 1: if len(options_summary) == 1:
options_summary.append(_('default options')) options_summary.append(_('default options'))
options_summary = ', '.join(str(s) for s in options_summary) return ', '.join(str(s) for s in options_summary)
return OrderedDict((
('origin', describe_location(self.origin, locations)),
('destination', describe_location(self.destination, locations)),
('distance', round(distance, 2)),
('duration', round(duration)),
('distance_str', distance_str),
('duration_str', duration_str),
('summary', summary),
('options_summary', options_summary),
('items', tuple(item.serialize(locations=locations) for item in items)),
))
class RouteItem: class RouteItem:
@ -232,7 +236,7 @@ class RouteItem:
def new_level(self): def new_level(self):
return not self.last_item or self.level.pk != self.last_item.level.pk return not self.last_item or self.level.pk != self.last_item.level.pk
def serialize(self, locations): def serialize(self): # todo: move this into schema
result = OrderedDict(( result = OrderedDict((
('id', self.node.pk), ('id', self.node.pk),
('coordinates', (self.node.x, self.node.y, self.node.altitude)), ('coordinates', (self.node.x, self.node.y, self.node.altitude)),
@ -243,10 +247,10 @@ class RouteItem:
result['waytype'] = self.waytype.serialize(detailed=False) result['waytype'] = self.waytype.serialize(detailed=False)
if self.new_space: if self.new_space:
result['space'] = describe_location(self.space, locations) result['space'] = describe_location(self.space, self.route.visible_locations)
if self.new_level: if self.new_level:
result['level'] = describe_location(self.level, locations) result['level'] = describe_location(self.level, self.route.visible_locations)
result['descriptions'] = [(icon, instruction) for (icon, instruction) in self.descriptions] result['descriptions'] = [(icon, instruction) for (icon, instruction) in self.descriptions]
return result return result

View file

@ -484,7 +484,7 @@ class Router:
pk: restriction for pk, restriction in self.restrictions.items() if pk not in permissions pk: restriction for pk, restriction in self.restrictions.items() if pk not in permissions
}) })
def get_route(self, origin, destination, permissions, options): def get_route(self, origin, destination, permissions, options, visible_locations):
restrictions = self.get_restrictions(permissions) restrictions = self.get_restrictions(permissions)
# get possible origins and destinations # get possible origins and destinations
@ -527,7 +527,8 @@ class Router:
destination_xyz = destination.xyz if isinstance(destination, RouterPoint) else None destination_xyz = destination.xyz if isinstance(destination, RouterPoint) else None
return Route(self, origin, destination, path_nodes, options, return Route(self, origin, destination, path_nodes, options,
origin_addition, destination_addition, origin_xyz, destination_xyz) origin_addition, destination_addition, origin_xyz, destination_xyz,
visible_locations)
CustomLocationDescription = namedtuple('CustomLocationDescription', ('space', 'altitude', CustomLocationDescription = namedtuple('CustomLocationDescription', ('space', 'altitude',