Add hotel layer, conversion scripts

This commit is contained in:
Robin van der Linde 2022-07-14 15:17:09 +02:00
parent 64288ec1b8
commit f7506e07cd
Signed by: Robin-van-der-Linde
GPG key ID: 53956B3252478F0D
11 changed files with 448 additions and 21 deletions

View file

@ -0,0 +1,53 @@
{
"id": "hotel",
"name": {
"en": "Hotels",
"nl": "Hotels"
},
"description": {
"en": "Layer showing all hotels",
"nl": "Laag die alle hotels toont"
},
"source": {
"osmTags": "tourism=hotel"
},
"mapRendering": [
{
"location": [
"point",
"centroid"
],
"icon": "pin:white"
}
],
"tagRenderings": [
"images",
"reviews",
{
"id": "name",
"freeform": {
"key": "name",
"placeholder": {
"en": "Name of the hotel",
"nl": "Naam van het hotel"
}
},
"question": {
"en": "What is the name of this hotel?",
"nl": "Wat is de naam van dit hotel?"
},
"render": {
"en": "This hotel is called {name}",
"nl": "Dit hotel heet {name}"
}
},
"phone",
"email",
"website",
"wheelchair-access"
],
"allowMove": {
"enableImproveAccuracy": true,
"enableRelocation": true
}
}

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="M 0.5 3 C 0.223 3 0 3.223 0 3.5 L 0 4 L 0 8 L 0 9 L 0 9.5 L 0 11 L 1 11 L 1 9.5 L 1 9 L 13 9 L 13 10.5 L 13 11 L 13.5 11 L 14 11 L 14 10.5 L 14 9 L 14 8 L 14 6 L 14 5.5 C 14 5.223 13.777 5 13.5 5 C 13.223 5 13 5.223 13 5.5 L 13 6 L 13 8 L 1 8 L 1 4 L 1 3.5 C 1 3.223 0.777 3 0.5 3 z M 3.5 4 C 2.671573 4 2 4.671573 2 5.5 C 2 6.328427 2.671573 7 3.5 7 C 4.328427 7 5 6.328427 5 5.5 C 5 4.671573 4.328427 4 3.5 4 z M 6 5 L 6 7 L 12 7 C 12 6 10.963825 5 10 5 L 6 5 z"/>
</svg>

After

Width:  |  Height:  |  Size: 569 B

View file

@ -0,0 +1,15 @@
[
{
"path": "hotel.svg",
"license": "",
"authors": [
"Andy Allan",
"Michael Glanznig",
"Adamant36",
"Paul Dicker"
],
"sources": [
"https://github.com/gravitystorm/openstreetmap-carto/blob/master/symbols/tourism/hotel.svg"
]
}
]

View file

@ -1,13 +1,19 @@
{
"id": "mapcomplete-changes",
"title": {
"en": "Changes made with MapComplete"
"en": "Changes made with MapComplete",
"de": "Mit MapComplete vorgenommene Änderungen",
"nl": "Wijzigingen gemaakt met MapComplete"
},
"shortDescription": {
"en": "Shows changes made by MapComplete"
"en": "Shows changes made by MapComplete",
"de": "Zeigt die mit MapComplete vorgenommenen Änderungen",
"nl": "Toont wijzigingen gemaakt met MapComplete"
},
"description": {
"en": "This maps shows all the changes made with MapComplete"
"en": "This maps shows all the changes made with MapComplete",
"de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen",
"nl": "Deze kaart toont alle wijzigingen die met MapComplete werden gemaakt"
},
"maintainer": "",
"icon": "./assets/svg/logo.svg",
@ -22,7 +28,8 @@
{
"id": "mapcomplete-changes",
"name": {
"en": "Changeset centers"
"en": "Changeset centers",
"de": "Zentrum der Änderungssätze"
},
"minzoom": 0,
"source": {
@ -36,35 +43,47 @@
],
"title": {
"render": {
"en": "Changeset for {theme}"
"en": "Changeset for {theme}",
"de": "Änderungssatz für {theme}",
"nl": "Wijzigingset voor {theme}"
}
},
"description": {
"en": "Shows all MapComplete changes"
"en": "Shows all MapComplete changes",
"de": "Zeigt alle MapComplete Änderungen",
"nl": "Toont alle wijzigingen met MapComplete"
},
"tagRenderings": [
{
"id": "render_id",
"render": {
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
"en": "Changeset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>",
"de": "Änderungssatz <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>",
"nl": "Wijzigingset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
}
},
{
"id": "contributor",
"render": {
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
"en": "Change made by <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>",
"de": "Geändert von <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>",
"nl": "Wijziging gemaakt door <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
}
},
{
"id": "theme",
"render": {
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
"en": "Change with theme <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>",
"de": "Änderung mit Thema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>",
"nl": "Wijziging met thema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
},
"mappings": [
{
"if": "theme~http.*",
"then": {
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
"en": "Change with <b>unofficial</b> theme <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>",
"de": "Änderung mit <b>inoffiziellem</b> Thema <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>",
"nl": "Wijziging met <b>officieus</b> thema <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
}
}
]
@ -364,7 +383,9 @@
}
],
"question": {
"en": "Themename contains {search}"
"en": "Themename contains {search}",
"de": "Themenname enthält {search}",
"nl": "Themanaam bevat {search}"
}
}
]
@ -380,7 +401,9 @@
}
],
"question": {
"en": "Made by contributor {search}"
"en": "Made by contributor {search}",
"de": "Erstellt von {search}",
"nl": "Gemaakt door bijdrager {search}"
}
}
]
@ -396,7 +419,9 @@
}
],
"question": {
"en": "<b>Not</b> made by contributor {search}"
"en": "<b>Not</b> made by contributor {search}",
"de": "<b>Nicht</b> erstellt von {search}",
"nl": "<b>Niet</b> gemaakt door bijdrager {search}"
}
}
]
@ -411,7 +436,9 @@
{
"id": "link_to_more",
"render": {
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>"
"en": "More statistics can be found <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>here</a>",
"de": "Weitere Statistiken finden Sie <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>hier</a>",
"nl": "Meer statistieken kunnen <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>hier</a> gevonden worden"
}
},
{

View file

@ -27,7 +27,21 @@
"shops",
"toilet",
"viewpoint",
"doctors"
"doctors",
"hotel",
{
"builtin": "maproulette_challenge",
"override": {
"source": {
"geoJson": "https://maproulette.org/api/v2/challenge/view/28012"
},
"calculatedTags": [
"_closest_osm_hotel=feat.closest('hotel')?.properties?.id",
"_closest_osm_hotel_distance=feat.distanceTo(feat.properties._closest_osm_hotel)",
"_has_closeby_feature=Number(feat.properties._closest_osm_hotel_distance) < 50 ? 'yes' : 'no'"
]
}
}
],
"overrideAll": {
"minzoom": "15",

View file

@ -4061,6 +4061,19 @@
"render": "Hospital"
}
},
"hotel": {
"description": "Layer showing all hotels",
"name": "Hotels",
"tagRenderings": {
"name": {
"freeform": {
"placeholder": "Name of the hotel"
},
"question": "What is the name of this hotel?",
"render": "This hotel is called {name}"
}
}
},
"hydrant": {
"description": "Map layer to show fire hydrants.",
"name": "Map of hydrants",

View file

@ -3937,6 +3937,19 @@
"render": "Hackerspace"
}
},
"hotel": {
"description": "Laag die alle hotels toont",
"name": "Hotels",
"tagRenderings": {
"name": {
"freeform": {
"placeholder": "Naam van het hotel"
},
"question": "Wat is de naam van dit hotel?",
"render": "Dit hotel heet {name}"
}
}
},
"hydrant": {
"description": "Kaartlaag met brandkranen.",
"name": "Kaart van brandkranen",

23
package-lock.json generated
View file

@ -18,6 +18,7 @@
"@turf/length": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/chai": "^4.3.0",
"@types/geojson": "^7946.0.10",
"@types/jquery": "^3.5.5",
"@types/leaflet-markercluster": "^1.0.3",
"@types/leaflet-providers": "^1.2.0",
@ -3223,9 +3224,9 @@
"integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw=="
},
"node_modules/@types/geojson": {
"version": "7946.0.8",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
"version": "7946.0.10",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
},
"node_modules/@types/jquery": {
"version": "3.5.5",
@ -7170,6 +7171,11 @@
"rbush": "^3.0.1"
}
},
"node_modules/geojson-rbush/node_modules/@types/geojson": {
"version": "7946.0.8",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
},
"node_modules/geojson-rbush/node_modules/quickselect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
@ -19249,9 +19255,9 @@
"integrity": "sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw=="
},
"@types/geojson": {
"version": "7946.0.8",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
"version": "7946.0.10",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.10.tgz",
"integrity": "sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA=="
},
"@types/jquery": {
"version": "3.5.5",
@ -22417,6 +22423,11 @@
"rbush": "^3.0.1"
},
"dependencies": {
"@types/geojson": {
"version": "7946.0.8",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
"integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA=="
},
"quickselect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",

View file

@ -76,6 +76,7 @@
"@turf/length": "^6.5.0",
"@turf/turf": "^6.5.0",
"@types/chai": "^4.3.0",
"@types/geojson": "^7946.0.10",
"@types/jquery": "^3.5.5",
"@types/leaflet-markercluster": "^1.0.3",
"@types/leaflet-providers": "^1.2.0",

View file

@ -0,0 +1,100 @@
/**
* Class containing all constants and tables used in the script
*
* @class Constants
*/
export default class Constants {
/**
* Table used to determine tags for the category
*
* Keys are the original category names,
* values are an object containing the tags
*/
public static categories = {
restaurant: {
amenity: "restaurant",
},
parking: {
amenity: "parking",
},
hotel: {
leisure: "hotel",
},
wc: {
amenity: "toilets",
},
winkel: {
shop: "yes",
},
apotheek: {
amenity: "pharmacy",
healthcare: "pharmacy",
},
ziekenhuis: {
amenity: "hospital",
healthcare: "hospital",
},
bezienswaardigheid: {
tourism: "attraction",
},
ontspanning: {
fixme: "Needs proper tags",
},
cafe: {
amenity: "cafe",
},
dienst: {
fixme: "Needs proper tags",
},
bank: {
amenity: "bank",
},
gas: {
amenity: "fuel",
},
medical: {
fixme: "Needs proper tags",
},
obstacle: {
fixme: "Needs proper tags",
},
};
/**
* Table used to rename original Onwheels properties to their corresponding OSM properties
*
* Keys are the original Onwheels properties, values are the corresponding OSM properties
*/
public static names = {
ID: "id",
Naam: "name",
Straat: "addr:street",
Nummer: "addr:housenumber",
Postcode: "addr:postcode",
Plaats: "addr:city",
Website: "website",
Email: "email",
"Aantal aangepaste parkeerplaatsen": "capacity:disabled",
"Aantal treden": "step_count",
"Hellend vlak aanwezig": "ramp",
"Baby verzorging aanwezig": "changing_table",
"Totale hoogte van de treden": "kerb:height"
};
/**
* In some cases types might need to be converted as well
*
* Keys are the OSM properties, values are the wanted type
*/
public static types = {
"Hellend vlak aanwezig": "boolean",
"Baby verzorging aanwezig": "boolean",
};
/**
* Some tags also need to have units added
*/
public static units = {
"Totale hoogte van de treden": "cm",
};
}

View file

@ -0,0 +1,177 @@
import { parse } from "csv-parse/sync";
import { readFileSync, writeFileSync } from "fs";
import { Feature, FeatureCollection, GeoJsonProperties } from "geojson";
import Constants from "./constants";
/**
* Function to determine the tags for a category
*
* @param category The category of the item
* @returns List of tags for the category
*/
function categoryTags(category: string): GeoJsonProperties {
const tags = Constants.categories[category];
if (!tags) {
throw `Unknown category: ${category}`;
}
return tags;
}
/**
* Rename tags to match the OSM standard
*
* @param item The item to convert
* @returns GeoJsonProperties for the item
*/
function renameTags(item): GeoJsonProperties {
const properties: GeoJsonProperties = {};
for (const key in item) {
if (Constants.names[key] && item[key]) {
properties[Constants.names[key]] = item[key];
}
}
return properties;
}
function convertTypes(properties: GeoJsonProperties): GeoJsonProperties {
for (const property in properties) {
// Determine the original tag by looking at the value in the names table
const originalTag = Object.keys(Constants.names).find(
(tag) => Constants.names[tag] === property
);
// Check if we need to convert the value
if (Constants.types[originalTag]) {
switch (Constants.types[originalTag]) {
case "boolean":
properties[property] = properties[property] === "1" ? "yes" : "no";
break;
default:
break;
}
}
}
return properties;
}
/**
* Function to add units to the properties if necessary
*
* @param properties The properties to add units to
* @returns The properties with units added
*/
function addUnits(properties: GeoJsonProperties): GeoJsonProperties {
for (const property in properties) {
// Check if the property needs units, and doesn't already have them
if (Constants.units[property] && property.match(/.*([A-z]).*/gi) === null) {
properties[
property
] = `${properties[property]} ${Constants.units[property]}`;
}
}
return properties;
}
/**
* Main function to convert original CSV into GeoJSON
*
* @param args List of arguments [input.csv]
*/
function main(args: string[]): void {
const csvOptions = {
columns: true,
skip_empty_lines: true,
trim: true,
};
const file = args[0];
const output = args[1];
// Create an empty list to store the converted features
var items: Feature[] = [];
// Read CSV file
const csv: Record<any, string>[] = parse(readFileSync(file), csvOptions);
// Loop through all the entries
for (var i = 0; i < csv.length; i++) {
const item = csv[i];
// Determine coordinates
const lat = Number(item["Latitude"]);
const lon = Number(item["Longitude"]);
// Check if coordinates are valid
if (isNaN(lat) || isNaN(lon)) {
throw `Not a valid lat or lon for entry ${i}: ${JSON.stringify(item)}`;
}
// Create a new collection to store the converted properties
var properties: GeoJsonProperties = {};
// Add standard tags for category
const category = item["Categorie"];
properties = { ...properties, ...categoryTags(category) };
// Add the rest of the needed tags
properties = { ...properties, ...renameTags(item) };
// Convert types
properties = convertTypes(properties);
// Loop through all the properties
// for (var key in item) {
// // Check if we need the property, and it's not empty
// if (Constants.names[key] && item[key]) {
// // Check if the type needs to be converted
// if (Constants.types[key]) {
// // Conversion necessary, use the typeTable
// switch (Constants.types[key]) {
// case "boolean":
// properties[Constants.names[key]] =
// item[key] === "1" ? "yes" : "no";
// break;
// default:
// properties[Constants.names[key]] = item[key];
// break;
// }
// } else {
// // No conversion necessary, we can just add the property
// properties[Constants.names[key]] = item[key];
// }
// }
// }
// Add units if necessary
addUnits(properties);
// Create the new feature
const feature: Feature = {
type: "Feature",
id: item["ID"],
geometry: {
type: "Point",
coordinates: [lon, lat],
},
properties,
};
// Push it to the list we created earlier
items.push(feature);
}
// Make a FeatureCollection out of it
const featureCollection: FeatureCollection = {
type: "FeatureCollection",
features: items,
};
// Output the data to the console
console.log(JSON.stringify(featureCollection));
// Write the data to a file
if (output) {
writeFileSync(`${output}.geojson`, JSON.stringify(featureCollection, null, 2));
}
}
// Execute the main function, with the stripped arguments
main(process.argv.slice(2));