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);
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
const color = this.retrieveFeatureColor(featureType, properties);
// Look for a custom field
let customField;
let customFieldOption;
if (featureType.customfield_set && Object.keys(properties).some(el => featureType.customfield_set.map(e => e.name).includes(el))) {
customField = Object.keys(properties).filter(el => featureType.customfield_set.map(e => e.name).includes(el));
customFieldOption = properties[customField[0]];
}
let defaultStyle;
let hiddenStyle;
if (
featureType.colors_style.value.icons[customFieldOption] &&
featureType.colors_style.value.icons[customFieldOption] !== 'circle'
) {
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',
});
defaultStyle = {
icon: customMapIcon
};
hiddenStyle = ({
icon: customMapIcon
});
} else {
defaultStyle = {
radius: 4,
fillOpacity: 0.5,
weight: 3,
fill: true,
color: color,
};
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())) {
// 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.length ?
color.value : typeof color === 'string' && color.length ?
color : '#000000';
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
) {
if (
featureType.colors_style.value.icons[customFieldOption] &&
featureType.colors_style.value.icons[customFieldOption] !== 'circle'
) {
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, {
radius: 4,
fillOpacity: 0.5,
weight: 3,
})
.bindPopup(popupContent)
.addTo(featureGroup);
if (featureType.icon && featureType.icon !== 'circle') {
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
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}
`;
},
};