forked from MapComplete/MapComplete
Themes: don't do face blurring for some layers (artwork, memorials, ghost_bikes)
This commit is contained in:
parent
7d83cb1a7f
commit
15176a1682
11 changed files with 370 additions and 342 deletions
|
@ -187,7 +187,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tagRenderings": [
|
"tagRenderings": [
|
||||||
"images",
|
"images_no_blur",
|
||||||
{
|
{
|
||||||
"labels": [
|
"labels": [
|
||||||
"artwork-question"
|
"artwork-question"
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
],
|
],
|
||||||
"tagRenderings": [
|
"tagRenderings": [
|
||||||
"preset_description",
|
"preset_description",
|
||||||
"images",
|
"images_no_blur",
|
||||||
{
|
{
|
||||||
"question": {
|
"question": {
|
||||||
"en": "Whom is remembered by this ghost bike?",
|
"en": "Whom is remembered by this ghost bike?",
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tagRenderings": [
|
"tagRenderings": [
|
||||||
"images",
|
"images_no_blur",
|
||||||
{
|
{
|
||||||
"id": "memorial-type",
|
"id": "memorial-type",
|
||||||
"labels": [
|
"labels": [
|
||||||
|
|
|
@ -19,6 +19,13 @@
|
||||||
"*": "{image_carousel()}{image_upload()}"
|
"*": "{image_carousel()}{image_upload()}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "images_no_blur",
|
||||||
|
"description": "Same as `images`, but uploaded request to disable blurring to the panoramax server",
|
||||||
|
"render": {
|
||||||
|
"*": "{image_carousel()}{image_upload(,,,true)}"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "mapillary",
|
"id": "mapillary",
|
||||||
"description": "Shows a button to open Mapillary on this location",
|
"description": "Shows a button to open Mapillary on this location",
|
||||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -64,7 +64,7 @@
|
||||||
"opening_hours": "^3.6.0",
|
"opening_hours": "^3.6.0",
|
||||||
"osm-auth": "^2.5.0",
|
"osm-auth": "^2.5.0",
|
||||||
"osmtogeojson": "^3.0.0-beta.5",
|
"osmtogeojson": "^3.0.0-beta.5",
|
||||||
"panoramax-js": "^0.3.6",
|
"panoramax-js": "^0.3.8",
|
||||||
"panzoom": "^9.4.3",
|
"panzoom": "^9.4.3",
|
||||||
"papaparse": "^5.3.1",
|
"papaparse": "^5.3.1",
|
||||||
"pg": "^8.11.3",
|
"pg": "^8.11.3",
|
||||||
|
@ -16002,9 +16002,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/panoramax-js": {
|
"node_modules/panoramax-js": {
|
||||||
"version": "0.3.6",
|
"version": "0.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.3.8.tgz",
|
||||||
"integrity": "sha512-CRdXwh91H6chd1PYptG070ukx+S6IkVaUeQVG91ySevoJoCYOuBT65qkMhRo49X2um1nGcs9UqolW90R57875g==",
|
"integrity": "sha512-l8bUi+urcdqLjckGcEyDmYyAYCKjwFXpk/En7gpi5x32Nq2r9sHq7obX3Jbk1F7zH4rmpKbVtjS97cKEZr9zHQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ogcapi-js/features": "^1.1.1",
|
"@ogcapi-js/features": "^1.1.1",
|
||||||
"@ogcapi-js/shared": "^1.1.1",
|
"@ogcapi-js/shared": "^1.1.1",
|
||||||
|
@ -32087,9 +32087,9 @@
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
},
|
},
|
||||||
"panoramax-js": {
|
"panoramax-js": {
|
||||||
"version": "0.3.6",
|
"version": "0.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/panoramax-js/-/panoramax-js-0.3.8.tgz",
|
||||||
"integrity": "sha512-CRdXwh91H6chd1PYptG070ukx+S6IkVaUeQVG91ySevoJoCYOuBT65qkMhRo49X2um1nGcs9UqolW90R57875g==",
|
"integrity": "sha512-l8bUi+urcdqLjckGcEyDmYyAYCKjwFXpk/En7gpi5x32Nq2r9sHq7obX3Jbk1F7zH4rmpKbVtjS97cKEZr9zHQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ogcapi-js/features": "^1.1.1",
|
"@ogcapi-js/features": "^1.1.1",
|
||||||
"@ogcapi-js/shared": "^1.1.1",
|
"@ogcapi-js/shared": "^1.1.1",
|
||||||
|
|
|
@ -208,7 +208,7 @@
|
||||||
"opening_hours": "^3.6.0",
|
"opening_hours": "^3.6.0",
|
||||||
"osm-auth": "^2.5.0",
|
"osm-auth": "^2.5.0",
|
||||||
"osmtogeojson": "^3.0.0-beta.5",
|
"osmtogeojson": "^3.0.0-beta.5",
|
||||||
"panoramax-js": "^0.3.6",
|
"panoramax-js": "^0.3.8",
|
||||||
"panzoom": "^9.4.3",
|
"panzoom": "^9.4.3",
|
||||||
"papaparse": "^5.3.1",
|
"papaparse": "^5.3.1",
|
||||||
"pg": "^8.11.3",
|
"pg": "^8.11.3",
|
||||||
|
|
|
@ -81,11 +81,10 @@ export class ImageUploadManager {
|
||||||
|
|
||||||
public canBeUploaded(file: File): true | { error: Translation } {
|
public canBeUploaded(file: File): true | { error: Translation } {
|
||||||
const sizeInBytes = file.size
|
const sizeInBytes = file.size
|
||||||
const self = this
|
|
||||||
if (sizeInBytes > this._uploader.maxFileSizeInMegabytes * 1000000) {
|
if (sizeInBytes > this._uploader.maxFileSizeInMegabytes * 1000000) {
|
||||||
const error = Translations.t.image.toBig.Subs({
|
const error = Translations.t.image.toBig.Subs({
|
||||||
actual_size: Math.floor(sizeInBytes / 1000000) + "MB",
|
actual_size: Math.floor(sizeInBytes / 1000000) + "MB",
|
||||||
max_size: self._uploader.maxFileSizeInMegabytes + "MB",
|
max_size: this._uploader.maxFileSizeInMegabytes + "MB",
|
||||||
})
|
})
|
||||||
return { error }
|
return { error }
|
||||||
}
|
}
|
||||||
|
@ -102,7 +101,8 @@ export class ImageUploadManager {
|
||||||
public async uploadImageAndApply(
|
public async uploadImageAndApply(
|
||||||
file: File,
|
file: File,
|
||||||
tagsStore: UIEventSource<OsmTags>,
|
tagsStore: UIEventSource<OsmTags>,
|
||||||
targetKey?: string,
|
targetKey: string,
|
||||||
|
noblur: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const canBeUploaded = this.canBeUploaded(file)
|
const canBeUploaded = this.canBeUploaded(file)
|
||||||
if (canBeUploaded !== true) {
|
if (canBeUploaded !== true) {
|
||||||
|
@ -120,6 +120,7 @@ export class ImageUploadManager {
|
||||||
author,
|
author,
|
||||||
file,
|
file,
|
||||||
targetKey,
|
targetKey,
|
||||||
|
noblur
|
||||||
)
|
)
|
||||||
if (!uploadResult) {
|
if (!uploadResult) {
|
||||||
return
|
return
|
||||||
|
@ -139,6 +140,7 @@ export class ImageUploadManager {
|
||||||
author: string,
|
author: string,
|
||||||
blob: File,
|
blob: File,
|
||||||
targetKey: string | undefined,
|
targetKey: string | undefined,
|
||||||
|
noblur: boolean
|
||||||
): Promise<UploadResult> {
|
): Promise<UploadResult> {
|
||||||
this.increaseCountFor(this._uploadStarted, featureId)
|
this.increaseCountFor(this._uploadStarted, featureId)
|
||||||
let key: string
|
let key: string
|
||||||
|
@ -153,12 +155,12 @@ export class ImageUploadManager {
|
||||||
location = GeoOperations.centerpointCoordinates(feature)
|
location = GeoOperations.centerpointCoordinates(feature)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
;({ key, value, absoluteUrl } = await this._uploader.uploadImage(blob, location, author))
|
({ key, value, absoluteUrl } = await this._uploader.uploadImage(blob, location, author, noblur))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.increaseCountFor(this._uploadRetried, featureId)
|
this.increaseCountFor(this._uploadRetried, featureId)
|
||||||
console.error("Could not upload image, trying again:", e)
|
console.error("Could not upload image, trying again:", e)
|
||||||
try {
|
try {
|
||||||
;({ key, value , absoluteUrl} = await this._uploader.uploadImage(blob, location, author))
|
({ key, value , absoluteUrl} = await this._uploader.uploadImage(blob, location, author, noblur))
|
||||||
this.increaseCountFor(this._uploadRetriedSuccess, featureId)
|
this.increaseCountFor(this._uploadRetriedSuccess, featureId)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Could again not upload image due to", e)
|
console.error("Could again not upload image due to", e)
|
||||||
|
|
|
@ -7,7 +7,8 @@ export interface ImageUploader {
|
||||||
uploadImage(
|
uploadImage(
|
||||||
blob: File,
|
blob: File,
|
||||||
currentGps: [number,number],
|
currentGps: [number,number],
|
||||||
author: string
|
author: string,
|
||||||
|
noblur: boolean
|
||||||
): Promise<UploadResult>
|
): Promise<UploadResult>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -167,12 +167,12 @@ export class PanoramaxUploader implements ImageUploader {
|
||||||
this._panoramax = new AuthorizedPanoramax(url, token)
|
this._panoramax = new AuthorizedPanoramax(url, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
async uploadImage(blob: File, currentGps: [number, number], author: string): Promise<{
|
async uploadImage(blob: File, currentGps: [number, number], author: string, noblur: boolean = false): Promise<{
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
absoluteUrl: string
|
absoluteUrl: string
|
||||||
}> {
|
}> {
|
||||||
|
// https://panoramax.openstreetmap.fr/api/docs/swagger#/
|
||||||
const tags = await ExifReader.load(blob)
|
const tags = await ExifReader.load(blob)
|
||||||
const hasDate = tags.DateTime !== undefined
|
const hasDate = tags.DateTime !== undefined
|
||||||
const hasGPS = tags.GPSLatitude !== undefined && tags.GPSLongitude !== undefined
|
const hasGPS = tags.GPSLatitude !== undefined && tags.GPSLongitude !== undefined
|
||||||
|
@ -184,6 +184,7 @@ export class PanoramaxUploader implements ImageUploader {
|
||||||
const img = <ImageData>await p.addImage(blob, defaultSequence, {
|
const img = <ImageData>await p.addImage(blob, defaultSequence, {
|
||||||
lat: !hasGPS ? lat : undefined,
|
lat: !hasGPS ? lat : undefined,
|
||||||
lon: !hasGPS ? lon : undefined,
|
lon: !hasGPS ? lon : undefined,
|
||||||
|
isBlurred: noblur,
|
||||||
datetime: !hasDate ? new Date().toISOString() : undefined,
|
datetime: !hasDate ? new Date().toISOString() : undefined,
|
||||||
exifOverride: {
|
exifOverride: {
|
||||||
Artist: author,
|
Artist: author,
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||||
import { ImmutableStore, UIEventSource } from "../../Logic/UIEventSource"
|
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import type { OsmId, OsmTags } from "../../Models/OsmFeature"
|
import type { OsmTags } from "../../Models/OsmFeature"
|
||||||
import LoginToggle from "../Base/LoginToggle.svelte"
|
import LoginToggle from "../Base/LoginToggle.svelte"
|
||||||
import Translations from "../i18n/Translations"
|
import Translations from "../i18n/Translations"
|
||||||
import Tr from "../Base/Tr.svelte"
|
import Tr from "../Base/Tr.svelte"
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
export let tags: UIEventSource<OsmTags>
|
export let tags: UIEventSource<OsmTags>
|
||||||
export let targetKey: string = undefined
|
export let targetKey: string = undefined
|
||||||
export let layer: LayerConfig
|
export let layer: LayerConfig
|
||||||
|
export let noBlur: boolean = false
|
||||||
/**
|
/**
|
||||||
* Image to show in the button
|
* Image to show in the button
|
||||||
* NOT the image to upload!
|
* NOT the image to upload!
|
||||||
|
@ -47,22 +48,22 @@
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if(layer?.id === "note"){
|
if (layer?.id === "note") {
|
||||||
const uploadResult = await state?.imageUploadManager.uploadImageWithLicense(tags.data.id,
|
const uploadResult = await state?.imageUploadManager.uploadImageWithLicense(tags.data.id,
|
||||||
state.osmConnection.userDetails.data?.name ?? "Anonymous",
|
state.osmConnection.userDetails.data?.name ?? "Anonymous",
|
||||||
file, "image")
|
file, "image", noBlur)
|
||||||
if(!uploadResult){
|
if (!uploadResult) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const url = uploadResult.absoluteUrl
|
const url = uploadResult.absoluteUrl
|
||||||
await state.osmConnection.addCommentToNote(tags.data.id, url)
|
await state.osmConnection.addCommentToNote(tags.data.id, url)
|
||||||
NoteCommentElement.addCommentTo(url, <UIEventSource<any>>tags, {
|
NoteCommentElement.addCommentTo(url, <UIEventSource<any>>tags, {
|
||||||
osmConnection: state.osmConnection,
|
osmConnection: state.osmConnection
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
await state?.imageUploadManager.uploadImageAndApply(file, tags, targetKey)
|
await state?.imageUploadManager.uploadImageAndApply(file, tags, targetKey, noBlur)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
state.reportError(e, "Could not upload image")
|
state.reportError(e, "Could not upload image")
|
||||||
|
@ -96,12 +97,21 @@
|
||||||
{#if labelText}
|
{#if labelText}
|
||||||
{labelText}
|
{labelText}
|
||||||
{:else}
|
{:else}
|
||||||
<Tr t={t.addPicture} />
|
<div class="flex flex-col">
|
||||||
|
|
||||||
|
<Tr t={t.addPicture} />
|
||||||
|
{#if noBlur}
|
||||||
|
<span class="subtle text-sm">
|
||||||
|
Faces will not be blurred
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</FileSelector>
|
</FileSelector>
|
||||||
<div class="text-xs subtle italic">
|
<div class="text-xs subtle italic">
|
||||||
<Tr t={Translations.t.general.attribution.panoramaxLicenseCCBYSA}/>
|
<Tr t={Translations.t.general.attribution.panoramaxLicenseCCBYSA} />
|
||||||
<span class="mx-1">—</span>
|
<span class="mx-1">—</span>
|
||||||
<Tr t={t.respectPrivacy} />
|
<Tr t={t.respectPrivacy} />
|
||||||
</div>
|
</div>
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue