forked from MapComplete/MapComplete
merge develop
This commit is contained in:
commit
3e4708b0b9
506 changed files with 7945 additions and 74587 deletions
|
@ -2,10 +2,7 @@ import { existsSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from
|
|||
import ScriptUtils from "./ScriptUtils"
|
||||
import { Utils } from "../src/Utils"
|
||||
import Script from "./Script"
|
||||
import { GeoOperations } from "../src/Logic/GeoOperations"
|
||||
import { Feature, Polygon } from "geojson"
|
||||
import { Tiles } from "../src/Models/TileRange"
|
||||
import { BBox } from "../src/Logic/BBox"
|
||||
|
||||
class StatsDownloader {
|
||||
private readonly urlTemplate =
|
||||
|
@ -205,13 +202,6 @@ class GenerateSeries extends Script {
|
|||
const targetDir = args[0] ?? "../../git/MapComplete-data"
|
||||
|
||||
await this.downloadStatistics(targetDir + "/changeset-metadata")
|
||||
this.generateCenterPoints(
|
||||
targetDir + "/changeset-metadata",
|
||||
targetDir + "/mapcomplete-changes/",
|
||||
{
|
||||
zoomlevel: 8,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private async downloadStatistics(targetDir: string) {
|
||||
|
@ -229,94 +219,19 @@ class GenerateSeries extends Script {
|
|||
day = Number(process.argv[4])
|
||||
}
|
||||
|
||||
do {
|
||||
let downloaded = false
|
||||
while (!downloaded) {
|
||||
try {
|
||||
await new StatsDownloader(targetDir).DownloadStats(year, month, day)
|
||||
break
|
||||
downloaded = true
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
} while (true)
|
||||
|
||||
}
|
||||
const allFiles = readdirSync(targetDir).filter((p) => p.endsWith(".json"))
|
||||
writeFileSync(targetDir + "/file-overview.json", JSON.stringify(allFiles))
|
||||
}
|
||||
|
||||
private generateCenterPoints(
|
||||
sourceDir: string,
|
||||
targetDir: string,
|
||||
options: {
|
||||
zoomlevel: number
|
||||
}
|
||||
) {
|
||||
const allPaths = readdirSync(sourceDir).filter(
|
||||
(p) => p.startsWith("stats.") && p.endsWith(".json")
|
||||
)
|
||||
let allFeatures: ChangeSetData[] = allPaths.flatMap(
|
||||
(path) => JSON.parse(readFileSync(sourceDir + "/" + path, "utf-8")).features
|
||||
)
|
||||
allFeatures = allFeatures.filter(
|
||||
(f) =>
|
||||
f?.properties !== undefined &&
|
||||
(f.properties.editor === null ||
|
||||
f.properties.editor.toLowerCase().startsWith("mapcomplete"))
|
||||
)
|
||||
|
||||
allFeatures = allFeatures.filter(
|
||||
(f) => f.geometry !== null && f.properties.metadata?.theme !== "EMPTY CS"
|
||||
)
|
||||
allFeatures = allFeatures.filter(
|
||||
(f) =>
|
||||
f?.properties !== undefined &&
|
||||
(f.properties.editor === null ||
|
||||
f.properties.editor.toLowerCase().startsWith("mapcomplete"))
|
||||
)
|
||||
|
||||
allFeatures = allFeatures.filter(
|
||||
(f) => f.properties.metadata?.theme !== "EMPTY CS" && f.geometry.coordinates.length > 0
|
||||
)
|
||||
const centerpointsAll = allFeatures.map((f) => {
|
||||
const centerpoint = GeoOperations.centerpoint(f)
|
||||
const c = centerpoint.geometry.coordinates
|
||||
// OsmCha doesn't adhere to the Geojson standard and uses `lat` `lon` as coordinates instead of `lon`, `lat`
|
||||
centerpoint.geometry.coordinates = [c[1], c[0]]
|
||||
return centerpoint
|
||||
})
|
||||
const centerpoints = centerpointsAll.filter((p) => {
|
||||
const bbox = BBox.get(p)
|
||||
if (bbox.minLat === -90 && bbox.maxLat === -90) {
|
||||
// Due to some bug somewhere, those invalid bboxes might appear if the latitude is < 90
|
||||
// This crashes the 'spreadIntoBBoxes
|
||||
// As workaround, we simply ignore them for now
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
console.log("Found", centerpoints.length, " changesets in total")
|
||||
|
||||
const perBbox = GeoOperations.spreadIntoBboxes(centerpoints, options.zoomlevel)
|
||||
|
||||
for (const [tileNumber, features] of perBbox) {
|
||||
const [z, x, y] = Tiles.tile_from_index(tileNumber)
|
||||
const path = `${targetDir}/tile_${z}_${x}_${y}.geojson`
|
||||
features.forEach((f) => {
|
||||
delete f.bbox
|
||||
})
|
||||
writeFileSync(
|
||||
path,
|
||||
JSON.stringify(
|
||||
{
|
||||
type: "FeatureCollection",
|
||||
features: features,
|
||||
},
|
||||
null,
|
||||
" "
|
||||
)
|
||||
)
|
||||
|
||||
ScriptUtils.erasableLog("Written ", path, "which has ", features.length, "features")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new GenerateSeries().run()
|
||||
|
|
|
@ -25,7 +25,7 @@ class DownloadEli extends Script {
|
|||
const props = layer.properties
|
||||
|
||||
if (props.type === "bing") {
|
||||
// A lot of work to implement - see https://github.com/pietervdvn/MapComplete/issues/648
|
||||
// A lot of work to implement - see https://source.mapcomplete.org/MapComplete/MapComplete/issues/648
|
||||
try {
|
||||
const bing = await BingRasterLayer.get()
|
||||
if (bing === "error") {
|
||||
|
|
|
@ -31,6 +31,7 @@ import MarkdownUtils from "../src/Utils/MarkdownUtils"
|
|||
import { parse as parse_html } from "node-html-parser"
|
||||
import { AvailableRasterLayers } from "../src/Models/RasterLayers"
|
||||
import { ImmutableStore } from "../src/Logic/UIEventSource"
|
||||
import * as unitUsage from "../Docs/Schemas/UnitConfigJson.schema.json"
|
||||
|
||||
/**
|
||||
* Converts a markdown-file into a .json file, which a walkthrough/slideshow element can use
|
||||
|
@ -268,7 +269,12 @@ export class GenerateDocs extends Script {
|
|||
|
||||
private generateBuiltinUnits() {
|
||||
const layer = new LayerConfig(<LayerConfigJson>unit, "units", true)
|
||||
const els: string[] = ["## " + layer.id]
|
||||
const els: string[] = [
|
||||
"# Units",
|
||||
"## How to use",
|
||||
unitUsage.description,
|
||||
"Units ",
|
||||
"## " + layer.id]
|
||||
|
||||
for (const unit of layer.units) {
|
||||
els.push("### " + unit.quantity)
|
||||
|
@ -295,8 +301,8 @@ export class GenerateDocs extends Script {
|
|||
}
|
||||
}
|
||||
|
||||
this.WriteMarkdownFile("./Docs/builtin_units.md", ["# Units", ...els].join("\n\n"), [
|
||||
`assets/layers/unit/unit.json`,
|
||||
this.WriteMarkdownFile("./Docs/builtin_units.md", els.join("\n\n"), [
|
||||
`assets/layers/unit/unit.json`, `src/Models/ThemeConfig/Json/UnitConfigJson.ts`
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
@ -426,7 +426,7 @@ class GenerateLayouts extends Script {
|
|||
const csp: Record<string, string> = {
|
||||
"default-src": "'self'",
|
||||
"child-src": "'self' blob: ",
|
||||
"img-src": "* data: blob:", // maplibre depends on 'data:' to load
|
||||
"img-src": "* data: blob:", // maplibre depends on 'data:' to load; 'blob:' is needed for both 360° stuff and local storage
|
||||
"report-to": "https://report.mapcomplete.org/csp",
|
||||
"worker-src": "'self' blob:", // Vite somehow loads the worker via a 'blob'
|
||||
"style-src": "'self' 'unsafe-inline'", // unsafe-inline is needed to change the default background pin colours
|
||||
|
|
|
@ -74,7 +74,7 @@ function generateLayerUsage(layer: LayerConfig): TagInfoPrototype[] {
|
|||
const usesImageUpload = (tr.render?.txt?.indexOf("image_upload") ?? -2) > 0
|
||||
|
||||
if (usesImageCarousel || usesImageUpload) {
|
||||
const descrNoUpload = `Images are displayed based on the keys image, image:0, image:1,..., panoramax, panoramax:0, panoramx:1, ... , wikidata, wikipedia, wikimedia_commons and mapillary`
|
||||
const descrNoUpload = `Images are displayed based on the keys image, image:0, image:1,..., panoramax, panoramax:0, panoramx:1, ... , wikidata, wikipedia, wikimedia_commons and mapillary`
|
||||
const descrUpload = `${descrNoUpload} Furthermore, this layer shows images based on the keys panoramax, image, wikidata, wikipedia, wikimedia_commons and mapillary`
|
||||
|
||||
const shownText = (usesImageUpload ? descrUpload : descrNoUpload) + condition
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# apt install unzip
|
||||
# npm i -g csp-logger
|
||||
|
||||
# wget https://github.com/pietervdvn/latlon2country/raw/main/tiles.zip
|
||||
# wget https://source.mapcomplete.org/MapComplete/latlon2country/raw/branch/main/tiles.zip
|
||||
# unzip tiles.zip
|
||||
|
||||
cp config.json config.json.bu &&
|
||||
|
|
|
@ -74,7 +74,7 @@ class NsiLogos extends Script {
|
|||
ttl--
|
||||
const dloaded = await Utils.downloadAdvanced(url, {
|
||||
"User-Agent":
|
||||
"MapComplete NSI scraper/0.1 (https://github.com/pietervdvn/MapComplete; pietervdvn@posteo.net)",
|
||||
"MapComplete NSI scraper/0.1 (https://source.mapcomplete.org/MapComplete/MapComplete; pietervdvn@posteo.net)",
|
||||
})
|
||||
const redirect: string | undefined = dloaded["redirect"]
|
||||
if (redirect) {
|
||||
|
|
117
scripts/repairPanoramax.ts
Normal file
117
scripts/repairPanoramax.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
import Script from "./Script"
|
||||
import { Overpass } from "../src/Logic/Osm/Overpass"
|
||||
import { Or } from "../src/Logic/Tags/Or"
|
||||
import { RegexTag } from "../src/Logic/Tags/RegexTag"
|
||||
import { Utils } from "../src/Utils"
|
||||
import Constants from "../src/Models/Constants"
|
||||
import { ImmutableStore } from "../src/Logic/UIEventSource"
|
||||
import { BBox } from "../src/Logic/BBox"
|
||||
import ChangeTagAction from "../src/Logic/Osm/Actions/ChangeTagAction"
|
||||
import { Tag } from "../src/Logic/Tags/Tag"
|
||||
import { Panoramax } from "panoramax-js/dist"
|
||||
import { Changes } from "../src/Logic/Osm/Changes"
|
||||
import OsmChangeAction from "../src/Logic/Osm/Actions/OsmChangeAction"
|
||||
import { writeFileSync } from "fs"
|
||||
import { Feature } from "geojson"
|
||||
|
||||
class RepairPanoramax extends Script {
|
||||
|
||||
private static readonly europe: Feature = {
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
-20.091159690050006,
|
||||
25.773375277790038
|
||||
],
|
||||
[
|
||||
46.12276429398841,
|
||||
25.773375277790038
|
||||
],
|
||||
[
|
||||
46.12276429398841,
|
||||
65.41389761819318
|
||||
],
|
||||
[
|
||||
-20.091159690050006,
|
||||
65.41389761819318
|
||||
],
|
||||
[
|
||||
-20.091159690050006,
|
||||
25.773375277790038
|
||||
]
|
||||
]
|
||||
],
|
||||
"type": "Polygon"
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super("See https://source.mapcomplete.org/MapComplete/MapComplete/issues/2372\n" +
|
||||
"We accidentally added the full image URL instead of the hash due to a bug. This scripts rewrites all")
|
||||
}
|
||||
|
||||
async main(args: string[]): Promise<void> {
|
||||
const keys = ["panoramax", ...Utils.TimesT(10, i => "panoramax:" + i)]
|
||||
const overpass = new Overpass(
|
||||
new Or(
|
||||
keys.map(k => new RegexTag(k, /^https:\/\/panoramax.mapcomplete.org\/.*/))
|
||||
),
|
||||
[],
|
||||
Constants.defaultOverpassUrls[0],
|
||||
new ImmutableStore(500)
|
||||
)
|
||||
|
||||
const [wrongFeatures] = await overpass.queryGeoJson(BBox.global)
|
||||
const allChanges: OsmChangeAction[] = []
|
||||
for (const f of wrongFeatures.features) {
|
||||
for (const key of keys) {
|
||||
const v = f.properties[key]
|
||||
if (!v) {
|
||||
continue
|
||||
}
|
||||
const pre = "https://panoramax.mapcomplete.org/api/pictures/"
|
||||
const pre1 = "https://panoramax.mapcomplete.org/permanent/"
|
||||
let correct: string
|
||||
if (v.startsWith(pre)) {
|
||||
correct = v.substring(pre.length)
|
||||
correct = correct.substring(0, correct.indexOf("/"))
|
||||
} else if (v.startsWith(pre1)) {
|
||||
const stripped = v.substring(pre1.length)
|
||||
correct = stripped.replace(/\//g, "").replace(/\.jpg$/, "")
|
||||
correct = correct.substring(0, 8) + "-" + correct.substring(8)
|
||||
} else if (Panoramax.isId(v)) {
|
||||
// This is a valid ID that came on an object also having an _invalid_ id
|
||||
// We can safely skip this
|
||||
continue
|
||||
} else {
|
||||
throw "Unknown url " + v
|
||||
}
|
||||
console.log(key, correct, " old: ", v)
|
||||
if (!Panoramax.isId(correct)) {
|
||||
throw "Constructed an invalid id:" + correct
|
||||
}
|
||||
const change = new ChangeTagAction(
|
||||
f.properties.id,
|
||||
new Tag(key, correct),
|
||||
f.properties,
|
||||
{
|
||||
theme: "fix",
|
||||
changeType: "fix"
|
||||
}
|
||||
)
|
||||
allChanges.push(change)
|
||||
}
|
||||
}
|
||||
|
||||
const xml = await Changes.createChangesetXMLForJosm(allChanges)
|
||||
console.log(xml)
|
||||
const path = "repairPanoramax.osc"
|
||||
writeFileSync(path, xml)
|
||||
console.log("Written XML to", path)
|
||||
}
|
||||
}
|
||||
|
||||
new RepairPanoramax().run()
|
|
@ -19,7 +19,7 @@ class ServerLdScrape extends Script {
|
|||
accept: "application/html",
|
||||
},
|
||||
/* {
|
||||
"User-Agent": "MapComplete/openstreetmap scraper; pietervdvn@posteo.net; https://github.com/pietervdvn/MapComplete",
|
||||
"User-Agent": "MapComplete/openstreetmap scraper; pietervdvn@posteo.net; https://source.mapcomplete.org/MapComplete",
|
||||
"accept": "application/html"
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue