forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			322 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			322 lines
		
	
	
	
		
			10 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
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("https://overpass-api.de/api/interpreter", criteria)
 | 
						||
        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()
 |