Merge branch 'develop' into feature/goejson-export

This commit is contained in:
Pieter Vander Vennet 2021-07-16 00:57:39 +02:00
commit 18e27c32be
13 changed files with 166 additions and 127 deletions

View file

@ -341,7 +341,7 @@ export class InitUiElements {
private static InitBaseMap() {
State.state.availableBackgroundLayers = new AvailableBaseLayers(State.state.locationControl).availableEditorLayers;
State.state.availableBackgroundLayers = AvailableBaseLayers.AvailableLayersAt(State.state.locationControl);
State.state.backgroundLayer = State.state.backgroundLayerId
.map((selectedId: string) => {

View file

@ -7,7 +7,6 @@ import {UIEventSource} from "../UIEventSource";
import {GeoOperations} from "../GeoOperations";
import {Utils} from "../../Utils";
import Loc from "../../Models/Loc";
import {isBoolean} from "util";
/**
* Calculates which layers are available at the current location
@ -31,42 +30,82 @@ export default class AvailableBaseLayers {
category: "osmbasedmap"
}
public static layerOverview = AvailableBaseLayers.LoadRasterIndex().concat(AvailableBaseLayers.LoadProviderIndex());
public availableEditorLayers: UIEventSource<BaseLayer[]>;
constructor(location: UIEventSource<Loc>) {
const self = this;
this.availableEditorLayers =
location.map(
(currentLocation) => {
public static AvailableLayersAt(location: UIEventSource<Loc>): UIEventSource<BaseLayer[]> {
const source = location.map(
(currentLocation) => {
if (currentLocation === undefined) {
return AvailableBaseLayers.layerOverview;
}
if (currentLocation === undefined) {
return AvailableBaseLayers.layerOverview;
}
const currentLayers = self.availableEditorLayers?.data;
const newLayers = AvailableBaseLayers.AvailableLayersAt(currentLocation?.lon, currentLocation?.lat);
const currentLayers = source?.data; // A bit unorthodox - I know
const newLayers = AvailableBaseLayers.CalculateAvailableLayersAt(currentLocation?.lon, currentLocation?.lat);
if (currentLayers === undefined) {
if (currentLayers === undefined) {
return newLayers;
}
if (newLayers.length !== currentLayers.length) {
return newLayers;
}
for (let i = 0; i < newLayers.length; i++) {
if (newLayers[i].name !== currentLayers[i].name) {
return newLayers;
}
if (newLayers.length !== currentLayers.length) {
return newLayers;
}
for (let i = 0; i < newLayers.length; i++) {
if (newLayers[i].name !== currentLayers[i].name) {
return newLayers;
}
}
return currentLayers;
});
}
return currentLayers;
});
return source;
}
private static AvailableLayersAt(lon: number, lat: number): BaseLayer[] {
public static SelectBestLayerAccordingTo(location: UIEventSource<Loc>, preferedCategory: UIEventSource<string | string[]>): UIEventSource<BaseLayer> {
return AvailableBaseLayers.AvailableLayersAt(location).map(available => {
// First float all 'best layers' to the top
available.sort((a, b) => {
if (a.isBest && b.isBest) {
return 0;
}
if (!a.isBest) {
return 1
}
return -1;
}
)
if (preferedCategory.data === undefined) {
return available[0]
}
let prefered: string []
if (typeof preferedCategory.data === "string") {
prefered = [preferedCategory.data]
} else {
prefered = preferedCategory.data;
}
prefered.reverse();
for (const category of prefered) {
//Then sort all 'photo'-layers to the top. Stability of the sorting will force a 'best' photo layer on top
available.sort((a, b) => {
if (a.category === category && b.category === category) {
return 0;
}
if (a.category !== category) {
return 1
}
return -1;
}
)
}
return available[0]
})
}
private static CalculateAvailableLayersAt(lon: number, lat: number): BaseLayer[] {
const availableLayers = [AvailableBaseLayers.osmCarto]
const globalLayers = [];
for (const layerOverviewItem of AvailableBaseLayers.layerOverview) {
@ -146,7 +185,7 @@ export default class AvailableBaseLayers {
layer: leafletLayer,
feature: layer,
isBest: props.best ?? false,
category: props.category
category: props.category
});
}
return layers;

View file

@ -52,7 +52,7 @@ export default class Minimap extends BaseUIElement {
return wrapper;
}
private InitMap() {
if (this._constructedHtmlElement === undefined) {
// This element isn't initialized yet

View file

@ -19,6 +19,7 @@ import {Translation} from "../i18n/Translation";
import LocationInput from "../Input/LocationInput";
import {InputElement} from "../Input/InputElement";
import Loc from "../../Models/Loc";
import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers";
/*
* The SimpleAddUI is a single panel, which can have multiple states:
@ -115,14 +116,21 @@ export default class SimpleAddUI extends Toggle {
let location = State.state.LastClickLocation;
let preciseInput: InputElement<Loc> = undefined
if (preset.preciseInput !== undefined) {
const locationSrc = new UIEventSource({
lat: location.data.lat,
lon: location.data.lon,
zoom: 19
});
let backgroundLayer = undefined;
if(preset.preciseInput.preferredBackground){
backgroundLayer= AvailableBaseLayers.SelectBestLayerAccordingTo(locationSrc, new UIEventSource<string | string[]>(preset.preciseInput.preferredBackground))
}
preciseInput = new LocationInput({
preferCategory: preset.preciseInput.preferredBackground ?? State.state.backgroundLayer,
centerLocation:
new UIEventSource({
lat: location.data.lat,
lon: location.data.lon,
zoom: 19
})
mapBackground: backgroundLayer,
centerLocation:locationSrc
})
preciseInput.SetClass("h-32 rounded-xl overflow-hidden border border-gray").SetStyle("height: 12rem;")
}

View file

@ -2,30 +2,27 @@ import {InputElement} from "./InputElement";
import Loc from "../../Models/Loc";
import {UIEventSource} from "../../Logic/UIEventSource";
import Minimap from "../Base/Minimap";
import AvailableBaseLayers from "../../Logic/Actors/AvailableBaseLayers";
import BaseLayer from "../../Models/BaseLayer";
import Combine from "../Base/Combine";
import Svg from "../../Svg";
import State from "../../State";
export default class LocationInput extends InputElement<Loc> {
IsSelected: UIEventSource<boolean> = new UIEventSource<boolean>(false);
private _centerLocation: UIEventSource<Loc>;
private readonly preferCategory;
private readonly mapBackground : UIEventSource<BaseLayer>;
constructor(options?: {
mapBackground?: UIEventSource<BaseLayer>,
centerLocation?: UIEventSource<Loc>,
preferCategory?: string | UIEventSource<string>,
}) {
super();
options = options ?? {}
options.centerLocation = options.centerLocation ?? new UIEventSource<Loc>({lat: 0, lon: 0, zoom: 1})
this._centerLocation = options.centerLocation;
if(typeof options.preferCategory === "string"){
options.preferCategory = new UIEventSource<string>(options.preferCategory);
}
this.preferCategory = options.preferCategory ?? new UIEventSource<string>(undefined)
this.mapBackground = options.mapBackground ?? State.state.backgroundLayer
this.SetClass("block h-full")
}
@ -38,43 +35,10 @@ export default class LocationInput extends InputElement<Loc> {
}
protected InnerConstructElement(): HTMLElement {
const layer: UIEventSource<BaseLayer> = new AvailableBaseLayers(this._centerLocation).availableEditorLayers.map(allLayers => {
// First float all 'best layers' to the top
allLayers.sort((a, b) => {
if (a.isBest && b.isBest) {
return 0;
}
if (!a.isBest) {
return 1
}
return -1;
}
)
if (this.preferCategory) {
const self = this;
//Then sort all 'photo'-layers to the top. Stability of the sorting will force a 'best' photo layer on top
allLayers.sort((a, b) => {
const preferred = self.preferCategory.data
if (a.category === preferred && b.category === preferred) {
return 0;
}
if (a.category !== preferred) {
return 1
}
return -1;
}
)
}
return allLayers[0]
}, [this.preferCategory]
)
layer.addCallbackAndRunD(layer => console.log(layer))
const map = new Minimap(
{
location: this._centerLocation,
background: layer
background: this.mapBackground
}
)
map.leafletMap.addCallbackAndRunD(leaflet => {
@ -84,7 +48,7 @@ export default class LocationInput extends InputElement<Loc> {
)
})
layer.map(layer => {
this.mapBackground.map(layer => {
const leaflet = map.leafletMap.data
if (leaflet === undefined || layer === undefined) {

View file

@ -25,9 +25,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="67.47399"
inkscape:cy="29.788021"
inkscape:zoom="5.6568542"
inkscape:cx="27.044982"
inkscape:cy="77.667126"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@ -68,40 +68,39 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-270.54165)">
<circle
style="fill:none;fill-opacity:1;stroke:#5555ec;stroke-width:2.64583335;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.98823529"
id="path815"
cx="13.16302"
cy="283.77081"
r="8.8715391" />
<path
style="fill:none;stroke:#5555ec;stroke-width:2.09723878;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529"
d="M 3.2841366,283.77082 H 1.0418969"
id="path817"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5555ec;stroke-width:2.11666679;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529"
d="M 25.405696,283.77082 H 23.286471"
id="path817-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5555ec;stroke-width:2.11666679;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529"
d="m 13.229167,295.9489 v -2.11763"
id="path817-3-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#5555ec;stroke-width:2.11666668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529"
d="m 13.229167,275.05759 v -3.44507"
id="path817-3-6-7"
inkscape:connector-curvature="0" />
<g
id="g824"
transform="matrix(0.63953151,0,0,0.64343684,6.732623,276.71502)"
style="fill:#ffcc33">
id="g827">
<circle
r="8.8715391"
cy="283.77081"
cx="13.16302"
id="path815"
style="fill:none;fill-opacity:1;stroke:#5555ec;stroke-width:2.64583335;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.98823529" />
<path
id="path822"
d="M 16.07,8 H 15 V 5 C 15,5 15,0 10,0 5,0 5,5 5,5 V 8 H 3.93 A 1.93,1.93 0 0 0 2,9.93 v 8.15 A 1.93,1.93 0 0 0 3.93,20 H 16.07 A 1.93,1.93 0 0 0 18,18.07 V 9.93 A 1.93,1.93 0 0 0 16.07,8 Z M 10,16 a 2,2 0 1 1 2,-2 2,2 0 0 1 -2,2 z M 13,8 H 7 V 5.5 C 7,4 7,2 10,2 c 3,0 3,2 3,3.5 z"
inkscape:connector-curvature="0" />
inkscape:connector-curvature="0"
id="path817"
d="M 3.2841366,283.77082 H 1.0418969"
style="fill:none;stroke:#5555ec;stroke-width:2.09723878;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" />
<path
inkscape:connector-curvature="0"
id="path817-3"
d="M 25.405696,283.77082 H 23.286471"
style="fill:none;stroke:#5555ec;stroke-width:2.11666679;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" />
<path
inkscape:connector-curvature="0"
id="path817-3-6"
d="m 13.229167,295.9489 v -2.11763"
style="fill:none;stroke:#5555ec;stroke-width:2.11666679;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" />
<path
inkscape:connector-curvature="0"
id="path817-3-6-7"
d="m 13.229167,275.05759 v -3.44507"
style="fill:none;stroke:#5555ec;stroke-width:2.11666668;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" />
</g>
<path
style="fill:#5555ec;fill-opacity:0.98823529;stroke-width:0.6151033"
inkscape:connector-curvature="0"
d="m 16.850267,281.91543 h -0.65616 v -1.85094 c 0,0 0,-3.08489 -3.066169,-3.08489 -3.066169,0 -3.066169,3.08489 -3.066169,3.08489 v 1.85094 H 9.4056091 a 1.1835412,1.1907685 0 0 0 -1.1835412,1.19077 v 5.02838 a 1.1835412,1.1907685 0 0 0 1.1835412,1.1846 h 7.4446579 a 1.1835412,1.1907685 0 0 0 1.183541,-1.19078 v -5.0222 a 1.1835412,1.1907685 0 0 0 -1.183541,-1.19077 z m -3.722329,4.93583 a 1.2264675,1.233957 0 1 1 1.226468,-1.23395 1.2264675,1.233957 0 0 1 -1.226468,1.23395 z m 1.839702,-4.93583 h -3.679403 v -1.54245 c 0,-0.92546 0,-2.15942 1.839701,-2.15942 1.839702,0 1.839702,1.23396 1.839702,2.15942 z"
id="path822" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -162,6 +162,18 @@
"license": "CC0; trivial",
"sources": []
},
{
"authors": [],
"path": "crosshair-empty.svg",
"license": "CC0; trivial",
"sources": []
},
{
"authors": [],
"path": "crosshair-locked.svg",
"license": "CC0; trivial",
"sources": []
},
{
"authors": [
"Dave Gandy"
@ -204,7 +216,7 @@
"license": "CC0",
"sources": [
"https://commons.wikimedia.org/wiki/File:Media-floppy.svg",
" http://tango.freedesktop.org/Tango_Desktop_Project"
"http://tango.freedesktop.org/Tango_Desktop_Project"
]
},
{

View file

@ -374,7 +374,7 @@
"en": "Is there a website with more information about this artwork?",
"nl": "Op welke website kan men meer informatie vinden over dit kunstwerk?",
"fr": "Sur quel site web pouvons-nous trouver plus d'informations sur cette œuvre d'art?",
"de": "Auf welcher Website gibt es mehr Informationen über dieses Kunstwerk?",
"de": "Gibt es eine Website mit weiteren Informationen über dieses Kunstwerk?",
"it": "Esiste un sito web con maggiori informazioni su questopera?",
"ru": "Есть ли сайт с более подробной информацией об этой работе?",
"ja": "この作品についての詳しい情報はどのウェブサイトにありますか?",

View file

@ -10,7 +10,8 @@
"ja",
"fr",
"zh_Hant",
"nb_NO"
"nb_NO",
"de"
],
"title": {
"en": "Bicycle libraries",
@ -20,7 +21,8 @@
"ja": "自転車ライブラリ",
"fr": "Vélothèques",
"zh_Hant": "單車圖書館",
"nb_NO": "Sykkelbibliotek"
"nb_NO": "Sykkelbibliotek",
"de": "Fahrradbibliothek"
},
"description": {
"nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.",

View file

@ -56,7 +56,7 @@
"tagRenderings": [
{
"render": {
"en": "The power output of this wind turbine is {canonical(generator:output:electricity)}."
"en": "The power output of this wind turbine is {generator:output:electricity}."
},
"question": {
"en": "What is the power output of this wind turbine? (e.g. 2.3 MW)"
@ -79,7 +79,7 @@
},
{
"render": {
"en": "The total height (including rotor radius) of this wind turbine is {canonical(height)}."
"en": "The total height (including rotor radius) of this wind turbine is {height} metres."
},
"question": {
"en": "What is the total height of this wind turbine (including rotor radius), in metres?"
@ -91,7 +91,7 @@
},
{
"render": {
"en": "The rotor diameter of this wind turbine is {canonical(rotor:diameter)}."
"en": "The rotor diameter of this wind turbine is {rotor:diameter} metres."
},
"question": {
"en": "What is the rotor diameter of this wind turbine, in metres?"
@ -129,7 +129,7 @@
}
],
"units": [
{
{
"appliesToKey": [
"generator:output:electricity"
],
@ -183,7 +183,8 @@
},
{
"appliesToKey": [
"height","rotor:diameter"
"height",
"rotor:diameter"
],
"applicableUnits": [
{

View file

@ -87,6 +87,9 @@
"shortDescription": "Eine Karte aller Sitzbänke",
"description": "Diese Karte zeigt alle Sitzbänke, die in OpenStreetMap eingetragen sind: Einzeln stehende Bänke und Bänke, die zu Haltestellen oder Unterständen gehören. Mit einem OpenStreetMap-Account können Sie neue Bänke eintragen oder Detailinformationen existierender Bänke bearbeiten."
},
"bicyclelib": {
"title": "Fahrradbibliothek"
},
"bookcases": {
"title": "Öffentliche Bücherschränke Karte",
"description": "Ein öffentlicher Bücherschrank ist ein kleiner Bücherschrank am Straßenrand, ein Kasten, eine alte Telefonzelle oder andere Gegenstände, in denen Bücher aufbewahrt werden. Jeder kann ein Buch hinstellen oder mitnehmen. Diese Karte zielt darauf ab, all diese Bücherschränke zu sammeln. Sie können neue Bücherschränke in der Nähe entdecken und mit einem kostenlosen OpenStreetMap-Account schnell Ihre Lieblingsbücherschränke hinzufügen."
@ -327,8 +330,5 @@
"toilets": {
"title": "Offene Toilette Karte",
"description": "Eine Karte der öffentlichen Toiletten"
},
"bicyclelib": {
"title": "Fahrradbibliothek"
}
}
}

View file

@ -1143,6 +1143,13 @@
"human": " gigawatts"
}
}
},
"1": {
"applicableUnits": {
"0": {
"human": " meter"
}
}
}
}
},

View file

@ -919,6 +919,13 @@
"human": " gigawatt"
}
}
},
"1": {
"applicableUnits": {
"0": {
"human": " meter"
}
}
}
}
},