forked from MapComplete/MapComplete
OsmObjects can now be used as featureSource, load selected object immediately, zoom to selected object on open; fix #191
This commit is contained in:
parent
5ce4140510
commit
a0c1bc2137
13 changed files with 205 additions and 98 deletions
|
@ -18,27 +18,32 @@ export default class FeaturePipeline implements FeatureSource {
|
|||
|
||||
public features: UIEventSource<{ feature: any; freshness: Date }[]>;
|
||||
|
||||
public readonly name = "FeaturePipeline"
|
||||
|
||||
public readonly name = "FeaturePipeline"
|
||||
|
||||
constructor(flayers: UIEventSource<{ isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }[]>,
|
||||
updater: FeatureSource,
|
||||
fromOsmApi: FeatureSource,
|
||||
layout: UIEventSource<LayoutConfig>,
|
||||
newPoints: FeatureSource,
|
||||
locationControl: UIEventSource<Loc>) {
|
||||
locationControl: UIEventSource<Loc>,
|
||||
selectedElement: UIEventSource<any>) {
|
||||
|
||||
// first we metatag, then we save to get the metatags into storage too
|
||||
// Note that we need to register before we do metatagging (as it expects the event sources)
|
||||
|
||||
const amendedOverpassSource =
|
||||
new RememberingSource(
|
||||
new LocalStorageSaver(
|
||||
new MetaTaggingFeatureSource( // first we metatag, then we save to get the metatags into storage too
|
||||
new RegisteringFeatureSource(
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
new MetaTaggingFeatureSource(
|
||||
new RegisteringFeatureSource(
|
||||
updater)
|
||||
)), layout));
|
||||
|
||||
const geojsonSources: FeatureSource [] = GeoJsonSource
|
||||
.ConstructMultiSource(flayers.data, locationControl)
|
||||
.map(geojsonSource => new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource)));
|
||||
|
||||
.map(geojsonSource => new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource)));
|
||||
|
||||
const amendedLocalStorageSource =
|
||||
new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout))
|
||||
));
|
||||
|
@ -46,10 +51,16 @@ export default class FeaturePipeline implements FeatureSource {
|
|||
newPoints = new MetaTaggingFeatureSource(new FeatureDuplicatorPerLayer(flayers,
|
||||
new RegisteringFeatureSource(newPoints)));
|
||||
|
||||
const amendedOsmApiSource = new RememberingSource(
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
new MetaTaggingFeatureSource(
|
||||
new RegisteringFeatureSource(fromOsmApi))));
|
||||
|
||||
const merged =
|
||||
|
||||
new FeatureSourceMerger([
|
||||
amendedOverpassSource,
|
||||
amendedOsmApiSource,
|
||||
amendedLocalStorageSource,
|
||||
newPoints,
|
||||
...geojsonSources
|
||||
|
@ -60,6 +71,7 @@ export default class FeaturePipeline implements FeatureSource {
|
|||
new FilteringFeatureSource(
|
||||
flayers,
|
||||
locationControl,
|
||||
selectedElement,
|
||||
merged
|
||||
));
|
||||
this.features = source.features;
|
||||
|
|
|
@ -5,12 +5,14 @@ import Loc from "../../Models/Loc";
|
|||
|
||||
export default class FilteringFeatureSource implements FeatureSource {
|
||||
public features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
|
||||
public readonly name = "FilteringFeatureSource"
|
||||
public readonly name = "FilteringFeatureSource"
|
||||
|
||||
constructor(layers: UIEventSource<{
|
||||
isDisplayed: UIEventSource<boolean>,
|
||||
layerDef: LayerConfig
|
||||
}[]>,
|
||||
location: UIEventSource<Loc>,
|
||||
selectedElement: UIEventSource<any>,
|
||||
upstream: FeatureSource) {
|
||||
|
||||
const self = this;
|
||||
|
@ -18,7 +20,7 @@ public readonly name = "FilteringFeatureSource"
|
|||
function update() {
|
||||
|
||||
const layerDict = {};
|
||||
if(layers.data.length == 0){
|
||||
if (layers.data.length == 0) {
|
||||
throw "No layers defined!"
|
||||
}
|
||||
for (const layer of layers.data) {
|
||||
|
@ -32,6 +34,11 @@ public readonly name = "FilteringFeatureSource"
|
|||
const newFeatures = features.filter(f => {
|
||||
const layerId = f.feature._matching_layer_id;
|
||||
|
||||
if(selectedElement.data === f.feature){
|
||||
// This is the selected object - it gets a free pass even if zoom is not sufficient
|
||||
return true;
|
||||
}
|
||||
|
||||
if (layerId !== undefined) {
|
||||
const layer: {
|
||||
isDisplayed: UIEventSource<boolean>,
|
||||
|
@ -41,16 +48,16 @@ public readonly name = "FilteringFeatureSource"
|
|||
missingLayers.add(layerId)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const isShown = layer.layerDef.isShown
|
||||
const tags = f.feature.properties;
|
||||
if(isShown.IsKnown(tags)){
|
||||
if (isShown.IsKnown(tags)) {
|
||||
const result = layer.layerDef.isShown.GetRenderValue(f.feature.properties).txt;
|
||||
if(result !== "yes"){
|
||||
if (result !== "yes") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (FilteringFeatureSource.showLayer(layer, location)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -69,7 +76,7 @@ public readonly name = "FilteringFeatureSource"
|
|||
});
|
||||
console.log("Filtering layer source: input: ", upstream.features.data?.length, "output:", newFeatures.length)
|
||||
self.features.setData(newFeatures);
|
||||
if(missingLayers.size > 0){
|
||||
if (missingLayers.size > 0) {
|
||||
console.error("Some layers were not found: ", Array.from(missingLayers))
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +93,7 @@ public readonly name = "FilteringFeatureSource"
|
|||
if (l.zoom < layer.layerDef.minzoom) {
|
||||
continue;
|
||||
}
|
||||
if(l.zoom > layer.layerDef.maxzoom){
|
||||
if (l.zoom > layer.layerDef.maxzoom) {
|
||||
continue;
|
||||
}
|
||||
if (!layer.isDisplayed.data) {
|
||||
|
@ -98,13 +105,13 @@ public readonly name = "FilteringFeatureSource"
|
|||
}).addCallback(() => {
|
||||
update();
|
||||
});
|
||||
|
||||
|
||||
layers.addCallback(update);
|
||||
|
||||
|
||||
const registered = new Set<UIEventSource<boolean>>();
|
||||
layers.addCallbackAndRun(layers => {
|
||||
for (const layer of layers) {
|
||||
if(registered.has(layer.isDisplayed)){
|
||||
if (registered.has(layer.isDisplayed)) {
|
||||
continue;
|
||||
}
|
||||
registered.add(layer.isDisplayed);
|
||||
|
|
21
Logic/FeatureSource/OsmApiFeatureSource.ts
Normal file
21
Logic/FeatureSource/OsmApiFeatureSource.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import FeatureSource from "./FeatureSource";
|
||||
import {UIEventSource} from "../UIEventSource";
|
||||
import {OsmObject} from "../Osm/OsmObject";
|
||||
|
||||
|
||||
export default class OsmApiFeatureSource implements FeatureSource {
|
||||
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]);
|
||||
public readonly name: string = "OsmApiFeatureSource";
|
||||
|
||||
|
||||
public load(id: string){
|
||||
console.log("Updating from OSM API: ", id)
|
||||
OsmObject.DownloadObject(id, (element, meta) => {
|
||||
const geojson = element.asGeoJson();
|
||||
console.warn(geojson)
|
||||
geojson.id = geojson.properties.id;
|
||||
this.features.setData([{feature:geojson, freshness: meta["_last_edit:timestamp"]}])
|
||||
})
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue