Example #1
0
 def test_write_to_rootgrp(self):
     crs = CoordinateReferenceSystem(epsg=4326, name='hello_world')
     path = os.path.join(self.current_dir_output, 'foo.nc')
     with nc_scope(path, 'w') as ds:
         variable = crs.write_to_rootgrp(ds)
         self.assertIsInstance(variable, nc.Variable)
         with self.assertRaises(AttributeError):
             variable.proj4
Example #2
0
    def test_ne(self):
        crs1 = CoordinateReferenceSystem(epsg=4326)
        crs2 = CoordinateReferenceSystem(epsg=2136)

        self.assertNotEqual(crs1, crs2)
        self.assertNotEqual(crs2, crs1)
        self.assertNotEqual(crs1, None)
        self.assertNotEqual(None, crs1)

        self.assertNotEqual(None, crs1)
        self.assertNotEqual('input', crs1)
Example #3
0
 def get_crs(self, group_metadata):
     crs = group_metadata['crs']
     if len(crs) == 0:
         ret = None
     else:
         ret = CoordinateReferenceSystem(value=crs)
     return ret
Example #4
0
    def test_system_process_geometries(self):
        """Test multiple geometries with coordinate system update."""

        a = 'POLYGON((-105.21347987288135073 40.21514830508475313,-104.39928495762711691 40.21514830508475313,-104.3192002118643984 39.5677966101694949,-102.37047139830508513 39.61451271186440692,-102.12354343220337682 37.51896186440677639,-105.16009004237288593 37.51896186440677639,-105.21347987288135073 40.21514830508475313))'
        b = 'POLYGON((-104.15235699152542281 39.02722457627118757,-103.71189088983049942 39.44099576271186436,-102.71750529661017026 39.28082627118644155,-102.35712394067796538 37.63908898305084705,-104.13900953389830306 37.63241525423728717,-104.15235699152542281 39.02722457627118757))'
        geom = [{'geom': wkt.loads(xx), 'properties': {'UGID': ugid}} for ugid, xx in enumerate([a, b])]

        grid_value = [
            [[37.0, 37.0, 37.0, 37.0], [38.0, 38.0, 38.0, 38.0], [39.0, 39.0, 39.0, 39.0], [40.0, 40.0, 40.0, 40.0]],
            [[-105.0, -104.0, -103.0, -102.0], [-105.0, -104.0, -103.0, -102.0], [-105.0, -104.0, -103.0, -102.0],
             [-105.0, -104.0, -103.0, -102.0]]]
        output_crs = CoordinateReferenceSystem(
            value={'a': 6370997, 'lon_0': -100, 'y_0': 0, 'no_defs': True, 'proj': 'laea', 'x_0': 0, 'units': 'm',
                   'b': 6370997, 'lat_0': 45})

        x = Variable('x', grid_value[1], dimensions=['lat', 'lon'])
        y = Variable('y', grid_value[0], dimensions=['lat', 'lon'])
        grid = Grid(x, y)
        field = Field(grid=grid, crs=Spherical())

        ops = OcgOperations(dataset=field, geom=geom, output_crs=output_crs)
        ret = ops.execute()

        expected = {0: -502052.79407259845,
                    1: -510391.37909706926}
        for field, container in ret.iter_fields(yield_container=True):
            self.assertAlmostEqual(field.grid.get_value_stacked().mean(),
                                   expected[container.geom.ugid.get_value()[0]])
Example #5
0
    def test_update_crs(self):
        # Test copying allows the CRS to be updated on the copy w/out changing the source CRS.
        desired = Spherical()
        gvar = GeometryVariable(value=[Point(1, 2)], name='geom', dimensions='geom')
        field = Field(crs=desired, geom=gvar)
        cfield = field.copy()
        self.assertEqual(cfield.crs, desired)
        new_crs = CoordinateReferenceSystem(name='i_am_new', epsg=4326)
        cfield.update_crs(new_crs)
        self.assertEqual(field.crs, desired)

        # Test geometry crs update is called.
        mfield = Mock(Field)
        mfield.is_empty = False
        mfield.dimension_map = Mock(DimensionMap)
        mfield.grid = Mock(Grid)
        mfield.geom = Mock(GeometryVariable)
        mcrs = Mock(Spherical)
        Field.update_crs(mfield, mcrs)
        mfield.grid.update_crs.assert_called_once_with(mcrs, from_crs=mfield.crs)
        mfield.geom.update_crs.assert_called_once_with(mcrs, from_crs=mfield.crs)
        from_crs = Mock(WGS84)
        mfield.grid.update_crs.reset_mock()
        mfield.geom.update_crs.reset_mock()
        Field.update_crs(mfield, mcrs, from_crs=from_crs)
        mfield.grid.update_crs.assert_called_once_with(mcrs, from_crs=from_crs)
        mfield.geom.update_crs.assert_called_once_with(mcrs, from_crs=from_crs)
Example #6
0
    def test_eq(self):
        value_lhs = {
            'a': 6370997,
            'b': 6370997,
            'no_defs': True,
            'proj': 'longlat',
            'wktext': True,
            'towgs84': '0,0,0,0,0,0,0'
        }
        lhs = CoordinateReferenceSystem(value=value_lhs)

        value_rhs = value_lhs.copy()
        value_rhs.pop('wktext')
        rhs = CoordinateReferenceSystem(value=value_rhs)

        self.assertEqual(lhs, rhs)
Example #7
0
    def test_system_properties(self):
        """Test field properties."""

        time = TemporalVariable(value=[20, 30, 40], dimensions=['the_time'], dtype=float, name='time')
        time_bounds = TemporalVariable(value=[[15, 25], [25, 35], [35, 45]], dimensions=['times', 'bounds'],
                                       dtype=float, name='time_bounds')
        other = Variable(value=[44, 55, 66], name='other', dimensions=['times_again'])
        x = Variable(value=[1, 2, 3], name='xc', dimensions=['x'])
        y = Variable(value=[10, 20, 30, 40], name='yc', dimensions=['y'])

        crs = CoordinateReferenceSystem(epsg=2136)
        f = self.get_ocgfield(variables=[time, time_bounds, other, x, y])
        f2 = deepcopy(f)

        self.assertIsNone(f.realization)
        self.assertIsNone(f.time)
        f.dimension_map.set_variable('time', time.name)
        self.assertNumpyAll(f.time.get_value(), time.get_value())
        self.assertEqual(f.time.attrs['axis'], 'T')
        self.assertIsNone(f.time.bounds)
        f.dimension_map.set_variable('time', 'time', bounds=time_bounds.name)
        self.assertNumpyAll(f.time.bounds.get_value(), time_bounds.get_value())
        self.assertIn('other', f.time.parent)

        dims = f.dimension_map.get_dimension('time')
        dims += ['times', 'times_again', 'the_time']
        sub = f.get_field_slice({'time': slice(1, 2)})
        desired = OrderedDict([('time', (1,)), ('time_bounds', (1, 2)), ('other', (1,)), ('xc', (3,)), ('yc', (4,))])
        self.assertEqual(sub.shapes, desired)
        self.assertIsNone(sub.grid)
        sub.dimension_map.set_variable('x', 'xc')
        sub.dimension_map.set_variable('y', 'yc')

        # Test writing to netCDF will load attributes.
        path = self.get_temporary_file_path('foo.nc')
        sub.write(path)
        with self.nc_scope(path) as ds:
            self.assertEqual(ds.variables[x.name].axis, 'X')
            self.assertEqual(ds.variables[y.name].axis, 'Y')

        self.assertEqual(sub.x.attrs['axis'], 'X')
        self.assertEqual(sub.y.attrs['axis'], 'Y')
        self.assertIsInstance(sub.grid, Grid)
        desired = OrderedDict([('time', (1,)), ('time_bounds', (1, 2)), ('other', (1,)), ('xc', (3,)), ('yc', (4,))])
        self.assertEqual(sub.shapes, desired)

        # Test a subset.
        bbox = [1.5, 15, 2.5, 35]
        data = Variable(name='data', value=np.random.rand(3, 4), dimensions=['x', 'y'])
        f2.add_variable(data)
        f2.dimension_map.set_variable('x', 'xc')
        f2.dimension_map.set_variable('y', 'yc')
        bbox = box(*bbox)
        spatial_sub = f2.grid.get_intersects(bbox).parent
        desired = OrderedDict([('time', (3,)), ('time_bounds', (3, 2)), ('other', (3,)), ('xc', (1,)), ('yc', (2,)),
                               ('data', (1, 2)), ])
        self.assertEqual(spatial_sub.shapes, desired)
Example #8
0
    def test_crs(self):
        rd = self.get_request_dataset_netcdf(crs=None)
        self.assertIsNone(rd.crs)
        self.assertTrue(rd._has_assigned_coordinate_system)
        self.assertIsNone(rd.get().crs)

        crs = CoordinateReferenceSystem(epsg=2136)
        rd = self.get_request_dataset_netcdf(crs=crs)
        self.assertEqual(rd.crs, crs)
Example #9
0
    def test_regrid_field_differing_crs(self):
        """Test exception raised when source and destination CRS values are not equal."""

        source = self.get_ofield()
        destination = deepcopy(source)
        source.set_crs(CoordinateReferenceSystem(epsg=2136))

        with self.assertRaises(RegriddingError):
            from ocgis.regrid.base import regrid_field
            regrid_field(source, destination)
Example #10
0
    def test_system_spatial_wrapping_and_reorder(self):
        if sys.version_info.major == 3 and sys.version_info.minor == 5:
            raise SkipTest('undefined behavior with Python 3.5')

        keywords = {'spatial_wrapping': list(SpatialWrapping.iter_possible()),
                    'crs': [None, Spherical(), CoordinateReferenceSystem(epsg=2136)],
                    'unwrapped': [True, False],
                    'spatial_reorder': [False, True]}
        for ctr, k in enumerate(self.iter_product_keywords(keywords)):
            field = self.get_wrap_field(crs=k.crs, unwrapped=k.unwrapped)

            ops = OcgOperations(dataset=field, spatial_wrapping=k.spatial_wrapping, spatial_reorder=k.spatial_reorder)
            ret = ops.execute()

            actual_field = ret.get_element()

            with vm.scoped_by_emptyable('wrapped state', actual_field):
                if not vm.is_null:
                    actual = actual_field.wrapped_state
                else:
                    actual = None
            actual_x = actual_field.grid.x.get_value()

            if not actual_field.is_empty:
                self.assertLessEqual(actual_x.max(), 360.)
                if k.spatial_reorder and k.unwrapped and k.spatial_wrapping == 'wrap' and k.crs == Spherical():
                    actual_data_value = actual_field.data_variables[0].get_value()
                    desired_reordered = [None] * actual_data_value.shape[1]
                    for idx in range(actual_data_value.shape[1]):
                        desired_reordered[idx] = [3.0, 4.0, 0.0, 1.0, 2.0]
                    for tidx in range(actual_data_value.shape[0]):
                        time_data_value = actual_data_value[tidx]
                        self.assertEqual(time_data_value.tolist(), desired_reordered)

                if k.spatial_reorder and not k.unwrapped and not k.spatial_wrapping:
                    self.assertTrue(actual_x[0] < actual_x[-1])

            if actual is None or k.crs != Spherical():
                desired = None
            else:
                p = k.spatial_wrapping
                if p is None:
                    if k.unwrapped:
                        desired = WrappedState.UNWRAPPED
                    else:
                        desired = WrappedState.WRAPPED
                elif p == 'wrap':
                    desired = WrappedState.WRAPPED
                else:
                    desired = WrappedState.UNWRAPPED

            self.assertEqual(actual, desired)
Example #11
0
    def test_update_crs(self):
        # Test copying allows the CRS to be updated on the copy w/out changing the source CRS.
        desired = Spherical()
        gvar = GeometryVariable(value=[Point(1, 2)],
                                name='geom',
                                dimensions='geom')
        field = Field(crs=desired, geom=gvar)
        cfield = field.copy()

        self.assertEqual(cfield.crs, desired)
        new_crs = CoordinateReferenceSystem(name='i_am_new', epsg=4326)
        cfield.update_crs(new_crs)
        self.assertEqual(field.crs, desired)
Example #12
0
    def test_system_crs_and_grid_abstraction(self):
        f = Field(grid_abstraction='point')
        grid = self.get_gridxy(with_xy_bounds=True)
        f.add_variable(grid.x)

        crs = CoordinateReferenceSystem(epsg=2136, name='location')
        f.add_variable(crs)
        self.assertIsNone(f.crs)
        f.dimension_map.set_crs(crs)
        f.dimension_map.set_variable('x', grid.x)
        f.dimension_map.set_variable('y', grid.y)
        self.assertEqual(f.grid.crs, crs)

        f.set_geom(f.grid.get_abstraction_geometry())
        self.assertEqual(f.grid.abstraction, 'point')
        self.assertEqual(f.geom.geom_type, 'Point')
Example #13
0
    def test_get_ocgis_grid_from_esmf_grid(self):
        from ocgis.regrid.base import get_esmf_grid
        from ocgis.regrid.base import get_ocgis_grid_from_esmf_grid

        rd = RequestDataset(**self.get_dataset())

        keywords = dict(has_corners=[True, False],
                        has_mask=[True, False],
                        crs=[None, CoordinateReferenceSystem(epsg=4326)])

        for k in itr_products_keywords(keywords, as_namedtuple=True):
            field = rd.get()
            grid = field.grid

            if k.has_mask:
                gmask = grid.get_mask(create=True)
                gmask[1, :] = True
                grid.set_mask(gmask)

            if not k.has_corners:
                grid.x.set_bounds(None)
                grid.y.set_bounds(None)
                self.assertFalse(grid.has_bounds)

            egrid = get_esmf_grid(grid)
            ogrid = get_ocgis_grid_from_esmf_grid(egrid, crs=k.crs)

            if k.has_mask:
                actual_mask = ogrid.get_mask()
                self.assertEqual(actual_mask.sum(), 4)
                self.assertTrue(actual_mask[1, :].all())

            self.assertEqual(ogrid.crs, k.crs)

            self.assertNumpyAll(grid.get_value_stacked(),
                                ogrid.get_value_stacked())
            if k.has_corners:
                desired = grid.x.bounds.get_value()
                actual = ogrid.x.bounds.get_value()
                self.assertNumpyAll(actual, desired)

                desired = grid.y.bounds.get_value()
                actual = ogrid.y.bounds.get_value()
                self.assertNumpyAll(actual, desired)
            else:
                self.assertFalse(ogrid.has_bounds)
Example #14
0
    def test_get_field(self):
        driver = self.get_drivernetcdf()
        field = driver.get_field(format_time=False)
        self.assertEqual(field.driver.key, driver.key)
        self.assertIsInstance(field.time, TemporalVariable)
        with self.assertRaises(CannotFormatTimeError):
            assert field.time.value_datetime
        self.assertIsInstance(field.crs, CoordinateReferenceSystem)

        # Test overloading the coordinate system.
        path = self.get_temporary_file_path('foo.nc')
        with self.nc_scope(path, 'w') as ds:
            v = ds.createVariable('latitude_longitude', np.int)
            v.grid_mapping_name = 'latitude_longitude'

        # First, test the default is found.
        rd = RequestDataset(uri=path)
        driver = DriverNetcdfCF(rd)
        self.assertEqual(driver.get_crs(driver.metadata_source), CFSpherical())
        self.assertEqual(driver.get_field().crs, CFSpherical())

        # Second, test the overloaded CRS is found.
        desired = CoordinateReferenceSystem(epsg=2136)
        rd = RequestDataset(uri=path, crs=desired)
        self.assertEqual(rd.crs, desired)
        driver = DriverNetcdfCF(rd)
        self.assertEqual(driver.get_crs(driver.metadata_source), CFSpherical())
        field = driver.get_field()
        self.assertEqual(field.crs, desired)
        # Test file coordinate system variable is removed.
        self.assertNotIn('latitude_longitude', field)

        # Test the default coordinate system is used when nothing is in the file.
        path = self.get_temporary_file_path('foo.nc')
        with self.nc_scope(path, 'w') as ds:
            ds.createVariable('nothing', np.int)
        rd = RequestDataset(uri=path)
        driver = DriverNetcdfCF(rd)
        self.assertEqual(rd.crs, env.DEFAULT_COORDSYS)
        self.assertEqual(driver.get_crs(driver.rd.metadata),
                         env.DEFAULT_COORDSYS)
        self.assertEqual(driver.get_field().crs, env.DEFAULT_COORDSYS)
Example #15
0
    def test_update_crs(self):
        grid = self.get_gridxy(crs=Spherical())

        targets = [grid.x, grid.y]
        for target in targets:
            self.assertIn('units', target.attrs)
            self.assertIn('standard_name', target.attrs)

        grid.set_extrapolated_bounds('xbounds', 'ybounds', 'bounds')
        self.assertIsNotNone(grid.y.bounds)
        self.assertIsNotNone(grid.x.bounds)
        to_crs = CoordinateReferenceSystem(epsg=3395)
        grid.update_crs(to_crs)

        targets = [grid.x, grid.y]
        for target in targets:
            self.assertNotIn('units', target.attrs)
            self.assertNotIn('standard_name', target.attrs)

        self.assertEqual(grid.crs, to_crs)
        for element in [grid.x, grid.y]:
            for target in [element.get_value(), element.bounds.get_value()]:
                self.assertTrue(np.all(target > 10000))
Example #16
0
 def test_dimensions(self):
     crs = CoordinateReferenceSystem(epsg=2136)
     field = Field(variables=[crs])
     self.assertEqual(len(field.dimensions), 0)
Example #17
0
 def _parse_string_(self, value):
     return CoordinateReferenceSystem(epsg=int(value))
Example #18
0
    def write(self):
        SEED = 1  #: random number seeding for missing data
        RES = 1  #: resolution of the grid
        ORIGIN = Point(-105, 40)  #: center coordinate of upper left cell
        from_sr = CoordinateReferenceSystem(epsg=4326).sr
        to_sr = CoordinateReferenceSystem(epsg=2163).sr
        ORIGIN = project_shapely_geometry(ORIGIN, from_sr, to_sr)
        DIM = [4, 4]  #: number of cells [dimx,dimy]
        VAR = 'foo'  #: name of the data variable
        ## any relevant variables for the time construction
        TIME = {'origin': datetime.datetime(2000, 3, 1, 12, 0, 0),
                'end': datetime.datetime(2000, 4, 30, 12, 0, 0),
                'calendar': 'proleptic_gregorian',
                'units': 'days since 2000-01-01 00:00:00',
                'name': 'time'}
        ## any relevant variables for the spatial construction
        SPACE = {'row_bnds': 'bounds_latitude',
                 'col_bnds': 'bounds_longitude'}
        ## any relevant variables for the level construction
        LEVEL = {'name': 'level',
                 'n': 2}
        ## variables for masked data
        MASK = {'n': 0,
                'value': float(1e20)}

        ## MANUAL VALUE SETTING ########################################################

        d1l1 = [[1, 1, 2, 2],
                [1, 1, 2, 2],
                [3, 3, 4, 4],
                [3, 3, 4, 4]]
        VAL = np.array(d1l1).reshape(1, 1, 4, 4)
        VAL_MAN = None

        ################################################################################

        ## GENERATE BASE ARRAYS ##

        ## make time vector
        delta = datetime.timedelta(1)
        start = TIME['origin']
        timevec = []
        while start <= TIME['end']:
            timevec.append(start)
            start += delta
        timevec = np.array(timevec)
        ## make vector time bounds
        timevec_bnds = np.empty((len(timevec), 2), dtype=object)
        delta = datetime.timedelta(hours=12)
        for idx, tv in iter_array(timevec, return_value=True):
            timevec_bnds[idx, 0] = tv - delta
            timevec_bnds[idx, 1] = tv + delta

        ## make the level vector
        levelvec = np.array([50, 150])
        levelvec_bounds = np.array([[0, 100], [100, 200]])

        ## make centroids
        col_coords = -np.arange(abs(ORIGIN.x) - RES * (DIM[0] - 1), abs(ORIGIN.x) + RES, RES)
        col_coords = col_coords[::-1]
        row_coords = np.arange(ORIGIN.y - RES * (DIM[1] - 1), ORIGIN.y + RES, RES)
        # row_coords = row_coords[::-1]
        # col,row = np.meshgrid(col_coords,row_coords)

        ## create bounds arrays
        col_bnds = self.make_bounds(col_coords, RES)
        row_bnds = self.make_bounds(row_coords, RES)

        ## make value array
        if VAL is not None:
            val = np.ones((len(timevec), LEVEL['n'], DIM[0], DIM[1]), dtype=float) * VAL
        else:
            val = VAL_MAN
        ## set up the mask if requested
        mask = np.zeros(val.shape, dtype=bool)
        np.random.seed(SEED)
        # set the random masked cells to None
        for ii in range(0, MASK['n']):
            rx = np.random.randint(0, DIM[0])
            ry = np.random.randint(0, DIM[1])
            mask[:, :, rx, ry] = True
        val = np.ma.array(val, dtype=float, mask=mask, fill_value=MASK['value'])

        ## WRITE THE NC FILE ###########################################################

        ## initialize the output file
        rootgrp = nc.Dataset(os.path.join(self.outdir, self.filename), 'w', format='NETCDF4')
        ## create the dimensions
        level = rootgrp.createDimension(LEVEL['name'], size=LEVEL['n'])
        time = rootgrp.createDimension(TIME['name'], size=len(timevec))
        lat = rootgrp.createDimension('lat', size=len(row_coords))
        lon = rootgrp.createDimension('lon', size=len(col_coords))
        bound = rootgrp.createDimension('bound', size=2)
        ## create the variables
        times = rootgrp.createVariable(TIME['name'], 'f8', ('time',))
        times.axis = 'T'
        bounds_times = rootgrp.createVariable('time_bnds', 'f8', ('time', 'bound'))
        levels = rootgrp.createVariable(LEVEL['name'], 'i4', ('level',))
        levels.axis = 'Z'
        bounds_levels = rootgrp.createVariable('level_bnds', 'i4', ('level', 'bound'))
        cols = rootgrp.createVariable('longitude', 'f8', ('lon',))
        cols.axis = 'X'
        cols.standard_name = 'projection_x_coordinate'
        rows = rootgrp.createVariable('latitude', 'f8', ('lat',))
        rows.axis = 'Y'
        rows.standard_name = 'projection_y_coordinate'
        bounds_col = rootgrp.createVariable(SPACE['col_bnds'], 'f8', ('lon', 'bound'))
        bounds_row = rootgrp.createVariable(SPACE['row_bnds'], 'f8', ('lat', 'bound'))
        value = rootgrp.createVariable(VAR, 'f8', ('time', 'level', 'lat', 'lon'), fill_value=1e20)
        ## fill variables
        times.units = TIME['units']
        times.calendar = TIME['calendar']
        times[:] = nc.date2num(timevec, units=times.units, calendar=times.calendar)
        bounds_times[:] = nc.date2num(timevec_bnds, units=times.units, calendar=times.calendar)
        levels[:] = levelvec
        bounds_levels[:] = levelvec_bounds
        cols[:] = col_coords
        rows[:] = row_coords
        bounds_col[:, :] = col_bnds
        bounds_row[:, :] = row_bnds
        value[:, :, :, :] = val
        value.missing_value = MASK['value']
        value.standard_name = 'foo'
        value.long_name = 'foo_foo'
        value.units = 'huge'
        value.grid_mapping = 'crs'

        grid_mapping = rootgrp.createVariable('crs', 'c')
        grid_mapping.grid_mapping_name = "lambert_conformal_conic"
        grid_mapping.standard_parallel = [30., 60.]
        grid_mapping.longitude_of_central_meridian = -97.
        grid_mapping.latitude_of_projection_origin = 47.5
        grid_mapping.false_easting = 3325000.
        grid_mapping.false_northing = 2700000.

        # add bounds attributes
        times.bounds = bounds_times._name
        rows.bounds = bounds_row._name
        cols.bounds = bounds_col._name
        levels.bounds = bounds_levels._name

        rootgrp.close()
