Esempio n. 1
0
    def write_ugeom(self, path=None, driver='ESRI Shapefile', fobject=None):
        """
        Write the user geometries to a ``fiona``-supported file format.

        :param str path: Full path of file to write. If ``None``, ``fobject`` is required.
        :param str driver: The ``fiona`` driver to use for writing. Ignored if ``fobject`` is provided.
        :param fobject: An open ``fiona`` file object to write to. If ``path`` is provided and this is not ``None``,
         then ``path`` will be ignored.
        :type fobject: :class:`fiona.collection.Collection`
        """

        if fobject is None and self.crs is None:
            msg = 'A coordinate system is required when writing to Fiona formats.'
            raise ValueError(msg)

        from ocgis.conv.fiona_ import AbstractFionaConverter

        build = True if fobject is None else False
        is_open = False
        needs_casting = False
        try:
            for ugid, geom in self.geoms.iteritems():
                if build:
                    # it is possible to end with a mix of singleton and multi-geometries
                    type_check = set()
                    for check_geom in self.geoms.itervalues():
                        type_check.update([check_geom.geom_type])
                    if len(type_check) > 1:
                        needs_casting = True
                        for xx in type_check:
                            if xx.startswith('Multi'):
                                geometry = xx
                            else:
                                cast_target_key = xx
                    else:
                        geometry = type_check.pop()

                    fiona_properties = OrderedDict()
                    archetype_properties = self.properties[ugid]
                    for name in archetype_properties.dtype.names:
                        fiona_properties[name] = AbstractFionaConverter.get_field_type(
                            type(archetype_properties[name][0]))
                    fiona_schema = {'geometry': geometry, 'properties': fiona_properties}
                    fiona_kwds = {'schema': fiona_schema, 'driver': driver, 'mode': 'w'}
                    if self.crs is not None:
                        fiona_kwds['crs'] = self.crs.value
                    fobject = fiona.open(path, **fiona_kwds)
                    is_open = True
                    build = False
                properties = get_ordered_dicts_from_records_array(self.properties[ugid])[0]
                if needs_casting:
                    if not isinstance(geom, BaseMultipartGeometry):
                        geom = self._multi_cast[cast_target_key]([geom])
                mapped_geom = mapping(geom)
                record = {'geometry': mapped_geom, 'properties': properties}
                fobject.write(record)
        finally:
            if is_open:
                fobject.close()
Esempio n. 2
0
    def test_get_ordered_dicts_from_records_array(self):
        """Test converting a records array to a list of ordered dictionaries."""

        arr = np.zeros(2, dtype=[('UGID', int), ('NAME', object)])
        arr[0] = (1, 'Name1')
        arr[1] = (2, 'Name2')
        ret = get_ordered_dicts_from_records_array(arr)
        self.assertListEqual(ret, [OrderedDict([('UGID', 1), ('NAME', 'Name1')]),
                                   OrderedDict([('UGID', 2), ('NAME', 'Name2')])])