switch to api v2

This commit is contained in:
Gwendolyn 2023-12-03 18:44:19 +01:00
parent f8f8f9fdc7
commit 4104ef5863
7 changed files with 251 additions and 192 deletions

View file

@ -93,16 +93,17 @@ editor = {
// load sources
editor._sources_control = L.control.layers([], [], { autoZIndex: false });
$.getJSON('/api/sources/', function (sources) {
var source;
for (var i = 0; i < sources.length; i++) {
source = sources[i];
editor.sources[source.id] = source;
source.layer = L.imageOverlay('/api/sources/'+source.id+'/image/', L.GeoJSON.coordsToLatLngs(source.bounds), {opacity: 0.3});
editor._sources_control.addOverlay(source.layer, source.name);
}
if (sources.length) editor._sources_control.addTo(editor.map);
});
c3nav_api.get('mapdata/sources')
.then(sources => {
var source;
for (var i = 0; i < sources.length; i++) {
source = sources[i];
editor.sources[source.id] = source;
source.layer = L.imageOverlay('/api/sources/'+source.id+'/image/', L.GeoJSON.coordsToLatLngs(source.bounds), {opacity: 0.3});
editor._sources_control.addOverlay(source.layer, source.name);
}
if (sources.length) editor._sources_control.addTo(editor.map);
})
},
// sidebar
@ -148,7 +149,7 @@ editor = {
if (window.mobileclient && mobileclient.wificollectorStop && $('#sidebar').find('.wificollector.running').length) {
mobileclient.wificollectorStop();
}
$('#sidebar').addClass('loading').find('.content').html('');
editor._cancel_editing();
},
@ -664,16 +665,19 @@ editor = {
editor.map.on('zoomend', editor._adjust_line_zoom);
$.getJSON('/api/editor/geometrystyles/', function(geometrystyles) {
editor.geometrystyles = geometrystyles;
$.getJSON('/api/editor/bounds/', function(bounds) {
bounds = L.GeoJSON.coordsToLatLngs(bounds.bounds);
editor._max_bounds = bounds;
editor._set_max_bounds();
editor.map.fitBounds(bounds, {padding: [30, 50]});
editor.init_sidebar();
});
});
c3nav_api.get('editor/geometrystyles')
.then(geometrystyles => {
editor.geometrystyles = geometrystyles;
c3nav_api.get('editor/bounds')
.then(bounds => {
bounds = L.GeoJSON.coordsToLatLngs(bounds.bounds);
editor._max_bounds = bounds;
editor._set_max_bounds();
editor.map.fitBounds(bounds, {padding: [30, 50]});
editor.init_sidebar();
})
})
editor.get_sources();
},
_set_max_bounds: function(bounds) {
@ -703,102 +707,103 @@ editor = {
editor._set_max_bounds();
if (same_url && editor._last_geometry_update_cache_key) {
geometry_url += '&update_cache_key='+editor._last_geometry_update_cache_key;
geometry_url += '?update_cache_key='+editor._last_geometry_update_cache_key;
}
$.getJSON(geometry_url, function(result) {
var geometries = [], feature, new_cache = {}, feature_type, feature_id;
// geometries cache logic
for (var i=0;i<result.length;i++) {
feature = result[i];
if (Array.isArray(feature)) {
if (feature[0] === 'update_cache_key') {
editor._last_geometry_update_cache_key = feature[1];
continue;
c3nav_api.get(geometry_url)
.then(result => {
var geometries = [], feature, new_cache = {}, feature_type, feature_id;
// geometries cache logic
for (var i=0;i<result.length;i++) {
feature = result[i];
if (Array.isArray(feature)) {
if (feature[0] === 'update_cache_key') {
editor._last_geometry_update_cache_key = feature[1];
continue;
}
// load from cache
if (feature[0] in editor._last_geometry_cache) {
feature = editor._last_geometry_cache[feature[0]][feature[1]];
} else {
feature = null;
}
if (!feature) {
editor._last_geometry_update_cache_key = null;
editor.load_geometries(editor._last_geometry_url, editor._highlight_type, editor._editing_id);
return;
}
}
// load from cache
if (feature[0] in editor._last_geometry_cache) {
feature = editor._last_geometry_cache[feature[0]][feature[1]];
} else {
feature = null;
}
if (!feature) {
editor._last_geometry_update_cache_key = null;
editor.load_geometries(editor._last_geometry_url, editor._highlight_type, editor._editing_id);
return;
if (!feature.properties.changed) {
if (!new_cache[feature.properties.type]) {
new_cache[feature.properties.type] = {};
}
new_cache[feature.properties.type][feature.properties.id] = feature;
}
geometries.push(feature);
}
if (!feature.properties.changed) {
if (!new_cache[feature.properties.type]) {
new_cache[feature.properties.type] = {};
}
new_cache[feature.properties.type][feature.properties.id] = feature;
}
geometries.push(feature);
}
editor._last_geometry_cache = new_cache;
editor._last_geometry_cache = new_cache;
editor.map.removeLayer(editor._highlight_layer);
editor._highlight_layer.clearLayers();
if (editor._geometries_layer !== null) {
editor.map.removeLayer(editor._geometries_layer);
}
var remove_feature = null;
if (editor._editing_id !== null) {
for (i=0;i<geometries.length;i++) {
feature = geometries[i];
if (feature.properties.original_type !== undefined && feature.properties.original_type+'-'+String(feature.properties.original_id) === editor._editing_id) {
remove_feature = i;
} else if (feature.original_geometry !== undefined && feature.properties.type+'-'+String(feature.properties.id) === editor._editing_id) {
feature.geometry = feature.original_geometry;
break;
editor.map.removeLayer(editor._highlight_layer);
editor._highlight_layer.clearLayers();
if (editor._geometries_layer !== null) {
editor.map.removeLayer(editor._geometries_layer);
}
var remove_feature = null;
if (editor._editing_id !== null) {
for (i=0;i<geometries.length;i++) {
feature = geometries[i];
if (feature.properties.original_type !== undefined && feature.properties.original_type+'-'+String(feature.properties.original_id) === editor._editing_id) {
remove_feature = i;
} else if (feature.original_geometry !== undefined && feature.properties.type+'-'+String(feature.properties.id) === editor._editing_id) {
feature.geometry = feature.original_geometry;
break;
}
}
}
}
if (remove_feature !== null) {
geometries.splice(remove_feature, 1);
}
if (editor._last_graph_path === null) {
geometries = geometries.filter(function(val) { return val.properties.type !== 'graphnode' && val.properties.type !== 'graphedge' })
}
editor._geometries_layer = L.geoJSON(geometries, {
style: editor._get_geometry_style,
pointToLayer: editor._point_to_layer,
onEachFeature: editor._register_geojson_feature
});
editor._geometries_layer.addTo(editor.map);
editor._highlight_layer.addTo(editor.map);
editor._loading_geometry = false;
if (editor._bounds_layer === null && editor._geometries_layer.getLayers().length) editor._bounds_layer = editor._geometries_layer;
if (editor._next_zoom && editor._bounds_layer !== null) {
editor.map.flyToBounds((editor._bounds_layer.getBounds !== undefined) ? editor._bounds_layer.getBounds() : [editor._bounds_layer.getLatLng(), editor._bounds_layer.getLatLng()], {
maxZoom: Math.max(4, editor.map.getZoom()),
duration: 0.5,
padding: [20, 20]
if (remove_feature !== null) {
geometries.splice(remove_feature, 1);
}
if (editor._last_graph_path === null) {
geometries = geometries.filter(function(val) { return val.properties.type !== 'graphnode' && val.properties.type !== 'graphedge' })
}
editor._geometries_layer = L.geoJSON(geometries, {
style: editor._get_geometry_style,
pointToLayer: editor._point_to_layer,
onEachFeature: editor._register_geojson_feature
});
}
editor._next_zoom = null;
editor.map.doubleClickZoom.enable();
editor._adjust_line_zoom();
if (editor.map.options.renderer._container !== undefined) {
var defs = editor.map.options.renderer._container.querySelector('defs');
if (defs === null) {
editor.map.options.renderer._container.insertAdjacentHTML('afterbegin', '<defs></defs>');
defs = editor.map.options.renderer._container.querySelector('defs');
} else {
defs.innerHTML = '';
editor._geometries_layer.addTo(editor.map);
editor._highlight_layer.addTo(editor.map);
editor._loading_geometry = false;
if (editor._bounds_layer === null && editor._geometries_layer.getLayers().length) editor._bounds_layer = editor._geometries_layer;
if (editor._next_zoom && editor._bounds_layer !== null) {
editor.map.flyToBounds((editor._bounds_layer.getBounds !== undefined) ? editor._bounds_layer.getBounds() : [editor._bounds_layer.getLatLng(), editor._bounds_layer.getLatLng()], {
maxZoom: Math.max(4, editor.map.getZoom()),
duration: 0.5,
padding: [20, 20]
});
}
for(i=0;i<editor._arrow_colors.length;i++) {
var color = editor._arrow_colors[i];
defs = editor.map.options.renderer._container.querySelector('defs');
// noinspection HtmlUnknownAttribute
defs.insertAdjacentHTML('beforeend', '<marker id="graph-edge-arrow-'+String(i)+'" markerWidth="2" markerHeight="3" refX="3.5" refY="1.5" orient="auto"><path d="M0,0 L2,1.5 L0,3 L0,0" fill="'+color+'"></path></marker>');
}
}
editor._next_zoom = null;
editor.map.doubleClickZoom.enable();
editor._check_start_editing();
});
editor._adjust_line_zoom();
if (editor.map.options.renderer._container !== undefined) {
var defs = editor.map.options.renderer._container.querySelector('defs');
if (defs === null) {
editor.map.options.renderer._container.insertAdjacentHTML('afterbegin', '<defs></defs>');
defs = editor.map.options.renderer._container.querySelector('defs');
} else {
defs.innerHTML = '';
}
for(i=0;i<editor._arrow_colors.length;i++) {
var color = editor._arrow_colors[i];
defs = editor.map.options.renderer._container.querySelector('defs');
// noinspection HtmlUnknownAttribute
defs.insertAdjacentHTML('beforeend', '<marker id="graph-edge-arrow-'+String(i)+'" markerWidth="2" markerHeight="3" refX="3.5" refY="1.5" orient="auto"><path d="M0,0 L2,1.5 L0,3 L0,0" fill="'+color+'"></path></marker>');
}
}
editor._check_start_editing();
})
},
reload_geometries: function () {
if ($('body').is('.map-enabled') && editor._last_geometry_url !== null) {
@ -870,13 +875,13 @@ editor = {
style.weight = 3;
style.color = '#00ff00';
}
if (feature.properties.color !== undefined) {
if (feature.properties.color !== null) {
style.fillColor = feature.properties.color;
}
if (feature.geometry.type === 'LineString') {
style = editor._line_draw_geometry_style(style);
}
if (feature.properties.opacity !== undefined) {
if (feature.properties.opacity !== null) {
style.fillOpacity = feature.properties.opacity;
}
return style
@ -1402,5 +1407,5 @@ LevelControl = L.Control.extend({
if ($('#sidebar').length) {
editor.init();
c3nav_api.authenticated().then(() => editor.init());
}

View file

@ -79,6 +79,7 @@
<script type="text/javascript" src="{% static 'bootstrap/js/bootstrap.js' %}"></script>
<script type="text/javascript" src="{% static 'leaflet/leaflet.js' %}"></script>
<script type="text/javascript" src="{% static 'leaflet/leaflet.editable.js' %}"></script>
<script type="text/javascript" src="{% static 'c3nav/js/api.js' %}"></script>
<script type="text/javascript" src="{% static 'editor/js/editor.js' %}"></script>
{% endcompress %}
</body>

View file

@ -34,7 +34,7 @@ class LevelChildEditUtils(DefaultEditUtils):
@property
def _geometry_url(self):
return '/api/editor/geometries/?level=' + str(self.level.primary_level_pk)
return '/api/v2/editor/geometries/level/' + str(self.level.primary_level_pk)
class SpaceChildEditUtils(DefaultEditUtils):
@ -54,4 +54,4 @@ class SpaceChildEditUtils(DefaultEditUtils):
@property
def _geometry_url(self):
return '/api/editor/geometries/?space='+str(self.space.pk)
return '/api/v2/editor/geometries/space/'+str(self.space.pk)

View file

@ -85,7 +85,7 @@ def level_detail(request, pk):
'child_models': [child_model(request, model_name, kwargs={'level': pk}, parent=level)
for model_name in submodels],
'levels_on_top': level.levels_on_top.filter(Level.q_for_request(request)).all(),
'geometry_url': ('/api/editor/geometries/?level='+str(level.primary_level_pk)
'geometry_url': ('/api/v2/editor/geometries/level/'+str(level.primary_level_pk)
if request.user_permissions.can_access_base_mapdata else None),
}, fields=('level', 'can_edit_graph', 'can_create_level', 'child_models', 'levels_on_top'))
@ -596,7 +596,7 @@ def graph_edit(request, level=None, space=None):
'back_url': reverse('editor.levels.detail', kwargs={'pk': level.pk}),
'back_title': _('back to level'),
'level': level,
'geometry_url': '/api/editor/geometries/?level='+str(level.primary_level_pk),
'geometry_url': '/api/v2/editor/geometries/level/'+str(level.primary_level_pk),
})
elif space is not None:
queryset = Space.objects.filter(Space.q_for_request(request)).select_related('level').defer('geometry')
@ -609,7 +609,7 @@ def graph_edit(request, level=None, space=None):
'back_title': _('back to space'),
'parent_url': reverse('editor.levels.graph', kwargs={'level': level.pk}),
'parent_title': _('to level graph'),
'geometry_url': '/api/editor/geometries/?space='+str(space.pk),
'geometry_url': '/api/v2/editor/geometries/space/'+str(space.pk),
})
create_nodes = True

View file

@ -137,16 +137,13 @@ c3nav = {
_searchable_locations_timer: null,
load_searchable_locations: function(firstTime) {
c3nav._searchable_locations_timer = null;
$.ajax({
dataType: "json",
url: '/api/locations/?searchable',
success: c3nav._searchable_locations_loaded,
ifModified: true,
}).fail(function() {
if(c3nav._searchable_locations_timer === null) {
c3nav._searchable_locations_timer = window.setTimeout(c3nav.load_searchable_locations, c3nav.init_completed ? 300000 : 15000);
}
});
c3nav_api.get('map/locations?searchable=true')
.then(c3nav._searchable_locations_loaded)
.catch(() => {
if (c3nav._searchable_locations_timer === null) {
c3nav._searchable_locations_timer = window.setTimeout(c3nav.load_searchable_locations, c3nav.init_completed ? 300000 : 15000);
}
});
},
_sort_labels: function(a, b) {
var result = (a[0].label_settings.min_zoom || -10) - (b[0].label_settings.min_zoom || -10);
@ -424,14 +421,15 @@ c3nav = {
if ($location_details.attr('data-id') !== String(location.id)) {
$location_details.addClass('loading').attr('data-id', location.id);
c3nav._clear_route_layers();
$.getJSON('/api/locations/'+location.id+'/details', c3nav._location_details_loaded).fail(function (data) {
var $location_details = $('#location-details');
$location_details.find('.details-body').text('Error '+String(data.status));
$location_details.find('.details-body').html('').append(elem);
$location_details.find('.editor').hide();
$location_details.find('.report').hide();
$location_details.removeClass('loading');
});
c3nav_api.get(`map/locations/${location.id}/display`).then(c3nav._location_details_loaded)
.catch(data => {
var $location_details = $('#location-details');
$location_details.find('.details-body').text('Error ' + String(data.status));
$location_details.find('.details-body').html('').append(elem);
$location_details.find('.editor').hide();
$location_details.find('.report').hide();
$location_details.removeClass('loading');
})
}
},
_location_details_loaded: function(data) {
@ -505,17 +503,13 @@ c3nav = {
$route.addClass('loading').attr('data-origin', origin.id).attr('data-destination', destination.id);
$details_wrapper.addClass('loading');
$options_wrapper.addClass('loading');
$.post('/api/routing/route/', $.extend({
'origin': origin.id,
'destination': destination.id,
'csrfmiddlewaretoken': c3nav.get_csrf_token()
}, c3nav.next_route_options || {}), function(data) {
c3nav._route_loaded(data, nofly)
}, 'json').fail(function(data) {
c3nav._route_loaded({
'error': 'Error '+String(data.status)
})
});
c3nav_api.post('routing/route', {
origin: origin.id,
destination: destination.id,
...(c3nav.next_route_options || {}),
})
.then(data => c3nav._route_loaded(data, nofly))
.catch(data => c3nav._route_loaded({error: `Error ${data.status}`}));
}
c3nav.next_route_options = null;
},
@ -824,7 +818,7 @@ c3nav = {
options[$(this).attr('name')] = $(this).val();
});
if ($(this).is('.save')) {
$.post('/api/routing/options/', options);
c3nav_api.post('routing/options', options);
}
c3nav.next_route_options = options;
c3nav.update_state(null, null, null, false);
@ -1443,30 +1437,32 @@ c3nav = {
name = c3nav._latlng_to_name(latlng);
c3nav._click_anywhere_popup = popup;
popup.on('remove', function() { c3nav._click_anywhere_popup = null }).openOn(c3nav.map);
$.getJSON('/api/locations/'+name+'/', function(data) {
if (c3nav._click_anywhere_popup !== popup || !popup.isOpen()) return;
popup.remove();
if (nearby) {
var $destination = $('#destination-input');
c3nav._locationinput_set($destination, data);
c3nav.update_state(false, false, false, false, true);
} else {
newpopup = L.popup(c3nav._add_map_padding({
className: 'location-popup',
maxWidth: 500
}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight'));
var buttons = $('#location-popup-buttons').clone();
buttons.find('.report-issue').remove();
buttons.find('.report').attr('href', '/report/l/' + String(data.id) + '/');
newpopup.setLatLng(latlng).setContent(c3nav._build_location_html(data) + buttons.html());
c3nav._click_anywhere_popup = newpopup;
newpopup.on('remove', function () {
c3nav._click_anywhere_popup = null
}).openOn(c3nav.map);
}
}).fail(function() {
popup.remove();
});
c3nav_api.get(`map/locations/${name}/`)
.then(data => {
if (c3nav._click_anywhere_popup !== popup || !popup.isOpen()) return;
popup.remove();
if (nearby) {
var $destination = $('#destination-input');
c3nav._locationinput_set($destination, data);
c3nav.update_state(false, false, false, false, true);
} else {
newpopup = L.popup(c3nav._add_map_padding({
className: 'location-popup',
maxWidth: 500
}, 'autoPanPaddingTopLeft', 'autoPanPaddingBottomRight'));
var buttons = $('#location-popup-buttons').clone();
buttons.find('.report-issue').remove();
buttons.find('.report').attr('href', '/report/l/' + String(data.id) + '/');
newpopup.setLatLng(latlng).setContent(c3nav._build_location_html(data) + buttons.html());
c3nav._click_anywhere_popup = newpopup;
newpopup.on('remove', function () {
c3nav._click_anywhere_popup = null
}).openOn(c3nav.map);
}
})
.catch(function() {
popup.remove();
});
},
_map_moved: function () {
c3nav.update_map_state();
@ -1588,7 +1584,8 @@ c3nav = {
}
if (location.dynamic) {
if (!('available' in location)) {
$.getJSON('/api/locations/dynamic/' + location.id + '/', c3nav._dynamic_location_loaded);
c3nav_api.get(`map/locations/dynamic/${location.id}/`)
.then(c3nav._dynamic_location_loaded);
return;
} else if (!location.available) {
return;
@ -1605,7 +1602,7 @@ c3nav = {
if (!no_geometry && c3nav._visible_map_locations.indexOf(location.id) === -1) {
c3nav._visible_map_locations.push(location.id);
$.getJSON('/api/locations/' + location.id + '/geometry/', c3nav._location_geometry_loaded);
c3nav_api.get(`map/locations/${location.id}/geometry/`).then(c3nav._location_geometry_loaded);
}
if (!location.point) return;
@ -1675,12 +1672,14 @@ c3nav = {
_fetch_updates_failure_count: 0,
fetch_updates: function () {
c3nav._fetch_updates_timer = null;
$.get('/api/updates/fetch/', c3nav._fetch_updates_callback).fail(function() {
c3nav._fetch_updates_failure_count++;
waittime = Math.min(5 + c3nav._fetch_updates_failure_count * 5, 120);
// console.log('fetch updates failed, retying in ' + waittime + 'sec');
c3nav.schedule_fetch_updates(waittime*1000);
});
c3nav_api.get('updates/fetch')
.then(c3nav._fetch_updates_callback)
.catch(() => {
c3nav._fetch_updates_failure_count++;
waittime = Math.min(5 + c3nav._fetch_updates_failure_count * 5, 120);
// console.log('fetch updates failed, retying in ' + waittime + 'sec');
c3nav.schedule_fetch_updates(waittime*1000);
});
},
_fetch_updates_callback: function (data) {
c3nav._fetch_updates_failure_count = 0;
@ -1782,21 +1781,12 @@ c3nav = {
}
c3nav._no_wifi_count = 0;
$.post({
url: '/api/routing/locate/',
data: JSON.stringify(data),
dataType: 'json',
contentType: 'application/json',
beforeSend: function(xhrObj){
xhrObj.setRequestHeader('X-CSRFToken', c3nav.get_csrf_token());
},
success: function(data) {
c3nav._set_user_location(data.location);
}
}).fail(function() {
c3nav._set_user_location(null);
c3nav._last_wifi_scan = Date.now() + 20000
});
c3nav_api.post('routing/locate', data)
.then(data => c3nav._set_user_location(data.location))
.catch(() => {
c3nav._set_user_location(null);
c3nav._last_wifi_scan = Date.now() + 20000
});
},
_current_user_location: null,
_set_user_location: function(location) {

View file

@ -238,6 +238,7 @@
<script type="text/javascript" src="{% static 'leaflet/leaflet.js' %}"></script>
<script type="text/javascript" src="{% static 'leaflet-layergroup-collision/rbush.js' %}"></script>
<script type="text/javascript" src="{% static 'leaflet-layergroup-collision/Leaflet.LayerGroup.Collision.js' %}"></script>
<script type="text/javascript" src="{% static 'c3nav/js/api.js' %}"></script>
<script type="text/javascript" src="{% static 'site/js/c3nav.js' %}"></script>
{% endcompress %}
{% endblock %}

View file

@ -0,0 +1,62 @@
(function () {
class C3NavApi {
token = 'anonymous';
constructor(base ) {
this.base = base;
this.auth_promise = fetch(this.base+'auth/session/', {
credentials: 'same-origin',
method: 'GET',
})
.then(res => res.json())
.then(data => {
this.token = data.token
})
.catch(err => {
throw err;
})
.then(_ => null);
}
authenticated() {
return this.auth_promise;
}
make_url(path) {
const url = new URL(path, this.base);
if (!url.pathname.endsWith('/')) {
url.pathname += '/';
}
return url;
}
get(path) {
return fetch(this.make_url(path), {
credentials: 'omit',
method: 'GET',
headers: {
'Authorization': `Bearer ${this.token}`,
'Accept': 'application/json'
}
})
.then(res => res.json())
}
async post(path, data) {
return fetch(this.make_url(path), {
credentials: 'omit',
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(res => res.json())
}
}
window.c3nav_api = new C3NavApi(`${window.location.origin}/api/v2/`);
})();