combo/combo/apps/maps/static/js/combo.map.js

206 lines
9.9 KiB
JavaScript

$(function() {
L.Map.include(
{
add_geojson_layer: function(callback) {
var map = this;
var $map_widget = $(map.getContainer());
var cell = $map_widget.parents('div.cell')[0];
var geojson_url = $map_widget.data('geojson-url');
if (!geojson_url) return;
if (map.geojson_retrieval) {
map.geojson_retrieval.abort();
}
map.geojson_retrieval = $.getJSON(geojson_url, function(data) {
var geo_json = L.geoJson(data, {
onEachFeature: function(feature, layer) {
$(cell).trigger('combo:map-feature-prepare', {'feature': feature, 'layer': layer});
var marker_behaviour_onclick = $map_widget.data('marker-behaviour-onclick');
if (marker_behaviour_onclick === 'display_data') {
var popup = '';
if (feature.properties.display_fields) {
var popup = '';
$.each(feature.properties.display_fields, function(idx, field) {
var $popup_field = $('<div><div class="popup-field property-' + field.varname + '"><span class="field-label"></span><span class="field-value"></span></div></div>');
$popup_field.find('.field-label').text(field.label);
if (field.html_value){
$popup_field.find('.field-value').html(field.html_value);
} else {
$popup_field.find('.field-value').text(field.value);
}
popup += $popup_field.html();
});
} else {
var ordered_keys = feature.properties.layer.properties;
if (! ordered_keys) {
ordered_keys = Object.keys(properties).sort();
}
var properties = feature.properties;
$.each(ordered_keys, function(idx, field) {
// exclude object type properties
if (typeof(properties[field]) !== 'object') {
var $popup_field = $('<div><div class="popup-field property-' + field + '"></span><span class="field-value"></span></div></div>');
$popup_field.find('.field-value').text(properties[field]);
popup += $popup_field.html()
}
});
}
layer.bindPopup(popup);
}
},
pointToLayer: function (feature, latlng) {
var markerStyles = "background-color: " + feature.properties.layer.colour + ";";
marker = L.divIcon({
iconAnchor: [0, 0],
popupAnchor: [5, -45],
html: '<span class="layer-' +
feature.properties.layer.identifier +
'" style="' + markerStyles + '"><i class="leaflet-marker-icon ' +
feature.properties.layer.icon + '" style="color:' +
feature.properties.layer.icon_colour +'"></i></span>'
});
return L.marker(latlng, {icon: marker});
}
});
if (map.geo_json) map.geo_json.remove();
map.geo_json = geo_json;
if ($map_widget.data('group-markers')) {
if (! map.clustered_markers) {
map.clustered_markers = L.markerClusterGroup({showCoverageOnHover: false,
zoomToBoundsOnClick: true,
removeOutsideVisibleBounds: true,
iconCreateFunction: function (cluster) {
var icon_size = 60;
var childCount = cluster.getChildCount();
var icon_html = '<div><span>' + childCount + '</span></div>';
var c = ' marker-cluster-';
if (childCount < 10) {
c += 'small';
} else if (childCount < 100) {
c += 'medium';
} else {
c += 'large';
}
return new L.DivIcon({html: icon_html, className: 'marker-cluster' + c, iconSize: new L.Point(icon_size, icon_size)});
}});
map.addLayer(map.clustered_markers);
}
map.clustered_markers.eachLayer(
function(layer) {
map.clustered_markers.removeLayer(layer);
}
);
map.clustered_markers.addLayer(geo_json);
} else {
geo_json.addTo(map);
}
if (callback) {
callback(geo_json);
}
$(cell).trigger('combo:map-markers-ready');
});
}
});
function render_map(cell) {
var $map_widget = $(cell).find('div.combo-cell-map');
var map_options = Object();
var initial_zoom = parseInt($map_widget.data('init-zoom'));
if (! isNaN(initial_zoom)) {
map_options.zoom = initial_zoom;
} else {
map_options.zoom = 13;
}
var init_state = $map_widget.data('init-state');
var max_zoom = parseInt($map_widget.data('max-zoom'));
if (!isNaN(max_zoom)) {
map_options.maxZoom = max_zoom;
} else {
map_options.maxZoom = 19;
}
var min_zoom = parseInt($map_widget.data('min-zoom'));
if (!isNaN(min_zoom)) map_options.minZoom = min_zoom;
map_options.zoomControl = false;
var latlng = [$map_widget.data('init-lat'), $map_widget.data('init-lng')];
var geojson_url = $map_widget.data('geojson-url');
if ($map_widget.data('max-bounds-lat1')) {
map_options.maxBounds = L.latLngBounds(
L.latLng($map_widget.data('max-bounds-lat1'), $map_widget.data('max-bounds-lng1')),
L.latLng($map_widget.data('max-bounds-lat2'), $map_widget.data('max-bounds-lng2')))
}
map_options.gestureHandling = true;
var map = L.map($map_widget[0], map_options);
if ($map_widget.data('draggable') === false) {
map.dragging.disable();
}
var map_controls_position = $('body').data('map-controls-position') || 'topleft';
if (map_options.maxZoom != map_options.minZoom) {
new L.Control.Zoom({
position: map_controls_position,
zoomInTitle: gettext('Zoom in'),
zoomOutTitle: gettext('Zoom out')
}).addTo(map);
}
var gps_control = null;
if (L.Control.Gps && $map_widget.data('include-geoloc-button')) {
gps_control = new L.Control.Gps({
position: map_controls_position,
tooltipTitle: gettext('Display my position')});
map.addControl(gps_control);
}
$map_widget[0].leaflet_map = map;
map.setView(latlng, map_options.zoom);
if (init_state == 'device-location') {
$map_widget.addClass('waiting-for-geolocation');
map.locate({timeout: 10000, maximumAge: 300000, enableHighAccuracy: false});
map.on('locationfound', function(e) {
$map_widget.removeClass('waiting-for-geolocation');
if (map_options.maxBounds && ! map_options.maxBounds.contains(e.latlng)) {
/* ouf of bounds, keep map centered on default position */
return;
}
map.setView(e.latlng, map_options.zoom);
if (gps_control) {
gps_control.addLayer();
}
});
map.on('locationerror', function(e) {
$map_widget.removeClass('waiting-for-geolocation');
$map_widget.addClass('geolocation-error');
});
}
var map_id = $map_widget.data('cell-id');
var tiles_layers = window['tiles_'+map_id];
$.each(tiles_layers, function(idx, layer) {
L.tileLayer(
layer.tile_urltemplate,
{
attribution: layer.map_attribution,
opacity: layer.opacity,
maxZoom: map_options.maxZoom
}
).addTo(map);
});
if (geojson_url) {
map.add_geojson_layer(function(geo_json) {
var bounds = geo_json.getBounds();
if (bounds.isValid()) {
if (init_state == 'fit-markers') {
map.fitBounds(bounds);
}
}
$(cell).trigger('combo:map-ready');
});
} else {
$(cell).trigger('combo:map-ready');
}
};
$('div.cell.map').each(function() {
render_map(this);
});
});