def test_update_crs(self): geoms,properties = self.get_2d_state_boundaries() crs = CoordinateReferenceSystem(epsg=4326) spdim = SpatialGeometryPolygonDimension(value=geoms) sdim = SpatialDimension(geom=SpatialGeometryDimension(polygon=spdim),properties=properties, crs=crs) to_crs = CoordinateReferenceSystem(epsg=2163) sdim.update_crs(to_crs)
def test_get_wrapped_state(self): refv = WrappableCoordinateReferenceSystem refm = refv.get_wrapped_state ## test grid ## row = VectorDimension(value=[50, 60]) col = VectorDimension(value=[0, 90, 180]) grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) self.assertEqual(refm(sdim), refv._flag_unknown) col = VectorDimension(value=[-170, 0, 30]) grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) self.assertEqual(refm(sdim), refv._flag_wrapped) col = VectorDimension(value=[0, 90, 180, 270]) grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) self.assertEqual(refm(sdim), refv._flag_unwrapped) ## test geom ## for with_polygon in [True, False]: row = VectorDimension(value=[50, 60]) col = VectorDimension(value=[155, 165, 175]) if with_polygon: row.set_extrapolated_bounds() col.set_extrapolated_bounds() grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) sdim.grid = None self.assertEqual(refm(sdim), refv._flag_unknown) row = VectorDimension(value=[50, 60]) col = VectorDimension(value=[160, 170, 180]) if with_polygon: row.set_extrapolated_bounds() col.set_extrapolated_bounds() grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) sdim.grid = None if with_polygon: actual = refv._flag_unwrapped else: actual = refv._flag_unknown self.assertEqual(refm(sdim), actual) row = VectorDimension(value=[50, 60]) col = VectorDimension(value=[-160, -150, -140]) if with_polygon: row.set_extrapolated_bounds() col.set_extrapolated_bounds() grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid) sdim.grid = None self.assertEqual(refm(sdim), refv._flag_wrapped)
def test_wrap_360_cross_axis(self): row = VectorDimension(value=40,bounds=[38,42]) col = VectorDimension(value=180,bounds=[179,181]) grid = SpatialGridDimension(row=row,col=col) sdim = SpatialDimension(grid=grid,crs=WGS84()) orig_sdim = deepcopy(sdim) sdim.crs.wrap(sdim) self.assertIsInstance(sdim.geom.polygon.value[0,0],MultiPolygon) sdim.crs.unwrap(sdim) self.assertEqual(orig_sdim.geom.polygon.value[0,0].bounds,sdim.geom.polygon.value[0,0].bounds) for target in ['point','polygon']: path = get_temp_path(name=target,suffix='.shp',wd=self._test_dir) sdim.write_fiona(path,target)
def test_get_buffered_subset_sdim(self): proj4 = '+proj=aea +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs' buffer_crs_list = [None, CoordinateReferenceSystem(proj4=proj4)] poly = make_poly((36, 44), (-104, -95)) for buffer_crs in buffer_crs_list: subset_sdim = SpatialDimension.from_records([{'geom': poly, 'properties': {'UGID': 1}}], crs=CFWGS84()) self.assertEqual(subset_sdim.crs, CFWGS84()) if buffer_crs is None: buffer_value = 1 else: buffer_value = 10 ret = SpatialSubsetOperation._get_buffered_subset_sdim_(subset_sdim, buffer_value, buffer_crs=buffer_crs) ref = ret.geom.polygon.value[0, 0] if buffer_crs is None: self.assertEqual(ref.bounds, (-105.0, 35.0, -94.0, 45.0)) else: self.assertNumpyAllClose(np.array(ref.bounds), np.array((-104.00013263459613, 35.9999147913708, -94.99986736540386, 44.00008450528758))) self.assertEqual(subset_sdim.crs, ret.crs) # check deepcopy ret.geom.polygon.value[0, 0] = make_poly((1, 2), (3, 4)) ref_buffered = ret.geom.polygon.value[0, 0] ref_original = subset_sdim.geom.polygon.value[0, 0] with self.assertRaises(AssertionError): self.assertNumpyAllClose(np.array(ref_buffered.bounds), np.array(ref_original.bounds))
def test_wrap_360(self): row = VectorDimension(value=40.,bounds=[38.,42.]) col = VectorDimension(value=181.5,bounds=[181.,182.]) grid = SpatialGridDimension(row=row,col=col) self.assertEqual(grid.value[1,0,0],181.5) sdim = SpatialDimension(grid=grid,crs=WGS84()) orig_sdim = deepcopy(sdim) orig_grid = deepcopy(sdim.grid) sdim.crs.wrap(sdim) self.assertNumpyAll(np.array(sdim.geom.point.value[0,0]),np.array([-178.5,40.])) self.assertEqual(sdim.geom.polygon.value[0,0].bounds,(-179.0,38.0,-178.0,42.0)) self.assertNumpyNotAll(orig_grid.value,sdim.grid.value) sdim.crs.unwrap(sdim) to_test = ([sdim.grid.value,orig_sdim.grid.value],[sdim.get_grid_bounds(),orig_sdim.get_grid_bounds()]) for tt in to_test: self.assertNumpyAll(*tt)
def iter_geoms(self, key=None, select_uid=None, path=None, load_geoms=True, as_spatial_dimension=False, uid=None, select_sql_where=None): """ See documentation for :class:`~ocgis.util.shp_cabinet.ShpCabinetIterator`. """ # ensure select ugid is in ascending order if select_uid is not None: test_select_ugid = list(deepcopy(select_uid)) test_select_ugid.sort() if test_select_ugid != list(select_uid): raise ValueError('"select_uid" must be sorted in ascending order.') # get the path to the output shapefile shp_path = self._get_path_by_key_or_direct_path_(key=key, path=path) # get the source CRS meta = self.get_meta(path=shp_path) # open the target shapefile ds = ogr.Open(shp_path) try: # return the features iterator features = self._get_features_object_(ds, uid=uid, select_uid=select_uid, select_sql_where=select_sql_where) build = True for ctr, feature in enumerate(features): if load_geoms: yld = {'geom': wkb.loads(feature.geometry().ExportToWkb())} else: yld = {} items = feature.items() properties = OrderedDict([(key, items[key]) for key in feature.keys()]) yld.update({'properties': properties, 'meta': meta}) if build: uid, add_uid = get_uid_from_properties(properties, uid) build = False # add the unique identifier if required if add_uid: properties[uid] = ctr + 1 # ensure the unique identifier is an integer else: properties[uid] = int(properties[uid]) if as_spatial_dimension: yld = SpatialDimension.from_records([yld], crs=yld['meta']['crs'], uid=uid) yield yld try: assert ctr >= 0 except UnboundLocalError: # occurs if there were not feature returned by the iterator. raise a more clear exception. msg = 'No features returned from target shapefile. Were features appropriately selected?' raise ValueError(msg) finally: # close the dataset object ds.Destroy() ds = None
def test_grid_value(self): for b in [True,False]: row = self.get_row(bounds=b) col = self.get_col(bounds=b) sdim = SpatialDimension(row=row,col=col) col_test,row_test = np.meshgrid(col.value,row.value) self.assertNumpyAll(sdim.grid.value[0].data,row_test) self.assertNumpyAll(sdim.grid.value[1].data,col_test) self.assertFalse(sdim.grid.value.mask.any()) try: ret = sdim.get_grid_bounds() self.assertEqual(ret.shape,(3,4,4)) self.assertFalse(ret.mask.any()) except ImproperPolygonBoundsError: if b is False: pass else: raise
def test_get_spatial_subset_rotated_pole(self): """Test input has rotated pole with now output CRS.""" rd = self.rd_rotated_pole ss = SpatialSubsetOperation(rd) subset_sdim = SpatialDimension.from_records([self.germany]) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertEqual(ret.spatial.crs, rd.get().spatial.crs) self.assertAlmostEqual(ret.spatial.grid.value.data.mean(), -2.0600000000000009)
def parse(self, value): if type(value) in [list, tuple]: if all([isinstance(element, dict) for element in value]): for ii, element in enumerate(value, start=1): if 'geom' not in element: ocgis_lh(exc=DefinitionValidationError(self, 'Geometry dictionaries must have a "geom" key.')) if 'properties' not in element: element['properties'] = {self._ugid_key: ii} crs = element.get('crs', CFWGS84()) if 'crs' not in element: ocgis_lh(msg='No CRS in geometry dictionary - assuming WGS84.', level=logging.WARN) ret = SpatialDimension.from_records(value, crs=crs, uid=self.geom_uid) else: if len(value) == 2: geom = Point(value[0], value[1]) elif len(value) == 4: minx, miny, maxx, maxy = value geom = Polygon(((minx, miny), (minx, maxy), (maxx, maxy), (maxx, miny))) if not geom.is_valid: raise DefinitionValidationError(self, 'Parsed geometry is not valid.') ret = [{'geom': geom, 'properties': {self._ugid_key: 1}}] ret = SpatialDimension.from_records(ret, crs=CFWGS84(), uid=self.geom_uid) self._bounds = geom.bounds elif isinstance(value, GeomCabinetIterator): self._shp_key = value.key or value.path # always want to yield SpatialDimension objects value.as_spatial_dimension = True ret = value elif isinstance(value, BaseGeometry): ret = [{'geom': value, 'properties': {self._ugid_key: 1}}] ret = SpatialDimension.from_records(ret, crs=CFWGS84(), uid=self.geom_uid) elif value is None: ret = value elif isinstance(value, SpatialDimension): ret = value else: raise NotImplementedError(type(value)) # convert to a tuple if this is a SpatialDimension object if isinstance(ret, SpatialDimension): ret = tuple(self._iter_spatial_dimension_tuple_(ret)) return ret
def test_spatial_dimension(self): """Test using a SpatialDimension as input value.""" sdim = SpatialDimension.from_records(GeomCabinetIterator(key='state_boundaries')) self.assertIsInstance(sdim.crs, CFWGS84) g = Geom(sdim) self.assertEqual(len(g.value), 51) for sdim in g.value: self.assertIsInstance(sdim, SpatialDimension) self.assertEqual(sdim.shape, (1, 1))
def test_get_spatial_subset_output_crs(self): """Test subsetting with an output CRS.""" # test with default crs converting to north american lambert proj4 = '+proj=aea +lat_1=20 +lat_2=60 +lat_0=40 +lon_0=-96 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs' output_crs = CoordinateReferenceSystem(proj4=proj4) subset_sdim = SpatialDimension.from_records([self.nebraska]) rd = self.test_data.get_rd('cancm4_tas') ss = SpatialSubsetOperation(rd, output_crs=output_crs) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertEqual(ret.spatial.crs, output_crs) self.assertAlmostEqual(ret.spatial.grid.value.mean(), -35065.750850951554) # test with an input rotated pole coordinate system rd = self.rd_rotated_pole ss = SpatialSubsetOperation(rd, output_crs=env.DEFAULT_COORDSYS) subset_sdim = SpatialDimension.from_records([self.germany]) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertEqual(ret.spatial.crs, env.DEFAULT_COORDSYS)
def test_write(self): records = [{'geom': Point(1, 2).buffer(1), 'properties': {'ID': 5, 'name': 'heaven'}}, {'geom': Point(7, 8).buffer(1), 'properties': {'ID': 50, 'name': 'hell'}}] sdim1 = SpatialDimension.from_records([records[0]], uid='ID') sdim2 = SpatialDimension.from_records([records[1]], uid='ID') field = self.get_field(crs=WGS84()) coll1 = SpatialCollection() coll1.add_field(field, ugeom=sdim1) coll2 = SpatialCollection() coll2.add_field(field, ugeom=sdim2) colls = [coll1, coll2] f = FakeAbstractCollectionConverter(colls, outdir=self.current_dir_output, prefix='me') ret = f.write() path = os.path.join(ret, 'shp', 'me_ugid.shp') with fiona.open(path, 'r') as source: records = list(source) self.assertEqual(len(records), 2) self.assertEqual([r['properties']['ID'] for r in records], [5, 50]) self.assertEqual([r['properties']['name'] for r in records], ['heaven', 'hell'])
def test_get_spatial_subset_circular_geometries(self): """Test circular geometries. They were causing wrapping errors.""" geoms = TestGeom.get_geometry_dictionaries() rd = self.test_data.get_rd('cancm4_tas') ss = SpatialSubsetOperation(rd, wrap=True) buffered = [element['geom'].buffer(rd.get().spatial.grid.resolution*2) for element in geoms] for buff in buffered: record = [{'geom': buff, 'properties': {'UGID': 1}}] subset_sdim = SpatialDimension.from_records(record) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertTrue(np.all(ret.spatial.grid.extent > 0))
def get_subset_sdim(self): # 1: nebraska nebraska = self.nebraska # 2: germany germany = self.germany # 3: nebraska and germany ret = [SpatialDimension.from_records(d) for d in [[nebraska], [germany], [nebraska, germany]]] return ret
def test_get_spatial_subset_wrap(self): """Test subsetting with wrap set to a boolean value.""" subset_sdim = SpatialDimension.from_records([self.nebraska]) rd = self.test_data.get_rd('cancm4_tas') self.assertEqual(rd.get().spatial.wrapped_state, WrappableCoordinateReferenceSystem._flag_unwrapped) ss = SpatialSubsetOperation(rd, wrap=True) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertEqual(ret.spatial.wrapped_state, WrappableCoordinateReferenceSystem._flag_wrapped) self.assertAlmostEqual(ret.spatial.grid.value.data[1].mean(), -99.84375) # test with wrap false ss = SpatialSubsetOperation(rd, wrap=False) ret = ss.get_spatial_subset('intersects', subset_sdim) self.assertEqual(ret.spatial.wrapped_state, WrappableCoordinateReferenceSystem._flag_unwrapped) self.assertAlmostEqual(ret.spatial.grid.value.data[1].mean(), 260.15625)
def test_prepare_subset_sdim(self): for subset_sdim in self.get_subset_sdim(): for ss, k in self: try: prepared = ss._prepare_subset_sdim_(subset_sdim) # check that a deepcopy has occurred self.assertFalse(np.may_share_memory(prepared.uid, subset_sdim.uid)) except KeyError: # the target has a rotated pole coordinate system. transformations to rotated pole for the subset # geometry is not supported. if isinstance(ss.sdim.crs, CFRotatedPole): continue else: raise self.assertEqual(prepared.crs, ss.sdim.crs) # test nebraska against an unwrapped dataset specifically nebraska = SpatialDimension.from_records([self.nebraska]) field = self.test_data.get_rd('cancm4_tas').get() ss = SpatialSubsetOperation(field) prepared = ss._prepare_subset_sdim_(nebraska) self.assertEqual(prepared.wrapped_state, WrappableCoordinateReferenceSystem._flag_unwrapped)
def test_get_ocgis_field_from_esmpy_field(self): np.random.seed(1) temporal = TemporalDimension(value=[3000.0, 4000.0, 5000.0]) level = VectorDimension(value=[10, 20, 30, 40]) realization = VectorDimension(value=[100, 200]) kwds = dict( crs=[None, CoordinateReferenceSystem(epsg=4326), Spherical()], with_mask=[False, True], with_corners=[False, True], dimensions=[False, True], drealization=[False, True], dtemporal=[False, True], dlevel=[False, True], ) for k in self.iter_product_keywords(kwds): row = VectorDimension(value=[1.0, 2.0]) col = VectorDimension(value=[3.0, 4.0]) if k.with_corners: row.set_extrapolated_bounds() col.set_extrapolated_bounds() value_tmin = np.random.rand(2, 3, 4, 2, 2) tmin = Variable(value=value_tmin, name="tmin") variables = VariableCollection([tmin]) grid = SpatialGridDimension(row=row, col=col) sdim = SpatialDimension(grid=grid, crs=k.crs) field = Field(variables=variables, spatial=sdim, temporal=temporal, level=level, realization=realization) if k.with_mask: mask = np.zeros(value_tmin.shape[-2:], dtype=bool) mask[0, 1] = True set_new_value_mask_for_field(field, mask) sdim.set_mask(mask) self.assertTrue(tmin.value.mask.any()) self.assertTrue(sdim.get_mask().any()) else: self.assertFalse(tmin.value.mask.any()) self.assertFalse(sdim.get_mask().any()) coll = SpatialCollection() coll[1] = {field.name: field} conv = ESMPyConverter([coll]) efield = conv.write() if k.dimensions: dimensions = {} if k.drealization: dimensions["realization"] = realization if k.dtemporal: dimensions["temporal"] = temporal if k.dlevel: dimensions["level"] = level else: dimensions = None ofield = get_ocgis_field_from_esmf_field(efield, crs=k.crs, dimensions=dimensions) self.assertIsInstance(ofield, Field) self.assertEqual(ofield.shape, efield.data.shape) # Test a default CRS is applied for the spherical case. if k.crs is None: self.assertEqual(ofield.spatial.crs, Spherical()) if k.drealization and k.dimensions: target = realization.value else: target = np.array([1, 2]) self.assertNumpyAll(ofield.realization.value, target) if k.dtemporal and k.dimensions: target = temporal.value else: target = np.array([1, 1, 1]) with self.assertRaises(CannotFormatTimeError): ofield.temporal.value_datetime self.assertFalse(ofield.temporal.format_time) self.assertNumpyAll(ofield.temporal.value, target) if k.dlevel and k.dimensions: target = level.value else: target = np.array([1, 2, 3, 4]) self.assertNumpyAll(ofield.level.value, target) self.assertNumpyAll(field.spatial.grid.value, ofield.spatial.grid.value) if k.with_corners: self.assertIsNotNone(ofield.spatial.grid.corners) self.assertNumpyAll(field.spatial.grid.corners, ofield.spatial.grid.corners) try: self.assertEqual(ofield.spatial.crs, sdim.crs) except AssertionError: # A "None" "crs" argument results in a default coordinate system applied to the output OCGIS field. self.assertIsNone(k.crs) ofield_tmin_value = ofield.variables[efield.name].value for arr1, arr2 in itertools.combinations([tmin.value.data, efield.data, ofield_tmin_value.data], r=2): self.assertNumpyAll(arr1, arr2, check_arr_type=False) rows = list(ofield.get_iter()) try: self.assertEqual(len(rows), len(value_tmin.flatten())) except AssertionError: self.assertTrue(k.with_mask) self.assertEqual(len(rows), len(tmin.value.compressed())) self.assertTrue(np.may_share_memory(ofield_tmin_value, efield.data)) self.assertFalse(np.may_share_memory(ofield_tmin_value, tmin.value))
def test_get_iter(self): field = self.get_field(with_value=True) rows = list(field.get_iter()) self.assertEqual(len(rows), 2 * 31 * 2 * 3 * 4) self.assertEqual(len(rows[0]), 2) self.assertEqual(rows[100][0].bounds, (-100.5, 38.5, -99.5, 39.5)) real = {'vid': 1, 'ub_time': datetime.datetime(2000, 1, 6, 0, 0), 'year': 2000, 'gid': 5, 'ub_level': 100, 'rid': 1, 'realization': 1, 'lb_level': 0, 'variable': 'tmax', 'month': 1, 'lb_time': datetime.datetime(2000, 1, 5, 0, 0), 'day': 5, 'level': 50, 'did': None, 'value': 0.32664490177209615, 'alias': 'tmax', 'lid': 1, 'time': datetime.datetime(2000, 1, 5, 12, 0), 'tid': 5, 'name': 'tmax', 'ugid': 1} self.assertAsSetEqual(rows[100][1].keys(), real.keys()) for k, v in rows[100][1].iteritems(): self.assertEqual(real[k], v) self.assertEqual(set(field.variables['tmax'].value.flatten().tolist()), set([r[1]['value'] for r in rows])) # Test without names. field = self.get_field(with_value=True, with_dimension_names=False) rows = list(field.get_iter()) self.assertAsSetEqual(rows[10][1].keys(), ['lid', 'name', 'vid', 'ub_time', 'did', 'lb_level', 'time', 'year', 'value', 'month', 'alias', 'tid', 'ub_level', 'rlz', 'variable', 'gid', 'rid', 'level', 'lb_time', 'day', 'ugid']) # Test not melted. field = self.get_field(with_value=True) other_variable = deepcopy(field.variables.first()) other_variable.alias = 'two' other_variable.value *= 2 field.variables.add_variable(other_variable, assign_new_uid=True) rows = list(field.get_iter(melted=False)) self.assertEqual(len(rows), 1488) for row in rows: attrs = row[1] # Test variable aliases are in the row dictionaries. for variable in field.variables.itervalues(): self.assertIn(variable.alias, attrs) # Test for upper keys. field = self.get_field(with_value=True)[0, 0, 0, 0, 0] for row in field.get_iter(use_upper_keys=True): for key in row[1].keys(): self.assertTrue(key.isupper()) # Test passing limiting headers. field = self.get_field(with_value=True) headers = ['time', 'tid'] for _, row in field.get_iter(headers=headers): self.assertEqual(row.keys(), headers) # Test passing a selection geometry identifier. field = self.get_field(with_value=True)[0, 0, 0, 0, 0] record = {'geom': Point(1, 2), 'properties': {'HI': 50, 'goodbye': 'forever'}} ugeom = SpatialDimension.from_records([record], uid='HI') _, row = field.get_iter(ugeom=ugeom).next() self.assertEqual(row['HI'], 50) # Test value keys. field = self.get_field(with_value=True)[0, 0, 0, 0, 0] fill = np.ma.array(np.zeros(2, dtype=[('a', float), ('b', float)])) value = np.ma.array(np.zeros(field.shape, dtype=object), mask=False) value.data[0, 0, 0, 0, 0] = fill field.variables['tmax']._value = value value_keys = ['a', 'b'] _, row = field.get_iter(value_keys=value_keys, melted=True) for vk in value_keys: self.assertIn(vk, row[1])
def test_write_fiona(self): keywords = dict(with_realization=[True, False], with_level=[True, False], with_temporal=[True, False], driver=['ESRI Shapefile', 'GeoJSON'], melted=[False, True]) for ii, k in enumerate(self.iter_product_keywords(keywords)): path = os.path.join(self.current_dir_output, '{0}'.format(ii)) field = self.get_field(with_value=True, crs=WGS84(), with_dimension_names=False, with_realization=k.with_realization, with_level=k.with_level, with_temporal=k.with_temporal) newvar = deepcopy(field.variables.first()) newvar.alias = 'newvar' newvar.value += 10 field.variables.add_variable(newvar, assign_new_uid=True) field = field[:, 0:2, :, 0:2, 0:2] field.write_fiona(path, driver=k.driver, melted=k.melted) with fiona.open(path) as source: records = list(source) if k.melted: dd = {a: [] for a in field.variables.keys()} for r in records: dd[r['properties']['alias']].append(r['properties']['value']) for kk, v in dd.iteritems(): self.assertAlmostEqual(np.mean(v), field.variables[kk].value.mean(), places=6) else: for alias in field.variables.keys(): values = [r['properties'][alias] for r in records] self.assertAlmostEqual(np.mean(values), field.variables[alias].value.mean(), places=6) n = reduce(lambda x, y: x * y, field.shape) if k.melted: n *= len(field.variables) self.assertEqual(n, len(records)) # test with a point abstraction field = self.get_field(with_value=True, crs=WGS84()) field = field[0, 0, 0, 0, 0] field.spatial.abstraction = 'point' path = self.get_temporary_file_path('foo.shp') field.write_fiona(path) with fiona.open(path) as source: gtype = source.meta['schema']['geometry'] self.assertEqual(gtype, 'Point') # test with a fake object passed in as a fiona object. this should raise an exception as the method will attempt # to use the object instead of creating a new collection. the object should not be closed when done. class DontHateMe(Exception): pass class WriteMe(Exception): pass class Nothing(object): def close(self): raise DontHateMe() def write(self, *args, **kwargs): raise WriteMe() with self.assertRaises(WriteMe): field.write_fiona(path, fobject=Nothing()) # Test all geometries are accounted for as well as properties. path = os.path.join(self.path_bin, 'shp', 'state_boundaries', 'state_boundaries.shp') rd = RequestDataset(path) field = rd.get() out = self.get_temporary_file_path('foo.shp') field.write_fiona(out) with fiona.open(out, 'r') as source: for record in source: target = shape(record['geometry']) self.assertEqual(record['properties'].keys(), [u'UGID', u'STATE_FIPS', u'ID', u'STATE_NAME', u'STATE_ABBR']) found = False for geom in field.spatial.abstraction_geometry.value.flat: if target.almost_equals(geom): found = True break self.assertTrue(found) # Test with upper keys. field = self.get_field(with_value=True, crs=WGS84())[0, 0, 0, 0, 0] path = self.get_temporary_file_path('what.shp') field.write_fiona(path=path, use_upper_keys=True) with fiona.open(path) as source: for row in source: for key in row['properties']: self.assertTrue(key.isupper()) # test with upper keys field = self.get_field(with_value=True, crs=WGS84())[0, 0, 0, 0, 0] path = self.get_temporary_file_path('what2.shp') headers = ['time', 'tid'] field.write_fiona(path=path, headers=headers) with fiona.open(path) as source: self.assertEqual(source.meta['schema']['properties'].keys(), headers) # test passing a ugid field = self.get_field(with_value=True, crs=WGS84())[0, 0, 0, 0, 0] path = self.get_temporary_file_path('what3.shp') record = {'geom': Point(1, 2), 'properties': {'ugid': 10}} ugeom = SpatialDimension.from_records([record], uid='ugid') field.write_fiona(path=path, ugeom=ugeom) with fiona.open(path) as source: for row in source: self.assertEqual(row['properties'][constants.HEADERS.ID_SELECTION_GEOMETRY], 10)