Skip to content

Commit

Permalink
update readme, simplify geojson_to_quadkey, change geocode() to retur…
Browse files Browse the repository at this point in the history
…n exact geometry, add test for multipolygon geocoding result
  • Loading branch information
felix-schott committed Nov 16, 2023
1 parent 0daad7c commit e545565
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 20 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ Will print out a help message. You then will be able run the CLI (download [1.js


```bash
ob tools get_buildings 1.json my-buildings.geojson --country_iso RW
ob tools get_buildings 1.json --dst my-buildings.geojson --country_iso RW
```

You can also stream the json in directly in one line:

```
curl https://data.source.coop/cholmes/aois/1.json | ob get_buildings - my-buildings.geojson --country_iso RW
curl https://data.source.coop/cholmes/aois/1.json | ob get_buildings - --dst my-buildings.geojson --country_iso RW
```


Expand Down Expand Up @@ -96,13 +96,17 @@ Usage: ob get_buildings [OPTIONS] [GEOJSON_INPUT] [DST]
this tool we hope to eliminate the need to hint with the country_iso.
Options:
--dst TEXT The path to write the output to. Can be a
directory or file.
--location TEXT Use city or region name instead of providing an
AOI as file.
--source [google|overture] Dataset to query, defaults to Overture
--country_iso TEXT A 2 character country ISO code to filter the
data by.
-s, --silent Suppress all print outputs.
--overwrite Overwrite the destination file if it already
exists.
--verbose Print detailed logs with timestamps.
-v, --verbose Print detailed logs with timestamps.
--help Show this message and exit.
```

Expand Down
6 changes: 3 additions & 3 deletions open_buildings/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ def handle_comma_separated(ctx, param, value):

def geocode(data: str):
location = osmnx.geocode_to_gdf(data)
wkt = box(*location.total_bounds)
geojson = json.loads(json.dumps({"type": "Feature", "geometry": mapping(wkt)})) # turn geom tuple into list by (de-)serialising
geom = location.geometry[0]
geojson = json.loads(json.dumps({"type": "Feature", "geometry": mapping(geom)})) # turn geom tuple into list by (de-)serialising
return geojson

@main.command(name="get_buildings")
@click.argument('geojson_input', type=click.File('r'), required=False)
@click.option('--dst', type=str, default="buildings.json", help='The path to write the output to. Can be a directory or file.')
@click.option('--location', type=str, default=None, help='Use city or region name')
@click.option('--location', type=str, default=None, help='Use city or region name instead of providing an AOI as file.')
@click.option('--source', default="overture", type=click.Choice(['google', 'overture']), help='Dataset to query, defaults to Overture')
@click.option('--country_iso', type=str, default=None, help='A 2 character country ISO code to filter the data by.')
@click.option('-s', '--silent', is_flag=True, default=False, help='Suppress all print outputs.')
Expand Down
14 changes: 2 additions & 12 deletions open_buildings/download_buildings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,8 @@
from open_buildings.settings import Source, Format, settings

def geojson_to_quadkey(data: dict) -> str:
if 'bbox' in data:
min_lon, min_lat, max_lon, max_lat = data['bbox']
else:
coords = data['geometry']['coordinates'][0]
min_lon = min_lat = float('inf')
max_lon = max_lat = float('-inf')

for lon, lat in coords:
min_lon = min(min_lon, lon)
min_lat = min(min_lat, lat)
max_lon = max(max_lon, lon)
max_lat = max(max_lat, lat)
geom = shape(data["geometry"])
min_lon, min_lat, max_lon, max_lat = geom.bounds

for zoom in range(12, -1, -1):
tiles = list(mercantile.tiles(min_lon, min_lat, max_lon, max_lat, zooms=zoom))
Expand Down
19 changes: 17 additions & 2 deletions tests/test_open_buildings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from pathlib import Path
import os
import json
from shapely.geometry import shape, box, mapping
import re
import subprocess

Expand Down Expand Up @@ -67,8 +68,10 @@ def test_quadkey_to_geojson():
assert quadkey_to_geojson('031313131112') == {'type': 'Feature', 'geometry': {'type': 'Polygon', 'coordinates': [[[-0.17578125, 51.50874245880333], [-0.087890625, 51.50874245880333], [-0.087890625, 51.56341232867588], [-0.17578125, 51.56341232867588], [-0.17578125, 51.50874245880333]]]}}

def test_geocode():
""" Tests geocode() using a pre-established true value. """
assert geocode('plymouth') == {"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[-4.0196056, 50.3327426], [-4.0196056, 50.4441737], [-4.2055324, 50.4441737], [-4.2055324, 50.3327426], [-4.0196056, 50.3327426]]]}}
""" Tests geocode() using a pre-established true value. Verifies the bbox of the returned geometry. """
geocoding_result = geocode('plymouth')
assert geocoding_result["type"] == "Feature"
assert shape(geocoding_result["geometry"]).bounds == (-4.2055324, 50.3327426, -4.0196056, 50.4441737)

@pytest.mark.integration
@pytest.mark.flaky(reruns=NUM_RERUNS)
Expand Down Expand Up @@ -214,3 +217,15 @@ def test_cli_get_buildings_geocode(tmp_path: Path):
subprocess.run(["ob", "get_buildings", "--dst", str(output_path), "--location", "oxford uk", "--country_iso", "GB"], check=True)
assert os.path.exists(output_path)
assert os.path.getsize(output_path) != 0

@pytest.mark.integration
@pytest.mark.flaky(reruns=NUM_RERUNS)
def test_cli_get_buildings_geocode_multipolygon(tmp_path: Path):
"""
Tests the geocoding functionality, implemented as the argument "location". Makes sure that a MultiPolygon geometry (the outline of Dubrovnik)
is simplified to a polygon (convex hull).
"""
output_path = tmp_path.joinpath("geocode_test.json")
subprocess.run(["ob", "get_buildings", "--dst", str(output_path), "--location", "dubrovnik", "--country_iso", "HR"], check=True)
assert os.path.exists(output_path)
assert os.path.getsize(output_path) != 0

0 comments on commit e545565

Please sign in to comment.