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()
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')])])