Refactor data maps and add building outlines (#630)

* Add subtle border for age layer buildings

* Simplify map data queries

* Fix typo in updated construction layer query

* Enable data tile caching switch for development

* Enable turning tile cache off

* Use render time variables for highlight tiles

* Create building numbers map layer

* Create database view for simpler map queries

* Decrease min zoom for numbers layer

* Add building outlines to all map layers

* Adjust building numbers style and zoom level

* Revert "Create database view for simpler map queries"

This reverts commit e3c342cb7393f491c838df5654c2316a9dab08e1
which cannot be implemented before upgrading Postgres to min v11
This commit is contained in:
Maciej Ziarkowski 2021-01-29 02:40:11 +00:00 committed by GitHub
parent 2927b04b54
commit 1ff3b38c4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 304 additions and 168 deletions

View File

@ -8,13 +8,6 @@
<MaxScaleDenominator>17000</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
</Rule>
<Rule>
<TextSymbolizer face-name="DejaVu Sans Condensed Bold" fill="#000000">
[location_number]
</TextSymbolizer>
<MaxScaleDenominator>5000</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
</Rule>
</Style>
<Style name="base_night">
<Rule>
@ -25,17 +18,25 @@
<MaxScaleDenominator>17000</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
</Rule>
</Style>
<Style name="number_labels">
<Rule>
<TextSymbolizer face-name="DejaVu Sans Condensed Bold" fill="#ffffff">
<TextSymbolizer
face-name="DejaVu Sans Condensed Bold"
fill="#eee"
size="21"
halo-radius="1"
halo-fill="#333"
>
[location_number]
</TextSymbolizer>
<MaxScaleDenominator>5000</MaxScaleDenominator>
<MaxScaleDenominator>2132</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
</Rule>
</Style>
<Style name="highlight">
<Rule>
<Filter>[base_layer] = 'location' or [base_layer] = 'conservation_area'</Filter>
<Filter>@base_data_layer = 'location' or @base_data_layer = 'conservation_area'</Filter>
<LineSymbolizer stroke="#ff0000aa" stroke-width="4.5" />
<LineSymbolizer stroke="#ff0000ff" stroke-width="2.5" />
</Rule>
@ -66,6 +67,17 @@
<Filter>[location_info_count] &gt; 0 and [location_info_count] &lt; 2</Filter>
<PolygonSymbolizer fill="#bae4bc" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="size_storeys">
<Rule>
@ -88,6 +100,17 @@
<Filter>[size_storeys] &gt;= 1 and [size_storeys] &lt; 6</Filter>
<PolygonSymbolizer fill="#800026" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#ccc" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#ccc" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="size_height">
<Rule>
@ -122,6 +145,17 @@
<Filter>[size_height] &gt;= 152</Filter>
<PolygonSymbolizer fill="#980043" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#ccc" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#ccc" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="construction_core_material">
<Rule>
@ -156,6 +190,17 @@
<Filter>[construction_core_material] = "Other Man-Made Material"</Filter>
<PolygonSymbolizer fill="#c48a85" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="date_year">
<Rule>
@ -218,6 +263,17 @@
<Filter>[date_year] &lt; 1700</Filter>
<PolygonSymbolizer fill="#d0c291" />
</Rule>
<Rule>
<MaxScaleDenominator>8530</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="conservation_area">
<Rule>
@ -246,6 +302,19 @@
<PolygonSymbolizer fill="#858ed4"/>
</Rule>
<Rule>
<Filter>[listing_type] != "None" or [planning_in_conservation_area] = true</Filter>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<Filter>[listing_type] != "None" or [planning_in_conservation_area] = true</Filter>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
<!-- Conservation area outline -->
<Rule>
<Filter>[listing_type] != "None" and [planning_in_conservation_area] = true</Filter>
@ -295,6 +364,17 @@
<Filter>[sust_dec] = G</Filter>
<PolygonSymbolizer fill="#e31d23" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="building_attachment_form">
<Rule>
@ -313,6 +393,17 @@
<Filter>[building_attachment_form] = "Mid-Terrace"</Filter>
<PolygonSymbolizer fill="#226291" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="2.0"/>
</Rule>
</Style>
<Style name="likes">
<Rule>
@ -343,6 +434,17 @@
<Filter>[likes] = 1</Filter>
<PolygonSymbolizer fill="#ffe8a9" />
</Rule>
<Rule>
<MaxScaleDenominator>17061</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="1.0"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
<Style name="landuse">
<Rule>
@ -393,5 +495,16 @@
<Filter>[current_landuse_order] = "Mixed Use"</Filter>
<PolygonSymbolizer fill="#e5050d" />
</Rule>
<Rule>
<MaxScaleDenominator>8530</MaxScaleDenominator>
<MinScaleDenominator>4264</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="0.8"/>
</Rule>
<Rule>
<MaxScaleDenominator>4264</MaxScaleDenominator>
<MinScaleDenominator>0</MinScaleDenominator>
<LineSymbolizer stroke="#888" stroke-width="3.0"/>
</Rule>
</Style>
</Map>

View File

@ -155,13 +155,21 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
const highlightLayer = this.props.building != undefined ?
<TileLayer
key={this.props.building.building_id}
url={`/tiles/highlight/{z}/{x}/{y}{r}.png?highlight=${this.props.building.geometry_id}&base=${tileset}`}
url={`/tiles/highlight/{z}/{x}/{y}{r}.png?highlight=${this.props.building.building_id}&base=${tileset}`}
minZoom={13}
maxZoom={19}
zIndex={100}
/>
: null;
const numbersLayer = <TileLayer
key={this.state.theme}
url={`/tiles/number_labels/{z}/{x}/{y}{r}.png?rev=${rev}`}
zIndex={200}
minZoom={17}
maxZoom={19}
/>
const isEdit = ['edit', 'multi-edit'].includes(this.props.mode);
return (
@ -182,6 +190,7 @@ class ColouringMap extends Component<ColouringMapProps, ColouringMapState> {
{ boundaryLayer }
{ dataLayer }
{ highlightLayer }
{ numbersLayer }
<ZoomControl position="topright" />
<AttributionControl prefix=""/>
</Map>

View File

@ -59,6 +59,11 @@ export function decBigInt(bigStr: string): string {
return bigStr == undefined ? bigStr : String(BigInt(bigStr) - BigInt(1));
}
export function parseBooleanExact(val: string) {
if(val === 'true') return true;
if(val === 'false') return false;
return null;
}
export function pickFields(obj: any, fieldWhitelist: Set<string>) {
const subObject = {};
@ -68,4 +73,4 @@ export function pickFields(obj: any, fieldWhitelist: Set<string>) {
}
}
return subObject;
}
}

View File

@ -2,211 +2,198 @@ import { strictParseInt } from "../parse";
import { DataConfig } from "./types";
const BUILDING_LAYER_DEFINITIONS = {
base_light: `(
const LAYER_QUERIES = {
base_light: `
SELECT
b.location_number as location_number,
g.geometry_geom
geometry_id
FROM
geometries as g,
buildings as b
WHERE
g.geometry_id = b.geometry_id
) as outline`,
base_night: `(
buildings`,
base_night: `
SELECT
b.location_number as location_number,
g.geometry_geom
geometry_id
FROM
geometries as g,
buildings as b
WHERE
g.geometry_id = b.geometry_id
) as outline`,
date_year: `(
buildings`,
number_labels:`
SELECT
b.date_year as date_year,
g.geometry_geom
geometry_id,
location_number
FROM
geometries as g,
buildings as b
WHERE
g.geometry_id = b.geometry_id
) as date_year`,
size_storeys: `(
buildings`,
highlight: `
SELECT
geometry_id
FROM
buildings
WHERE building_id = !@highlight!`,
date_year: `
SELECT
geometry_id,
date_year
FROM
buildings
WHERE date_year IS NOT NULL`,
size_storeys: `
SELECT
geometry_id,
(
coalesce(b.size_storeys_attic, 0) +
coalesce(b.size_storeys_core, 0)
) as size_storeys,
g.geometry_geom
coalesce(size_storeys_attic, 0) +
coalesce(size_storeys_core, 0)
) AS size_storeys
FROM
geometries as g,
buildings as b
buildings
WHERE
g.geometry_id = b.geometry_id
) as size_stories`,
size_height: `(
size_storeys_attic IS NOT NULL OR size_storeys_core IS NOT NULL`,
size_height: `
SELECT
b.size_height_apex as size_height,
g.geometry_geom
geometry_id,
size_height_apex AS size_height
FROM
geometries as g,
buildings as b
WHERE g.geometry_id = b.geometry_id
) as size_height`,
construction_core_material: `(
buildings
WHERE
size_height_apex IS NOT NULL`,
construction_core_material: `
SELECT
b.construction_core_material::text as construction_core_material,
g.geometry_geom
geometry_id,
construction_core_material::text AS construction_core_material
FROM
geometries as g,
buildings as b
WHERE g.geometry_id = b.geometry_id
) as construction_core_material`,
location: `(
buildings
WHERE
construction_core_material IS NOT NULL`,
location: `
SELECT
geometry_id,
(
case when b.location_name is null then 0 else 1 end +
case when b.location_number is null then 0 else 1 end +
case when b.location_street is null then 0 else 1 end +
case when b.location_line_two is null then 0 else 1 end +
case when b.location_town is null then 0 else 1 end +
case when b.location_postcode is null then 0 else 1 end +
case when b.location_latitude is null then 0 else 1 end +
case when b.location_longitude is null then 0 else 1 end +
case when b.ref_toid is null then 0 else 1 end +
case when b.ref_osm_id is null then 0 else 1 end
) as location_info_count,
g.geometry_geom
case when location_name IS NULL then 0 else 1 end +
case when location_number IS NULL then 0 else 1 end +
case when location_street IS NULL then 0 else 1 end +
case when location_line_two IS NULL then 0 else 1 end +
case when location_town IS NULL then 0 else 1 end +
case when location_postcode IS NULL then 0 else 1 end +
case when location_latitude IS NULL then 0 else 1 end +
case when location_longitude IS NULL then 0 else 1 end +
case when ref_toid IS NULL then 0 else 1 end +
case when ref_osm_id IS NULL then 0 else 1 end
) AS location_info_count
FROM
geometries as g,
buildings as b
WHERE
g.geometry_id = b.geometry_id
) as location`,
likes: `(
buildings`,
likes: `
SELECT
g.geometry_geom,
b.likes_total as likes
geometry_id,
likes_total AS likes
FROM
geometries as g,
buildings as b
buildings
WHERE
g.geometry_id = b.geometry_id
AND b.likes_total > 0
) as likes`,
planning_combined: `(
likes_total > 0`,
planning_combined: `
SELECT
g.geometry_geom,
geometry_id,
(
CASE
WHEN b.planning_list_cat = 'Listed Building' and b.planning_list_grade = 'I' THEN 'Grade I Listed'
WHEN b.planning_list_cat = 'Listed Building' and b.planning_list_grade = 'II*' THEN 'Grade II* Listed'
WHEN b.planning_list_cat = 'Listed Building' and b.planning_list_grade = 'II' THEN 'Grade II Listed'
WHEN b.planning_in_local_list THEN 'Locally Listed'
WHEN planning_list_cat = 'Listed Building' and planning_list_grade = 'I' THEN 'Grade I Listed'
WHEN planning_list_cat = 'Listed Building' and planning_list_grade = 'II*' THEN 'Grade II* Listed'
WHEN planning_list_cat = 'Listed Building' and planning_list_grade = 'II' THEN 'Grade II Listed'
WHEN planning_in_local_list THEN 'Locally Listed'
ELSE 'None'
END
) as listing_type,
b.planning_in_conservation_area
FROM geometries as g
JOIN buildings as b
ON g.geometry_id = b.geometry_id
) AS listing_type,
planning_in_conservation_area
FROM buildings
WHERE
b.planning_in_conservation_area
OR b.planning_in_local_list
OR b.planning_list_cat is not null
) as planning_combined`,
conservation_area: `(
planning_in_conservation_area
OR planning_in_local_list
OR planning_list_cat IS NOT NULL`,
conservation_area: `
SELECT
g.geometry_geom
geometry_id
FROM
geometries as g,
buildings as b
buildings
WHERE
g.geometry_id = b.geometry_id
AND b.planning_in_conservation_area = true
) as conservation_area`,
sust_dec: `(
planning_in_conservation_area = true`,
sust_dec: `
SELECT
b.sust_dec::text as sust_dec,
g.geometry_geom
geometry_id,
sust_dec::text AS sust_dec
FROM
geometries as g,
buildings as b
buildings
WHERE
g.geometry_id = b.geometry_id
) as sust_dec`,
building_attachment_form: `(
sust_dec IS NOT NULL`,
building_attachment_form: `
SELECT
b.building_attachment_form::text as building_attachment_form,
g.geometry_geom
geometry_id,
building_attachment_form::text AS building_attachment_form
FROM
geometries as g,
buildings as b
buildings
WHERE
g.geometry_id = b.geometry_id
) as building_attachment_form`,
landuse: `(
building_attachment_form IS NOT NULL`,
landuse: `
SELECT
b.current_landuse_order,
g.geometry_geom
FROM geometries as g
JOIN buildings as b
ON g.geometry_id = b.geometry_id
) as current_landuse_order`,
geometry_id,
current_landuse_order
FROM
buildings
WHERE
current_landuse_order IS NOT NULL`,
};
const GEOMETRY_FIELD = 'geometry_geom';
function getBuildingLayerNames() {
return Object.keys(BUILDING_LAYER_DEFINITIONS);
return Object.keys(LAYER_QUERIES);
}
function getAllLayerNames() {
return ['highlight', ...getBuildingLayerNames()];
}
function getBuildingsDataConfig(tileset: string, dataParams: any): DataConfig {
const table = BUILDING_LAYER_DEFINITIONS[tileset];
function getDataConfig(tileset: string): DataConfig {
const table = LAYER_QUERIES[tileset];
if(table == undefined) {
throw new Error('Invalid tileset requested');
}
const query = `(
SELECT
d.*,
g.geometry_geom
FROM (
${table}
) AS d
JOIN
geometries AS g
ON d.geometry_id = g.geometry_id
) AS data
`;
return {
geometry_field: GEOMETRY_FIELD,
table: table
table: query
};
}
function getHighlightDataConfig(tileset: string, dataParams: any): DataConfig {
let { highlight, base } = dataParams;
function getLayerVariables(tileset: string, dataParams: any): object {
if(tileset == 'highlight') {
let { highlight, base } = dataParams;
highlight = strictParseInt(highlight);
base = base || 'default';
highlight = strictParseInt(highlight);
base = base || 'default';
if(isNaN(highlight) || base.match(/^\w+$/) == undefined) {
throw new Error('Bad parameters for highlight layer');
if(isNaN(highlight) || base.match(/^\w+$/) == undefined) {
throw new Error('Bad parameters for highlight layer');
}
return {
highlight,
base_data_layer: base
};
}
return {
geometry_field: GEOMETRY_FIELD,
table: `(
SELECT
g.geometry_geom,
'${base}' as base_layer
FROM
geometries as g
WHERE
g.geometry_id = ${highlight}
) as highlight`
};
return {};
}
export {
getBuildingLayerNames,
getAllLayerNames,
getBuildingsDataConfig,
getHighlightDataConfig
getDataConfig,
getLayerVariables
};

View File

@ -1,4 +1,5 @@
import { getAllLayerNames, getBuildingLayerNames, getBuildingsDataConfig, getHighlightDataConfig } from "./dataDefinition";
import { parseBooleanExact } from '../helpers';
import { getAllLayerNames, getBuildingLayerNames, getDataConfig, getLayerVariables } from "./dataDefinition";
import { createBlankTile } from "./renderers/createBlankTile";
import { getTileWithCaching } from "./renderers/getTileWithCaching";
import { renderDataSourceTile } from "./renderers/renderDataSourceTile";
@ -24,6 +25,23 @@ const STITCH_THRESHOLD = 12;
*/
const EXTENT_BBOX: BoundingBox = [-61149.622628, 6667754.851372, 28128.826409, 6744803.375884];
const allLayersCacheSwitch = parseBooleanExact(process.env.CACHE_TILES) ?? true;
const dataLayersCacheSwitch = parseBooleanExact(process.env.CACHE_DATA_TILES) ?? true;
let shouldCacheFn: (t: TileParams) => boolean;
if(!allLayersCacheSwitch) {
shouldCacheFn = t => false;
} else if(!dataLayersCacheSwitch) {
// cache age data and base building outlines for more zoom levels than other layers
shouldCacheFn = ({ tileset, z }: TileParams) =>
(tileset === 'date_year' && z <= 16) ||
(['base_light', 'base_night'].includes(tileset) && z <= 17) ||
z <= 13;
} else {
shouldCacheFn = ({ tileset, z }: TileParams) =>
['base_light', 'base_night'].includes(tileset) && z <= 17;
}
const tileCache = new TileCache(
process.env.TILECACHE_PATH,
{
@ -32,18 +50,13 @@ const tileCache = new TileCache(
maxZoom: 19,
scales: [1, 2]
},
// cache age data and base building outlines for more zoom levels than other layers
({ tileset, z }: TileParams) => (tileset === 'date_year' && z <= 16) ||
((tileset === 'base_light' || tileset === 'base_night') && z <= 17) ||
z <= 13,
shouldCacheFn,
// don't clear base_light and base_night on bounding box cache clear
(tileset: string) => tileset !== 'base_light' && tileset !== 'base_night'
);
const renderBuildingTile = (t: TileParams, d: any) => renderDataSourceTile(t, d, getBuildingsDataConfig);
const renderHighlightTile = (t: TileParams, d: any) => renderDataSourceTile(t, d, getHighlightDataConfig);
const renderBuildingTile = (t: TileParams, d: any) => renderDataSourceTile(t, d, getDataConfig, getLayerVariables);
function cacheOrCreateBuildingTile(tileParams: TileParams, dataParams: any): Promise<Tile> {
return getTileWithCaching(tileParams, dataParams, tileCache, stitchOrRenderBuildingTile);
@ -64,7 +77,7 @@ function renderTile(tileParams: TileParams, dataParams: any): Promise<Tile> {
}
if (tileParams.tileset === 'highlight') {
return renderHighlightTile(tileParams, dataParams);
return renderBuildingTile(tileParams, dataParams);
}
return cacheOrCreateBuildingTile(tileParams, dataParams);

View File

@ -2,7 +2,7 @@ import mapnik from "mapnik";
import path from 'path';
import { promisify } from "util";
import { TableDefinitionFunction, Tile, TileParams } from "../types";
import { TableDefinitionFunction, VariablesFunction, Tile, TileParams } from "../types";
import { getBbox, TILE_SIZE } from "../util";
@ -29,7 +29,12 @@ if (mapnik.register_default_input_plugins) {
mapnik.register_default_fonts();
async function renderDataSourceTile({ tileset, z, x, y, scale }: TileParams, dataParams: any, getTableDefinitionFn: TableDefinitionFunction): Promise<Tile> {
async function renderDataSourceTile(
{ tileset, z, x, y, scale }: TileParams,
dataParams: any,
getTableDefinitionFn: TableDefinitionFunction,
getVariablesFn: VariablesFunction
): Promise<Tile> {
const bbox = getBbox(z, x, y);
const tileSize = TILE_SIZE * scale;
@ -37,9 +42,11 @@ async function renderDataSourceTile({ tileset, z, x, y, scale }: TileParams, dat
map.bufferSize = TILE_BUFFER_SIZE;
const layer = new mapnik.Layer('tile', PROJ4_STRING);
const dataSourceConfig = getTableDefinitionFn(tileset, dataParams);
const dataSourceConfig = getTableDefinitionFn(tileset);
const dataSourceVariables = getVariablesFn(tileset, dataParams);
const conf = Object.assign(dataSourceConfig, DATASOURCE_CONFIG);
const vars = Object.assign(dataSourceVariables, { zoom: z});
const postgis = new mapnik.Datasource(conf);
layer.datasource = postgis;
@ -52,7 +59,7 @@ async function renderDataSourceTile({ tileset, z, x, y, scale }: TileParams, dat
map.add_layer(layer);
const im = new mapnik.Image(map.width, map.height);
map.extent = bbox;
const rendered = await promisify(map.render.bind(map))(im, {});
const rendered = await promisify(map.render.bind(map))(im, { variables: vars});
return await promisify(rendered.encode.bind(rendered))('png');
}

View File

@ -38,7 +38,8 @@ interface DataConfig {
geometry_field: string;
}
type TableDefinitionFunction = (tileset: string, dataParams: any) => DataConfig;
type TableDefinitionFunction = (tileset: string) => DataConfig;
type VariablesFunction = (tileset: string, dataParams: any) => object;
type Tile = Image | Sharp;
type RendererFunction = (tileParams: TileParams, dataParams: any) => Promise<Tile>;
@ -54,5 +55,6 @@ export {
Tile,
RendererFunction,
DataConfig,
TableDefinitionFunction
TableDefinitionFunction,
VariablesFunction
};