Merge develop

This commit is contained in:
Pieter Vander Vennet 2021-07-26 16:59:51 +02:00
commit 0fbde7ec24
71 changed files with 448 additions and 402 deletions

View file

@ -14,6 +14,14 @@ A string, but allows input of longer strings more comfortably (a text area)
A date
## direction
A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)
## length
A geographical length in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma seperated) ], e.g. `["21", "map,photo"]
## wikidata
A wikidata identifier, e.g. Q42
@ -30,10 +38,6 @@ A positive number or zero
A strict positive number
## direction
A geographical direction, in degrees. 0° is north, 90° is east, ... Will return a value between 0 (incl) and 360 (excl)
## float
A decimal

View file

@ -588,6 +588,25 @@
"description": "Layer 'Bike stations (repair, pump or both)' shows manometer=broken with a fixed text, namely 'There is manometer but it is broken' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')",
"value": "broken"
},
{
"key": "level",
"description": "Layer 'Bike stations (repair, pump or both)' shows and asks freeform values for key 'level' (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')"
},
{
"key": "location",
"description": "Layer 'Bike stations (repair, pump or both)' shows location=underground with a fixed text, namely 'Located underground' (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')",
"value": "underground"
},
{
"key": "level",
"description": "Layer 'Bike stations (repair, pump or both)' shows level=0 with a fixed text, namely 'Located on the ground floor' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')",
"value": "0"
},
{
"key": "level",
"description": "Layer 'Bike stations (repair, pump or both)' shows level=1 with a fixed text, namely 'Located on the first floor' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')",
"value": "1"
},
{
"key": "service:bicycle:cleaning:charge",
"description": "Layer 'Bike stations (repair, pump or both)' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Cyclofix - an open map for cyclists')"

View file

@ -0,0 +1,55 @@
{
"data_format": 1,
"project": {
"name": "MapComplete OpenWindPowerMap",
"description": "A map for showing and editing wind turbines",
"project_url": "https://mapcomplete.osm.be/openwindpowermap",
"doc_url": "https://github.com/pietervdvn/MapComplete/tree/master/assets/themes/",
"icon_url": "https://mapcomplete.osm.be/assets/themes/openwindpowermap/wind_turbine.svg",
"contact_name": "Pieter Vander Vennet, Seppe Santens",
"contact_email": "pietervdvn@posteo.net"
},
"tags": [
{
"key": "generator:source",
"description": "The MapComplete theme OpenWindPowerMap has a layer wind turbine showing features with this tag",
"value": "wind"
},
{
"key": "generator:output:electricity",
"description": "Layer 'wind turbine' shows and asks freeform values for key 'generator:output:electricity' (in the MapComplete.osm.be theme 'OpenWindPowerMap')"
},
{
"key": "operator",
"description": "Layer 'wind turbine' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'OpenWindPowerMap')"
},
{
"key": "height",
"description": "Layer 'wind turbine' shows and asks freeform values for key 'height' (in the MapComplete.osm.be theme 'OpenWindPowerMap')"
},
{
"key": "rotor:diameter",
"description": "Layer 'wind turbine' shows and asks freeform values for key 'rotor:diameter' (in the MapComplete.osm.be theme 'OpenWindPowerMap')"
},
{
"key": "start_date",
"description": "Layer 'wind turbine' shows and asks freeform values for key 'start_date' (in the MapComplete.osm.be theme 'OpenWindPowerMap')"
},
{
"key": "image",
"description": "The layer 'wind turbine allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
},
{
"key": "mapillary",
"description": "The layer 'wind turbine allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
},
{
"key": "wikidata",
"description": "The layer 'wind turbine allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
},
{
"key": "wikipedia",
"description": "The layer 'wind turbine allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary"
}
]
}

View file

@ -20,158 +20,138 @@ the URL-parameters are stated in the part between the `?` and the `#`. There are
Finally, the URL-hash is the part after the `#`. It is `node/1234` in this case.
backend
---------
The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default value is _osm_
test
------
If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org The default value is _false_
layout
--------
The layout to load into MapComplete The default value is __
userlayout
------------
If not 'false', a custom (non-official) theme is loaded. This custom layout can be done in multiple ways:
- The hash of the URL contains a base64-encoded .json-file containing the theme definition
- The hash of the URL contains a lz-compressed .json-file, as generated by the custom theme generator
- The parameter itself is an URL, in which case that URL will be downloaded. It should point to a .json of a theme The default value is _false_
layer-control-toggle
layer-control-toggle
----------------------
Whether or not the layer control is shown The default value is _false_
Whether or not the layer control is shown The default value is _false_
tab
tab
-----
The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_
The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >50 changesets) The default value is _0_
z
z
---
The initial/current zoom level The default value is _14_
The initial/current zoom level The default value is _0_
lat
lat
-----
The initial/current latitude The default value is _51.2095_
The initial/current latitude The default value is _0_
lon
lon
-----
The initial/current longitude of the app The default value is _3.2228_
The initial/current longitude of the app The default value is _0_
fs-userbadge
fs-userbadge
--------------
Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_
Disables/Enables the user information pill (userbadge) at the top left. Disabling this disables logging in and thus disables editing all together, effectively putting MapComplete into read-only mode. The default value is _true_
fs-search
fs-search
-----------
Disables/Enables the search bar The default value is _true_
Disables/Enables the search bar The default value is _true_
fs-layers
fs-layers
-----------
Disables/Enables the layer control The default value is _true_
Disables/Enables the layer control The default value is _true_
fs-add-new
fs-add-new
------------
Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default value is _true_
Disables/Enables the 'add new feature'-popup. (A theme without presets might not have it in the first place) The default value is _true_
fs-welcome-message
fs-welcome-message
--------------------
Disables/enables the help menu or welcome message The default value is _true_
Disables/enables the help menu or welcome message The default value is _true_
fs-iframe
fs-iframe
-----------
Disables/Enables the iframe-popup The default value is _false_
Disables/Enables the iframe-popup The default value is _false_
fs-more-quests
fs-more-quests
----------------
Disables/Enables the 'More Quests'-tab in the welcome message The default value is _true_
Disables/Enables the 'More Quests'-tab in the welcome message The default value is _true_
fs-share-screen
fs-share-screen
-----------------
Disables/Enables the 'Share-screen'-tab in the welcome message The default value is _true_
Disables/Enables the 'Share-screen'-tab in the welcome message The default value is _true_
fs-geolocation
fs-geolocation
----------------
Disables/Enables the geolocation button The default value is _true_
Disables/Enables the geolocation button The default value is _true_
fs-all-questions
fs-all-questions
------------------
Always show all questions The default value is _false_
Always show all questions The default value is _false_
fs-export
fs-export
-----------
If set, enables the 'download'-button to download everything as geojson The default value is _false_
If set, enables the 'download'-button to download everything as geojson The default value is _false_
fake-user
test
------
If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org The default value is _false_
fake-user
-----------
If true, 'dryrun' mode is activated and a fake user account is loaded The default value is _false_
If true, 'dryrun' mode is activated and a fake user account is loaded The default value is _false_
debug
debug
-------
If true, shows some extra debugging help such as all the available tags on every object The default value is _false_
If true, shows some extra debugging help such as all the available tags on every object The default value is _false_
custom-css
backend
---------
The OSM backend to use - can be used to redirect mapcomplete to the testing backend when using 'osm-test' The default value is _osm_
custom-css
------------
If specified, the custom css from the given link will be loaded additionaly The default value is __
If specified, the custom css from the given link will be loaded additionaly The default value is __
background
background
------------
The id of the background layer to start with The default value is _osm_
The id of the background layer to start with The default value is _osm_
oauth_token
-------------
Used to complete the login No default value set
layer-<layer-id>
------------------

