def test_array2wkt(self): """Conversion to wkt data works It should create something like this 'POLYGON((0 1, 2 3, 4 5, 6 7, 8 9))' """ # Arrays first A = numpy.arange(10) A = A.reshape(5, 2) wkt = array2wkt(A, geom_type='POLYGON') assert wkt.startswith('POLYGON((') fields = wkt[9:-2].split(',') for i, field in enumerate(fields): x, y = field.split() assert numpy.allclose(A[i, :], [float(x), float(y)]) # Then list wkt = array2wkt(A.tolist(), geom_type='POLYGON') assert wkt.startswith('POLYGON((') fields = wkt[9:-2].split(',') for i, field in enumerate(fields): x, y = field.split() assert numpy.allclose(A[i, :], [float(x), float(y)]) # Then a linestring example (note one less bracket) wkt = array2wkt(A, geom_type='LINESTRING') assert wkt.startswith('LINESTRING(') fields = wkt[11:-1].split(',') for i, field in enumerate(fields): x, y = field.split() assert numpy.allclose(A[i, :], [float(x), float(y)])
def write_to_file(self, filename): """Save vector data to file Input filename: filename with extension .shp or .gml Note, if attribute names are longer than 10 characters they will be truncated. This is due to limitations in the shp file driver and has to be done here since gdal v1.7 onwards has changed its handling of this issue: http://www.gdal.org/ogr/drv_shapefile.html """ # Check file format basename, extension = os.path.splitext(filename) msg = "Invalid file type for file %s. Only extensions " "shp or gml allowed." % filename assert extension == ".shp" or extension == ".gml", msg driver = DRIVER_MAP[extension] # FIXME (Ole): Tempory flagging of GML issue (ticket #18) if extension == ".gml": msg = ( "OGR GML driver does not store geospatial reference." "This format is disabled for the time being. See " "https://github.com/AIFDR/riab/issues/18" ) raise Exception(msg) # Derive layername from filename (excluding preceding dirs) layername = os.path.split(basename)[-1] # Get vector data geometry = self.get_geometry() data = self.get_data() N = len(geometry) # Clear any previous file of this name (ogr does not overwrite) try: os.remove(filename) except: pass # Create new file with one layer drv = ogr.GetDriverByName(driver) if drv is None: msg = "OGR driver %s not available" % driver raise Exception(msg) ds = drv.CreateDataSource(filename) if ds is None: msg = "Creation of output file %s failed" % filename raise Exception(msg) lyr = ds.CreateLayer(layername, self.projection.spatial_reference, self.geometry_type) if lyr is None: msg = "Could not create layer %s" % layername raise Exception(msg) # Define attributes if any store_attributes = False if data is not None: if len(data) > 0: try: fields = data[0].keys() except: msg = ( 'Input parameter "attributes" was specified ' "but it does not contain dictionaries with " "field information as expected. The first" "element is %s" % data[0] ) raise Exception(msg) else: # Establish OGR types for each element ogrtypes = {} for name in fields: att = data[0][name] py_type = type(att) msg = "Unknown type for storing vector " "data: %s, %s" % (name, str(py_type)[1:-1]) assert py_type in TYPE_MAP, msg ogrtypes[name] = TYPE_MAP[py_type] else: msg = 'Input parameter "data" was specified ' "but appears to be empty" raise Exception(msg) # Create attribute fields in layer store_attributes = True for name in fields: fd = ogr.FieldDefn(name, ogrtypes[name]) # FIXME (Ole): Trying to address issue #16 # But it doesn't work and # somehow changes the values of MMI in test # width = max(128, len(name)) # print name, width # fd.SetWidth(width) # Silent handling of warnings like # Warning 6: Normalized/laundered field name: #'CONTENTS_LOSS_AUD' to 'CONTENTS_L' gdal.PushErrorHandler("CPLQuietErrorHandler") if lyr.CreateField(fd) != 0: msg = "Could not create field %s" % name raise Exception(msg) # Restore error handler gdal.PopErrorHandler() # Store geometry geom = ogr.Geometry(self.geometry_type) layer_def = lyr.GetLayerDefn() for i in range(N): # Create new feature instance feature = ogr.Feature(layer_def) # Store geometry and check if self.geometry_type == ogr.wkbPoint: x = float(geometry[i][0]) y = float(geometry[i][1]) geom.SetPoint_2D(0, x, y) elif self.geometry_type == ogr.wkbPolygon: wkt = array2wkt(geometry[i], geom_type="POLYGON") geom = ogr.CreateGeometryFromWkt(wkt) else: msg = "Geometry type %s not implemented" % self.geometry_type raise Exception(msg) feature.SetGeometry(geom) G = feature.GetGeometryRef() if G is None: msg = "Could not create GeometryRef for file %s" % filename raise Exception(msg) # Store attributes if store_attributes: for j, name in enumerate(fields): actual_field_name = layer_def.GetFieldDefn(j).GetNameRef() val = data[i][name] if type(val) == numpy.ndarray: # A singleton of type <type 'numpy.ndarray'> works # for gdal version 1.6 but fails for version 1.8 # in SetField with error: NotImplementedError: # Wrong number of arguments for overloaded function val = float(val) feature.SetField(actual_field_name, val) # Save this feature if lyr.CreateFeature(feature) != 0: msg = "Failed to create feature %i in file %s" % (i, filename) raise Exception(msg) feature.Destroy() # Write keywords if any write_keywords(self.keywords, basename + ".keywords")
def write_to_file(self, filename): """Save vector data to file Input filename: filename with extension .shp or .gml Note, if attribute names are longer than 10 characters they will be truncated. This is due to limitations in the shp file driver and has to be done here since gdal v1.7 onwards has changed its handling of this issue: http://www.gdal.org/ogr/drv_shapefile.html """ # Check file format basename, extension = os.path.splitext(filename) msg = ('Invalid file type for file %s. Only extensions ' 'shp or gml allowed.' % filename) assert extension == '.shp' or extension == '.gml', msg driver = DRIVER_MAP[extension] # FIXME (Ole): Tempory flagging of GML issue (ticket #18) if extension == '.gml': msg = ('OGR GML driver does not store geospatial reference.' 'This format is disabled for the time being. See ' 'https://github.com/AIFDR/riab/issues/18') raise Exception(msg) # Derive layername from filename (excluding preceding dirs) layername = os.path.split(basename)[-1] # Get vector data geometry = self.get_geometry() data = self.get_data() N = len(geometry) # Clear any previous file of this name (ogr does not overwrite) try: os.remove(filename) except: pass # Create new file with one layer drv = ogr.GetDriverByName(driver) if drv is None: msg = 'OGR driver %s not available' % driver raise Exception(msg) ds = drv.CreateDataSource(filename) if ds is None: msg = 'Creation of output file %s failed' % filename raise Exception(msg) lyr = ds.CreateLayer(layername, self.projection.spatial_reference, self.geometry_type) if lyr is None: msg = 'Could not create layer %s' % layername raise Exception(msg) # Define attributes if any store_attributes = False if data is not None: if len(data) > 0: try: fields = data[0].keys() except: msg = ('Input parameter "attributes" was specified ' 'but it does not contain dictionaries with ' 'field information as expected. The first' 'element is %s' % data[0]) raise Exception(msg) else: # Establish OGR types for each element ogrtypes = {} for name in fields: att = data[0][name] py_type = type(att) msg = ('Unknown type for storing vector ' 'data: %s, %s' % (name, str(py_type)[1:-1])) assert py_type in TYPE_MAP, msg ogrtypes[name] = TYPE_MAP[py_type] else: msg = ('Input parameter "data" was specified ' 'but appears to be empty') raise Exception(msg) # Create attribute fields in layer store_attributes = True for name in fields: fd = ogr.FieldDefn(name, ogrtypes[name]) # FIXME (Ole): Trying to address issue #16 # But it doesn't work and # somehow changes the values of MMI in test #width = max(128, len(name)) #print name, width #fd.SetWidth(width) # Silent handling of warnings like # Warning 6: Normalized/laundered field name: #'CONTENTS_LOSS_AUD' to 'CONTENTS_L' gdal.PushErrorHandler('CPLQuietErrorHandler') if lyr.CreateField(fd) != 0: msg = 'Could not create field %s' % name raise Exception(msg) # Restore error handler gdal.PopErrorHandler() # Store geometry geom = ogr.Geometry(self.geometry_type) layer_def = lyr.GetLayerDefn() for i in range(N): # Create new feature instance feature = ogr.Feature(layer_def) # Store geometry and check if self.geometry_type == ogr.wkbPoint: x = float(geometry[i][0]) y = float(geometry[i][1]) geom.SetPoint_2D(0, x, y) elif self.geometry_type == ogr.wkbPolygon: wkt = array2wkt(geometry[i], geom_type='POLYGON') geom = ogr.CreateGeometryFromWkt(wkt) else: msg = 'Geometry type %s not implemented' % self.geometry_type raise Exception(msg) feature.SetGeometry(geom) G = feature.GetGeometryRef() if G is None: msg = 'Could not create GeometryRef for file %s' % filename raise Exception(msg) # Store attributes if store_attributes: for j, name in enumerate(fields): actual_field_name = layer_def.GetFieldDefn(j).GetNameRef() val = data[i][name] if type(val) == numpy.ndarray: # A singleton of type <type 'numpy.ndarray'> works # for gdal version 1.6 but fails for version 1.8 # in SetField with error: NotImplementedError: # Wrong number of arguments for overloaded function val = float(val) feature.SetField(actual_field_name, val) # Save this feature if lyr.CreateFeature(feature) != 0: msg = 'Failed to create feature %i in file %s' % (i, filename) raise Exception(msg) feature.Destroy() # Write keywords if any write_keywords(self.keywords, basename + '.keywords')
def write_to_file(self, filename): """Save vector data to file Input filename: filename with extension .shp or .gml """ # Check file format basename, extension = os.path.splitext(filename) msg = ('Invalid file type for file %s. Only extensions ' 'shp or gml allowed.' % filename) assert extension == '.shp' or extension == '.gml', msg driver = DRIVER_MAP[extension] # FIXME (Ole): Tempory flagging of GML issue (ticket #18) if extension == '.gml': msg = ('OGR GML driver does not store geospatial reference.' 'This format is disabled for the time being. See ' 'https://github.com/AIFDR/riab/issues/18') raise Exception(msg) # Derive layername from filename (excluding preceding dirs) layername = os.path.split(basename)[-1] # Get vector data geometry = self.get_geometry() data = self.get_data() N = len(geometry) # Clear any previous file of this name (ogr does not overwrite) try: os.remove(filename) except: pass # Create new file with one layer drv = ogr.GetDriverByName(driver) if drv is None: msg = 'OGR driver %s not available' % driver raise Exception(msg) ds = drv.CreateDataSource(filename) if ds is None: msg = 'Creation of output file %s failed' % filename raise Exception(msg) lyr = ds.CreateLayer(layername, self.projection.spatial_reference, self.geometry_type) if lyr is None: msg = 'Could not create layer %s' % layername raise Exception(msg) # Define attributes if any store_attributes = False if data is not None: if len(data) > 0: try: fields = data[0].keys() except: msg = ('Input parameter "attributes" was specified ' 'but it does not contain dictionaries with ' 'field information as expected. The first' 'element is %s' % data[0]) raise Exception(msg) else: # Establish OGR types for each element ogrtypes = {} for name in fields: att = data[0][name] py_type = type(att) msg = ('Unknown type for storing vector ' 'data: %s, %s' % (name, str(py_type)[1:-1])) assert py_type in TYPE_MAP, msg ogrtypes[name] = TYPE_MAP[py_type] else: msg = ('Input parameter "data" was specified ' 'but appears to be empty') raise Exception(msg) # Create attribute fields in layer store_attributes = True for name in fields: fd = ogr.FieldDefn(name, ogrtypes[name]) # FIXME (Ole): Trying to address issue #16 # But it doesn't work and # somehow changes the values of MMI in test #width = max(128, len(name)) #print name, width #fd.SetWidth(width) if lyr.CreateField(fd) != 0: msg = 'Could not create field %s' % name raise Exception(msg) # Store geometry geom = ogr.Geometry(self.geometry_type) layer_def = lyr.GetLayerDefn() for i in range(N): # Create new feature instance feature = ogr.Feature(layer_def) # Store geometry and check if self.geometry_type == ogr.wkbPoint: x = float(geometry[i][0]) y = float(geometry[i][1]) geom.SetPoint_2D(0, x, y) elif self.geometry_type == ogr.wkbPolygon: wkt = array2wkt(geometry[i]) geom = ogr.CreateGeometryFromWkt(wkt) else: msg = 'Geometry %s not implemented' % self.geometry_type raise Exception(msg) feature.SetGeometry(geom) G = feature.GetGeometryRef() if G is None: msg = 'Could not create GeometryRef for file %s' % filename raise Exception(msg) # Store attributes if store_attributes: for name in fields: feature.SetField(name, data[i][name]) # Save this feature if lyr.CreateFeature(feature) != 0: msg = 'Failed to create feature %i in file %s' % (i, filename) raise Exception(msg) feature.Destroy() # Write keywords if any write_keywords(self.keywords, basename + '.keywords')