MapComplete/src/Models/Constants.ts

348 lines
13 KiB
TypeScript

import * as packagefile from "../../package.json"
import * as extraconfig from "../../config.json"
import { AuthConfig } from "../Logic/Osm/AuthConfig"
import { ServerSourceInfo } from "./SourceOverview"
export type PriviligedLayerType = (typeof Constants.priviliged_layers)[number]
export type DefaultPinIcon = (typeof Constants._defaultPinIcons)[number]
export default class Constants {
public static vNumber: string = packagefile.version
/**
* API key for Maproulette
*
* There is no user-friendly way to get the user's API key currently.
* See https://github.com/maproulette/maproulette2/issues/476 for more information.
* Using an empty string however does work for most actions, but will attribute all actions to the Superuser.
*/
public static readonly MaprouletteApiKey = ""
public static readonly added_by_default = [
"selected_element",
"gps_location",
"gps_location_history",
"home_location",
"gps_track",
"range",
"last_click",
"favourite",
"summary",
"search",
"geocoded_image",
] as const
/**
* Special layers which are not included in a theme by default
*/
public static readonly no_include = [
"conflation",
"split_point",
"split_road",
"current_view",
"import_candidate",
"usersettings",
"icons",
"filters",
] as const
/**
* Layer IDs of layers which have special properties through built-in hooks
*/
public static readonly priviliged_layers = [
...Constants.added_by_default,
...Constants.no_include,
] as const
public static panoramax: {
url: string
token: string
sequence: string
testsequence: string
} & ServerSourceInfo = { ...packagefile.config.panoramax,
description: "The panoramax-server that MapComplete uploads to",
category: "core",
sourceAvailable: true,
openData: true,
selfhostable: true,
moreInfo: ["https://wiki.openstreetmap.org/wiki/Panoramax"]
}
// The user journey states thresholds when a new feature gets unlocked
public static userJourney = {
moreScreenUnlock: 1,
personalThemeUnlock: 5,
historyLinkVisible: 10,
deletePointsOfOthersUnlock: 20,
tagsVisibleAt: 25,
tagsVisibleAndWikiLinked: 30,
mapCompleteHelpUnlock: 50,
themeGeneratorReadOnlyUnlock: 50,
addNewPointWithUnreadMessagesUnlock: 500,
importHelperUnlock: 5000,
}
static readonly minZoomLevelToAddNewPoint = 18
/**
* Used by 'PendingChangesUploader', which waits this amount of seconds to upload changes.
* (Note that pendingChanges might upload sooner if the popup is closed or similar)
*/
static updateTimeoutSec: number = 15
/**
* If the contributor has their GPS location enabled and makes a change,
* the points visited less then `nearbyVisitTime`-seconds ago will be inspected.
* The point closest to the changed feature will be considered and this distance will be tracked.
* ALl these distances are used to calculate a nearby-score
*/
static nearbyVisitTime: number = 30 * 60
/**
* If a user makes a change, the distance to the changed object is calculated.
* If a user makes multiple changes, all these distances are put into multiple bins, depending on this distance.
* For every bin, the totals are uploaded as metadata
*/
static distanceToChangeObjectBins = [25, 50, 100, 500, 1000, 5000, Number.MAX_VALUE]
static themeOrder = [
"personal",
"cyclofix",
"etymology",
"waste",
"food",
"cafes_and_pubs",
"shops",
"healthcare",
"sports",
"artwork",
"bookcases",
"playgrounds",
"drinking_water",
"toilets",
"vending_machine",
"aed",
"clock",
"charging_stations",
"surveillance",
"advertising",
"circular_economy",
]
/**
* Upon initialization, the GPS will search the location.
* If the location is found within the given timout, it'll automatically fly to it.
*
* In seconds
*/
static zoomToLocationTimeout = 15
public static readonly viewportCenterCloseToGpsCutoff: number = 20
private static readonly config = (() => {
const defaultConfig = packagefile.config
return { ...defaultConfig, ...extraconfig }
})()
public static ImgurApiKey = Constants.config.api_keys.imgur
public static readonly mapillary_client_token_v4 = Constants.config.api_keys.mapillary_v4
public static defaultOverpassUrls = Constants.config.default_overpass_urls
public static countryCoderEndpoint: string = Constants.config.country_coder_host
public static countryCoderInfo: ServerSourceInfo = {
url: this.countryCoderEndpoint,
trigger: ["always"],
openData: true,
category: "core",
logging: "no",
selfhostable: true,
sourceAvailable: true,
moreInfo:["https://source.mapcomplete.org/MapComplete/latlon2country"],
description: "For quite some functions, we need to know in what _country_ a feature is located. LatLon2Country is a static dataset, which, by cleverly encoding the data, can quickly tell in what country a feature is located."
}
public static communityIndexHost: string = Constants.config.community_index_host
private static osmServerInfo: Omit<ServerSourceInfo, "url"> = { trigger: ["always"],
description: "Login service, by OpenStreetMap.org",
sourceAvailable: true,
openData: true,
selfhostable: "partially - a copy can be hosted, but this would be useless",
category: "core",
moreInfo: ["https://www.openstreetmap.org/copyright","https://www.openstreetmap.org/about", "https://osmfoundation.org/wiki/Privacy_Policy"]
}
public static osmAuthConfig: AuthConfig & ServerSourceInfo= {... Constants.config.oauth_credentials,
...this.osmServerInfo
}
public static nominatimEndpoint: string = Constants.config.nominatimEndpoint
public static nominatimEndpointInfo: ServerSourceInfo = {
url: this.nominatimEndpoint,
description: "Nominatim search engine endpoint, used when searching",
selfhostable: true,
openData: true,
sourceAvailable: true,
category: "core",
trigger:["specific_feature"],
moreInfo: ["https://wiki.openstreetmap.org/wiki/Nominatim"]
}
public static photonEndpoint: string = Constants.config.photonEndpoint
public static photonEndpointInfo: ServerSourceInfo = {
url: this.photonEndpoint,
description: "Endpoint for search with photon",
sourceAvailable: true,
selfhostable: true,
openData: true,
category: "core",
trigger: ["specific_feature"],
moreInfo: ["https://wiki.openstreetmap.org/wiki/Photon"]
}
public static nsiLogosEndpoint: string = Constants.config.nsi_logos_server ?? null
public static weblate: string = "https://translate.mapcomplete.org/"
public static linkedDataProxy: string = Constants.config["jsonld-proxy"]
public static linkedDataProxyInfo: ServerSourceInfo = {
url: Constants.config["jsonld-proxy"],
trigger: ["specific_feature"],
category: "core",
openData: true,
description: "This proxy queries websites to detect if they contain linked open data and gives this data back. Triggered by opening a feature",
sourceAvailable: true,
selfhostable: true,
moreInfo: ["https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/scripts/serverLdScrape.ts"]
}
/**
* These are the values that are allowed to use as 'backdrop' icon for a map pin
*/
public static readonly _defaultPinIcons = [
"addSmall",
"airport",
"brick_wall_round",
"brick_wall_square",
"building_office_2",
"building_storefront",
"bug",
"checkmark",
"checkmark",
"circle",
"clock",
"close",
"close",
"confirm",
"computer",
"cross_bottom_right",
"crosshair",
"desktop",
"direction",
"gear",
"globe_alt",
"gps_arrow",
"heart",
"heart_outline",
"help",
"help",
"home",
"house",
"key",
"invalid",
"invalid",
"link",
"location",
"location_empty",
"location_locked",
"lock",
"mastodon",
"not_found",
"note",
"party",
"pencil",
"pin",
"resolved",
"ring",
"scissors",
"snowflake",
"square",
"square_rounded",
"teardrop",
"teardrop_with_hole_green",
"train",
"triangle",
"user_circle",
"wifi",
] as const
public static readonly defaultPinIcons: string[] = <any>Constants._defaultPinIcons
/**
* The location that the MVT-layer is hosted.
* This is a MapLibre/MapBox vector tile server which hosts vector tiles for every (official) layer
*/
public static VectorTileServer: string | undefined = Constants.config.mvt_layer_server
public static vectorTileServerInfo: ServerSourceInfo = {
url: this.VectorTileServer,
description: "The vectortileserver is a cache of OSM data and can be used as an alternative for overpass to actually show data, esp on low zoom levels",
selfhostable: true,
openData: true,
category: "core",
sourceAvailable: true,
trigger: ["always"],
moreInfo: ["https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/Docs/SettingUpPSQL.md"]
}
public static GeoIpServer: string | undefined = Constants.config.geoip_server
public static geoIpServerInfo: ServerSourceInfo = {
url: this.GeoIpServer,
category: "core",
description: "When opening MapComplete for the first time, we try to set the map at a relevant location. For this, we try to determine the location based on the IP-address; this is done by this service.",
selfhostable: true,
openData: false,
trigger: ["always"],
sourceAvailable: true
}
public static ErrorReportServer: string | undefined = Constants.config.error_server
public static errorReportServerInfo: ServerSourceInfo = {
url: this.ErrorReportServer,
logging: "yes",
category: "core",
selfhostable: "yes",
openData: "no (privacy)",
trigger: ["on_failure"],
description: "If a severe error occurs in MapComplete, this is logged on this server - this mostly concerns errors where making a change to OpenStreetMap failed. Data is handled confidentially and _only_ to replay the change and fix the root cause."
}
public static readonly SummaryServer: string = Constants.config.summary_server
public static readonly summaryServerInfo: ServerSourceInfo = {
url: this.SummaryServer,
trigger: ["always"],
category: "core",
selfhostable: true,
sourceAvailable: true,
openData: true,
description: "This server indicates how much items there are (according to OpenStreetMap) at a given slippy tile coordinate"
}
public static allServers: ServerSourceInfo[] = [
{
description: "OpenStreetMap.org, the source of most data",
url: "https://api.openstreetmap.org",
category: "core"
},
Constants.summaryServerInfo,
Constants.vectorTileServerInfo,
Constants.geoIpServerInfo,
Constants.errorReportServerInfo,
Constants.osmAuthConfig,
Constants.countryCoderInfo,
Constants.nominatimEndpointInfo,
Constants.photonEndpointInfo,
...Constants.defaultOverpassUrls.map(url => (<ServerSourceInfo>{
url,
openData: true,
selfhostable: true,
trigger: ["always"],
sourceAvailable: true,
category: "core",
description: "Overpass is a query service where OpenStreetMap-data can be retrieved. Various overpass-servers are used to query this data",
moreInfo: ["https://wiki.openstreetmap.org/wiki/Overpass_turbo"]
})),
]
private static priviligedLayerSet = new Set<string>(Constants.priviliged_layers)
public static isPriviliged(layer: string | { id: string }) {
let id: string
if (typeof layer === "string") {
id = layer
} else {
id = layer.id
}
return this.priviligedLayerSet.has(id)
}
}