proof of concept for borough names with Mapnik-based tiles
This commit is contained in:
parent
838a0dd087
commit
c4933fdc11
@ -24,6 +24,11 @@
|
||||
<MinScaleDenominator>0</MinScaleDenominator>
|
||||
</Rule>
|
||||
</Style>
|
||||
<Style name="base_boroughs">
|
||||
<Rule>
|
||||
<TextSymbolizer size="24" fill="#f99" face-name="DejaVu Sans Bold Oblique" halo-radius="1" wrap-width="20">[name]</TextSymbolizer>
|
||||
</Rule>
|
||||
</Style>
|
||||
<Style name="number_labels">
|
||||
<Rule>
|
||||
<TextSymbolizer
|
||||
|
@ -8,12 +8,13 @@ export const initialMapViewport: MapViewport = {
|
||||
zoom: 16,
|
||||
};
|
||||
|
||||
export type MapTheme = 'light' | 'night' | 'night_outlines';
|
||||
export type MapTheme = 'light' | 'night' | 'night_outlines' | 'boroughs';
|
||||
|
||||
export type LayerEnablementState = 'enabled' | 'disabled';
|
||||
|
||||
export const mapBackgroundColor: Record<MapTheme, string> = {
|
||||
light: '#F0EEEB',
|
||||
night: '#162639',
|
||||
night_outlines: '#162639'
|
||||
night_outlines: '#162639',
|
||||
boroughs: '#ff0000',
|
||||
};
|
||||
|
@ -21,6 +21,6 @@ export type BuildingMapTileset = 'date_year' |
|
||||
'dynamics_demolished_count' |
|
||||
'team';
|
||||
|
||||
export type SpecialMapTileset = 'base_light' | 'base_night' | 'base_night_outlines' | 'highlight' | 'number_labels';
|
||||
export type SpecialMapTileset = 'base_light' | 'base_night' | 'base_night_outlines' | 'highlight' | 'number_labels' | 'base_boroughs';
|
||||
|
||||
export type MapTileset = BuildingMapTileset | SpecialMapTileset;
|
||||
|
@ -3,6 +3,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { GeoJSON } from 'react-leaflet';
|
||||
import { useDisplayPreferences } from '../../displayPreferences-context';
|
||||
import { apiGet } from '../../apiHelpers';
|
||||
import { BuildingBaseLayerAllZoom } from './building-base-layer-all-zoom';
|
||||
|
||||
export function BoroughBoundaryLayer({}) {
|
||||
const [boundaryGeojson, setBoundaryGeojson] = useState<GeoJsonObject>(null);
|
||||
@ -15,12 +16,12 @@ export function BoroughBoundaryLayer({}) {
|
||||
|
||||
if(borough == "enabled") {
|
||||
return boundaryGeojson &&
|
||||
<GeoJSON
|
||||
<><GeoJSON
|
||||
attribution='Borough boundary from <a href=https://data.london.gov.uk/dataset/london_boroughs>London Datastore</a> Ordnance Survey Open Data - Contains public sector information licensed under the <a href=https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/>Open Government Licence v3.0</a>'
|
||||
data={boundaryGeojson}
|
||||
style={{color: '#f00', fill: false, weight: 1}}
|
||||
/* minNativeZoom={17}*/
|
||||
/>;
|
||||
/><BuildingBaseLayerAllZoom theme="boroughs" /></>;
|
||||
} else if (borough == "disabled") {
|
||||
return <div></div>
|
||||
// do not display anything
|
||||
|
19
app/src/frontend/map/layers/building-base-layer-all-zoom.tsx
Normal file
19
app/src/frontend/map/layers/building-base-layer-all-zoom.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import * as React from 'react';
|
||||
import { TileLayer } from 'react-leaflet';
|
||||
|
||||
import { MapTheme } from '../../config/map-config';
|
||||
import { MapTileset } from '../../config/tileserver-config';
|
||||
|
||||
import {getTileLayerUrl } from './get-tile-layer-url';
|
||||
|
||||
export function BuildingBaseLayerAllZoom({ theme }: {theme: MapTheme}) {
|
||||
const tileset = `base_${theme}` as const;
|
||||
|
||||
return <TileLayer
|
||||
key={theme} /* needed because TileLayer url is not mutable in react-leaflet v3 */
|
||||
url={getTileLayerUrl(tileset)}
|
||||
minZoom={1}
|
||||
maxZoom={109}
|
||||
detectRetina={true}
|
||||
/>;
|
||||
}
|
@ -18,6 +18,12 @@ const LAYER_QUERIES = {
|
||||
geometry_id
|
||||
FROM
|
||||
buildings`,
|
||||
base_boroughs: `
|
||||
SELECT
|
||||
geometry_id,
|
||||
name
|
||||
FROM
|
||||
external_data_borough_boundary`,
|
||||
number_labels:`
|
||||
SELECT
|
||||
geometry_id,
|
||||
@ -245,6 +251,29 @@ function getDataConfig(tileset: string): DataConfig {
|
||||
throw new Error('Invalid tileset requested');
|
||||
}
|
||||
|
||||
if(tileset == 'base_boroughs') {
|
||||
const query = `(
|
||||
SELECT
|
||||
d.*,
|
||||
g.geometry_geom
|
||||
FROM (
|
||||
${table}
|
||||
) AS d
|
||||
JOIN
|
||||
geometries AS g
|
||||
ON d.geometry_id = g.geometry_id
|
||||
JOIN
|
||||
external_data_borough_boundary AS b
|
||||
ON d.geometry_id = b.geometry_id
|
||||
) AS data
|
||||
`;
|
||||
|
||||
return {
|
||||
geometry_field: GEOMETRY_FIELD,
|
||||
table: query
|
||||
};
|
||||
}
|
||||
|
||||
const query = `(
|
||||
SELECT
|
||||
d.*,
|
||||
|
1
migrations/036.borough_borders_and_labels.down.sql
Normal file
1
migrations/036.borough_borders_and_labels.down.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS external_data_borough_boundary;
|
8
migrations/036.borough_borders_and_labels.up.sql
Normal file
8
migrations/036.borough_borders_and_labels.up.sql
Normal file
@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS external_data_borough_boundary (
|
||||
-- internal unique id
|
||||
planning_entry_id serial PRIMARY KEY,
|
||||
|
||||
-- geometry as EPSG:3857 avoiding reprojection for tiles
|
||||
geometry_id integer REFERENCES geometries,
|
||||
name VARCHAR(50)
|
||||
);
|
Loading…
Reference in New Issue
Block a user