forked from MapComplete/MapComplete
		
	More work on layerserver, generate
This commit is contained in:
		
							parent
							
								
									f0823f4c4d
								
							
						
					
					
						commit
						6b507504f8
					
				
					 13 changed files with 124 additions and 70 deletions
				
			
		
							
								
								
									
										9
									
								
								Docs/ServerConfig/cache/Caddyfile
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Docs/ServerConfig/cache/Caddyfile
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | cache.mapcomplete.org { | ||||||
|  |     reverse_proxy /mvt { | ||||||
|  |         to http://127.0.0.1:7800 | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     reverse_proxy /summary { | ||||||
|  |         to http://127.0.0.1:2345 | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								Docs/ServerConfig/cache/cache.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Docs/ServerConfig/cache/cache.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | # Cache.mapComplete.org server config | ||||||
|  | 
 | ||||||
|  | The "cache"-server is hosted at nerdlab. | ||||||
|  | 
 | ||||||
|  | It has a full OSM-copy on disk, and has a Postgis/Postgres database with a table for every layer for quick access. It should run the tileserver and the summaryserver | ||||||
|  | 
 | ||||||
|  | ## Dyndns | ||||||
|  | 
 | ||||||
|  | https://dynamicdns.park-your-domain.com/update?host=cache&domain=mapcomplete.org&password=[ddns_password] | ||||||
|  | 
 | ||||||
|  | ## Setup | ||||||
|  | 
 | ||||||
|  | See SettingUpPSQL.md | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
							
								
								
									
										5
									
								
								Docs/ServerConfig/hetzner/hetzner.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Docs/ServerConfig/hetzner/hetzner.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | # Hetzner | ||||||
|  | 
 | ||||||
|  | This server hosts the studio files and is used for expermintal builds. | ||||||
|  | 
 | ||||||
|  | For used hosts, see the Caddyfile | ||||||
|  | @ -54,7 +54,7 @@ pg_tileserv kan hier gedownload worden: https://github.com/CrunchyData/pg_tilese | ||||||
| 
 | 
 | ||||||
| ```` | ```` | ||||||
| export DATABASE_URL=postgresql://user:password@localhost:5444/osm-poi | export DATABASE_URL=postgresql://user:password@localhost:5444/osm-poi | ||||||
| ./pg_tileserv | nohup ./pg_tileserv & | ||||||
| ```` | ```` | ||||||
| 
 | 
 | ||||||
| Tiles are available at:  | Tiles are available at:  | ||||||
|  | @ -64,3 +64,8 @@ map.addSource("drinking_water", { | ||||||
| "tiles": ["http://127.0.0.2:7800/public.drinking_water/{z}/{x}/{y}.pbf"] // http://127.0.0.2:7800/public.drinking_water.json", | "tiles": ["http://127.0.0.2:7800/public.drinking_water/{z}/{x}/{y}.pbf"] // http://127.0.0.2:7800/public.drinking_water.json", | ||||||
| }) | }) | ||||||
| ```` | ```` | ||||||
|  | 
 | ||||||
|  | # Rebooting: | ||||||
|  | 
 | ||||||
|  | -> Restart the docker container | ||||||
|  | ->  | ||||||
|  |  | ||||||
|  | @ -1,2 +1,2 @@ | ||||||
| SPDX-FileCopyrightText: Pieter Vander Vennet | SPDX-FileCopyrightText: Pieter Vander Vennet | ||||||
| SPDX-License-Identifier: CC0 | SPDX-License-Identifier: CC0-1.0 | ||||||
|  | @ -1,2 +1,2 @@ | ||||||
| SPDX-FileCopyrightText: Pieter Vander Vennet | SPDX-FileCopyrightText: Pieter Vander Vennet | ||||||
| SPDX-License-Identifier: CC0 | SPDX-License-Identifier: CC0-1.0 | ||||||
|  | @ -59,4 +59,3 @@ | ||||||
|     "minzoom": 16 |     "minzoom": 16 | ||||||
|   } |   } | ||||||
| } | } | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
|       "oauth_secret": "NBWGhWDrD3QDB35xtVuxv4aExnmIt4FA_WgeLtwxasg", |       "oauth_secret": "NBWGhWDrD3QDB35xtVuxv4aExnmIt4FA_WgeLtwxasg", | ||||||
|       "url": "https://www.openstreetmap.org" |       "url": "https://www.openstreetmap.org" | ||||||
|     }, |     }, | ||||||
|     "mvt_layer_server": "http://127.0.0.1:7800/public.{type}_{layer}/{z}/{x}/{y}.pbf", |     "mvt_layer_server": "http://cache.mapcomplete.org/mvt/public.{type}_{layer}/{z}/{x}/{y}.pbf", | ||||||
|     "disabled:oauth_credentials": { |     "disabled:oauth_credentials": { | ||||||
|       "##": "DEV", |       "##": "DEV", | ||||||
|       "#": "This client-id is registered by 'MapComplete' on https://master.apis.dev.openstreetmap.org/", |       "#": "This client-id is registered by 'MapComplete' on https://master.apis.dev.openstreetmap.org/", | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ class OsmPoiDatabase { | ||||||
|     private static readonly prefixes: ReadonlyArray<string> = ["pois", "lines", "polygons"] |     private static readonly prefixes: ReadonlyArray<string> = ["pois", "lines", "polygons"] | ||||||
|     private readonly _client: Client |     private readonly _client: Client | ||||||
|     private isConnected = false |     private isConnected = false | ||||||
|     private supportedLayers: string[] = undefined |     private supportedLayers: Set<string> = undefined | ||||||
|     private metaCache: PoiDatabaseMeta = undefined |     private metaCache: PoiDatabaseMeta = undefined | ||||||
|     private metaCacheDate: Date = undefined |     private metaCacheDate: Date = undefined | ||||||
| 
 | 
 | ||||||
|  | @ -64,7 +64,7 @@ class OsmPoiDatabase { | ||||||
|         this._client.end() |         this._client.end() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getLayers(): Promise<string[]> { |     async getLayers(): Promise<Set<string>> { | ||||||
|         if (this.supportedLayers !== undefined) { |         if (this.supportedLayers !== undefined) { | ||||||
|             return this.supportedLayers |             return this.supportedLayers | ||||||
|         } |         } | ||||||
|  | @ -74,8 +74,8 @@ class OsmPoiDatabase { | ||||||
|                 "WHERE table_schema = 'public' AND table_name LIKE 'lines_%';" |                 "WHERE table_schema = 'public' AND table_name LIKE 'lines_%';" | ||||||
|         ) |         ) | ||||||
|         const layers = result.rows.map((r) => r.table_name.substring("lines_".length)) |         const layers = result.rows.map((r) => r.table_name.substring("lines_".length)) | ||||||
|         this.supportedLayers = layers |         this.supportedLayers = new Set(layers) | ||||||
|         return layers |         return this.supportedLayers | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getMeta(): Promise<PoiDatabaseMeta> { |     async getMeta(): Promise<PoiDatabaseMeta> { | ||||||
|  | @ -218,7 +218,12 @@ const server = new Server(2345, [ | ||||||
| 
 | 
 | ||||||
|             let sum = 0 |             let sum = 0 | ||||||
|             let properties: Record<string, number> = {} |             let properties: Record<string, number> = {} | ||||||
|  |             const availableLayers = await tcs.getLayers() | ||||||
|             for (const layer of layers.split("+")) { |             for (const layer of layers.split("+")) { | ||||||
|  |                 console.log("Getting layer", layer) | ||||||
|  |                 if (!availableLayers.has(layer)) { | ||||||
|  |                     continue | ||||||
|  |                 } | ||||||
|                 const count = await tcs.getCount( |                 const count = await tcs.getCount( | ||||||
|                     layer, |                     layer, | ||||||
|                     Tiles.tile_bounds_lon_lat(Number(z), Number(x), Number(y)) |                     Tiles.tile_bounds_lon_lat(Number(z), Number(x), Number(y)) | ||||||
|  |  | ||||||
|  | @ -11,9 +11,7 @@ import DynamicGeoJsonTileSource from "../TiledFeatureSource/DynamicGeoJsonTileSo | ||||||
| import { BBox } from "../../BBox" | import { BBox } from "../../BBox" | ||||||
| import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeatureSource" | import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeatureSource" | ||||||
| import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource" | import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource" | ||||||
| import { Features } from "@rgossiaux/svelte-headlessui/types" |  | ||||||
| import DynamicMvtileSource from "../TiledFeatureSource/DynamicMvtTileSource" | import DynamicMvtileSource from "../TiledFeatureSource/DynamicMvtTileSource" | ||||||
| import { layouts } from "chart.js" |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * This source will fetch the needed data from various sources for the given layout. |  * This source will fetch the needed data from various sources for the given layout. | ||||||
|  | @ -21,17 +19,18 @@ import { layouts } from "chart.js" | ||||||
|  * Note that special layers (with `source=null` will be ignored) |  * Note that special layers (with `source=null` will be ignored) | ||||||
|  */ |  */ | ||||||
| export default class LayoutSource extends FeatureSourceMerger { | export default class LayoutSource extends FeatureSourceMerger { | ||||||
|     private readonly _isLoading: UIEventSource<boolean> = new UIEventSource<boolean>(false) |  | ||||||
|     /** |     /** | ||||||
|      * Indicates if a data source is loading something |      * Indicates if a data source is loading something | ||||||
|      */ |      */ | ||||||
|     public readonly isLoading: Store<boolean> = this._isLoading |     public readonly isLoading: Store<boolean> | ||||||
|  | 
 | ||||||
|     constructor( |     constructor( | ||||||
|         layers: LayerConfig[], |         layers: LayerConfig[], | ||||||
|         featureSwitches: FeatureSwitchState, |         featureSwitches: FeatureSwitchState, | ||||||
|         mapProperties: { bounds: Store<BBox>; zoom: Store<number> }, |         mapProperties: { bounds: Store<BBox>; zoom: Store<number> }, | ||||||
|         backend: string, |         backend: string, | ||||||
|         isDisplayed: (id: string) => Store<boolean>, |         isDisplayed: (id: string) => Store<boolean>, | ||||||
|  |         mvtAvailableLayers: Set<string>, | ||||||
|         fullNodeDatabaseSource?: FullNodeDatabaseSource |         fullNodeDatabaseSource?: FullNodeDatabaseSource | ||||||
|     ) { |     ) { | ||||||
|         const { bounds, zoom } = mapProperties |         const { bounds, zoom } = mapProperties | ||||||
|  | @ -47,18 +46,25 @@ export default class LayoutSource extends FeatureSourceMerger { | ||||||
|                     maxAge: l.maxAgeOfCache, |                     maxAge: l.maxAgeOfCache, | ||||||
|                 }) |                 }) | ||||||
|         ) |         ) | ||||||
|         console.log(mapProperties) |         const mvtSources: FeatureSource[] = osmLayers | ||||||
|         const mvtSources: FeatureSource[] = osmLayers.map(l => LayoutSource.setupMvtSource(l, mapProperties, isDisplayed(l.id))) |             .filter((f) => mvtAvailableLayers.has(f.id)) | ||||||
|  |             .map((l) => LayoutSource.setupMvtSource(l, mapProperties, isDisplayed(l.id))) | ||||||
|  |         const nonMvtSources = [] | ||||||
|  |         const nonMvtLayers = osmLayers.filter((l) => !mvtAvailableLayers.has(l.id)) | ||||||
| 
 | 
 | ||||||
| 
 |         const isLoading = new UIEventSource(false) | ||||||
|         /* |         if (nonMvtLayers.length > 0) { | ||||||
|  |             console.log( | ||||||
|  |                 "Layers ", | ||||||
|  |                 nonMvtLayers.map((l) => l.id), | ||||||
|  |                 " cannot be fetched from the cache server, defaulting to overpass/OSM-api" | ||||||
|  |             ) | ||||||
|             const overpassSource = LayoutSource.setupOverpass( |             const overpassSource = LayoutSource.setupOverpass( | ||||||
|                 osmLayers, |                 osmLayers, | ||||||
|                 bounds, |                 bounds, | ||||||
|                 zoom, |                 zoom, | ||||||
|                 featureSwitches |                 featureSwitches | ||||||
|         )//*/
 |             ) | ||||||
| /* |  | ||||||
|             const osmApiSource = LayoutSource.setupOsmApiSource( |             const osmApiSource = LayoutSource.setupOsmApiSource( | ||||||
|                 osmLayers, |                 osmLayers, | ||||||
|                 bounds, |                 bounds, | ||||||
|  | @ -66,28 +72,34 @@ export default class LayoutSource extends FeatureSourceMerger { | ||||||
|                 backend, |                 backend, | ||||||
|                 featureSwitches, |                 featureSwitches, | ||||||
|                 fullNodeDatabaseSource |                 fullNodeDatabaseSource | ||||||
|         )*/ |             ) | ||||||
|  |             nonMvtSources.push(overpassSource, osmApiSource) | ||||||
|  | 
 | ||||||
|  |             function setIsLoading() { | ||||||
|  |                 const loading = overpassSource?.runningQuery?.data || osmApiSource?.isRunning?.data | ||||||
|  |                 isLoading.setData(loading) | ||||||
|  |             } | ||||||
|  |             overpassSource?.runningQuery?.addCallbackAndRun((_) => setIsLoading()) | ||||||
|  |             osmApiSource?.isRunning?.addCallbackAndRun((_) => setIsLoading()) | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         const geojsonSources: FeatureSource[] = geojsonlayers.map((l) => |         const geojsonSources: FeatureSource[] = geojsonlayers.map((l) => | ||||||
|             LayoutSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) |             LayoutSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  |         super(...geojsonSources, ...fromCache, ...mvtSources, ...nonMvtSources) | ||||||
| 
 | 
 | ||||||
|         super(...geojsonSources, ...fromCache, ...mvtSources) |         this.isLoading = isLoading | ||||||
| 
 |  | ||||||
|         const self = this |  | ||||||
|         function setIsLoading() { |  | ||||||
|            // const loading = overpassSource?.runningQuery?.data || osmApiSource?.isRunning?.data
 |  | ||||||
|            // self._isLoading.setData(loading)
 |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|         // overpassSource?.runningQuery?.addCallbackAndRun((_) => setIsLoading())
 |     private static setupMvtSource( | ||||||
|        // osmApiSource?.isRunning?.addCallbackAndRun((_) => setIsLoading())
 |         layer: LayerConfig, | ||||||
|     } |         mapProperties: { zoom: Store<number>; bounds: Store<BBox> }, | ||||||
| 
 |         isActive?: Store<boolean> | ||||||
|     private static setupMvtSource(layer: LayerConfig, mapProperties:  { zoom: Store<number>; bounds: Store<BBox> },    isActive?: Store<boolean>): FeatureSource{ |     ): FeatureSource { | ||||||
|         return new DynamicMvtileSource(layer, mapProperties, { isActive }) |         return new DynamicMvtileSource(layer, mapProperties, { isActive }) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     private static setupGeojsonSource( |     private static setupGeojsonSource( | ||||||
|         layer: LayerConfig, |         layer: LayerConfig, | ||||||
|         mapProperties: { zoom: Store<number>; bounds: Store<BBox> }, |         mapProperties: { zoom: Store<number>; bounds: Store<BBox> }, | ||||||
|  |  | ||||||
							
								
								
									
										28
									
								
								src/index.ts
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								src/index.ts
									
										
									
									
									
								
							|  | @ -7,6 +7,7 @@ import Combine from "./UI/Base/Combine" | ||||||
| import { SubtleButton } from "./UI/Base/SubtleButton" | import { SubtleButton } from "./UI/Base/SubtleButton" | ||||||
| import { Utils } from "./Utils" | import { Utils } from "./Utils" | ||||||
| import Download from "./assets/svg/Download.svelte" | import Download from "./assets/svg/Download.svelte" | ||||||
|  | import Constants from "./Models/Constants" | ||||||
| 
 | 
 | ||||||
| function webgl_support() { | function webgl_support() { | ||||||
|     try { |     try { | ||||||
|  | @ -19,29 +20,32 @@ function webgl_support() { | ||||||
|         return false |         return false | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | async function availableLayers(): Promise<Set<string>> { | ||||||
|  |     const status = await Utils.downloadJson(Constants.VectorTileServer + "/status.json") | ||||||
|  |     return new Set<string>(status.layers) | ||||||
|  | } | ||||||
|  | async function main() { | ||||||
|     // @ts-ignore
 |     // @ts-ignore
 | ||||||
|     try { |     try { | ||||||
|         if (!webgl_support()) { |         if (!webgl_support()) { | ||||||
|             throw "WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this." |             throw "WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this." | ||||||
|         } |         } | ||||||
|     DetermineLayout.GetLayout() |         const [layout, availableLayers] = await Promise.all([ | ||||||
|         .then((layout) => { |             DetermineLayout.GetLayout(), | ||||||
|  |             await availableLayers(), | ||||||
|  |         ]) | ||||||
|         const state = new ThemeViewState(layout) |         const state = new ThemeViewState(layout) | ||||||
|         const main = new SvelteUIElement(ThemeViewGUI, { state }) |         const main = new SvelteUIElement(ThemeViewGUI, { state }) | ||||||
|         main.AttachTo("maindiv") |         main.AttachTo("maindiv") | ||||||
|         }) |     } catch (err) { | ||||||
|         .catch((err) => { |  | ||||||
|         console.error("Error while initializing: ", err, err.stack) |         console.error("Error while initializing: ", err, err.stack) | ||||||
|         const customDefinition = DetermineLayout.getCustomDefinition() |         const customDefinition = DetermineLayout.getCustomDefinition() | ||||||
|         new Combine([ |         new Combine([ | ||||||
|             new FixedUiElement(err).SetClass("block alert"), |             new FixedUiElement(err).SetClass("block alert"), | ||||||
| 
 | 
 | ||||||
|             customDefinition?.length > 0 |             customDefinition?.length > 0 | ||||||
|                     ? new SubtleButton( |                 ? new SubtleButton(new SvelteUIElement(Download), "Download the raw file").onClick( | ||||||
|                           new SvelteUIElement(Download), |                       () => | ||||||
|                           "Download the raw file" |  | ||||||
|                       ).onClick(() => |  | ||||||
|                           Utils.offerContentsAsDownloadableFile( |                           Utils.offerContentsAsDownloadableFile( | ||||||
|                               DetermineLayout.getCustomDefinition(), |                               DetermineLayout.getCustomDefinition(), | ||||||
|                               "mapcomplete-theme.json", |                               "mapcomplete-theme.json", | ||||||
|  | @ -50,7 +54,7 @@ try { | ||||||
|                   ) |                   ) | ||||||
|                 : undefined, |                 : undefined, | ||||||
|         ]).AttachTo("maindiv") |         ]).AttachTo("maindiv") | ||||||
|         }) |  | ||||||
| } catch (err) { |  | ||||||
|     new FixedUiElement(err).SetClass("block alert").AttachTo("maindiv") |  | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | main().then((_) => {}) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue