Merge branch 'feature/levels' into develop

This commit is contained in:
pietervdvn 2022-07-25 16:56:03 +02:00
commit 64d0aac88f
20 changed files with 976 additions and 522 deletions

View file

@ -1,10 +1,9 @@
import {UIEventSource} from "../../UIEventSource";
import FilteredLayer from "../../../Models/FilteredLayer";
import {Store, UIEventSource} from "../../UIEventSource";
import FilteredLayer, {FilterState} from "../../../Models/FilteredLayer";
import {FeatureSourceForLayer, Tiled} from "../FeatureSource";
import {BBox} from "../../BBox";
import {ElementStorage} from "../../ElementStorage";
import {TagsFilter} from "../../Tags/TagsFilter";
import {tag} from "@turf/turf";
import {OsmFeature} from "../../../Models/OsmFeature";
export default class FilteringFeatureSource implements FeatureSourceForLayer, Tiled {
@ -16,7 +15,9 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
public readonly bbox: BBox
private readonly upstream: FeatureSourceForLayer;
private readonly state: {
locationControl: UIEventSource<{ zoom: number }>; selectedElement: UIEventSource<any>,
locationControl: Store<{ zoom: number }>;
selectedElement: Store<any>,
globalFilters: Store<{ filter: FilterState }[]>,
allElements: ElementStorage
};
private readonly _alreadyRegistered = new Set<UIEventSource<any>>();
@ -25,9 +26,10 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
constructor(
state: {
locationControl: UIEventSource<{ zoom: number }>,
selectedElement: UIEventSource<any>,
allElements: ElementStorage
locationControl: Store<{ zoom: number }>,
selectedElement: Store<any>,
allElements: ElementStorage,
globalFilters: Store<{ filter: FilterState }[]>
},
tileIndex,
upstream: FeatureSourceForLayer,
@ -61,6 +63,10 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
self._is_dirty.setData(true)
})
state.globalFilters.addCallback(_ => {
self.update()
})
this.update();
}
@ -69,6 +75,7 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
const layer = this.upstream.layer;
const features: { feature: OsmFeature; freshness: Date }[] = (this.upstream.features.data ?? []);
const includedFeatureIds = new Set<string>();
const globalFilters = self.state.globalFilters.data.map(f => f.filter);
const newFeatures = (features ?? []).filter((f) => {
self.registerCallback(f.feature)
@ -88,6 +95,14 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
}
}
for (const filter of globalFilters) {
const neededTags: TagsFilter = filter?.currentFilter
if (neededTags !== undefined && !neededTags.matchesProperties(f.feature.properties)) {
// Hidden by the filter on the layer itself - we want to hide it no matter what
return false;
}
}
includedFeatureIds.add(f.feature.properties.id)
return true;
});

View file

