Add possibility to add external geojson

This commit is contained in:
pietervdvn 2021-03-21 01:32:21 +01:00
parent d7c1f38d26
commit f0765df5ed
10 changed files with 98 additions and 11 deletions

View file

@ -127,7 +127,7 @@ export default class LayerConfig {
* A string is interpreted as a name to call * A string is interpreted as a name to call
* @param tagRenderings * @param tagRenderings
*/ */
function trs(tagRenderings?: (string | TagRenderingConfigJson)[]) { function trs(tagRenderings?: (string | TagRenderingConfigJson)[], readOnly = false) {
if (tagRenderings === undefined) { if (tagRenderings === undefined) {
return []; return [];
} }
@ -137,6 +137,10 @@ export default class LayerConfig {
if (typeof renderingJson === "string") { if (typeof renderingJson === "string") {
if (renderingJson === "questions") { if (renderingJson === "questions") {
if(readOnly){
throw `A tagrendering has a question, but asking a question does not make sense here: is it a title icon or a geojson-layer? ${context}`
}
return new TagRenderingConfig("questions", undefined) return new TagRenderingConfig("questions", undefined)
} }
@ -151,7 +155,7 @@ export default class LayerConfig {
}); });
} }
this.tagRenderings = trs(json.tagRenderings); this.tagRenderings = trs(json.tagRenderings, this.source.geojsonSource !== undefined);
const titleIcons = []; const titleIcons = [];
@ -164,7 +168,7 @@ export default class LayerConfig {
} }
} }
this.titleIcons = trs(titleIcons); this.titleIcons = trs(titleIcons, true);
this.title = tr("title", undefined); this.title = tr("title", undefined);

View file

