Chore: housekeeping, linting

This commit is contained in:
Pieter Vander Vennet 2025-06-04 00:21:28 +02:00
parent f942529755
commit 30d00eb06d
74 changed files with 998 additions and 623 deletions

View file

@ -8,7 +8,6 @@ import { Utils } from "../../../Utils"
import { TagsFilter } from "../../Tags/TagsFilter"
import { BBox } from "../../BBox"
import { OsmTags } from "../../../Models/OsmFeature"
;("use strict")
/**

View file

@ -10,12 +10,12 @@ import {
MultiPolygon,
Point,
Polygon,
Position
Position,
} from "geojson"
import { Tiles } from "../Models/TileRange"
import { Utils } from "../Utils"
("use strict")
;("use strict")
export class GeoOperations {
private static readonly _earthRadius: number = 6378137
@ -107,7 +107,10 @@ export class GeoOperations {
* @param lonlat0
* @param lonlat1
*/
static distanceBetween(lonlat0: [number, number] | Coord | Position, lonlat1: [number, number] | Position | Coord) {
static distanceBetween(
lonlat0: [number, number] | Coord | Position,
lonlat1: [number, number] | Position | Coord
) {
return turf.distance(lonlat0, lonlat1, { units: "meters" })
}

View file

@ -13,7 +13,7 @@ export interface ProvidedImage {
/**
* An alternative ID, used to deduplicate some images
*/
alt_id?: string,
alt_id?: string
date?: Date
status?: string | "ready"
/**

View file

@ -98,7 +98,11 @@ export class ImageUploadManager {
const tags = await ExifReader.load(file)
if (tags.ProjectionType.value === "cylindrical") {
return { error: new Translation({ en: "Cylindrical images (typically created by a Panorama-app) are not supported" }) }
return {
error: new Translation({
en: "Cylindrical images (typically created by a Panorama-app) are not supported",
}),
}
}
return true
@ -125,7 +129,6 @@ export class ImageUploadManager {
ignoreGPS: boolean | false
}
): void {
const tags: OsmTags = tagsStore.data
const featureId = <OsmId | NoteId>tags.id
@ -290,7 +293,7 @@ export class ImageUploadManager {
let absoluteUrl: string
try {
({ key, value, absoluteUrl } = await this._uploader.uploadImage(
;({ key, value, absoluteUrl } = await this._uploader.uploadImage(
blob,
location,
author,

View file

@ -196,7 +196,10 @@ export class Mapillary extends ImageProvider {
try {
license.date = new Date(date)
} catch (e) {
console.warn("Could not parse captured_at date from mapillary image. The date is:", date)
console.warn(
"Could not parse captured_at date from mapillary image. The date is:",
date
)
}
return license
}

View file

@ -28,7 +28,8 @@ export default class PanoramaxImageProvider extends ImageProvider {
* const match = url.match(PanoramaxImageProvider.isDirectLink)
* match[1] // => "e931ce57-4591-4dd5-aa4c-595e89c37e84"
*/
public static readonly isDirectLink = /https:\/\/panoramax.mapcomplete.org\/api\/pictures\/([0-9a-f-]+)\/(hd)|(sd)|(thumb).jpg/
public static readonly isDirectLink =
/https:\/\/panoramax.mapcomplete.org\/api\/pictures\/([0-9a-f-]+)\/(hd)|(sd)|(thumb).jpg/
public defaultKeyPrefixes: string[] = ["panoramax", "image"]
public readonly name: string = "panoramax"
@ -51,7 +52,7 @@ export default class PanoramaxImageProvider extends ImageProvider {
new SvelteUIElement(Panoramax_bw),
p.createViewLink({
imageId: img?.id,
location
location,
}),
true
)
@ -65,14 +66,14 @@ export default class PanoramaxImageProvider extends ImageProvider {
const p = new Panoramax(host)
return p.createViewLink({
imageId: img?.id,
location
location,
})
}
public addKnownMeta(meta: ImageData, url?: string) {
PanoramaxImageProvider.knownMeta[meta.id] = {
data: Promise.resolve({ data: meta, url }),
time: new Date()
time: new Date(),
}
}
@ -125,7 +126,7 @@ export default class PanoramaxImageProvider extends ImageProvider {
status: meta.properties["geovisio:status"],
rotation: Number(meta.properties["view:azimuth"]),
isSpherical: meta.properties.exif["Xmp.GPano.ProjectionType"] === "equirectangular",
date: new Date(meta.properties.datetime)
date: new Date(meta.properties.datetime),
}
}
@ -156,7 +157,7 @@ export default class PanoramaxImageProvider extends ImageProvider {
const promise: Promise<{ data: ImageData; url: string }> = this.getInfoForUncached(id)
PanoramaxImageProvider.knownMeta[id] = {
time: new Date(),
data: promise
data: promise,
}
return await promise
}
@ -215,7 +216,7 @@ export default class PanoramaxImageProvider extends ImageProvider {
return {
artist: meta.data.providers.at(-1).name, // We take the last provider, as that one probably contain the username of the uploader
date: new Date(meta.data.properties["datetime"]),
licenseShortName: meta.data.properties["geovisio:license"]
licenseShortName: meta.data.properties["geovisio:license"],
}
}
@ -247,8 +248,8 @@ export default class PanoramaxImageProvider extends ImageProvider {
properties: {
url,
northOffset,
pitchOffset
}
pitchOffset,
},
}
}
}
@ -263,7 +264,6 @@ export class PanoramaxUploader implements ImageUploader {
this.panoramax = new AuthorizedPanoramax(url, token)
}
async uploadImage(
blob: File,
currentGps: [number, number],
@ -287,13 +287,12 @@ export class PanoramaxUploader implements ImageUploader {
throw "Unsupported image format: cylindrical images (panorama images) are currently not supported"
}
if (tags?.GPSLatitude?.value && tags?.GPSLongitude?.value) {
const [[latD], [latM], [latS, latSDenom]] = <
[[number, number], [number, number], [number, number]]
>tags?.GPSLatitude?.value
>tags?.GPSLatitude?.value
const [[lonD], [lonM], [lonS, lonSDenom]] = <
[[number, number], [number, number], [number, number]]
>tags?.GPSLongitude?.value
>tags?.GPSLongitude?.value
const exifLat = latD + latM / 60 + latS / (3600 * latSDenom)
const exifLon = lonD + lonM / 60 + lonS / (3600 * lonSDenom)
@ -335,9 +334,7 @@ export class PanoramaxUploader implements ImageUploader {
} else {
datetime = exifDatetime.toISOString()
}
}
} catch (e) {
console.warn("Could not read EXIF-tags due to", e)
}
@ -356,7 +353,7 @@ export class PanoramaxUploader implements ImageUploader {
indexInSequence: sequence["stats:items"].count + 1, // stats:items is '1'-indexed, so .count is also the last index
exifOverride: {
Artist: author,
}
},
}
if (progress) {
options.onProgress = (e: ProgressEvent) => {
@ -373,7 +370,7 @@ export class PanoramaxUploader implements ImageUploader {
return {
key: "panoramax",
value: img.id,
absoluteUrl: img.assets.hd.href
absoluteUrl: img.assets.hd.href,
}
}
}

View file

@ -54,7 +54,7 @@ export class Changes {
featureSwitchIsTesting?: Store<boolean>
}
osmConnection: OsmConnection
reportError?: ((message: string | Error | XMLHttpRequest, extramessage?: string) => void),
reportError?: (message: string | Error | XMLHttpRequest, extramessage?: string) => void
featureProperties?: FeaturePropertiesStore
historicalUserLocations?: FeatureSource<Feature<Point, GeoLocationPointProperties>>
allElements?: IndexedFeatureSource
@ -694,7 +694,7 @@ export class Changes {
"Refusing change about " +
c.type +
"/" +
id +
id +
" as not in the objects. No internet?"
)
refused.push(c)

View file

@ -154,8 +154,8 @@ export class OsmConnection {
constructor(options?: {
dryRun?: Store<boolean>
fakeUser?: false | boolean
oauth_token?: UIEventSource<string>,
shared_cookie?: string,
oauth_token?: UIEventSource<string>
shared_cookie?: string
// Used to keep multiple changesets open and to write to the correct changeset
singlePage?: boolean
attemptLogin?: boolean

View file

@ -5,7 +5,6 @@ import { BBox } from "../BBox"
import osmtogeojson from "osmtogeojson"
import { FeatureCollection, Geometry } from "geojson"
import { OsmTags } from "../../Models/OsmFeature"
;("use strict")
/**
* Interfaces overpass to get all the latest data

View file

@ -1,14 +1,42 @@
import { Utils } from "../../Utils"
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
export class ThemeMetaTagging {
public static readonly themeName = "usersettings"
public static readonly themeName = "usersettings"
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/&lt;/g,'<')?.replace(/&gt;/g,'>') ?? '' )
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
feat.properties['__current_backgroun'] = 'initial_value'
}
}
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
feat.properties._description
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
?.at(1)
)
Utils.AddLazyProperty(
feat.properties,
"_d",
() => feat.properties._description?.replace(/&lt;/g, "<")?.replace(/&gt;/g, ">") ?? ""
)
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.href.match(/mastodon|en.osm.town/) !== null
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
((feat) => {
const e = document.createElement("div")
e.innerHTML = feat.properties._d
return Array.from(e.getElementsByTagName("a")).filter(
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
)[0]?.href
})(feat)
)
Utils.AddLazyProperty(
feat.properties,
"_mastodon_candidate",
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
)
feat.properties["__current_backgroun"] = "initial_value"
}
}

View file

@ -361,7 +361,13 @@ export default class NameSuggestionIndex {
return nsi.generateMappings(key, tags, country, center, options)
}
private static readonly brandPrefix = ["name", "alt_name", "operator", "brand", "official_name"] as const
private static readonly brandPrefix = [
"name",
"alt_name",
"operator",
"brand",
"official_name",
] as const
/**
* An NSI-item might have tags such as `name=X`, `alt_name=brand X`, `brand=X`, `brand:wikidata`, `shop=Y`, `service:abc=yes`

View file

@ -101,7 +101,7 @@ class P4CImageFetcher implements ImageFetcher {
searchRadius,
{
mindate: new Date().getTime() - maxAgeSeconds,
towardscenter: false
towardscenter: false,
}
)
} catch (e) {
@ -152,9 +152,9 @@ class ImagesInLoadedDataFetcher implements ImageFetcher {
coordinates: { lng: centerpoint[0], lat: centerpoint[1] },
provider: "OpenStreetMap",
details: {
isSpherical: false
isSpherical: false,
},
osmTags: { image }
osmTags: { image },
})
}
})
@ -170,7 +170,7 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
public static readonly apiUrls: ReadonlyArray<string> = [
"https://panoramax.openstreetmap.fr",
"https://api.panoramax.xyz",
"https://panoramax.mapcomplete.org"
"https://panoramax.mapcomplete.org",
]
constructor(url?: string, radius: number = 50) {
@ -191,7 +191,7 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
provider: "panoramax",
direction: imageData.properties["view:azimuth"],
osmTags: {
panoramax: imageData.id
panoramax: imageData.id,
},
thumbUrl: imageData.assets.thumb.href,
date: new Date(imageData.properties.datetime).getTime(),
@ -200,8 +200,8 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
detailsUrl: imageData.id,
details: {
isSpherical:
imageData.properties["exif"]["Xmp.GPano.ProjectionType"] === "equirectangular"
}
imageData.properties["exif"]["Xmp.GPano.ProjectionType"] === "equirectangular",
},
}
}
@ -209,23 +209,26 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
const radiusSettings = [
{
place_fov_tolerance: 180,
radius: 15
radius: 15,
},
{
place_fov_tolerance: 180,
radius: 25
radius: 25,
},
{
place_fov_tolerance: 90,
radius: 50
}
radius: 50,
},
]
const promises: Promise<ImageData[]>[] = []
const maxRadius = this._radius
let prevRadius = 0
const nearby = this._panoramax.search({
bbox: new BBox([[lon - 0.0001, lat - 0.0001], [lon + 0.0001, lat + 0.0001]]).toLngLatFlat()
bbox: new BBox([
[lon - 0.0001, lat - 0.0001],
[lon + 0.0001, lat + 0.0001],
]).toLngLatFlat(),
})
promises.push(nearby) // We do a nearby search with bbox, see https://source.mapcomplete.org/MapComplete/MapComplete/issues/2384
for (const radiusSetting of radiusSettings) {
@ -233,7 +236,7 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
place: [lon, lat],
place_distance: [prevRadius, Math.min(maxRadius, radiusSetting.radius)],
place_fov_tolerance: radiusSetting.place_fov_tolerance,
limit: 50
limit: 50,
})
promises.push(promise)
prevRadius = radiusSetting.radius
@ -277,7 +280,7 @@ class MapillaryFetcher implements ImageFetcher {
boundingBox.getWest(),
boundingBox.getSouth(),
boundingBox.getEast(),
boundingBox.getNorth()
boundingBox.getNorth(),
].join(",") +
"&access_token=" +
encodeURIComponent(Constants.mapillary_client_token_v4) +
@ -323,17 +326,17 @@ class MapillaryFetcher implements ImageFetcher {
coordinates: { lng: c[0], lat: c[1] },
thumbUrl: img.thumb_256_url,
osmTags: {
mapillary: img.id
mapillary: img.id,
},
details: {
isSpherical: this._panoramas === "only"
isSpherical: this._panoramas === "only",
},
detailsUrl: Mapillary.singleton.visitUrl(img, { lon, lat }),
date: img.captured_at,
license: "CC-BY-SA",
author: img.creator.username,
direction: img.compass_angle
direction: img.compass_angle,
})
}
return pics
@ -349,7 +352,7 @@ export class CombinedFetcher {
Imgur.apiUrl,
...Imgur.supportingUrls,
...MapillaryFetcher.apiUrls,
...ImagesFromPanoramaxFetcher.apiUrls
...ImagesFromPanoramaxFetcher.apiUrls,
]
constructor(radius: number, maxage: Date, indexedFeatures: IndexedFeatureSource) {
@ -361,15 +364,15 @@ export class CombinedFetcher {
new MapillaryFetcher({
max_images: 25,
start_captured_at: maxage,
panoramas: "only"
panoramas: "only",
}),
new MapillaryFetcher({
max_images: 25,
start_captured_at: maxage,
panoramas: "no"
panoramas: "no",
}),
new P4CImageFetcher("mapillary"),
new P4CImageFetcher("wikicommons")
new P4CImageFetcher("wikicommons"),
].map((f) => new CachedFetcher(f))
}
@ -387,7 +390,7 @@ export class CombinedFetcher {
const newList = []
const seenIds = new Set<string>()
for (const p4CPicture of [...sink.data ?? [], ...pics]) {
for (const p4CPicture of [...(sink.data ?? []), ...pics]) {
const id = p4CPicture.pictureUrl
if (seenIds.has(id)) {
continue