From 4fdac7e4bca30456e121d880cdfb800dd04c898a Mon Sep 17 00:00:00 2001 From: "Shaun A. Noordin" Date: Thu, 18 Mar 2021 00:36:57 +0000 Subject: [PATCH 1/4] Allow geojson renderer to handle Carto's encrypted 'the_geom' data --- plugins/geo_json_renderer.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/plugins/geo_json_renderer.py b/plugins/geo_json_renderer.py index 8d3a7cc..d797be8 100644 --- a/plugins/geo_json_renderer.py +++ b/plugins/geo_json_renderer.py @@ -1,6 +1,7 @@ from datasette import hookimpl from datasette.utils.asgi import Response import geojson +from plpygis import Geometry # https://docs.datasette.io/en/stable/plugin_hooks.html#register-output-renderer-datasette @@ -23,12 +24,23 @@ async def render_geo_json( feature_list = list() for row in result: - # https://geojson.org/geojson-spec.html#id2 - point = geojson.Point((row['longitude'], row['latitude'])) - # create a geojson feature - feature = geojson.Feature(geometry=point, properties=dict(row)) - # append the current feature to the list of all features - feature_list.append(feature) + # Is this a blatant Point object? + if hasattr(row, 'longitude') and hasattr(row, 'latitude'): + # https://geojson.org/geojson-spec.html#id2 + point = geojson.Point((row['longitude'], row['latitude'])) + # create a geojson feature + feature = geojson.Feature(geometry=point, properties=dict(row)) + # append the current feature to the list of all features + feature_list.append(feature) + + # Otherwise, does this have a "the_geom" object, which was used in the old Carto database, which encodes geographical data as a string in the "well-known binary" format? + elif hasattr(row, 'the_geom'): + feature = Geometry(row['the_geom']) + feature_list.append(feature) + + else: + # TODO: do we need to have error handling here? + pass feature_collection = geojson.FeatureCollection(feature_list) body = geojson.dumps(feature_collection) From e851cf5d911f19348d164511f3ece40219431336 Mon Sep 17 00:00:00 2001 From: "Shaun A. Noordin" Date: Thu, 18 Mar 2021 01:32:57 +0000 Subject: [PATCH 2/4] Add plpygis to Dockerfile --- Dockerfile | 2 +- plugins/geo_json_renderer.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d94f99e..3dabd5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ WORKDIR /mnt/datasette # for csv import - https://datasette.io/tools/csvs-to-sqlite # for datasette db maniupluations and tools - https://datasette.io/tools/sqlite-utils # for geojson api responses - https://pypi.org/project/geojson/ -RUN pip install csvs-to-sqlite sqlite-utils geojson +RUN pip install csvs-to-sqlite sqlite-utils geojson plpygis # Add the csv data files COPY data/ . diff --git a/plugins/geo_json_renderer.py b/plugins/geo_json_renderer.py index d797be8..6911e17 100644 --- a/plugins/geo_json_renderer.py +++ b/plugins/geo_json_renderer.py @@ -25,7 +25,7 @@ async def render_geo_json( for row in result: # Is this a blatant Point object? - if hasattr(row, 'longitude') and hasattr(row, 'latitude'): + if 'longitude' in row and 'latitude' in row: # https://geojson.org/geojson-spec.html#id2 point = geojson.Point((row['longitude'], row['latitude'])) # create a geojson feature @@ -34,7 +34,7 @@ async def render_geo_json( feature_list.append(feature) # Otherwise, does this have a "the_geom" object, which was used in the old Carto database, which encodes geographical data as a string in the "well-known binary" format? - elif hasattr(row, 'the_geom'): + if 'the_geom' in row: feature = Geometry(row['the_geom']) feature_list.append(feature) From 62a7999b3c1279526c7894fdfd4cb046ca7c62bd Mon Sep 17 00:00:00 2001 From: "Shaun A. Noordin" Date: Thu, 18 Mar 2021 01:34:39 +0000 Subject: [PATCH 3/4] Fix if/elif typo --- plugins/geo_json_renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/geo_json_renderer.py b/plugins/geo_json_renderer.py index 6911e17..451ed28 100644 --- a/plugins/geo_json_renderer.py +++ b/plugins/geo_json_renderer.py @@ -34,7 +34,7 @@ async def render_geo_json( feature_list.append(feature) # Otherwise, does this have a "the_geom" object, which was used in the old Carto database, which encodes geographical data as a string in the "well-known binary" format? - if 'the_geom' in row: + elif 'the_geom' in row: feature = Geometry(row['the_geom']) feature_list.append(feature) From d2e42021a38816be79b90144ca8eeee2ed00976b Mon Sep 17 00:00:00 2001 From: "Shaun A. Noordin" Date: Thu, 18 Mar 2021 01:37:31 +0000 Subject: [PATCH 4/4] Fix 'in' checks --- plugins/geo_json_renderer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/geo_json_renderer.py b/plugins/geo_json_renderer.py index 451ed28..1c80c51 100644 --- a/plugins/geo_json_renderer.py +++ b/plugins/geo_json_renderer.py @@ -25,7 +25,7 @@ async def render_geo_json( for row in result: # Is this a blatant Point object? - if 'longitude' in row and 'latitude' in row: + if 'longitude' in row.keys() and 'latitude' in row.keys(): # https://geojson.org/geojson-spec.html#id2 point = geojson.Point((row['longitude'], row['latitude'])) # create a geojson feature @@ -34,7 +34,7 @@ async def render_geo_json( feature_list.append(feature) # Otherwise, does this have a "the_geom" object, which was used in the old Carto database, which encodes geographical data as a string in the "well-known binary" format? - elif 'the_geom' in row: + elif 'the_geom' in row.keys(): feature = Geometry(row['the_geom']) feature_list.append(feature)