File: test_shapereader.py

package info (click to toggle)
python-cartopy 0.25.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,152 kB
  • sloc: python: 16,526; makefile: 159; javascript: 66
file content (138 lines) | stat: -rw-r--r-- 6,076 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Copyright Crown and Cartopy Contributors
#
# This file is part of Cartopy and is released under the BSD 3-clause license.
# See LICENSE in the root of the repository for full licensing details.
from pathlib import Path

import numpy as np
from numpy.testing import assert_array_almost_equal
import pytest
import shapely.geometry as sgeom

import cartopy.io.shapereader as shp


class TestLakes:
    @pytest.fixture(autouse=True, params=[0, 1])
    def setup_class(self, request):
        LAKES_PATH = (Path(__file__).parent / 'lakes_shapefile'
                      / 'ne_110m_lakes.shp')
        # run tests with both available Readers
        if request.param == 0:
            self.reader = shp.BasicReader(LAKES_PATH)
        elif not shp._HAS_FIONA:
            pytest.skip("Fiona library not available")
        else:
            self.reader = shp.FionaReader(LAKES_PATH)
        names = [record.attributes['name'] for record in self.reader.records()]
        # Choose a nice small lake
        self.lake_name = 'Lago de\rNicaragua'
        self.lake_index = names.index(self.lake_name)
        self.test_lake_geometry = \
            list(self.reader.geometries())[self.lake_index]
        self.test_lake_record = list(self.reader.records())[self.lake_index]

    def test_geometry(self):
        lake_geometry = self.test_lake_geometry
        assert lake_geometry.geom_type == 'Polygon'

        # force an orientation due to potential reader differences
        # with pyshp 2.2.0 forcing a specific orientation.
        polygon = sgeom.polygon.orient(lake_geometry, -1)

        expected = np.array([(-84.85548682324658, 11.147898667846633),
                             (-85.29013729525353, 11.176165676310276),
                             (-85.79132117383625, 11.509737046754324),
                             (-85.8851655748783, 11.900100816287136),
                             (-85.5653401354239, 11.940330918826362),
                             (-85.03684526237491, 11.5216484643976),
                             (-84.85548682324658, 11.147898667846633),
                             (-84.85548682324658, 11.147898667846633)])

        assert_array_almost_equal(expected, polygon.exterior.coords)

        assert len(polygon.interiors) == 0

    def test_record(self):
        lake_record = self.test_lake_record
        assert lake_record.attributes.get('name') == self.lake_name
        expected = sorted(['admin', 'featurecla', 'min_label', 'min_zoom',
                           'name', 'name_alt', 'scalerank'])
        actual = sorted(lake_record.attributes.keys())
        assert actual == expected
        assert lake_record.geometry == self.test_lake_geometry

    def test_no_included_projection_file(self):
        # No .prj file included with the lakes shapefile
        assert self.reader.crs is None

    def test_bounds(self):
        if isinstance(self.reader, shp.BasicReader):
            # tests that a file which has a record with a bbox can
            # use the bbox without first creating the geometry
            record = next(self.reader.records())
            assert not record._geometry, \
                'The geometry was loaded before it was needed.'
            assert len(record._bounds) == 4
            assert record._bounds == record.bounds
            assert not record._geometry, \
                'The geometry was loaded in order to create the bounds.'
        else:
            pytest.skip("Fiona reader doesn't support lazy loading")


@pytest.mark.filterwarnings("ignore:Downloading")
@pytest.mark.natural_earth
class TestRivers:
    def setup_class(self):
        RIVERS_PATH = shp.natural_earth(resolution='110m',
                                        category='physical',
                                        name='rivers_lake_centerlines')
        self.reader = shp.Reader(RIVERS_PATH)
        names = [record.attributes['name'] for record in self.reader.records()]
        # Choose a nice small river
        self.river_name = 'Peace'
        self.river_index = names.index(self.river_name)
        self.test_river_geometry = \
            list(self.reader.geometries())[self.river_index]
        self.test_river_record = list(self.reader.records())[self.river_index]

    def test_geometry(self):
        geometry = self.test_river_geometry
        assert geometry.geom_type == 'LineString'

        linestring = geometry
        coords = linestring.coords
        assert round(abs(coords[0][0] - -124.83563045947423), 7) == 0
        assert round(abs(coords[0][1] - 56.75692352968272), 7) == 0
        assert round(abs(coords[1][0] - -124.20045039940291), 7) == 0
        assert round(abs(coords[1][1] - 56.243492336646824), 7) == 0

    def test_record(self):
        records = list(self.reader.records())
        assert len(records) == len(self.reader)

        # Choose a nice small lake
        river_record = records[self.river_index]
        expected_attributes = {'featurecla': 'River',
                               'min_label': 3.1,
                               'min_zoom': 2.1,
                               'name': self.river_name,
                               'name_en': self.river_name,
                               'scalerank': 2}
        for key, value in river_record.attributes.items():
            if key in expected_attributes:
                assert value == expected_attributes[key]
        assert river_record.geometry == self.test_river_geometry

    def test_included_projection_file(self):
        # This shapefile includes a .prj definition
        wkt = ('GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",'
            'ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],'
            'ID["EPSG",6326]],PRIMEM["Greenwich",0,'
            'ANGLEUNIT["Degree",0.0174532925199433]],CS[ellipsoidal,2],'
            'AXIS["longitude",east,ORDER[1],'
            'ANGLEUNIT["Degree",0.0174532925199433]],'
            'AXIS["latitude",north,ORDER[2],'
            'ANGLEUNIT["Degree",0.0174532925199433]]]')
        assert self.reader.crs.to_wkt() == wkt