Skip to content

Commit

Permalink
Updated geocoded function and added test
Browse files Browse the repository at this point in the history
  • Loading branch information
mtravis committed Nov 4, 2023
1 parent e03dc60 commit ce0bc83
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 39 deletions.
6 changes: 3 additions & 3 deletions open_buildings/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def handle_comma_separated(ctx, param, value):
@click.option('-s', '--silent', is_flag=True, default=False, help='Suppress all print outputs.')
@click.option('--overwrite', default=False, is_flag=True, help='Overwrite the destination file if it already exists.')
@click.option('--verbose', default=False, is_flag=True, help='Print detailed logs with timestamps.')
@click.option('--geocode', default=False, is_flag=True, help='Use city or region name')
def get_buildings(geojson_input, geocode, dst, source, country_iso, silent, overwrite, verbose):
@click.option('--location', type=str, default=None, help='Use city or region name')
def get_buildings(geojson_input, location, dst, source, country_iso, silent, overwrite, verbose):
"""Tool to extract buildings in common geospatial formats from large archives of GeoParquet data online. GeoJSON
input can be provided as a file or piped in from stdin. If no GeoJSON input is provided, the tool will read from stdin.
Expand Down Expand Up @@ -75,7 +75,7 @@ def get_buildings(geojson_input, geocode, dst, source, country_iso, silent, over
else:
geojson_data = json.load(click.get_text_stream('stdin'))

download_buildings(geojson_data, generate_sql=False, dst=dst, silent=silent, overwrite=overwrite, verbose=verbose, country_iso=country_iso)
download_buildings(geojson_data, location, generate_sql=False, dst=dst, silent=silent, overwrite=overwrite, verbose=verbose, country_iso=country_iso)

@google.command('benchmark')
@click.argument('input_path', type=click.Path(exists=True))
Expand Down
70 changes: 35 additions & 35 deletions open_buildings/download_buildings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
import geopandas as gpd
import subprocess
from shapely import wkb
from shapely.geometry import mapping
import shutil
import osmnx
from open_buildings.settings import Source, Format, settings
from settings import Source, Format, settings

def geojson_to_quadkey(data: dict) -> str:
if 'bbox' in data:
Expand All @@ -43,10 +44,11 @@ def geojson_to_wkt(data: dict) -> str:
geometry = shape(data['geometry'])
return geometry.wkt

def geocode_to_wkt(data: str):
def geocode(data: str):
location = osmnx.geocode_to_gdf(data)
wkt = box(*location.total_bounds)
return wkt
geojson = json.dumps(mapping(wkt))
return geojson

def quadkey_to_geojson(quadkey: str) -> dict:
# Convert the quadkey to tile coordinates
Expand Down Expand Up @@ -84,55 +86,53 @@ def quadkey(geojson_input):
geojson_data = json.load(geojson_input)
else:
geojson_data = json.load(click.get_text_stream('stdin'))

result = geojson_to_quadkey(geojson_data)
print()
click.echo(result)

@cli.command()
@click.argument('geojson_input', type=click.File('r'), required=False)
@click.option('--geocode', type=str, is_flag=True, help='geocode using a city or region')
def WKT(geojson_input, geocode_input):
"""Convert GeoJSON to Well Known Text."""
@click.option('--location', type=str, help='geocode using a city or region')
def WKT(geojson_input, location):
"""Convert GeoJSON to Well Known Text."""
if geojson_input:
geojson_data = json.load(geojson_input)
result = json.load(geojson_input)
elif location:
result = geocode(location)
else:
geojson_data = json.load(click.get_text_stream('stdin'))
if geocode_input:
result = geocode_to_wkt(geocode_input)
else:
result = geojson_to_wkt(geojson_data)
geojson_data = json.load(click.get_text_stream('stdin'))
result = geojson_to_wkt(geojson_data)
click.echo(result)


@click.command()
@click.argument('geojson_input', type=click.File('r'), required=False)
@click.option('--only-quadkey', is_flag=True, help='Include only the quadkey in the WHERE clause.')
@click.option('--local', is_flag=True, help='Use local path for parquet files instead of the S3 URL.')
# def sql(geojson_input, only_quadkey, local):
# """Generate an SQL query based on the input GeoJSON."""
def sql(geojson_input, only_quadkey, local):
"""Generate an SQL query based on the input GeoJSON."""

# # Read the GeoJSON
# if geojson_input:
# geojson_data = json.load(geojson_input)
# else:
# geojson_data = json.load(click.get_text_stream('stdin'))

# quadkey = geojson_to_quadkey(geojson_data)
# wkt = geojson_to_wkt(geojson_data)

# # Adjust the path in read_parquet based on the --local flag
# path = '*.parquet' if local else 's3://us-west-2.opendata.source.coop/cholmes/overture/geoparquet-country-quad-2/*.parquet'
# base_sql = f"select * from read_parquet('{path}')"
# Read the GeoJSON
if geojson_input:
geojson_data = json.load(geojson_input)
else:
geojson_data = json.load(click.get_text_stream('stdin'))

quadkey = geojson_to_quadkey(geojson_data)
wkt = geojson_to_wkt(geojson_data)

# Adjust the path in read_parquet based on the --local flag
path = '*.parquet' if local else 's3://us-west-2.opendata.source.coop/cholmes/overture/geoparquet-country-quad-2/*.parquet'
base_sql = f"select * from read_parquet('{path}')"

# # Construct the WHERE clause based on the options
# where_clause = f"WHERE quadkey LIKE '{quadkey}%'"
# if not only_quadkey:
# where_clause += f" AND\nST_Within(ST_GeomFromWKB(geometry), ST_GeomFromText('{wkt}'))"
# Construct the WHERE clause based on the options
where_clause = f"WHERE quadkey LIKE '{quadkey}%'"
if not only_quadkey:
where_clause += f" AND\nST_Within(ST_GeomFromWKB(geometry), ST_GeomFromText('{wkt}'))"

# sql_query = f"{base_sql},\n{where_clause}"
# full_sql_query = f"COPY ('{sql_query}' TO 'buildings.fgb' WITH (FORMAT GDAL, DRIVER 'FlatGeobuf')"
# click.echo(full_sql_query)
sql_query = f"{base_sql},\n{where_clause}"
full_sql_query = f"COPY ('{sql_query}' TO 'buildings.fgb' WITH (FORMAT GDAL, DRIVER 'FlatGeobuf')"
click.echo(full_sql_query)

@cli.command()
@click.argument('quadkey_input', type=str)
Expand All @@ -143,7 +143,7 @@ def quad2json(quadkey_input):

def download(
geojson_data: Dict[str, Any],
geocode: Optional[str] = None,
#geocode: Optional[str] = None,
dst: Union[Path, str] = "buildings.json",
source: Union[Source, str] = Source.OVERTURE,
format: Optional[Union[Format, str]] = None,
Expand Down
6 changes: 5 additions & 1 deletion tests/test_open_buildings.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,15 @@ def test_geojson_to_wkt(aoi: Dict[str, Any]):
def test_geojson_to_quadkey(aoi: Dict[str, Any]):
""" Tests geojson_to_quadkey() using a pre-established true value. """
assert geojson_to_quadkey(aoi) == '301001330310'

def test_quadkey_to_geojson():
""" Tests quadkey_to_geojson() using a pre-established true value. """
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": "Polygon", "coordinates": [[[-4.0196056, 50.3327426], [-4.0196056, 50.4441737], [-4.2055324, 50.4441737], [-4.2055324, 50.3327426], [-4.0196056, 50.3327426]]]}

@pytest.mark.integration
@pytest.mark.flaky(reruns=NUM_RERUNS)
@pytest.mark.parametrize("source", [s for s in Source])
Expand Down

0 comments on commit ce0bc83

Please sign in to comment.