@ -72,7 +72,7 @@ export default class CreateNewNodeAction extends OsmCreateAction {
this.setElementId(id)
for (const kv of this._basicTags) {
if (typeof kv.value !== "string") {
throw "Invalid value: don't use a regex in a preset"
throw "Invalid value: don't use non-string value in a preset. The tag "+kv.key+"="+kv.value+" is not a string, the value is a "+typeof kv.value
}
properties[kv.key] = kv.value;
}

View file

@ -8,6 +8,7 @@ import {FixedUiElement} from "../UI/Base/FixedUiElement";
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
import {CountryCoder} from "latlon2country"
import Constants from "../Models/Constants";
import {TagUtils} from "./Tags/TagUtils";
export class SimpleMetaTagger {
@ -32,7 +33,7 @@ export class SimpleMetaTagger {
if (!docs.cleanupRetagger) {
for (const key of docs.keys) {
if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) {
throw `Incorrect metakey ${key}: it should start with underscore (_)`
throw `Incorrect key for a calculated meta value '${key}': it should start with underscore (_)`
}
}
}
@ -211,6 +212,27 @@ export default class SimpleMetaTaggers {
return true;
})
);
private static levels = new SimpleMetaTagger(
{
doc: "Extract the 'level'-tag into a normalized, ';'-separated value",
keys: ["_level"]
},
((feature) => {
if (feature.properties["level"] === undefined) {
return false;
}
const l = feature.properties["level"]
const newValue = TagUtils.LevelsParser(l).join(";")
if(l === newValue) {
return false;
}
feature.properties["level"] = newValue
return true
})
)
private static canonicalize = new SimpleMetaTagger(
{
doc: "If 'units' is defined in the layoutConfig, then this metatagger will rewrite the specified keys to have the canonical form (e.g. `1meter` will be rewritten to `1m`)",
@ -327,13 +349,13 @@ export default class SimpleMetaTaggers {
delete tags._isOpen
tags["_isOpen"] = "parse_error";
}
}});
}
});
const tagsSource = state.allElements.getEventSourceById(feature.properties.id);
})
)
private static directionSimplified = new SimpleMetaTagger(
@ -400,7 +422,8 @@ export default class SimpleMetaTaggers {
SimpleMetaTaggers.currentTime,
SimpleMetaTaggers.objectMetaInfo,
SimpleMetaTaggers.noBothButLeftRight,
SimpleMetaTaggers.geometryType
SimpleMetaTaggers.geometryType,
SimpleMetaTaggers.levels
];
public static readonly lazyTags: string[] = [].concat(...SimpleMetaTaggers.metatags.filter(tagger => tagger.isLazy)

View file

@ -19,6 +19,19 @@ import TitleHandler from "../Actors/TitleHandler";
import {BBox} from "../BBox";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import {TiledStaticFeatureSource} from "../FeatureSource/Sources/StaticFeatureSource";
import {Translation, TypedTranslation} from "../../UI/i18n/Translation";
import {Tag} from "../Tags/Tag";
export interface GlobalFilter {
filter: FilterState,
id: string,
onNewPoint: {
safetyCheck: Translation,
confirmAddNew: TypedTranslation<{ preset: Translation }>
tags: Tag[]
}
}
/**
* Contains all the leaflet-map related state
@ -78,6 +91,12 @@ export default class MapState extends UserRelatedState {
* Which layers are enabled in the current theme and what filters are applied onto them
*/
public filteredLayers: UIEventSource<FilteredLayer[]> = new UIEventSource<FilteredLayer[]>([], "filteredLayers");
/**
* Filters which apply onto all layers
*/
public globalFilters: UIEventSource<GlobalFilter[]> = new UIEventSource([], "globalFilters")
/**
* Which overlays are shown
*/

View file

@ -493,6 +493,16 @@ export class TagUtils {
return " (" + joined + ") "
}
public static ExtractSimpleTags(tf: TagsFilter) : Tag[] {
const result: Tag[] = []
tf.visit(t => {
if(t instanceof Tag){
result.push(t)
}
})
return result;
}
/**
* Returns 'true' is opposite tags are detected.
* Note that this method will never work perfectly
@ -581,4 +591,38 @@ export class TagUtils {
return listToFilter.some(tf => guards.some(guard => guard.shadows(tf)))
}
/**
* Parses a level specifier to the various available levels
*
* TagUtils.LevelsParser("0") // => ["0"]
* TagUtils.LevelsParser("1") // => ["1"]
* TagUtils.LevelsParser("0;2") // => ["0","2"]
* TagUtils.LevelsParser("0-5") // => ["0","1","2","3","4","5"]
* TagUtils.LevelsParser("0") // => ["0"]
* TagUtils.LevelsParser("-1") // => ["-1"]
* TagUtils.LevelsParser("0;-1") // => ["0", "-1"]
*/
public static LevelsParser(level: string): string[] {
let spec = Utils.NoNull([level])
spec = [].concat(...spec.map(s => s?.split(";")))
spec = [].concat(...spec.map(s => {
s = s.trim()
if (s.indexOf("-") < 0 || s.startsWith("-")) {
return s
}
const [start, end] = s.split("-").map(s => Number(s.trim()))
if (isNaN(start) || isNaN(end)) {
return undefined
}
const values = []
for (let i = start; i <= end; i++) {
values.push(i + "")
}
return values
}))
return Utils.NoNull(spec);
}
}

View file

@ -70,11 +70,14 @@ export default abstract class BaseUIElement {
return this;
}
public RemoveClass(clss: string): BaseUIElement {
public RemoveClass(classes: string): BaseUIElement {
const all = classes.split(" ").map(clsName => clsName.trim());
for (let clss of all) {
if (this.clss.has(clss)) {
this.clss.delete(clss);
this._constructedHtmlElement?.classList.remove(clss)
}
}
return this;
}

View file

@ -3,11 +3,22 @@ import Toggle from "../Input/Toggle";
import MapControlButton from "../MapControlButton";
import GeoLocationHandler from "../../Logic/Actors/GeoLocationHandler";
import Svg from "../../Svg";
import MapState from "../../Logic/State/MapState";
import MapState, {GlobalFilter} from "../../Logic/State/MapState";
import LevelSelector from "../Input/LevelSelector";
import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline";
import {Utils} from "../../Utils";
import {TagUtils} from "../../Logic/Tags/TagUtils";
import {RegexTag} from "../../Logic/Tags/RegexTag";
import {Or} from "../../Logic/Tags/Or";
import {Tag} from "../../Logic/Tags/Tag";
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
import Translations from "../i18n/Translations";
import {BBox} from "../../Logic/BBox";
import {OsmFeature} from "../../Models/OsmFeature";
export default class RightControls extends Combine {
constructor(state: MapState) {
constructor(state: MapState & { featurePipeline: FeaturePipeline }) {
const geolocatioHandler = new GeoLocationHandler(
state
@ -38,7 +49,91 @@ export default class RightControls extends Combine {
state.locationControl.ping();
});
super([plus, min, geolocationButton].map(el => el.SetClass("m-0.5 md:m-1")))
const levelsInView = state.currentBounds.map(bbox => {
if (bbox === undefined) {
return []
}
const allElementsUnfiltered: OsmFeature[] = [].concat(... state.featurePipeline.GetAllFeaturesAndMetaWithin(bbox).map(ff => ff.features))
const allElements = allElementsUnfiltered.filter(f => BBox.get(f).overlapsWith(bbox))
const allLevelsRaw: string[] = allElements.map(f => f.properties["level"])
const allLevels = [].concat(...allLevelsRaw.map(l => TagUtils.LevelsParser(l)))
if (allLevels.indexOf("0") < 0) {
allLevels.push("0")
}
allLevels.sort((a, b) => a < b ? -1 : 1)
return Utils.Dedup(allLevels)
})
state.globalFilters.data.push({
filter: {
currentFilter: undefined,
state: undefined,
},
id: "level",
onNewPoint: undefined
})
const levelSelect = new LevelSelector(levelsInView)
const isShown = levelsInView.map(levelsInView => {
if (levelsInView.length == 0) {
return false;
}
if (state.locationControl.data.zoom <= 16) {
return false;
}
if (levelsInView.length == 1 && levelsInView[0] == "0") {
return false
}
return true;
},
[state.locationControl])
function setLevelFilter() {
console.log("Updating levels filter")
const filter: GlobalFilter = state.globalFilters.data.find(gf => gf.id === "level")
if (!isShown.data) {
filter.filter = {
state: "*",
currentFilter: undefined,
}
filter.onNewPoint = undefined
} else {
const l = levelSelect.GetValue().data
let neededLevel: TagsFilter = new RegexTag("level", new RegExp("(^|;)" + l + "(;|$)"));
if (l === "0") {
neededLevel = new Or([neededLevel, new Tag("level", "")])
}
filter.filter = {
state: l,
currentFilter: neededLevel
}
const t = Translations.t.general.levelSelection
filter.onNewPoint = {
confirmAddNew: t.confirmLevel.PartialSubs({level: l}),
safetyCheck: t.addNewOnLevel.Subs({level: l}),
tags: [new Tag("level", l)]
}
}
state.globalFilters.ping();
return;
}
isShown.addCallbackAndRun(shown => {
console.log("Is level selector shown?", shown)
setLevelFilter()
if (shown) {
levelSelect.RemoveClass("invisible")
} else {
levelSelect.SetClass("invisible")
}
})
levelSelect.GetValue().addCallback(_ => setLevelFilter())
super([new Combine([levelSelect]).SetClass(""), plus, min, geolocationButton].map(el => el.SetClass("m-0.5 md:m-1")))
this.SetClass("flex flex-col items-center")
}

View file

@ -25,6 +25,7 @@ import ConfirmLocationOfPoint from "../NewPoint/ConfirmLocationOfPoint";
import BaseLayer from "../../Models/BaseLayer";
import Loading from "../Base/Loading";
import Hash from "../../Logic/Web/Hash";
import {GlobalFilter} from "../../Logic/State/MapState";
/*
* The SimpleAddUI is a single panel, which can have multiple states:
@ -66,7 +67,8 @@ export default class SimpleAddUI extends Toggle {
locationControl: UIEventSource<Loc>,
filteredLayers: UIEventSource<FilteredLayer[]>,
featureSwitchFilter: UIEventSource<boolean>,
backgroundLayer: UIEventSource<BaseLayer>
backgroundLayer: UIEventSource<BaseLayer>,
globalFilters: UIEventSource<GlobalFilter[]>
},
takeLocationFrom?: UIEventSource<{lat: number, lon: number}>
) {

70
UI/Input/LevelSelector.ts Normal file
View file

@ -0,0 +1,70 @@
import {InputElement} from "./InputElement";
import {Store, Stores, UIEventSource} from "../../Logic/UIEventSource";
import Combine from "../Base/Combine";
import Slider from "./Slider";
import {ClickableToggle} from "./Toggle";
import {FixedUiElement} from "../Base/FixedUiElement";
import {VariableUiElement} from "../Base/VariableUIElement";
export default class LevelSelector extends VariableUiElement implements InputElement<string> {
private readonly _value: UIEventSource<string>;
constructor(currentLevels: Store<string[]>, options?: {
value?: UIEventSource<string>
}) {
const value = options?.value ?? new UIEventSource<string>(undefined)
super(Stores.ListStabilized(currentLevels).map(levels => {
console.log("CUrrent levels are", levels)
let slider = new Slider(0, levels.length - 1, {vertical: true});
const toggleClass = "flex border-2 border-blue-500 w-10 h-10 place-content-center items-center border-box"
slider.SetClass("flex elevator w-10").SetStyle(`height: ${2.5 * levels.length}rem; background: #00000000`)
const values = levels.map((data, i) => new ClickableToggle(
new FixedUiElement(data).SetClass("font-bold active bg-subtle " + toggleClass),
new FixedUiElement(data).SetClass("normal-background " + toggleClass),
slider.GetValue().sync(
(sliderVal) => {
return sliderVal === i
},
[],
(isSelected) => {
return isSelected ? i : slider.GetValue().data
}
))
.ToggleOnClick()
.SetClass("flex w-10 h-10"))
values.reverse(/* This is a new list, no side-effects */)
const combine = new Combine([new Combine(values), slider])
combine.SetClass("flex flex-row overflow-hidden");
slider.GetValue().addCallbackAndRun(i => {
if (currentLevels?.data === undefined) {
return
}
value.setData(currentLevels?.data[i]);
})
value.addCallback(level => {
const i = currentLevels?.data?.findIndex(l => l === level)
slider.GetValue().setData(i)
})
return combine
}))
this._value = value
}
GetValue(): UIEventSource<string> {
return this._value;
}
IsValid(t: string): boolean {
return false;
}
}

