Store custom layers as FeatureCollection

Replace custom format with GeoJSON Features which are already used for
layer configuration. This allows storing also MVT or GeoJSON layers.
This commit is contained in:
Manuel Fuhr 2023-10-10 23:32:51 +02:00 committed by Gautier P
parent 97b94fb5c4
commit 96e3355c85

View file

@ -4,8 +4,26 @@ BR.Layers = L.Class.extend({
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
var layers = JSON.parse(localStorage.getItem('map/customLayers')); var layers = JSON.parse(localStorage.getItem('map/customLayers'));
if (layers?.type == 'FeatureCollection') {
for (const layerData of layers.features) {
this._addLayer(layerData);
}
}
// convert legacy custom format to GeoJSON Feature
else {
for (a in layers) { for (a in layers) {
this._addLayer(a, layers[a].layer, layers[a].isOverlay, layers[a].dataSource); var layerData = {
geometry: null,
properties: {
name: a,
overlay: layers[a].isOverlay,
dataSource: layers[a].dataSource,
query: layers[a].dataSource === 'OverpassAPI' ? layers[a].layer : undefined,
url: layers[a].layer,
},
};
this._addLayer(layerData);
}
} }
} }
}, },
@ -13,17 +31,14 @@ BR.Layers = L.Class.extend({
_loadTable: function () { _loadTable: function () {
var layersData = []; var layersData = [];
for (layer in this._customLayers) { for (layer in this._customLayers) {
if (this._customLayers[layer].dataSource === 'OverpassAPI') { var layerProps = this._customLayers[layer].layerData.properties;
layersData.push([ if (layerProps.dataSource === 'OverpassAPI') {
layer, layersData.push([layer, layerProps.query, i18next.t('sidebar.layers.table.type_overpass_query')]);
this._customLayers[layer].layer.options.query,
i18next.t('sidebar.layers.table.type_overpass_query'),
]);
} else { } else {
var isOverlay = this._customLayers[layer].isOverlay; var isOverlay = layerProps.overlay;
layersData.push([ layersData.push([
layer, layer,
this._customLayers[layer].layer._url, layerProps.url,
isOverlay isOverlay
? i18next.t('sidebar.layers.table.type_overlay') ? i18next.t('sidebar.layers.table.type_overlay')
: i18next.t('sidebar.layers.table.type_layer'), : i18next.t('sidebar.layers.table.type_layer'),
@ -92,45 +107,71 @@ BR.Layers = L.Class.extend({
} }
}, },
_addFromInput: function (isOverlay, dataSource) { _addFromInput: function (layerProps) {
var layer_name = L.DomUtil.get('layer_name').value; var layer_name = L.DomUtil.get('layer_name').value;
var layer_url = L.DomUtil.get('layer_url').value; var layer_url = L.DomUtil.get('layer_url').value;
if (layer_name.length > 0 && layer_url.length > 0) this._addLayer(layer_name, layer_url, isOverlay, dataSource);
var layerData = {
geometry: null,
properties: {
...layerProps,
name: L.DomUtil.get('layer_name').value,
},
type: 'Feature',
};
if (layer_name.length > 0 && layer_url.length > 0) this._addLayer(layerData);
}, },
_addBaseLayer: function (evt) { _addBaseLayer: function (evt) {
this._addFromInput(false); var layerProps = {
type: 'tms',
url: L.DomUtil.get('layer_url').value,
};
this._addFromInput(layerProps);
}, },
_addOverlay: function (evt) { _addOverlay: function (evt) {
this._addFromInput(true); var layerProps = {
type: 'tms',
url: L.DomUtil.get('layer_url').value,
overlay: true,
};
this._addFromInput(layerProps);
}, },
_addOverpassQuery: function (evt) { _addOverpassQuery: function (evt) {
this._addFromInput(true, 'OverpassAPI'); var layerProps = {
overlay: true,
dataSource: 'OverpassAPI',
query: L.DomUtil.get('layer_url').value,
};
this._addFromInput(layerProps);
}, },
_addLayer: function (layerName, layerUrl, isOverlay, dataSource) { _createTmsProps: function (props) {
var tmsProps = {
type: 'tms',
...props,
};
return tmsProps;
},
_addLayer: function (layerData) {
var props = layerData.properties;
var layerName = props.name;
if (layerName in this._layers) return; if (layerName in this._layers) return;
if (layerName in this._customLayers) return; if (layerName in this._customLayers) return;
try { try {
var layer; var layer = this._layersControl.layersConfig.createLayer(layerData);
if (dataSource === 'OverpassAPI') {
layer = this._layersControl.layersConfig.createOverpassLayer(layerUrl);
} else if (dataSource === 'OpenStreetMapNotesAPI') {
layer = this._layersControl.layersConfig.createOpenStreetMapNotesLayer();
} else {
layer = L.tileLayer(layerUrl);
}
this._customLayers[layerName] = { this._customLayers[layerName] = {
layer: layer, layer: layer,
isOverlay: isOverlay, layerData: layerData,
dataSource: dataSource,
}; };
if (isOverlay) { if (props.overlay) {
this._layersControl.addOverlay(layer, layerName); this._layersControl.addOverlay(layer, layerName);
} else { } else {
this._layersControl.addBaseLayer(layer, layerName); this._layersControl.addBaseLayer(layer, layerName);
@ -146,25 +187,11 @@ BR.Layers = L.Class.extend({
_sync: function () { _sync: function () {
if (BR.Util.localStorageAvailable()) { if (BR.Util.localStorageAvailable()) {
localStorage.setItem( var geojson = {
'map/customLayers', type: 'FeatureCollection',
JSON.stringify(this._customLayers, function (k, v) { features: Object.values(this._customLayers).map((layer) => layer.layerData),
if (v === undefined) {
return undefined;
}
if (v.dataSource === 'OverpassAPI') {
return {
dataSource: 'OverpassAPI',
isOverlay: true,
layer: v.layer.options.query,
}; };
} localStorage.setItem('map/customLayers', JSON.stringify(geojson));
// dont write Leaflet.Layer in localStorage; simply keep the URL
return v._url || v;
})
);
} }
}, },
}); });