show nearby locations
This commit is contained in:
parent
3134829cc7
commit
27b35a384d
7 changed files with 68 additions and 19 deletions
|
@ -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 ''
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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)
|
||||
|
|
BIN
src/c3nav/static/img/marker-icon-nearby-2x.png
Normal file
BIN
src/c3nav/static/img/marker-icon-nearby-2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
src/c3nav/static/img/marker-icon-nearby.png
Normal file
BIN
src/c3nav/static/img/marker-icon-nearby.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
Loading…
Add table
Add a link
Reference in a new issue