diff --git a/scripts/osm_cleanup/FixWikimediaInImageTag.ts b/scripts/osm_cleanup/FixWikimediaInImageTag.ts new file mode 100644 index 000000000..1b93fc6c7 --- /dev/null +++ b/scripts/osm_cleanup/FixWikimediaInImageTag.ts @@ -0,0 +1,95 @@ +import Script from "../Script" +import { Overpass } from "../../src/Logic/Osm/Overpass" +import Constants from "../../src/Models/Constants" +import { BBox } from "../../src/Logic/BBox" +import { RegexTag } from "../../src/Logic/Tags/RegexTag" +import { Tag } from "../../src/Logic/Tags/Tag" + +import { Feature, FeatureCollection } from "geojson" +import { existsSync, readFileSync, writeFileSync } from "fs" +import { Changes } from "../../src/Logic/Osm/Changes" +import ChangeTagAction from "../../src/Logic/Osm/Actions/ChangeTagAction" +import { And } from "../../src/Logic/Tags/And" +import { Lists } from "../../src/Utils/Lists" + +export class FixWikimediaInImageTag extends Script { + + constructor() { + super("For the given bbox, queries all `image=http(s)://commons.wikimedia.org` tags and replaces it with `commons`-tagging") + } + + + private handleFeature(f: Feature): ChangeTagAction { + const p = f.properties + const existingCommons = p["wikimedia_commons"] + const img = p["image"] + const id = p.id + if (!img) { + return undefined + } + + const extractedCommons: string = img.match(/^https?:\/\/commons.wikimedia.org\/wiki\/(.*)$/)[1] + console.log("Feature " + p.id + ": " + img + ", extr " + extractedCommons + ", old: " + existingCommons) + + + if (existingCommons === extractedCommons) { + return new ChangeTagAction(id, + new Tag("image", ""), + p, + { + changeType: "cleanup", + theme: "/" + } + ) + } + if (existingCommons) { + return undefined + } + if (!extractedCommons.startsWith("File:")) { + return undefined + } + return new ChangeTagAction(id, + new And([new Tag("image", ""), new Tag("wikimedia_commons", decodeURIComponent(extractedCommons))]), + p, + { + changeType: "cleanup", + theme: "/" + } + ) + } + + private async fetchData(bbox: BBox): Promise { + const pth = "fix_wikimedia_" + bbox.toLngLatFlat().join("_") + ".geojson" + if (existsSync(pth)) { + return JSON.parse(readFileSync(pth, "utf-8")) + } + const overpass = new Overpass(Constants.defaultOverpassUrls[0], + new RegexTag("image", /https?:\/\/commons.wikimedia.org/) + ) + const [feats] = await overpass.queryGeoJson(bbox) + writeFileSync(pth, JSON.stringify(feats), "utf8") + return feats + } + + async main(args: string[]): Promise { + if (args.length < 1) { + this.printHelp() + //return + } + + const bbox = new BBox([3.632100582083325, + 51.11343904784337, 3.8584183481742116, + 50.99383861993195]) + const feats = await this.fetchData(bbox) + + const actions = Lists.noNull(feats.features.map(f => this.handleFeature(f))) + + const xml = await Changes.createChangesetXMLForJosm(actions) + const pth = "move_image_to_wikimedia_commons_" + bbox.toLngLatFlat().join("_") + ".osc" + writeFileSync(pth, xml, "utf-8") + console.log("Written xml to file://" + pth) + + } +} + +new FixWikimediaInImageTag().run() diff --git a/src/Logic/Osm/Overpass.ts b/src/Logic/Osm/Overpass.ts index 3c9edd61b..c242367fc 100644 --- a/src/Logic/Osm/Overpass.ts +++ b/src/Logic/Osm/Overpass.ts @@ -3,7 +3,7 @@ import { Utils } from "../../Utils" import { ImmutableStore, Store } from "../UIEventSource" import { BBox } from "../BBox" import osmtogeojson from "osmtogeojson" -import { Feature } from "geojson" +import { Feature, FeatureCollection } from "geojson" ("use strict") /** @@ -37,7 +37,7 @@ export class Overpass { this._includeMeta = includeMeta } - public async queryGeoJson(bounds: BBox): Promise<[{features: T[]}, Date]> { + public async queryGeoJson(bounds: BBox): Promise<[{ features: T[] } & FeatureCollection, Date]> { const bbox = "[bbox:" + bounds.getSouth() + @@ -49,16 +49,16 @@ export class Overpass { bounds.getEast() + "]" const query = this.buildScript(bbox) - return await this.ExecuteQuery(query) + return await this.executeQuery(query) } public buildUrl(query: string) { return `${this._interpreterUrl}?data=${encodeURIComponent(query)}` } - private async ExecuteQuery( + private async executeQuery( query: string - ): Promise<[{features: T[]}, Date]> { + ): Promise<[{ features: T[] } & FeatureCollection, Date]> { const json = await Utils.downloadJson<{ elements: [] remark @@ -73,7 +73,7 @@ export class Overpass { console.warn("No features for", this.buildUrl(query)) } - const geojson = <{features: T[]}> osmtogeojson(json) + const geojson = <{ features: T[] } & FeatureCollection>osmtogeojson(json) const osmTime = new Date(json.osm3s.timestamp_osm_base) return [geojson, osmTime] }