Skip to content

Commit

Permalink
Merge pull request #351 from CartoDB/iss348-optional-non-shoreline-cl…
Browse files Browse the repository at this point in the history
…ipped

optionally add non-shoreline clipped boundaries to search
  • Loading branch information
andy-esch authored Dec 19, 2017
2 parents ad476c8 + a4f630c commit 9566be9
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
37 changes: 28 additions & 9 deletions cartoframes/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ def _geom_type(self, source):
return resp['rows'][0]['geom_type']

def data_boundaries(self, boundary=None, region=None, decode_geom=False,
timespan=None):
timespan=None, include_nonclipped=False):
"""
Find all boundaries available for the world or a `region`. If
`boundary` is specified, get all available boundary polygons for the
Expand Down Expand Up @@ -1122,7 +1122,8 @@ def data_boundaries(self, boundary=None, region=None, decode_geom=False,
# get median income data and original table as new dataframe
idaho_falls_income = cc.data(
'idaho_falls_tracts',
median_income_meta)
median_income_meta,
how='geom_refs')
# overwrite existing table with newly-enriched dataframe
cc.write(idaho_falls_income,
'idaho_falls_tracts',
Expand All @@ -1146,6 +1147,15 @@ def data_boundaries(self, boundary=None, region=None, decode_geom=False,
southern latitude, eastern longitude, and northern latitude.
For example, Switzerland fits in
``[5.9559111595,45.8179931641,10.4920501709,47.808380127]``
timespan (str, optional): Specific timespan to get geometries from.
Defaults to use the most recent. See the Data Observatory catalog
for more information.
decode_geom (bool, optional): Whether to return the geometries as
Shapely objects or keep them encoded as EWKB strings. Defaults
to False.
include_nonclipped (bool, optional): Optionally include
non-shoreline-clipped boundaries. These boundaries are the raw
boundaries provided by, for example, US Census Tiger.
Returns:
pandas.DataFrame: If `boundary` is specified, then all available
Expand Down Expand Up @@ -1179,7 +1189,7 @@ def data_boundaries(self, boundary=None, region=None, decode_geom=False,
'FROM {table})').format(table=region)
except CartoException:
# see if it's a Data Obs region tag
regionsearch = 'WHERE "geom_tags"::text ilike \'%{}%\''.format(
regionsearch = '"geom_tags"::text ilike \'%{}%\''.format(
get_countrytag(region))
bounds = 'ST_MakeEnvelope(-180.0, -85.0, 180.0, 85.0, 4326)'

Expand All @@ -1189,12 +1199,22 @@ def data_boundaries(self, boundary=None, region=None, decode_geom=False,
raise ValueError('`region` must be a str, a list of two lng/lat '
'pairs, or ``None`` (which defaults to the '
'world)')
if include_nonclipped:
clipped = None
else:
clipped = (r"(geom_id ~ '^us\.census\..*_clipped$' OR "
r"geom_id !~ '^us\.census\..*')")

if boundary is None:
regionsearch = locals().get('regionsearch')
query = ('SELECT * FROM OBS_GetAvailableGeometries('
'{bounds}) {regionsearch}').format(
bounds=bounds,
regionsearch=regionsearch if regionsearch else '')
filters = ' AND '.join(r for r in [regionsearch, clipped] if r)
query = utils.minify_sql((
'SELECT *',
'FROM OBS_GetAvailableGeometries({bounds})',
'{filters}')).format(
bounds=bounds,
filters='WHERE {}'.format(filters) if filters else ''
)
return self.query(query)

query = utils.minify_sql((
Expand All @@ -1203,10 +1223,9 @@ def data_boundaries(self, boundary=None, region=None, decode_geom=False,
' {bounds},',
' {boundary},',
' {time})', )).format(
boundary=utils.pgquote(boundary),
bounds=bounds,
boundary=utils.pgquote(boundary),
time=utils.pgquote(timespan))
self._debug_print(query=query)
return self.query(query, decode_geom=decode_geom)

def data_discovery(self, region, keywords=None, regex=None, time=None,
Expand Down
9 changes: 9 additions & 0 deletions test/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,15 @@ def test_data_boundaries(self):
self.assertSetEqual(set(('the_geom', 'geom_refs', )),
set(geoms.columns))

# presence or lack of clipped boundaries
nonclipped = (True, False, )
for tf in nonclipped:
meta = cc.data_boundaries(include_nonclipped=tf)
self.assertEqual(
'us.census.tiger.state' in set(meta.geom_id),
tf
)

with self.assertRaises(ValueError):
cc.data_boundaries(region=[1, 2, 3])

Expand Down

0 comments on commit 9566be9

Please sign in to comment.