forked from MapComplete/MapComplete
Better handling of GPX-state
This commit is contained in:
parent
519feaa54b
commit
a37a7462a2
17 changed files with 585 additions and 412 deletions
|
@ -19,12 +19,12 @@ export default class AllKnownLayers {
|
|||
public static sharedLayersJson: Map<string, any> = AllKnownLayers.getSharedLayersJson();
|
||||
|
||||
|
||||
public static added_by_default: string[] = ["gps_location", "home_location", "gps_track"]
|
||||
public static added_by_default: string[] = ["gps_location","gps_location_history", "home_location", "gps_track",]
|
||||
public static no_include: string[] = [ "conflation", "left_right_style"]
|
||||
/**
|
||||
* Layer IDs of layers which have special properties through built-in hooks
|
||||
*/
|
||||
public static priviliged_layers: string[] = [...AllKnownLayers.added_by_default, "type_node",...AllKnownLayers.no_include]
|
||||
public static priviliged_layers: string[] = [...AllKnownLayers.added_by_default, "type_node",...AllKnownLayers.no_include]
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
|
|||
* Makes sure the hash shows the selected element and vice-versa.
|
||||
*/
|
||||
export default class SelectedFeatureHandler {
|
||||
private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "filters", "", undefined])
|
||||
private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "filters", "location_track", "", undefined])
|
||||
private readonly hash: UIEventSource<string>;
|
||||
private readonly state: {
|
||||
selectedElement: UIEventSource<any>,
|
||||
|
|
|
@ -5,11 +5,9 @@ import FeatureSource, {FeatureSourceForLayer, IndexedFeatureSource, Tiled} from
|
|||
import TiledFeatureSource from "./TiledFeatureSource/TiledFeatureSource";
|
||||
import {UIEventSource} from "../UIEventSource";
|
||||
import {TileHierarchyTools} from "./TiledFeatureSource/TileHierarchy";
|
||||
import FilteredLayer from "../../Models/FilteredLayer";
|
||||
import MetaTagging from "../MetaTagging";
|
||||
import RememberingSource from "./Sources/RememberingSource";
|
||||
import OverpassFeatureSource from "../Actors/OverpassFeatureSource";
|
||||
import {Changes} from "../Osm/Changes";
|
||||
import GeoJsonSource from "./Sources/GeoJsonSource";
|
||||
import Loc from "../../Models/Loc";
|
||||
import RegisteringAllFromFeatureSourceActor from "./Actors/RegisteringAllFromFeatureSourceActor";
|
||||
|
@ -22,11 +20,10 @@ import {NewGeometryFromChangesFeatureSource} from "./Sources/NewGeometryFromChan
|
|||
import ChangeGeometryApplicator from "./Sources/ChangeGeometryApplicator";
|
||||
import {BBox} from "../BBox";
|
||||
import OsmFeatureSource from "./TiledFeatureSource/OsmFeatureSource";
|
||||
import {OsmConnection} from "../Osm/OsmConnection";
|
||||
import {Tiles} from "../../Models/TileRange";
|
||||
import TileFreshnessCalculator from "./TileFreshnessCalculator";
|
||||
import {ElementStorage} from "../ElementStorage";
|
||||
import FullNodeDatabaseSource from "./TiledFeatureSource/FullNodeDatabaseSource";
|
||||
import MapState from "../State/MapState";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -51,19 +48,7 @@ export default class FeaturePipeline {
|
|||
public readonly newDataLoadedSignal: UIEventSource<FeatureSource> = new UIEventSource<FeatureSource>(undefined)
|
||||
|
||||
private readonly overpassUpdater: OverpassFeatureSource
|
||||
private state: {
|
||||
readonly filteredLayers: UIEventSource<FilteredLayer[]>,
|
||||
readonly locationControl: UIEventSource<Loc>,
|
||||
readonly selectedElement: UIEventSource<any>,
|
||||
readonly changes: Changes,
|
||||
readonly layoutToUse: LayoutConfig,
|
||||
readonly leafletMap: any,
|
||||
readonly overpassUrl: UIEventSource<string[]>;
|
||||
readonly overpassTimeout: UIEventSource<number>;
|
||||
readonly overpassMaxZoom: UIEventSource<number>;
|
||||
readonly osmConnection: OsmConnection
|
||||
readonly currentBounds: UIEventSource<BBox>
|
||||
};
|
||||
private state: MapState;
|
||||
private readonly relationTracker: RelationsTracker
|
||||
private readonly perLayerHierarchy: Map<string, TileHierarchyMerger>;
|
||||
|
||||
|
@ -74,24 +59,7 @@ export default class FeaturePipeline {
|
|||
|
||||
constructor(
|
||||
handleFeatureSource: (source: FeatureSourceForLayer & Tiled) => void,
|
||||
state: {
|
||||
readonly historicalUserLocations: FeatureSourceForLayer & Tiled;
|
||||
readonly homeLocation: FeatureSourceForLayer & Tiled;
|
||||
readonly currentUserLocation: FeatureSourceForLayer & Tiled;
|
||||
readonly filteredLayers: UIEventSource<FilteredLayer[]>,
|
||||
readonly locationControl: UIEventSource<Loc>,
|
||||
readonly selectedElement: UIEventSource<any>,
|
||||
readonly changes: Changes,
|
||||
readonly layoutToUse: LayoutConfig,
|
||||
readonly leafletMap: any,
|
||||
readonly overpassUrl: UIEventSource<string[]>;
|
||||
readonly overpassTimeout: UIEventSource<number>;
|
||||
readonly overpassMaxZoom: UIEventSource<number>;
|
||||
readonly osmConnection: OsmConnection
|
||||
readonly currentBounds: UIEventSource<BBox>,
|
||||
readonly osmApiTileSize: UIEventSource<number>,
|
||||
readonly allElements: ElementStorage
|
||||
}) {
|
||||
state: MapState) {
|
||||
this.state = state;
|
||||
|
||||
const self = this
|
||||
|
@ -138,7 +106,7 @@ export default class FeaturePipeline {
|
|||
handleFeatureSource(srcFiltered)
|
||||
self.somethingLoaded.setData(true)
|
||||
// We do not mark as visited here, this is the responsability of the code near the actual loader (e.g. overpassLoader and OSMApiFeatureLoader)
|
||||
};
|
||||
}
|
||||
|
||||
function handlePriviligedFeatureSource(src: FeatureSourceForLayer & Tiled){
|
||||
// Passthrough to passed function, except that it registers as well
|
||||
|
@ -168,11 +136,16 @@ export default class FeaturePipeline {
|
|||
continue
|
||||
}
|
||||
|
||||
if (id === "gps_track") {
|
||||
if (id === "gps_location_history") {
|
||||
handlePriviligedFeatureSource(state.historicalUserLocations)
|
||||
continue
|
||||
}
|
||||
|
||||
if (id === "gps_track") {
|
||||
handlePriviligedFeatureSource(state.historicalUserLocationsTrack)
|
||||
continue
|
||||
}
|
||||
|
||||
if (id === "home_location") {
|
||||
handlePriviligedFeatureSource(state.homeLocation)
|
||||
continue
|
||||
|
|
|
@ -16,6 +16,8 @@ import FilterConfig from "../../Models/ThemeConfig/FilterConfig";
|
|||
import ShowOverlayLayer from "../../UI/ShowDataLayer/ShowOverlayLayer";
|
||||
import {FeatureSourceForLayer, Tiled} from "../FeatureSource/FeatureSource";
|
||||
import SimpleFeatureSource from "../FeatureSource/Sources/SimpleFeatureSource";
|
||||
import {LocalStorageSource} from "../Web/LocalStorageSource";
|
||||
import {GeoOperations} from "../GeoOperations";
|
||||
|
||||
/**
|
||||
* Contains all the leaflet-map related state
|
||||
|
@ -52,6 +54,11 @@ export default class MapState extends UserRelatedState {
|
|||
* All previously visited points
|
||||
*/
|
||||
public historicalUserLocations: FeatureSourceForLayer & Tiled;
|
||||
/**
|
||||
* The number of seconds that the GPS-locations are stored in memory
|
||||
*/
|
||||
public gpsLocationHistoryRetentionTime = new UIEventSource(7 * 24 * 60 * 60, "gps_location_retention" )
|
||||
public historicalUserLocationsTrack: FeatureSourceForLayer & Tiled;
|
||||
|
||||
/**
|
||||
* A feature source containing the current home location of the user
|
||||
|
@ -70,7 +77,7 @@ export default class MapState extends UserRelatedState {
|
|||
*/
|
||||
public overlayToggles: { config: TilesourceConfig, isDisplayed: UIEventSource<boolean> }[]
|
||||
|
||||
|
||||
|
||||
constructor(layoutToUse: LayoutConfig) {
|
||||
super(layoutToUse);
|
||||
|
||||
|
@ -188,42 +195,75 @@ export default class MapState extends UserRelatedState {
|
|||
}
|
||||
|
||||
private initUserLocationTrail(){
|
||||
const histCoordinates = []
|
||||
let lineFeature = {
|
||||
type:"Feature",
|
||||
geometry:{
|
||||
type: "LineString",
|
||||
coordinates: histCoordinates
|
||||
},
|
||||
properties:{
|
||||
"user:location":"yes",
|
||||
"id":"gps_track"
|
||||
}
|
||||
}
|
||||
const features = new UIEventSource<{feature: any, freshness: Date}[]>([], "gps_track")
|
||||
const features = LocalStorageSource.GetParsed<{feature: any, freshness: Date}[]>("gps_location_history", [])
|
||||
const now = new Date().getTime()
|
||||
features.data = features.data
|
||||
.map(ff => ({feature: ff.feature, freshness: new Date(ff.freshness)}))
|
||||
.filter(ff => (now - ff.freshness.getTime()) < this.gpsLocationHistoryRetentionTime.data)
|
||||
features.ping()
|
||||
const self = this;
|
||||
let i = 0
|
||||
this.currentUserLocation.features.addCallbackAndRunD(([location]) => {
|
||||
if(location === undefined){
|
||||
return;
|
||||
}
|
||||
const feature = JSON.parse(JSON.stringify(location.feature))
|
||||
feature.properties.id = "gps/"+i
|
||||
i++
|
||||
features.data.push({feature, freshness: new Date()})
|
||||
histCoordinates.push(feature.geometry.coordinates)
|
||||
|
||||
if(lineFeature !== undefined && lineFeature.geometry.coordinates.length >= 2){
|
||||
features.data.push({feature: lineFeature, freshness: new Date()})
|
||||
lineFeature = undefined
|
||||
const previousLocation = features.data[features.data.length - 1]
|
||||
if(previousLocation !== undefined){
|
||||
const d = GeoOperations.distanceBetween(
|
||||
previousLocation.feature.geometry.coordinates,
|
||||
location.feature.geometry.coordinates
|
||||
|
||||
)
|
||||
if(d < 20){
|
||||
// Do not append changes less then 20m - it's probably noise anyway
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const feature = JSON.parse(JSON.stringify(location.feature))
|
||||
feature.properties.id = "gps/"+features.data.length
|
||||
i++
|
||||
features.data.push({feature, freshness: new Date()})
|
||||
features.ping()
|
||||
})
|
||||
|
||||
|
||||
let gpsLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_track")[0]
|
||||
let gpsLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_location_history")[0]
|
||||
this.historicalUserLocations = new SimpleFeatureSource(gpsLayerDef, Tiles.tile_index(0, 0, 0), features);
|
||||
this.changes.useLocationHistory(this)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const asLine = features.map(allPoints => {
|
||||
if(allPoints === undefined || allPoints.length < 2){
|
||||
return []
|
||||
}
|
||||
|
||||
const feature = {
|
||||
type: "Feature",
|
||||
properties:{
|
||||
"id":"location_track",
|
||||
"_date:now": new Date().toISOString(),
|
||||
},
|
||||
geometry:{
|
||||
type: "LineString",
|
||||
coordinates: allPoints.map(ff => ff.feature.geometry.coordinates)
|
||||
}
|
||||
}
|
||||
|
||||
self.allElements.ContainingFeatures.set(feature.properties.id, feature)
|
||||
|
||||
return [{
|
||||
feature,
|
||||
freshness: new Date()
|
||||
}]
|
||||
})
|
||||
let gpsLineLayerDef: FilteredLayer = this.filteredLayers.data.filter(l => l.layerDef.id === "gps_track")[0]
|
||||
this.historicalUserLocationsTrack = new SimpleFeatureSource(gpsLineLayerDef, Tiles.tile_index(0, 0, 0), asLine);
|
||||
}
|
||||
|
||||
private initHomeLocation() {
|
||||
|
|
|
@ -39,10 +39,11 @@ import {And} from "../Logic/Tags/And";
|
|||
import Toggle from "./Input/Toggle";
|
||||
import {DefaultGuiState} from "./DefaultGuiState";
|
||||
import {GeoOperations} from "../Logic/GeoOperations";
|
||||
import Hash from "../Logic/Web/Hash";
|
||||
|
||||
export interface SpecialVisualization {
|
||||
funcName: string,
|
||||
constr: ((state: State, tagSource: UIEventSource<any>, argument: string[], guistate: DefaultGuiState, ) => BaseUIElement),
|
||||
constr: ((state: State, tagSource: UIEventSource<any>, argument: string[], guistate: DefaultGuiState,) => BaseUIElement),
|
||||
docs: string,
|
||||
example?: string,
|
||||
args: { name: string, defaultValue?: string, doc: string }[]
|
||||
|
@ -174,11 +175,11 @@ export default class SpecialVisualizations {
|
|||
idList = JSON.parse(value)
|
||||
}
|
||||
|
||||
|
||||
for (const id of idList) {
|
||||
const feature = featureStore.get(id)
|
||||
features.push({
|
||||
freshness: new Date(),
|
||||
feature: featureStore.get(id)
|
||||
feature
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -606,8 +607,8 @@ export default class SpecialVisualizations {
|
|||
args: [],
|
||||
constr: (state, tagSource, args) => {
|
||||
const t = Translations.t.general.download;
|
||||
|
||||
return new SubtleButton(Svg.download_ui(),
|
||||
|
||||
return new SubtleButton(Svg.download_ui(),
|
||||
new Combine([t.downloadGpx.SetClass("font-bold text-lg"),
|
||||
t.downloadGpxHelper.SetClass("subtle")]).SetClass("flex flex-col")
|
||||
).onClick(() => {
|
||||
|
@ -617,11 +618,24 @@ export default class SpecialVisualizations {
|
|||
const matchingLayer = state?.layoutToUse?.getMatchingLayer(tags)
|
||||
const gpx = GeoOperations.AsGpx(feature, matchingLayer)
|
||||
const title = matchingLayer.title?.GetRenderValue(tags)?.Subs(tags)?.txt ?? "gpx_track"
|
||||
Utils.offerContentsAsDownloadableFile(gpx, title+"_mapcomplete_export.gpx", {
|
||||
Utils.offerContentsAsDownloadableFile(gpx, title + "_mapcomplete_export.gpx", {
|
||||
mimetype: "{gpx=application/gpx+xml}"
|
||||
})
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
funcName: "clear_location_history",
|
||||
docs: "A button to remove the travelled track information from the device",
|
||||
args: [],
|
||||
constr: state => {
|
||||
return new SubtleButton(
|
||||
Svg.delete_icon_svg().SetStyle("height: 1.5rem"), Translations.t.general.removeLocationHistory
|
||||
).onClick(() => {
|
||||
state.historicalUserLocations.features.setData([])
|
||||
Hash.hash.setData(undefined)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
28
Utils.ts
28
Utils.ts
|
@ -361,6 +361,34 @@ Note that these values can be prepare with javascript in the theme by using a [c
|
|||
)
|
||||
}
|
||||
|
||||
public static upload(url: string, data, headers?: any): Promise<string> {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onload = () => {
|
||||
if (xhr.status == 200) {
|
||||
resolve(xhr.response)
|
||||
} else if (xhr.status === 509 || xhr.status === 429) {
|
||||
reject("rate limited")
|
||||
} else {
|
||||
reject(xhr.statusText)
|
||||
}
|
||||
};
|
||||
xhr.open('POST', url);
|
||||
if (headers !== undefined) {
|
||||
|
||||
for (const key in headers) {
|
||||
xhr.setRequestHeader(key, headers[key])
|
||||
}
|
||||
}
|
||||
|
||||
xhr.send(data);
|
||||
xhr.onerror = reject
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
public static async downloadJsonCached(url: string, maxCacheTimeMs: number, headers?: any): Promise<any> {
|
||||
const cached = Utils._download_cache.get(url)
|
||||
if (cached !== undefined) {
|
||||
|
|
|
@ -189,7 +189,6 @@
|
|||
"it": "Si tratta di un normale defibrillatore automatico o un defibrillatore manuale riservato ai professionisti?",
|
||||
"de": "Ist dies ein normaler automatischer Defibrillator oder ein manueller Defibrillator nur für Profis?"
|
||||
},
|
||||
|
||||
"condition": {
|
||||
"and": [
|
||||
"access=no"
|
||||
|
|
10
assets/layers/gps_location_history/gps_location_history.json
Normal file
10
assets/layers/gps_location_history/gps_location_history.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"id": "gps_location_history",
|
||||
"description": "Meta layer which contains the previous locations of the user as single points. This is mainly for technical reasons, e.g. to keep match the distance to the modified object",
|
||||
"minzoom": 0,
|
||||
"source": {
|
||||
"osmTags": "user:location=yes",
|
||||
"maxCacheAge": 604800
|
||||
},
|
||||
"mapRendering": null
|
||||
}
|
|
@ -1,27 +1,32 @@
|
|||
{
|
||||
"id": "gps_track",
|
||||
"description": "Meta layer showing the previou locations of the user. Add this to your theme and override the icon to change the appearance of the current location.",
|
||||
"description": "Meta layer showing the previous locations of the user as single line. Add this to your theme and override the icon to change the appearance of the current location.",
|
||||
"minzoom": 0,
|
||||
"source": {
|
||||
"osmTags": "user:location=yes",
|
||||
"osmTags": "id=location_track",
|
||||
"maxCacheAge": 0
|
||||
},
|
||||
"#title": {
|
||||
"title": {
|
||||
"render": "Your travelled path"
|
||||
},
|
||||
"tagRenderings": [
|
||||
{
|
||||
"id": "Privacy notice",
|
||||
"render": {
|
||||
"en": "This is the path you've travelled since this website is opened. Don't worry - this is only visible to you and no one else. Your location data is never sent off-device."
|
||||
"en": "This is the path you've travelled since this website is opened. Don't worry - this is only visible to you and no one else. Your location data is never sent off-device without your permission."
|
||||
}
|
||||
},
|
||||
"export_as_gpx"
|
||||
"export_as_gpx",
|
||||
"minimap",
|
||||
{
|
||||
"id": "delete",
|
||||
"render": "{clear_location_history()}"
|
||||
}
|
||||
],
|
||||
"#name": "Your track",
|
||||
"name": "Your track",
|
||||
"mapRendering": [
|
||||
{
|
||||
"width": 0,
|
||||
"width": 3,
|
||||
"color": "#bb000077"
|
||||
}
|
||||
]
|
||||
|
|
72
assets/svg/upload.svg
Normal file
72
assets/svg/upload.svg
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 600 600"
|
||||
enable-background="new 0 0 600 600"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="upload.svg"
|
||||
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"><metadata
|
||||
id="metadata17"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata>
|
||||
<defs
|
||||
id="defs15">
|
||||
|
||||
|
||||
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1003"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.78666667"
|
||||
inkscape:cx="257.94125"
|
||||
inkscape:cy="387.47074"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
<rect
|
||||
display="none"
|
||||
fill="#020202"
|
||||
stroke="#000000"
|
||||
stroke-width="1.1344"
|
||||
stroke-miterlimit="10"
|
||||
width="600"
|
||||
height="600"
|
||||
id="rect2" />
|
||||
<polygon
|
||||
display="none"
|
||||
fill="#FFFFFF"
|
||||
points="0,0 0,600 600,300 "
|
||||
id="polygon4" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 449.20044,207.4 h -99.8 v 153.3 c 0,14 -11.2,25.5 -25,25.5 h -49.9 c -13.7,0 -25,-11.5 -25,-25.5 V 207.4 h -99.8 L 299.40044,3 Z"
|
||||
id="path20"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
d="m 37.300444,274.5 c 20.7,0 37.4,17.2 37.4,38.3 V 504.4 H 524.00044 V 312.8 c 0,-21.2 16.8,-38.3 37.4,-38.3 20.7,0 37.5,17.1 37.5,38.3 v 229.9 c 0,21.1 -16.8,38.3 -37.4,38.3 H 37.400444 C 16.700444,581 4.4412682e-4,563.8 4.4412682e-4,542.7 V 312.8 C -0.09955587,291.6 16.700444,274.5 37.300444,274.5 Z"
|
||||
id="path6" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
8
assets/svg/upload.svg.license_info.json
Normal file
8
assets/svg/upload.svg.license_info.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"authors": [
|
||||
"Pieter Vander Vennet"
|
||||
],
|
||||
"path": "upload.svg",
|
||||
"license": "CC0",
|
||||
"sources": []
|
||||
}
|
|
@ -5,27 +5,31 @@
|
|||
"nl": "Verrekijkers",
|
||||
"de": "Ferngläser",
|
||||
"it": "Binocoli",
|
||||
"nb_NO": "Kikkerter"
|
||||
"nb_NO": "Kikkerter",
|
||||
"zh_Hant": "望遠鏡"
|
||||
},
|
||||
"shortDescription": {
|
||||
"en": "A map with fixed binoculars",
|
||||
"nl": "Een kaart met publieke verrekijker",
|
||||
"de": "Eine Karte mit festinstallierten Ferngläsern",
|
||||
"it": "Una cartina dei binocoli pubblici fissi",
|
||||
"nb_NO": "Et kart over fastmonterte kikkerter"
|
||||
"nb_NO": "Et kart over fastmonterte kikkerter",
|
||||
"zh_Hant": "固定望遠鏡的地圖"
|
||||
},
|
||||
"description": {
|
||||
"en": "A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve.",
|
||||
"nl": "Een kaart met verrekijkers die op een vaste plaats zijn gemonteerd",
|
||||
"de": "Eine Karte mit festinstallierten Ferngläsern. Man findet sie typischerweise an touristischen Orten, Aussichtspunkten, auf Aussichtstürmen oder gelegentlich in einem Naturschutzgebiet.",
|
||||
"it": "Una cartina dei binocoli su un palo fissi in un luogo. Si trovano tipicamente nei luoghi turistici, nei belvedere, in cima a torri panoramiche oppure occasionalmente nelle riserve naturali."
|
||||
"it": "Una cartina dei binocoli su un palo fissi in un luogo. Si trovano tipicamente nei luoghi turistici, nei belvedere, in cima a torri panoramiche oppure occasionalmente nelle riserve naturali.",
|
||||
"zh_Hant": "固定一地的望遠鏡地圖,特別是能夠在旅遊景點、觀景點、城鎮環景點,或是自然保護區找到。"
|
||||
},
|
||||
"language": [
|
||||
"en",
|
||||
"nl",
|
||||
"de",
|
||||
"it",
|
||||
"nb_NO"
|
||||
"nb_NO",
|
||||
"zh_Hant"
|
||||
],
|
||||
"maintainer": "",
|
||||
"icon": "./assets/layers/binocular/telescope.svg",
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
"de": "Cafés und Kneipen",
|
||||
"it": "Caffè e pub",
|
||||
"nb_NO": "Kafeer og kneiper",
|
||||
"id": "Kafe dan pub"
|
||||
"id": "Kafe dan pub",
|
||||
"zh_Hant": "咖啡廳與酒吧"
|
||||
},
|
||||
"description": {
|
||||
"nl": "Cafés, kroegen en drinkgelegenheden"
|
||||
|
@ -17,7 +18,8 @@
|
|||
"de",
|
||||
"it",
|
||||
"nb_NO",
|
||||
"id"
|
||||
"id",
|
||||
"zh_Hant"
|
||||
],
|
||||
"maintainer": "",
|
||||
"icon": "./assets/layers/cafe_pub/pub.svg",
|
||||
|
|
|
@ -658,7 +658,8 @@
|
|||
"it": "Aggiungi una nuova area di sosta ufficiale per camper. Si tratta di aree destinate alla sosta notturna dei camper. Potrebbe trattarsi di luoghi di campeggio o semplici parcheggi. Potrebbero anche non essere segnalati sul posto, ma semplicemente indicati in una delibera comunale. Un parcheggio destinato ai camper in cui non è però consentito trascorrere la notte -non- va considerato un'area di sosta per camper. ",
|
||||
"fr": "Ajouter une nouvelle aire de camping officielle, destinée à y passer la nuit avec un camping-car. Elle ne nécessite pas d’infrastructures particulières et peut être simplement désignée sous arrêté municipal, un simple parking ne suffit pas à rentrer dans cette catégorie ",
|
||||
"de": "Fügen Sie einen neuen offiziellen Wohnmobilstellplatz hinzu. Dies sind ausgewiesene Plätze, an denen Sie in Ihrem Wohnmobil übernachten können. Sie können wie ein richtiger Campingplatz oder nur wie ein Parkplatz aussehen. Möglicherweise sind sie gar nicht ausgeschildert, sondern nur in einem Gemeindebeschluss festgelegt. Ein normaler Parkplatz für Wohnmobile, auf dem übernachten nicht zulässig ist, ist kein Wohnmobilstellplatz. ",
|
||||
"nl": "Voeg een nieuwe officiële camperplaats toe. Dit zijn speciaal aangeduide plaatsen waar het toegestaan is om te overnachten met een camper. Ze kunnen er uitzien als een parking, of soms eerder als een camping. Soms staan ze niet ter plaatse aangeduid, maar heeft de gemeente wel degelijk beslist dat dit een camperplaats is. Een parking voor campers waar je niet mag overnachten is géén camperplaats. "
|
||||
"nl": "Voeg een nieuwe officiële camperplaats toe. Dit zijn speciaal aangeduide plaatsen waar het toegestaan is om te overnachten met een camper. Ze kunnen er uitzien als een parking, of soms eerder als een camping. Soms staan ze niet ter plaatse aangeduid, maar heeft de gemeente wel degelijk beslist dat dit een camperplaats is. Een parking voor campers waar je niet mag overnachten is géén camperplaats. ",
|
||||
"zh_Hant": "新增正式露營地點,通常是設計給過夜的露營者的地點。看起來像是真的露營地或是一般的停車場,而且也許沒有任何指標,但在城鎮被定議地點。如果一般給露營者的停車場並不是用來過夜,則不是露營地點 "
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -704,7 +705,8 @@
|
|||
"it": "Luoghi di sversamento delle acque reflue",
|
||||
"fr": "Site de vidange",
|
||||
"pt_BR": "Estações de despejo sanitário",
|
||||
"de": "Sanitäre Entsorgungsstationen"
|
||||
"de": "Sanitäre Entsorgungsstationen",
|
||||
"zh_Hant": "垃圾處理站"
|
||||
},
|
||||
"minzoom": 10,
|
||||
"source": {
|
||||
|
@ -751,7 +753,8 @@
|
|||
"it": "Luoghi di sversamento delle acque reflue",
|
||||
"fr": "Site de vidange",
|
||||
"pt_BR": "Estações de despejo sanitário",
|
||||
"de": "Sanitäre Entsorgungsstationen"
|
||||
"de": "Sanitäre Entsorgungsstationen",
|
||||
"zh_Hant": "垃圾處理站"
|
||||
},
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
|
@ -764,7 +767,8 @@
|
|||
"it": "Questo luogo è a pagamento?",
|
||||
"fr": "Ce site est-il payant ?",
|
||||
"pt_BR": "Este lugar cobra alguma taxa?",
|
||||
"de": "Wird hier eine Gebühr erhoben?"
|
||||
"de": "Wird hier eine Gebühr erhoben?",
|
||||
"zh_Hant": "這個地方需要付費嗎?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -780,7 +784,8 @@
|
|||
"it": "A pagamento",
|
||||
"fr": "Ce site demande un paiement",
|
||||
"pt_BR": "Você precisa pagar pelo uso",
|
||||
"de": "Sie müssen für die Nutzung bezahlen"
|
||||
"de": "Sie müssen für die Nutzung bezahlen",
|
||||
"zh_Hant": "你需要付費才能使用"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -796,7 +801,8 @@
|
|||
"it": "È gratuito",
|
||||
"fr": "Ce site ne demande pas de paiement",
|
||||
"pt_BR": "Pode ser usado gratuitamente",
|
||||
"de": "Nutzung kostenlos"
|
||||
"de": "Nutzung kostenlos",
|
||||
"zh_Hant": "這裡可以免費使用"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -809,7 +815,8 @@
|
|||
"it": "Ha una tariffa di {charge}",
|
||||
"fr": "Ce site fait payer {charge}",
|
||||
"pt_BR": "Este lugar cobra {charge}",
|
||||
"de": "Die Gebühr beträgt {charge}"
|
||||
"de": "Die Gebühr beträgt {charge}",
|
||||
"zh_Hant": "這個地方收費 {charge}"
|
||||
},
|
||||
"question": {
|
||||
"en": "How much does this place charge?",
|
||||
|
@ -818,7 +825,8 @@
|
|||
"it": "Qual è la tariffa di questo luogo?",
|
||||
"fr": "Combien ce site demande t’il de payer ?",
|
||||
"pt_BR": "Quanto este lugar cobra?",
|
||||
"de": "Wie hoch ist die Gebühr an diesem Ort?"
|
||||
"de": "Wie hoch ist die Gebühr an diesem Ort?",
|
||||
"zh_Hant": "這個地方收費多少?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "charge"
|
||||
|
@ -973,7 +981,8 @@
|
|||
"it": "Chi può utilizzare questo luogo di sversamento?",
|
||||
"ru": "Кто может использовать эту станцию утилизации?",
|
||||
"fr": "Qui peut utiliser le site de vidange ?",
|
||||
"de": "Wer darf diese sanitäre Entsorgungsstation nutzen?"
|
||||
"de": "Wer darf diese sanitäre Entsorgungsstation nutzen?",
|
||||
"zh_Hant": "誰可以使用這個垃圾站?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -987,7 +996,8 @@
|
|||
"ja": "これを使用するには、ネットワークキー/コードが必要です",
|
||||
"it": "Servono una chiave o un codice di accesso",
|
||||
"fr": "Un code est nécessaire",
|
||||
"de": "Sie benötigen einen Schlüssel/Code zur Benutzung"
|
||||
"de": "Sie benötigen einen Schlüssel/Code zur Benutzung",
|
||||
"zh_Hant": "你需要網路鑰匙/密碼來使用這個設施"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1001,7 +1011,8 @@
|
|||
"ja": "この場所を使用するには、キャンプ/キャンプサイトのお客様である必要があります",
|
||||
"it": "È obbligatorio essere un cliente di questo campeggio o di questa area camper",
|
||||
"fr": "Le site est réservés aux clients",
|
||||
"de": "Sie müssen Kunde des Campingplatzes sein, um diesen Ort nutzen zu können"
|
||||
"de": "Sie müssen Kunde des Campingplatzes sein, um diesen Ort nutzen zu können",
|
||||
"zh_Hant": "你需要是露營/露營地的客戶才能使用這一地方"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1016,7 +1027,8 @@
|
|||
"it": "Chiunque può farne uso",
|
||||
"ru": "Любой может воспользоваться этой станцией утилизации",
|
||||
"fr": "Le site est en libre-service",
|
||||
"de": "Jeder darf diese sanitäre Entsorgungsstation nutzen"
|
||||
"de": "Jeder darf diese sanitäre Entsorgungsstation nutzen",
|
||||
"zh_Hant": "任何人都可以使用這個衛生廢棄物站"
|
||||
},
|
||||
"hideInAnswer": true
|
||||
},
|
||||
|
@ -1032,7 +1044,8 @@
|
|||
"it": "Chiunque può farne uso",
|
||||
"ru": "Любой может воспользоваться этой станцией утилизации",
|
||||
"fr": "Le site est en libre-service",
|
||||
"de": "Jeder darf diese sanitäre Entsorgungsstation nutzen"
|
||||
"de": "Jeder darf diese sanitäre Entsorgungsstation nutzen",
|
||||
"zh_Hant": "任何人都可以使用這個垃圾站"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -1070,14 +1083,16 @@
|
|||
"ja": "衛生ゴミ捨て場",
|
||||
"it": "luogo di sversamento delle acque reflue",
|
||||
"fr": "Site de vidange",
|
||||
"de": "Sanitäre Entsorgungsstation"
|
||||
"de": "Sanitäre Entsorgungsstation",
|
||||
"zh_Hant": "垃圾丟棄站"
|
||||
},
|
||||
"description": {
|
||||
"en": "Add a new sanitary dump station. This is a place where camper drivers can dump waste water or chemical toilet waste. Often there's also drinking water and electricity.",
|
||||
"ja": "新しい衛生ゴミ捨て場を追加します。ここは、キャンピングカーの運転手が排水や携帯トイレの廃棄物を捨てることができる場所です。飲料水や電気もあることが多いです。",
|
||||
"it": "Aggiungi un nuovo luogo di sversamento delle acque reflue. Si tratta di luoghi dove chi viaggia in camper può smaltire le acque grigie o le acque nere. Spesso forniscono anche acqua ed elettricità.",
|
||||
"fr": "Ajouter un nouveau site de vidange. Un espace où évacuer ses eaux usées (grises et/ou noires) généralement alimenté en eau potable et électricité.",
|
||||
"de": "Fügen Sie eine neue sanitäre Entsorgungsstation hinzu. Hier können Camper Abwasser oder chemischen Toilettenabfälle entsorgen. Oft gibt es auch Trinkwasser und Strom."
|
||||
"de": "Fügen Sie eine neue sanitäre Entsorgungsstation hinzu. Hier können Camper Abwasser oder chemischen Toilettenabfälle entsorgen. Oft gibt es auch Trinkwasser und Strom.",
|
||||
"zh_Hant": "新增垃圾站,這通常是提供露營駕駛丟棄廢水與化學性廁所廢水的地方,也會有飲用水與電力。"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -172,6 +172,7 @@
|
|||
"readYourMessages": "Please, read all your OpenStreetMap-messages before adding a new point.",
|
||||
"fewChangesBefore": "Please, answer a few questions of existing points before adding a new point.",
|
||||
"goToInbox": "Open inbox",
|
||||
"removeLocationHistory": "Delete the location history",
|
||||
"getStartedLogin": "Log in with OpenStreetMap to get started",
|
||||
"getStartedNewAccount": " or <a href='https://www.openstreetmap.org/user/new' target='_blank'>create a new account</a>",
|
||||
"noTagsSelected": "No tags selected",
|
||||
|
@ -192,6 +193,8 @@
|
|||
"downloadGeojson": "Download visible data as GeoJSON",
|
||||
"downloadGpx":"Download as GPX-file",
|
||||
"downloadGpxHelper":"A GPX-file can be used with most navigation devices and applications",
|
||||
"uploadGpx":"Upload your track to OpenStreetMap",
|
||||
|
||||
"exporting": "Exporting…",
|
||||
"downloadGeoJsonHelper": "Compatible with QGIS, ArcGIS, ESRI, …",
|
||||
"downloadCSV": "Download visible data as CSV",
|
||||
|
|
|
@ -2852,7 +2852,7 @@
|
|||
"gps_track": {
|
||||
"tagRenderings": {
|
||||
"Privacy notice": {
|
||||
"render": "This is the path you've travelled since this website is opened. Don't worry - this is only visible to you and no one else. Your location data is never sent off-device."
|
||||
"render": "This is the path you've travelled since this website is opened. Don't worry - this is only visible to you and no one else. Your location data is never sent off-device without your permission."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,323 +1,323 @@
|
|||
{
|
||||
"aed": {
|
||||
"description": "在這份地圖上,你可以找到與標記附近的除顫器",
|
||||
"title": "開放AED地圖"
|
||||
},
|
||||
"artwork": {
|
||||
"description": "歡迎來到開放藝術品地圖,這份地圖會顯示全世界的雕像、半身像、塗鴉以及其他類型的藝術品",
|
||||
"title": "開放藝術品地圖"
|
||||
},
|
||||
"benches": {
|
||||
"description": "這份地圖顯示開放街圖上所有記錄的長椅:單獨的長椅,屬於大眾運輸站點或涼亭的長椅。只要有開放街圖帳號,你可以新增長椅或是編輯既有長椅的詳細內容。",
|
||||
"shortDescription": "長椅的地圖",
|
||||
"title": "長椅"
|
||||
},
|
||||
"bicyclelib": {
|
||||
"description": "單車圖書館是指每年支付小額費用,然後可以租用單車的地方。最有名的單車圖書館案例是給小孩的,能夠讓長大的小孩用目前的單車換成比較大的單車",
|
||||
"title": "單車圖書館"
|
||||
},
|
||||
"bookcases": {
|
||||
"description": "公共書架是街邊箱子、盒子、舊的電話亭或是其他存放書本的物件,每一個人都能放置或拿取書本。這份地圖收集所有類型的書架,你可以探索你附近新的書架,同時也能用免費的開放街圖帳號來快速新增你最愛的書架。",
|
||||
"title": "開放書架地圖"
|
||||
},
|
||||
"campersite": {
|
||||
"description": "這個網站收集所有官方露營地點,以及那邊能排放廢水。你可以加上詳細的服務項目與價格,加上圖片以及評價。這是網站與網路 app,資料則是存在開放街圖,因此會永遠免費,而且可以被所有 app 再利用。",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "露營地",
|
||||
"name": "露營地",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "露營地",
|
||||
"description": "新增正式露營地點,通常是設計給過夜的露營者的地點。看起來像是真的露營地或是一般的停車場,而且也許沒有任何指標,但在城鎮被定議地點。如果一般給露營者的停車場並不是用來過夜,則不是露營地點 "
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"caravansites-capacity": {
|
||||
"question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)",
|
||||
"render": "{capacity} 露營者能夠同時使用這個地方"
|
||||
},
|
||||
"caravansites-charge": {
|
||||
"question": "這個地方收多少費用?",
|
||||
"render": "這個地方收費 {charge}"
|
||||
},
|
||||
"caravansites-description": {
|
||||
"question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)",
|
||||
"render": "這個地方更詳細的資訊: {description}"
|
||||
},
|
||||
"caravansites-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你要付費才能使用"
|
||||
},
|
||||
"1": {
|
||||
"then": "可以免費使用"
|
||||
}
|
||||
},
|
||||
"question": "這個地方收費嗎?"
|
||||
},
|
||||
"caravansites-internet": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這裡有網路連線"
|
||||
},
|
||||
"1": {
|
||||
"then": "這裡有網路連線"
|
||||
},
|
||||
"2": {
|
||||
"then": "這裡沒有網路連線"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有提網路連線嗎?"
|
||||
},
|
||||
"caravansites-internet-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要額外付費來使用網路連線"
|
||||
},
|
||||
"1": {
|
||||
"then": "你不需要額外付費來使用網路連線"
|
||||
}
|
||||
},
|
||||
"question": "你需要為網路連線付費嗎?"
|
||||
},
|
||||
"caravansites-long-term": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "有,這個地方有提供長期租用,但你也可以用天計算費用"
|
||||
},
|
||||
"1": {
|
||||
"then": "沒有,這裡沒有永久的客戶"
|
||||
},
|
||||
"2": {
|
||||
"then": "如果有長期租用合約才有可能待下來(如果你選擇這個地方則會在這份地圖消失)"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有提供長期租用嗎?"
|
||||
},
|
||||
"caravansites-name": {
|
||||
"question": "這個地方叫做什麼?",
|
||||
"render": "這個地方叫做 {name}"
|
||||
},
|
||||
"caravansites-sanitary-dump": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這個地方有衛生設施"
|
||||
},
|
||||
"1": {
|
||||
"then": "這個地方沒有衛生設施"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有衛生設施嗎?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這個地方有廁所"
|
||||
},
|
||||
"1": {
|
||||
"then": "這個地方並沒有廁所"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有廁所嗎?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "這個地方有網站嗎?",
|
||||
"render": "官方網站:<a href='{website}'>{website}</a>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "沒有名稱的露營地"
|
||||
}
|
||||
},
|
||||
"render": "露營地 {name}"
|
||||
}
|
||||
"aed": {
|
||||
"description": "在這份地圖上,你可以找到與標記附近的除顫器",
|
||||
"title": "開放AED地圖"
|
||||
},
|
||||
"artwork": {
|
||||
"description": "歡迎來到開放藝術品地圖,這份地圖會顯示全世界的雕像、半身像、塗鴉以及其他類型的藝術品",
|
||||
"title": "開放藝術品地圖"
|
||||
},
|
||||
"benches": {
|
||||
"description": "這份地圖顯示開放街圖上所有記錄的長椅:單獨的長椅,屬於大眾運輸站點或涼亭的長椅。只要有開放街圖帳號,你可以新增長椅或是編輯既有長椅的詳細內容。",
|
||||
"shortDescription": "長椅的地圖",
|
||||
"title": "長椅"
|
||||
},
|
||||
"bicyclelib": {
|
||||
"description": "單車圖書館是指每年支付小額費用,然後可以租用單車的地方。最有名的單車圖書館案例是給小孩的,能夠讓長大的小孩用目前的單車換成比較大的單車",
|
||||
"title": "單車圖書館"
|
||||
},
|
||||
"binoculars": {
|
||||
"description": "固定一地的望遠鏡地圖,特別是能夠在旅遊景點、觀景點、城鎮環景點,或是自然保護區找到。",
|
||||
"shortDescription": "固定望遠鏡的地圖",
|
||||
"title": "望遠鏡"
|
||||
},
|
||||
"bookcases": {
|
||||
"description": "公共書架是街邊箱子、盒子、舊的電話亭或是其他存放書本的物件,每一個人都能放置或拿取書本。這份地圖收集所有類型的書架,你可以探索你附近新的書架,同時也能用免費的開放街圖帳號來快速新增你最愛的書架。",
|
||||
"title": "開放書架地圖"
|
||||
},
|
||||
"cafes_and_pubs": {
|
||||
"title": "咖啡廳與酒吧"
|
||||
},
|
||||
"campersite": {
|
||||
"description": "這個網站收集所有官方露營地點,以及那邊能排放廢水。你可以加上詳細的服務項目與價格,加上圖片以及評價。這是網站與網路 app,資料則是存在開放街圖,因此會永遠免費,而且可以被所有 app 再利用。",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "露營地",
|
||||
"name": "露營地",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "新增正式露營地點,通常是設計給過夜的露營者的地點。看起來像是真的露營地或是一般的停車場,而且也許沒有任何指標,但在城鎮被定議地點。如果一般給露營者的停車場並不是用來過夜,則不是露營地點 ",
|
||||
"title": "露營地"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"caravansites-capacity": {
|
||||
"question": "多少露營者能夠待在這裡?(如果沒有明顯的空間數字或是允許車輛則可以跳過)",
|
||||
"render": "{capacity} 露營者能夠同時使用這個地方"
|
||||
},
|
||||
"caravansites-charge": {
|
||||
"question": "這個地方收多少費用?",
|
||||
"render": "這個地方收費 {charge}"
|
||||
},
|
||||
"caravansites-description": {
|
||||
"question": "你想要為這個地方加一般的敘述嗎?(不要重覆加先前問過或提供的資訊,請保持敘述性-請將意見留在評價)",
|
||||
"render": "這個地方更詳細的資訊: {description}"
|
||||
},
|
||||
"caravansites-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你要付費才能使用"
|
||||
},
|
||||
"1": {
|
||||
"then": "可以免費使用"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"tagRenderings": {
|
||||
"dumpstations-chemical-waste": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你可以在這邊丟棄廁所化學廢棄物"
|
||||
},
|
||||
"1": {
|
||||
"then": "你不能在這邊丟棄廁所化學廢棄物"
|
||||
}
|
||||
},
|
||||
"question": "你能在這裡丟棄廁所化學廢棄物嗎?"
|
||||
},
|
||||
"dumpstations-access": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要網路鑰匙/密碼來使用這個設施"
|
||||
},
|
||||
"1": {
|
||||
"then": "你需要是露營/露營地的客戶才能使用這一地方"
|
||||
},
|
||||
"3": {
|
||||
"then": "任何人都可以使用這個垃圾站"
|
||||
},
|
||||
"2": {
|
||||
"then": "任何人都可以使用這個衛生廢棄物站"
|
||||
}
|
||||
},
|
||||
"question": "誰可以使用這個垃圾站?"
|
||||
},
|
||||
"dumpstations-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要付費才能使用"
|
||||
},
|
||||
"1": {
|
||||
"then": "這裡可以免費使用"
|
||||
}
|
||||
},
|
||||
"question": "這個地方需要付費嗎?"
|
||||
},
|
||||
"dumpstations-charge": {
|
||||
"render": "這個地方收費 {charge}",
|
||||
"question": "這個地方收費多少?"
|
||||
}
|
||||
},
|
||||
"description": "垃圾處理站",
|
||||
"name": "垃圾處理站",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "垃圾丟棄站",
|
||||
"description": "新增垃圾站,這通常是提供露營駕駛丟棄廢水與化學性廁所廢水的地方,也會有飲用水與電力。"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "露營者尋找渡過夜晚的場地",
|
||||
"title": "露營地點"
|
||||
},
|
||||
"charging_stations": {
|
||||
"description": "在這份開放地圖上,你可以尋找與標示充電站的資訊",
|
||||
"shortDescription": "全世界的充電站地圖",
|
||||
"title": "充電站"
|
||||
},
|
||||
"climbing": {
|
||||
"description": "在這份地圖上你會發現能夠攀爬機會,像是攀岩體育館、抱石大廳以及大自然當中的巨石。",
|
||||
"descriptionTail": "攀爬地圖最初由 <a href='https://utopicode.de/en/?ref=kletterspots' target='_blank'>Christian Neumann</a> 製作。如果你有回饋意見或問題請到Please <a href='https://utopicode.de/en/contact/?project=kletterspots&ref=kletterspots' target='blank'>這邊反應</a>。</p><p>這專案使用來自<a href='https://www.openstreetmap.org/' target='_blank'>開放街圖</a>專案的資料。</p>",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "攀岩社團或組織",
|
||||
"name": "攀岩社團",
|
||||
"tagRenderings": {
|
||||
"climbing_club-name": {
|
||||
"render": "<strong>{name}</strong>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "攀岩 NGO"
|
||||
}
|
||||
},
|
||||
"render": "攀岩社團"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "開放攀爬地圖"
|
||||
},
|
||||
"cyclestreets": {
|
||||
"description": "單車街道是<b>機動車輛受限制,只允許單車通行</b>的道路。通常會有路標顯示特別的交通指標。單車街道通常在荷蘭、比利時看到,但德國與法國也有。 ",
|
||||
"layers": {
|
||||
"0": {
|
||||
"name": "單車街道"
|
||||
"question": "這個地方收費嗎?"
|
||||
},
|
||||
"caravansites-internet": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這裡有網路連線"
|
||||
},
|
||||
"1": {
|
||||
"then": "這裡有網路連線"
|
||||
},
|
||||
"2": {
|
||||
"then": "這裡沒有網路連線"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"name": "將來的單車街道"
|
||||
}
|
||||
},
|
||||
"shortDescription": "單車街道的地圖",
|
||||
"title": "單車街道"
|
||||
},
|
||||
"cyclofix": {
|
||||
"description": "這份地圖的目的是為單車騎士能夠輕易顯示滿足他們需求的相關設施。<br><br>你可以追蹤你確切位置 (只有行動版),以及在左下角選擇相關的圖層。你可以使用這工具在地圖新增或編輯釘子,以及透過回答問題來提供更多資訊。<br><br>所有你的變動都會自動存在開放街圖這全球資料圖,並且能被任何人自由取用。<br><br>你可以到 <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a> 閱讀更多資訊。",
|
||||
"title": "單車修正 - 單車騎士的開放地圖"
|
||||
},
|
||||
"drinking_water": {
|
||||
"description": "在這份地圖上,公共可及的飲水點可以顯示出來,也能輕易的增加",
|
||||
"title": "飲用水"
|
||||
},
|
||||
"facadegardens": {
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "立面花園",
|
||||
"name": "立面花園",
|
||||
"title": {
|
||||
"render": "立面花園"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "這地圖顯示立面花園的照片以及其他像是方向、日照以及植栽種類等實用訊息。",
|
||||
"title": "立面花園"
|
||||
},
|
||||
"ghostbikes": {
|
||||
"description": "<b>幽靈單車</b>是用來紀念死於交通事故的單車騎士,在事發地點附近放置白色單車。<br/><br/>在這份地圖上面,你可以看到所有在開放街圖已知的幽靈單車。有缺漏的幽靈單車嗎?所有人都可以在這邊新增或是更新資訊-只有你有(免費)開放街圖帳號。",
|
||||
"title": "幽靈單車"
|
||||
},
|
||||
"hailhydrant": {
|
||||
"description": "在這份地圖上面你可以在你喜愛的社區尋找與更新消防栓、消防隊、急救站與滅火器。\n\n你可以追蹤確切位置 (只有行動版) 以及在左下角選擇與你相關的圖層。你也可以使用這工具新增或編輯地圖上的釘子 (興趣點),以及透過回答一些問題提供額外的資訊。\n\n所有你做出的變動都會自動存到開放街圖這個全球資料庫,而且能自由讓其他人取用。",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "顯示消防栓的地圖圖層。",
|
||||
"name": "消防栓地圖"
|
||||
"question": "這個地方有提網路連線嗎?"
|
||||
},
|
||||
"caravansites-internet-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要額外付費來使用網路連線"
|
||||
},
|
||||
"1": {
|
||||
"then": "你不需要額外付費來使用網路連線"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"description": "顯示消防栓的地圖圖層。"
|
||||
}
|
||||
"question": "你需要為網路連線付費嗎?"
|
||||
},
|
||||
"caravansites-long-term": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "有,這個地方有提供長期租用,但你也可以用天計算費用"
|
||||
},
|
||||
"1": {
|
||||
"then": "沒有,這裡沒有永久的客戶"
|
||||
},
|
||||
"2": {
|
||||
"then": "如果有長期租用合約才有可能待下來(如果你選擇這個地方則會在這份地圖消失)"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有提供長期租用嗎?"
|
||||
},
|
||||
"caravansites-name": {
|
||||
"question": "這個地方叫做什麼?",
|
||||
"render": "這個地方叫做 {name}"
|
||||
},
|
||||
"caravansites-sanitary-dump": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這個地方有衛生設施"
|
||||
},
|
||||
"1": {
|
||||
"then": "這個地方沒有衛生設施"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有衛生設施嗎?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這個地方有廁所"
|
||||
},
|
||||
"1": {
|
||||
"then": "這個地方並沒有廁所"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有廁所嗎?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "這個地方有網站嗎?",
|
||||
"render": "官方網站:<a href='{website}'>{website}</a>"
|
||||
}
|
||||
},
|
||||
"shortDescription": "顯示消防栓、滅火器、消防隊與急救站的地圖。",
|
||||
"title": "消防栓、滅火器、消防隊、以及急救站。"
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "沒有名稱的露營地"
|
||||
}
|
||||
},
|
||||
"render": "露營地 {name}"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"description": "垃圾處理站",
|
||||
"name": "垃圾處理站",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "新增垃圾站,這通常是提供露營駕駛丟棄廢水與化學性廁所廢水的地方,也會有飲用水與電力。",
|
||||
"title": "垃圾丟棄站"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"dumpstations-access": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要網路鑰匙/密碼來使用這個設施"
|
||||
},
|
||||
"1": {
|
||||
"then": "你需要是露營/露營地的客戶才能使用這一地方"
|
||||
},
|
||||
"2": {
|
||||
"then": "任何人都可以使用這個衛生廢棄物站"
|
||||
},
|
||||
"3": {
|
||||
"then": "任何人都可以使用這個垃圾站"
|
||||
}
|
||||
},
|
||||
"question": "誰可以使用這個垃圾站?"
|
||||
},
|
||||
"dumpstations-charge": {
|
||||
"question": "這個地方收費多少?",
|
||||
"render": "這個地方收費 {charge}"
|
||||
},
|
||||
"dumpstations-chemical-waste": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你可以在這邊丟棄廁所化學廢棄物"
|
||||
},
|
||||
"1": {
|
||||
"then": "你不能在這邊丟棄廁所化學廢棄物"
|
||||
}
|
||||
},
|
||||
"question": "你能在這裡丟棄廁所化學廢棄物嗎?"
|
||||
},
|
||||
"dumpstations-fee": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "你需要付費才能使用"
|
||||
},
|
||||
"1": {
|
||||
"then": "這裡可以免費使用"
|
||||
}
|
||||
},
|
||||
"question": "這個地方需要付費嗎?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"maps": {
|
||||
"description": "在這份地圖你可以找到所在在開放街圖上已知的地圖 - 特別是顯示地區、城市、區域的資訊版面上的大型地圖,例如佈告欄背面的旅遊地圖,自然保護區的地圖,區域的單車網路地圖,...)<br/><br/>如果有缺少的地圖,你可以輕易在開放街圖上新增這地圖。",
|
||||
"shortDescription": "這份主題顯示所有已知的開放街圖上的 (旅遊) 地圖",
|
||||
"title": "地圖的地圖"
|
||||
"shortDescription": "露營者尋找渡過夜晚的場地",
|
||||
"title": "露營地點"
|
||||
},
|
||||
"charging_stations": {
|
||||
"description": "在這份開放地圖上,你可以尋找與標示充電站的資訊",
|
||||
"shortDescription": "全世界的充電站地圖",
|
||||
"title": "充電站"
|
||||
},
|
||||
"climbing": {
|
||||
"description": "在這份地圖上你會發現能夠攀爬機會,像是攀岩體育館、抱石大廳以及大自然當中的巨石。",
|
||||
"descriptionTail": "攀爬地圖最初由 <a href='https://utopicode.de/en/?ref=kletterspots' target='_blank'>Christian Neumann</a> 製作。如果你有回饋意見或問題請到Please <a href='https://utopicode.de/en/contact/?project=kletterspots&ref=kletterspots' target='blank'>這邊反應</a>。</p><p>這專案使用來自<a href='https://www.openstreetmap.org/' target='_blank'>開放街圖</a>專案的資料。</p>",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "攀岩社團或組織",
|
||||
"name": "攀岩社團",
|
||||
"tagRenderings": {
|
||||
"climbing_club-name": {
|
||||
"render": "<strong>{name}</strong>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "攀岩 NGO"
|
||||
}
|
||||
},
|
||||
"render": "攀岩社團"
|
||||
}
|
||||
}
|
||||
},
|
||||
"personal": {
|
||||
"description": "從所有可用的主題圖層創建個人化主題",
|
||||
"title": "個人化主題"
|
||||
"title": "開放攀爬地圖"
|
||||
},
|
||||
"cyclestreets": {
|
||||
"description": "單車街道是<b>機動車輛受限制,只允許單車通行</b>的道路。通常會有路標顯示特別的交通指標。單車街道通常在荷蘭、比利時看到,但德國與法國也有。 ",
|
||||
"layers": {
|
||||
"0": {
|
||||
"name": "單車街道"
|
||||
},
|
||||
"1": {
|
||||
"name": "將來的單車街道"
|
||||
}
|
||||
},
|
||||
"playgrounds": {
|
||||
"description": "在這份地圖上,你可以尋找遊樂場以及其相關資訊",
|
||||
"shortDescription": "遊樂場的地圖",
|
||||
"title": "遊樂場"
|
||||
"shortDescription": "單車街道的地圖",
|
||||
"title": "單車街道"
|
||||
},
|
||||
"cyclofix": {
|
||||
"description": "這份地圖的目的是為單車騎士能夠輕易顯示滿足他們需求的相關設施。<br><br>你可以追蹤你確切位置 (只有行動版),以及在左下角選擇相關的圖層。你可以使用這工具在地圖新增或編輯釘子,以及透過回答問題來提供更多資訊。<br><br>所有你的變動都會自動存在開放街圖這全球資料圖,並且能被任何人自由取用。<br><br>你可以到 <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a> 閱讀更多資訊。",
|
||||
"title": "單車修正 - 單車騎士的開放地圖"
|
||||
},
|
||||
"drinking_water": {
|
||||
"description": "在這份地圖上,公共可及的飲水點可以顯示出來,也能輕易的增加",
|
||||
"title": "飲用水"
|
||||
},
|
||||
"facadegardens": {
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "立面花園",
|
||||
"name": "立面花園",
|
||||
"title": {
|
||||
"render": "立面花園"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shops": {
|
||||
"description": "這份地圖上,你可以標記商家基本資訊,新增營業時間以及聯絡電話",
|
||||
"title": "開放商店地圖"
|
||||
"shortDescription": "這地圖顯示立面花園的照片以及其他像是方向、日照以及植栽種類等實用訊息。",
|
||||
"title": "立面花園"
|
||||
},
|
||||
"ghostbikes": {
|
||||
"description": "<b>幽靈單車</b>是用來紀念死於交通事故的單車騎士,在事發地點附近放置白色單車。<br/><br/>在這份地圖上面,你可以看到所有在開放街圖已知的幽靈單車。有缺漏的幽靈單車嗎?所有人都可以在這邊新增或是更新資訊-只有你有(免費)開放街圖帳號。",
|
||||
"title": "幽靈單車"
|
||||
},
|
||||
"hailhydrant": {
|
||||
"description": "在這份地圖上面你可以在你喜愛的社區尋找與更新消防栓、消防隊、急救站與滅火器。\n\n你可以追蹤確切位置 (只有行動版) 以及在左下角選擇與你相關的圖層。你也可以使用這工具新增或編輯地圖上的釘子 (興趣點),以及透過回答一些問題提供額外的資訊。\n\n所有你做出的變動都會自動存到開放街圖這個全球資料庫,而且能自由讓其他人取用。",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "顯示消防栓的地圖圖層。",
|
||||
"name": "消防栓地圖"
|
||||
},
|
||||
"1": {
|
||||
"description": "顯示消防栓的地圖圖層。"
|
||||
}
|
||||
},
|
||||
"sport_pitches": {
|
||||
"description": "運動場地是進行運動的地方",
|
||||
"shortDescription": "顯示運動場地的地圖",
|
||||
"title": "運動場地"
|
||||
},
|
||||
"surveillance": {
|
||||
"description": "在這份開放地圖,你可以找到監視鏡頭。",
|
||||
"shortDescription": "監視鏡頭與其他型式的監視",
|
||||
"title": "被監視的監視器"
|
||||
},
|
||||
"toilets": {
|
||||
"description": "公共廁所的地圖",
|
||||
"title": "開放廁所地圖"
|
||||
},
|
||||
"trees": {
|
||||
"description": "繪製所有樹木!",
|
||||
"shortDescription": "所有樹木的地圖",
|
||||
"title": "樹木"
|
||||
},
|
||||
"binoculars": {
|
||||
"shortDescription": "固定望遠鏡的地圖",
|
||||
"title": "望遠鏡",
|
||||
"description": "固定一地的望遠鏡地圖,特別是能夠在旅遊景點、觀景點、城鎮環景點,或是自然保護區找到。"
|
||||
},
|
||||
"cafes_and_pubs": {
|
||||
"title": "咖啡廳與酒吧"
|
||||
}
|
||||
}
|
||||
"shortDescription": "顯示消防栓、滅火器、消防隊與急救站的地圖。",
|
||||
"title": "消防栓、滅火器、消防隊、以及急救站。"
|
||||
},
|
||||
"maps": {
|
||||
"description": "在這份地圖你可以找到所在在開放街圖上已知的地圖 - 特別是顯示地區、城市、區域的資訊版面上的大型地圖,例如佈告欄背面的旅遊地圖,自然保護區的地圖,區域的單車網路地圖,...)<br/><br/>如果有缺少的地圖,你可以輕易在開放街圖上新增這地圖。",
|
||||
"shortDescription": "這份主題顯示所有已知的開放街圖上的 (旅遊) 地圖",
|
||||
"title": "地圖的地圖"
|
||||
},
|
||||
"personal": {
|
||||
"description": "從所有可用的主題圖層創建個人化主題",
|
||||
"title": "個人化主題"
|
||||
},
|
||||
"playgrounds": {
|
||||
"description": "在這份地圖上,你可以尋找遊樂場以及其相關資訊",
|
||||
"shortDescription": "遊樂場的地圖",
|
||||
"title": "遊樂場"
|
||||
},
|
||||
"shops": {
|
||||
"description": "這份地圖上,你可以標記商家基本資訊,新增營業時間以及聯絡電話",
|
||||
"title": "開放商店地圖"
|
||||
},
|
||||
"sport_pitches": {
|
||||
"description": "運動場地是進行運動的地方",
|
||||
"shortDescription": "顯示運動場地的地圖",
|
||||
"title": "運動場地"
|
||||
},
|
||||
"surveillance": {
|
||||
"description": "在這份開放地圖,你可以找到監視鏡頭。",
|
||||
"shortDescription": "監視鏡頭與其他型式的監視",
|
||||
"title": "被監視的監視器"
|
||||
},
|
||||
"toilets": {
|
||||
"description": "公共廁所的地圖",
|
||||
"title": "開放廁所地圖"
|
||||
},
|
||||
"trees": {
|
||||
"description": "繪製所有樹木!",
|
||||
"shortDescription": "所有樹木的地圖",
|
||||
"title": "樹木"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue