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 untrusted user: Robin-van-der-Linde
GPG key ID: 53956B3252478F0D
11 changed files with 448 additions and 21 deletions

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));