forked from MapComplete/MapComplete
More refactoring, stabilizing rotation and direction_gradient
This commit is contained in:
parent
5fec108ba2
commit
778044d0fb
45 changed files with 656 additions and 640 deletions
68
Logic/FeatureSource/FeatureDuplicatorPerLayer.ts
Normal file
68
Logic/FeatureSource/FeatureDuplicatorPerLayer.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import FeatureSource from "./FeatureSource";
|
||||
import {UIEventSource} from "../UIEventSource";
|
||||
import LayerConfig from "../../Customizations/JSON/LayerConfig";
|
||||
|
||||
|
||||
/**
|
||||
* In some rare cases, some elements are shown on multiple layers (when 'passthrough' is enabled)
|
||||
* If this is the case, multiple objects with a different _matching_layer_id are generated.
|
||||
* If not, the _feature_layter_id is added
|
||||
*/
|
||||
export default class FeatureDuplicatorPerLayer implements FeatureSource {
|
||||
public readonly features: UIEventSource<{ feature: any; freshness: Date }[]>;
|
||||
|
||||
|
||||
constructor(layers: { layerDef: LayerConfig }[], upstream: FeatureSource) {
|
||||
let noPassthroughts = true;
|
||||
for (const layer of layers) {
|
||||
if (layer.layerDef.passAllFeatures) {
|
||||
noPassthroughts = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.features = upstream.features.map(features => {
|
||||
const newFeatures: { feature: any, freshness: Date }[] = [];
|
||||
if(features === undefined){
|
||||
return newFeatures;
|
||||
}
|
||||
|
||||
|
||||
for (const f of features) {
|
||||
if (f.feature._matching_layer_id) {
|
||||
// Already matched previously
|
||||
// We simply add it
|
||||
newFeatures.push(f);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const layer of layers) {
|
||||
if (layer.layerDef.overpassTags.matchesProperties(f.feature.properties)) {
|
||||
if (layer.layerDef.passAllFeatures) {
|
||||
|
||||
// We copy the feature; the "properties" field is kept identical though!
|
||||
// Keeping "properties" identical is needed, as it might break the 'allElementStorage' otherwise
|
||||
const newFeature = {
|
||||
geometry: f.feature.geometry,
|
||||
id: f.feature.id,
|
||||
type: f.feature.type,
|
||||
properties: f.feature.properties,
|
||||
_matching_layer_id : layer.layerDef.id
|
||||
}
|
||||
newFeatures.push({feature: newFeature, freshness: f.freshness});
|
||||
} else {
|
||||
// If not 'passAllFeatures', we are done
|
||||
f.feature._matching_layer_id = layer.layerDef.id;
|
||||
newFeatures.push(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newFeatures;
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -18,7 +18,7 @@ export default class FeatureSourceMerger implements FeatureSource {
|
|||
let all = {}; // Mapping 'id' -> {feature, freshness}
|
||||
for (const source of this._sources) {
|
||||
for (const f of source.features.data) {
|
||||
const id = f.feature.properties.id+f.feature.geometry.type;
|
||||
const id = f.feature.properties.id+f.feature.geometry.type+f.feature._matching_layer_id;
|
||||
const oldV = all[id];
|
||||
if(oldV === undefined){
|
||||
all[id] = f;
|
||||
|
|
|
@ -14,14 +14,13 @@ export default class FilteringFeatureSource implements FeatureSource {
|
|||
upstream: FeatureSource) {
|
||||
|
||||
const layerDict = {};
|
||||
|
||||
|
||||
const self = this;
|
||||
|
||||
|
||||
function update() {
|
||||
console.log("UPdating...")
|
||||
const features: { feature: any, freshness: Date }[] = upstream.features.data;
|
||||
const newFeatures = features.filter(f => {
|
||||
const layerId = f.feature.properties._matching_layer_id;
|
||||
const layerId = f.feature._matching_layer_id;
|
||||
if (layerId === undefined) {
|
||||
console.error(f)
|
||||
throw "feature._matching_layer_id is undefined"
|
||||
|
@ -37,16 +36,22 @@ export default class FilteringFeatureSource implements FeatureSource {
|
|||
});
|
||||
self.features.setData(newFeatures);
|
||||
}
|
||||
|
||||
for (const layer of layers) {
|
||||
layerDict[layer.layerDef.id] = layer;
|
||||
layer.isDisplayed.addCallback(update)
|
||||
layer.isDisplayed.addCallback(() => {
|
||||
console.log("Updating due to layer change")
|
||||
update()})
|
||||
}
|
||||
upstream.features.addCallback(update);
|
||||
location.map(l => l.zoom).addCallback(update);
|
||||
upstream.features.addCallback(() => {
|
||||
console.log("Updating due to upstream change")
|
||||
update()});
|
||||
location.map(l => l.zoom).addCallback(() => {
|
||||
console.log("UPdating due to zoom level change")
|
||||
update();});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ export default class NoOverlapSource {
|
|||
partitions[layerId] = []
|
||||
}
|
||||
for (const feature of features) {
|
||||
partitions[feature.feature.properties._matching_layer_id].push(feature);
|
||||
partitions[feature.feature._matching_layer_id].push(feature);
|
||||
}
|
||||
|
||||
// With this partitioning in hand, we run over every layer and remove every underlying feature if needed
|
||||
|
|
|
@ -32,7 +32,7 @@ export default class WayHandlingApplyingFeatureSource implements FeatureSource {
|
|||
const newFeatures: { feature: any, freshness: Date }[] = [];
|
||||
for (const f of features) {
|
||||
const feat = f.feature;
|
||||
const layerId = feat.properties._matching_layer_id;
|
||||
const layerId = feat._matching_layer_id;
|
||||
const layer: LayerConfig = layerDict[layerId].layerDef;
|
||||
if (layer === undefined) {
|
||||
throw "No layer found with id " + layerId;
|
||||
|
@ -50,6 +50,7 @@ export default class WayHandlingApplyingFeatureSource implements FeatureSource {
|
|||
}
|
||||
|
||||
const centerPoint = GeoOperations.centerpoint(feat);
|
||||
centerPoint._matching_layer_id = feat._matching_layer_id;
|
||||
newFeatures.push({feature: centerPoint, freshness: f.freshness});
|
||||
|
||||
if(layer.wayHandling === LayerConfig.WAYHANDLING_CENTER_AND_WAY){
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue