Skip to content

Commit

Permalink
Consolidate crs validity test.
Browse files Browse the repository at this point in the history
Also add another test of the --all callback and fix the bug it
exposed.
  • Loading branch information
Sean Gillies committed Jul 8, 2015
1 parent 7c07a58 commit ee1ef2d
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 13 deletions.
24 changes: 17 additions & 7 deletions rasterio/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@
# {'proj': 'longlat', 'ellps': 'WGS84', 'datum': 'WGS84', 'no_defs': True}
#

from rasterio._base import is_geographic_crs, is_projected_crs
from rasterio._base import is_geographic_crs, is_projected_crs, is_same_crs
from rasterio.five import string_types


def is_valid_crs(crs):
return is_geographic_crs(crs) or is_projected_crs(crs)


def to_string(crs):
"""Turn a parameter mapping into a more conventional PROJ.4 string.
Expand All @@ -24,22 +29,24 @@ def to_string(crs):
items = []
for k, v in sorted(filter(
lambda x: x[0] in all_proj_keys and x[1] is not False and (
isinstance(x[1], (bool, int, float)) or
isinstance(x[1], (bool, int, float)) or
isinstance(x[1], string_types)),
crs.items() )):
crs.items())):
items.append(
"+" + "=".join(
map(str, filter(
lambda y: (y or y == 0) and y is not True, (k, v)))) )
lambda y: (y or y == 0) and y is not True, (k, v)))))
return " ".join(items)


def from_string(prjs):
"""Turn a PROJ.4 string into a mapping of parameters.
Bare parameters like "+no_defs" are given a value of ``True``. All keys
are checked against the ``all_proj_keys`` list.
"""
parts = [o.lstrip('+') for o in prjs.strip().split()]

def parse(v):
if v in ('True', 'true'):
return True
Expand All @@ -54,10 +61,13 @@ def parse(v):
return float(v)
except ValueError:
return v

items = map(
lambda kv: len(kv) == 2 and (kv[0], parse(kv[1])) or (kv[0], True),
(p.split('=') for p in parts) )
return dict((k,v) for k, v in items if k in all_proj_keys)
(p.split('=') for p in parts))

return dict((k, v) for k, v in items if k in all_proj_keys)


def from_epsg(code):
"""Given an integer code, returns an EPSG-like mapping.
Expand Down Expand Up @@ -183,5 +193,5 @@ def from_epsg(code):

_lines = filter(lambda x: len(x) > 1, _param_data.split("\n"))
all_proj_keys = list(
set(line.split()[0].lstrip("+").strip() for line in _lines)
set(line.split()[0].lstrip("+").strip() for line in _lines)
) + ['no_mayo']
5 changes: 2 additions & 3 deletions rasterio/rio/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def from_like_context(ctx, param, value):

def all_handler(ctx, param, value):
"""Get tags from a template file or command line."""
if ctx.obj and ctx.obj.get('like'):
if ctx.obj and ctx.obj.get('like') and value is not None:
ctx.obj['all_like'] = value
value = ctx.obj.get('like')
return value
Expand All @@ -43,8 +43,7 @@ def crs_handler(ctx, param, value):
retval = json.loads(value)
except ValueError:
retval = value
if not (rasterio.crs.is_geographic_crs(retval) or
rasterio.crs.is_projected_crs(retval)):
if not rasterio.crs.is_valid_crs(retval):
raise click.BadParameter(
"'%s' is not a recognized CRS." % retval,
param=param, param_hint='crs')
Expand Down
19 changes: 17 additions & 2 deletions tests/test_crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@

import rasterio
from rasterio import crs
from rasterio._base import is_geographic_crs, is_projected_crs, is_same_crs
from rasterio.crs import (
is_geographic_crs, is_projected_crs, is_same_crs, is_valid_crs)


logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)


# When possible, Rasterio gives you the CRS in the form of an EPSG code.
def test_read_epsg(tmpdir):
with rasterio.drivers():
Expand Down Expand Up @@ -117,4 +120,16 @@ def test_is_same_crs():
# Make sure that same projection with different parameter are not equal
lcc_crs1 = crs.from_string('+lon_0=-95 +ellps=GRS80 +y_0=0 +no_defs=True +proj=lcc +x_0=0 +units=m +lat_2=77 +lat_1=49 +lat_0=0')
lcc_crs2 = crs.from_string('+lon_0=-95 +ellps=GRS80 +y_0=0 +no_defs=True +proj=lcc +x_0=0 +units=m +lat_2=77 +lat_1=45 +lat_0=0')
assert is_same_crs(lcc_crs1, lcc_crs2) is False
assert is_same_crs(lcc_crs1, lcc_crs2) is False


def test_to_string():
assert crs.to_string({'init': 'EPSG:4326'}) == "+init=EPSG:4326"


def test_is_valid_false():
assert not is_valid_crs('EPSG:432600')


def test_is_valid():
assert is_valid_crs('EPSG:4326')
8 changes: 7 additions & 1 deletion tests/test_rio_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,16 @@ def test_like_dataset_callback(data):
assert ctx.obj['like']['crs'] == {'init': 'epsg:32618'}


def test_all_callback_pass(data):
ctx = MockContext()
ctx.obj['like'] = {'transform': 'foo'}
assert info.all_handler(ctx, None, None) == None


def test_all_callback(data):
ctx = MockContext()
ctx.obj['like'] = {'transform': 'foo'}
assert info.all_handler(ctx, None, None) == {'transform': 'foo'}
assert info.all_handler(ctx, None, True) == {'transform': 'foo'}


def test_all_callback_None(data):
Expand Down

0 comments on commit ee1ef2d

Please sign in to comment.