View file

@ -4,9 +4,10 @@ import {UIEventSource} from "../../Logic/UIEventSource";
export default class Slider extends InputElement<number> {
private readonly _value: UIEventSource<number>
private min: number;
private max: number;
private step: number;
private readonly min: number;
private readonly max: number;
private readonly step: number;
private readonly vertical: boolean;
/**
* Constructs a slider input element for natural numbers
@ -16,13 +17,15 @@ export default class Slider extends InputElement<number> {
*/
constructor(min: number, max: number, options?: {
value?: UIEventSource<number>,
step?: 1 | number
step?: 1 | number,
vertical?: false | boolean
}) {
super();
this.max = max;
this.min = min;
this._value = options?.value ?? new UIEventSource<number>(min)
this.step = options?.step ?? 1;
this.vertical = options?.vertical ?? false;
}
GetValue(): UIEventSource<number> {
@ -39,6 +42,10 @@ export default class Slider extends InputElement<number> {
el.oninput = () => {
valuestore.setData(Number(el.value))
}
if(this.vertical){
el.classList.add("vertical")
el.setAttribute('orient','vertical'); // firefox only workaround...
}
valuestore.addCallbackAndRunD(v => el.value = ""+valuestore.data)
return el;
}

View file

@ -15,12 +15,16 @@ import SimpleAddUI, {PresetInfo} from "../BigComponents/SimpleAddUI";
import BaseLayer from "../../Models/BaseLayer";
import Img from "../Base/Img";
import Title from "../Base/Title";
import {GlobalFilter} from "../../Logic/State/MapState";
import {VariableUiElement} from "../Base/VariableUIElement";
import {Tag} from "../../Logic/Tags/Tag";
export default class ConfirmLocationOfPoint extends Combine {
constructor(
state: {
globalFilters: UIEventSource<GlobalFilter[]>;
featureSwitchIsTesting: UIEventSource<boolean>;
osmConnection: OsmConnection,
featurePipeline: FeaturePipeline,
@ -106,7 +110,11 @@ export default class ConfirmLocationOfPoint extends Combine {
).SetClass("font-bold break-words")
.onClick(() => {
console.log("The confirmLocationPanel - precise input yielded ", preciseInput?.GetValue()?.data)
confirm(preset.tags, preciseInput?.GetValue()?.data ?? loc, preciseInput?.snappedOnto?.data?.properties?.id);
const globalFilterTagsToAdd: Tag[][] = state.globalFilters.data.filter(gf => gf.onNewPoint !== undefined)
.map(gf => gf.onNewPoint.tags)
const globalTags : Tag[] = [].concat(...globalFilterTagsToAdd)
console.log("Global tags to add are: ", globalTags)
confirm([...preset.tags, ...globalTags], preciseInput?.GetValue()?.data ?? loc, preciseInput?.snappedOnto?.data?.properties?.id);
});
if (preciseInput !== undefined) {
@ -126,7 +134,7 @@ export default class ConfirmLocationOfPoint extends Combine {
.onClick(() => filterViewIsOpened.setData(true))
const openLayerOrConfirm = new Toggle(
let openLayerOrConfirm = new Toggle(
confirmButton,
openLayerControl,
preset.layerToAddTo.isDisplayed
@ -152,6 +160,29 @@ export default class ConfirmLocationOfPoint extends Combine {
closePopup()
})
// We assume the number of global filters won't change during the run of the program
for (let i = 0; i < state.globalFilters.data.length; i++) {
const hasBeenCheckedOf = new UIEventSource(false);
const filterConfirmPanel = new VariableUiElement(
state.globalFilters.map(gfs => {
const gf = gfs[i]
const confirm = gf.onNewPoint?.confirmAddNew?.Subs({preset: preset.title})
return new Combine([
gf.onNewPoint?.safetyCheck,
new SubtleButton(Svg.confirm_svg(), confirm).onClick(() => hasBeenCheckedOf.setData(true))
])
}
))
openLayerOrConfirm = new Toggle(
openLayerOrConfirm, filterConfirmPanel,
state.globalFilters.map(f => hasBeenCheckedOf.data || f[i]?.onNewPoint === undefined, [hasBeenCheckedOf])
)
}
const hasActiveFilter = preset.layerToAddTo.appliedFilters
.map(appliedFilters => {
const activeFilters = Array.from(appliedFilters.values()).filter(f => f?.currentFilter !== undefined);

View file

@ -319,4 +319,17 @@ export class TypedTranslation<T> extends Translation {
}
PartialSubs<X extends string>(text: Partial<T> & Record<X, string>): TypedTranslation<Omit<T, X>> {
const newTranslations : Record<string, string> = {}
for (const lang in this.translations) {
const template = this.translations[lang]
if(lang === "_context"){
newTranslations[lang] = template
continue
}
newTranslations[lang] = Utils.SubstituteKeys(template, text, lang)
}
return new TypedTranslation<Omit<T, X>>(newTranslations, this.context)
}
}

78
assets/svg/elevator.svg Normal file
View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
id="图层_1"
x="0px"
y="0px"
viewBox="0 0 65.9 66"
style="enable-background:new 0 0 65.9 66;"
xml:space="preserve"
sodipodi:docname="elevator.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs33">
</defs><sodipodi:namedview
id="namedview31"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
showgrid="false"
inkscape:zoom="61.063924"
inkscape:cx="32.105699"
inkscape:cy="40.138265"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="图层_1" />
<path
d="M 48.2,15.6 H 19.3 c -1.6,0 -2.8,1.3 -2.8,2.8 v 29 c 0,1.6 1.3,2.8 2.8,2.8 h 28.9 c 1.6,0 2.8,-1.3 2.8,-2.8 V 18.5 C 51,17 49.7,15.6 48.2,15.6 Z m 0.3,30.7 c 0,0.8 -0.6,1.4 -1.4,1.4 H 20.4 C 19.6,47.7 19,47.1 19,46.3 V 19.6 c 0,-0.8 0.6,-1.4 1.4,-1.4 h 26.7 c 0.8,0 1.4,0.6 1.4,1.4 z"
id="path2" /><polygon
points="29.4,9.5 33.7,5.5 38.1,9.5 35.3,9.5 35.3,13.5 32.2,13.5 32.2,9.5 "
id="polygon8" /><polygon
points="38.1,56.6 33.7,60.5 29.4,56.6 32.2,56.6 32.2,52.5 35.3,52.5 35.3,56.6 "
id="polygon10" /><circle
cx="28.6"
cy="21.4"
r="1.9"
id="circle12" /><path
d="m 29.1,35.6 c 0,-0.2 -0.2,-0.5 -0.5,-0.5 -0.3,0 -0.5,0.2 -0.5,0.5 v 1.7 3 5 c 0,0.6 -0.6,1.2 -1.2,1.2 -0.6,0 -1.2,-0.5 -1.2,-1.2 V 40.5 37.3 33.2 32 28.2 28.3 c 0,-0.2 -0.1,-0.4 -0.4,-0.4 -0.2,0 -0.4,0.2 -0.4,0.4 v 1.3 3.5 1.8 c 0,0.4 -0.3,0.7 -0.7,0.7 -0.4,0 -0.7,-0.3 -0.7,-0.7 v -1 -3.5 -4.2 c 0,-1 0.8,-1.9 1.9,-1.9 h 5.2 0.3 c 0.2,0 0.5,0.1 0.6,0.3 l 2.1,2.1 2.5,-2.5 c 0.4,-0.4 1,-0.4 1.3,0 0.4,0.4 0.4,1 0,1.3 l -3.2,3.2 C 34,28.9 33.8,29 33.5,29 33.3,29 33,28.9 32.8,28.7 L 32,27.9 31.8,27.8 h -0.2 c -0.2,0 -0.4,0.2 -0.4,0.4 v 1.6 10.6 l 7.68e-4,4.906766 c 9.4e-5,0.6 -0.6,1.2 -1.2,1.2 -0.6,0 -0.957071,-0.484801 -0.957071,-1.184801 0,0 0.0563,-6.496244 0.0563,-9.721965 z"
id="path14"
sodipodi:nodetypes="cssccsssccccccssccsssccsscsccsccsssccssccsscc" /><circle
cx="42.400002"
cy="21"
r="1.5"
id="circle16" /><circle
cx="42.400002"
cy="24.5"
r="1.5"
id="circle18" /><circle
cx="42.400002"
cy="28.200001"
r="1.5"
id="circle20" />
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -1 +1,76 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 228.57 239.29"><defs><style>.cls-1{fill:#1d1d1b;}</style></defs><path class="cls-1" d="M208.18,119.08V11.93c0-5.24,0-5.24,5.15-5.24,2.43,0,4.87,0,7.31,0,2.05,0,3.12.76,3,2.92-.07,1.13,0,2.27,0,3.4q0,106.5,0,213c0,.69-.06,1.39,0,2.09.13,1.9-.73,2.68-2.62,2.64-3.39-.05-6.79,0-10.19,0-1.84,0-2.73-.76-2.66-2.67s0-4,0-6Z"/><path class="cls-1" d="M20,119.06V226.75c0,3.9,0,3.92-3.91,4-3,0-5.93-.05-8.89,0-1.76,0-2.58-.7-2.55-2.47s0-3.31,0-5q0-106.12,0-212.25c0-4.17.22-4.39,4.45-4.36,2.52,0,5.05.08,7.58,0,2.26-.09,3.47.67,3.32,3.13-.1,1.47,0,3,0,4.44q0,52.41,0,104.82Z"/><path class="cls-1" d="M135.46,156.52a4.35,4.35,0,0,0-4.86-3.21,12.64,12.64,0,0,0-2.44.73c-2.07.72-4.13,1.47-6.22,2.21l-.26-.54q-1.94-4.52-3.88-9c-1.77-4.11-3.53-8.22-5.32-12.31a4.21,4.21,0,0,0-4.06-2.71c-4.84-.06-9.68-.07-14.52-.11L81,131.46c-.18,0-.5-.09-.52-.19-.16-.78-.27-1.58-.4-2.42H99.2c.35,0,.69,0,1,0a4.41,4.41,0,0,0,3.41-6.75,4.58,4.58,0,0,0-4.22-2.1q-10,0-20,0h-.72c-.52-3.24-1-6.39-1.54-9.56h-9c.55,3.45,1.11,6.9,1.66,10.35.83,5.11,1.71,10.2,2.47,15.32a4.76,4.76,0,0,0,4.92,4.29c9.22,0,18.45.11,27.68.15a.86.86,0,0,1,.91.61q4.72,11.05,9.48,22.08a4.49,4.49,0,0,0,6.12,2.69c3.69-1.31,7.39-2.61,11.07-3.95a6.74,6.74,0,0,0,1.67-1,4.71,4.71,0,0,0,1.49-2.56v-1.48C135.55,156.8,135.5,156.66,135.46,156.52Z"/><path class="cls-1" d="M53.61,145.09c.2-1.23.33-2.47.59-3.69a26.58,26.58,0,0,1,6.42-12.56,4.42,4.42,0,0,1,6.63,5.85,18.7,18.7,0,0,0-4.46,8.95,18.32,18.32,0,0,0,34.75,10.84,4.62,4.62,0,0,1,3.67-3,4.41,4.41,0,0,1,4.76,5.84,23.53,23.53,0,0,1-3.45,6.12,26.77,26.77,0,0,1-14.83,10c-1.46.38-3,.53-4.47.79l-.56.11H78.9c-.14,0-.29-.08-.43-.1a34.79,34.79,0,0,1-3.7-.6c-11-2.89-17.86-9.91-20.58-20.95-.29-1.19-.39-2.43-.58-3.64Z"/><ellipse class="cls-1" cx="72.62" cy="109.74" rx="4.51" ry="3.94"/><circle class="cls-1" cx="71.76" cy="95.49" r="8.93"/><path class="cls-1" d="M157.33,131.79H154v1.75q0,18,0,36c0,2.4-1,3.89-2.94,4.52a4.17,4.17,0,0,1-5.43-3.17,10.86,10.86,0,0,1-.13-2q0-31,0-61.93v-2.49h-2c0,.48-.07,1-.07,1.47,0,7.32,0,14.65,0,22,0,2.28-1.42,3.66-3.4,3.39a3,3,0,0,1-2.63-3.33c0-5.24,0-10.47,0-15.7,0-4.38,0-8.75,0-13.13,0-5.09,2.76-7.89,7.83-7.92q10.48-.06,21,0c4.89,0,7.67,2.88,7.67,7.77q0,14.49,0,29c0,2.3-1.56,3.7-3.6,3.31-1.57-.3-2.41-1.44-2.41-3.35q0-10.84,0-21.69v-1.76h-2v1.76q0,31.32,0,62.64a10.81,10.81,0,0,1-.17,2.13,4.23,4.23,0,0,1-4.41,3.27,4.18,4.18,0,0,1-3.9-4c0-2.95,0-5.9,0-8.84V131.79Z"/><path class="cls-1" d="M155.74,89.56a9,9,0,0,1-9.1-9,9,9,0,0,1,18,0A9,9,0,0,1,155.74,89.56Z"/><path class="cls-1" d="M191.93,36.94h-71V24.12h10l-17-17-17,17h10V36.94h-71a5.83,5.83,0,0,0-5.83,5.83V197.05a5.83,5.83,0,0,0,5.83,5.83h71V215.7h-10l17,17,17-17h-10V202.88h71a5.83,5.83,0,0,0,5.83-5.83V42.77A5.83,5.83,0,0,0,191.93,36.94Zm-7.5,147a5.83,5.83,0,0,1-5.83,5.84H49.22a5.83,5.83,0,0,1-5.83-5.84V56a5.83,5.83,0,0,1,5.83-5.83H178.6A5.83,5.83,0,0,1,184.43,56Z"/></svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="Layer_1"
data-name="Layer 1"
viewBox="0 0 228.57 239.29"
version="1.1"
sodipodi:docname="elevator_wheelchair.svg"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview25"
pagecolor="#ffffff"
bordercolor="#111111"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
showgrid="false"
inkscape:zoom="1.9145025"
inkscape:cx="60.851318"
inkscape:cy="68.425087"
inkscape:window-width="1920"
inkscape:window-height="1007"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<defs
id="defs4">
<style
id="style2">.cls-1{fill:#1d1d1b;}</style>
</defs>
<path
class="cls-1"
d="m 146.05301,172.90366 a 6.4729946,6.4729946 0 0 0 -7.2319,-4.77662 18.808885,18.808885 0 0 0 -3.63083,1.08627 c -3.08025,1.07139 -6.14562,2.18743 -9.25563,3.28858 l -0.3869,-0.80354 q -2.8868,-6.72597 -5.77361,-13.39241 c -2.63384,-6.11586 -5.2528,-12.23172 -7.9164,-18.31783 a 6.2646683,6.2646683 0 0 0 -6.04146,-4.0326 c -7.202135,-0.0893 -14.404272,-0.10416 -21.606408,-0.16368 l -19.195777,-0.17857 c -0.267848,0 -0.744022,-0.13392 -0.773783,-0.28273 -0.238087,-1.16067 -0.401772,-2.35111 -0.595218,-3.60107 h 28.451415 c 0.520816,0 1.026751,0 1.488045,0 a 6.5622772,6.5622772 0 0 0 5.074232,-10.0443 6.8152448,6.8152448 0 0 0 -6.279548,-3.12489 q -14.880448,0 -29.760895,0 H 61.546951 C 60.773168,113.739 60.058906,109.05166 59.255362,104.33456 H 45.862959 c 0.818425,5.13375 1.65173,10.26751 2.470155,15.40126 1.235077,7.60391 2.544556,15.17806 3.67547,22.79685 a 7.0830929,7.0830929 0 0 0 7.32118,6.38371 c 13.719773,0 27.454425,0.16369 41.189076,0.22321 a 1.2797185,1.2797185 0 0 1 1.35412,0.9077 q 7.02357,16.4429 14.10667,32.85603 a 6.6813208,6.6813208 0 0 0 9.10683,4.00284 c 5.49089,-1.94934 10.99665,-3.88379 16.47266,-5.87777 a 10.029421,10.029421 0 0 0 2.48503,-1.48805 7.0086907,7.0086907 0 0 0 2.21719,-3.80939 v -2.20231 c -0.0744,-0.20833 -0.14881,-0.41665 -0.20833,-0.62498 z"
id="path10"
style="stroke-width:1.48804" />
<path
class="cls-1"
d="m 24.25655,155.89531 c 0.297609,-1.83029 0.491055,-3.67547 0.877946,-5.49088 a 39.552229,39.552229 0 0 1 9.553248,-18.68985 6.5785825,6.5785825 0 0 1 9.865736,8.70507 27.826436,27.826436 0 0 0 -6.636679,13.318 27.260979,27.260979 0 0 0 51.709554,16.1304 6.8747666,6.8747666 0 0 1 5.461124,-4.46413 6.5622772,6.5622772 0 0 1 7.083091,8.69018 35.013692,35.013692 0 0 1 -5.133752,9.10683 39.834957,39.834957 0 0 1 -22.067704,14.88045 c -2.172545,0.56546 -4.464134,0.78866 -6.65156,1.17555 l -0.833305,0.16369 h -5.595048 c -0.208326,0 -0.431533,-0.11905 -0.639859,-0.14881 a 51.769076,51.769076 0 0 1 -5.505766,-0.89282 c -16.368492,-4.30045 -26.576478,-14.74653 -30.62396,-31.17454 -0.431533,-1.77077 -0.580337,-3.61595 -0.863066,-5.41648 z"
id="path12"
style="stroke-width:1.48804" />
<ellipse
class="cls-1"
cx="52.544285"
cy="103.29292"
rx="6.711082"
ry="5.8628964"
id="ellipse14"
style="stroke-width:1.48804" />
<circle
class="cls-1"
cx="51.264565"
cy="82.088287"
r="13.288239"
id="circle16"
style="stroke-width:1.48804" />
<path
class="cls-1"
d="m 178.59655,136.10432 h -4.95519 v 2.60407 q 0,26.78481 0,53.56961 c 0,3.57131 -1.48804,5.7885 -4.37485,6.72597 a 6.2051465,6.2051465 0 0 1 -8.08008,-4.71711 16.160166,16.160166 0 0 1 -0.19345,-2.97609 q 0,-46.12938 0,-92.154605 v -3.705232 h -2.97609 c 0,0.714262 -0.10416,1.488045 -0.10416,2.187426 0,10.892491 0,21.799851 0,32.736981 0,3.39275 -2.11303,5.44625 -5.05935,5.04447 a 4.4641342,4.4641342 0 0 1 -3.91356,-4.95518 c 0,-7.79736 0,-15.57983 0,-23.36231 0,-6.51763 0,-13.020388 0,-19.538024 0,-7.574147 4.107,-11.740672 11.65139,-11.785314 q 15.59471,-0.08928 31.24894,0 c 7.27654,0 11.4133,4.285569 11.4133,11.562108 q 0,21.56177 0,43.1533 c 0,3.4225 -2.32135,5.50576 -5.35696,4.92542 -2.33623,-0.44641 -3.58619,-2.14278 -3.58619,-4.98495 q 0,-16.1304 0,-32.275685 v -2.618959 h -2.97609 v 2.618959 q 0,46.605565 0,93.211125 a 16.085763,16.085763 0 0 1 -0.25297,3.16953 6.2944292,6.2944292 0 0 1 -6.56227,4.86591 6.2200269,6.2200269 0 0 1 -5.80338,-5.95218 c 0,-4.38973 0,-8.77946 0,-13.15432 v -44.19492 z"
id="path18"
style="stroke-width:1.48804" />
<path
class="cls-1"
d="m 176.23056,73.264187 a 13.392403,13.392403 0 0 1 -13.54121,-13.392403 13.392405,13.392405 0 0 1 26.78481,0 13.392403,13.392403 0 0 1 -13.2436,13.392403 z"
id="path20"
style="stroke-width:1.48804" />
<path
class="cls-1"
d="M 226.27477,0.4068479 H 124.01222 V -18.058024 H 138.4154 L 113.93,-42.543423 89.444601,-18.058024 H 103.84778 V 0.4068479 H 1.5852264 A 8.3970517,8.3970517 0 0 0 -6.8118252,8.8038996 V 231.0161 a 8.3970517,8.3970517 0 0 0 8.3970516,8.39705 H 103.84778 v 18.46487 H 89.444601 l 24.485399,24.4854 24.4854,-24.4854 h -14.40318 v -18.46487 h 102.26255 a 8.3970517,8.3970517 0 0 0 8.39706,-8.39705 V 8.8038996 A 8.3970517,8.3970517 0 0 0 226.27477,0.4068479 Z M 215.47239,212.13354 a 8.3970517,8.3970517 0 0 1 -8.39705,8.41145 H 20.727047 a 8.3970517,8.3970517 0 0 1 -8.397051,-8.41145 V 27.859302 A 8.3970517,8.3970517 0 0 1 20.727047,19.46225 H 207.07534 a 8.3970517,8.3970517 0 0 1 8.39705,8.397052 z"
id="path22"
style="stroke-width:1.44032" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -387,9 +387,19 @@
],
"sources": []
},
{
"path": "elevator.svg",
"license": "CC-BY-SA 4.0",
"authors": [
"Yveltal"
],
"sources": [
"https://commons.wikimedia.org/wiki/File:HZM_elevator_icon.svg"
]
},
{
"path": "elevator_wheelchair.svg",
"license": "CC-BY_SA",
"license": "CC-BY-SA",
"authors": [
"Robin Julien"
],

View file

@ -1110,10 +1110,6 @@ video {
height: 12rem;
}
.max-h-screen {
max-height: 100vh;
}
.max-h-7 {
max-height: 1.75rem;
}
@ -1302,6 +1298,10 @@ video {
flex-wrap: wrap-reverse;
}
.place-content-center {
place-content: center;
}
.content-start {
align-content: flex-start;
}
@ -1481,6 +1481,11 @@ video {
border-color: rgba(252, 165, 165, var(--tw-border-opacity));
}
.border-blue-500 {
--tw-border-opacity: 1;
border-color: rgba(59, 130, 246, var(--tw-border-opacity));
}
.border-gray-200 {
--tw-border-opacity: 1;
border-color: rgba(229, 231, 235, var(--tw-border-opacity));
@ -1510,6 +1515,11 @@ video {
background-color: rgba(224, 231, 255, var(--tw-bg-opacity));
}
.bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgba(239, 68, 68, var(--tw-bg-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
@ -1530,11 +1540,6 @@ video {
background-color: rgba(209, 213, 219, var(--tw-bg-opacity));
}
.bg-red-500 {
--tw-bg-opacity: 1;
background-color: rgba(239, 68, 68, var(--tw-bg-opacity));
}
.bg-red-200 {
--tw-bg-opacity: 1;
background-color: rgba(254, 202, 202, var(--tw-bg-opacity));
@ -1857,15 +1862,11 @@ video {
}
.z-above-map {
z-index: 10000
z-index: 10000;
}
.z-above-controls {
z-index: 10001
}
.w-160 {
width: 40rem;
z-index: 10001;
}
.bg-subtle {
@ -1892,14 +1893,14 @@ video {
* Base colour of interactive elements, mainly the 'subtle button'
*
*/
--subtle-detail-color: #DBEAFE;
--subtle-detail-color: #dbeafe;
--subtle-detail-color-contrast: black;
--subtle-detail-color-light-contrast: lightgrey;
/**
* A stronger variant of the 'subtle-detail-colour'
* Used as subtle button hover
*/
--unsubtle-detail-color: #BFDBFE;
--unsubtle-detail-color: #bfdbfe;
--unsubtle-detail-color-contrast: black;
--catch-detail-color: #3a3aeb;
--catch-detail-color-contrast: white;
@ -1913,7 +1914,8 @@ video {
--variable-title-height: 0px;
}
html, body {
html,
body {
height: 100%;
min-height: 100vh;
min-height: -webkit-fill-available;
@ -1921,7 +1923,7 @@ html, body {
padding: 0;
background-color: var(--background-color);
color: var(--foreground-color);
font-family: 'Helvetica Neue', Arial, sans-serif;
font-family: "Helvetica Neue", Arial, sans-serif;
}
.leaflet-overlay-pane .leaflet-zoom-animated {
@ -1944,7 +1946,8 @@ html, body {
height: 100% !important;
}
svg, img {
svg,
img {
box-sizing: content-box;
width: 100%;
height: 100%;
@ -2048,6 +2051,35 @@ a {
height: min-content;
}
/* slider */
input[type="range"].vertical {
-webkit-writing-mode: bt-lr;
-ms-writing-mode: bt-lr;
writing-mode: bt-lr;
/* IE */
-webkit-appearance: slider-vertical;
/* Chromium */
cursor: pointer;
}
@-moz-document url-prefix() {
input[type="range"].elevator::-moz-range-thumb {
background-color: #00000000 !important;
background-image: url("/assets/svg/elevator_wheelchair.svg");
width: 150px !important;
height: 30px !important;
border: 2px;
border-style: solid;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
border-image: linear-gradient(to right, black 50%, transparent 50%) 100% 1;
padding-bottom: 5px;
}
}
.border-detail {
border-color: var(--foreground-color);
}
@ -2117,7 +2149,7 @@ p {
}
li::marker {
content: "•"
content: "•";
}
.subtle-background {
@ -2127,7 +2159,7 @@ li::marker {
.normal-background {
background: var(--background-color);
color: var(--foreground-color)
color: var(--foreground-color);
}
.subtle-lighter {
@ -2205,7 +2237,8 @@ li::marker {
color: unset !important;
}
.disable-links a.must-link, .disable-links .must-link a {
.disable-links a.must-link,
.disable-links .must-link a {
/* Hide links if they are disabled */
display: none;
}
@ -2424,7 +2457,7 @@ li::marker {
/***************** Info box (box containing features and questions ******************/
input {
color: var(--foreground-color)
color: var(--foreground-color);
}
.leaflet-popup-content {
@ -2485,7 +2518,7 @@ input {
}
.animate-height {
transition: max-height .5s ease-in-out;
transition: max-height 0.5s ease-in-out;
overflow-y: hidden;
}
@ -2855,4 +2888,3 @@ input {
display: inline;
}
}

View file

@ -14,11 +14,11 @@
@layer utilities {
@variants responsive {
.z-above-map {
z-index: 10000
z-index: 10000;
}
.z-above-controls {
z-index: 10001
z-index: 10001;
}
.w-160 {
@ -50,10 +50,8 @@
border-top-right-radius: 999rem;
}
}
}
:root {
/* The main colour scheme of mapcomplete is configured here.
* For a custom styling, set 'customCss' in your layoutConfig and overwrite some of these.
@ -71,7 +69,7 @@
* Base colour of interactive elements, mainly the 'subtle button'
*
*/
--subtle-detail-color: #DBEAFE;
--subtle-detail-color: #dbeafe;
--subtle-detail-color-contrast: black;
--subtle-detail-color-light-contrast: lightgrey;
@ -79,14 +77,12 @@
* A stronger variant of the 'subtle-detail-colour'
* Used as subtle button hover
*/
--unsubtle-detail-color: #BFDBFE;
--unsubtle-detail-color: #bfdbfe;
--unsubtle-detail-color-contrast: black;
--catch-detail-color: #3a3aeb;
--catch-detail-color-contrast: white;
--non-active-tab-svg: var(--foreground-color);
--shadow-color: #00000066;
@ -100,7 +96,8 @@
--variable-title-height: 0px;
}
html, body {
html,
body {
height: 100%;
min-height: 100vh;
min-height: -webkit-fill-available;
@ -108,7 +105,7 @@ html, body {
padding: 0;
background-color: var(--background-color);
color: var(--foreground-color);
font-family: 'Helvetica Neue', Arial, sans-serif;
font-family: "Helvetica Neue", Arial, sans-serif;
}
.leaflet-overlay-pane .leaflet-zoom-animated {
@ -131,7 +128,8 @@ html, body {
height: 100% !important;
}
svg, img {
svg,
img {
box-sizing: content-box;
width: 100%;
height: 100%;
@ -210,7 +208,6 @@ a {
.btn-secondary {
background-color: var(--catch-detail-color);
filter: saturate(0.5);
}
.btn-secondary:hover {
@ -231,6 +228,29 @@ a {
height: min-content;
}
/* slider */
input[type="range"].vertical {
writing-mode: bt-lr; /* IE */
-webkit-appearance: slider-vertical; /* Chromium */
cursor: pointer;
}
@-moz-document url-prefix() {
input[type="range"].elevator::-moz-range-thumb {
background-color: #00000000 !important;
background-image: url("/assets/svg/elevator_wheelchair.svg");
width: 150px !important;
height: 30px !important;
border: 2px;
border-style: solid;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
cursor: pointer;
border-image: linear-gradient(to right, black 50%, transparent 50%) 100% 1;
padding-bottom: 5px;
}
}
.border-detail {
border-color: var(--foreground-color);
@ -302,7 +322,7 @@ p {
}
li::marker {
content: "•"
content: "•";
}
.subtle-background {
@ -312,7 +332,7 @@ li::marker {
.normal-background {
background: var(--background-color);
color: var(--foreground-color)
color: var(--foreground-color);
}
.subtle-lighter {
@ -335,7 +355,6 @@ li::marker {
fill: var(--catch-detail-color) !important;
}
#leafletDiv {
height: 100%;
}
@ -375,7 +394,6 @@ li::marker {
max-width: 2em !important;
}
.block-ruby {
display: block ruby;
}
@ -392,14 +410,14 @@ li::marker {
color: unset !important;
}
.disable-links a.must-link, .disable-links .must-link a {
.disable-links a.must-link,
.disable-links .must-link a {
/* Hide links if they are disabled */
display: none;
}
/**************** GENERIC ****************/
.alert {
background-color: var(--alert-color);
color: var(--foreground-color);
@ -434,7 +452,6 @@ li::marker {
padding: 0.15em 0.3em;
}
.subtle {
color: #999;
}
@ -444,7 +461,6 @@ li::marker {
color: #7193bb;
}
.thanks {
background-color: #43d904;
font-weight: bold;
@ -462,7 +478,6 @@ li::marker {
pointer-events: none !important;
}
@keyframes slide {
/* This is the animation on the marker to add a new point - it slides through all the possible presets */
from {
@ -506,7 +521,6 @@ li::marker {
transform: rotate(-30deg);
}
36% {
opacity: 0;
transform: rotate(-30deg);
@ -516,12 +530,10 @@ li::marker {
opacity: 0;
transform: rotate(-30deg);
}
}
/**************************************/
#topleft-tools {
display: block;
position: absolute;
@ -540,12 +552,10 @@ li::marker {
color: var(--foreground-color);
}
/***************** Info box (box containing features and questions ******************/
input {
color: var(--foreground-color)
color: var(--foreground-color);
}
.leaflet-popup-content {
@ -579,7 +589,6 @@ input {
box-sizing: border-box;
}
.code {
display: inline-block;
background-color: lightgray;
@ -600,18 +609,16 @@ input {
max-width: 1em;
}
.slideshow-item img {
height: var(--image-carousel-height);
width: unset;
}
.animate-height {
transition: max-height .5s ease-in-out;
transition: max-height 0.5s ease-in-out;
overflow-y: hidden;
}
.zebra-table tr:nth-child(even) {
background-color: #f2f2f2;
}
@ -657,7 +664,6 @@ input {
width: unset;
}
.mapping-icon-small {
/* A mapping icon type */
width: 1.5rem;
@ -681,7 +687,4 @@ input {
margin-bottom: 0.5rem;
margin-right: 1.5rem;
margin-left: 1.5rem;
}

View file

@ -140,6 +140,10 @@
"title": "Select layers",
"zoomInToSeeThisLayer": "Zoom in to see this layer"
},
"levelSelection": {
"addNewOnLevel": "Is the new point location on level {level}?",
"confirmLevel": "Yes, add {preset} on level {level}"
},
"loading": "Loading…",
"loadingTheme": "Loading {theme}…",
"loginFailed": "Logging in into OpenStreetMap failed",

View file

@ -10,7 +10,7 @@ import {AllKnownLayouts} from "../Customizations/AllKnownLayouts";
import RelationsTracker from "../Logic/Osm/RelationsTracker";
import * as OsmToGeoJson from "osmtogeojson";
import MetaTagging from "../Logic/MetaTagging";
import {UIEventSource} from "../Logic/UIEventSource";
import {ImmutableStore, UIEventSource} from "../Logic/UIEventSource";
import {TileRange, Tiles} from "../Models/TileRange";
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
import ScriptUtils from "./ScriptUtils";
@ -250,9 +250,10 @@ function sliceToTiles(allFeatures: FeatureSource, theme: LayoutConfig, relations
}
const filteredTile = new FilteringFeatureSource({
locationControl: new UIEventSource<Loc>(undefined),
locationControl: new ImmutableStore<Loc>(undefined),
allElements: undefined,
selectedElement: new UIEventSource<any>(undefined)
selectedElement: new ImmutableStore<any>(undefined),
globalFilters: new ImmutableStore([])
},
tileIndex,
tile,
@ -323,9 +324,10 @@ function sliceToTiles(allFeatures: FeatureSource, theme: LayoutConfig, relations
if (pointsOnlyLayers.indexOf(layer.id) >= 0) {
const filtered = new FilteringFeatureSource({
locationControl: new UIEventSource<Loc>(undefined),
locationControl: new ImmutableStore<Loc>(undefined),
allElements: undefined,
selectedElement: new UIEventSource<any>(undefined)
selectedElement: new ImmutableStore<any>(undefined),
globalFilters: new ImmutableStore([])
},
Tiles.tile_index(0, 0, 0),
source,

76
test.ts
View file

@ -1,76 +1,4 @@
import ChartJs from "./UI/Base/ChartJs";
import TagRenderingChart from "./UI/BigComponents/TagRenderingChart";
import {OsmFeature} from "./Models/OsmFeature";
import * as food from "./assets/generated/layers/food.json"
import TagRenderingConfig from "./Models/ThemeConfig/TagRenderingConfig";
import LevelSelector from "./UI/Input/LevelSelector";
import {UIEventSource} from "./Logic/UIEventSource";
import Combine from "./UI/Base/Combine";
const data = new UIEventSource<OsmFeature[]>([
{
properties: {
id: "node/1234",
cuisine:"pizza",
"payment:cash":"yes"
},
geometry:{
type: "Point",
coordinates: [0,0]
},
id: "node/1234",
type: "Feature"
},
{
properties: {
id: "node/42",
cuisine:"pizza",
"payment:cash":"yes"
},
geometry:{
type: "Point",
coordinates: [1,0]
},
id: "node/42",
type: "Feature"
},
{
properties: {
id: "node/452",
cuisine:"pasta",
"payment:cash":"yes",
"payment:cards":"yes"
},
geometry:{
type: "Point",
coordinates: [2,0]
},
id: "node/452",
type: "Feature"
},
{
properties: {
id: "node/4542",
cuisine:"something_comletely_invented",
"payment:cards":"yes"
},
geometry:{
type: "Point",
coordinates: [3,0]
},
id: "node/4542",
type: "Feature"
},
{
properties: {
id: "node/45425",
},
geometry:{
type: "Point",
coordinates: [3,0]
},
id: "node/45425",
type: "Feature"
}
]);
new Combine(food.tagRenderings.map(tr => new TagRenderingChart(data, new TagRenderingConfig(tr, "test"), {chartclasses: "w-160 h-160"})))
.AttachTo("maindiv")
new LevelSelector(new UIEventSource(["0","1","2","2.5","x","3"])).AttachTo("maindiv")