toodego: redo marker/tile loading with cache & reduced queries

This commit is contained in:
Frédéric Péters 2020-05-16 14:31:14 +02:00
parent 5d0c17e88d
commit f28ddab475
1 changed files with 143 additions and 74 deletions

View File

@ -92,6 +92,74 @@ $(function() {
return false;
});
/* map/marker tile */
function map_marker_identifier(slug, marker) {
return slug + ':' + (
marker.feature.properties.gid ||
marker.feature.properties.id ||
marker.feature.properties.pkgid ||
marker.feature.properties.identifiant);
}
function map_marker_tile(map, marker_tile_identifier, marker, options) {
if (!options) options = Object();
var marker_tile_cache = map.geojson_tile_cache[marker_tile_identifier];
var $tile = $('[data-leaflet-id="' + marker_tile_identifier + '"]');
if ($tile.length == 0) {
$tile = $('<div class="cell" data-leaflet-id="' + marker_tile_identifier + '"><div class="tile">' +
'<div class="tile-picture"></div>' +
'<div class="tile-head"><div class="tile-title"><h2></h2><span class="producer"></span></div></div>' +
' </div></div>');
}
$tile.html(marker_tile_cache.html);
if ($tile.find('[data-tile-cache]').length == 0) {
map.geojson_tile_cache[marker_tile_identifier].html = null;
} else {
var now = new Date().getTime() / 1000;
if (options.init) {
var cache = parseInt($tile.find('[data-tile-cache]').data('tile-cache'));
map.geojson_tile_cache[marker_tile_identifier].expire = now + cache / (1 + Math.random());
} else {
if (map.geojson_tile_cache[marker_tile_identifier].expire > now) {
map.geojson_tile_cache[marker_tile_identifier].html = null;
}
}
}
$sidebar.removeClass('empty');
$sidebar.removeClass('loading');
$('#empty-map-results').remove();
if (options.move_first) {
$tile.detach().prependTo($sidebar);
$sidebar[0].scrollTop = 0;
}
if (options.select) {
$('#sidebar .cell').removeClass('selected');
$tile.addClass('selected');
/* on mobile, increase search zone height to make cell visible */
var mql = window.matchMedia("(max-width: 1100px)");
if (mql.matches) {
$('#sidebar').css('min-height', $tile.height() + 10);
}
}
$tile[0].matching_marker = marker;
marker.matching_tile = $tile;
$tile.off('click').on('click', function(ev) {
if (ev.target.nodeName != 'A') {
var zoom_level = 18;
if (map.getZoom() > zoom_level) {
// no unzooming to avoid clusters reappearing (#26554)
zoom_level = map.getZoom();
}
map.flyTo(marker.getLatLng(), zoom_level);
$('#sidebar .cell').removeClass('selected');
$tile.addClass('selected');
}
return true;
});
}
/* map search */
$('.search-page div.cell.map').addClass('loading').on('combo:map-markers-ready', function() {
$(this).removeClass('loading');
@ -113,9 +181,12 @@ $(function() {
$('.search-page div.cell.map').on('combo:map-feature-prepare', function(ev, info) {
var geojson_layer_slug = info.geojson_layer.slug;
info.layer.on('click', function(ev) {
var marker = info.layer;
var marker_tile_identifier = map_marker_identifier(geojson_layer_slug, marker);
var $matching_tile = $('[data-leaflet-id="' + marker_tile_identifier + '"]');
$('.leaflet-marker-icon.loading').removeClass('loading');
if (info.layer.matching_tile) {
if (info.layer.matching_tile.hasClass('selected')) {
if ($matching_tile.length) {
if ($matching_tile.hasClass('selected')) {
/* second click on same tile */
var mql = window.matchMedia("(max-width: 1100px)");
if (mql.matches) {
@ -125,7 +196,7 @@ $(function() {
return;
}
$('#sidebar .cell').removeClass('selected');
info.layer.matching_tile.addClass('selected');
$matching_tile.addClass('selected');
var $selected_cell = $('#sidebar .cell.selected');
if ($selected_cell.prev().length) {
$selected_cell.prependTo($selected_cell.parent());
@ -139,33 +210,33 @@ $(function() {
return;
}
/* dynamically load tile and put it first */
$(info.layer._icon).addClass('loading');
$.ajax({
url: '/api/dashboard/auto-tile/' + geojson_layer_slug + '/',
data: JSON.stringify(ev.target.feature.properties),
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
success: function(html) {
$(info.layer._icon).removeClass('loading');
$('#sidebar .cell').removeClass('selected');
var $tile = $('<div class="cell selected">' + html + '</div>');
$tile.prependTo($sidebar);
$sidebar[0].scrollTop = 0;
if ($tile.siblings().length > 1) {
$tile.siblings().last()[0].matching_marker.matching_tile = null;
$tile.siblings().last().remove();
}
$tile[0].matching_marker = info.layer;
info.layer.matching_tile = $tile;
/* on mobile, increase search zone height to make cell visible */
var mql = window.matchMedia("(max-width: 1100px)");
if (mql.matches) {
$('#sidebar').css('min-height', $tile.height() + 10);
}
}
});
var marker_tile_cache = map.geojson_tile_cache[marker_tile_identifier];
if (marker_tile_cache && marker_tile_cache.html) {
var mql = window.matchMedia("(max-width: 1100px)");
if (mql.matches) {
map_marker_tile(map, marker_tile_identifier, marker, {init: false, move_first: true});
} else {
map_marker_tile(map, marker_tile_identifier, marker, {init: false});
}
} else {
map.geojson_tile_cache[marker_tile_identifier] = Object();
map.geojson_tile_cache[marker_tile_identifier].loading = true;
$(marker._icon).addClass('loading');
$.ajax({
url: '/api/dashboard/auto-tile/' + geojson_layer_slug + '/',
data: JSON.stringify(ev.target.feature.properties),
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
success: function(html) {
$(marker._icon).removeClass('loading');
map.geojson_tile_cache[marker_tile_identifier].html = html;
map.geojson_tile_cache[marker_tile_identifier].loading = false;
map_marker_tile(map, marker_tile_identifier, marker, {init: true, move_first: true, select: true});
return;
}
});
}
});
});
@ -176,6 +247,16 @@ $(function() {
var $map_widget = $('div.combo-cell-map');
var map = $map_widget[0].leaflet_map;
var search_timeout_id = null;
function reset_map_query_string() {
map.query_string = "";
if (is_autour_de_moi) {
var center = map.getCenter();
var distance_q = '&distance=1000';
map.query_string += distance_q + '&lat=' + center.lat + '&lng=' + center.lng;
}
}
$map_search_input.on('change keyup paste search', function(e) {
var keycode = e.which || e.keyCode;
if (keycode == 13) { // enter
@ -193,7 +274,7 @@ $(function() {
query = query.toLowerCase();
query = query.replace(/^rue\s/i, '');
if (query.length == 0) { // reset view
map.query_string = "";
reset_map_query_string();
var initial_zoom = parseInt($map_widget.data('init-zoom'));
map.setZoom(initial_zoom);
} else if (query.length < 2) {
@ -228,12 +309,17 @@ $(function() {
$(map).on('movestart', function() {
var mql = window.matchMedia("(max-width: 1100px)");
if (mql.matches) {
$('#sidebar .cell').removeClass('selected');
$('#sidebar').css('min-height', 0);
}
});
$(map).on('zoomend moveend', function() {
$(document).trigger('gnm:new-results');
});
if (map.geojson_tile_cache === undefined) {
map.geojson_tile_cache = Object();
}
$(document).on('gnm:new-results', function(ev, params) {
params = params || {};
if (map.clustered_markers) {
@ -261,11 +347,7 @@ $(function() {
if (! map.getBounds().contains(marker.getLatLng())) {
return;
}
var marker_tile_identifier = (this.slug + ':' + (
marker.feature.properties.gid ||
marker.feature.properties.id ||
marker.feature.properties.pkgid ||
marker.feature.properties.identifiant));
var marker_tile_identifier = map_marker_identifier(this.slug, marker);
var $tile = $('[data-leaflet-id="' + marker_tile_identifier + '"]');
if ($tile.length && params.loadmore) {
return;
@ -273,48 +355,35 @@ $(function() {
if (counter > MAX_DISPLAYED_RESULTS) return;
counter += 1;
if ($tile.length) {
return;
}
$tile = $('<div class="cell" data-leaflet-id="' + marker_tile_identifier + '"><div class="tile placeholder">' +
if ($tile.length == 0) {
$tile = $('<div class="cell" data-leaflet-id="' + marker_tile_identifier + '"><div class="tile placeholder">' +
'<div class="tile-picture"></div>' +
'<div class="tile-head"><div class="tile-title"><h2></h2><span class="producer"></span></div></div>' +
' </div></div>');
$tile.appendTo($sidebar);
$.ajax({
url: '/api/dashboard/auto-tile/' + this.slug + '/',
data: JSON.stringify(marker.feature.properties),
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
success: function(html) {
if (marker.matching_tile) {
$(marker.matching_tile).remove();
marker.matching_tile = null;
$tile.appendTo($sidebar);
}
var marker_tile_cache = map.geojson_tile_cache[marker_tile_identifier];
if (marker_tile_cache && marker_tile_cache.loading) {
// pass
} else if (marker_tile_cache && marker_tile_cache.html) {
map_marker_tile(map, marker_tile_identifier, marker, {init: false});
} else {
map.geojson_tile_cache[marker_tile_identifier] = Object();
map.geojson_tile_cache[marker_tile_identifier].loading = true;
$.ajax({
url: '/api/dashboard/auto-tile/' + this.slug + '/',
data: JSON.stringify(marker.feature.properties),
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
success: function(html) {
map.geojson_tile_cache[marker_tile_identifier].html = html;
map.geojson_tile_cache[marker_tile_identifier].loading = false;
map_marker_tile(map, marker_tile_identifier, marker, {init: true});
}
$tile.html(html);
$sidebar.removeClass('empty');
$tile[0].matching_marker = marker;
marker.matching_tile = $tile;
$tile.on('click', function(ev) {
if (ev.target.nodeName != 'A') {
var zoom_level = 18;
if (map.getZoom() > zoom_level) {
// no unzooming to avoid clusters reappearing (#26554)
zoom_level = map.getZoom();
}
map.flyTo(marker.getLatLng(), zoom_level);
}
return true;
});
tile_counter += 1;
if (tile_counter == counter) {
$sidebar.removeClass('loading');
}
$sidebar.removeClass('empty');
$('#empty-map-results').remove();
}
});
});
}
});
if (counter == 0) {
/* remove loading marker if there were no tiles */