Example #19
0
    def from_records(cls, records, schema=None, crs=UNINITIALIZED, uid=None, union=False, data_model=None):
        """
        Create a :class:`~ocgis.Field` from Fiona-like records.

        :param records: A sequence of records returned from an Fiona file object.
        :type records: `sequence` of :class:`dict`
        :param schema: A Fiona-like schema dictionary. If ``None`` and any records properties are ``None``, then this
         must be provided.
        :type schema: dict

        >>> schema = {'geometry': 'Point', 'properties': {'UGID': 'int', 'NAME', 'str:4'}}

        :param crs: If :attr:`ocgis.constants.UNINITIALIZED`, default to :attr:`ocgis.env.DEFAULT_COORDSYS`.
        :type crs: :class:`dict` | :class:`~ocgis.variable.crs.AbstractCoordinateReferenceSystem`
        :param str uid: If provided, use this attribute name as the unique identifier. Otherwise search for
         :attr:`env.DEFAULT_GEOM_UID` and, if not present, construct a 1-based identifier with this name.
        :param bool union: If ``True``, union the geometries from records yielding a single geometry with a unique
         identifier value of ``1``.
        :param str data_model: See :meth:`~ocgis.driver.nc.create_typed_variable_from_data_model`.
        :returns: Field object constructed from records.
        :rtype: :class:`~ocgis.Field`
        """

        if uid is None:
            uid = env.DEFAULT_GEOM_UID

        if isinstance(crs, dict):
            crs = CoordinateReferenceSystem(value=crs)
        elif crs == UNINITIALIZED:
            crs = env.DEFAULT_COORDSYS

        if union:
            deque_geoms = None
            deque_uid = [1]
        else:
            # Holds geometry objects.
            deque_geoms = deque()
            # Holds unique identifiers.
            deque_uid = deque()

        build = True
        for ctr, record in enumerate(records, start=1):

            # Get the geometry from a keyword present on the input dictionary or construct from the coordinates
            # sequence.
            try:
                current_geom = record['geom']
            except KeyError:
                current_geom = shape(record['geometry'])

            if union:
                if build:
                    deque_geoms = current_geom
                else:
                    deque_geoms = deque_geoms.union(current_geom)
            else:
                deque_geoms.append(current_geom)

            # Set up the properties array
            if build:
                build = False

                if uid in record['properties']:
                    has_uid = True
                else:
                    has_uid = False

            # The geometry unique identifier may be present as a property. Otherwise the enumeration counter is used for
            # the identifier.
            if not union:
                if has_uid:
                    to_append = int(record['properties'][uid])
                else:
                    to_append = ctr
                deque_uid.append(to_append)

        # If we are unioning, the target geometry is not yet a sequence.
        if union:
            deque_geoms = [deque_geoms]

        # Dimension for the outgoing field.
        if union:
            size = 1
        else:
            size = ctr
        dim = Dimension(name=DimensionName.GEOMETRY_DIMENSION, size=size)

        # Set default geometry type if no schema is provided.
        if schema is None:
            geom_type = 'auto'
        else:
            geom_type = schema['geometry']

        geom = GeometryVariable(value=deque_geoms, geom_type=geom_type, dimensions=dim)
        uid = create_typed_variable_from_data_model('int', data_model=data_model, name=uid, value=deque_uid,
                                                    dimensions=dim)
        geom.set_ugid(uid)

        field = Field(geom=geom, crs=crs)

        # All records from a unioned geometry are not relevant.
        if not union:
            from ocgis.driver.vector import get_dtype_from_fiona_type, get_fiona_type_from_pydata

            if schema is None:
                has_schema = False
            else:
                has_schema = True

            for idx, record in enumerate(records):
                if idx == 0 and not has_schema:
                    schema = {'properties': OrderedDict()}
                    for k, v in list(record['properties'].items()):
                        schema['properties'][k] = get_fiona_type_from_pydata(v)
                if idx == 0:
                    for k, v in list(schema['properties'].items()):
                        if k == uid.name:
                            continue
                        dtype = get_dtype_from_fiona_type(v, data_model=data_model)
                        var = Variable(name=k, dtype=dtype, dimensions=dim)
                        if v.startswith('str:'):
                            var.set_string_max_length_global(value=int(v.split(':')[1]))
                        field.add_variable(var)
                for k, v in list(record['properties'].items()):
                    if k == uid.name:
                        continue

                    if v is None:
                        # Mask the value if it is None. NULLs are allowed in OGR Vector files, but they do not translate
                        # well to Python. Strings are generally okay but floats/ints case problems.
                        field[k].get_mask(create=True)[idx] = v
                    else:
                        # Set the associated field value.
                        field[k].get_value()[idx] = v

        data_variables = [uid.name]
        if not union:
            data_variables += [k for k in list(schema['properties'].keys()) if k != uid.name]
        field.append_to_tags(TagName.DATA_VARIABLES, data_variables, create=True)

        return field
