Skip to content

Commit fdadbcb

Browse files
authored
Merge pull request #104 from developmentseed/bug/78-render-boundary
Bug/78 render boundary
2 parents 811f298 + 7d74220 commit fdadbcb

File tree

5 files changed

+56
-47
lines changed

5 files changed

+56
-47
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Before running any commands, it is necessary to create a `config.json` file to s
4444
- `name`: The class name
4545
- `filter`: A [Mapbox GL Filter](https://www.mapbox.com/mapbox-gl-js/style-spec#other-filter) to define any vector features matching this class. Filters are applied with the standalone [featureFilter](https://github.com/mapbox/mapbox-gl-js/tree/master/src/style-spec/feature_filter) from Mapbox GL JS.
4646
- `buffer`: The number of pixels to buffer the geometry by. This is an optional parameter to buffer the label for `object-detection` and `segmentation` tasks. Accepts any number (positive or negative). It uses [Shapely `object.buffer`](https://shapely.readthedocs.io/en/latest/manual.html#object.buffer) to calculate the final geometry. You can verify that your buffer options create the desired labels by inspecting the files created in `data/labels/` after running the `labels` command.
47-
- `imagery`: One of:
47+
- `imagery`: Label Maker expects to receive imagery tiles that are 256 x 256 pixels. You can specific the source of the imagery with one of:
4848
- A template string for a tiled imagery service. Note that you will generally need an API key to obtain images and there may be associated costs. The above example requires a [Mapbox access token](https://www.mapbox.com/help/how-access-tokens-work/)
4949
- A GeoTIFF file location. Works with both local and remote files. Ex: `'http://oin-hotosm.s3.amazonaws.com/593ede5ee407d70011386139/0/3041615b-2bdb-40c5-b834-36f580baca29.tif'`
5050
- A [WMS endpoint](http://www.opengeospatial.org/standards/wms) `GetMap` request. Fill out all necessary parameters except `bbox` which should be set as `{bbox}`. Ex:

label_maker/label.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import numpy as np
1010
import mapbox_vector_tile
1111
import pyproj
12-
from shapely.geometry import shape, mapping
12+
from shapely.geometry import shape, mapping, Polygon
1313
from rasterio.features import rasterize
1414
from geojson import Feature, FeatureCollection as fc
1515
from mercantile import tiles, feature, Tile
@@ -24,6 +24,9 @@
2424
# declare a global accumulator so the workers will have access
2525
tile_results = dict()
2626

27+
# clip all geometries to a tile
28+
clip_mask = Polygon(((0, 0), (0, 255), (255, 255), (255, 0), (0, 0)))
29+
2730
def make_labels(dest_folder, zoom, country, classes, ml_type, bounding_box, sparse, **kwargs):
2831
"""Create label data from OSM QA tiles for specified classes
2932
@@ -215,6 +218,7 @@ def _mapper(x, y, z, data, args):
215218
if ff(feat):
216219
feat['geometry']['coordinates'] = _convert_coordinates(feat['geometry']['coordinates'])
217220
geo = shape(feat['geometry'])
221+
geo = geo.intersection(clip_mask)
218222
if cl.get('buffer'):
219223
geo = geo.buffer(cl.get('buffer'), 4)
220224
geos.append((mapping(geo), i + 1))
@@ -238,21 +242,27 @@ def _pixel_bbox(bb):
238242

239243
def _buffer_bbox(bb, buffer=4):
240244
"""Buffer a bounding box in pixel coordinates"""
241-
return [
242-
bb[0] - buffer,
243-
bb[1] - buffer,
244-
bb[2] + buffer,
245-
bb[3] + buffer
246-
]
245+
return list(map(
246+
_clamp,
247+
[
248+
bb[0] - buffer,
249+
bb[1] - buffer,
250+
bb[2] + buffer,
251+
bb[3] + buffer
252+
]
253+
))
254+
255+
def _clamp(coordinate):
256+
"""restrict a single coordinate to 0-255"""
257+
return max(0, min(255, coordinate))
247258

248259
def _pixel_bounds_convert(x):
249260
"""Convert a single 0-4096 coordinate to a pixel coordinate"""
250261
(i, b) = x
251262
# input bounds are in the range 0-4096 by default: https://github.com/tilezen/mapbox-vector-tile
252263
# we want them to match our fixed imagery size of 256
253264
pixel = round(b * 255. / 4096) # convert to tile pixels
254-
flipped = pixel if (i % 2 == 0) else 255 - pixel # flip the y axis
255-
return max(0, min(255, flipped)) # clamp to the correct range
265+
return pixel if (i % 2 == 0) else 255 - pixel # flip the y axis
256266

257267
def _callback(tile_label):
258268
"""Attach tile labels to a global tile_results dict"""

test/integration/test_object_labels.py

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,44 +29,44 @@ def test_cli(self):
2929
expected_bboxes = dict()
3030
expected_bboxes['62092-50162-17'] = np.empty((0, 5))
3131
expected_bboxes['62092-50163-17'] = np.array([
32-
[209, 192, 259, 259, 6], [251, 251, 259, 259, 6]
32+
[209, 192, 255, 255, 6], [253, 251, 255, 255, 6]
3333
])
3434
expected_bboxes['62092-50164-17'] = np.array([
35-
[209, -4, 250, 28, 6], [242, -4, 259, 28, 6],
36-
[222, 13, 235, 66, 6], [87, 20, 250, 259, 6]
35+
[209, 0, 250, 28, 6], [242, 0, 255, 28, 6],
36+
[222, 13, 235, 66, 6], [87, 20, 250, 255, 6]
3737
])
3838
expected_bboxes['62093-50162-17'] = np.array([
39-
[81, 145, 128, 259, 6], [124, -4, 218, 259, 6],
40-
[207, -4, 247, 153, 6], [140, 108, 193, 259, 6],
41-
[125, 236, 152, 259, 6], [162, 177, 176, 216, 6],
42-
[170, 151, 214, 179, 6], [141, 166, 244, 259, 6],
43-
[203, 88, 259, 186, 6]
39+
[81, 145, 128, 255, 6], [124, 0, 218, 255, 6],
40+
[207, 0, 247, 153, 6], [140, 108, 193, 255, 6],
41+
[125, 236, 152, 255, 6], [162, 177, 176, 216, 6],
42+
[170, 151, 214, 179, 6], [141, 166, 244, 255, 6],
43+
[203, 88, 255, 186, 6]
4444
])
4545
expected_bboxes['62093-50163-17'] = np.array([
46-
[81, -4, 125, 15, 6], [117, -4, 133, 17, 6],
47-
[119, -4, 151, 36, 6], [125, -4, 140, 7, 6],
48-
[141, -4, 187, 7, 6], [64, 32, 91, 60, 4],
46+
[81, 0, 125, 15, 6], [117, 0, 133, 17, 6],
47+
[119, 0, 151, 36, 6], [125, 0, 140, 7, 6],
48+
[141, 0, 187, 7, 6], [64, 32, 91, 60, 4],
4949
[84, 50, 106, 64, 6], [111, 9, 127, 26, 6],
5050
[111, 18, 127, 35, 6], [84, 15, 119, 52, 6],
5151
[74, 6, 129, 69, 5], [93, 24, 123, 46, 6],
52-
[88, 27, 127, 93, 6], [-4, 85, 96, 213, 6],
53-
[-2, 85, 96, 259, 6], [115, 38, 259, 100, 6]
52+
[88, 27, 127, 93, 6], [0, 85, 96, 213, 6],
53+
[0, 85, 96, 255, 6], [115, 38, 255, 100, 6]
5454
])
5555
expected_bboxes['62094-50162-17'] = np.array([
56-
[67, -4, 172, 248, 6], [-4, 172, 90, 259, 6],
57-
[91, 170, 259, 227, 6]
56+
[67, 0, 172, 248, 6], [0, 172, 90, 255, 6],
57+
[91, 170, 255, 227, 6]
5858
])
5959
expected_bboxes['62093-50164-17'] = np.array([
60-
[-4, -4, 12, 22, 6], [207, 158, 259, 195, 6]
60+
[0, 0, 12, 22, 6], [207, 158, 255, 195, 6]
6161
])
6262
expected_bboxes['62094-50163-17'] = np.array([
63-
[73, -4, 259, 78, 6], [30, 166, 60, 196, 1],
64-
[30, 166, 60, 196, 2], [203, 129, 259, 259, 6],
65-
[-4, 90, 259, 138, 6]
63+
[73, 0, 255, 78, 6], [30, 166, 60, 196, 1],
64+
[30, 166, 60, 196, 2], [203, 129, 255, 255, 6],
65+
[0, 90, 255, 138, 6]
6666
])
6767
expected_bboxes['62094-50164-17'] = np.array([
68-
[158, -4, 216, 82, 6], [-4, 108, 147, 173, 6],
69-
[139, 74, 254, 143, 6], [240, 90, 259, 232, 6]
68+
[158, 0, 216, 82, 6], [0, 108, 147, 173, 6],
69+
[139, 74, 254, 143, 6], [240, 90, 255, 232, 6]
7070
])
7171

7272
self.assertEqual(len(labels.files), len(expected_bboxes.keys())) # First check the number of tiles

test/integration/test_segmentation_labels.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ def test_cli(self):
2727
# our labels should look like this
2828
expected_sums = {
2929
'62092-50162-17': 0,
30-
'62092-50163-17': 2760,
31-
'62092-50164-17': 13728,
32-
'62093-50162-17': 38004,
33-
'62093-50164-17': 2688,
34-
'62094-50162-17': 21630,
35-
'62094-50164-17': 19440,
36-
'62094-50163-17': 21895,
37-
'62093-50163-17': 32198
30+
'62092-50163-17': 0,
31+
'62092-50164-17': 13500,
32+
'62093-50162-17': 36822,
33+
'62093-50164-17': 2400,
34+
'62094-50162-17': 21234,
35+
'62094-50164-17': 19146,
36+
'62094-50163-17': 21613,
37+
'62093-50163-17': 31568
3838
}
3939

4040
labels = np.load('integration-sg/labels.npz')

test/integration/test_segmentation_labels_sparse.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@ def test_cli(self):
2626

2727
# our labels should look like this
2828
expected_sums = {
29-
'62092-50163-17': 2760,
30-
'62092-50164-17': 13728,
31-
'62093-50162-17': 38004,
32-
'62093-50164-17': 2688,
33-
'62094-50162-17': 21630,
34-
'62094-50164-17': 19440,
35-
'62094-50163-17': 21895,
36-
'62093-50163-17': 32198
29+
'62092-50164-17': 13500,
30+
'62093-50162-17': 36822,
31+
'62093-50164-17': 2400,
32+
'62094-50162-17': 21234,
33+
'62094-50164-17': 19146,
34+
'62094-50163-17': 21613,
35+
'62093-50163-17': 31568
3736
}
3837

3938
labels = np.load('integration-sg/labels.npz')

0 commit comments

Comments
 (0)