forked from MapComplete/MapComplete
Feature: first working version of inspecting 360° images
This commit is contained in:
parent
7d104b4266
commit
01ba98a820
24 changed files with 330 additions and 436 deletions
|
@ -7,8 +7,6 @@ import { BBox } from "../BBox"
|
|||
import Constants from "../../Models/Constants"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Point } from "geojson"
|
||||
import MvtSource from "../FeatureSource/Sources/MvtSource"
|
||||
import AllImageProviders from "../ImageProviders/AllImageProviders"
|
||||
import { Imgur } from "../ImageProviders/Imgur"
|
||||
import { Panoramax, PanoramaxXYZ } from "panoramax-js/dist"
|
||||
|
||||
|
@ -211,111 +209,6 @@ class ImagesFromPanoramaxFetcher implements ImageFetcher {
|
|||
}
|
||||
}
|
||||
|
||||
class ImagesFromCacheServerFetcher implements ImageFetcher {
|
||||
private readonly _searchRadius: number
|
||||
public readonly name = "fromCacheServer"
|
||||
private readonly _serverUrl: string
|
||||
|
||||
constructor(searchRadius: number = 500, serverUrl: string = Constants.VectorTileServer) {
|
||||
this._searchRadius = searchRadius
|
||||
this._serverUrl = serverUrl
|
||||
}
|
||||
|
||||
async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> {
|
||||
return (
|
||||
await Promise.all([
|
||||
this.fetchImagesForType(lat, lon, "lines"),
|
||||
this.fetchImagesForType(lat, lon, "pois"),
|
||||
this.fetchImagesForType(lat, lon, "polygons"),
|
||||
])
|
||||
).flatMap((x) => x)
|
||||
}
|
||||
|
||||
async fetchImagesForType(
|
||||
targetlat: number,
|
||||
targetlon: number,
|
||||
type: "lines" | "pois" | "polygons"
|
||||
): Promise<P4CPicture[]> {
|
||||
const { x, y, z } = Tiles.embedded_tile(targetlat, targetlon, 14)
|
||||
|
||||
const url = this._serverUrl
|
||||
|
||||
async function getFeatures(x: number, y: number) {
|
||||
const src = new MvtSource(
|
||||
Utils.SubstituteKeys(url, {
|
||||
type,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
layer: "item_with_image",
|
||||
}),
|
||||
x,
|
||||
y,
|
||||
z
|
||||
)
|
||||
await src.updateAsync()
|
||||
return src.features.data
|
||||
}
|
||||
|
||||
const features = (
|
||||
await Promise.all([
|
||||
getFeatures(x, y),
|
||||
getFeatures(x, y + 1),
|
||||
getFeatures(x, y - 1),
|
||||
|
||||
getFeatures(x + 1, y + 1),
|
||||
getFeatures(x + 1, y),
|
||||
getFeatures(x + 1, y - 1),
|
||||
|
||||
getFeatures(x - 1, y - 1),
|
||||
getFeatures(x - 1, y),
|
||||
getFeatures(x - 1, y + 1),
|
||||
])
|
||||
).flatMap((x) => x)
|
||||
|
||||
const pics: P4CPicture[] = []
|
||||
for (const f of features) {
|
||||
const [lng, lat] = GeoOperations.centerpointCoordinates(f)
|
||||
if (
|
||||
GeoOperations.distanceBetween([targetlon, targetlat], [lng, lat]) >
|
||||
this._searchRadius
|
||||
) {
|
||||
return []
|
||||
}
|
||||
for (let i = -1; i < 50; i++) {
|
||||
let key = "image"
|
||||
if (i >= 0) {
|
||||
key += ":" + i
|
||||
}
|
||||
const v = f.properties[key]
|
||||
console.log(v)
|
||||
if (!v) {
|
||||
continue
|
||||
}
|
||||
let provider = "unkown"
|
||||
try {
|
||||
provider = (await AllImageProviders.selectBestProvider("image", v))?.name
|
||||
} catch (e) {
|
||||
console.error("Could not detect provider for", "image", v)
|
||||
}
|
||||
pics.push({
|
||||
pictureUrl: v,
|
||||
coordinates: { lat, lng },
|
||||
details: {
|
||||
isSpherical: false,
|
||||
},
|
||||
osmTags: {
|
||||
image: v,
|
||||
},
|
||||
thumbUrl: v,
|
||||
provider,
|
||||
})
|
||||
}
|
||||
}
|
||||
return pics
|
||||
}
|
||||
}
|
||||
|
||||
class MapillaryFetcher implements ImageFetcher {
|
||||
public readonly name = "mapillary_new"
|
||||
private readonly _panoramas: "only" | "no" | undefined
|
||||
|
@ -390,7 +283,7 @@ class MapillaryFetcher implements ImageFetcher {
|
|||
mapillary: img.id,
|
||||
},
|
||||
details: {
|
||||
isSpherical: img.is_pano,
|
||||
isSpherical: this._panoramas === "only"
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -407,15 +300,20 @@ export class CombinedFetcher {
|
|||
constructor(radius: number, maxage: Date, indexedFeatures: IndexedFeatureSource) {
|
||||
this.sources = [
|
||||
new ImagesInLoadedDataFetcher(indexedFeatures, radius),
|
||||
new ImagesFromCacheServerFetcher(radius),
|
||||
new ImagesFromPanoramaxFetcher(),
|
||||
new ImagesFromPanoramaxFetcher(Constants.panoramax.url),
|
||||
// For mapillary, we need to query both with and without panoramas. See https://www.mapillary.com/developer/api-documentation/
|
||||
new MapillaryFetcher({
|
||||
max_images: 25,
|
||||
start_captured_at: maxage,
|
||||
panoramas: "only"
|
||||
}),
|
||||
new P4CImageFetcher("mapillary"),
|
||||
new P4CImageFetcher("wikicommons"),
|
||||
new MapillaryFetcher({
|
||||
max_images: 25,
|
||||
start_captured_at: maxage,
|
||||
panoramas: "no"
|
||||
}), new P4CImageFetcher("mapillary"),
|
||||
new P4CImageFetcher("wikicommons")
|
||||
].map((f) => new CachedFetcher(f))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue