From dc0774360d2666bcff5b97ee81e3d8c89ba40b98 Mon Sep 17 00:00:00 2001 From: mtravis Date: Mon, 16 Oct 2023 14:10:22 +0100 Subject: [PATCH 01/13] added geocoding function --- open_buildings/download_buildings.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 610161d..997c980 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -1,7 +1,7 @@ import json import click from math import tan, cos, log, pi -from shapely.geometry import shape +from shapely.geometry import shape, box from typing import Dict, Any, Union import mercantile import duckdb @@ -15,6 +15,7 @@ import subprocess from shapely import wkb import shutil +import osmnx from open_buildings.settings import Source, Format, settings @@ -43,6 +44,11 @@ def geojson_to_wkt(data: dict) -> str: geometry = shape(data['geometry']) return geometry.wkt +def geocode_to_wkt(data: str): + location = ox.geocode_to_gdf(data) + wkt = box(*location.total_bounds) + return wkt + def quadkey_to_geojson(quadkey: str) -> dict: # Convert the quadkey to tile coordinates tile = mercantile.quadkey_to_tile(quadkey) From cd80183b995e1cd47581cdc93d6ab9dad6301fd7 Mon Sep 17 00:00:00 2001 From: mtravis Date: Thu, 19 Oct 2023 20:54:57 +0100 Subject: [PATCH 02/13] added osmnx to requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 56110fd..3f5f010 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ click duckdb pandas geopandas +osmnx shapely openlocationcode tabulate From e03dc60bcd91bb516d44a545a444d259a274cf5b Mon Sep 17 00:00:00 2001 From: mtravis Date: Fri, 20 Oct 2023 15:02:37 +0100 Subject: [PATCH 03/13] made changes to downloads.py --- open_buildings/cli.py | 13 ++++-- open_buildings/download_buildings.py | 63 +++++++++++++++------------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/open_buildings/cli.py b/open_buildings/cli.py index d5c2122..c18ce8b 100644 --- a/open_buildings/cli.py +++ b/open_buildings/cli.py @@ -8,7 +8,7 @@ from open_buildings.download_buildings import download as download_buildings from open_buildings.overture.add_columns import process_parquet_files from open_buildings.overture.partition import process_db -from open_buildings.settings import Source +from settings import Source from datetime import datetime, timedelta from tabulate import tabulate import boto3 # Required for S3 operations @@ -42,7 +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.') -def get_buildings(geojson_input, dst, source, country_iso, silent, overwrite, verbose): +@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): """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. @@ -74,7 +75,7 @@ def get_buildings(geojson_input, dst, source, country_iso, silent, overwrite, ve else: geojson_data = json.load(click.get_text_stream('stdin')) - download_buildings(geojson_data, source=source, generate_sql=False, dst=dst, silent=silent, overwrite=overwrite, verbose=verbose, country_iso=country_iso) + download_buildings(geojson_data, 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)) @@ -162,6 +163,12 @@ def benchmark( @click.option( '--overwrite', is_flag=True, help="Whether to overwrite any existing output files." ) +@click.option( + '--geocode', + type=str, + is_flag=True, + help="Use city or region name instead of geojson" +) @click.option( '--process', type=click.Choice(['duckdb', 'pandas', 'ogr']), diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 997c980..a02b619 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -16,7 +16,6 @@ from shapely import wkb import shutil import osmnx - from open_buildings.settings import Source, Format, settings def geojson_to_quadkey(data: dict) -> str: @@ -45,7 +44,7 @@ def geojson_to_wkt(data: dict) -> str: return geometry.wkt def geocode_to_wkt(data: str): - location = ox.geocode_to_gdf(data) + location = osmnx.geocode_to_gdf(data) wkt = box(*location.total_bounds) return wkt @@ -87,18 +86,22 @@ def quadkey(geojson_input): 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) -def WKT(geojson_input): - """Convert GeoJSON to Well Known Text.""" +@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.""" if geojson_input: geojson_data = json.load(geojson_input) else: - geojson_data = json.load(click.get_text_stream('stdin')) - - result = geojson_to_wkt(geojson_data) + 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) click.echo(result) @@ -106,30 +109,30 @@ def WKT(geojson_input): @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) @@ -138,9 +141,9 @@ def quad2json(quadkey_input): result = quadkey_to_geojson(quadkey_input) click.echo(json.dumps(result, indent=2)) - def download( - geojson_data: Dict[str, Any], + geojson_data: Dict[str, Any], + geocode: Optional[str] = None, dst: Union[Path, str] = "buildings.json", source: Union[Source, str] = Source.OVERTURE, format: Optional[Union[Format, str]] = None, From ce0bc83e2869c70a588f908f698c7f5ba79a3088 Mon Sep 17 00:00:00 2001 From: mtravis Date: Sat, 4 Nov 2023 13:27:33 +0000 Subject: [PATCH 04/13] Updated geocoded function and added test --- open_buildings/cli.py | 6 +-- open_buildings/download_buildings.py | 70 ++++++++++++++-------------- tests/test_open_buildings.py | 6 ++- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/open_buildings/cli.py b/open_buildings/cli.py index c18ce8b..b23ef83 100644 --- a/open_buildings/cli.py +++ b/open_buildings/cli.py @@ -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. @@ -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)) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index a02b619..25bb145 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -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: @@ -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 @@ -84,24 +86,22 @@ 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) @@ -109,30 +109,30 @@ def WKT(geojson_input, geocode_input): @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) @@ -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, diff --git a/tests/test_open_buildings.py b/tests/test_open_buildings.py index be60566..87e7a2b 100644 --- a/tests/test_open_buildings.py +++ b/tests/test_open_buildings.py @@ -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]) From 9d488c62b0006861bd4f713dcfa88ff8c18442b1 Mon Sep 17 00:00:00 2001 From: mtravis Date: Sat, 4 Nov 2023 13:33:36 +0000 Subject: [PATCH 05/13] Updated settings source --- open_buildings/download_buildings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 25bb145..bf090c4 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -17,7 +17,7 @@ from shapely.geometry import mapping import shutil import osmnx -from settings import Source, Format, settings +from open_buildings.settings import Source, Format, settings def geojson_to_quadkey(data: dict) -> str: if 'bbox' in data: From 290558a275d352812c42ff84526f40b4c0006c76 Mon Sep 17 00:00:00 2001 From: mtravis Date: Sat, 4 Nov 2023 13:38:48 +0000 Subject: [PATCH 06/13] import geocode function to tests --- tests/test_open_buildings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_open_buildings.py b/tests/test_open_buildings.py index 87e7a2b..0b5d1ca 100644 --- a/tests/test_open_buildings.py +++ b/tests/test_open_buildings.py @@ -4,7 +4,7 @@ import os import json -from open_buildings.download_buildings import download, geojson_to_wkt, geojson_to_quadkey, quadkey_to_geojson +from open_buildings.download_buildings import download, geojson_to_wkt, geojson_to_quadkey, quadkey_to_geojson, geocode from open_buildings.settings import Source, Format, settings ########################################################################### From 9ffae1e1cb4c5ee6987566d5cd272ada2a5002be Mon Sep 17 00:00:00 2001 From: mtravis Date: Sat, 4 Nov 2023 18:27:30 +0000 Subject: [PATCH 07/13] Fixed geocode test --- tests/test_open_buildings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_open_buildings.py b/tests/test_open_buildings.py index 0b5d1ca..8dc68cc 100644 --- a/tests/test_open_buildings.py +++ b/tests/test_open_buildings.py @@ -65,7 +65,8 @@ def test_quadkey_to_geojson(): 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]]]} + + assert json.loads(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) From d10fb9030fe0decce9fbf70a0c645542e6917921 Mon Sep 17 00:00:00 2001 From: mtravis Date: Sun, 5 Nov 2023 10:49:25 +0000 Subject: [PATCH 08/13] added location arg to cli.py --- open_buildings/cli.py | 10 ++++++++++ open_buildings/download_buildings.py | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/open_buildings/cli.py b/open_buildings/cli.py index b23ef83..ee1a677 100644 --- a/open_buildings/cli.py +++ b/open_buildings/cli.py @@ -3,6 +3,8 @@ import click import json import pandas as pd +import osmnx +from shapely.geometry import shape, box, mapping import matplotlib.pyplot as plt from open_buildings.google.process import process_benchmark, process_geometries from open_buildings.download_buildings import download as download_buildings @@ -34,6 +36,12 @@ def overture(): def handle_comma_separated(ctx, param, value): return value.split(',') +def geocode(data: str): + location = osmnx.geocode_to_gdf(data) + wkt = box(*location.total_bounds) + geojson = json.dumps(mapping(wkt)) + return geojson + @main.command(name="get_buildings") @click.argument('geojson_input', type=click.File('r'), required=False) @click.argument('dst', type=str, default="buildings.json") @@ -72,6 +80,8 @@ def get_buildings(geojson_input, location, dst, source, country_iso, silent, ove if geojson_input: geojson_data = json.load(geojson_input) + elif geocode: + geojson_data = geocode(location) else: geojson_data = json.load(click.get_text_stream('stdin')) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index bf090c4..d38e166 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -1,7 +1,7 @@ import json import click from math import tan, cos, log, pi -from shapely.geometry import shape, box +from shapely.geometry import shape, box, mapping from typing import Dict, Any, Union import mercantile import duckdb @@ -14,7 +14,7 @@ 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 @@ -87,7 +87,6 @@ def quadkey(geojson_input): else: geojson_data = json.load(click.get_text_stream('stdin')) result = geojson_to_quadkey(geojson_data) - print() click.echo(result) @cli.command() @@ -143,7 +142,7 @@ def quad2json(quadkey_input): def download( geojson_data: Dict[str, Any], - #geocode: Optional[str] = None, + location: Optional[str] = None, dst: Union[Path, str] = "buildings.json", source: Union[Source, str] = Source.OVERTURE, format: Optional[Union[Format, str]] = None, From 02203c46489ad20fbad474eac2b93fee7934fc48 Mon Sep 17 00:00:00 2001 From: mtravis Date: Mon, 6 Nov 2023 12:41:02 +0000 Subject: [PATCH 09/13] fixed import settings --- open_buildings/cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open_buildings/cli.py b/open_buildings/cli.py index ee1a677..55c17d2 100644 --- a/open_buildings/cli.py +++ b/open_buildings/cli.py @@ -10,7 +10,7 @@ from open_buildings.download_buildings import download as download_buildings from open_buildings.overture.add_columns import process_parquet_files from open_buildings.overture.partition import process_db -from settings import Source +from open_buildings.settings import Source from datetime import datetime, timedelta from tabulate import tabulate import boto3 # Required for S3 operations From 04bd2241d0adb0813514c29eb271f545f98ab1cc Mon Sep 17 00:00:00 2001 From: mtravis Date: Mon, 6 Nov 2023 14:31:55 +0000 Subject: [PATCH 10/13] added exception for when location geojson isn't true geojson --- open_buildings/download_buildings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index d38e166..03ce968 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -22,6 +22,10 @@ def geojson_to_quadkey(data: dict) -> str: if 'bbox' in data: min_lon, min_lat, max_lon, max_lat = data['bbox'] + elif data['type'] is 'Polygon': + coords = data['coordinates'][0] + min_lon = min_lat = float('inf') + max_lon = max_lat = float('-inf') else: coords = data['geometry']['coordinates'][0] min_lon = min_lat = float('inf') From d2955aa4b6adedd51942bfdc6f8448e048974d8b Mon Sep 17 00:00:00 2001 From: Matt Travis Date: Mon, 6 Nov 2023 18:47:16 +0000 Subject: [PATCH 11/13] Update download_buildings.py --- open_buildings/download_buildings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 03ce968..27c7dc5 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -22,7 +22,7 @@ def geojson_to_quadkey(data: dict) -> str: if 'bbox' in data: min_lon, min_lat, max_lon, max_lat = data['bbox'] - elif data['type'] is 'Polygon': + elif data['type'] == 'Polygon': coords = data['coordinates'][0] min_lon = min_lat = float('inf') max_lon = max_lat = float('-inf') @@ -344,4 +344,4 @@ def print_elapsed_time(start_time): #cli.add_command(download) if __name__ == '__main__': - cli() \ No newline at end of file + cli() From b5c97d233b7ef233403475ea716cd3942449bdf1 Mon Sep 17 00:00:00 2001 From: mtravis Date: Mon, 6 Nov 2023 19:11:05 +0000 Subject: [PATCH 12/13] Fixed wkt to geojson for geocode --- open_buildings/download_buildings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 27c7dc5..71f144e 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -13,7 +13,7 @@ import pandas as pd import geopandas as gpd import subprocess -from shapely import wkb +import shapely import shutil import osmnx @@ -51,7 +51,7 @@ def geojson_to_wkt(data: dict) -> str: def geocode(data: str): location = osmnx.geocode_to_gdf(data) wkt = box(*location.total_bounds) - geojson = json.dumps(mapping(wkt)) + geojson = shapely.to_geojson(wkt) return geojson def quadkey_to_geojson(quadkey: str) -> dict: From f723da6c0649cfd3cc420eb5e78bf1c048e28214 Mon Sep 17 00:00:00 2001 From: Matt Travis Date: Mon, 6 Nov 2023 21:12:35 +0000 Subject: [PATCH 13/13] Update download_buildings.py --- open_buildings/download_buildings.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/open_buildings/download_buildings.py b/open_buildings/download_buildings.py index 71f144e..801ab4d 100644 --- a/open_buildings/download_buildings.py +++ b/open_buildings/download_buildings.py @@ -14,7 +14,7 @@ import geopandas as gpd import subprocess import shapely - +import geojson import shutil import osmnx from open_buildings.settings import Source, Format, settings @@ -22,10 +22,6 @@ def geojson_to_quadkey(data: dict) -> str: if 'bbox' in data: min_lon, min_lat, max_lon, max_lat = data['bbox'] - elif data['type'] == 'Polygon': - coords = data['coordinates'][0] - min_lon = min_lat = float('inf') - max_lon = max_lat = float('-inf') else: coords = data['geometry']['coordinates'][0] min_lon = min_lat = float('inf') @@ -51,8 +47,8 @@ def geojson_to_wkt(data: dict) -> str: def geocode(data: str): location = osmnx.geocode_to_gdf(data) wkt = box(*location.total_bounds) - geojson = shapely.to_geojson(wkt) - return geojson + g2 = geojson.Feature(geometry=wkt) + return (g2) def quadkey_to_geojson(quadkey: str) -> dict: # Convert the quadkey to tile coordinates