Newer
Older
/* eslint-disable no-mixed-spaces-and-tabs */
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */
Sébastien DA ROCHA
committed
import L from "leaflet"
import "leaflet/dist/leaflet.css";
import flip from '@turf/flip'
Sébastien DA ROCHA
committed
import { FillSymbolizer, PointSymbolizer, LineSymbolizer } from "@/assets/js/vector_tile_fix.js";
Sébastien DA ROCHA
committed
let map;
let dictLayersToLeaflet = {};
{
name: "Brouillon",
value: "draft",
},
{
name: "Publié",
value: "published",
},
{
name: "Archivé",
value: "archived",
},
{
name: "En attente de publication",
value: "pending",
},
];
Sébastien DA ROCHA
committed
L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({
onAdd: function (map) {
// Triggered when the layer is added to a map.
// Register a click listener, then do all the upstream WMS things
L.TileLayer.WMS.prototype.onAdd.call(this, map);
map.on('click', this.getFeatureInfo, this);
},
onRemove: function (map) {
// Triggered when the layer is removed from a map.
// Unregister a click listener, then do all the upstream WMS things
L.TileLayer.WMS.prototype.onRemove.call(this, map);
map.off('click', this.getFeatureInfo, this);
},
getFeatureInfo: function (evt) {
if (this.wmsParams.basemapId != undefined) {
const queryableLayerSelected = document.getElementById(`queryable-layers-selector-${this.wmsParams.basemapId}`).getElementsByClassName('selected')[0].textContent;
if (queryableLayerSelected.trim() === this.wmsParams.title.trim()) {
Sébastien DA ROCHA
committed
// Make an AJAX request to the server and hope for the best
var params = this.getFeatureInfoUrl(evt.latlng);
var showResults = L.Util.bind(this.showGetFeatureInfo, this);
Sébastien DA ROCHA
committed
window.proxy_url,
{
Sébastien DA ROCHA
committed
//dataType: "json",
}
).then(response => {
let data = response.data;
var err = typeof data === 'object' ? null : data;
if (data.features || err) {
showResults(err, evt.latlng, data);
}
})
.catch(error => {
throw (error)
//xhr.status;
//xhr.responseText;
}
)
Sébastien DA ROCHA
committed
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
}
}
},
getFeatureInfoUrl: function (latlng) {
// Construct a GetFeatureInfo request URL given a point
var point = this._map.latLngToContainerPoint(latlng, this._map.getZoom());
var size = this._map.getSize(),
params = {
url: this._url,
request: 'GetFeatureInfo',
service: 'WMS',
// srs: this.wmsParams.srs,
srs: 'EPSG:4326',
// styles: this.wmsParams.styles,
// transparent: this.wmsParams.transparent,
version: this.wmsParams.version,
// format: this.wmsParams.format,
bbox: this._map.getBounds().toBBoxString(),
height: size.y,
width: size.x,
layers: this.wmsParams.layers,
query_layers: this.wmsParams.layers,
info_format: 'application/json'
};
params[params.version === '1.3.0' ? 'i' : 'x'] = Math.floor(point.x);
params[params.version === '1.3.0' ? 'j' : 'y'] = Math.floor(point.y);
return params;
},
showGetFeatureInfo: function (err, latlng, data) {
let content;
if (err) {
content = `
<h4>${this.options.title}</h4>
<p>Données de la couche inaccessibles</p>
`
L.popup({ maxWidth: 800 })
.setLatLng(latlng)
.setContent(content)
.openOn(this._map);
} else {
// Otherwise show the content in a popup
let contentLines = [];
let contentTitle;
if (data.features.length > 0) {
Object.entries(data.features[0].properties).forEach(entry => {
const [key, value] = entry;
if (key !== 'bbox') {
contentLines.push(`<div>${key}: ${value}</div>`);
}
})
contentTitle = `<h4>${this.options.title}</h4>`;
content = contentTitle.concat(contentLines.join(''));
L.popup({ maxWidth: 800 })
.setLatLng(latlng)
.setContent(content)
.openOn(this._map);
Sébastien DA ROCHA
committed
}
}
});
L.tileLayer.betterWms = function (url, options) {
return new L.TileLayer.BetterWMS(url, options);
};
const mapUtil = {
getMap: () => {
return map;
},
Sébastien DA ROCHA
committed
const {
lat,
lng,
mapDefaultViewCenter,
mapDefaultViewZoom,
zoom,
zoomControl = true,
} = options;
Sébastien DA ROCHA
committed
maxZoom: 18,
Sébastien DA ROCHA
committed
zoomControl: false,
}).setView(
[
!lat ? mapDefaultViewCenter[0] : lat,
!lng ? mapDefaultViewCenter[1] : lng,
],
!zoom ? mapDefaultViewZoom : zoom
);
Sébastien DA ROCHA
committed
if (zoomControl) {
L.control
.zoom({
zoomInTitle: 'Zoomer',
zoomOutTitle: 'Dézoomer',
position: 'topright',
})
.addTo(map);
}
L.control.scale().addTo(map);
return map;
},
addGeocoders: function (configuration) {
let geocoder;
const geocoderLabel = configuration.SELECTED_GEOCODER.PROVIDER;
const LIMIT_RESULTS = 5;
if (
geocoderLabel === configuration.GEOCODER_PROVIDERS.ADDOK
) {
geocoder = L.Control.Geocoder.addok({ limit: LIMIT_RESULTS });
} else if (
geocoderLabel === configuration.GEOCODER_PROVIDERS.PHOTON
) {
geocoder = L.Control.Geocoder.photon();
} else if (
geocoderLabel === configuration.GEOCODER_PROVIDERS.NOMINATIM
) {
geocoder = L.Control.Geocoder.nominatim();
}
Sébastien DA ROCHA
committed
L.Control.geocoder({
placeholder: "Chercher une adresse...",
geocoder: geocoder,
}).addTo(map);
}
},
Sébastien DA ROCHA
committed
addLayers: function (layers, serviceMap, optionsMap) {
if (layers) {
layers.forEach((layer) => {
if (layer) {
const options = layer.options;
Sébastien DA ROCHA
committed
if (options) {
options.opacity = layer.opacity;
if (layer.schema_type === 'wms') {
let leafletLayer;
if (layer.queryable) {
options.title = layer.title;
leafletLayer = L.tileLayer
.betterWms(layer.service, options)
.addTo(map);
} else {
leafletLayer = L.tileLayer
.wms(layer.service, options)
.addTo(map);
}
dictLayersToLeaflet[layer.id] = leafletLayer._leaflet_id;
} else if (layer.schema_type === 'tms') {
const leafletLayer = L.tileLayer(layer.service, options).addTo(map);
dictLayersToLeaflet[layer.id] = leafletLayer._leaflet_id;
}
}
}
});
} else {
Sébastien DA ROCHA
committed
L.tileLayer(serviceMap, optionsMap).addTo(map);
}
},
// Remove the base layers (not the features)
removeLayers: function () {
map.eachLayer((leafLetlayer) => {
if (
Object.values(dictLayersToLeaflet).includes(leafLetlayer._leaflet_id)
) {
map.removeLayer(leafLetlayer);
}
});
dictLayersToLeaflet = {};
},
updateOpacity(layerId, opacity) {
const internalLeafletLayerId = dictLayersToLeaflet[layerId];
map.eachLayer((layer) => {
if (layer._leaflet_id === internalLeafletLayerId) {
layer.setOpacity(opacity);
}
});
},
Sébastien DA ROCHA
committed
updateOrder(layers) {
// First remove existing layers undefined
layers = layers.filter(function (x) {
return x !== undefined;
});
// First remove existing layers
map.eachLayer((leafLetlayer) => {
layers.forEach((layerOptions) => {
if (dictLayersToLeaflet[layerOptions.id] === leafLetlayer._leaflet_id) {
map.removeLayer(leafLetlayer);
}
});
});
dictLayersToLeaflet = {};
// Redraw the layers
this.addLayers(layers);
},
retrieveFeatureColor: function (featureType, properties) {
const colorsStyle = featureType.colors_style;
if (featureType && colorsStyle && colorsStyle.custom_field_name) {
const currentValue = properties[colorsStyle.custom_field_name];
const colorStyle = colorsStyle.colors[currentValue];
return colorStyle ? colorStyle : featureType.color
}
addVectorTileLayer: function (url, project_slug, featureTypes, form_filters) {
"default": (properties) => {
const featureType = featureTypes.find((x) => x.slug.split('-')[0] === '' + properties.feature_type_id);
const color = this.retrieveFeatureColor(featureType, properties)
const hiddenStyle = ({
radius: 0,
fillOpacity: 0.5,
weight: 0,
fill: false,
color: featureType.color,
})
// Filtre sur le feature type
if (form_filters && form_filters.type.selected) {
if (featureType.title !== form_filters.type.selected) {
return hiddenStyle;
// Filtre sur le statut
if (form_filters && form_filters.status.selected.value) {
if (properties.status !== form_filters.status.selected.value) {
return hiddenStyle;
}
}
// Filtre sur le titre
if (form_filters && form_filters.title) {
if (!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())) {
return ({
radius: 4,
fillOpacity: 0.5,
weight: 3,
fill: true,
color: color,
});
// subdomains: "0123",
// key: 'abcdefghi01234567890',
getFeatureId: function (f) {
return f.properties.id;
}
layerMVT.on('click', (e) => { // The .on method attaches an event handler
const popupContent = this._createContentPopup(e.layer, featureTypes, project_slug);
.setContent(popupContent)
.setLatLng(e.latlng)
.openOn(map)
});
addFeatures: function (features, filter, addToMap = true, featureTypes) {
const featureGroup = new L.FeatureGroup();
Sébastien DA ROCHA
committed
features.forEach((feature) => {
const featureProperties = feature.properties ? feature.properties : feature;
const featureType = featureTypes.find((ft) => ft.slug === (featureProperties.feature_type.slug || featureProperties.feature_type));
Sébastien DA ROCHA
committed
let filters = [];
if (filter) {
const typeCheck = filter.featureType && featureProperties.feature_type.slug === filter.featureType;
const statusCheck = filter.featureStatus && featureProperties.status.value === filter.featureStatus;
const titleCheck = filter.featureTitle && featureProperties.title.includes(filter.featureTitle);
Sébastien DA ROCHA
committed
filters = [typeCheck, statusCheck, titleCheck];
}
if (
!filter ||
!Object.values(filter).some(val => val) ||
Object.values(filter).some(val => val) &&
filters.length && filters.every(val => val !== false)
) {
const geomJSON = flip(feature.geometry || feature.geom);
Sébastien DA ROCHA
committed
const popupContent = this._createContentPopup(feature);
// Look for a custom field
let customField;
let customFieldOption;
if (featureType.customfield_set && Object.keys(featureProperties).some(el => featureType.customfield_set.map(e => e.name).includes(el))) {
customField = Object.keys(featureProperties).filter(el => featureType.customfield_set.map(e => e.name).includes(el));
customFieldOption = featureProperties[customField[0]];
let color = this.retrieveFeatureColor(featureType, featureProperties) || featureProperties.color;
if (color == undefined){
color = featureType.color;
const colorValue = color.value ? color.value : color;
Sébastien DA ROCHA
committed
if (geomJSON.type === 'Point') {
if (
customFieldOption &&
featureType.colors_style &&
featureType.colors_style.value &&
featureType.colors_style.value.icons &&
!!Object.keys(featureType.colors_style.value.icons).length
) {
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
if (featureType.colors_style.value.icons[customFieldOption]) {
const iconHTML = `
<i
class="fas fa-${featureType.colors_style.value.icons[customFieldOption]} fa-lg"
style="color: ${colorValue}"
></i>
`;
const customMapIcon = L.divIcon({
html: iconHTML,
iconSize: [20, 20],
className: 'myDivIcon',
});
L.marker(geomJSON.coordinates, {
icon: customMapIcon,
color: colorValue,
zIndexOffset: 100
})
.bindPopup(popupContent)
.addTo(featureGroup);
} else {
L.circleMarker(geomJSON.coordinates, {
color: color,
radius: 4,
fillOpacity: 0.5,
weight: 3,
})
.bindPopup(popupContent)
.addTo(featureGroup);
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
if (featureType.icon) {
const iconHTML = `
<i
class="fas fa-${featureType.icon} fa-lg"
style="color: ${colorValue}"
></i>
`;
const customMapIcon = L.divIcon({
html: iconHTML,
iconSize: [20, 20],
className: 'myDivIcon',
});
L.marker(geomJSON.coordinates, {
icon: customMapIcon,
color: colorValue,
zIndexOffset: 100
})
.bindPopup(popupContent)
.addTo(featureGroup);
} else {
L.circleMarker(geomJSON.coordinates, {
color: color,
radius: 4,
fillOpacity: 0.5,
weight: 3,
})
.bindPopup(popupContent)
.addTo(featureGroup);
}
Sébastien DA ROCHA
committed
} else if (geomJSON.type === 'LineString') {
L.polyline(geomJSON.coordinates, {
Sébastien DA ROCHA
committed
weight: 3,
})
.bindPopup(popupContent)
.addTo(featureGroup);
} else if (geomJSON.type === 'Polygon') {
L.polygon(geomJSON.coordinates, {
Sébastien DA ROCHA
committed
weight: 3,
fillOpacity: 0.5,
})
.bindPopup(popupContent)
.addTo(featureGroup);
}
}
});
Sébastien DA ROCHA
committed
return featureGroup;
},
addMapEventListener: function (eventName, callback) {
map.on(eventName, callback);
},
_createContentPopup: function (feature, featureTypes, project_slug) {
const formatDate = (current_datetime) => {
let formatted_date = current_datetime.getFullYear() + "-" + ("0" + (current_datetime.getMonth() + 1)).slice(-2) + "-" + ("0" + current_datetime.getDate()).slice(-2) + " " +
("0" + current_datetime.getHours()).slice(-2) + ":" + ("0" + current_datetime.getMinutes()).slice(-2);
let status;
let date_maj;
let feature_type_url;
let feature_url;
if (feature.properties) {
status = feature.properties.status;
date_maj = feature.properties.updated_on;
feature_type_url = feature.properties.feature_type_url;
feature_url = feature.properties.feature_url;
} else {
status = feature.status;
date_maj = feature.updated_on;
feature_type_url =feature.feature_type_url;
feature_url = feature.feature_url;
}
if (featureTypes) { // => VectorTile
feature_type = featureTypes.find((x) => x.slug.split('-')[0] === '' + feature.properties.feature_type_id);
status = statusList.find((x) => x.value === feature.properties.status).name;
date_maj = formatDate(new Date(feature.properties.updated_on));
feature_type_url = '/geocontrib/projet/' + project_slug + '/type-signalement/' + feature_type.slug + '/';
feature_url = feature_type_url + 'signalement/' + feature.properties.feature_id + '/';
feature_type = feature.properties ? feature.properties.feature_type : feature.feature_type;
status = feature.properties ? feature.properties.status.label : feature.status.label;
let author = '';
const creator = feature.properties ? feature.properties.creator : feature.creator
if (creator) {
author = creator.full_name
Auteur : ${creator.first_name} ${creator.last_name}
Sébastien DA ROCHA
committed
</div>`
: creator.username ? `<div>Auteur: ${creator.username}</div>` : '';
Sébastien DA ROCHA
committed
}
const title = feature.properties ? feature.properties.title : feature.title;
Sébastien DA ROCHA
committed
return `
<h4>
<a href="${feature_url}">${title}</a>
Sébastien DA ROCHA
committed
</h4>
<div>
Sébastien DA ROCHA
committed
</div>
<div>
Type : <a href="${feature_type_url}"> ${feature_type.title} </a>
Sébastien DA ROCHA
committed
</div>
<div>
Sébastien DA ROCHA
committed
</div>
${author}
`;
},
};