View file

@ -1,262 +1,265 @@
import * as L from "leaflet";
import { UIEventSource } from "../UIEventSource";
import { Utils } from "../../Utils";
import {UIEventSource} from "../UIEventSource";
import {Utils} from "../../Utils";
import Svg from "../../Svg";
import Img from "../../UI/Base/Img";
import { LocalStorageSource } from "../Web/LocalStorageSource";
import {LocalStorageSource} from "../Web/LocalStorageSource";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
import { VariableUiElement } from "../../UI/Base/VariableUIElement";
import {VariableUiElement} from "../../UI/Base/VariableUIElement";
export default class GeoLocationHandler extends VariableUiElement {
/**
* Wether or not the geolocation is active, aka the user requested the current location
* @private
*/
private readonly _isActive: UIEventSource<boolean>;
/**
* Wether or not the geolocation is active, aka the user requested the current location
* @private
*/
private readonly _isActive: UIEventSource<boolean>;
/**
* Wether or not the geolocation is locked, aka the user requested the current location and wants the crosshair to follow the user
* @private
*/
private readonly _isLocked: UIEventSource<boolean>;
/**
* Wether or not the geolocation is locked, aka the user requested the current location and wants the crosshair to follow the user
* @private
*/
private readonly _isLocked: UIEventSource<boolean>;
/**
* The callback over the permission API
* @private
*/
private readonly _permission: UIEventSource<string>;
/***
* The marker on the map, in order to update it
* @private
*/
private _marker: L.Marker;
/**
* Literally: _currentGPSLocation.data != undefined
* @private
*/
private readonly _hasLocation: UIEventSource<boolean>;
private readonly _currentGPSLocation: UIEventSource<{
latlng: any;
accuracy: number;
}>;
/**
* Kept in order to update the marker
* @private
*/
private readonly _leafletMap: UIEventSource<L.Map>;
/**
* The date when the user requested the geolocation. If we have a location, it'll autozoom to it the first 30 secs
* @private
*/
private _lastUserRequest: Date;
/**
* A small flag on localstorage. If the user previously granted the geolocation, it will be set.
* On firefox, the permissions api is broken (probably fingerprint resistiance) and "granted + don't ask again" doesn't stick between sessions.
*
* Instead, we set this flag. If this flag is set upon loading the page, we start geolocating immediately.
* If the user denies the geolocation this time, we unset this flag
* @private
*/
private readonly _previousLocationGrant: UIEventSource<string>;
private readonly _layoutToUse: UIEventSource<LayoutConfig>;
/**
* The callback over the permission API
* @private
*/
private readonly _permission: UIEventSource<string>;
/***
* The marker on the map, in order to update it
* @private
*/
private _marker: L.Marker;
/**
* Literally: _currentGPSLocation.data != undefined
* @private
*/
private readonly _hasLocation: UIEventSource<boolean>;
private readonly _currentGPSLocation: UIEventSource<{
latlng: any;
accuracy: number;
}>;
/**
* Kept in order to update the marker
* @private
*/
private readonly _leafletMap: UIEventSource<L.Map>;
/**
* The date when the user requested the geolocation. If we have a location, it'll autozoom to it the first 30 secs
* @private
*/
private _lastUserRequest: Date;
/**
* A small flag on localstorage. If the user previously granted the geolocation, it will be set.
* On firefox, the permissions api is broken (probably fingerprint resistiance) and "granted + don't ask again" doesn't stick between sessions.
*
* Instead, we set this flag. If this flag is set upon loading the page, we start geolocating immediately.
* If the user denies the geolocation this time, we unset this flag
* @private
*/
private readonly _previousLocationGrant: UIEventSource<string>;
private readonly _layoutToUse: UIEventSource<LayoutConfig>;
constructor(
currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>,
leafletMap: UIEventSource<L.Map>,
layoutToUse: UIEventSource<LayoutConfig>
) {
const hasLocation = currentGPSLocation.map(
(location) => location !== undefined
);
const previousLocationGrant = LocalStorageSource.Get(
"geolocation-permissions"
);
const isActive = new UIEventSource<boolean>(false);
const isLocked = new UIEventSource<boolean>(false);
super(
hasLocation.map(
(hasLocationData) => {
if (isLocked.data) {
return Svg.crosshair_locked_ui();
} else if (hasLocationData) {
return Svg.crosshair_blue_ui();
} else if (isActive.data) {
return Svg.crosshair_blue_center_ui();
} else {
return Svg.crosshair_ui();
}
},
[isActive, isLocked]
)
);
this._isActive = isActive;
this._isLocked = isLocked;
this._permission = new UIEventSource<string>("");
this._previousLocationGrant = previousLocationGrant;
this._currentGPSLocation = currentGPSLocation;
this._leafletMap = leafletMap;
this._layoutToUse = layoutToUse;
this._hasLocation = hasLocation;
const self = this;
const currentPointer = this._isActive.map(
(isActive) => {
if (isActive && !self._hasLocation.data) {
return "cursor-wait";
}
return "cursor-pointer";
},
[this._hasLocation]
);
currentPointer.addCallbackAndRun((pointerClass) => {
self.SetClass(pointerClass);
});
this.onClick(() => {
if (self._hasLocation.data) {
self._isLocked.setData(!self._isLocked.data);
}
self.init(true);
});
this.init(false);
this._currentGPSLocation.addCallback((location) => {
self._previousLocationGrant.setData("granted");
const timeSinceRequest =
(new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000;
if (timeSinceRequest < 30) {
self.MoveToCurrentLoction(16);
} else if (self._isLocked.data) {
self.MoveToCurrentLoction();
}
let color = "#1111cc";
try {
color = getComputedStyle(document.body).getPropertyValue(
"--catch-detail-color"
);
} catch (e) {
console.error(e);
}
const icon = L.icon({
iconUrl: Img.AsData(Svg.crosshair.replace(/#000000/g, color)),
iconSize: [40, 40], // size of the icon
iconAnchor: [20, 20], // point of the icon which will correspond to marker's location
});
const map = self._leafletMap.data;
const newMarker = L.marker(location.latlng, { icon: icon });
newMarker.addTo(map);
if (self._marker !== undefined) {
map.removeLayer(self._marker);
}
self._marker = newMarker;
});
}
private init(askPermission: boolean) {
const self = this;
if (self._isActive.data) {
self.MoveToCurrentLoction(16);
return;
}
try {
navigator?.permissions
?.query({ name: "geolocation" })
?.then(function (status) {
console.log("Geolocation is already", status);
if (status.state === "granted") {
self.StartGeolocating(false);
}
self._permission.setData(status.state);
status.onchange = function () {
self._permission.setData(status.state);
};
});
} catch (e) {
console.error(e);
}
if (askPermission) {
self.StartGeolocating(true);
} else if (this._previousLocationGrant.data === "granted") {
this._previousLocationGrant.setData("");
self.StartGeolocating(false);
}
}
private MoveToCurrentLoction(targetZoom?: number) {
const location = this._currentGPSLocation.data;
this._lastUserRequest = undefined;
if (
this._currentGPSLocation.data.latlng[0] === 0 &&
this._currentGPSLocation.data.latlng[1] === 0
constructor(
currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>,
leafletMap: UIEventSource<L.Map>,
layoutToUse: UIEventSource<LayoutConfig>
) {
console.debug("Not moving to GPS-location: it is null island");
return;
}
const hasLocation = currentGPSLocation.map(
(location) => location !== undefined
);
const previousLocationGrant = LocalStorageSource.Get(
"geolocation-permissions"
);
const isActive = new UIEventSource<boolean>(false);
const isLocked = new UIEventSource<boolean>(false);
// We check that the GPS location is not out of bounds
const b = this._layoutToUse.data.lockLocation;
let inRange = true;
if (b) {
if (b !== true) {
// B is an array with our locklocation
inRange =
b[0][0] <= location.latlng[0] &&
location.latlng[0] <= b[1][0] &&
b[0][1] <= location.latlng[1] &&
location.latlng[1] <= b[1][1];
}
}
if (!inRange) {
console.log(
"Not zooming to GPS location: out of bounds",
b,
location.latlng
);
} else {
this._leafletMap.data.setView(location.latlng, targetZoom);
}
}
super(
hasLocation.map(
(hasLocationData) => {
if (isLocked.data) {
return Svg.crosshair_locked_ui();
} else if (hasLocationData) {
return Svg.crosshair_blue_ui();
} else if (isActive.data) {
return Svg.crosshair_blue_center_ui();
} else {
return Svg.crosshair_ui();
}
},
[isActive, isLocked]
)
);
this._isActive = isActive;
this._isLocked = isLocked;
this._permission = new UIEventSource<string>("");
this._previousLocationGrant = previousLocationGrant;
this._currentGPSLocation = currentGPSLocation;
this._leafletMap = leafletMap;
this._layoutToUse = layoutToUse;
this._hasLocation = hasLocation;
const self = this;
private StartGeolocating(zoomToGPS = true) {
const self = this;
console.log("Starting geolocation");
this._lastUserRequest = zoomToGPS ? new Date() : new Date(0);
if (self._permission.data === "denied") {
self._previousLocationGrant.setData("");
return "";
}
if (this._currentGPSLocation.data !== undefined) {
this.MoveToCurrentLoction(16);
}
console.log("Searching location using GPS");
if (self._isActive.data) {
return;
}
self._isActive.setData(true);
navigator.geolocation.watchPosition(
function (position) {
self._currentGPSLocation.setData({
latlng: [position.coords.latitude, position.coords.longitude],
accuracy: position.coords.accuracy,
const currentPointer = this._isActive.map(
(isActive) => {
if (isActive && !self._hasLocation.data) {
return "cursor-wait";
}
return "cursor-pointer";
},
[this._hasLocation]
);
currentPointer.addCallbackAndRun((pointerClass) => {
self.SetClass(pointerClass);
});
},
function () {
console.warn("Could not get location with navigator.geolocation");
}
);
}
this.onClick(() => {
if (self._hasLocation.data) {
self._isLocked.setData(!self._isLocked.data);
}
self.init(true);
});
this.init(false);
this._currentGPSLocation.addCallback((location) => {
self._previousLocationGrant.setData("granted");
const timeSinceRequest =
(new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000;
if (timeSinceRequest < 30) {
self.MoveToCurrentLoction(16);
} else if (self._isLocked.data) {
self.MoveToCurrentLoction();
}
let color = "#1111cc";
try {
color = getComputedStyle(document.body).getPropertyValue(
"--catch-detail-color"
);
} catch (e) {
console.error(e);
}
const icon = L.icon({
iconUrl: Img.AsData(Svg.crosshair.replace(/#000000/g, color)),
iconSize: [40, 40], // size of the icon
iconAnchor: [20, 20], // point of the icon which will correspond to marker's location
});
const map = self._leafletMap.data;
const newMarker = L.marker(location.latlng, {icon: icon});
newMarker.addTo(map);
if (self._marker !== undefined) {
map.removeLayer(self._marker);
}
self._marker = newMarker;
});
}
private init(askPermission: boolean) {
const self = this;
if (self._isActive.data) {
self.MoveToCurrentLoction(16);
return;
}
try {
navigator?.permissions
?.query({name: "geolocation"})
?.then(function (status) {
console.log("Geolocation is already", status);
if (status.state === "granted") {
self.StartGeolocating(false);
}
self._permission.setData(status.state);
status.onchange = function () {
self._permission.setData(status.state);
};
});
} catch (e) {
console.error(e);
}
if (askPermission) {
self.StartGeolocating(true);
} else if (this._previousLocationGrant.data === "granted") {
this._previousLocationGrant.setData("");
self.StartGeolocating(false);
}
}
private MoveToCurrentLoction(targetZoom?: number) {
const location = this._currentGPSLocation.data;
this._lastUserRequest = undefined;
if (
this._currentGPSLocation.data.latlng[0] === 0 &&
this._currentGPSLocation.data.latlng[1] === 0
) {
console.debug("Not moving to GPS-location: it is null island");
return;
}
// We check that the GPS location is not out of bounds
const b = this._layoutToUse.data.lockLocation;
let inRange = true;
if (b) {
if (b !== true) {
// B is an array with our locklocation
inRange =
b[0][0] <= location.latlng[0] &&
location.latlng[0] <= b[1][0] &&
b[0][1] <= location.latlng[1] &&
location.latlng[1] <= b[1][1];
}
}
if (!inRange) {
console.log(
"Not zooming to GPS location: out of bounds",
b,
location.latlng
);
} else {
this._leafletMap.data.setView(location.latlng, targetZoom);
}
}
private StartGeolocating(zoomToGPS = true) {
const self = this;
console.log("Starting geolocation");
this._lastUserRequest = zoomToGPS ? new Date() : new Date(0);
if (self._permission.data === "denied") {
self._previousLocationGrant.setData("");
return "";
}
if (this._currentGPSLocation.data !== undefined) {
this.MoveToCurrentLoction(16);
}
console.log("Searching location using GPS");
if (self._isActive.data) {
return;
}
self._isActive.setData(true);
navigator.geolocation.watchPosition(
function (position) {
self._currentGPSLocation.setData({
latlng: [position.coords.latitude, position.coords.longitude],
accuracy: position.coords.accuracy,
});
},
function () {
console.warn("Could not get location with navigator.geolocation");
},
{
enableHighAccuracy: true
}
);
}
}

View file

@ -2,7 +2,7 @@ import { Utils } from "../Utils";
export default class Constants {
public static vNumber = "0.8.4/bike-infra";
public static vNumber = "0.8.4a";
// The user journey states thresholds when a new feature gets unlocked
public static userJourney = {

View file

@ -517,7 +517,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/benches/bench_poi.svg",
"mappings": []

View file

@ -126,7 +126,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/benches/bench_public_transport.svg"
},

View file

@ -210,7 +210,6 @@
},
"description"
],
"hideUnderlayingFeaturesMinPercentage": 1,
"presets": [
{
"title": {

View file

@ -293,7 +293,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/layers/bike_cafe/bike_cafe.svg"
},

View file

@ -63,7 +63,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/layers/bike_monitoring_station/monitoring_station.svg"
},

View file

@ -601,7 +601,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 1,
"presets": [
{
"title": {

View file

@ -56,7 +56,6 @@
"phone",
"opening_hours"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/layers/bike_themed_object/other_services.svg"
},

View file

@ -29,7 +29,6 @@
"tagRenderings": [
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/layers/information_board/board.svg"
},

View file

@ -159,7 +159,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/layers/map/map.svg",
"mappings": [

View file

@ -383,7 +383,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 10,
"wayHandling": 2,
"icon": {
"render": "./assets/themes/buurtnatuur/nature_reserve.svg"

View file

@ -72,7 +72,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:#e6cf39;./assets/layers/picnic_table/picnic_table.svg"
},

View file

@ -87,7 +87,6 @@
"render": "{reviews(name, play_forest)}"
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"hideFromOverview": false,
"icon": {
"render": "./assets/layers/play_forest/icon.svg"

View file

@ -437,7 +437,6 @@
"render": "{reviews(name, playground)}"
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/playgrounds/playground.svg"
},

View file

@ -215,7 +215,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"width": {
"render": "7"
},

View file

@ -383,7 +383,6 @@
"render": "{reviews(name, sportpitch)}"
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/layers/sport_pitch/sport_pitch.svg",
"mappings": [

View file

@ -421,7 +421,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/surveillance_cameras/logo.svg",
"mappings": [

View file

@ -449,7 +449,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:#ffffff;./assets/themes/trees/unknown.svg",
"mappings": [

View file

@ -1,4 +1,12 @@
[
{
"authors": [
"Pieter Vander Vennet"
],
"path": "length-crosshair.svg",
"license": "CC0",
"sources": []
},
{
"authors": [
"Pieter Vander Vennet"

View file

@ -1,5 +1,5 @@
{
"id": "artworks",
"id": "artwork",
"version": "2020-08-30",
"title": {
"en": "Open Artwork Map",
@ -429,4 +429,4 @@
]
}
]
}
}

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 593 KiB

After

Width:  |  Height:  |  Size: 593 KiB

Before After
Before After

View file

@ -521,7 +521,6 @@
"questions",
"reviews"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/themes/campersites/caravan.svg",
"mappings": [
@ -862,7 +861,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/themes/campersites/sanitary_dump_station.svg"
},

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Before After
Before After

View file

@ -307,7 +307,6 @@
]
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "pin:#fff;./assets/themes/charging_stations/plug.svg",
"mappings": [

View file

@ -140,7 +140,6 @@
"phone",
"opening_hours"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/climbing/club.svg"
},
@ -280,7 +279,6 @@
"opening_hours",
"reviews"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/climbing/climbing_gym.svg"
},
@ -471,7 +469,6 @@
},
"reviews"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/themes/climbing/climbing_route.svg"
},
@ -695,7 +692,6 @@
},
"reviews"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/climbing/climbing_no_rope.svg"
},
@ -850,7 +846,6 @@
}
],
"icon": "./assets/themes/climbing/climbing_unknown.svg",
"hideUnderlayingFeaturesMinPercentage": 0,
"width": {
"render": "2"
},

View file

@ -1,5 +1,5 @@
{
"id": "fietsstraten",
"id": "cyclestreets",
"version": "2020-08-30",
"title": {
"nl": "Fietsstraten",
@ -68,7 +68,7 @@
]
},
"then": {
"nl": "Deze straat is een fietsstraat",
"nl": "Deze straat i een fietsstraat",
"en": "This street is a cyclestreet",
"ja": "この通りはcyclestreetだ",
"nb_NO": "Denne gaten er en sykkelvei"
@ -279,4 +279,4 @@
]
}
]
}
}

View file

@ -330,7 +330,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "circle:white;./assets/themes/facadegardens/geveltuin.svg",
"mappings": [

View file

@ -1,5 +1,5 @@
{
"id": "boomgaarden",
"id": "fruit_trees",
"title": {
"nl": "Open Boomgaardenkaart"
},
@ -43,7 +43,6 @@
"tagRenderings": [
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/buurtnatuur/forest.svg"
},
@ -143,7 +142,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/fruit_trees/fruit_tree.svg"
},
@ -172,4 +170,4 @@
}
],
"roamingRenderings": []
}
}

