forked from MapComplete/MapComplete
Enable more privacy for some themes and layers
This commit is contained in:
parent
484adf1ee1
commit
91b836bf66
15 changed files with 59 additions and 16 deletions
|
@ -28,6 +28,7 @@
|
||||||
"pt_BR": "Completaremos os dados das características de publicidade com referência, operador e iluminação",
|
"pt_BR": "Completaremos os dados das características de publicidade com referência, operador e iluminação",
|
||||||
"it": "Completeremo i dati da caratteristiche pubblicitarie, con referenza, operatore e illuminazione"
|
"it": "Completeremo i dati da caratteristiche pubblicitarie, con referenza, operatore e illuminazione"
|
||||||
},
|
},
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": {
|
"osmTags": {
|
||||||
"and": [
|
"and": [
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": "amenity=brothel"
|
"osmTags": "amenity=brothel"
|
||||||
},
|
},
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"minzoom": 6,
|
"minzoom": 6,
|
||||||
"title": {
|
"title": {
|
||||||
"render": {
|
"render": {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"en": "A love hotel is a type of short-stay hotel found around the world operated primarily for the purpose of allowing guests privacy for sexual activities",
|
"en": "A love hotel is a type of short-stay hotel found around the world operated primarily for the purpose of allowing guests privacy for sexual activities",
|
||||||
"de": "Ein Love Hotel ist eine Art Kurzzeithotel, das in erster Linie zu dem Zweck betrieben wird, den Gästen Privatsphäre für sexuelle Aktivitäten zu bieten"
|
"de": "Ein Love Hotel ist eine Art Kurzzeithotel, das in erster Linie zu dem Zweck betrieben wird, den Gästen Privatsphäre für sexuelle Aktivitäten zu bieten"
|
||||||
},
|
},
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": "amenity=love_hotel"
|
"osmTags": "amenity=love_hotel"
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"en": "A venue where erotic dance, striptease, or lap dances are performed commercially. ",
|
"en": "A venue where erotic dance, striptease, or lap dances are performed commercially. ",
|
||||||
"de": "Ein Ort, an dem erotische Tanz-, Striptease- oder Lapdances kommerziell durchgeführt werden. "
|
"de": "Ein Ort, an dem erotische Tanz-, Striptease- oder Lapdances kommerziell durchgeführt werden. "
|
||||||
},
|
},
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": "amenity=stripclub"
|
"osmTags": "amenity=stripclub"
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"cs": "Tato vrstva zobrazuje sledovací kamery a umožňuje přispěvateli aktualizovat informace a přidávat nové kamery",
|
"cs": "Tato vrstva zobrazuje sledovací kamery a umožňuje přispěvateli aktualizovat informace a přidávat nové kamery",
|
||||||
"sl": "Ta sloj prikazuje nadzorne kamere in urednikom omogoča posodabljanje informacij obstoječih in dodajanje novih kamer"
|
"sl": "Ta sloj prikazuje nadzorne kamere in urednikom omogoča posodabljanje informacij obstoječih in dodajanje novih kamer"
|
||||||
},
|
},
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"source": {
|
"source": {
|
||||||
"osmTags": {
|
"osmTags": {
|
||||||
"and": [
|
"and": [
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
},
|
},
|
||||||
"icon": "./assets/layers/stripclub/stripclub.svg",
|
"icon": "./assets/layers/stripclub/stripclub.svg",
|
||||||
"hideFromOverview": true,
|
"hideFromOverview": true,
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"layers": [
|
"layers": [
|
||||||
"brothel",
|
"brothel",
|
||||||
"stripclub",
|
"stripclub",
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
},
|
},
|
||||||
"icon": "./assets/themes/surveillance/logo.svg",
|
"icon": "./assets/themes/surveillance/logo.svg",
|
||||||
"defaultBackgroundId": "maptiler.carto",
|
"defaultBackgroundId": "maptiler.carto",
|
||||||
|
"enableMorePrivacy": true,
|
||||||
"layers": [
|
"layers": [
|
||||||
"surveillance_camera",
|
"surveillance_camera",
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ import Title from "../../UI/Base/Title"
|
||||||
import Table from "../../UI/Base/Table"
|
import Table from "../../UI/Base/Table"
|
||||||
import ChangeLocationAction from "./Actions/ChangeLocationAction"
|
import ChangeLocationAction from "./Actions/ChangeLocationAction"
|
||||||
import ChangeTagAction from "./Actions/ChangeTagAction"
|
import ChangeTagAction from "./Actions/ChangeTagAction"
|
||||||
|
import FeatureSwitchState from "../State/FeatureSwitchState"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all changes made to OSM.
|
* Handles all changes made to OSM.
|
||||||
|
@ -28,7 +29,7 @@ export class Changes {
|
||||||
public readonly pendingChanges: UIEventSource<ChangeDescription[]> =
|
public readonly pendingChanges: UIEventSource<ChangeDescription[]> =
|
||||||
LocalStorageSource.GetParsed<ChangeDescription[]>("pending-changes", [])
|
LocalStorageSource.GetParsed<ChangeDescription[]>("pending-changes", [])
|
||||||
public readonly allChanges = new UIEventSource<ChangeDescription[]>(undefined)
|
public readonly allChanges = new UIEventSource<ChangeDescription[]>(undefined)
|
||||||
public readonly state: { allElements?: IndexedFeatureSource; osmConnection: OsmConnection }
|
public readonly state: { allElements?: IndexedFeatureSource; osmConnection: OsmConnection, featureSwitches?: FeatureSwitchState }
|
||||||
public readonly extraComment: UIEventSource<string> = new UIEventSource(undefined)
|
public readonly extraComment: UIEventSource<string> = new UIEventSource(undefined)
|
||||||
public readonly backend: string
|
public readonly backend: string
|
||||||
public readonly isUploading = new UIEventSource(false)
|
public readonly isUploading = new UIEventSource(false)
|
||||||
|
@ -45,7 +46,8 @@ export class Changes {
|
||||||
allElements?: IndexedFeatureSource
|
allElements?: IndexedFeatureSource
|
||||||
featurePropertiesStore?: FeaturePropertiesStore
|
featurePropertiesStore?: FeaturePropertiesStore
|
||||||
osmConnection: OsmConnection
|
osmConnection: OsmConnection
|
||||||
historicalUserLocations?: FeatureSource
|
historicalUserLocations?: FeatureSource,
|
||||||
|
featureSwitches?: FeatureSwitchState
|
||||||
},
|
},
|
||||||
leftRightSensitive: boolean = false
|
leftRightSensitive: boolean = false
|
||||||
) {
|
) {
|
||||||
|
@ -431,6 +433,9 @@ export class Changes {
|
||||||
// Probably irrelevant, such as a new helper node
|
// Probably irrelevant, such as a new helper node
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if(this.state.featureSwitches.featureSwitchMorePrivacy?.data){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const recentLocationPoints = locations
|
const recentLocationPoints = locations
|
||||||
|
|
|
@ -6,14 +6,6 @@ import Constants from "../../Models/Constants"
|
||||||
import { Changes } from "./Changes"
|
import { Changes } from "./Changes"
|
||||||
import { Utils } from "../../Utils"
|
import { Utils } from "../../Utils"
|
||||||
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
||||||
import ChangeLocationAction from "./Actions/ChangeLocationAction"
|
|
||||||
import ChangeTagAction from "./Actions/ChangeTagAction"
|
|
||||||
import DeleteAction from "./Actions/DeleteAction"
|
|
||||||
import LinkImageAction from "./Actions/LinkImageAction"
|
|
||||||
import OsmChangeAction from "./Actions/OsmChangeAction"
|
|
||||||
import RelationSplitHandler from "./Actions/RelationSplitHandler"
|
|
||||||
import ReplaceGeometryAction from "./Actions/ReplaceGeometryAction"
|
|
||||||
import SplitAction from "./Actions/SplitAction"
|
|
||||||
|
|
||||||
export interface ChangesetTag {
|
export interface ChangesetTag {
|
||||||
key: string
|
key: string
|
||||||
|
@ -232,7 +224,7 @@ export class ChangesetHandler {
|
||||||
if (newMetaTag === undefined) {
|
if (newMetaTag === undefined) {
|
||||||
extraMetaTags.push({
|
extraMetaTags.push({
|
||||||
key: key,
|
key: key,
|
||||||
value: oldCsTags[key],
|
value: oldCsTags[key]
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -361,21 +353,22 @@ export class ChangesetHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private defaultChangesetTags(): ChangesetTag[] {
|
private defaultChangesetTags(): ChangesetTag[] {
|
||||||
|
const usedGps = this.changes.state["currentUserLocation"]?.features?.data?.length > 0
|
||||||
|
const hasMorePrivacy = !!this.changes.state?.featureSwitches?.featureSwitchMorePrivacy?.data
|
||||||
|
const setSourceAsSurvey = !hasMorePrivacy && usedGps
|
||||||
return [
|
return [
|
||||||
["created_by", `MapComplete ${Constants.vNumber}`],
|
["created_by", `MapComplete ${Constants.vNumber}`],
|
||||||
["locale", Locale.language.data],
|
["locale", Locale.language.data],
|
||||||
["host", `${window.location.origin}${window.location.pathname}`],
|
["host", `${window.location.origin}${window.location.pathname}`],
|
||||||
[
|
[
|
||||||
"source",
|
"source",
|
||||||
this.changes.state["currentUserLocation"]?.features?.data?.length > 0
|
setSourceAsSurvey ? "survey" : undefined
|
||||||
? "survey"
|
|
||||||
: undefined,
|
|
||||||
],
|
],
|
||||||
["imagery", this.changes.state["backgroundLayer"]?.data?.id],
|
["imagery", this.changes.state["backgroundLayer"]?.data?.id]
|
||||||
].map(([key, value]) => ({
|
].map(([key, value]) => ({
|
||||||
key,
|
key,
|
||||||
value,
|
value,
|
||||||
aggregate: false,
|
aggregate: false
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
||||||
public readonly overpassMaxZoom: UIEventSource<number>
|
public readonly overpassMaxZoom: UIEventSource<number>
|
||||||
public readonly osmApiTileSize: UIEventSource<number>
|
public readonly osmApiTileSize: UIEventSource<number>
|
||||||
public readonly backgroundLayerId: UIEventSource<string>
|
public readonly backgroundLayerId: UIEventSource<string>
|
||||||
|
public readonly featureSwitchMorePrivacy: UIEventSource<boolean>
|
||||||
|
|
||||||
public constructor(layoutToUse?: LayoutConfig) {
|
public constructor(layoutToUse?: LayoutConfig) {
|
||||||
super()
|
super()
|
||||||
|
@ -164,6 +165,14 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
|
||||||
"If true, shows some extra debugging help such as all the available tags on every object"
|
"If true, shows some extra debugging help such as all the available tags on every object"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
this.featureSwitchMorePrivacy = QueryParameters.GetBooleanQueryParameter(
|
||||||
|
"moreprivacy",
|
||||||
|
layoutToUse.enableMorePrivacy,
|
||||||
|
"If true, the location distance indication will not be written to the changeset and other privacy enhancing measures might be taken."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
this.overpassUrl = QueryParameters.GetQueryParameter(
|
this.overpassUrl = QueryParameters.GetQueryParameter(
|
||||||
"overpassUrl",
|
"overpassUrl",
|
||||||
(layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(","),
|
(layoutToUse?.overpassUrl ?? Constants.defaultOverpassUrls).join(","),
|
||||||
|
|
|
@ -554,4 +554,15 @@ export interface LayerConfigJson {
|
||||||
* group: hidden
|
* group: hidden
|
||||||
*/
|
*/
|
||||||
fullNodeDatabase?: boolean
|
fullNodeDatabase?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* question: Should a theme using this layer leak some location info when making changes?
|
||||||
|
*
|
||||||
|
* When a changeset is made, a 'distance to object'-class is written to the changeset.
|
||||||
|
* For some particular themes and layers, this might leak too much information, and we want to obfuscate this
|
||||||
|
*
|
||||||
|
* ifunset: Write 'change_within_x_m' as usual and if GPS is enabled
|
||||||
|
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
|
||||||
|
*/
|
||||||
|
enableMorePrivacy: boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,4 +439,16 @@ export interface LayoutConfigJson {
|
||||||
* group: hidden
|
* group: hidden
|
||||||
*/
|
*/
|
||||||
enableNodeDatabase?: boolean
|
enableNodeDatabase?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* question: Should this theme leak some location info when making changes?
|
||||||
|
*
|
||||||
|
* When a changeset is made, a 'distance to object'-class is written to the changeset.
|
||||||
|
* For some particular themes and layers, this might leak too much information, and we want to obfuscate this
|
||||||
|
*
|
||||||
|
* ifunset: Write 'change_within_x_m' as usual and if GPS is enabled
|
||||||
|
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
|
||||||
|
*/
|
||||||
|
enableMorePrivacy: boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ export default class LayerConfig extends WithContextLoader {
|
||||||
|
|
||||||
public readonly _needsFullNodeDatabase: boolean
|
public readonly _needsFullNodeDatabase: boolean
|
||||||
public readonly popupInFloatover: boolean | string
|
public readonly popupInFloatover: boolean | string
|
||||||
|
public readonly enableMorePrivacy: boolean
|
||||||
|
|
||||||
constructor(json: LayerConfigJson, context?: string, official: boolean = true) {
|
constructor(json: LayerConfigJson, context?: string, official: boolean = true) {
|
||||||
context = context + "." + json.id
|
context = context + "." + json.id
|
||||||
|
@ -149,6 +150,7 @@ export default class LayerConfig extends WithContextLoader {
|
||||||
this.shownByDefault = json.shownByDefault ?? true
|
this.shownByDefault = json.shownByDefault ?? true
|
||||||
this.doCount = json.isCounted ?? this.shownByDefault ?? true
|
this.doCount = json.isCounted ?? this.shownByDefault ?? true
|
||||||
this.forceLoad = json.forceLoad ?? false
|
this.forceLoad = json.forceLoad ?? false
|
||||||
|
this.enableMorePrivacy = json.enableMorePrivacy ?? false
|
||||||
if (json.presets === null) json.presets = undefined
|
if (json.presets === null) json.presets = undefined
|
||||||
if (json.presets !== undefined && json.presets?.map === undefined) {
|
if (json.presets !== undefined && json.presets?.map === undefined) {
|
||||||
throw "Presets should be a list of items (at " + context + ")"
|
throw "Presets should be a list of items (at " + context + ")"
|
||||||
|
|
|
@ -63,6 +63,8 @@ export default class LayoutConfig implements LayoutInformation {
|
||||||
public readonly enableExportButton: boolean
|
public readonly enableExportButton: boolean
|
||||||
public readonly enablePdfDownload: boolean
|
public readonly enablePdfDownload: boolean
|
||||||
public readonly enableTerrain: boolean
|
public readonly enableTerrain: boolean
|
||||||
|
public readonly enableMorePrivacy: boolean
|
||||||
|
|
||||||
|
|
||||||
public readonly customCss?: string
|
public readonly customCss?: string
|
||||||
|
|
||||||
|
@ -204,6 +206,7 @@ export default class LayoutConfig implements LayoutInformation {
|
||||||
this.overpassTimeout = json.overpassTimeout ?? 30
|
this.overpassTimeout = json.overpassTimeout ?? 30
|
||||||
this.overpassMaxZoom = json.overpassMaxZoom ?? 16
|
this.overpassMaxZoom = json.overpassMaxZoom ?? 16
|
||||||
this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1
|
this.osmApiTileSize = json.osmApiTileSize ?? this.overpassMaxZoom + 1
|
||||||
|
this.enableMorePrivacy = json.enableMorePrivacy || json.layers.some(l => (<LayerConfigJson> l).enableMorePrivacy)
|
||||||
|
|
||||||
this.layersDict = new Map<string, LayerConfig>()
|
this.layersDict = new Map<string, LayerConfig>()
|
||||||
for (const layer of this.layers) {
|
for (const layer of this.layers) {
|
||||||
|
|
|
@ -265,6 +265,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
||||||
featurePropertiesStore: this.featureProperties,
|
featurePropertiesStore: this.featureProperties,
|
||||||
osmConnection: this.osmConnection,
|
osmConnection: this.osmConnection,
|
||||||
historicalUserLocations: this.geolocation.historicalUserLocations,
|
historicalUserLocations: this.geolocation.historicalUserLocations,
|
||||||
|
featureSwitches: this.featureSwitches
|
||||||
},
|
},
|
||||||
layout?.isLeftRightSensitive() ?? false
|
layout?.isLeftRightSensitive() ?? false
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue