Skip to content

changes to generalize get_bounds #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions label_maker/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import argparse
import logging
import json
import numpy as np
from os import makedirs, path as op

from cerberus import Validator
from shapely.geometry import MultiPolygon, Polygon
from shapely.geometry import shape
from shapely.ops import unary_union

from label_maker.version import __version__
from label_maker.download import download_mbtiles
Expand All @@ -20,9 +23,9 @@
logger = logging.getLogger(__name__)

def get_bounds(feature_collection):
"""Get a bounding box for a FeatureCollection of Polygon Features"""
features = [f for f in feature_collection['features'] if f['geometry']['type'] in ['Polygon']]
return MultiPolygon(list(map(lambda x: Polygon(x['geometry']['coordinates'][0]), features))).bounds
"""Get a bounding box for a FeatureCollection"""
shape_lst = [shape(f['geometry']) for f in feature_collection['features']]
return unary_union(shape_lst).bounds


def parse_args(args):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"type": "FeatureCollection", "features": [{"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82424926757812, 19.055627823152516], [72.82424926757812, 19.05692585554252], [72.82562255859375, 19.05692585554252], [72.82562255859375, 19.055627823152516], [72.82424926757812, 19.055627823152516]]]}, "properties": {"label": [0, 1, 0, 0, 0, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82424926757812, 19.05692585554252], [72.82424926757812, 19.05822387777432], [72.82562255859375, 19.05822387777432], [72.82562255859375, 19.05692585554252], [72.82424926757812, 19.05692585554252]]]}, "properties": {"label": [0, 1, 0, 0, 0, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82424926757812, 19.053031727900255], [72.82424926757812, 19.0543297806049], [72.82562255859375, 19.0543297806049], [72.82562255859375, 19.053031727900255], [72.82424926757812, 19.053031727900255]]]}, "properties": {"label": [0, 1, 0, 0, 0, 1, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82699584960938, 19.055627823152516], [72.82699584960938, 19.05692585554252], [72.828369140625, 19.05692585554252], [72.828369140625, 19.055627823152516], [72.82699584960938, 19.055627823152516]]]}, "properties": {"label": [0, 0, 0, 0, 0, 1, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82699584960938, 19.0543297806049], [72.82699584960938, 19.055627823152516], [72.828369140625, 19.055627823152516], [72.828369140625, 19.0543297806049], [72.82699584960938, 19.0543297806049]]]}, "properties": {"label": [0, 0, 0, 0, 1, 1, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82562255859375, 19.055627823152516], [72.82562255859375, 19.05692585554252], [72.82699584960938, 19.05692585554252], [72.82699584960938, 19.055627823152516], [72.82562255859375, 19.055627823152516]]]}, "properties": {"label": [0, 1, 0, 0, 0, 1, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82562255859375, 19.05692585554252], [72.82562255859375, 19.05822387777432], [72.82699584960938, 19.05822387777432], [72.82699584960938, 19.05692585554252], [72.82562255859375, 19.05692585554252]]]}, "properties": {"label": [0, 1, 0, 0, 0, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82424926757812, 19.0543297806049], [72.82424926757812, 19.055627823152516], [72.82562255859375, 19.055627823152516], [72.82562255859375, 19.0543297806049], [72.82424926757812, 19.0543297806049]]]}, "properties": {"label": [0, 1, 0, 0, 1, 1, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82562255859375, 19.053031727900255], [72.82562255859375, 19.0543297806049], [72.82699584960938, 19.0543297806049], [72.82699584960938, 19.053031727900255], [72.82562255859375, 19.053031727900255]]]}, "properties": {"label": [0, 1, 0, 0, 0, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82699584960938, 19.053031727900255], [72.82699584960938, 19.0543297806049], [72.828369140625, 19.0543297806049], [72.828369140625, 19.053031727900255], [72.82699584960938, 19.053031727900255]]]}, "properties": {"label": [0, 1, 0, 0, 0, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82562255859375, 19.0543297806049], [72.82562255859375, 19.055627823152516], [72.82699584960938, 19.055627823152516], [72.82699584960938, 19.0543297806049], [72.82562255859375, 19.0543297806049]]]}, "properties": {"label": [0, 1, 0, 0, 1, 0, 0]}}, {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[72.82699584960938, 19.05692585554252], [72.82699584960938, 19.05822387777432], [72.828369140625, 19.05822387777432], [72.828369140625, 19.05692585554252], [72.82699584960938, 19.05692585554252]]]}, "properties": {"label": [1, 0, 0, 0, 0, 0, 0]}}]}
17 changes: 17 additions & 0 deletions test/fixtures/integration/config-linestring.geojson.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"zoom": 18,
"classes": [
{"name": "tertiary", "filter": ["in","highway","tertiary"]},
{"name": "motorway", "filter": ["in", "highway", "motorway"]},
{"name": "primary", "filter": ["in", "highway", "primary"]},
{"name": "secondary", "filter": ["in", "highway", "secondary"]},
{"name": "residential", "filter": ["in", "highway", "residential"]},
{"name": "unclassified", "filter": ["in", "highway", "unclassified"]}
],
"geojson": "/Users/marthamorrissey/repos/label-maker/test/fixtures/integration/labels-linestring.geojson",
"imagery": "https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.jpg?access_token=ACCESS_TOKEN",
"background_ratio": 1,
"split_vals": [1.0, 0.0, 0.0],
"split_names": ["train", "validation", "test"],
"ml_type": "classification"
}
33 changes: 33 additions & 0 deletions test/fixtures/integration/labels-linestring.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825157300000058, 19.057085400000062 ], [ 72.825155500000051, 19.057146400000022 ], [ 72.824615333099686, 19.0571280429862 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825155500000051, 19.057146400000022 ], [ 72.825155900000084, 19.05720830000007 ], [ 72.825155558349365, 19.057218598633863 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825155500000051, 19.057146400000022 ], [ 72.825903600000061, 19.057181300000025 ], [ 72.826663500000052, 19.05721740000007 ], [ 72.826686300000063, 19.057030900000029 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825903600000061, 19.057181300000025 ], [ 72.825902481175845, 19.057218598633863 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826663500000052, 19.05721740000007 ], [ 72.826663397204598, 19.057218598633863 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826663500000052, 19.05721740000007 ], [ 72.826674942130694, 19.057218598633863 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary" }, "geometry": { "type": "LineString", "coordinates": [ [ 72.826733800000056, 19.054766900000061 ], [ 72.826745600000038, 19.054660200000058 ], [ 72.82674940000004, 19.054554400000029 ], [ 72.826731400000028, 19.054217900000026 ] ] } },
{ "type": "Feature", "properties": { "highway": "residential"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825243667732295, 19.053565022042594 ], [ 72.825305, 19.053576100000043 ], [ 72.825366600000052, 19.053594 ], [ 72.825409200000081, 19.053714800000023 ], [ 72.825456600000052, 19.053853600000025 ], [ 72.825537100000076, 19.053936400000055 ], [ 72.825548900000058, 19.054079600000023 ], [ 72.825534700000048, 19.054283300000066 ], [ 72.825454200000081, 19.054372800000067 ], [ 72.825395, 19.054500300000029 ], [ 72.825367, 19.054628700000023 ] ] } },
{ "type": "Feature", "properties": { "highway": "residential"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.827679800000055, 19.054791600000044 ], [ 72.827760200000057, 19.056113800000048 ] ] } },
{ "type": "Feature", "properties": { "highway": "residential"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826005800000075, 19.056489800000065 ], [ 72.82601290000008, 19.056308500000057 ], [ 72.826287600000057, 19.05629730000004 ], [ 72.826313600000049, 19.056243600000073 ], [ 72.82670440000004, 19.056270700000027 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826287600000057, 19.055807200000061 ], [ 72.826320700000053, 19.055514100000039 ], [ 72.826446, 19.055473600000028 ] ] } },
{ "type": "Feature", "properties": { "highway": "secondary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.824692900000059, 19.054467 ], [ 72.82472510000008, 19.054551700000047 ], [ 72.824763, 19.054584 ], [ 72.824998200000039, 19.054655700000069 ], [ 72.825244200000043, 19.054697500000032 ], [ 72.82534540000006, 19.05470820000005 ], [ 72.825437, 19.054717900000071 ], [ 72.825928500000032, 19.054769200000067 ], [ 72.826292400000057, 19.054795 ], [ 72.826475200000061, 19.054811900000061 ], [ 72.82653270000003, 19.054750400000046 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826733800000056, 19.054766900000061 ], [ 72.826711200000034, 19.055120700000032 ], [ 72.82670440000004, 19.055479900000023 ], [ 72.826712, 19.055629100000033 ], [ 72.826708800000063, 19.056027700000072 ], [ 72.82670440000004, 19.056270700000027 ], [ 72.826699900000051, 19.056516500000043 ], [ 72.826689700000031, 19.056831700000032 ], [ 72.826686300000063, 19.057030900000029 ] ] } },
{ "type": "Feature", "properties": { "highway": "secondary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.824615333099686, 19.054372428398164 ], [ 72.824692900000059, 19.054467 ] ] } },
{ "type": "Feature", "properties": { "highway": "secondary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.824692900000059, 19.054467 ], [ 72.824789700000053, 19.054501100000039 ], [ 72.824923100000035, 19.054546100000039 ], [ 72.825027800000043, 19.054569600000036 ], [ 72.825220200000047, 19.054614 ], [ 72.825367, 19.054628700000023 ], [ 72.825453500000037, 19.054637300000024 ], [ 72.825730400000054, 19.054669600000068 ], [ 72.82600750000006, 19.054689300000064 ], [ 72.82612110000008, 19.054697400000066 ], [ 72.826449800000034, 19.054722100000049 ], [ 72.82653270000003, 19.054750400000046 ] ] } },
{ "type": "Feature", "properties": { "highway": "secondary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.82653270000003, 19.054750400000046 ], [ 72.826733800000056, 19.054766900000061 ], [ 72.827414600000054, 19.054782500000044 ], [ 72.827679800000055, 19.054791600000044 ], [ 72.827989200000047, 19.05480220000004 ], [ 72.828268909690948, 19.054808057794592 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826475200000061, 19.054811900000061 ], [ 72.826446, 19.055473600000028 ], [ 72.82670440000004, 19.055479900000023 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.826689700000031, 19.056831700000032 ], [ 72.825182900000073, 19.056758900000034 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.825157300000058, 19.057085400000062 ], [ 72.825182900000073, 19.056758900000034 ], [ 72.825142, 19.056470600000068 ], [ 72.825085100000081, 19.056345100000044 ], [ 72.82503550000007, 19.056230200000073 ], [ 72.824983100000054, 19.056112600000063 ], [ 72.824961400000063, 19.056017200000042 ], [ 72.824954800000057, 19.055897100000038 ], [ 72.82496830000008, 19.055794800000058 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.82534540000006, 19.05470820000005 ], [ 72.825347200000067, 19.054909 ], [ 72.825346100000047, 19.055033700000024 ], [ 72.825228800000048, 19.055137100000024 ], [ 72.825171300000079, 19.055186100000071 ], [ 72.825157800000056, 19.055243700000062 ], [ 72.825143100000048, 19.055436600000064 ], [ 72.825121700000068, 19.055511200000069 ], [ 72.825026300000047, 19.055670700000064 ], [ 72.82496830000008, 19.055794800000058 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.824615333099686, 19.055298401040453 ], [ 72.82463690000003, 19.05527660000007 ], [ 72.824745200000052, 19.055210600000066 ], [ 72.825171300000079, 19.055186100000071 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.828246535504462, 19.053565022042594 ], [ 72.828246900000067, 19.053566600000067 ], [ 72.828264, 19.053632 ], [ 72.828268909690948, 19.053650283600202 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.828268909690948, 19.05412767431369 ], [ 72.827803900000049, 19.054134500000032 ], [ 72.827427300000068, 19.054137900000057 ], [ 72.827039200000058, 19.054152100000067 ], [ 72.826987400000064, 19.054184100000043 ], [ 72.826731400000028, 19.054217900000026 ], [ 72.826599400000077, 19.054235300000073 ], [ 72.826479900000038, 19.054297100000042 ], [ 72.826362600000039, 19.054365300000029 ], [ 72.826076200000045, 19.054582800000048 ], [ 72.82600750000006, 19.054689300000064 ] ] } },
{ "type": "Feature", "properties": {"highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.82727562635931, 19.053565022042594 ], [ 72.827273500000047, 19.053646900000047 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.827273500000047, 19.053646900000047 ], [ 72.827261600000043, 19.053758300000027 ], [ 72.827178700000047, 19.053830600000026 ], [ 72.827119700000083, 19.053800500000023 ], [ 72.826878900000054, 19.053768800000057 ], [ 72.826859700000057, 19.054002500000024 ], [ 72.826851800000043, 19.054065800000046 ], [ 72.827024, 19.054079400000035 ], [ 72.827039200000058, 19.054152100000067 ] ] } },
{ "type": "Feature", "properties": {"highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.828246900000067, 19.053566600000067 ], [ 72.827698, 19.053585200000043 ] ] } },
{ "type": "Feature", "properties": { "highway": "tertiary"}, "geometry": { "type": "LineString", "coordinates": [ [ 72.824615333099686, 19.053756329319864 ], [ 72.82503580000008, 19.053739300000075 ], [ 72.825051179925325, 19.053565022042594 ] ] } }
]
}
70 changes: 70 additions & 0 deletions test/integration/test_classification_labels_linestring_geojson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Test that the following CLI command returns the expected outputs
label-maker labels --dest integration-cl --config test/fixtures/integration/config.geojson.json"""
import unittest
import json
from os import makedirs
from shutil import copyfile, rmtree
import subprocess

import numpy as np

class TestClassificationLabelGeoJSON(unittest.TestCase):
"""Tests for classification label creation"""
@classmethod
def setUpClass(cls):
makedirs('integration-cl')
copyfile('test/fixtures/integration/labels-linestring.geojson', 'integration-cl/labels.geojson')

@classmethod
def tearDownClass(cls):
rmtree('integration-cl')

def test_cli(self):
"""Verify stdout, geojson, and labels.npz produced by CLI"""
# our command line output should look like this
expected_output = """Determining labels for each tile
---
tertiary: 9 tiles
motorway: 0 tiles
primary: 0 tiles
secondary: 3 tiles
residential: 5 tiles
unclassified: 0 tiles
Total tiles: 12
Writing out labels to integration-cl/labels.npz
"""

cmd = 'label-maker labels --dest integration-cl --config test/fixtures/integration/config-linestring.geojson.json'
cmd = cmd.split(' ')
with subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE) as p:
self.assertEqual(expected_output, p.stdout.read())

# our labels should look like this

expected_labels = {
'184101-116932-18': np.array([0, 1, 0, 0, 0, 0, 0]),
'184101-116931-18': np.array([0, 1, 0, 0, 0, 0, 0]),
'184101-116934-18': np.array([0, 1, 0, 0, 0, 1, 0]),
'184103-116932-18': np.array([0, 0, 0, 0, 0, 1, 0]),
'184103-116933-18': np.array([0, 0, 0, 0, 1, 1, 0]),
'184102-116932-18': np.array([0, 1, 0, 0, 0, 1, 0]),
'184102-116931-18': np.array([0, 1, 0, 0, 0, 0, 0]),
'184101-116933-18': np.array([0, 1, 0, 0, 1, 1, 0]),
'184102-116934-18': np.array([0, 1, 0, 0, 0, 0, 0]),
'184103-116934-18': np.array([0, 1, 0, 0, 0, 0, 0]),
'184102-116933-18': np.array([0, 1, 0, 0, 1, 0, 0]),
'184103-116931-18': np.array([1, 0, 0, 0, 0, 0, 0])
}

labels = np.load('integration-cl/labels.npz')
self.assertEqual(len(labels.files), len(expected_labels.keys())) # First check number of tiles
for tile in labels.files:
self.assertTrue(np.array_equal(expected_labels[tile], labels[tile])) # Now, content

# our GeoJSON looks like the fixture
with open('test/fixtures/integration/classification_linestring.geojson') as fixture:
with open('integration-cl/classification.geojson') as geojson_file:
expected_geojson = json.load(fixture)
geojson = json.load(geojson_file)

self.assertCountEqual(expected_geojson, geojson)