show nearby locations

This commit is contained in:
Laura Klünder 2019-12-25 00:40:19 +01:00
parent 3134829cc7
commit 27b35a384d
7 changed files with 68 additions and 19 deletions

View file

@ -283,6 +283,7 @@ class CustomLocation:
('grid_square', self.grid_square),
('near_area', self.near_area.pk if self.near_area else None),
('near_poi', self.near_poi.pk if self.near_poi else None),
('nearby', tuple(location.pk for location in self.nearby)),
('altitude', None if self.altitude is None else round(self.altitude, 2))
))
if not grid.enabled:
@ -378,6 +379,10 @@ class CustomLocation:
def near_poi(self):
return self.description.near_poi
@cached_property
def nearby(self):
return self.description.nearby
@cached_property
def grid_square(self):
return grid.get_square_for_point(self.x, self.y) or ''

View file

@ -363,15 +363,25 @@ class Router:
restrictions = self.get_restrictions(location.permissions)
space = self.space_for_point(level=location.level.pk, point=location, restrictions=restrictions)
if not space:
return CustomLocationDescription(space=space, altitude=None, areas=(), near_area=None, near_poi=None)
return CustomLocationDescription(space=space, altitude=None, areas=(), near_area=None, near_poi=None,
nearby=())
try:
altitude = space.altitudearea_for_point(location).get_altitude(location)
except LocationUnreachable:
altitude = None
areas, near_area = space.areas_for_point(areas=self.areas, point=location, restrictions=restrictions)
near_poi = space.poi_for_point(pois=self.pois, point=location, restrictions=restrictions)
areas, near_area, nearby_areas = space.areas_for_point(
areas=self.areas, point=location, restrictions=restrictions
)
near_poi, nearby_pois = space.poi_for_point(
pois=self.pois, point=location, restrictions=restrictions
)
nearby = tuple(sorted(
tuple(l for l in nearby_areas+nearby_pois if l[0].can_search),
key=operator.itemgetter(1)
))[:20]
nearby = tuple(location for location, distance in nearby)
return CustomLocationDescription(space=space, altitude=altitude,
areas=areas, near_area=near_area, near_poi=near_poi)
areas=areas, near_area=near_area, near_poi=near_poi, nearby=nearby)
def shortest_path(self, restrictions, options):
options_key = options.serialize_string()
@ -482,7 +492,7 @@ class Router:
CustomLocationDescription = namedtuple('CustomLocationDescription', ('space', 'altitude',
'areas', 'near_area', 'near_poi'))
'areas', 'near_area', 'near_poi', 'nearby'))
class BaseRouterProxy:
@ -535,26 +545,30 @@ class RouterSpace(BaseRouterProxy):
areas = {pk: area for pk, area in areas.items()
if pk in self.areas and area.can_describe and area.access_restriction_id not in restrictions}
nearby = ((area, area.geometry.distance(point)) for area in areas.values())
nearby = tuple((area, distance) for area, distance in nearby if distance < 20)
contained = tuple(area for area in areas.values() if area.geometry_prep.contains(point))
if contained:
return tuple(sorted(contained, key=lambda area: area.geometry.area)), None
return tuple(sorted(contained, key=lambda area: area.geometry.area)), None, nearby
near = ((area, area.geometry.distance(point)) for area in areas.values())
near = tuple((area, distance) for area, distance in near if distance < 5)
near = tuple((area, distance) for area, distance in nearby if distance < 5)
if not near:
return (), None
return (), min(near, key=operator.itemgetter(1))[0]
return (), None, nearby
return (), min(near, key=operator.itemgetter(1))[0], nearby
def poi_for_point(self, pois, point, restrictions):
point = Point(point.x, point.y)
pois = {pk: poi for pk, poi in pois.items()
if pk in self.pois and poi.can_describe and poi.access_restriction_id not in restrictions}
near = ((poi, poi.geometry.distance(point)) for poi in pois.values())
near = tuple((poi, distance) for poi, distance in near if distance < 5)
nearby = ((poi, poi.geometry.distance(point)) for poi in pois.values())
nearby = tuple((poi, distance) for poi, distance in nearby if distance < 20)
near = tuple((poi, distance) for poi, distance in nearby if distance < 5)
if not near:
return None
return min(near, key=operator.itemgetter(1))[0]
return None, nearby
return min(near, key=operator.itemgetter(1))[0], nearby
class RouterArea(BaseRouterProxy):

View file

@ -213,13 +213,18 @@ c3nav = {
},
state: {},
update_state: function(routing, replace, details, options) {
update_state: function(routing, replace, details, options, nearby) {
if (typeof routing !== "boolean") routing = c3nav.state.routing;
if (details) {
options = false;
nearby = false;
} else if (options) {
details = false;
nearby = false;
} else if (nearby) {
details = false;
options = false;
}
var destination = $('#destination-input').data('location'),
@ -230,7 +235,8 @@ c3nav = {
destination: destination,
sidebar: true,
details: !!details,
options: !!options
options: !!options,
nearby: !!nearby,
};
c3nav._push_state(new_state, replace);
@ -669,6 +675,9 @@ c3nav = {
if (state.details && (url.startsWith('/l/') || url.startsWith('/r/'))) {
url += 'details/'
}
if (state.nearby && url.startsWith('/l/')) {
url += 'nearby/'
}
if (state.options && url.startsWith('/r/')) {
url += 'options/'
}
@ -1212,6 +1221,7 @@ c3nav = {
L.Icon.Default.imagePath = '/static/leaflet/images/';
c3nav._add_icon('origin');
c3nav._add_icon('destination');
c3nav._add_icon('nearby');
// setup scale control
L.control.scale({imperial: false}).addTo(c3nav.map);
@ -1281,7 +1291,7 @@ c3nav = {
if (nearby) {
var $destination = $('#destination-input');
c3nav._locationinput_set($destination, data);
c3nav.update_state(false);
c3nav.update_state(false, false, false, false, true);
} else {
newpopup = L.popup(c3nav._add_map_padding({
className: 'location-popup',
@ -1333,6 +1343,24 @@ c3nav = {
c3nav._visible_map_locations = [];
if (origin) c3nav._merge_bounds(bounds, c3nav._add_location_to_map(origin, single ? new L.Icon.Default() : c3nav.originIcon));
if (destination) c3nav._merge_bounds(bounds, c3nav._add_location_to_map(destination, single ? new L.Icon.Default() : c3nav.destinationIcon));
var done = [];
if (c3nav.state.nearby && destination && 'areas' in destination) {
if (destination.space) {
c3nav._merge_bounds(bounds, c3nav._add_location_to_map(c3nav.locations_by_id[destination.space], c3nav.nearbyIcon, true));
}
if (destination.near_area) {
done.push(destination.near_area);
c3nav._merge_bounds(bounds, c3nav._add_location_to_map(c3nav.locations_by_id[destination.near_area], c3nav.nearbyIcon, true));
}
for (var area of destination.areas) {
done.push(area);
c3nav._merge_bounds(bounds, c3nav._add_location_to_map(c3nav.locations_by_id[area], c3nav.nearbyIcon, true));
}
for (var location of destination.nearby) {
if (location in done) continue;
c3nav._merge_bounds(bounds, c3nav._add_location_to_map(c3nav.locations_by_id[location], c3nav.nearbyIcon, true));
}
}
c3nav._locationLayerBounds = bounds;
},
fly_to_bounds: function(replace_state, nofly) {

View file

@ -8,12 +8,13 @@ slug = r'(?P<slug>[a-z0-9-_.:]+)'
coordinates = r'(?P<coordinates>[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)'
slug2 = r'(?P<slug2>[a-z0-9-_.:]+)'
details = r'(?P<details>details/)?'
nearby = r'(?P<nearby>nearby/)?'
options = r'(?P<options>options/)?'
pos = r'(@(?P<level>[a-z0-9-_:]+),(?P<x>-?\d+(\.\d+)?),(?P<y>-?\d+(\.\d+)?),(?P<zoom>-?\d+(\.\d+)?))?'
embed = r'(?P<embed>embed/)?'
urlpatterns = [
url(r'^%s(?P<mode>[l])/%s/%s%s$' % (embed, slug, details, pos), map_index, name='site.index'),
url(r'^%s(?P<mode>[l])/%s/(%s|%s)%s$' % (embed, slug, details, nearby, pos), map_index, name='site.index'),
url(r'^%s(?P<mode>[od])/%s/%s$' % (embed, slug, pos), map_index, name='site.index'),
url(r'^%sr/%s/%s/(%s|%s)%s$' % (embed, slug, slug2, details, options, pos), map_index, name='site.index'),
url(r'^%s(?P<mode>r)/%s$' % (embed, pos), map_index, name='site.index'),

View file

@ -57,7 +57,7 @@ def check_location(location: Optional[str], request) -> Optional[SpecificLocatio
return location
def map_index(request, mode=None, slug=None, slug2=None, details=None, options=None,
def map_index(request, mode=None, slug=None, slug2=None, details=None, options=None, nearby=None,
level=None, x=None, y=None, zoom=None, embed=None):
# check for access token
@ -108,6 +108,7 @@ def map_index(request, mode=None, slug=None, slug2=None, details=None, options=N
'sidebar': routing or destination is not None,
'details': True if details else False,
'options': True if options else False,
'nearby': True if nearby else False,
}
levels = levels_by_short_label_for_request(request)

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB