def contour_real_world_case(): ogr_ds = ogr.GetDriverByName('Memory').CreateDataSource('') ogr_lyr = ogr_ds.CreateLayer('contour', geom_type=ogr.wkbLineString) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) ds = gdal.Open('data/contour_in.tif') gdal.ContourGenerate(ds.GetRasterBand(1), 10, 0, [], 0, 0, ogr_lyr, 0, 1) ds = None ogr_lyr.SetAttributeFilter('elev = 330') if ogr_lyr.GetFeatureCount() != 1: gdaltest.post_reason('fail') return 'fail' f = ogr_lyr.GetNextFeature() if ogrtest.check_feature_geometry( f, 'LINESTRING (4.50497512437811 11.5,4.5 11.501996007984,3.5 11.8333333333333,2.5 11.5049751243781,2.490099009901 11.5,2.0 10.5,2.5 10.1666666666667,3.0 9.5,3.5 9.21428571428571,4.49800399201597 8.5,4.5 8.49857346647646,5.5 8.16666666666667,6.5 8.0,7.5 8.0,8.0 7.5,8.5 7.0,9.490099009901 6.5,9.5 6.49667774086379,10.5 6.16666666666667,11.4950248756219 5.5,11.5 5.49833610648919,12.5 5.49667774086379,13.5 5.49800399201597,13.501996007984 5.5,13.5 5.50199600798403,12.501996007984 6.5,12.5 6.50142653352354,11.5 6.509900990099,10.509900990099 7.5,10.5 7.50142653352354,9.5 7.9,8.50332225913621 8.5,8.5 8.50249376558603,7.83333333333333 9.5,7.5 10.0,7.0 10.5,6.5 10.7857142857143,5.5 11.1666666666667,4.50497512437811 11.5)' ) != 0: return 'fail' return 'success'
def create_contour(gdal_image, interval=10, offset=0, ele_name='ele'): """ Ref: https://github.com/OSGeo/gdal/blob/3554675bbce8dc00030bac33c99d92764d0f3844/autotest/alg/contour.py#L88-L97 Args: - gdal_image: opened GDAL object representing input image - interval: Elevation interval between contours - offset: Offset from zero relative to which to interpret intervals. - ele_name: Name of property to contain elevation. Defaults to `ele` Returns: Iterator of GeoJSON LineString Features representing contour isobands """ ogr_ds = ogr.GetDriverByName('Memory').CreateDataSource('memory_filename') ogr_lyr = ogr_ds.CreateLayer('contour') field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn(ele_name, ogr.OFTReal) ogr_lyr.CreateField(field_defn) gdal.ContourGenerate(gdal_image.GetRasterBand(1), interval, offset, [], 0, 0, ogr_lyr, 0, 1) for i in range(ogr_lyr.GetFeatureCount()): yield json.loads(ogr_lyr.GetFeature(i).ExportToJson())
def dem_contour_fl(fn_dem_in,fn_shp_out,fl): src_ds = gdal.Open(fn_dem_in, gdalconst.GA_ReadOnly) src_band = src_ds.GetRasterBand(1) mask_band = src_band.GetMaskBand() srs = osr.SpatialReference() srs.ImportFromWkt(src_ds.GetProjectionRef()) # remove the .shp if specified by user # if fn_shp_out[-4:] == '.shp': # fn_shp_out = fn_shp_out[:-4] drv = ogr.GetDriverByName('ESRI Shapefile') if os.path.exists(fn_shp_out): drv.DeleteDataSource(fn_shp_out) dst_ds = drv.CreateDataSource(fn_shp_out) dst_layer = dst_ds.CreateLayer('contour', srs=srs) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) dst_layer.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) dst_layer.CreateField(field_defn) #first parameter is interval, third is fixed elevation list to contour gdal.ContourGenerate(src_band, 0, 0, fl, 0, 0, dst_layer, 0, 1) dst_ds.Destroy() src_ds = None
def generate(self, levels): # Generate isolines with fixed levels print("Level count: {}".format(levels)) if self.output_ds is None: raise RadiationError("Output datasource not defined, destination() method must be called.") band = self.input_ds.GetRasterBand(1) ret = gdal.ContourGenerate(band, 0, 0, levels, 0, 0, self.output_layer, 0, 1) if ret != gdal.CE_None: raise RadiationError("Isolines generation failed")
def shakemap_contour(shakemap_layer_path, output_file_path='', active_band=1): """Creating contour from a shakemap layer. :param shakemap_layer_path: The shake map raster layer path. :type shakemap_layer_path: basestring :param output_file_path: The path where the contour will be saved. :type output_file_path: basestring :param active_band: The band which the data located, default to 1. :type active_band: int :returns: The contour of the shake map layer path. :rtype: basestring """ # Set output path if not output_file_path: output_file_path = unique_filename(suffix='.shp', dir=temp_dir()) output_directory = os.path.dirname(output_file_path) output_file_name = os.path.basename(output_file_path) output_base_name = os.path.splitext(output_file_name)[0] # Based largely on # http://svn.osgeo.org/gdal/trunk/autotest/alg/contour.py driver = ogr.GetDriverByName('ESRI Shapefile') ogr_dataset = driver.CreateDataSource(output_file_path) if ogr_dataset is None: # Probably the file existed and could not be overriden raise ContourCreationError( 'Could not create datasource for:\n%s. Check that the file ' 'does not already exist and that you do not have file system ' 'permissions issues' % output_file_path) layer = ogr_dataset.CreateLayer('contour') for contour_field in contour_fields: field_definition = create_ogr_field_from_definition(contour_field) layer.CreateField(field_definition) shakemap_data = gdal.Open(shakemap_layer_path, GA_ReadOnly) # see http://gdal.org/java/org/gdal/gdal/gdal.html for these options contour_interval = 0.5 contour_base = 0 fixed_level_list = [] use_no_data_flag = 0 no_data_value = -9999 id_field = 0 # first field defined above elevation_field = 1 # second (MMI) field defined above try: gdal.ContourGenerate(shakemap_data.GetRasterBand(active_band), contour_interval, contour_base, fixed_level_list, use_no_data_flag, no_data_value, layer, id_field, elevation_field) except Exception, e: LOGGER.exception('Contour creation failed') raise ContourCreationError(str(e))
def test_contour_2(): try: os.remove('tmp/contour.shp') except OSError: pass try: os.remove('tmp/contour.dbf') except OSError: pass try: os.remove('tmp/contour.shx') except OSError: pass ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource('tmp/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour', geom_type=ogr.wkbLineString25D) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) ds = gdal.Open('tmp/gdal_contour.tif') gdal.ContourGenerate(ds.GetRasterBand(1), 0, 0, [10, 20, 25], 0, 0, ogr_lyr, 0, 1) ds = None size = 160 precision = 1. / size expected_envelopes = [[1.25, 1.75, 49.25, 49.75], [1.25 + 0.125, 1.75 - 0.125, 49.25 + 0.125, 49.75 - 0.125], [1.25 + 0.125 + 0.0625, 1.75 - 0.125 - 0.0625, 49.25 + 0.125 + 0.0625, 49.75 - 0.125 - 0.0625]] expected_height = [10, 20, 25, 10000] lyr = ogr_ds.ExecuteSQL("select * from contour order by elev asc") assert lyr.GetFeatureCount() == len(expected_envelopes) i = 0 feat = lyr.GetNextFeature() while feat is not None: assert feat.GetGeometryRef().GetZ(0) == expected_height[i] envelope = feat.GetGeometryRef().GetEnvelope() assert feat.GetField('elev') == expected_height[i] for j in range(4): if expected_envelopes[i][j] != pytest.approx(envelope[j], abs=precision / 2 * 1.001): print('i=%d, wkt=%s' % (i, feat.GetGeometryRef().ExportToWkt())) print(feat.GetGeometryRef().GetEnvelope()) pytest.fail('%f, %f' % (expected_envelopes[i][j] - envelope[j], precision / 2)) i = i + 1 feat = lyr.GetNextFeature() ogr_ds.ReleaseResultSet(lyr) ogr_ds.Destroy()
def generate_contours(self, shape_file, **kwargs): ''' Generate contour shapefile using GDALContourGenerate Parameters ----------- shape_file: str path of output contour shapefile base: float, default 0 base relative to which contour intervals are generated interval: float, default 10 elevation interval between generated contours fixed_levels: list, default [] List of elevations at which additional contours are generated ignore_nodata: bool, default True flag to ignore nodata pixel during contour generation ''' interval = kwargs.get('interval', 10) base = kwargs.get('base', 0) fixed_levels = kwargs.get('fixed_levels', []) ignore_nodata = kwargs.get('ignore_nodata', True) # grid profile prof = self._default_rasterio_profile() # create in-memory gdal raster source ds1 = self._as_gdal_datasource() srcband = ds1.GetRasterBand(1) # create contour shape file crs = ogr.osr.SpatialReference() crs.ImportFromWkt(prof['crs']) ds2 = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource( shape_file) contour_layer = ds2.CreateLayer('contour', crs, ogr.wkbMultiLineString) field_defn = ogr.FieldDefn("ID", ogr.OFTInteger) contour_layer.CreateField(field_defn) field_defn = ogr.FieldDefn("ELEV", ogr.OFTReal) contour_layer.CreateField(field_defn) # contouring method use_nodata = 0 if ignore_nodata else 1 gdal.ContourGenerate( srcband, interval, base, # interval, base fixed_levels, # fixedlevelcount list use_nodata, prof['nodata'], # usenodata, nodata contour_layer, # dstlayer 0, 1) # ID field, ELEV field
def Contour(self, Input1, ContourInterval=100, contourBase=0, OutputFilePath=None): """ Creates a vector dataset with contour lines from a DEM. Parameters: Input1: An SpaDatasetRaster object OR a string representing the path to the raster file Return: A SpaDatasetRaster object depicting aspect """ Input1 = SpaBase.GetInput(Input1) NewDataset = SpaRasters.SpaDatasetRaster() NewDataset.CopyPropertiesButNotData(Input1) UseNoData = 0 NoDataValue = 0 if (Input1.GetNoDataValue() != None): UseNoData = 1 NoDataValue = Input1.GetNoDataValue() TheBand = Input1.GDALDataset.GetRasterBand(1) #Generate layer to save Contourlines in #TheDataset=SpaVectors.SpaDatasetVector() #create a new layer ## add a square geometry in at 0,0 #TheDataset.AddAttribute("ID","int") #TheDataset.AddAttribute("elev","float") ## Save the result #TheDataset.Save(OutputFolderPath+"NewBox.shp") ogr_ds = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource( OutputFilePath) contour_shp = ogr_ds.CreateLayer('contour') field_defn = ogr.FieldDefn("ID", ogr.OFTInteger) contour_shp.CreateField(field_defn) field_defn = ogr.FieldDefn("elev", ogr.OFTReal) contour_shp.CreateField(field_defn) #ContourGenerate(Band srcBand, double contourInterval, double contourBase, int fixedLevelCount, int useNoData, double noDataValue, Layer dstLayer, int idField, int elevField, GDALProgressFunc callback=0, void * callback_data=None) gdal.ContourGenerate(TheBand, ContourInterval, contourBase, [], UseNoData, NoDataValue, contour_shp, 0, 1) ogr_ds = None return (NewDataset)
def contour(self, inLayer, outLayer): ds = ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource('tmp/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour') field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) gdal.ContourGenerate(ds.GetRasterBand(1), 10, 0, [], 0, 0, ogr_lyr, 0, 1) ds = None
def genContour(self, folder, layer, layerName): folder = toUnicode(folder) provider = layer.dataProvider() extent = layer.extent() stats = provider.bandStatistics(1, QgsRasterBandStats.All, extent, 0) minVal = stats.minimumValue maxVal = stats.maximumValue interval = (maxVal - minVal) / 10. rasDataSet = gdal.Open(layer.source(), GA_ReadOnly) layerCrs = layer.crs() # Get the no data value: rows = layer.rasterUnitsPerPixelY() cols = layer.rasterUnitsPerPixelX() noDataVal = provider.block(1, extent, rows, cols).noDataValue() # Generate layer to save Contourlines in ogr_ds = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource( toUnicode(os.path.join(folder, str(layerName) + '.shp'))) contour_shp = ogr_ds.CreateLayer(str(layerName), geom_type=ogr.wkbLineString25D) field_defn = ogr.FieldDefn("ID", ogr.OFTInteger) contour_shp.CreateField(field_defn) field_defn = ogr.FieldDefn("VALUE", ogr.OFTReal) contour_shp.CreateField(field_defn) try: self.iface.messageBar().pushMessage('Generate Contour of ' + layerName) gdal.ContourGenerate(rasDataSet.GetRasterBand(1), interval, 0, [], 0, noDataVal, contour_shp, 0, 1) conLayer = self.iface.addVectorLayer( toUnicode(os.path.join(folder, str(layerName) + '.shp')), str(layerName) + '_contour', 'ogr') conLayer.setCrs(layerCrs) except Exception, e: self.iface.messageBar().pushMessage(str(e))
from osgeo import gdal from osgeo.gdalconst import * from numpy import * from osgeo import ogr #Primero se lee la data grd data_elevacion = gdal.Open( "/usr/cbarrios/Documentos/Gerardo/vallesdeltuyhillshade/raster_combinado.grd", GA_ReadOnly) banda_raster = data_elevacion.GetRasterBand(1) #Generacion de la capa para las lineas de nivel ogr_ds = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource( "lineas de nivel.shp") contour_shp = ogr_ds.CreateLayer('lineas de nivel') #Se definen los campos (atributos de la capa), uno de enteros(la cantidad de lineas) y uno de reales que representara las alturas field_defn = ogr.FieldDefn("ID", ogr.OFTInteger) contour_shp.CreateField(field_defn) field_defn = ogr.FieldDefn("elev", ogr.OFTReal) contour_shp.CreateField(field_defn) #Generate Contourlines gdal.ContourGenerate(banda_raster, 100, 0, [], 0, 0, contour_shp, 0, 1) #se elimina la data para dejar solo las lineas de contorno ogr_ds = None del ogr_ds
def mmi_to_contours(self, force_flag=True, algorithm='nearest'): """Extract contours from the event's tif file. Contours are extracted at a 0.5 MMI interval. The resulting file will be saved in the extract directory. In the easiest use case you can :param force_flag: (Optional). Whether to force the regeneration of contour product. Defaults to False. :type force_flag: bool :param algorithm: (Optional) Which interpolation algorithm to use to create the underlying raster. Defaults to 'nearest'. :type algorithm: str **Only enforced if theForceFlag is true!** :returns: An absolute filesystem path pointing to the generated contour dataset. :exception: ContourCreationError simply do:: shake_grid = ShakeGrid() contour_path = shake_grid.mmi_to_contours() which will return the contour dataset for the latest event on the ftp server. """ LOGGER.debug('mmi_to_contours requested.') # TODO: Use sqlite rather? output_file_base = os.path.join( self.output_dir, '%s-contours-%s.' % (self.output_basename, algorithm)) output_file = output_file_base + 'shp' if os.path.exists(output_file) and force_flag is not True: return output_file elif os.path.exists(output_file): try: os.remove(output_file_base + 'shp') os.remove(output_file_base + 'shx') os.remove(output_file_base + 'dbf') os.remove(output_file_base + 'prj') except OSError: LOGGER.exception( 'Old contour files not deleted' ' - this may indicate a file permissions issue.') tif_path = self.mmi_to_raster(force_flag, algorithm) # Based largely on # http://svn.osgeo.org/gdal/trunk/autotest/alg/contour.py driver = ogr.GetDriverByName('ESRI Shapefile') ogr_dataset = driver.CreateDataSource(output_file) if ogr_dataset is None: # Probably the file existed and could not be overriden raise ContourCreationError( 'Could not create datasource for:\n%s. Check that the file ' 'does not already exist and that you do not have file system ' 'permissions issues' % output_file) layer = ogr_dataset.CreateLayer('contour') field_definition = ogr.FieldDefn('ID', ogr.OFTInteger) layer.CreateField(field_definition) field_definition = ogr.FieldDefn('MMI', ogr.OFTReal) layer.CreateField(field_definition) # So we can fix the x pos to the same x coord as centroid of the # feature so labels line up nicely vertically field_definition = ogr.FieldDefn('X', ogr.OFTReal) layer.CreateField(field_definition) # So we can fix the y pos to the min y coord of the whole contour so # labels line up nicely vertically field_definition = ogr.FieldDefn('Y', ogr.OFTReal) layer.CreateField(field_definition) # So that we can set the html hex colour based on its MMI class field_definition = ogr.FieldDefn('RGB', ogr.OFTString) layer.CreateField(field_definition) # So that we can set the label in it roman numeral form field_definition = ogr.FieldDefn('ROMAN', ogr.OFTString) layer.CreateField(field_definition) # So that we can set the label horizontal alignment field_definition = ogr.FieldDefn('ALIGN', ogr.OFTString) layer.CreateField(field_definition) # So that we can set the label vertical alignment field_definition = ogr.FieldDefn('VALIGN', ogr.OFTString) layer.CreateField(field_definition) # So that we can set feature length to filter out small features field_definition = ogr.FieldDefn('LEN', ogr.OFTReal) layer.CreateField(field_definition) tif_dataset = gdal.Open(tif_path, GA_ReadOnly) # see http://gdal.org/java/org/gdal/gdal/gdal.html for these options band = 1 contour_interval = 0.5 contour_base = 0 fixed_level_list = [] use_no_data_flag = 0 no_data_value = -9999 id_field = 0 # first field defined above elevation_field = 1 # second (MMI) field defined above try: gdal.ContourGenerate(tif_dataset.GetRasterBand(band), contour_interval, contour_base, fixed_level_list, use_no_data_flag, no_data_value, layer, id_field, elevation_field) except Exception, e: LOGGER.exception('Contour creation failed') raise ContourCreationError(str(e))
def contour_1(): try: os.remove('tmp/contour.shp') except: pass try: os.remove('tmp/contour.dbf') except: pass try: os.remove('tmp/contour.shx') except: pass drv = gdal.GetDriverByName('GTiff') wkt = 'GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9108\"]],AUTHORITY[\"EPSG\",\"4326\"]]' size = 160 precision = 1. / size ds = drv.Create('tmp/gdal_contour.tif', size, size, 1) ds.SetProjection(wkt) ds.SetGeoTransform([1, precision, 0, 50, 0, -precision]) raw_data = array.array('h', [10 for i in range(int(size / 2))]).tostring() for i in range(int(size / 2)): ds.WriteRaster(int(size / 4), i + int(size / 4), int(size / 2), 1, raw_data, buf_type=gdal.GDT_Int16, band_list=[1]) raw_data = array.array('h', [20 for i in range(int(size / 2))]).tostring() for i in range(int(size / 4)): ds.WriteRaster(int(size / 4) + int(size / 8), i + int(size / 4) + int(size / 8), int(size / 4), 1, raw_data, buf_type=gdal.GDT_Int16, band_list=[1]) raw_data = array.array('h', [25 for i in range(int(size / 4))]).tostring() for i in range(int(size / 8)): ds.WriteRaster(int(size / 4) + int(size / 8) + int(size / 16), i + int(size / 4) + int(size / 8) + int(size / 16), int(size / 8), 1, raw_data, buf_type=gdal.GDT_Int16, band_list=[1]) ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource( 'tmp/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour') field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) gdal.ContourGenerate(ds.GetRasterBand(1), 10, 0, [], 0, 0, ogr_lyr, 0, 1) ds = None expected_envelopes = [[1.25, 1.75, 49.25, 49.75], [ 1.25 + 0.125, 1.75 - 0.125, 49.25 + 0.125, 49.75 - 0.125 ]] expected_height = [10, 20] lyr = ogr_ds.ExecuteSQL("select * from contour order by elev asc") if lyr.GetFeatureCount() != len(expected_envelopes): print('Got %d features. Expected %d' % (lyr.GetFeatureCount(), len(expected_envelopes))) return 'fail' i = 0 feat = lyr.GetNextFeature() while feat is not None: envelope = feat.GetGeometryRef().GetEnvelope() if feat.GetField('elev') != expected_height[i]: print('Got %f. Expected %f' % (feat.GetField('elev'), expected_height[i])) return 'fail' for j in range(4): if abs(expected_envelopes[i][j] - envelope[j]) > precision / 2 * 1.001: print('i=%d, wkt=%s' % (i, feat.GetGeometryRef().ExportToWkt())) print(feat.GetGeometryRef().GetEnvelope()) print(expected_envelopes[i]) print('%f, %f' % (expected_envelopes[i][j] - envelope[j], precision / 2)) return 'fail' i = i + 1 feat = lyr.GetNextFeature() ogr_ds.ReleaseResultSet(lyr) ogr_ds.Destroy() return 'success'
def contour_2(): try: os.remove('tmp/contour.shp') except: pass try: os.remove('tmp/contour.dbf') except: pass try: os.remove('tmp/contour.shx') except: pass ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource( 'tmp/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour', geom_type=ogr.wkbLineString25D) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) ds = gdal.Open('tmp/gdal_contour.tif') gdal.ContourGenerate(ds.GetRasterBand(1), 0, 0, [10, 20, 25], 0, 0, ogr_lyr, 0, 1) ds = None size = 160 precision = 1. / size expected_envelopes = [[1.25, 1.75, 49.25, 49.75], [ 1.25 + 0.125, 1.75 - 0.125, 49.25 + 0.125, 49.75 - 0.125 ], [ 1.25 + 0.125 + 0.0625, 1.75 - 0.125 - 0.0625, 49.25 + 0.125 + 0.0625, 49.75 - 0.125 - 0.0625 ]] expected_height = [10, 20, 25] lyr = ogr_ds.ExecuteSQL("select * from contour order by elev asc") if lyr.GetFeatureCount() != len(expected_envelopes): print('Got %d features. Expected %d' % (lyr.GetFeatureCount(), len(expected_envelopes))) return 'fail' i = 0 feat = lyr.GetNextFeature() while feat is not None: if feat.GetGeometryRef().GetZ(0) != expected_height[i]: print('Got %f as z. Expected %f' % (feat.GetGeometryRef().GetZ(0), expected_height[i])) return 'fail' envelope = feat.GetGeometryRef().GetEnvelope() if feat.GetField('elev') != expected_height[i]: print('Got %f. Expected %f' % (feat.GetField('elev'), expected_height[i])) return 'fail' for j in range(4): if abs(expected_envelopes[i][j] - envelope[j]) > precision / 2 * 1.001: print('i=%d, wkt=%s' % (i, feat.GetGeometryRef().ExportToWkt())) print(feat.GetGeometryRef().GetEnvelope()) print(expected_envelopes[i]) print('%f, %f' % (expected_envelopes[i][j] - envelope[j], precision / 2)) return 'fail' i = i + 1 feat = lyr.GetNextFeature() ogr_ds.ReleaseResultSet(lyr) ogr_ds.Destroy() return 'success'
def process(parsed, target, temp_metatile, temp_processed, save_offsetx, save_offsety, save_xsize, save_ysize, nodata, ot, *args, **kwargs): #target_db = target.split(".")[0] + ".sqlite" targetdb = "geodata" dbuser = "******" targettable = str(parsed.table) elevation = int(parsed.elevation) median = int(parsed.median) glacier_mask = parsed.glacier_mask nodata = 0 #print "read temp_metatile" _, gt, _, nodata, array_numpy = numpy_read(temp_metatile) processed_numpy = ndimage.median_filter(array_numpy, size=median) #processed_numpy = array_numpy #print "save processed_numpy" #print str(processed_numpy.shape[0]) + " " + str(processed_numpy.shape[1]) # geotransform values for tile xmin = gt[0] + (save_offsetx * gt[1]) xmax = gt[0] + ((save_offsetx + save_xsize) * gt[1]) ymin = gt[3] + ((save_offsety + save_ysize) * gt[5]) ymax = gt[3] + (save_offsety * gt[5]) # geotransform values for metatile save_offsetx = 0 save_offsety = 0 save_xsize = processed_numpy.shape[1] save_ysize = processed_numpy.shape[0] # create contours from processed_numpy ds = gdal.Open(temp_metatile) drv = ogr.GetDriverByName( 'Memory' ) ogr_ds = drv.CreateDataSource('out') #ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource('contours_ogr/contour.shp') ogr_lyr = ogr_ds.CreateLayer('contour', geom_type = ogr.wkbMultiLineString) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) ogr_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) ogr_lyr.CreateField(field_defn) #create Memory driver src_ds = gdal.Open( temp_metatile ) format = "MEM" driver = gdal.GetDriverByName( format ) mem_ds = driver.CreateCopy('', src_ds ) # write filtered numpy array to GDAL band gdal_array.BandWriteArray(mem_ds.GetRasterBand(1), processed_numpy) mem_ds.GetRasterBand(1).WriteArray(processed_numpy) # write contours to OGR layer gdal.ContourGenerate(mem_ds.GetRasterBand(1), elevation, 0, [], 0, 0, ogr_lyr, 0, 1) # convert 3D geometries to 2D for i in range(ogr_lyr.GetFeatureCount()): feature = ogr_lyr.GetFeature(i) geometry = feature.GetGeometryRef() geometry.SetCoordinateDimension(2) # clip to tile boundary ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(xmin, ymin) ring.AddPoint(xmin, ymax) ring.AddPoint(xmax, ymax) ring.AddPoint(xmax, ymin) ring.AddPoint(xmin, ymin) clipbox = ogr.Geometry(ogr.wkbPolygon) clipbox.AddGeometry(ring) cliplayer = ogr_ds.CreateLayer('clipbox', geom_type=ogr.wkbPolygon) clipfeaturedefn = cliplayer.GetLayerDefn() clipfeature = ogr.Feature(clipfeaturedefn) clipfeature.SetGeometry(clipbox) cliplayer.CreateFeature(clipfeature) clipped = ogr_ds.CreateLayer('contour_clipped', geom_type=ogr.wkbMultiLineString) #clipped.ForceToMultiLineString() field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) clipped.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) clipped.CreateField(field_defn) ogr_lyr.Clip(cliplayer, clipped) # PostGIS connection #connection = db.connect('contours.sqlite') connection = psycopg2.connect(database = targetdb, user = dbuser) # psql -d geodata -c "DROP TABLE contours; CREATE TABLE contours (id bigserial primary key, elev double precision, type text); SELECT AddGeometryColumn ('','contours','the_geom',4326,'MULTILINESTRING',2);" cursor = connection.cursor() if glacier_mask: # read glacier_mask shapefile = glacier_mask driver = ogr.GetDriverByName("ESRI Shapefile") dataSource = driver.Open(shapefile, 0) glacier_layer = dataSource.GetLayer() glacier_layer_clipped = ogr_ds.CreateLayer('glacier_clipped', geom_type=ogr.wkbPolygon) glacier_layer.Clip(cliplayer, glacier_layer_clipped) #print "processing land contours" # clip & save land contours land_clipped = ogr_ds.CreateLayer('contour_clipped', geom_type=ogr.wkbMultiLineString) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) land_clipped.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) land_clipped.CreateField(field_defn) if glacier_layer_clipped.GetFeatureCount() == 0: land_clipped = clipped else: # create inverse clip inverse_clip = ogr_ds.CreateLayer('inverse_clip', geom_type=ogr.wkbPolygon) cliplayer.Erase(glacier_layer_clipped, inverse_clip) clipped.Clip(inverse_clip, land_clipped) contour_type = "land" for i in range(land_clipped.GetFeatureCount()): feature = land_clipped.GetFeature(i) geometry = feature.GetGeometryRef() # hack removing loose points from geometry if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") : continue if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" : geometry_new = ogr.Geometry(ogr.wkbMultiLineString) for i in xrange(geometry.GetGeometryCount()): g = geometry.GetGeometryRef(i) if g.GetGeometryName() == "LINESTRING" : geometry_new.AddGeometry(g.Clone()) geometry = geometry_new elev = feature.GetField("elev") geometry.SetCoordinateDimension(2) wkt = geometry.ExportToWkt() cursor.execute("INSERT INTO " + targettable + " (elev,the_geom,type) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)), %s)", (elev, wkt, contour_type)) connection.commit() #print "processing glacier contours" # clip & save glacier contours glacier_clipped = ogr_ds.CreateLayer('glacier_clipped', geom_type=ogr.wkbMultiLineString) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) glacier_clipped.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) glacier_clipped.CreateField(field_defn) clipped.Clip(glacier_layer_clipped, glacier_clipped) contour_type = "glaciated" for i in range(glacier_clipped.GetFeatureCount()): feature = glacier_clipped.GetFeature(i) geometry = feature.GetGeometryRef() # hack removing loose points from geometry if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") : continue if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" : geometry_new = ogr.Geometry(ogr.wkbMultiLineString) for i in xrange(geometry.GetGeometryCount()): g = geometry.GetGeometryRef(i) if g.GetGeometryName() == "LINESTRING" : geometry_new.AddGeometry(g.Clone()) geometry = geometry_new elev = feature.GetField("elev") geometry.SetCoordinateDimension(2) wkt = geometry.ExportToWkt() cursor.execute("INSERT INTO " + targettable + " (elev,the_geom,type) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)), %s)",(elev, wkt, contour_type)) connection.commit() else: # save to POSTGIS for i in range(clipped.GetFeatureCount()): feature = clipped.GetFeature(i) geometry = feature.GetGeometryRef() # hack removing loose points from geometry if geometry.GetGeometryName() in ("POINT", "MULTIPOINT") : continue if geometry.GetGeometryName() == "GEOMETRYCOLLECTION" : geometry_new = ogr.Geometry(ogr.wkbMultiLineString) for i in xrange(geometry.GetGeometryCount()): g = geometry.GetGeometryRef(i) if g.GetGeometryName() == "LINESTRING" : geometry_new.AddGeometry(g.Clone()) geometry = geometry_new elev = feature.GetField("elev") #feature_geometry = ogr.ForceToMultiLineString(feature.GetGeometryRef()) geometry.SetCoordinateDimension(2) wkt = geometry.ExportToWkt() cursor.execute("INSERT INTO " + targettable + " (elev,the_geom) VALUES (%s, ST_Multi(ST_GeomFromText(%s, " +"4326)))", (elev, wkt)) connection.commit() ogr_ds.Destroy() processed_numpy = [] mem_ds = None #os.remove(target) #os.remove(temp_target) cursor.close() connection.close()
def isobands(in_file, band, out_file, out_format, layer_name, attr_name, offset, interval, min_level=None): ''' The method that calculates the isobands ''' #Loading the raster file ds_in = gdal.Open(in_file) band_in = ds_in.GetRasterBand(band) xsize_in = band_in.XSize ysize_in = band_in.YSize stats = band_in.GetStatistics(True, True) if min_level == None: min_value = stats[0] min_level = (offset + interval * (floor( (min_value - offset) / interval) - 1)) nodata_value = min_level - interval geotransform_in = ds_in.GetGeoTransform() srs = osr.SpatialReference() srs.ImportFromWkt(ds_in.GetProjectionRef()) data_in = band_in.ReadAsArray(0, 0, xsize_in, ysize_in) #The contour memory contour_ds = ogr.GetDriverByName('Memory').CreateDataSource('') contour_lyr = contour_ds.CreateLayer('contour', geom_type=ogr.wkbLineString25D, srs=srs) field_defn = ogr.FieldDefn('ID', ogr.OFTInteger) contour_lyr.CreateField(field_defn) field_defn = ogr.FieldDefn('elev', ogr.OFTReal) contour_lyr.CreateField(field_defn) #The in memory raster band, with new borders to close all the polygons driver = gdal.GetDriverByName('MEM') xsize_out = xsize_in + 2 ysize_out = ysize_in + 2 column = numpy.ones((ysize_in, 1)) * nodata_value line = numpy.ones((1, xsize_out)) * nodata_value data_out = numpy.concatenate((column, data_in, column), axis=1) data_out = numpy.concatenate((line, data_out, line), axis=0) ds_mem = driver.Create('', xsize_out, ysize_out, 1, band_in.DataType) ds_mem.GetRasterBand(1).WriteArray(data_out, 0, 0) ds_mem.SetProjection(ds_in.GetProjection()) #We have added the buffer! ds_mem.SetGeoTransform( (geotransform_in[0] - geotransform_in[1], geotransform_in[1], 0, geotransform_in[3] - geotransform_in[5], 0, geotransform_in[5])) gdal.ContourGenerate(ds_mem.GetRasterBand(1), interval, offset, [], 0, 0, contour_lyr, 0, 1) #Creating the output vectorial file drv = ogr.GetDriverByName(out_format) if exists(out_file): remove(out_file) dst_ds = drv.CreateDataSource(out_file) dst_layer = dst_ds.CreateLayer(layer_name, geom_type=ogr.wkbPolygon, srs=srs) fdef = ogr.FieldDefn(attr_name, ogr.OFTReal) dst_layer.CreateField(fdef) contour_lyr.ResetReading() geometry_list = {} for feat_in in contour_lyr: value = feat_in.GetFieldAsDouble(1) geom_in = feat_in.GetGeometryRef() points = geom_in.GetPoints() if ((value >= min_level and points[0][0] == points[-1][0]) and (points[0][1] == points[-1][1])): if (value in geometry_list) is False: geometry_list[value] = [] pol = ogr.Geometry(ogr.wkbPolygon) ring = ogr.Geometry(ogr.wkbLinearRing) for point in points: p_y = point[1] p_x = point[0] if p_x < (geotransform_in[0] + 0.5 * geotransform_in[1]): p_x = geotransform_in[0] + 0.5 * geotransform_in[1] elif p_x > ((geotransform_in[0] + (xsize_in - 0.5) * geotransform_in[1])): p_x = (geotransform_in[0] + (xsize_in - 0.5) * geotransform_in[1]) if p_y > (geotransform_in[3] + 0.5 * geotransform_in[5]): p_y = geotransform_in[3] + 0.5 * geotransform_in[5] elif p_y < ((geotransform_in[3] + (ysize_in - 0.5) * geotransform_in[5])): p_y = (geotransform_in[3] + (ysize_in - 0.5) * geotransform_in[5]) ring.AddPoint_2D(p_x, p_y) pol.AddGeometry(ring) geometry_list[value].append(pol) values = sorted(geometry_list.keys()) geometry_list2 = {} for i in range(len(values)): geometry_list2[values[i]] = [] interior_rings = [] for j in range(len(geometry_list[values[i]])): if (j in interior_rings) == False: geom = geometry_list[values[i]][j] for k in range(len(geometry_list[values[i]])): if ((k in interior_rings) == False and (j in interior_rings) == False): geom2 = geometry_list[values[i]][k] if j != k and geom2 != None and geom != None: if geom2.Within(geom) == True: geom3 = geom.Difference(geom2) interior_rings.append(k) geometry_list[values[i]][j] = geom3 elif geom.Within(geom2) == True: geom3 = geom2.Difference(geom) interior_rings.append(j) geometry_list[values[i]][k] = geom3 for j in range(len(geometry_list[values[i]])): if ((j in interior_rings) == False and geometry_list[values[i]][j] != None): geometry_list2[values[i]].append(geometry_list[values[i]][j]) for i in range(len(values)): value = values[i] if value >= min_level: for geom in geometry_list2[values[i]]: if i < len(values) - 1: for geom2 in geometry_list2[values[i + 1]]: if geom.Intersects(geom2) is True: geom = geom.Difference(geom2) feat_out = ogr.Feature(dst_layer.GetLayerDefn()) feat_out.SetField(attr_name, value) feat_out.SetGeometry(geom) if dst_layer.CreateFeature(feat_out) != 0: print "Failed to create feature in shapefile.\n" exit(1) feat_out.Destroy()
#Save_NDVI_Change saveRaster(ndviChange, path_NDVIChange, cols, rows, projection) # In[41]: #Plot_NDVI_Change plotNDVI(path_NDVIChange, extentArray, -0.5, 'Spectral') # In[43]: #Create Contourlines Dataset_ndvi = gdal.Open(path_NDVIChange) #path_NDVI_2014 ndvi_raster = Dataset_ndvi.GetRasterBand(1) ogr_ds = ogr.GetDriverByName("ESRI Shapefile").CreateDataSource( contours_NDVIChange) prj = Dataset_ndvi.GetProjectionRef() #GetProjection() srs = osr.SpatialReference(wkt=prj) # #srs.ImportFromProj4(prj) contour_shp = ogr_ds.CreateLayer('contour', srs) field_defn = ogr.FieldDefn("ID", ogr.OFTInteger) contour_shp.CreateField(field_defn) field_defn = ogr.FieldDefn("ndviChange", ogr.OFTReal) contour_shp.CreateField(field_defn) #Generate Contourlines gdal.ContourGenerate(ndvi_raster, 0.1, 0, [], 1, -999, contour_shp, 0, 1) ogr_ds = None
def generateContours(overwrite, src, dest): #Create destination folder if it does not already exist os.makedirs(dest, exist_ok=True) dated_sections = determine_section_week_contour(src) for pairs in dated_sections: section = pairs[0] week = pairs[1] #List of all the rasters in the current week and section that has the M3C2 layer all_files = [ x for x in os.listdir(src) if "Zone" + section in x and date_boundary(x, week) and "Raster_Z.tif" in x ] for filename in all_files: #Check if the path already exists if overwrite or not os.path.exists(dest + "\\" + filename.replace( ".tif", "_Contour_Shapefile.shp").replace("Raster_Z", "")): pathname = src + "\\" + filename writefilename = src + "\\" + filename.replace( ".tif", "_temp.tif") #Read M3C2 band from raster [xsize, ysize, geotransform, geoproj, Z] = readFile(pathname) #Set NaN values to 9999 Z[numpy.isnan(Z)] = 9999 #Rewrite the M3C2 band to a file writeFile(writefilename, geotransform, geoproj, Z) print("Contour plotting for: ") print(filename) print("") #Import your image from file. Select band to contour. If a DSM will probably be band 1. image = gdal.Open(src + "\\" + filename.replace(".tif", "_temp.tif")) band = image.GetRasterBand(1) #Generate shapefile to save Contourlines in outShapefile = pathname.replace(".tif", "") driver = ogr.GetDriverByName("ESRI Shapefile") #Generates new layer in shapefile outDataSource = driver.CreateDataSource(outShapefile + ".shp") layer = outDataSource.CreateLayer('contour') #Add fields to new layer in shapefile. #These are shown in attribute tabe in ArcGIS. #Set Precision sets the precision to # number of decimal places id_field = ogr.FieldDefn("ID", ogr.OFTInteger) layer.CreateField(id_field) length_field = ogr.FieldDefn("Length", ogr.OFTReal) length_field.SetPrecision(8) layer.CreateField(length_field) area_field = ogr.FieldDefn("Area", ogr.OFTReal) area_field.SetPrecision(8) layer.CreateField(area_field) m3c2_field = ogr.FieldDefn("M3C2", ogr.OFTReal) m3c2_field.SetPrecision(5) layer.CreateField(m3c2_field) """ Generate Contourlines. band= band of raster layer to contour- as defined above 0.003 - contour interval value -0.4- first contour value [] - List takes priority over the previous two arguments, contours are only at these levels 0 0 layer - the output layer 0 - the index of the id field 3 - the index of the elevation (M3C2) field """ gdal.ContourGenerate(band, 0.003, -0.4, [x / 1000 for x in range(-3000, 0, 1)], 0, 0, layer, 0, 3) #gdal.ContourGenerate(band, 0.003, -0.4, [x / 10000 for x in range(-3000,0,1)], 0, 0, layer, 0, 3) #delete particular features in attribute table. for features in layer: geom = features.GetGeometryRef() length = geom.Length() area = geom.Area() features.SetField( "Length", length) # add length value to each feature features.SetField("Area", area) # add area value to each feature layer.SetFeature(features) #Delete contours with length less than 0.2m or area less than 0.001m^2 if length < 0.2 or area < 0.001: layer.DeleteFeature(features.GetFID()) #delete data source at the end. Important to do this otherwise code gets stuck! image = None del image outDataSource = None del outDataSource #Delete old output files if they exists and the overwrite option is on #Rename new file if overwrite and os.path.exists(dest + "\\" + filename.replace( ".tif", "_Contour_Shapefile.shp").replace( "Raster_Z", "")): os.remove(dest + "\\" + filename.replace( ".tif", "_Contour_Shapefile.shp")).replace( "Raster_Z", "") os.rename( outShapefile + ".shp", dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.shp").replace( "Raster_Z", "")) if os.path.exists( dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.dbf" ).replace("Raster_Z", "")): os.remove(dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.dbf" ).replace("Raster_Z", "")) os.rename( outShapefile + ".dbf", dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.dbf").replace( "Raster_Z", "")) if os.path.exists( dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.shx" ).replace("Raster_Z", "")): os.remove(dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.shx" ).replace("Raster_Z", "")) os.rename( outShapefile + ".shx", dest + "\\" + filename.replace(".tif", "_Contour_Shapefile.shx").replace( "Raster_Z", "")) os.remove(writefilename) print("Section " + section + " Week " + week + " Completed") print("")
def shakemap_contour(shakemap_layer_path, output_file_path='', active_band=1): """Creating contour from a shakemap layer. :param shakemap_layer_path: The shake map raster layer path. :type shakemap_layer_path: basestring :param output_file_path: The path where the contour will be saved. :type output_file_path: basestring :param active_band: The band which the data located, default to 1. :type active_band: int :returns: The contour of the shake map layer path. :rtype: basestring """ # Set output path if not output_file_path: # There are minor issues with shapefile, so we switch to gpkg # See https://github.com/inasafe/inasafe/issues/5063 output_file_path = unique_filename(suffix='.gpkg', dir=temp_dir()) output_directory = os.path.dirname(output_file_path) output_file_name = os.path.basename(output_file_path) output_base_name = os.path.splitext(output_file_name)[0] # Based largely on # http://svn.osgeo.org/gdal/trunk/autotest/alg/contour.py # Use Geopackage driver to overcome this: # See https://github.com/inasafe/inasafe/issues/5063 driver = ogr.GetDriverByName('GPKG') ogr_dataset = driver.CreateDataSource(output_file_path) if ogr_dataset is None: # Probably the file existed and could not be overriden raise ContourCreationError( 'Could not create datasource for:\n%s. Check that the file ' 'does not already exist and that you do not have file system ' 'permissions issues' % output_file_path) # Set default fid options = ['FID={}'.format(contour_id_field['field_name'])] layer = ogr_dataset.CreateLayer('contour', options=options) for contour_field in contour_fields: field_definition = create_ogr_field_from_definition(contour_field) layer.CreateField(field_definition) shakemap_data = gdal.Open(shakemap_layer_path, GA_ReadOnly) # see http://gdal.org/java/org/gdal/gdal/gdal.html for these options contour_interval = 0.5 contour_base = 0 fixed_level_list = [] use_no_data_flag = 0 no_data_value = -9999 id_field = 0 # first field defined above elevation_field = 1 # second (MMI) field defined above try: gdal.ContourGenerate(shakemap_data.GetRasterBand(active_band), contour_interval, contour_base, fixed_level_list, use_no_data_flag, no_data_value, layer, id_field, elevation_field) except Exception as e: LOGGER.exception('Contour creation failed') raise ContourCreationError(str(e)) finally: ogr_dataset.Release() # Copy over the standard .prj file since ContourGenerate does not # create a projection definition projection_path = os.path.join(output_directory, output_base_name + '.prj') source_projection_path = resources_path('converter_data', 'mmi-contours.prj') shutil.copyfile(source_projection_path, projection_path) # Lastly copy over the standard qml (QGIS Style file) qml_path = os.path.join(output_directory, output_base_name + '.qml') source_qml_path = resources_path('converter_data', 'mmi-contours.qml') shutil.copyfile(source_qml_path, qml_path) # Create metadata file create_contour_metadata(output_file_path) # Now update the additional columns - X,Y, ROMAN and RGB try: set_contour_properties(output_file_path) except InvalidLayerError: raise del shakemap_data return output_file_path
def bound_clusters_in_raster(a, aa, shape_file_dir, contour_interval, contour_value, use_bb=True, use_distance=False): """Create a shapefile that contains contours and bounding boxes for clusters of contours. :param a: A numpy array that contains the data inwhich to find clusters :type a: Numpy array :param aa: The analysis object that sets the coordinate system for the area that contains the array :type aa: ambry.geo.AnalysisArea :param shape_file_dir: The path to a directory where generated files will be stored. :type shape_file_dir: string :param contour_interval: The difference between successive contour intervals. :type contour_interval: float :param contour_value: :type contour_value: float :param use_bb: If True, compute nearness and intersection using the contours bounding boxes, not the geometry :type use_bb: bool :param use_distance: If not False, consider contours that are closer than this value to be overlapping. :type : number :rtype: Returns a list of dictionaries, one for each of the combined bounding boxes This method will store, in the `shape_file_dir` directory: * a GeoTIFF representation of the array `a` * An ERSI shapefile layer named `countours`, holding all of the countours. * A layer named `contour_bounds` with the bounding boxes for all of the contours with value `contour_value` * A layer named `combined_bounds` with bounding boxes of intersecting and nearby boxes rom `contour_bounds` The routine will iteratively combine contours that overlap. If `use_distance` is set to a number, and contours that are closer than this value will be joined. If `use_bb` is set, the intersection and distance computations use the bounding boxes of the contours, not the contours themselves. """ import ambry.geo as dg from osgeo.gdalconst import GDT_Float32 import ambry.util as util from osgeo import gdal import ogr import os import numpy as np if os.path.exists(shape_file_dir): util.rm_rf(shape_file_dir) os.makedirs(shape_file_dir) rasterf = os.path.join(shape_file_dir, 'contour.tiff') ogr_ds = ogr.GetDriverByName('ESRI Shapefile').CreateDataSource( shape_file_dir) # Setup the countour layer. ogr_lyr = ogr_ds.CreateLayer('contours', aa.srs) ogr_lyr.CreateField(ogr.FieldDefn('id', ogr.OFTInteger)) ogr_lyr.CreateField(ogr.FieldDefn('value', ogr.OFTReal)) # Create the contours from the GeoTIFF file. ds = aa.get_geotiff(rasterf, data_type=GDT_Float32) ds.GetRasterBand(1).SetNoDataValue(0) ds.GetRasterBand(1).WriteArray(np.flipud(a)) gdal.ContourGenerate( ds.GetRasterBand(1), contour_interval, # contourInterval 0, # contourBase [], # fixedLevelCount 0, # useNoData 0, # noDataValue ogr_lyr, # destination layer 0, # idField 1 # elevation field ) # Get buffered bounding boxes around each of the hotspots, # and put them into a new layer. bound_lyr = ogr_ds.CreateLayer('contour_bounds', aa.srs) for i in range(ogr_lyr.GetFeatureCount()): f1 = ogr_lyr.GetFeature(i) if f1.GetFieldAsDouble('value') != contour_value: continue g1 = f1.GetGeometryRef() bb = dg.create_bb(g1.GetEnvelope(), g1.GetSpatialReference()) f = ogr.Feature(bound_lyr.GetLayerDefn()) f.SetGeometry(bb) bound_lyr.CreateFeature(f) # Doing a full loop instead of a list comprehension b/c the way that comprehensions # compose arrays results in segfaults, probably because a copied geometry # object is being released before being used. geos = [] for i in range(bound_lyr.GetFeatureCount()): f = bound_lyr.GetFeature(i) g = f.geometry() geos.append(g.Clone()) # Combine hot spots that have intersecting bounding boxes, to get larger # areas that cover all of the adjacent intersecting smaller areas. geos = dg.combine_envelopes(geos, use_bb=use_bb, use_distance=use_distance) # Write out the combined bounds areas. lyr = ogr_ds.CreateLayer('combined_bounds', aa.srs) lyr.CreateField(ogr.FieldDefn('id', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('area', ogr.OFTReal)) lyr.CreateField(ogr.FieldDefn('name', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('code', ogr.OFTString)) envelopes = [] id = 1 for env in geos: f = ogr.Feature(lyr.GetLayerDefn()) bb = dg.create_bb(env.GetEnvelope(), env.GetSpatialReference()) f.SetGeometry(bb) f.SetField(0, id) f.SetField(1, bb.Area()) f.SetField(2, None) f.SetField(3, None) id += 1 lyr.CreateFeature(f) envelopes.append({ 'id': id, 'env': bb.GetEnvelope(), 'area': bb.Area() }) return envelopes