import Script from "./Script" import * as eli from "../public/assets/data/editor-layer-index.json" import Constants from "../src/Models/Constants" import { AvailableRasterLayers, EditorLayerIndexProperties } from "../src/Models/RasterLayers" import { GeoOperations } from "../src/Logic/GeoOperations" import { Feature, Geometry } from "geojson" import { Tiles } from "../src/Models/TileRange" import { Utils } from "../src/Utils" import { writeFileSync } from "fs" import MarkdownUtils from "../src/Utils/MarkdownUtils" import ScriptUtils from "./ScriptUtils" import RasterLayerHandler from "../src/UI/Map/RasterLayerHandler" class GenerateEliHealthReport extends Script { static continents = { "AF":"Asia", "AL":"Europe", "AQ":"Antarctica", "DZ":"Africa", "AS":"Oceania", "AD":"Europe", "AO":"Africa", "AG":"North-America", "AZ":"Europe", "AZ":"Asia", "AR":"South-America", "AU":"Oceania", "AT":"Europe", "BS":"North-America", "BH":"Asia", "BD":"Asia", "AM":"Europe", "AM":"Asia", "BB":"North-America", "BE":"Europe", "BM":"North-America", "BT":"Asia", "BO":"South-America", "BA":"Europe", "BW":"Africa", "BV":"Antarctica", "BR":"South-America", "BZ":"North-America", "IO":"Asia", "SB":"Oceania", "VG":"North-America", "BN":"Asia", "BG":"Europe", "MM":"Asia", "BI":"Africa", "BY":"Europe", "KH":"Asia", "CM":"Africa", "CA":"North-America", "CV":"Africa", "KY":"North-America", "CF":"Africa", "LK":"Asia", "TD":"Africa", "CL":"South-America", "CN":"Asia", "TW":"Asia", "CX":"Asia", "CC":"Asia", "CO":"South-America", "KM":"Africa", "YT":"Africa", "CG":"Africa", "CD":"Africa", "CK":"Oceania", "CR":"North-America", "HR":"Europe", "CU":"North-America", "CY":"Europe", "CY":"Asia", "CZ":"Europe", "BJ":"Africa", "DK":"Europe", "DM":"North-America", "DO":"North-America", "EC":"South-America", "SV":"North-America", "GQ":"Africa", "ET":"Africa", "ER":"Africa", "EE":"Europe", "FO":"Europe", "FK":"South-America", "GS":"Antarctica", "FJ":"Oceania", "FI":"Europe", "AX":"Europe", "FR":"Europe", "GF":"South-America", "PF":"Oceania", "TF":"Antarctica", "DJ":"Africa", "GA":"Africa", "GE":"Europe", "GE":"Asia", "GM":"Africa", "PS":"Asia", "DE":"Europe", "GH":"Africa", "GI":"Europe", "KI":"Oceania", "GR":"Europe", "GL":"North-America", "GD":"North-America", "GP":"North-America", "GU":"Oceania", "GT":"North-America", "GN":"Africa", "GY":"South-America", "HT":"North-America", "HM":"Antarctica", "VA":"Europe", "HN":"North-America", "HK":"Asia", "HU":"Europe", "IS":"Europe", "IN":"Asia", "ID":"Asia", "IR":"Asia", "IQ":"Asia", "IE":"Europe", "IL":"Asia", "IT":"Europe", "CI":"Africa", "JM":"North-America", "JP":"Asia", "KZ":"Europe", "KZ":"Asia", "JO":"Asia", "KE":"Africa", "KP":"Asia", "KR":"Asia", "KW":"Asia", "KG":"Asia", "LA":"Asia", "LB":"Asia", "LS":"Africa", "LV":"Europe", "LR":"Africa", "LY":"Africa", "LI":"Europe", "LT":"Europe", "LU":"Europe", "MO":"Asia", "MG":"Africa", "MW":"Africa", "MY":"Asia", "MV":"Asia", "ML":"Africa", "MT":"Europe", "MQ":"North-America", "MR":"Africa", "MU":"Africa", "MX":"North-America", "MC":"Europe", "MN":"Asia", "MD":"Europe", "ME":"Europe", "MS":"North-America", "MA":"Africa", "MZ":"Africa", "OM":"Asia", "NA":"Africa", "NR":"Oceania", "NP":"Asia", "NL":"Europe", "AN":"North-America", "CW":"North-America", "AW":"North-America", "SX":"North-America", "BQ":"North-America", "NC":"Oceania", "VU":"Oceania", "NZ":"Oceania", "NI":"North-America", "NE":"Africa", "NG":"Africa", "NU":"Oceania", "NF":"Oceania", "NO":"Europe", "MP":"Oceania", "UM":"Oceania", "UM":"North-America", "FM":"Oceania", "MH":"Oceania", "PW":"Oceania", "PK":"Asia", "PA":"North-America", "PG":"Oceania", "PY":"South-America", "PE":"South-America", "PH":"Asia", "PN":"Oceania", "PL":"Europe", "PT":"Europe", "GW":"Africa", "TL":"Asia", "PR":"North-America", "QA":"Asia", "RE":"Africa", "RO":"Europe", "RU":"Europe", "RW":"Africa", "BL":"North-America", "SH":"Africa", "KN":"North-America", "AI":"North-America", "LC":"North-America", "MF":"North-America", "PM":"North-America", "VC":"North-America", "SM":"Europe", "ST":"Africa", "SA":"Asia", "SN":"Africa", "RS":"Europe", "SC":"Africa", "SL":"Africa", "SG":"Asia", "SK":"Europe", "VN":"Asia", "SI":"Europe", "SO":"Africa", "ZA":"Africa", "ZW":"Africa", "ES":"Europe", "SS":"Africa", "EH":"Africa", "SD":"Africa", "SR":"South-America", "SJ":"Europe", "SZ":"Africa", "SE":"Europe", "CH":"Europe", "SY":"Asia", "TJ":"Asia", "TH":"Asia", "TG":"Africa", "TK":"Oceania", "TO":"Oceania", "TT":"North-America", "AE":"Asia", "TN":"Africa", "TR":"Asia", "TM":"Asia", "TC":"North-America", "TV":"Oceania", "UG":"Africa", "UA":"Europe", "MK":"Europe", "EG":"Africa", "GB":"Europe", "GG":"Europe", "JE":"Europe", "IM":"Europe", "TZ":"Africa", "US":"North-America", "VI":"North-America", "BF":"Africa", "UY":"South-America", "UZ":"Asia", "VE":"South-America", "WF":"Oceania", "WS":"Oceania", "YE":"Asia", "ZM":"Africa", "XX":"Oceania", "XE":"Asia", "PZ":"Asia", "XD":"Asia", "XS":"Asia", } constructor() { super("Runs over the ELI, attempts to get a valid tile in the center of the bounds and checks the response") } private buildUrl(layer: Feature): string { const p = layer.properties const prepped = RasterLayerHandler.prepareSource(p) const [lon, lat] = GeoOperations.centerpointCoordinates(layer) const z = p.max_zoom ?? (p.min_zoom ?? 10)+2 const tile = Tiles.embedded_tile(lat, lon, z) const [[lon0, lat0], [lon1, lat1]] = Tiles.tile_bounds_lon_lat(z, tile.x, tile.y) const subsProps = { ...tile, width: 256, height: 256, proj: "EPSG:4326", bbox: [lon0, lat1, lon1, lat0].join(","), BBOX: [lon0, lat1, lon1, lat0].join(","), } return Utils.SubstituteKeys(prepped.url ?? prepped.tiles[0], subsProps) } private countryCodeToContinent(): Record { const result: Record = {} for (const k in GenerateEliHealthReport.continents) { result[k.toLowerCase()] = GenerateEliHealthReport.continents[k].toLowerCase() } return result } public async main(): Promise { const continents = this.countryCodeToContinent() const header = ["index", "ID", "SOURCE URL", "STATUS", "CORS", "Github",'notes'] const data: string[][] = [] let success = 0 let fail = 0 const feats: Feature[] = eli.features function writeFile(){ writeFileSync("./Docs/EditorLayerIndex_Health_report.md", [ "# Editor layer index - health report", "This document shows if an entry in the ELI can probably be used by MapComplete", "Time of test: " + new Date().toISOString(), `Success: ${success}; failed: ${fail}; total: ${fail + success}`, MarkdownUtils.table( header, data, )].join("\n\n"), "utf-8") } for (let i = 0; i < feats.length; i++) { const f = feats[i] const p = f.properties const url = this.buildUrl(f) const result: string[] = [i, p.id + " (_" + p.name + "_)", `[Tested tile](${url})`] data.push(result) try { let response = await fetch(url, { method: "OPTIONS" }) if (response.status == 405) { response = await fetch(url) } result.push(response.statusText) const cors = response.headers.get("Access-Control-Allow-Origin") result.push(cors ?? "_None_") if (response.status >= 300) { fail++ } else { success++ } } catch (e) { console.error(e) result.push("FAIL: " + e, "") fail++ } const continent = continents[p.country_code.toLowerCase()] const githubPrefix = `https://github.com/osmlab/editor-layer-index/blob/gh-pages/sources` const github = `${githubPrefix}/${continent}/${p.country_code.toLowerCase()}/${p.id}.geojson` result.push(`[Github](${github})`) if(p.category === "map" && (p.id.toLowerCase().indexOf("photo") >= 0 || p.name.toLowerCase().indexOf("photo") >= 0)){ result.push("WARN: might be a wrong category: category MAP but name or ID contains 'photo'") } ScriptUtils.erasableLog(i + "/" + feats.length, p.id, result[2]) if(i % 50 === 0){ writeFile() } } writeFile() } } new GenerateEliHealthReport().run()