Example #20
0
 def crs(self):
     return CoordinateReferenceSystem(epsg=2136)
Example #21
0
    def test_init(self):
        keywords = dict(
            value=[
                None, {
                    'no_defs': True,
                    'ellps': 'WGS84',
                    'proj': 'longlat',
                    'towgs84': '0,0,0,0,0,0,0'
                }
            ],
            epsg=[None, 4326],
            proj4=[
                None,
                '+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs '
            ])

        prev_crs = None
        for k in itr_products_keywords(keywords):
            if k['epsg'] is not None and k['value'] is None and k[
                    'proj4'] is None:
                epsg_only = True
                prev_crs = None
            else:
                epsg_only = False

            try:
                crs = CoordinateReferenceSystem(**k)
            except ValueError:
                if all([ii is None for ii in list(k.values())]):
                    continue
                else:
                    raise

            self.assertEqual(
                crs.proj4,
                '+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs ')
            try:
                self.assertDictEqual(
                    crs.value, {
                        'no_defs': True,
                        'ellps': 'WGS84',
                        'proj': 'longlat',
                        'towgs84': '0,0,0,0,0,0,0'
                    })
            except AssertionError:
                self.assertDictEqual(
                    crs.value, {
                        'no_defs': True,
                        'datum': 'WGS84',
                        'proj': 'longlat',
                        'towgs84': '0,0,0,0,0,0,0'
                    })
            if prev_crs is not None:
                self.assertEqual(crs, prev_crs)
            if not epsg_only:
                prev_crs = deepcopy(crs)

        # test with a name parameter
        crs = CoordinateReferenceSystem(epsg=4326)
        self.assertEqual(crs.name, constants.OcgisConvention.Name.COORDSYS)
        crs = CoordinateReferenceSystem(epsg=4326, name='foo')
        self.assertEqual(crs.name, 'foo')

        # test using the init parameter
        value = {'init': 'epsg:4326'}
        self.assertEqual(CoordinateReferenceSystem(value=value), WGS84())
