1import pytest
2
3from fiona import crs, _crs
4from fiona.errors import CRSError
5
6from .conftest import requires_gdal_lt_3
7
8
9def test_proj_keys():
10    assert len(crs.all_proj_keys) == 87
11    assert 'init' in crs.all_proj_keys
12    assert 'proj' in crs.all_proj_keys
13    assert 'no_mayo' in crs.all_proj_keys
14
15
16def test_from_string():
17    # A PROJ.4 string with extra whitespace.
18    val = crs.from_string(
19        " +proj=longlat +ellps=WGS84 +datum=WGS84  +no_defs +foo  ")
20    assert len(val.items()) == 4
21    assert val['proj'] == 'longlat'
22    assert val['ellps'] == 'WGS84'
23    assert val['datum'] == 'WGS84'
24    assert val['no_defs']
25    assert 'foo' not in val
26
27
28def test_from_string_utm():
29    # A PROJ.4 string with extra whitespace and integer UTM zone.
30    val = crs.from_string(
31        " +proj=utm +zone=13 +ellps=WGS84 +foo  ")
32    assert len(val.items()) == 3
33    assert val['proj'] == 'utm'
34    assert val['ellps'] == 'WGS84'
35    assert val['zone'] == 13
36    assert 'foo' not in val
37
38
39def test_to_string():
40    # Make a string from a mapping with a few bogus items
41    val = {
42        'proj': 'longlat', 'ellps': 'WGS84', 'datum': 'WGS84',
43        'no_defs': True, 'foo': True, 'axis': False, 'belgium': [1, 2]}
44    assert crs.to_string(
45        val) == "+datum=WGS84 +ellps=WGS84 +no_defs +proj=longlat"
46
47
48def test_to_string_utm():
49    # Make a string from a mapping with a few bogus items
50    val = {
51        'proj': 'utm', 'ellps': 'WGS84', 'zone': 13,
52        'no_defs': True, 'foo': True, 'axis': False, 'belgium': [1, 2]}
53    assert crs.to_string(
54        val) == "+ellps=WGS84 +no_defs +proj=utm +zone=13"
55
56
57def test_to_string_epsg():
58    val = {'init': 'epsg:4326', 'no_defs': True}
59    assert crs.to_string(val) == "+init=epsg:4326 +no_defs"
60
61
62def test_to_string_zeroval():
63    # Make a string with some 0 values (e.g. esri:102017)
64    val = {'proj': 'laea', 'lat_0': 90, 'lon_0': 0, 'x_0': 0, 'y_0': 0,
65           'ellps': 'WGS84', 'datum': 'WGS84', 'units': 'm', 'no_defs': True}
66    assert crs.to_string(val) == (
67        "+datum=WGS84 +ellps=WGS84 +lat_0=90 +lon_0=0 +no_defs +proj=laea "
68        "+units=m +x_0=0 +y_0=0")
69
70
71def test_from_epsg():
72    val = crs.from_epsg(4326)
73    assert val['init'] == "epsg:4326"
74    assert val['no_defs']
75
76
77def test_from_epsg_neg():
78    try:
79        crs.from_epsg(-1)
80    except ValueError:
81        pass
82    except:
83        raise
84
85
86def test_to_string_unicode():
87    # See issue #83.
88    val = crs.to_string({
89        u'units': u'm',
90        u'no_defs': True,
91        u'datum': u'NAD83',
92        u'proj': u'utm',
93        u'zone': 16})
94    assert 'NAD83' in val
95
96
97@requires_gdal_lt_3
98def test_wktext():
99    """Test +wktext parameter is preserved."""
100    proj4 = ('+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 '
101             '+x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext '
102             '+no_defs')
103    assert 'wktext' in crs.from_string(proj4)
104
105
106def test_towgs84():
107    """+towgs84 is preserved"""
108    proj4 = ('+proj=lcc +lat_1=49 +lat_2=46 +lat_0=47.5 '
109             '+lon_0=13.33333333333333 +x_0=400000 +y_0=400000 +ellps=bessel '
110             '+towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 '
111             '+units=m +wktext +no_defs')
112    assert 'towgs84' in crs.from_string(proj4)
113
114
115@requires_gdal_lt_3
116def test_towgs84_wkt():
117    """+towgs84 +wktext are preserved in WKT"""
118    proj4 = ('+proj=lcc +lat_1=49 +lat_2=46 +lat_0=47.5 '
119             '+lon_0=13.33333333333333 +x_0=400000 +y_0=400000 +ellps=bessel '
120             '+towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 '
121             '+units=m +wktext +no_defs')
122    wkt = _crs.crs_to_wkt(proj4)
123    assert 'towgs84' in wkt
124    assert 'wktext' in _crs.crs_to_wkt(proj4)
125
126
127@pytest.mark.parametrize("invalid_input", [
128    "a random string that is invalid",
129    ("a", "tuple"),
130    "-48567=409 =2095"
131])
132def test_invalid_crs(invalid_input):
133    with pytest.raises(CRSError):
134        _crs.crs_to_wkt(invalid_input)
135