View file

@ -173,7 +173,6 @@
}
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"label": {
"mappings": [
{

View file

@ -258,7 +258,6 @@
},
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/hailhydrant/hydrant.svg"
},
@ -365,7 +364,6 @@
},
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/hailhydrant/Twemoji12_1f9ef.svg"
},
@ -568,7 +566,6 @@
},
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/hailhydrant/Twemoji12_1f692.svg"
},
@ -744,7 +741,6 @@
},
"images"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/hailhydrant/Twemoji_1f691.svg"
},

View file

@ -305,7 +305,6 @@
"questions",
"reviews"
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/shops/shop.svg"
},

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Before After
Before After

View file

@ -147,7 +147,6 @@
"render": "<span style='border: 1px solid black; border-radius: 0.5em; padding: 0.25em;'><b>{_width:needed}m</b> nodig in het totaal</span>"
}
],
"hideUnderlayingFeaturesMinPercentage": 0,
"icon": {
"render": "./assets/themes/widths/icon.svg"
},

View file

@ -56,7 +56,7 @@
"loginWithOpenStreetMap": "Login with OpenStreetMap",
"welcomeBack": "You are logged in, welcome back!",
"loginToStart": "Login to answer this question",
"openStreetMapIntro": "<h3>An Open Map</h3><p>Wouldn't it be cool if there was a single map, which everyone could freely use and edit? A single place to store all geo-information? Then, all those websites with different, small and incompatible maps (which are always outdated) wouldn't be needed anymore.</p><p><b><a href='https://OpenStreetMap.org' target='_blank'>OpenStreetMap</a></b> is this map. The map data can be used for free (with <a href='https://osm.org/copyright' target='_blank'>attribution and publication of changes to that data</a>). On top of that, everyone can freely add new data and fix errors. This website uses OpenStreetMap as well. All the data is from there, and your answers and corrections are added there as well.</p><p>A ton of people and application already use OpenStreetMap: <a href='https://maps.me/' target='_blank'>Maps.me</a>, <a href='https://osmAnd.net' target='_blank'>OsmAnd</a>, but also the maps at Facebook, Instagram, Apple-maps and Bing-maps are (partly) powered by OpenStreetMap. If you change something here, it'll be reflected in those applications too - after their next update!</p>",
"openStreetMapIntro": "<h3>An Open Map</h3><p>Wouldn't it be cool if there was a single map, which everyone could freely use and edit? A single place to store all geo-information? Then, all those websites with different, small and incompatible maps (which are always outdated) wouldn't be needed anymore.</p><p><b><a href='https://OpenStreetMap.org' target='_blank'>OpenStreetMap</a></b> is this map. The map data can be used for free (with <a href='https://osm.org/copyright' target='_blank'>attribution and publication of changes to that data</a>). On top of that, everyone can freely add new data and fix errors. This website uses OpenStreetMap as well. All the data is from there, and your answers and corrections are added there as well.</p><p>A ton of people and application already use OpenStreetMap: <a href='https://organicmaps.app/' target='_blank'>Organic Maps</a>, <a href='https://osmAnd.net' target='_blank'>OsmAnd</a>, but also the maps at Facebook, Instagram, Apple-maps and Bing-maps are (partly) powered by OpenStreetMap. If you change something here, it'll be reflected in those applications too - after their next update!</p>",
"search": {
"search": "Search a location",
"searching": "Searching…",

View file

@ -126,7 +126,7 @@
"goToInbox": "受信トレイを開く",
"fewChangesBefore": "新しいポイントを追加する前に、既存のポイントに関するいくつかの質問に答えてください。",
"readYourMessages": "新しいポイントを追加する前に、OpenStreetMapのメッセージをすべて読んでください。",
"openStreetMapIntro": "<h3>オープン地図</h3><p>誰もが自由に使用して編集できる1つのマップがあればクールではないでしょうか?すべての地理情報を格納するための単一の場所?そうすれば、異なる、小さくて互換性のない地図(常に時代遅れのもの)を持つウェブサイトは、必要なくなるでしょう。</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">OpenStreetMap</a></b>こそが地図です。地図データは、(<a href=\"https://osm.org/copyright\" target=\"_blank\">データ変更の公開と帰属表示</a>をすれば)無料で利用できます。さらに、誰でも自由に新しいデータを追加したり、間違いを修正したりすることができます。このサイトでもOpenStreetMapを使っています。すべてのデータは、OSMからのものであり、あなたの答えと訂正もOSMに追加されます。</p><p>すでに多くの人やアプリケーションがOpenStreetMapを使っています:<a href=\"https://maps.me/\" target=\"_blank\">Maps.me</a>や、<a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>など。Fさらに、acebook、Instagram、Apple-maps、Bing-mapsも(部分的に)OpenStreetMapを利用しています。ここで何かを変更すると、次の更新後にアプリケーションにも反映されます。</p>",
"openStreetMapIntro": "<h3>オープン地図</h3><p>誰もが自由に使用して編集できる1つのマップがあればクールではないでしょうか?すべての地理情報を格納するための単一の場所?そうすれば、異なる、小さくて互換性のない地図(常に時代遅れのもの)を持つウェブサイトは、必要なくなるでしょう。</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">OpenStreetMap</a></b>こそが地図です。地図データは、(<a href=\"https://osm.org/copyright\" target=\"_blank\">データ変更の公開と帰属表示</a>をすれば)無料で利用できます。さらに、誰でも自由に新しいデータを追加したり、間違いを修正したりすることができます。このサイトでもOpenStreetMapを使っています。すべてのデータは、OSMからのものであり、あなたの答えと訂正もOSMに追加されます。</p><p>すでに多くの人やアプリケーションがOpenStreetMapを使っています:<a href=\"https://organicmaps.app//\" target=\"_blank\">Maps.me</a>や、<a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>など。Fさらに、acebook、Instagram、Apple-maps、Bing-mapsも(部分的に)OpenStreetMapを利用しています。ここで何かを変更すると、次の更新後にアプリケーションにも反映されます。</p>",
"noNameCategory": "名前のない {category}",
"pickLanguage": "言語を選択します: ",
"number": "number",

View file

@ -69,7 +69,7 @@
"emailOf": "Wat is het email-adres van {category}?",
"emailIs": "Het email-adres van {category} is <a href='mailto:{email}' target='_blank'>{email}</a>"
},
"openStreetMapIntro": "<h3>Een open kaart</h3><p>Zou het niet fantastisch zijn als er een open kaart zou zijn die door iedereen aangepast én gebruikt kan worden? Een kaart waar iedereen zijn interesses aan zou kunnen toevoegen? Dan zouden er geen duizend-en-één verschillende kleine kaartjes, websites, ... meer nodig zijn</p><p><b><a href='https://OpenStreetMap.org' target='_blank'>OpenStreetMap</a></b> is deze open kaart. Je mag de kaartdata gratis gebruiken (mits <a href='https://osm.org/copyright' target='_blank'>bronvermelding en herpublicatie van aanpassingen</a>). Daarenboven mag je de kaart ook gratis aanpassen als je een account maakt. Ook deze website is gebaseerd op OpenStreetMap. Als je hier een vraag beantwoord, gaat het antwoord daar ook naartoe</p><p>Tenslotte zijn er reeds vele gebruikers van OpenStreetMap. Denk maar <a href='https://maps.me/' target='_blank'>Maps.me</a>, <a href='https://osmAnd.net' target='_blank'>OsmAnd</a>, verschillende gespecialiseerde routeplanners, de achtergrondkaarten op Facebook, Instagram,...<br/>Zelfs Apple Maps en Bing-Maps gebruiken OpenStreetMap in hun kaarten!</p></p><p>Kortom, als je hier een punt toevoegd of een vraag beantwoord, zal dat na een tijdje ook in al dié applicaties te zien zijn.</p>",
"openStreetMapIntro": "<h3>Een open kaart</h3><p>Zou het niet fantastisch zijn als er een open kaart zou zijn die door iedereen aangepast én gebruikt kan worden? Een kaart waar iedereen zijn interesses aan zou kunnen toevoegen? Dan zouden er geen duizend-en-één verschillende kleine kaartjes, websites, ... meer nodig zijn</p><p><b><a href='https://OpenStreetMap.org' target='_blank'>OpenStreetMap</a></b> is deze open kaart. Je mag de kaartdata gratis gebruiken (mits <a href='https://osm.org/copyright' target='_blank'>bronvermelding en herpublicatie van aanpassingen</a>). Daarenboven mag je de kaart ook gratis aanpassen als je een account maakt. Ook deze website is gebaseerd op OpenStreetMap. Als je hier een vraag beantwoord, gaat het antwoord daar ook naartoe</p><p>Tenslotte zijn er reeds vele gebruikers van OpenStreetMap. Denk maar <a href='https://organicmaps.app//' target='_blank'>Organic Maps</a>, <a href='https://osmAnd.net' target='_blank'>OsmAnd</a>, verschillende gespecialiseerde routeplanners, de achtergrondkaarten op Facebook, Instagram,...<br/>Zelfs Apple Maps en Bing-Maps gebruiken OpenStreetMap in hun kaarten!</p></p><p>Kortom, als je hier een punt toevoegd of een vraag beantwoord, zal dat na een tijdje ook in al dié applicaties te zien zijn.</p>",
"attribution": {
"attributionTitle": "Met dank aan",
"attributionContent": "<p>Alle data is voorzien door <a href='https://osm.org' target='_blank'>OpenStreetMap</a>, gratis en vrij te hergebruiken onder <a href='https://osm.org/copyright' target='_blank'>de Open DataBase Licentie</a>.</p>",

View file

@ -121,7 +121,7 @@
"attributionContent": "<p>Все данные предоставлены <a href=\"https://osm.org\" target=\"_blank\">OpenStreetMap</a>, свободное повторное использование согласно <a href=\"https://osm.org/copyright\" target=\"_blank\">Open DataBase License</a>.</p>",
"attributionTitle": "Уведомление об авторстве"
},
"openStreetMapIntro": "<h3>Свободная карта</h3><p>Было бы здорово если бы была одна карта, которую каждый может свободно использовать и редактировать? Использовать как общее хранилище для всей гео-информации? Тогда, все сайты с разной, неполной и несовместимой информацией (которая обычно устарела) будут больше не нужны.</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">OpenStreetMap</a></b> такая карта. Данные карты могу быть свободно использованы (с <a href=\"https://osm.org/copyright\" target=\"_blank\">аннотацией и публикацией изменений к данным</a>). Более того, каждый может свободно добавлять информацию и исправлять ошибки. Этот сайт также использует OpenStreetMap. Все данные берутся оттуда, а ваши ответы и исправления отправляются обратно туда.</p><p>Огромное количество людей уже использует OpenStreetMap: <a href=\"https://maps.me/\" target=\"_blank\">Maps.me</a>, <a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>, а также карты в Facebook, Instagram, Apple-карты и Bing-карты (частично) используют OpenStreetMap. Если вы что-то измените здесь, это также будет отражено в этих приложениях - после их следующего обновления!</p>"
"openStreetMapIntro": "<h3>Свободная карта</h3><p>Было бы здорово если бы была одна карта, которую каждый может свободно использовать и редактировать? Использовать как общее хранилище для всей гео-информации? Тогда, все сайты с разной, неполной и несовместимой информацией (которая обычно устарела) будут больше не нужны.</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">OpenStreetMap</a></b> такая карта. Данные карты могу быть свободно использованы (с <a href=\"https://osm.org/copyright\" target=\"_blank\">аннотацией и публикацией изменений к данным</a>). Более того, каждый может свободно добавлять информацию и исправлять ошибки. Этот сайт также использует OpenStreetMap. Все данные берутся оттуда, а ваши ответы и исправления отправляются обратно туда.</p><p>Огромное количество людей уже использует OpenStreetMap: <a href=\"https://organicmaps.app//\" target=\"_blank\">Organic Maps</a>, <a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>, а также карты в Facebook, Instagram, Apple-карты и Bing-карты (частично) используют OpenStreetMap. Если вы что-то измените здесь, это также будет отражено в этих приложениях - после их следующего обновления!</p>"
},
"index": {
"pickTheme": "Выберите тему ниже, чтобы начать.",

View file

@ -3,7 +3,7 @@
"title": "AED-Karte öffnen",
"description": "Auf dieser Karte kann man nahe gelegene Defibrillatoren finden und markieren"
},
"artworks": {
"artwork": {
"title": "Freie Kunstwerk-Karte",
"description": "Willkommen bei der Freien Kunstwerk-Karte, einer Karte von Statuen, Büsten, Grafitti, ... auf der ganzen Welt",
"layers": {

View file

@ -3,7 +3,7 @@
"title": "Open AED Map",
"description": "On this map, one can find and mark nearby defibrillators"
},
"artworks": {
"artwork": {
"title": "Open Artwork Map",
"description": "Welcome to Open Artwork Map, a map of statues, busts, grafittis and other artwork all over the world",
"layers": {
@ -1174,7 +1174,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"title": "Cyclestreets",
"shortDescription": "A map of cyclestreets",
"description": "A cyclestreet is is a street where <b>motorized traffic is not allowed to overtake cyclists</b>. They are signposted by a special traffic sign. Cyclestreets can be found in the Netherlands and Belgium, but also in Germany and France. ",

View file

@ -3,7 +3,7 @@
"title": "Mapa abierto de desfibriladores (DEA)",
"description": "En este mapa , cualquiera puede encontrar y marcar los desfibriladores externos automáticos más cercanos"
},
"artworks": {
"artwork": {
"description": "Bienvenido a Open Artwork Map, un mapa de estatuas, bustos, grafitis y otras obras de arte de todo el mundo",
"layers": {
"0": {

View file

@ -3,7 +3,7 @@
"title": "Carte des défibrillateurs (DAE)",
"description": "Sur cette carte, vous pouvez trouver et améliorer les informations sur les défibrillateurs"
},
"artworks": {
"artwork": {
"title": "Carte ouverte des œuvres d'art",
"description": "Bienvenue sur la carte ouverte des œuvres d'art, une carte des statues, fresques, ... du monde entier",
"layers": {

View file

@ -2,7 +2,7 @@
"aed": {
"title": "Nyílt AED Térkép"
},
"artworks": {
"artwork": {
"title": "Nyít Műalkotás Térkép"
}
}

View file

@ -3,7 +3,7 @@
"title": "Buka Peta AED",
"description": "Di peta ini, seseorang dapat menemukan dan menandai defibrillator terdekat"
},
"artworks": {
"artwork": {
"title": "Buka Peta Karya Seni",
"description": "Selamat datang di Open Artwork Map, peta untuk patung, grafiti, dan karya seni lain di seluruh dunia",
"layers": {

View file

@ -3,7 +3,7 @@
"title": "Mappa dei defibrillatori (DAE)",
"description": "Su questa mappa puoi trovare e segnalare i defibrillatori nelle vicinanze"
},
"artworks": {
"artwork": {
"title": "Mappa libera delle opere d'arte",
"description": "Benvenuto/a sulla mappa libera dellarte, una mappa delle statue, i busti, i graffiti e le altre realizzazioni artistiche di tutto il mondo",
"layers": {
@ -396,7 +396,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"roamingRenderings": {
"0": {
"mappings": {

View file

@ -3,7 +3,7 @@
"title": "オープンAEDマップ",
"description": "この地図では近くにある除細動器(AED)を見つけてマークします"
},
"artworks": {
"artwork": {
"title": "オープン アートワーク マップ",
"description": "オープン アートワーク マップへようこそ。世界中の銅像や胸像、壁の落書きなどのアートワークの地図です",
"layers": {
@ -583,7 +583,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"title": "Cyclestreets",
"shortDescription": "cyclestreetsの地図",
"description": "cyclestreetとは、<b>自動車がサイクリストを追い越すことができない</b>道です。専用の道路標識で表示されます。Cyclestreetsはオランダやベルギーにもありますが、ドイツやフランスにもあります。 ",

View file

@ -2,7 +2,7 @@
"aed": {
"title": "Åpne AED-kart"
},
"artworks": {
"artwork": {
"layers": {
"0": {
"name": "Kunstverk",
@ -213,7 +213,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"shortDescription": "Et kart over sykkelveier",
"roamingRenderings": {
"0": {

View file

@ -7,7 +7,7 @@
"title": "Open AED-kaart - Brugge edition",
"description": "Op deze kaart kan je informatie over AEDs vinden en verbeteren + een export van de brugse defibrillatoren"
},
"artworks": {
"artwork": {
"title": "Kunstwerkenkaart",
"description": "Welkom op de Open Kunstwerken Kaart",
"layers": {
@ -995,7 +995,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"title": "Fietsstraten",
"shortDescription": "Een kaart met alle gekende fietsstraten",
"description": "Een fietsstraat is een straat waar <ul><li><b>automobilisten geen fietsers mogen inhalen</b></li><li>Er een maximumsnelheid van <b>30km/u</b> geldt</li><li>Fietsers gemotoriseerde voortuigen links mogen inhalen</li><li>Fietsers nog steeds voorrang aan rechts moeten verlenen - ook aan auto's en voetgangers op het zebrapad</li></ul><br/><br/>Op deze open kaart kan je alle gekende fietsstraten zien en kan je ontbrekende fietsstraten aanduiden. Om de kaart aan te passen, moet je je aanmelden met OpenStreetMap en helemaal inzoomen tot straatniveau.",
@ -1007,7 +1007,7 @@
"then": "Deze straat is een fietsstraat (en dus zone 30)"
},
"1": {
"then": "Deze straat is een fietsstraat"
"then": "Deze straat i een fietsstraat"
},
"2": {
"then": "Deze straat wordt binnenkort een fietsstraat"
@ -1235,7 +1235,7 @@
}
}
},
"boomgaarden": {
"fruit_trees": {
"title": "Open Boomgaardenkaart",
"shortDescription": "Boomgaarden en fruitbomen",
"description": "Op deze kaart vindt je boomgaarden en fruitbomen",

View file

@ -3,7 +3,7 @@
"title": "Открытая карта АВД (Автоматизированных внешних дефибрилляторов)",
"description": "На этой карте вы можете найти и отметить ближайшие дефибрилляторы"
},
"artworks": {
"artwork": {
"title": "Открытая карта произведений искусства",
"description": "Добро пожаловать на Open Artwork Map, карту статуй, бюстов, граффити и других произведений искусства по всему миру",
"layers": {
@ -407,7 +407,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"layers": {
"2": {
"name": "Все улицы",

View file

@ -3,7 +3,7 @@
"title": "Öppna AED-karta",
"description": "På denna karta kan man hitta och markera närliggande defibrillatorer"
},
"artworks": {
"artwork": {
"title": "Öppen konstverkskarta"
}
}

View file

@ -3,7 +3,7 @@
"title": "開放AED地圖",
"description": "在這份地圖上,你可以找到與標記附近的除顫器"
},
"artworks": {
"artwork": {
"title": "開放藝術品地圖",
"description": "歡迎來到開放藝術品地圖,這份地圖會顯示全世界的雕像、半身像、塗鴉以及其他類型的藝術品",
"layers": {
@ -294,7 +294,7 @@
}
}
},
"fietsstraten": {
"cyclestreets": {
"title": "單車街道",
"shortDescription": "單車街道的地圖",
"description": "單車街道是<b>機動車輛受限制,只允許單車通行</b>的道路。通常會有路標顯示特別的交通指標。單車街道通常在荷蘭、比利時看到,但德國與法國也有。 ",

View file

@ -101,7 +101,7 @@
"attributionContent": "<p>所有資料由<a href=\"https://osm.org\" target=\"_blank\">開放街圖</a>提供,在<a href=\"https://osm.org/copyright\" target=\"_blank\">開放資料庫授權條款</a>之下自由再利用。</p>",
"attributionTitle": "署名通知"
},
"openStreetMapIntro": "<h3>開放的地圖</h3><p>如果有一份地圖,任何人都能自由使用與編輯,單一的地圖能夠儲存所有地理相關資訊?這樣不就很酷嗎?接著,所有的網站使用不同的、範圍小的,不相容的地圖 (通常也都過時了),也就不再需要了。</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">開放街圖</a></b>就是這樣的地圖,人人都能免費這些圖資 (只要<a href=\"https://osm.org/copyright\" target=\"_blank\">署名與公開變動這資料</a>)。只要遵循這些,任何人都能自由新增新資料與修正錯誤,這些網站也都使用開放街圖,資料也都來自開放街圖,你的答案與修正也會加到開放街圖上面。</p><p>許多人與應用程式已經採用開放街圖了:<a href=\"https://maps.me/\" target=\"_blank\">Maps.me</a>、<a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>,還有 Facebook、Instagram蘋果地圖、Bing 地圖(部分)採用開放街圖。如果你在開放街圖上變動資料,也會同時影響這些應用 - 在他們下次更新資料之後!</p>",
"openStreetMapIntro": "<h3>開放的地圖</h3><p>如果有一份地圖,任何人都能自由使用與編輯,單一的地圖能夠儲存所有地理相關資訊?這樣不就很酷嗎?接著,所有的網站使用不同的、範圍小的,不相容的地圖 (通常也都過時了),也就不再需要了。</p><p><b><a href=\"https://OpenStreetMap.org\" target=\"_blank\">開放街圖</a></b>就是這樣的地圖,人人都能免費這些圖資 (只要<a href=\"https://osm.org/copyright\" target=\"_blank\">署名與公開變動這資料</a>)。只要遵循這些,任何人都能自由新增新資料與修正錯誤,這些網站也都使用開放街圖,資料也都來自開放街圖,你的答案與修正也會加到開放街圖上面。</p><p>許多人與應用程式已經採用開放街圖了:<a href=\"https://organicmaps.app//\" target=\"_blank\">Organic Maps</a>、<a href=\"https://osmAnd.net\" target=\"_blank\">OsmAnd</a>,還有 Facebook、Instagram蘋果地圖、Bing 地圖(部分)採用開放街圖。如果你在開放街圖上變動資料,也會同時影響這些應用 - 在他們下次更新資料之後!</p>",
"questions": {
"emailIs": "{category} 的電子郵件地址是<a href=\"mailto:{email}\" target=\"_blank\">{email}</a>",
"emailOf": "{category} 的電子郵件地址是?",

View file

@ -56,6 +56,10 @@ class LayerOverviewUtils {
if (path != undefined && path.indexOf(expected) < 0) {
errorCount.push("Layer is in an incorrect place. The path is " + path + ", but expected " + expected)
}
if(layerJson["hideUnderlayingFeaturesMinPercentage"] !== undefined){
errorCount.push("Layer "+layer.id+" contains an old 'hideUnderlayingFeaturesMinPercentage'")
}
for (const image of images) {
if (image.indexOf("{") >= 0) {
@ -78,9 +82,8 @@ class LayerOverviewUtils {
main(args: string[]) {
const lt = this.loadThemesAndLayers();
const layerFiles = lt.layers;
const themeFiles = lt.themes;
const layerFiles = ScriptUtils.getLayerFiles();
const themeFiles = ScriptUtils.getThemeFiles();
console.log(" ---------- VALIDATING ---------")
const licensePaths = []
@ -98,7 +101,9 @@ class LayerOverviewUtils {
}
let themeErrorCount = []
for (const themeFile of themeFiles) {
for (const themeInfo of themeFiles) {
const themeFile = themeInfo.parsed
const themePath = themeInfo.path
if (typeof themeFile.language === "string") {
themeErrorCount.push("The theme " + themeFile.id + " has a string as language. Please use a list of strings")
}
@ -108,12 +113,13 @@ class LayerOverviewUtils {
themeErrorCount.push(`Unknown layer id: ${layer} in theme ${themeFile.id}`)
}
} else {
if (layer.builtin !== undefined) {
if (!knownLayerIds.has(layer.builtin)) {
themeErrorCount.push("Unknown layer id: " + layer.builtin + "(which uses inheritance)")
if (layer["builtin"] !== undefined) {
if (!knownLayerIds.has(layer["builtin"])) {
themeErrorCount.push("Unknown layer id: " + layer["builtin"] + "(which uses inheritance)")
}
} else {
// layer.builtin contains layer overrides - we can skip those
// @ts-ignore
layerErrorCount.push(...this.validateLayer(layer, undefined, knownPaths, themeFile.id))
}
}
@ -121,7 +127,7 @@ class LayerOverviewUtils {
themeFile.layers = themeFile.layers
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
.filter(l => l.builtin === undefined)
.filter(l => l["builtin"] === undefined)
try {
@ -129,6 +135,12 @@ class LayerOverviewUtils {
if (theme.id !== theme.id.toLowerCase()) {
themeErrorCount.push("Theme ids should be in lowercase, but it is " + theme.id)
}
let filename = themePath.substring(themePath.lastIndexOf("/") + 1, themePath.length - 5)
if(theme.id !== filename){
themeErrorCount.push("Theme ids should be the same as the name.json, but we got id: " + theme.id + " and filename "+filename+" ("+themePath+")")
}
} catch (e) {
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)
}