Example #22
0
 def _run_(arr, actual_wrapped_state):
     ret = CoordinateReferenceSystem._get_wrapped_state_from_array_(arr)
     self.assertEqual(ret, actual_wrapped_state)
Example #23
0
    def test_add_shapefile_unique_identifier(self):
        in_path = os.path.join(self.current_dir_output, 'foo_in.shp')

        # create a shapefile without a ugid and another integer attribute
        data = [{
            'geom': Point(1, 2),
            'fid': 6
        }, {
            'geom': Point(2, 3),
            'fid': 60
        }]
        crs = Spherical()
        driver = 'ESRI Shapefile'
        schema = {'properties': {'fid': 'int'}, 'geometry': 'Point'}
        with fiona.open(in_path,
                        'w',
                        driver=driver,
                        crs=crs.value,
                        schema=schema) as source:
            for xx in data:
                record = {
                    'properties': {
                        'fid': xx['fid']
                    },
                    'geometry': mapping(xx['geom'])
                }
                source.write(record)

        out_path = os.path.join(self.current_dir_output, 'foo_out.shp')
        add_shapefile_unique_identifier(in_path, out_path)

        sci = GeomCabinetIterator(path=out_path)
        records = list(sci)
        self.assertAsSetEqual([1, 2], [
            xx['properties'][OCGIS_UNIQUE_GEOMETRY_IDENTIFIER]
            for xx in records
        ])
        self.assertAsSetEqual([6, 60],
                              [xx['properties']['fid'] for xx in records])
        self.assertEqual(CoordinateReferenceSystem(records[0]['meta']['crs']),
                         crs)

        # test it works for the current working directory
        cwd = os.getcwd()
        os.chdir(self.current_dir_output)
        try:
            add_shapefile_unique_identifier(in_path, 'foo3.shp')
            self.assertTrue(
                os.path.exists(
                    os.path.join(self.current_dir_output, 'foo3.shp')))
        finally:
            os.chdir(cwd)

        # test using a template attribute
        out_path = os.path.join(self.current_dir_output, 'template.shp')
        add_shapefile_unique_identifier(in_path, out_path, template='fid')
        sci = GeomCabinetIterator(path=out_path)
        records = list(sci)
        self.assertAsSetEqual([6, 60], [
            xx['properties'][OCGIS_UNIQUE_GEOMETRY_IDENTIFIER]
            for xx in records
        ])

        # test with a different name attribute
        out_path = os.path.join(self.current_dir_output, 'name.shp')
        add_shapefile_unique_identifier(in_path,
                                        out_path,
                                        template='fid',
                                        name='new_id')
        with fiona.open(out_path) as sci:
            records = list(sci)
        self.assertAsSetEqual([6, 60],
                              [xx['properties']['new_id'] for xx in records])
Example #24
0
 def test_write_to_rootgrp(self):
     crs = CoordinateReferenceSystem(epsg=4326, name='hello_world')
     path = os.path.join(self.current_dir_output, 'foo.nc')
     with nc_scope(path, 'w') as ds:
         variable = crs.write_to_rootgrp(ds)
         self.assertIsInstance(variable, nc.Variable)
Example #25
0
 def _run_(arr, actual_wrapped_state):
     ret = CoordinateReferenceSystem._get_wrapped_state_from_array_(arr)
     self.assertEqual(ret, actual_wrapped_state)