@ -394,7 +394,7 @@ export class InitUiElements {
features.forEach(feature => { features.forEach(feature => {
State.state.allElements.addOrGetElement(feature); State.state.allElements.addOrGetElement(feature);
if (Hash.hash.data === feature.properties.id.replace("/", "_")) { if (Hash.hash.data === feature.properties.id) {
State.state.selectedElement.setData(feature); State.state.selectedElement.setData(feature);
} }

View file

@ -85,6 +85,10 @@ export default class UpdateFromOverpass implements FeatureSource {
if (layer.doNotDownload) { if (layer.doNotDownload) {
continue; continue;
} }
if(layer.source.geojsonSource !== undefined){
// Not our responsibility to download this layer!
continue;
}
// Check if data for this layer has already been loaded // Check if data for this layer has already been loaded

View file

@ -11,6 +11,7 @@ import LayerConfig from "../../Customizations/JSON/LayerConfig";
import LocalStorageSource from "./LocalStorageSource"; import LocalStorageSource from "./LocalStorageSource";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
import Loc from "../../Models/Loc"; import Loc from "../../Models/Loc";
import GeoJsonSource from "./GeoJsonSource";
export default class FeaturePipeline implements FeatureSource { export default class FeaturePipeline implements FeatureSource {
@ -30,6 +31,15 @@ export default class FeaturePipeline implements FeatureSource {
) )
); );
const geojsonSources: GeoJsonSource [] = []
for (const flayer of flayers.data) {
const sourceUrl = flayer.layerDef.source.geojsonSource
if (sourceUrl !== undefined) {
geojsonSources.push(new WayHandlingApplyingFeatureSource(flayers,
new GeoJsonSource(flayer.layerDef.id, sourceUrl)))
}
}
const amendedLocalStorageSource = const amendedLocalStorageSource =
new RememberingSource( new RememberingSource(
new WayHandlingApplyingFeatureSource(flayers, new WayHandlingApplyingFeatureSource(flayers,
@ -41,7 +51,8 @@ export default class FeaturePipeline implements FeatureSource {
const merged = new FeatureSourceMerger([ const merged = new FeatureSourceMerger([
amendedOverpassSource, amendedOverpassSource,
amendedLocalStorageSource, amendedLocalStorageSource,
newPoints newPoints,
...geojsonSources
]); ]);
const source = const source =

View file

@ -22,7 +22,6 @@ export default class FeatureSourceMerger implements FeatureSource {
let all = {}; // Mapping 'id' -> {feature, freshness} let all = {}; // Mapping 'id' -> {feature, freshness}
for (const source of this._sources) { for (const source of this._sources) {
if(source?.features?.data === undefined){ if(source?.features?.data === undefined){
console.log("Not defined");
continue; continue;
} }
for (const f of source.features.data) { for (const f of source.features.data) {

View file

@ -0,0 +1,52 @@
import FeatureSource from "./FeatureSource";
import {UIEventSource} from "../UIEventSource";
import * as $ from "jquery";
import {Layer} from "leaflet";
/**
* Fetches a geojson file somewhere and passes it along
*/
export default class GeoJsonSource implements FeatureSource {
features: UIEventSource<{ feature: any; freshness: Date }[]>;
constructor(layerId: string, url: string, onFail: ((errorMsg: any) => void) = undefined) {
if (onFail === undefined) {
onFail = errorMsg => {
console.warn(`Could not load geojson layer from`, url, "due to", errorMsg)
}
}
this.features = new UIEventSource<{ feature: any; freshness: Date }[]>(undefined)
const eventSource = this.features;
$.getJSON(url, function (json, status) {
if (status !== "success") {
console.log("Fetching geojson failed failed")
onFail(status);
return;
}
if (json.elements === [] && json.remarks.indexOf("runtime error") > 0) {
console.log("Timeout or other runtime error");
onFail("Runtime error (timeout)")
return;
}
const time = new Date();
const features: { feature: any, freshness: Date } [] = []
let i = 0;
for (const feature of json.features) {
if (feature.properties.id === undefined) {
feature.properties.id = url + "/" + i;
feature.id = url + "/" + i;
i++;
}
feature._matching_layer_id = layerId;
features.push({feature: feature, freshness: time})
}
console.log("Loaded features are", features)
eventSource.setData(features)
}).fail(onFail)
}
}

View file

@ -44,6 +44,7 @@ export class Overpass {
if (status !== "success") { if (status !== "success") {
console.log("Query failed") console.log("Query failed")
onFail(status); onFail(status);
return;
} }
if (json.elements === [] && json.remarks.indexOf("runtime error") > 0) { if (json.elements === [] && json.remarks.indexOf("runtime error") > 0) {

View file

@ -110,7 +110,7 @@ export default class ShowDataLayer {
private postProcessFeature(feature, leafletLayer: L.Layer) { private postProcessFeature(feature, leafletLayer: L.Layer) {
const layer: LayerConfig = this._layerDict[feature._matching_layer_id]; const layer: LayerConfig = this._layerDict[feature._matching_layer_id];
if(layer === undefined){ if(layer === undefined){
console.warn("No layer found for object (probably a now disabled layer)", feature) console.warn("No layer found for object (probably a now disabled layer)", feature, this._layerDict)
return; return;
} }
if (layer.title === undefined && (layer.tagRenderings ?? []).length === 0) { if (layer.title === undefined && (layer.tagRenderings ?? []).length === 0) {

View file

@ -62,7 +62,8 @@
"if": "id~=-", "if": "id~=-",
"then": "<span class='alert'>Uploading...</alert>" "then": "<span class='alert'>Uploading...</alert>"
} }
] ],
"condition": "id~(node|way|relation)/[0-9]*"
}, },
"sharelink": { "sharelink": {
"render": "{share_link()}" "render": "{share_link()}"

View file

@ -15,7 +15,7 @@
"maintainer": "MapComplete", "maintainer": "MapComplete",
"icon": "./assets/layers/play_forest/icon.svg", "icon": "./assets/layers/play_forest/icon.svg",
"hideFromOverview": true, "hideFromOverview": true,
"lockLocation": true, "lockLocation": false,
"version": "0", "version": "0",
"startLat": 51.17174, "startLat": 51.17174,
"startLon": 4.449462, "startLon": 4.449462,
@ -23,13 +23,28 @@
"widenFactor": 0.05, "widenFactor": 0.05,
"socialImage": "", "socialImage": "",
"defaultBackgroundId": "CartoDB.Positron", "defaultBackgroundId": "CartoDB.Positron",
"layers": [ "layersX": [
"play_forest", "play_forest",
"playground", "playground",
"sport_pitch", "sport_pitch",
"slow_roads", "slow_roads",
"grass_in_parks", "grass_in_parks",
"village_green" "village_green"
],
"layers": [
{
"id": "test",
"source": {
"osmTags": "country~*",
"geoJsonSource": "https://pietervdvn.github.io/latlon2country/15.10774.14922.json"
},
"maxOverlapPercentage": 0,
"name": "test",
"title": "Test",
"minzoom": 0
}
], ],
"roamingRenderings": [] "roamingRenderings": []
} }