Skip to content

Commit 911e618

Browse files
authoredOct 15, 2021
Make buffer_cfg work for meta tile build (#401)
1 parent 2aca6be commit 911e618

File tree

3 files changed

+53
-22
lines changed

3 files changed

+53
-22
lines changed
 

‎tilequeue/process.py

+12-14
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from tilequeue.tile import calc_meters_per_pixel_dim
1313
from tilequeue.tile import coord_to_mercator_bounds
1414
from tilequeue.tile import normalize_geometry_type
15-
from tilequeue.transform import mercator_point_to_lnglat
15+
from tilequeue.transform import mercator_point_to_lnglat, calc_max_padded_bounds
1616
from tilequeue.transform import transform_feature_layers_shape
1717
from tilequeue import utils
1818
from zope.dottedname.resolve import resolve
@@ -518,7 +518,7 @@ def process_coord(coord, nominal_zoom, feature_layers, post_process_data,
518518
return all_formatted_tiles, extra_data
519519

520520

521-
def convert_source_data_to_feature_layers(rows, layer_data, bounds, zoom):
521+
def convert_source_data_to_feature_layers(rows, layer_data, unpadded_bounds, zoom):
522522
# TODO we might want to fold in the other processing into this
523523
# step at some point. This will prevent us from having to iterate
524524
# through all the features again.
@@ -581,12 +581,9 @@ def convert_source_data_to_feature_layers(rows, layer_data, bounds, zoom):
581581
for layer_datum in layer_data:
582582
layer_name = layer_datum['name']
583583
features = features_by_layer[layer_name]
584-
# TODO padded bounds
585-
padded_bounds = dict(
586-
polygon=bounds,
587-
line=bounds,
588-
point=bounds,
589-
)
584+
query_bounds_pad_fn = layer_datum['query_bounds_pad_fn']
585+
586+
padded_bounds = query_bounds_pad_fn(unpadded_bounds, calc_meters_per_pixel_dim(zoom))
590587
feature_layer = dict(
591588
name=layer_name,
592589
features=features,
@@ -748,24 +745,25 @@ def __init__(self, coord, metatile_zoom, fetch_fn, layer_data,
748745
self.cfg_tile_sizes = cfg_tile_sizes
749746
self.log_fn = None
750747

751-
def fetch(self):
752-
unpadded_bounds = coord_to_mercator_bounds(self.coord)
748+
self.unpadded_bounds = coord_to_mercator_bounds(self.coord)
749+
meters_per_pixel_dim = calc_meters_per_pixel_dim(self.coord.zoom)
750+
self.max_padded_bounds = calc_max_padded_bounds(self.unpadded_bounds, meters_per_pixel_dim, self.buffer_cfg)
753751

752+
def fetch(self):
754753
cut_coords_by_zoom = calculate_cut_coords_by_zoom(
755754
self.coord, self.metatile_zoom, self.cfg_tile_sizes, self.max_zoom)
756755
feature_layers_by_zoom = {}
757756

758757
for nominal_zoom, _ in cut_coords_by_zoom.items():
759-
source_rows = self.fetch_fn(nominal_zoom, unpadded_bounds)
758+
source_rows = self.fetch_fn(nominal_zoom, self.max_padded_bounds)
760759
feature_layers = convert_source_data_to_feature_layers(
761-
source_rows, self.layer_data, unpadded_bounds, self.coord.zoom)
760+
source_rows, self.layer_data, self.unpadded_bounds, self.coord.zoom)
762761
feature_layers_by_zoom[nominal_zoom] = feature_layers
763762

764763
self.cut_coords_by_zoom = cut_coords_by_zoom
765764
self.feature_layers_by_zoom = feature_layers_by_zoom
766765

767766
def process_tiles(self):
768-
unpadded_bounds = coord_to_mercator_bounds(self.coord)
769767

770768
all_formatted_tiles = []
771769
all_extra_data = {}
@@ -782,7 +780,7 @@ def log_fn(data):
782780
feature_layers = self.feature_layers_by_zoom[nominal_zoom]
783781
formatted_tiles, extra_data = process_coord(
784782
self.coord, nominal_zoom, feature_layers,
785-
self.post_process_data, self.formats, unpadded_bounds,
783+
self.post_process_data, self.formats, self.unpadded_bounds,
786784
cut_coords, self.buffer_cfg, self.output_calc_mapping,
787785
log_fn=log_fn,
788786
)

‎tilequeue/query/rawr.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,11 @@ def _add_feature(source, feature):
724724

725725
return source_features.iteritems()
726726

727-
def __call__(self, zoom, unpadded_bounds):
727+
def __call__(self, zoom, bounds):
728+
""" The bounds is either an unpadded bounds if buffer_cfg is not set
729+
or a padded bounds if buffer_cfg is set upstream """
728730
read_rows = []
729-
bbox = box(*unpadded_bounds)
731+
bbox = box(*bounds)
730732

731733
# check that the call is fetching data which is actually within the
732734
# bounds of the tile pyramid. we don't have data outside of that, so
@@ -735,25 +737,27 @@ def __call__(self, zoom, unpadded_bounds):
735737
# loaded?
736738
assert zoom <= self.tile_pyramid.max_z
737739
assert zoom >= self.tile_pyramid.z
738-
assert bbox.within(self.tile_pyramid.bbox())
740+
# assert bbox.within(self.tile_pyramid.bbox())
739741

740-
for source, features in self._lookup(zoom, unpadded_bounds):
742+
for source, features in self._lookup(zoom, bounds):
741743
for (fid, shape, props, layer_min_zooms) in features:
742744
read_row = self._parse_row(
743-
zoom, unpadded_bounds, bbox, source, fid, shape, props,
745+
zoom, bounds, bbox, source, fid, shape, props,
744746
layer_min_zooms)
745747
if read_row:
746748
read_rows.append(read_row)
747749

748750
return read_rows
749751

750-
def _parse_row(self, zoom, unpadded_bounds, bbox, source, fid, shape,
752+
def _parse_row(self, zoom, bounds, bbox, source, fid, shape,
751753
props, layer_min_zooms):
754+
""" The bounds is either an unpadded bounds if buffer_cfg is not set
755+
or a padded bounds if buffer_cfg is set upstream"""
752756
# reject any feature which doesn't intersect the given bounds
753757
if bbox.disjoint(shape):
754758
return None
755759

756-
# place for assembing the read row as if from postgres
760+
# place for assembling the read row as if from postgres
757761
read_row = {}
758762
generate_label_placement = False
759763

@@ -826,11 +830,15 @@ def _parse_row(self, zoom, unpadded_bounds, bbox, source, fid, shape,
826830

827831
# if this is a water layer feature, then clip to an expanded
828832
# bounding box to avoid tile-edge artefacts.
833+
# Note: As of Oct 2021 we added support for buffer_cfg to
834+
# tilequeue such that this extra buffer for water can actually be
835+
# configured as a water layer buffer_cfg. But we leave as is for
836+
# now.
829837
clip_box = bbox
830838
if layer_name == 'water':
831839
pad_factor = 1.1
832840
clip_box = calculate_padded_bounds(
833-
pad_factor, unpadded_bounds)
841+
pad_factor, bounds)
834842
# don't need to clip if geom is fully within the clipping box
835843
if box(*shape.bounds).within(clip_box):
836844
clip_shape = shape

‎tilequeue/transform.py

+25
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,31 @@ def calc_buffered_bounds(
9797
return bounds
9898

9999

100+
def calc_max_padded_bounds(bounds, meters_per_pixel_dim, buffer_cfg):
101+
"""
102+
:return: The bounds expanded by the maximum value in buffer_cfg, default = 0
103+
"""
104+
max_buffer = 0
105+
106+
if buffer_cfg is None:
107+
return bounds
108+
109+
for _, format_cfg in buffer_cfg.items():
110+
layer_cfg = format_cfg.get('layer', {})
111+
if layer_cfg is not None:
112+
for _, value in layer_cfg.items():
113+
assert isinstance(value, Number)
114+
max_buffer = max(max_buffer, value)
115+
116+
geometry_cfg = format_cfg.get('geometry', {})
117+
if geometry_cfg is not None:
118+
for _, value in geometry_cfg.items():
119+
assert isinstance(value, Number)
120+
max_buffer = max(max_buffer, value)
121+
122+
return bounds_buffer(bounds, meters_per_pixel_dim * max_buffer)
123+
124+
100125
def _intersect_multipolygon(shape, tile_bounds, clip_bounds):
101126
"""
102127
Return the parts of the MultiPolygon shape which overlap the tile_bounds,

0 commit comments

Comments
 (0)
Please sign in to comment.