Merge remote-tracking branches 'weblate-github/weblate-mapcomplete-core' and 'weblate-github/weblate-mapcomplete-layers'

This commit is contained in:
Pieter Vander Vennet 2023-02-06 00:40:54 +01:00
commit 69dc02d65b
35 changed files with 2154 additions and 195 deletions

View file

@ -0,0 +1,15 @@
# Meeting notes
As of February 2023, regular meetings with Fix My City Berlin (and the wider community) are organized.
Meeting notes are tracked here.
## 2023-02-01 14:00
Present:
### Recent changes
- Experimenting with Svelte
- User research
- Research: reviews and picture licenses

View file

@ -10,7 +10,7 @@ import {
MultiPolygon,
Polygon,
} from "@turf/turf"
import { GeoJSON, LineString, Point } from "geojson"
import { GeoJSON, LineString, Point, Position } from "geojson"
import togpx from "togpx"
import Constants from "../Models/Constants"
@ -46,7 +46,7 @@ export class GeoOperations {
* @param lonlat0
* @param lonlat1
*/
static distanceBetween(lonlat0: [number, number], lonlat1: [number, number]) {
static distanceBetween(lonlat0: [number, number], lonlat1: [number, number] | Position) {
return turf.distance(lonlat0, lonlat1, { units: "meters" })
}

View file

@ -118,6 +118,7 @@ export default class SimpleMetaTaggers {
/*Note: also called by 'UpdateTagsFromOsmAPI'*/
const tgs = feature.properties
let movedSomething = false;
function move(src: string, target: string) {
if (tgs[src] === undefined) {
@ -125,6 +126,7 @@ export default class SimpleMetaTaggers {
}
tgs[target] = tgs[src]
delete tgs[src]
movedSomething = true
}
move("user", "_last_edit:contributor")
@ -132,7 +134,7 @@ export default class SimpleMetaTaggers {
move("changeset", "_last_edit:changeset")
move("timestamp", "_last_edit:timestamp")
move("version", "_version_number")
return true
return movedSomething
}
)
public static country = new CountryTagger()
@ -499,7 +501,7 @@ export default class SimpleMetaTaggers {
return false
}
OsmObject.DownloadReferencingWays(id).then((referencingWays) => {
const currentTagsSource = state.allElements.getEventSourceById(id)
const currentTagsSource = state.allElements?.getEventSourceById(id) ?? []
const wayIds = referencingWays.map((w) => "way/" + w.id)
wayIds.sort()
const wayIdsStr = wayIds.join(";")

View file

@ -87,21 +87,23 @@ export default class FeatureReviews {
if (feature.geometry.type === "Point") {
this._uncertainty = options?.uncertaintyRadius ?? 10
} else {
let coords: Position[][]
let coordss: Position[][]
if (feature.geometry.type === "LineString") {
coords = [feature.geometry.coordinates]
coordss = [feature.geometry.coordinates]
} else if (
feature.geometry.type === "MultiLineString" ||
feature.geometry.type === "Polygon"
) {
coords = feature.geometry.coordinates
coordss = feature.geometry.coordinates
}
let maxDistance = 0
for (const coord of coords) {
maxDistance = Math.max(
maxDistance,
GeoOperations.distanceBetween(centerLonLat, <any>coord)
)
for (const coords of coordss) {
for (const coord of coords) {
maxDistance = Math.max(
maxDistance,
GeoOperations.distanceBetween(centerLonLat, coord)
)
}
}
this._uncertainty = options?.uncertaintyRadius ?? maxDistance

View file

@ -87,27 +87,33 @@ export class NearbyImageVis implements SpecialVisualization {
const nearby = new Lazy(() => {
const towardsCenter = new CheckBox(t.onlyTowards, false)
const radiusValue =
state?.osmConnection?.GetPreference("nearby-images-radius", "300").sync(
const maxSearchRadius = 100
const stepSize = 10
const defaultValue = Math.floor(maxSearchRadius / (2 * stepSize)) * stepSize
const fromOsmPreferences = state?.osmConnection
?.GetPreference("nearby-images-radius", "" + defaultValue)
.sync(
(s) => Number(s),
[],
(i) => "" + i
) ?? new UIEventSource(300)
)
const radiusValue = new UIEventSource(fromOsmPreferences.data)
radiusValue.addCallbackAndRunD((v) => fromOsmPreferences.setData(v))
const radius = new Slider(25, 500, {
const radius = new Slider(stepSize, maxSearchRadius, {
value: radiusValue,
step: 25,
step: 10,
})
const alreadyInTheImage = AllImageProviders.LoadImagesFor(tagSource)
const options: NearbyImageOptions & { value } = {
lon,
lat,
searchRadius: 500,
searchRadius: maxSearchRadius,
shownRadius: radius.GetValue(),
value: selectedImage,
blacklist: alreadyInTheImage,
towardscenter: towardsCenter.GetValue(),
maxDaysOld: 365 * 5,
maxDaysOld: 365 * 3,
}
const slideshow = canBeEdited
? new SelectOneNearbyImage(options, state)

View file

@ -15,7 +15,7 @@ import { SubtleButton } from "../Base/SubtleButton"
import { GeoOperations } from "../../Logic/GeoOperations"
import { ElementStorage } from "../../Logic/ElementStorage"
import Lazy from "../Base/Lazy"
import P4C from "pic4carto"
export interface P4CPicture {
pictureUrl: string
date?: number
@ -175,7 +175,6 @@ export default class NearbyImages extends Lazy {
options: NearbyImageOptions,
state?: { allElements: ElementStorage }
) {
const P4C = require("../../vendor/P4C.min")
const picManager = new P4C.PicturesManager({})
const searchRadius = options.searchRadius ?? 500

View file

@ -149,7 +149,6 @@
],
"CY": [
"tr",
"el",
"el"
],
"CZ": [
@ -249,9 +248,6 @@
"es",
"pt"
],
"GR": [
"el"
],
"GT": [
"es"
],

File diff suppressed because it is too large Load diff

View file

@ -21,13 +21,6 @@
"#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag",
"or": [
"shop=bicycle",
{
"#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them",
"and": [
"amenity=bicycle_rental",
"network="
]
},
{
"#": "if sport is defined and is not bicycle, it is not matched; if bicycle retail/repair is marked as 'no', it is not shown to too.",
"##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it",

View file

@ -1199,7 +1199,7 @@
"bicycle=designated",
"mofa=designated",
"moped=no",
"speed_pedelec=no",
"speed_pedelec=yes",
"segregated=yes"
],
"icon": {
@ -1675,4 +1675,4 @@
"fr": "Toutes les infrastructures sur lesquelles quelqu'un peut rouler, accompagnées de questions sur cette infrastructure",
"ca": "Totes les infraestructures per les quals algú pot ciclar, acompanyades de preguntes sobre aquesta infraestructura"
}
}
}

View file

@ -0,0 +1,12 @@
[
{
"path": "parking_tickets.svg",
"license": "CC0",
"authors": [
"Jérémy Ragusa"
],
"sources": [
"https://github.com/gravitystorm/openstreetmap-carto/blob/master/symbols/amenity/parking_tickets.svg"
]
}
]

View file

@ -0,0 +1,79 @@
{
"id": "parking_ticket_machine",
"name": {
"en": "Parking Ticket Machines",
"nl": "Parkeerkaartautomaten"
},
"description": {
"en": "Layer with parking ticket machines to pay for parking.",
"nl": "Laag met parkeerkaartautomaten om voor parkeren te betalen."
},
"title": {
"render": {
"en": "Parking Ticket Machine",
"nl": "Parkeerkaartautomaat"
}
},
"source": {
"osmTags": {
"and": [
"amenity=vending_machine",
"vending=parking_tickets"
]
}
},
"minzoom": 16,
"presets": [
{
"tags": [
"amenity=vending_machine",
"vending=parking_tickets"
],
"title": {
"en": "a parking ticket machine",
"nl": "een parkeerkaartautomaat"
}
}
],
"tagRenderings": [
"images",
"payment-options-split",
"denominations-coins",
"denominations-notes",
{
"id": "ref",
"question": {
"en": "What is the reference number of this parking ticket machine?",
"nl": "Wat is het referentienummer van deze parkeerkaartautomaat?"
},
"freeform": {
"key": "ref",
"type": "string",
"placeholder": {
"en": "Reference number",
"nl": "Referentienummer"
}
},
"render": {
"en": "This parking ticket machine has the reference number {ref}",
"nl": "Deze parkeerkaartautomaat heeft het referentienummer {ref}"
},
"mappings": [
{
"if": "noref=yes",
"then": {
"en": "This parking ticket machine has no reference number",
"nl": "Deze parkeerkaartautomaat heeft geen referentienummer"
}
}
]
}
],
"mapRendering": [
{
"location": ["point", "centroid"],
"icon": "square:white;./assets/layers/parking_ticket_machine/parking_tickets.svg",
"iconSize": "20,20,center"
}
]
}

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
<path d="m0,0 v3 h1 v-2 h12 v2 h1 v-3 z m3,2 v12 h3 v-1 a1,1 0 0 1 2,0 v1 h3 v-12 h-1 v11 h-1 a2,2 0 0 0 -4,0 h-1 v-11 z m2,2 v6 h1 v-2.5 h1.6666 c 1.7777,0 1.7777,-3.5 0,-3.5 z m1,0.875 h1.4453 c0.9364,0 0.9364,1.75 0,1.75 h-1.4453 z"/>
</svg>

After

Width:  |  Height:  |  Size: 330 B

View file

@ -1053,6 +1053,44 @@
"it": "Quali sono gli orari di apertura di questo impianto di raccolta e riciclo?"
}
}
},
{
"id": "access",
"question": {
"en": "Who can use this recycling facility?",
"nl": "Wie kan deze recyclingfaciliteit gebruiken?"
},
"mappings": [
{
"if": "access=yes",
"then": {
"en": "Everyone can use this recycling facility",
"nl": "Iedereen mag deze recyclingfaciliteit gebruiken"
}
},
{
"if": "access=residents",
"then": {
"en": "Only residents can use this recycling facility",
"nl": "Enkel bewoners kunnen deze recyclingfaciliteit gebruiken"
}
},
{
"if": "access=private",
"then": {
"en": "This recycling facility is only for private use",
"nl": "Deze recyclingfaciliteit is alleen voor privégebruik"
}
}
],
"freeform": {
"key": "access",
"type": "string"
},
"render": {
"en": "This recycling facility can be used by {access}",
"nl": "Deze recyclingfaciliteit kan gebruikt worden door {access}"
}
}
],
"filter": [
@ -1262,6 +1300,28 @@
"osmTags": "recycling:waste=yes"
}
]
},
{
"#": "ignore-possible-duplicate",
"id": "public-access",
"options": [
{
"question": {
"en": "Only public access",
"nl": "Enkel publiek toegankelijke afvalcontainers",
"de": "Nur öffentliche Mülltonnen",
"it": "Solo accesso pubblico",
"id": "Hanya akses publik",
"da": "Kun offentlig adgang"
},
"osmTags": {
"or": [
"access=yes",
"access="
]
}
}
]
}
],
"deletion": {

View file

@ -66,7 +66,8 @@
]
},
"payment-options-split",
"denominations-coins"
"denominations-coins",
"denominations-notes"
],
"presets": [
{

View file

@ -64,6 +64,31 @@
}
],
"tagRenderings": [
"images",
{
"id": "type",
"description": "Mapping allowing to change between waste_disposal and recycling",
"question": {
"en": "What kind of waste disposal bin is this?"
},
"mappings": [
{
"if": "amenity=waste_disposal",
"then": {
"en": "This is a medium to large bin for disposal of (household) waste"
}
},
{
"if": "amenity=recycling",
"then": {
"en": "This is actually a recycling container"
},
"addExtraTags": [
"recycling_type=container"
]
}
]
},
{
"id": "access",
"render": {

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 234 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 109 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 121 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 118 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 107 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 186 KiB

View file

@ -1,4 +1,15 @@
[
{
"path": "100euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311346/worksheet-100-euro-coloured"
]
},
{
"path": "10cent.svg",
"license": "CC0",
@ -10,6 +21,17 @@
"https://openclipart.org/detail/311337/worksheet-10-cent-coloured"
]
},
{
"path": "10euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311343/worksheet-10-euro-coloured"
]
},
{
"path": "1cent.svg",
"license": "CC0",
@ -32,6 +54,17 @@
"https://openclipart.org/detail/311340/worksheet-1-euro-coloured"
]
},
{
"path": "200euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311347/worksheet-200-euro-coloured"
]
},
{
"path": "20cent.svg",
"license": "CC0",
@ -43,6 +76,17 @@
"https://openclipart.org/detail/311338/worksheet-20-cent-coloured"
]
},
{
"path": "20euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311344/worksheet-20-euro-coloured"
]
},
{
"path": "2cent.svg",
"license": "CC0",
@ -65,6 +109,17 @@
"https://openclipart.org/detail/311341/worksheet-2-euro-coloured"
]
},
{
"path": "500euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311348/worksheet-500-euro-coloured"
]
},
{
"path": "50cent.svg",
"license": "CC0",
@ -76,6 +131,17 @@
"https://openclipart.org/detail/311339/worksheet-50-cent-coloured"
]
},
{
"path": "50euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311345/worksheet-50-euro-coloured"
]
},
{
"path": "5cent.svg",
"license": "CC0",
@ -87,6 +153,17 @@
"https://openclipart.org/detail/311336/worksheet-5-cent-coloured"
]
},
{
"path": "5euro.svg",
"license": "CC0",
"authors": [
"OpenClipart",
"frankes"
],
"sources": [
"https://openclipart.org/detail/311342/worksheet-5-euro-coloured"
]
},
{
"path": "audio_induction_loop.svg",
"license": "CC-BY 4.0",

View file

@ -1195,6 +1195,105 @@
}
]
},
"denominations-notes": {
"condition": {
"and": [
{
"or": [
"payment:notes=yes",
"payment:cash=yes"
]
},
{
"or": [
"_country=at",
"_country=be",
"_country=cy",
"_country=de",
"_country=ee",
"_country=es",
"_country=fi",
"_country=fr",
"_country=gr",
"_country=hr",
"_country=ie",
"_country=it",
"_country=lt",
"_country=lu",
"_country=lv",
"_country=mt",
"_country=nl",
"_country=pt",
"_country=si",
"_country=sk"
]
}
]
},
"question": {
"en": "what notes can you use to pay here?",
"nl": "Met welke bankbiljetten kan je hier betalen?"
},
"multiAnswer": true,
"mappings": [
{
"if": "payment:notes:denominations=5 EUR",
"icon": "./assets/tagRenderings/5euro.svg",
"then": {
"en": "5 euro notes are accepted",
"nl": "Biljetten van 5 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=10 EUR",
"icon": "./assets/tagRenderings/10euro.svg",
"then": {
"en": "10 euro notes are accepted",
"nl": "Biljetten van 10 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=20 EUR",
"icon": "./assets/tagRenderings/20euro.svg",
"then": {
"en": "20 euro notes are accepted",
"nl": "Biljetten van 20 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=50 EUR",
"icon": "./assets/tagRenderings/50euro.svg",
"then": {
"en": "50 euro notes are accepted",
"nl": "Biljetten van 50 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=100 EUR",
"icon": "./assets/tagRenderings/100euro.svg",
"then": {
"en": "100 euro notes are accepted",
"nl": "Biljetten van 100 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=200 EUR",
"icon": "./assets/tagRenderings/200euro.svg",
"then": {
"en": "200 euro notes are accepted",
"nl": "Biljetten van 200 euro worden geaccepteerd"
}
},
{
"if": "payment:notes:denominations=500 EUR",
"icon": "./assets/tagRenderings/500euro.svg",
"then": {
"en": "500 euro notes are accepted",
"nl": "Biljetten van 500 euro worden geaccepteerd"
}
}
]
},
"last_edit": {
"#": "Gives some metainfo about the last edit and who did edit it - rendering only",
"condition": "_last_edit:contributor~*",

View file

@ -49,6 +49,7 @@
"widenFactor": 1.2,
"layers": [
"parking",
"parking_spaces"
"parking_spaces",
"parking_ticket_machine"
]
}

View file

@ -225,13 +225,13 @@
"loadingCountry": "Determining country…",
"not_all_rules_parsed": "These opening hours are complicated. The following rules are ignored in the input element:",
"openTill": "till",
"open_24_7": "Opened around the clock",
"open_24_7": "Open around the clock",
"open_during_ph": "During a public holiday, this is",
"opensAt": "from",
"ph_closed": "closed",
"ph_not_known": " ",
"ph_open": "opened",
"ph_open_as_usual": "opened as usual"
"ph_open": "open",
"ph_open_as_usual": "open, as usual"
},
"osmLinkTooltip": "Browse this object on OpenStreetMap for history and more editing options",
"pdf": {

View file

@ -127,13 +127,35 @@
},
"11": {
"then": "Enrajolat"
},
"12": {
"then": "Tallat a la fusta"
}
},
"question": "Quin tipus d'obra és aquesta peça?",
"render": "Aquesta és un {artwork_type}"
},
"artwork-website": {
"question": "Hi ha un lloc web amb més informació sobre aquesta obra d'art?"
"question": "Hi ha un lloc web amb més informació sobre aquesta obra d'art?",
"render": "Més informació a <a href='{website}' target='_blank'>aquesta pàgina web</a>"
},
"doubles_as_bench": {
"question": "Aquesta obra d'art serveix com a un banc?",
"mappings": {
"1": {
"then": "Aquesta obra d'art no serveix com a banc"
},
"0": {
"then": "Aquesta obra d'art també serveix com a banc"
},
"2": {
"then": "Aquesta obra d'art no serveix com a un banc"
}
}
},
"artwork_subject": {
"question": "Què representa aquesta obra d'art?",
"render": "Aquesta obra d'art representa {wikidata_label(subject:wikidata)}{wikipedia(subject:wikidata)}"
}
},
"title": {
@ -155,24 +177,42 @@
},
"tagRenderings": {
"brand": {
"question": "De quina marca és aquest caixer?"
"question": "De quina marca és aquest caixer?",
"freeform": {
"placeholder": "Nom de la marca"
},
"render": "La marca d'aquest caixer és {brand}"
},
"cash_in": {
"mappings": {
"0": {
"then": "Probablement no pots ingressar diners a aquest caixer"
},
"1": {
"then": "Pots dipositar diners a aquest caixer"
},
"2": {
"then": "No pots dipositar diners a aquest caixer"
}
}
},
"question": "Pots dipositar diners a aquest caixer?"
},
"cash_out": {
"mappings": {
"0": {
"then": "Pots retirar diners a aquest caixer"
},
"1": {
"then": "Pots retirar diners des d'aquest caixer"
},
"2": {
"then": "No pots retirar diners des d'aquest caixer"
}
}
},
"question": "Pots retirar diners des d'aquest caixer?"
},
"name": {
"render": "El daquest caixer és {name}"
"render": "El nom d'aquest caixer és {name}"
},
"speech_output": {
"mappings": {
@ -184,11 +224,48 @@
}
},
"question": "Aquest caixer té un lector de pantalla per a usuaris amb discapacitat visual?"
},
"speech_output_language": {
"render": {
"special": {
"render_single_language": "Aquest caixer té sortida de veu en {language():font-bold}",
"question": "En quins idiomes té sortida de veu aquest caixer?",
"render_list_item": "Aquest caixer té sortida de veu en {language():font-bold}"
}
}
},
"operator": {
"render": "{operator} opera aquest caixer",
"question": "Quina companyia opera aquest caixer?",
"freeform": {
"placeholder": "Operador"
}
}
},
"title": {
"render": "Caixer Automàtic"
},
"filter": {
"1": {
"options": {
"0": {
"question": "Amb sortida de veu"
}
}
}
}
},
"bank": {
"name": "Bancs"
"name": "Bancs",
"tagRenderings": {
"has_atm": {
"mappings": {
"2": {
"then": "Aquest banc té un caixer, però està mapejat com a un element diferent"
}
}
}
}
},
"barrier": {
"name": "Barreres",
@ -236,6 +313,13 @@
"then": "Un ciclista pot passar-hi."
}
}
},
"Cycle barrier type": {
"mappings": {
"0": {
"then": "Simple, simplement dos barreres amb un espai al mig"
}
}
}
},
"title": {
@ -1072,6 +1156,49 @@
"then": "Via ciclista obligatòria"
}
}
},
"Surface of the street": {
"mappings": {
"0": {
"then": "Utilitzable per rodets: patins en línia, monopatí"
},
"1": {
"then": "Utilitzable per rodes fines: bicicletes de carrera"
},
"2": {
"then": "Utilitzable per rodes normals: Bicicletes de ciutat, cadires de rodes, scooter"
},
"3": {
"then": "Utilitzable per rodes robustes; Bicicleta de treking, cotxes, bicitaxi"
}
}
},
"Surface of the road": {
"mappings": {
"8": {
"then": "Aquest carril bici està fet de fusta"
},
"2": {
"then": "Aquest carril bici està fet d'asfalt"
},
"4": {
"then": "Aquest carril bici està fet de formigó"
},
"1": {
"then": "Aquest carril bici està pavimentat"
}
},
"question": "De què està feta la superfície d'aquest carrer?",
"render": "Aquesta carretera està feta de {surface}"
},
"Maxspeed (for road)": {
"question": "Quina és la velocitat màxima a aquest carrer?",
"mappings": {
"4": {
"then": "La velocitat màxima és de 90km/h"
}
},
"render": "La velocitat màxima a aquesta carretera és {maxspeed} km/h"
}
},
"title": {
@ -1315,7 +1442,8 @@
"then": "Aquesta estació l'opera una entitat privada."
}
},
"question": "Com es classifica l'operador de l'estació?"
"question": "Com es classifica l'operador de l'estació?",
"render": "Aquest operador és una entitat {operator:type}."
},
"station-place": {
"question": "On es troba aquesta estació? (p.e. nom del barri, poble o ciutat)",
@ -1324,7 +1452,11 @@
"station-street": {
"question": " Quin és el nom del carrer on es troba aquesta estació?"
}
}
},
"title": {
"render": "Parc de bombers"
},
"description": "Capa del mapa que mostra els parcs de bombers."
},
"food": {
"presets": {
@ -1631,6 +1763,12 @@
"tagRenderings": {
"Email": {
"render": "<a href='mailto:{email}' target='_blank'>{email}</a>"
},
"Name tag": {
"render": ""
},
"Surface area": {
"render": "Superfície: {_surface:ha}Ha"
}
}
},
@ -2292,6 +2430,13 @@
"then": "La superfície és <b>formigó</b>"
}
}
},
"sport_pitch-opening_hours": {
"mappings": {
"0": {
"then": "Sempre accesible"
}
}
}
},
"title": {
@ -2406,6 +2551,9 @@
"mappings": {
"4": {
"then": "Aquest fanal està muntat en un pal"
},
"6": {
"then": "Aquest fanal està muntat a la paret utilitzat una barra metàl·lica"
}
}
}
@ -2716,6 +2864,13 @@
}
},
"question": "Aquesta parada té una superfície podotàctil?"
},
"departures_board": {
"mappings": {
"2": {
"then": "Aquesta parada té un tauló amb els horaris en temps real"
}
}
}
}
},
@ -2859,5 +3014,9 @@
}
}
}
},
"fitness_centre": {
"description": "Capa que mostra centres de fitnes o gimnasos",
"name": "Centre de fitnes o gimnàs"
}
}
}

View file

@ -7191,6 +7191,12 @@
"render_single_language": "Die Treppe hat taktile Schrift in {language():font-bold}"
}
}
},
"multilevels": {
"override": {
"question": "Zwischen welchen Stockwerken befindet sich die Treppe?",
"render": "Die Treppe befindet sich zwischen den Stockwerken {level}"
}
}
},
"title": {
@ -7571,6 +7577,18 @@
},
"question": "Wer ist der Betreiber dieses Fahrkartenentwerters?",
"render": "Dieser Fahrkartenentwerter wird betrieben von {operator}"
},
"payment-options": {
"override": {
"mappings+": {
"1": {
"then": "Dieser Fahrkartenentwerter akzeptiert OV-Chipkaart"
},
"0": {
"then": "Dieser Fahrkartenentwerter akzeptiert OV-Chipkaart"
}
}
}
}
},
"title": {
@ -7837,6 +7855,11 @@
"wheelchair-door-width": {
"question": "Wie breit ist die Tür zur rollstuhlgerechten Toilette?",
"render": "Die Tür zur rollstuhlgerechten Toilette ist {canonical(toilets:door:width)} breit"
},
"opening_hours": {
"override": {
"question": "Wann ist die Einrichtung, in der sich diese Toiletten befinden, geöffnet?"
}
}
},
"title": {
@ -8551,4 +8574,4 @@
}
}
}
}
}

View file

@ -3004,6 +3004,27 @@
}
},
"question": "Wat voor oversteekplaats is dit?"
},
"crossing-vibration": {
"mappings": {
"1": {
"then": "De knop bij dit verkeerslicht kan <b>niet</b> trillen om aan te geven dat men veilig kan oversteken."
},
"0": {
"then": "De knop bij dit verkeerslicht trilt om aan te geven dat men veilig kan oversteken."
}
},
"question": "Heeft dit verkeerslicht een element dat trilt om te helpen bij het oversteken? (meestal onderaan de oversteekknop geplaatst)"
},
"crossing-minimap": {
"mappings": {
"0": {
"then": "Dit verkeerlicht heeft een voelkaart die de indeling van de oversteekplaats laat zien."
},
"1": {
"then": "Dit verkeerlicht heeft <b>geen</b> voelkaart die de indeling van de oversteekplaats laat zien."
}
}
}
},
"title": {
@ -8360,4 +8381,4 @@
}
}
}
}
}

59
package-lock.json generated
View file

@ -39,6 +39,7 @@
"osm-auth": "^1.0.2",
"osmtogeojson": "^3.0.0-beta.5",
"papaparse": "^5.3.1",
"pic4carto": "^2.1.15",
"prompt-sync": "^4.2.0",
"showdown": "^2.1.0",
"svg-path-parser": "^1.1.0",
@ -2035,6 +2036,17 @@
"geojson-rewind": "geojson-rewind"
}
},
"node_modules/@mapbox/sphericalmercator": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz",
"integrity": "sha512-ZTOuuwGuMOJN+HEmG/68bSEw15HHaMWmQ5gdTsWdWsjDe56K1kGvLOK6bOSC8gWgIvEO0w6un/2Gvv1q5hJSkQ==",
"bin": {
"bbox": "bin/bbox.js",
"to4326": "bin/to4326.js",
"to900913": "bin/to900913.js",
"xyz": "bin/xyz.js"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -6684,6 +6696,11 @@
"xmldom": "^0.1.21"
}
},
"node_modules/kdbush": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz",
"integrity": "sha512-Y75c18KdvLKRmqHc0u2WUYud1vEj54i+8SNBxsowr6LJJsnNUJ8KK8cH7uHDpC5U66NNlieEzVxeWipZaYfN0w=="
},
"node_modules/latlon2country": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/latlon2country/-/latlon2country-1.2.6.tgz",
@ -7573,6 +7590,21 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"node_modules/pic4carto": {
"version": "2.1.15",
"resolved": "https://registry.npmjs.org/pic4carto/-/pic4carto-2.1.15.tgz",
"integrity": "sha512-A1jvSWeX7siZbmY1wr7rGk6ElWeulaP+WQR3/Rpkqe7rnCKYPErc+jtp7lDOGw4TzMp57wARoA47TVleL/70ZA==",
"dependencies": {
"@mapbox/sphericalmercator": "^1.1.0",
"csv-parse": "^1.2.3",
"kdbush": "^1.0.1"
}
},
"node_modules/pic4carto/node_modules/csv-parse": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.3.3.tgz",
"integrity": "sha512-byxnDBxM1AVF3YfmsK7Smop9/usNz7gAZYSo9eYp61TGcNXraJby1rAiLyJSt1/8Iho2qaxZOtZCOvQMXogPtg=="
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@ -11972,6 +12004,11 @@
"minimist": "^1.2.6"
}
},
"@mapbox/sphericalmercator": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz",
"integrity": "sha512-ZTOuuwGuMOJN+HEmG/68bSEw15HHaMWmQ5gdTsWdWsjDe56K1kGvLOK6bOSC8gWgIvEO0w6un/2Gvv1q5hJSkQ=="
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -15557,6 +15594,11 @@
"xmldom": "^0.1.21"
}
},
"kdbush": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz",
"integrity": "sha512-Y75c18KdvLKRmqHc0u2WUYud1vEj54i+8SNBxsowr6LJJsnNUJ8KK8cH7uHDpC5U66NNlieEzVxeWipZaYfN0w=="
},
"latlon2country": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/latlon2country/-/latlon2country-1.2.6.tgz",
@ -16229,6 +16271,23 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
},
"pic4carto": {
"version": "2.1.15",
"resolved": "https://registry.npmjs.org/pic4carto/-/pic4carto-2.1.15.tgz",
"integrity": "sha512-A1jvSWeX7siZbmY1wr7rGk6ElWeulaP+WQR3/Rpkqe7rnCKYPErc+jtp7lDOGw4TzMp57wARoA47TVleL/70ZA==",
"requires": {
"@mapbox/sphericalmercator": "^1.1.0",
"csv-parse": "^1.2.3",
"kdbush": "^1.0.1"
},
"dependencies": {
"csv-parse": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-1.3.3.tgz",
"integrity": "sha512-byxnDBxM1AVF3YfmsK7Smop9/usNz7gAZYSo9eYp61TGcNXraJby1rAiLyJSt1/8Iho2qaxZOtZCOvQMXogPtg=="
}
}
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",

View file

@ -47,9 +47,8 @@
"weblate-add-upstream": "git remote add weblate-github git@github.com:weblate/MapComplete.git",
"weblate-merge": "git remote update weblate-github; git merge weblate-github/weblate-mapcomplete-core weblate-github/weblate-mapcomplete-layers weblate-github/weblate-mapcomplete-layer-translations",
"weblate-fix-heavy": "git remote rm weblate-layers; git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layers/; git remote update weblate-layers; git merge weblate-layers/master",
"housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && npm run format && git add assets/ langs/ Docs/ **/*.ts Docs/* && git commit -m 'Housekeeping...'",
"parseSchools": "ts-node scripts/schools/amendSchoolData.ts",
"steal": "ts-node scripts/fetchLanguages.ts"
"housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && ts-node scripts/fetchLanguages.ts && npm run format && git add assets/ langs/ Docs/ **/*.ts Docs/* && git commit -m 'Housekeeping...'",
"parseSchools": "ts-node scripts/schools/amendSchoolData.ts"
},
"keywords": [
"OpenStreetMap",
@ -94,6 +93,7 @@
"osm-auth": "^1.0.2",
"osmtogeojson": "^3.0.0-beta.5",
"papaparse": "^5.3.1",
"pic4carto": "^2.1.15",
"prompt-sync": "^4.2.0",
"showdown": "^2.1.0",
"svg-path-parser": "^1.1.0",

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
import fs, { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "fs"
import { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "fs"
import ScriptUtils from "./ScriptUtils"
import { Utils } from "../Utils"
import Script from "./Script"
@ -56,9 +56,9 @@ class StatsDownloader {
}.day.json`
writtenFiles.push(path)
if (existsSync(path)) {
let features = JSON.parse(readFileSync(path, { encoding: "utf-8" }))
features = features?.features ?? features
features.push(...features.features) // day-stats are generally a list already, but in some ad-hoc cases might be a geojson-collection too
let loadedFeatures = JSON.parse(readFileSync(path, { encoding: "utf-8" }))
loadedFeatures = loadedFeatures?.features ?? loadedFeatures
features.push(...loadedFeatures) // day-stats are generally a list already, but in some ad-hoc cases might be a geojson-collection too
console.log(
"Loaded ",
path,
@ -296,7 +296,7 @@ class GenerateSeries extends Script {
features.forEach((f) => {
delete f.bbox
})
fs.writeFileSync(
writeFileSync(
path,
JSON.stringify(
{

View file

@ -7,10 +7,22 @@ import * as wds from "wikidata-sdk"
import { Utils } from "../Utils"
import ScriptUtils from "./ScriptUtils"
import { existsSync, readFileSync, writeFileSync } from "fs"
import { QuestionableTagRenderingConfigJson } from "../Models/ThemeConfig/Json/QuestionableTagRenderingConfigJson"
import { LayerConfigJson } from "../Models/ThemeConfig/Json/LayerConfigJson"
import WikidataUtils from "../Utils/WikidataUtils"
import LanguageUtils from "../Utils/LanguageUtils"
import Wikidata from "../Logic/Web/Wikidata"
interface value<T> {
value: T
type: "uri" | "literal" | string
"xml:lang"?: string
}
interface LanguageSpecResult {
directionalityLabel: value<string | "right-to-left" | "left-to-right">
lang: value<string>
code: value<string>
label: value<string>
}
async function fetch(target: string) {
const regular = await fetchRegularLanguages()
@ -36,33 +48,52 @@ async function fetchRegularLanguages() {
// request the generated URL with your favorite HTTP request library
const result = await Utils.downloadJson(url, { "User-Agent": "MapComplete script" })
const bindings = result.results.bindings
const bindings = <LanguageSpecResult[]>result.results.bindings
const zh_hant = await fetchSpecial(18130932, "zh_Hant")
const zh_hans = await fetchSpecial(13414913, "zh_Hant")
const pt_br = await fetchSpecial(750553, "pt_BR")
const punjabi = await fetchSpecial(58635, "pa_PK")
const Shahmukhi = await Wikidata.LoadWikidataEntryAsync(133800)
punjabi.forEach((item) => {
const neededLanguage = item.label["xml:lang"]
const native = Shahmukhi.labels.get(neededLanguage) ?? Shahmukhi.labels.get("en")
item.label.value = item.label.value + " (" + native + ")"
})
const fil = await fetchSpecial(33298, "fil")
bindings.push(...zh_hant)
bindings.push(...zh_hans)
bindings.push(...pt_br)
bindings.push(...fil)
bindings.push(...punjabi)
return result.results.bindings
}
async function fetchSpecial(id: number, code: string) {
/**
* Fetches the object as is. Sets a 'code' binding as predifined value
* @param id
* @param code
*/
async function fetchSpecial(id: number, code: string): Promise<LanguageSpecResult[]> {
ScriptUtils.fixUtils()
console.log("Fetching languages")
const lang = " wd:Q" + id
const sparql =
"SELECT ?lang ?label ?code \n" +
"SELECT ?label ?directionalityLabel \n" +
"WHERE \n" +
"{ \n" +
" wd:Q" +
id +
" rdfs:label ?label. \n" +
lang +
" rdfs:label ?label." +
lang +
" wdt:P282 ?writing_system. \n" +
" ?writing_system wdt:P1406 ?directionality. \n" +
' SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } \n' +
"} "
console.log("Special sparql:", sparql)
const url = wds.sparqlQuery(sparql)
const result = await Utils.downloadJson(url, { "User-Agent": "MapComplete script" })