forked from MapComplete/MapComplete
First working version of split road functionality
This commit is contained in:
parent
61f2ebf9ba
commit
248ea78b17
11 changed files with 88 additions and 66 deletions
|
@ -34,7 +34,6 @@ export default class ChangeApplicator implements FeatureSource {
|
||||||
runningUpdate = true;
|
runningUpdate = true;
|
||||||
changes = changes.filter(ch => !seenChanges.has(ch))
|
changes = changes.filter(ch => !seenChanges.has(ch))
|
||||||
changes.forEach(c => seenChanges.add(c))
|
changes.forEach(c => seenChanges.add(c))
|
||||||
console.log("Called back", changes)
|
|
||||||
ChangeApplicator.ApplyChanges(self.features.data, changes, mode)
|
ChangeApplicator.ApplyChanges(self.features.data, changes, mode)
|
||||||
source.features.ping()
|
source.features.ping()
|
||||||
runningUpdate = false;
|
runningUpdate = false;
|
||||||
|
@ -67,6 +66,7 @@ export default class ChangeApplicator implements FeatureSource {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
|
||||||
function add(feature) {
|
function add(feature) {
|
||||||
|
feature.id = feature.properties.id
|
||||||
features.push({
|
features.push({
|
||||||
feature: feature,
|
feature: feature,
|
||||||
freshness: now
|
freshness: now
|
||||||
|
@ -135,9 +135,7 @@ export default class ChangeApplicator implements FeatureSource {
|
||||||
for (const change of changesPerId.get(id)) {
|
for (const change of changesPerId.get(id)) {
|
||||||
for (const kv of change.tags ?? []) {
|
for (const kv of change.tags ?? []) {
|
||||||
// Apply tag changes and ping the consumers
|
// Apply tag changes and ping the consumers
|
||||||
const k = kv.k
|
f.properties[kv.k] = kv.v;
|
||||||
let v = kv.v
|
|
||||||
f.properties[k] = v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply other changes to the object
|
// Apply other changes to the object
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class FeaturePipeline implements FeatureSource {
|
||||||
new FeatureDuplicatorPerLayer(flayers,
|
new FeatureDuplicatorPerLayer(flayers,
|
||||||
new RegisteringFeatureSource(
|
new RegisteringFeatureSource(
|
||||||
new ChangeApplicator(
|
new ChangeApplicator(
|
||||||
updater, changes, {generateNewGeometries: true}
|
updater, changes
|
||||||
))
|
))
|
||||||
)), layout));
|
)), layout));
|
||||||
|
|
||||||
|
@ -65,7 +65,12 @@ export default class FeaturePipeline implements FeatureSource {
|
||||||
const amendedOsmApiSource = new RememberingSource(
|
const amendedOsmApiSource = new RememberingSource(
|
||||||
new MetaTaggingFeatureSource(allLoadedFeatures,
|
new MetaTaggingFeatureSource(allLoadedFeatures,
|
||||||
new FeatureDuplicatorPerLayer(flayers,
|
new FeatureDuplicatorPerLayer(flayers,
|
||||||
new RegisteringFeatureSource(new ChangeApplicator(fromOsmApi, changes)))));
|
new RegisteringFeatureSource(new ChangeApplicator(fromOsmApi, changes,
|
||||||
|
{
|
||||||
|
// We lump in the new points here
|
||||||
|
generateNewGeometries: true
|
||||||
|
}
|
||||||
|
)))));
|
||||||
|
|
||||||
const merged =
|
const merged =
|
||||||
new FeatureSourceMerger([
|
new FeatureSourceMerger([
|
||||||
|
|
|
@ -76,7 +76,6 @@ export default class FilteringFeatureSource implements FeatureSource {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
});
|
});
|
||||||
console.log("Filtering layer source: input: ", upstream.features.data?.length, "output:", newFeatures.length)
|
|
||||||
self.features.setData(newFeatures);
|
self.features.setData(newFeatures);
|
||||||
if (missingLayers.size > 0) {
|
if (missingLayers.size > 0) {
|
||||||
console.error("Some layers were not found: ", Array.from(missingLayers))
|
console.error("Some layers were not found: ", Array.from(missingLayers))
|
||||||
|
|
|
@ -95,7 +95,7 @@ export default class SplitAction extends OsmChangeAction {
|
||||||
changeDescription.push({
|
changeDescription.push({
|
||||||
type: "node",
|
type: "node",
|
||||||
id: element.originalIndex,
|
id: element.originalIndex,
|
||||||
changes:{
|
changes: {
|
||||||
lon: element.lngLat[0],
|
lon: element.lngLat[0],
|
||||||
lat: element.lngLat[1]
|
lat: element.lngLat[1]
|
||||||
}
|
}
|
||||||
|
@ -110,9 +110,9 @@ export default class SplitAction extends OsmChangeAction {
|
||||||
if (isOriginal) {
|
if (isOriginal) {
|
||||||
// We change the actual element!
|
// We change the actual element!
|
||||||
changeDescription.push({
|
changeDescription.push({
|
||||||
type:"way",
|
type: "way",
|
||||||
id: originalElement.id,
|
id: originalElement.id,
|
||||||
changes:{
|
changes: {
|
||||||
locations: wayPart.map(p => p.lngLat),
|
locations: wayPart.map(p => p.lngLat),
|
||||||
nodes: wayPart.map(p => p.originalIndex)
|
nodes: wayPart.map(p => p.originalIndex)
|
||||||
}
|
}
|
||||||
|
@ -123,16 +123,19 @@ export default class SplitAction extends OsmChangeAction {
|
||||||
|
|
||||||
const kv = []
|
const kv = []
|
||||||
for (const k in originalElement.tags) {
|
for (const k in originalElement.tags) {
|
||||||
if(!originalElement.tags.hasOwnProperty(k)){
|
if (!originalElement.tags.hasOwnProperty(k)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
kv .push({k: k, v: originalElement.tags[k]})
|
if (k.startsWith("_") || k === "id") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
kv.push({k: k, v: originalElement.tags[k]})
|
||||||
}
|
}
|
||||||
changeDescription.push({
|
changeDescription.push({
|
||||||
type:"way",
|
type: "way",
|
||||||
id:id,
|
id: id,
|
||||||
tags: kv,
|
tags: kv,
|
||||||
changes:{
|
changes: {
|
||||||
locations: wayPart.map(p => p.lngLat),
|
locations: wayPart.map(p => p.lngLat),
|
||||||
nodes: wayPart.map(p => p.originalIndex)
|
nodes: wayPart.map(p => p.originalIndex)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,19 @@ export class Tag extends TagsFilter {
|
||||||
|
|
||||||
matchesProperties(properties: any): boolean {
|
matchesProperties(properties: any): boolean {
|
||||||
for (const propertiesKey in properties) {
|
for (const propertiesKey in properties) {
|
||||||
|
if(!properties.hasOwnProperty(propertiesKey)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
if (this.key === propertiesKey) {
|
if (this.key === propertiesKey) {
|
||||||
const value = properties[propertiesKey];
|
const value = properties[propertiesKey];
|
||||||
|
if(value === undefined){
|
||||||
|
continue
|
||||||
|
}
|
||||||
return value === this.value;
|
return value === this.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The tag was not found
|
// The tag was not found
|
||||||
|
|
||||||
if (this.value === "") {
|
if (this.value === "") {
|
||||||
// and it shouldn't be found!
|
// and it shouldn't be found!
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Utils } from "../Utils";
|
||||||
|
|
||||||
export default class Constants {
|
export default class Constants {
|
||||||
|
|
||||||
public static vNumber = "0.8.4-rc3";
|
public static vNumber = "0.8.5";
|
||||||
|
|
||||||
// The user journey states thresholds when a new feature gets unlocked
|
// The user journey states thresholds when a new feature gets unlocked
|
||||||
public static userJourney = {
|
public static userJourney = {
|
||||||
|
|
|
@ -76,7 +76,12 @@ export default class SimpleAddUI extends Toggle {
|
||||||
State.state.changes.applyAction(newElementAction)
|
State.state.changes.applyAction(newElementAction)
|
||||||
selectedPreset.setData(undefined)
|
selectedPreset.setData(undefined)
|
||||||
isShown.setData(false)
|
isShown.setData(false)
|
||||||
Hash.hash.setData(newElementAction.newElementId)
|
State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get(
|
||||||
|
newElementAction.newElementId
|
||||||
|
))
|
||||||
|
console.log("Did set selected element to",State.state.allElements.ContainingFeatures.get(
|
||||||
|
newElementAction.newElementId
|
||||||
|
))
|
||||||
}, () => {
|
}, () => {
|
||||||
selectedPreset.setData(undefined)
|
selectedPreset.setData(undefined)
|
||||||
})
|
})
|
||||||
|
|
|
@ -42,7 +42,6 @@ export default class LocationInput extends InputElement<Loc> {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
map.leafletMap.addCallbackAndRunD(leaflet => {
|
map.leafletMap.addCallbackAndRunD(leaflet => {
|
||||||
console.log(leaflet.getBounds(), leaflet.getBounds().pad(0.15))
|
|
||||||
leaflet.setMaxBounds(
|
leaflet.setMaxBounds(
|
||||||
leaflet.getBounds().pad(0.15)
|
leaflet.getBounds().pad(0.15)
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default class ShowDataLayer {
|
||||||
layoutToUse: UIEventSource<LayoutConfig>,
|
layoutToUse: UIEventSource<LayoutConfig>,
|
||||||
enablePopups = true,
|
enablePopups = true,
|
||||||
zoomToFeatures = false,
|
zoomToFeatures = false,
|
||||||
name?:string) {
|
name?: string) {
|
||||||
this._leafletMap = leafletMap;
|
this._leafletMap = leafletMap;
|
||||||
this._enablePopups = enablePopups;
|
this._enablePopups = enablePopups;
|
||||||
this._features = features;
|
this._features = features;
|
||||||
|
@ -130,6 +130,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) {
|
||||||
|
@ -185,11 +186,13 @@ export default class ShowDataLayer {
|
||||||
if (selected.properties.id === feature.properties.id) {
|
if (selected.properties.id === feature.properties.id) {
|
||||||
// A small sanity check to prevent infinite loops:
|
// A small sanity check to prevent infinite loops:
|
||||||
if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again
|
if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again
|
||||||
|
|
||||||
&& feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too
|
&& feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too
|
||||||
) {
|
) {
|
||||||
leafletLayer.openPopup()
|
leafletLayer.openPopup()
|
||||||
}
|
}
|
||||||
|
if(feature.id !== feature.properties.id){
|
||||||
|
console.log("Not opening the popup for", feature)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -55,9 +55,12 @@ export default class SpecialVisualizations {
|
||||||
if (!tags.hasOwnProperty(key)) {
|
if (!tags.hasOwnProperty(key)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
parts.push(key + "=" + tags[key]);
|
parts.push([key , tags[key] ?? "<b>undefined</b>" ]);
|
||||||
}
|
}
|
||||||
return parts.join("<br/>")
|
return new Table(
|
||||||
|
["key","value"],
|
||||||
|
parts
|
||||||
|
)
|
||||||
})).SetStyle("border: 1px solid black; border-radius: 1em;padding:1em;display:block;")
|
})).SetStyle("border: 1px solid black; border-radius: 1em;padding:1em;display:block;")
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"increase-memory": "export NODE_OPTIONS=--max_old_space_size=4096",
|
"increase-memory": "export NODE_OPTIONS=--max_old_space_size=4096",
|
||||||
"start": "ts-node scripts/generateLayerOverview.ts --no-fail && npm run increase-memory && parcel *.html UI/** Logic/** assets/*.json assets/generated/* assets/layers/*/*.svg assets/tagRendering/*.json assets/themes/*/*.svg assets/themes/*/*.png vendor/* vendor/*/*",
|
"start": "ts-node scripts/generateLayerOverview.ts --no-fail && npm run increase-memory && parcel *.html UI/** Logic/** assets/*.json assets/svg/* assets/generated/* assets/layers/*/*.svg assets/tagRendering/*.json assets/themes/*/*.svg assets/themes/*/*.png vendor/* vendor/*/*",
|
||||||
"test": "ts-node test/TestAll.ts",
|
"test": "ts-node test/TestAll.ts",
|
||||||
"init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean",
|
"init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean",
|
||||||
"add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote update weblate-layers",
|
"add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote update weblate-layers",
|
||||||
|
|
Loading…
Reference in a new issue