forked from MapComplete/MapComplete
More fancyness, less bugs
This commit is contained in:
parent
16612b10ef
commit
2177db376c
27 changed files with 821 additions and 607 deletions
|
@ -129,88 +129,65 @@ export class FilteredLayer {
|
|||
|
||||
let self = this;
|
||||
this._geolayer = L.geoJSON(data, {
|
||||
style: feature =>
|
||||
self.layerDef.GenerateLeafletStyle(feature.properties),
|
||||
pointToLayer: function (feature, latLng) {
|
||||
// Point to layer converts the 'point' to a layer object - as the geojson layer natively cannot handle points
|
||||
// Click handling is done in the next step
|
||||
style: feature =>
|
||||
self.layerDef.GenerateLeafletStyle(feature.properties, self._showOnPopup !== undefined),
|
||||
pointToLayer: function (feature, latLng) {
|
||||
// Point to layer converts the 'point' to a layer object - as the geojson layer natively cannot handle points
|
||||
// Click handling is done in the next step
|
||||
|
||||
const style = self.layerDef.GenerateLeafletStyle(feature.properties);
|
||||
let marker;
|
||||
if (style.icon === undefined) {
|
||||
marker = L.circle(latLng, {
|
||||
radius: 25,
|
||||
color: style.color
|
||||
});
|
||||
} else if (style.icon.iconUrl.startsWith("$circle")) {
|
||||
marker = L.circle(latLng, {
|
||||
radius: 25,
|
||||
color: style.color
|
||||
});
|
||||
} else {
|
||||
marker = L.marker(latLng, {
|
||||
icon: L.divIcon(style.icon)
|
||||
});
|
||||
}
|
||||
return marker;
|
||||
},
|
||||
onEachFeature: function (feature, layer: Layer) {
|
||||
|
||||
if (self._showOnPopup === undefined) {
|
||||
// No popup contents defined -> don't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
function openPopup(latlng: any) {
|
||||
if (layer.getPopup() === undefined
|
||||
&& (window.screen.availHeight > 600 || window.screen.availWidth > 600) // We DON'T trigger this code on small screens! No need to create a popup
|
||||
) {
|
||||
const popup = L.popup({
|
||||
autoPan: true,
|
||||
closeOnEscapeKey: true,
|
||||
}, layer);
|
||||
|
||||
popup.setLatLng(latlng)
|
||||
|
||||
layer.bindPopup(popup);
|
||||
const eventSource = State.state.allElements.addOrGetElement(feature);
|
||||
const uiElement = self._showOnPopup(eventSource, feature);
|
||||
// We first render the UIelement (which'll still need an update later on...)
|
||||
// But at least it'll be visible already
|
||||
popup.setContent(uiElement.Render());
|
||||
popup.openOn(State.state.bm.map);
|
||||
// popup.openOn(State.state.bm.map);
|
||||
// ANd we perform the pending update
|
||||
uiElement.Update();
|
||||
// @ts-ignore
|
||||
popup.Update = () => {
|
||||
uiElement.Update();
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
layer.getPopup().Update();
|
||||
}
|
||||
|
||||
|
||||
// We set the element as selected...
|
||||
State.state.selectedElement.setData(feature);
|
||||
|
||||
}
|
||||
|
||||
layer.on("click", (e) => {
|
||||
// @ts-ignore
|
||||
openPopup(e.latlng);
|
||||
// We mark the event as consumed
|
||||
L.DomEvent.stop(e);
|
||||
const style = self.layerDef.GenerateLeafletStyle(feature.properties, self._showOnPopup !== undefined);
|
||||
let marker;
|
||||
if (style.icon === undefined) {
|
||||
marker = L.circle(latLng, {
|
||||
radius: 25,
|
||||
color: style.color
|
||||
});
|
||||
} else if (style.icon.iconUrl.startsWith("$circle")) {
|
||||
marker = L.circle(latLng, {
|
||||
radius: 25,
|
||||
color: style.color
|
||||
});
|
||||
} else {
|
||||
marker = L.marker(latLng, {
|
||||
icon: L.divIcon(style.icon)
|
||||
});
|
||||
|
||||
if (feature.properties.id.replace(/\//g, "_") === Hash.Get().data) {
|
||||
const center = GeoOperations.centerpoint(feature).geometry.coordinates;
|
||||
openPopup({lat: center[1], lng: center[0]})
|
||||
}
|
||||
|
||||
}
|
||||
return marker;
|
||||
},
|
||||
onEachFeature: function (feature, layer: Layer) {
|
||||
|
||||
if (self._showOnPopup === undefined) {
|
||||
// No popup contents defined -> don't do anything
|
||||
return;
|
||||
}
|
||||
const popup = L.popup({
|
||||
autoPan: true,
|
||||
closeOnEscapeKey: true,
|
||||
}, layer);
|
||||
|
||||
let uiElement: UIElement;
|
||||
|
||||
const eventSource = State.state.allElements.addOrGetElement(feature);
|
||||
uiElement = self._showOnPopup(eventSource, feature);
|
||||
popup.setContent(uiElement.Render());
|
||||
layer.bindPopup(popup);
|
||||
// We first render the UIelement (which'll still need an update later on...)
|
||||
// But at least it'll be visible already
|
||||
|
||||
|
||||
layer.on("click", (e) => {
|
||||
// We set the element as selected...
|
||||
State.state.selectedElement.setData(feature);
|
||||
uiElement.Update();
|
||||
});
|
||||
|
||||
if (feature.properties.id.replace(/\//g, "_") === Hash.Get().data) {
|
||||
const center = GeoOperations.centerpoint(feature).geometry.coordinates;
|
||||
popup.setLatLng({lat: center[1], lng: center[0]});
|
||||
popup.openOn(State.state.bm.map)
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
if (this.combinedIsDisplayed.data) {
|
||||
|
|
|
@ -82,7 +82,7 @@ export default class MetaTagging {
|
|||
})
|
||||
)
|
||||
private static isOpen = new SimpleMetaTagger(
|
||||
["_isOpen", "_isOpen:description"], "If 'opening_hours' is present, it will add the current state of the feature (being 'yes' or 'no",
|
||||
["_isOpen", "_isOpen:description"], "If 'opening_hours' is present, it will add the current state of the feature (being 'yes' or 'no')",
|
||||
(feature => {
|
||||
const tagsSource = State.state.allElements.addOrGetElement(feature);
|
||||
tagsSource.addCallback(tags => {
|
||||
|
@ -123,16 +123,40 @@ export default class MetaTagging {
|
|||
})
|
||||
)
|
||||
|
||||
public static carriageWayWidth = new SimpleMetaTagger(
|
||||
["_width:needed","_width:needed:no_pedestrians", "_width:difference"],
|
||||
private static directionSimplified = new SimpleMetaTagger(
|
||||
["_direction:simplified", "_direction:leftright"], "_direction:simplified turns 'camera:direction' and 'direction' into either 0, 45, 90, 135, 180, 225, 270 or 315, whichever is closest. _direction:leftright is either 'left' or 'right', which is left-looking on the map or 'right-looking' on the map",
|
||||
(feature => {
|
||||
const tags = feature.properties;
|
||||
const direction = tags["camera:direction"] ?? tags["direction"];
|
||||
if (direction === undefined) {
|
||||
return;
|
||||
}
|
||||
let n = Number(direction);
|
||||
if (isNaN(n)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// [22.5 -> 67.5] is sector 1
|
||||
// [67.5 -> ] is sector 1
|
||||
n = (n + 22.5) % 360;
|
||||
n = Math.floor(n / 45);
|
||||
tags["_direction:simplified"] = n;
|
||||
tags["_direction:leftright"] = n <= 3 ? "right" : "left";
|
||||
|
||||
|
||||
})
|
||||
)
|
||||
|
||||
private static carriageWayWidth = new SimpleMetaTagger(
|
||||
["_width:needed", "_width:needed:no_pedestrians", "_width:difference"],
|
||||
"Legacy for a specific project calculating the needed width for safe traffic on a road. Only activated if 'width:carriageway' is present",
|
||||
(feature: any, index: number) => {
|
||||
|
||||
const properties = feature.properties;
|
||||
if(properties["width:carriageway"] === undefined){
|
||||
if (properties["width:carriageway"] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const carWidth = 2;
|
||||
const cyclistWidth = 1.5;
|
||||
const pedestrianWidth = 0.75;
|
||||
|
@ -239,7 +263,8 @@ export default class MetaTagging {
|
|||
MetaTagging.surfaceArea,
|
||||
MetaTagging.country,
|
||||
MetaTagging.isOpen,
|
||||
MetaTagging.carriageWayWidth
|
||||
MetaTagging.carriageWayWidth,
|
||||
MetaTagging.directionSimplified
|
||||
|
||||
];
|
||||
|
||||
|
|
|
@ -136,6 +136,7 @@ export class UpdateFromOverpass {
|
|||
const self = this;
|
||||
window?.setTimeout(
|
||||
function () {
|
||||
self.runningQuery.setData(false)
|
||||
self.update(state)
|
||||
}, this.retries.data * 5000
|
||||
)
|
||||
|
|
|
@ -56,8 +56,8 @@ export class Imgur {
|
|||
},
|
||||
};
|
||||
$.ajax(settings).done(function (response) {
|
||||
const descr : string= response.data.description;
|
||||
const data : any = {};
|
||||
const descr: string = response.data.description ?? "";
|
||||
const data: any = {};
|
||||
for (const tag of descr.split("\n")) {
|
||||
const kv = tag.split(":");
|
||||
const k = kv[0];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue