mapcomplete/scripts/importscripts/cleanRepair.ts

322 lines
10 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import Script from "../Script"
import { writeFileSync } from "fs"
import { Feature, Geometry } from "geojson"
import { OsmObject } from "../../src/Logic/Osm/OsmObject"
import OsmObjectDownloader from "../../src/Logic/Osm/OsmObjectDownloader"
import { Changes } from "../../src/Logic/Osm/Changes"
import { ImmutableStore } from "../../src/Logic/UIEventSource"
import { OsmConnection } from "../../src/Logic/Osm/OsmConnection"
import ChangeTagAction from "../../src/Logic/Osm/Actions/ChangeTagAction"
import { Tag } from "../../src/Logic/Tags/Tag"
import { ChangeDescription } from "../../src/Logic/Osm/Actions/ChangeDescription"
import { GeoOperations } from "../../src/Logic/GeoOperations"
import { Overpass } from "../../src/Logic/Osm/Overpass"
import { TagUtils } from "../../src/Logic/Tags/TagUtils"
import { BBox } from "../../src/Logic/BBox"
export default class CleanRepair extends Script {
constructor() {
super("Cleans 'repair'-tags for mass retagging")
}
async main(args: string[]) {
const path = args[0]
console.log("Loading", path)
const criteria = TagUtils.Tag({
and: [
"repair~*",
"repair!=no",
"repair!=yes",
"repair!=brand",
"repair!=only",
"repair!=only_sold",
"repair!=assisted_self_service",
],
})
const overpass = new Overpass(criteria, [], "https://overpass-api.de/api/interpreter")
const data: Feature<Geometry, Record<string, string>>[] = (
await overpass.queryGeoJson(BBox.global)
)[0].features
console.log("Got", data.length, "features; sample", data[0])
const changes = new Changes({
dryRun: new ImmutableStore(true),
osmConnection: new OsmConnection({
dryRun: new ImmutableStore(true),
}),
})
const metakeys = ["id", "version", "changeset", "user", "uid", "timestamp"]
const replace = {
phone: "mobile_phone",
phones: "mobile_phone",
mobile: "mobile_phone",
cellphone: "mobile_phone",
pc: "computers",
mobile_phones: "mobile_phone",
mobilephones: "mobile_phone",
mobilephone: "mobile_phone",
clocks: "clock",
elektronik: "electronics",
tires: "tyres",
welcome: "yes",
tyre: "tyres",
electronic_products: "electronics",
shoe: "shoes",
pc_repairs: "computer",
computers: "computer",
body_construction: "body_work",
body: "body_work",
body_repairer: "body_work",
instruments: "musical_instrument",
service: "yes",
punture: "tyres",
electricity: "electronics",
self_service: "assisted_self_repair",
paint: "bodywork",
"paint shop": "bodywork",
paint_shop: "bodywork",
lawnmower: "lawn_mower",
aircon: "air_conditioning",
"*": "yes",
ammeublement: "furniture",
all: "yes",
appliances: "appliance",
electronic: "electronics",
escooter: "electric_scooter",
"aviation maintenance, repair, and_overhaul": "airplane",
aviation_maintenance: "airplanes",
bags: "bag",
boats: "boat",
boilers: "boiler",
breaks: "brakes",
car: "cars",
tv: "television",
clothing: "clothes",
coat_of_lacquer: "body_work",
cycle: "bicycle",
cars: "car",
blacharstwo: "tin",
lakiernictwo: "body_work",
tire: "tyres",
powder_coating: "body_work",
leather_products: "leather",
motocycle: "motorcycle",
motor: "motorcycle",
motoo: "motorcycle",
motorbike: "motorcycle",
motorcycle_repair: "motorcycle",
motorsports: "motorcycle",
printers: "printer",
tyres24: "tyres",
paintings: "painting",
paintwork: "body_work",
pumps: "pump",
"shoes:yes": "shoes",
wheel: "tyres",
wheels: "tyres",
vacuum: "vacuum_cleaner",
glass: "car_glassj",
}
const brands = [
"garage",
"audi",
"renault",
"apple",
"honda",
"ducati",
"ford",
"mazda",
"garage_renault_aie",
]
const valid = [
"train",
"tv",
"jewelry",
"scooter",
...Object.values(replace),
"watch",
"oldtimer",
"car",
"bicycle",
"boat",
"windbreaker",
"agricultural",
"alternator",
"antiques",
"atv",
"auto",
"aviation maintenance",
"bag",
"bags",
"battery",
"bicyle",
"borehole",
"building",
"camera",
"car_glass",
"caravan",
"carpenter",
"coffee_machine",
"construction machinery",
"cycle",
"dentures",
"ducati",
"electric motor",
"electric_bike",
"electric_scooter",
"espresso_machines",
"exhaust",
"fire_extinguishers",
"fountain_pen",
"fridge",
"garden_machinery",
"gas appliances",
"generator",
"glasses",
"golfcart",
"guitar",
"hammock",
"hardware",
"heating pumps",
"hifi",
"hvac",
"installation",
"jewellery",
"keys",
"kick_scooter",
"kitesurfing",
"tools",
"toys",
"tractor",
"trailer",
"transformer",
"truck",
"typewriter",
"sail",
"sewing_machine",
"ship",
"picture",
"pillow",
"plastic",
"cash_register",
"cnc",
"laptop",
"laundry_machines",
"photo_camera",
"photocopier",
"piano",
"power_tools",
"pressure_gauges",
"printer",
,
"snowboard",
"snowmobile",
"starter",
"machines",
"mainframe",
"outboard_motor",
"video",
"washing_machine",
"ski",
"radiator",
"radio",
"refrigerator",
"rv",
"ski",
"window",
"zipper",
"weighing_scale",
"small_electric_vehicle",
].map((s) => s.replace(/ /g, "_"))
const skip = ["yes", "no", "only", "brand", "assisted_self_repair", "only_sold"]
const dloader = new OsmObjectDownloader()
const rm = [
"50243147100015",
"81342677200048",
"and overhaul",
"repair",
"unset",
"сервисный_центр",
"taller_de_michu",
"quitandinha_g_&_a",
"mechanika",
].map((v) => v.replace(/ /g, "_"))
const objects: OsmObject[] = []
const changesToMake: ChangeDescription[] = []
const first = GeoOperations.centerpointCoordinates(data[0])
for (const f of data) {
if (
GeoOperations.distanceBetween(first, GeoOperations.centerpointCoordinates(f)) >
2500000
) {
continue
}
let keyRaw = f.properties.repair
keyRaw = replace[keyRaw] ?? keyRaw
if (brands.some((br) => keyRaw.toLowerCase().indexOf(br.trim()) >= 0)) {
f.properties.repair = "brand"
}
if (skip.indexOf(keyRaw) >= 0) {
f.properties.repair = keyRaw
} else {
const r = keyRaw
.replace(/\/|,/g, ";")
.split(";")
.map((k) => k.trim().replace(/ /g, "_").toLowerCase())
for (let key of r) {
key = replace[key] ?? key
if (rm.indexOf(key) >= 0) {
delete f.properties.repair
continue
}
f.properties[key + ":repair"] = "yes"
delete f.properties.repair
}
}
if (f.properties.service === "repair") {
delete f.properties.service
f.properties.repair = "yes"
}
const id = f.properties["id"]
const osm = await dloader.DownloadObjectAsync(id)
if (osm === "deleted") {
continue
}
objects.push(osm)
for (const key in f.properties) {
if (metakeys.indexOf(key) >= 0) {
continue
}
const value = f.properties[key]
const ct = await new ChangeTagAction(id, new Tag(key, value), f.properties, {
changeType: "fix",
theme: "script",
}).CreateChangeDescriptions()
changesToMake.push(...ct)
console.log(ct.map((cd) => cd.tags))
if (f.properties.repair === undefined) {
const ct = await new ChangeTagAction(id, new Tag("repair", ""), f.properties, {
changeType: "fix",
theme: "script",
}).CreateChangeDescriptions()
changesToMake.push(...ct)
}
}
}
const changedObjects = changes.CreateChangesetObjects(changesToMake, objects)
const osc = Changes.buildChangesetXML("", changedObjects)
writeFileSync("Cleanup.osc", osc, "utf8")
}
}
new CleanRepair().run()