Beispiel #1
0
def merge_files(f1, f2, out):
    print("Merging files...")
    try:        
        fgc_shp = ogr.Open(f1)
        lyr1 = fgc_shp.GetLayer() 
        
        fgc_shp2 = ogr.Open(f2)
        lyr2 = fgc_shp2.GetLayer()
    
        driver=ogr.GetDriverByName('ESRI Shapefile')
        ds=driver.CreateDataSource(out)
    
        merge_lyr = ds.CreateLayer('temp', lyr2.GetSpatialRef(), ogr.wkbMultiPolygon )
    #   diff_lyr = createFieldsFrom(lyr2, diff_lyr)
    
        print("    First file uninon..")
        union1 = ogr.Geometry(ogr.wkbMultiPolygon)
        for feat1 in lyr1:
            geom1 = feat1.GetGeometryRef()
            if geom1 != None: 
                union1 = union1.Union(geom1)
                 
            geom1 = None
        print("    Second file uninon..")    
        union2 = ogr.Geometry(ogr.wkbMultiPolygon)
        for feat2 in lyr2:
            geom2 = feat2.GetGeometryRef()
            if geom2 != None:        
                union2 = union2.Union(geom2) 
            geom2 = None
          
                
        union1 = union1.Buffer(0)
        union2 = union2.Buffer(0)
        
        print("    Final uninon..")
        merge = union1.Union(union2)
        
        new_feat = ogr.Feature(merge_lyr.GetLayerDefn())
        new_feat.SetGeometry(merge)
        merge_lyr.CreateFeature(new_feat)   
    
    except:
        print("exception thrown!")
        traceback.print_exc()
        

    new_feat= None
    union1 = None   
    union2 = None            
    diff_lyr = None
    fgc_shp = None
    fgc_shp2 = None
    ds = None
    lyr1 = None
    lyr2 = None
Beispiel #2
0
def remove_biggest_polygon(f1, area, out):
    print("Removing biggest polygon")
    
    fgc_shp = ogr.Open(f1)
    lyr = fgc_shp.GetLayer()
    
    driver=ogr.GetDriverByName('ESRI Shapefile')
    ds=driver.CreateDataSource(out)
    
    holes_lyr = ds.CreateLayer('temp', lyr.GetSpatialRef(), ogr.wkbMultiPolygon )        
    
    
    max_area = 0.0
    max_index = 0
    for feature in lyr:
        geom = feature.GetGeometryRef() 
        print(geom.GetGeometryCount())
        for j in range(0,geom.GetGeometryCount() ):
            ring = geom.GetGeometryRef(j)
            area = ring.GetArea()
            print(area)
            if area> max_area:
                max_index = j
                max_area = area
                
              
    lyr =None
    fgc_shp = None 
#    print("max= ", max_index)
    
    fgc_shp2 = ogr.Open(f1)
    lyr2 = fgc_shp2.GetLayer()
    
    for feature in lyr2:
        geom = feature.GetGeometryRef() 
        
        for j in range(0,geom.GetGeometryCount()):
            ring = geom.GetGeometryRef(j)
            if j != max_index:
                new_feat = ogr.Feature(holes_lyr.GetLayerDefn())
                new_feat.SetGeometry(ring.Buffer(0))
                holes_lyr.CreateFeature(new_feat)
                new_feat = None
#                print(ring.GetArea())
        
    holes_lyr = None
    ds=None
    lyr =None
    fgc_shp = None
Beispiel #3
0
def addBuffer(file,size, new_file):

    fgc_shp = ogr.Open(file)
    layer = fgc_shp.GetLayer()
    
    driver=ogr.GetDriverByName('ESRI Shapefile')
    ds=driver.CreateDataSource(new_file)

    out_lyr=ds.CreateLayer('temp', layer.GetSpatialRef(), ogr.wkbPolygon)
    
    out_lyr = createFieldsFrom(layer, out_lyr)
    
    
    for feature in layer:
        geom = feature.GetGeometryRef()
        
        if geom != None:
            new_feat = ogr.Feature(out_lyr.GetLayerDefn())
            new_feat.SetFrom(feature)
            new_feat.SetGeometry(geom.Buffer(size))
            
            
            out_lyr.CreateFeature(new_feat)
        # else:
            #out_lyr.CreateFeature(feature)
                        
            new_feat = None
            geom = None
                    
    out_lyr= None
    ds=None
    driver = None
    layer = None  
    fgc_shp  = None  
Beispiel #4
0
def extent_polygon(file,out):
    fgc_shp = ogr.Open(file)
    lyr = fgc_shp.GetLayer()
    
    extent  = lyr.GetExtent()
    
    ring = ogr.Geometry(ogr.wkbLinearRing)
    ring.AddPoint(extent[0], extent[2])
    ring.AddPoint(extent[1], extent[2])
    ring.AddPoint(extent[1], extent[3])
    ring.AddPoint(extent[0], extent[3])
    ring.AddPoint(extent[0], extent[2])
    poly = ogr.Geometry(ogr.wkbPolygon)
    poly.AddGeometry(ring)

    driver=ogr.GetDriverByName('ESRI Shapefile')
    ds=driver.CreateDataSource(out)    
    extent_lyr = ds.CreateLayer('temp', lyr.GetSpatialRef(), ogr.wkbMultiPolygon )      
    new_feat = ogr.Feature(extent_lyr.GetLayerDefn())
    new_feat.SetGeometry(poly)
    extent_lyr.CreateFeature(new_feat)
    
    extent_lyr = None
    ds = None
    driver = None
    new_feat = None
    lyr = None
    fgc_shp = None
def get_interesecting_vdatum_regions(datafilepath):
    """
    Find the vdatum regions that intersect the given data.
    """
    dataset = gdal.Open(datafilepath)
    is_raster = dataset.RasterCount > 0
    if is_raster:
        # get raster bounds
        crs = pyproj.CRS.from_wkt(dataset.GetProjectionRef())
        transform = dataset.GetGeoTransform()
        pixelWidth = transform[1]
        pixelHeight = transform[5]
        cols = dataset.RasterXSize
        rows = dataset.RasterYSize
        x0 = transform[0]
        y1 = transform[3]
        x1 = x0+cols*pixelWidth
        y0 = y1-rows*pixelHeight
        if crs.is_projected:
            unproject = pyproj.Proj(proj='utm', zone = 19, ellps = 'WGS84')
            ul = unproject(x0,x1, inverse = True)
            ur = unproject(x1, y1, inverse = True)
            lr = unproject(x1, y0, inverse = True)
            ll = unproject(x0, y0, inverse = True)
        else:
            ul = (x0, y1)
            ur = (x1, y1)
            lr = (x1, y0)
            ll = (x0, y0)
        # build polygon from raster
        ring = ogr.Geometry(ogr.wkbLinearRing)
        ring.AddPoint(ul[0], ul[1])
        ring.AddPoint(ur[0], ur[1])
        ring.AddPoint(lr[0], lr[1])
        ring.AddPoint(ll[0], ll[1])
        ring.AddPoint(ul[0], ul[1])
        dataGeometry = ogr.Geometry(ogr.wkbPolygon)
        dataGeometry.AddGeometry(ring)
    else:
        raise NotImplementedError('Not handling XYZ data yet')
    dataset = None
    # get all the regions represented by geometry files
    geom_list = get_vdatum_region_polygons()
    # see if the regions intersect with the provided geometries
    intersecting_regions = []
    for region in geom_list:
        vector = ogr.Open(geom_list[region])
        layer_count = vector.GetLayerCount()
        for m in range(layer_count):
            layer = vector.GetLayerByIndex(m)
            feature_count = layer.GetFeatureCount()
            for n in range(feature_count):
                feature = layer.GetFeature(n)
                feature_name = feature.GetField(0)
                if feature_name[:15] == 'valid-transform':
                    valid_vdatum_poly = feature.GetGeometryRef()
                    if dataGeometry.Intersect(valid_vdatum_poly):
                        intersecting_regions.append(region)
        vector = None
    return intersecting_regions
Beispiel #6
0
def test_concav(file,out):
    
    points_by_id = get_points_from_geomety(file)
    
    
    fgc_shp = ogr.Open(file)
    lyr = fgc_shp.GetLayer()
    
    driver=ogr.GetDriverByName('ESRI Shapefile')
    
    ds1=driver.CreateDataSource(out)
    concave_lyr=ds1.CreateLayer('temp', lyr.GetSpatialRef(), ogr.wkbPolygon)
    concave_lyr = createFieldsFrom(lyr,concave_lyr)
    print("starting concave")


    ps = np.array([ ( points_by_id.iloc[xi,0] , np.array(points_by_id.iloc[xi,1]) ) for xi in range(0,points_by_id.shape[0]) ], dtype=object)

    #Processar em várias threads
    pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
    res = pool.map( temp,ps ) 
   
    print("End of concave calculations.")
    
    
    print("Saving to file")
    res = np.asarray(res,dtype=object)


    for i in range(0, res.shape[0]):
        try:
            fgc_id = res[i][0]
            hull = res[i][1]
            
            new_ring = ogr.Geometry(ogr.wkbLinearRing)
            hull = np.asarray(hull)

            for i in range(0, hull.shape[0]):
                new_ring.AddPoint(hull[i,0], hull[i,1])
                        
            poly = ogr.Geometry(ogr.wkbPolygon)
            poly.AddGeometry(new_ring)
            new_feat = ogr.Feature(concave_lyr.GetLayerDefn())
            new_feat.SetField("ID_SEQ",fgc_id)
            new_feat.SetGeometry(poly)
            concave_lyr.CreateFeature(new_feat)                   
            new_feat = None
            
        except:
            print("exception thrown!")
            traceback.print_exc()
            break
    def generate_geojson_features(self, shapefile_name):
        """
        Generates and yields a series of meteocode geodata features,
        one for each feature in <self.filepath/self.filepath.stem/
        shapefile_name>. Features are returned as ElasticSearch bulk API
        upsert actions, with documents in GeoJSON to match the ElasticSearch
        index mappings.
        :returns: Generator of ElasticSearch actions to upsert the forecast
                  polygons for given shapefile in zip archive
        """
        filepath = str(
            (self.filepath / self.filepath.stem / shapefile_name).resolve())
        data = ogr.Open(r'/vsizip/{}'.format(filepath))
        lyr = data.GetLayer()

        for feature in lyr:
            feature_json = feature.ExportToJson(as_object=True,
                                                options=['RFC7946=YES'])
            feature_json['properties']['version'] = self.version

            _id = feature_json['properties']['FEATURE_ID']

            self.items.append(feature_json)

            action = {
                '_id':
                '{}'.format(_id),
                '_index':
                INDEX_NAME.format(self.zone.lower(),
                                  shapefile_name.split('_')[2]),
                '_op_type':
                'update',
                'doc':
                feature_json,
                'doc_as_upsert':
                True
            }

            yield action
Beispiel #8
0
def get_points_from_geomety(file):
    print("Getting geometry points")    
    fgc_shp = ogr.Open(file)
    lyr = fgc_shp.GetLayer()
    
    points_by_id = pd.DataFrame(data=[], columns=["id","points"])
    
    for feature in  lyr:
#        print("entrou")
        i_desc_fgc = feature.GetFieldIndex("ID_SEQ")
        fgc_id = feature.GetFieldAsInteger(i_desc_fgc)
        geom = feature.GetGeometryRef() 
           

        for j in range(0,geom.GetGeometryCount() ):
            ring = geom.GetGeometryRef(j)
            if ring != None:
                #Se a faixa ainda nao foi vista adiciona ao dataframe
                if(points_by_id[points_by_id.iloc[:,0]==fgc_id].shape[0] == 0):
                    points_by_id = points_by_id.append({'id' : fgc_id , 'points' :[] } , ignore_index=True)
                
                #Adicionar os pontos a lista de pontos da respetiva faixa
#                temp_points = points_by_id[points_by_id.iloc[:,0]==fgc_id].iloc[0,1]
#                print("  ",j," has", ring.GetPointCount(), " points" )
                for i in range(0, ring.GetPointCount()):
                    lon, lat, z = ring.GetPoint(i)
                    points_by_id[points_by_id.iloc[:,0]==fgc_id].iloc[0,1].append((lon,lat))
#                    temp_points.append((lon,lat))
#            else:
#                print("  ",j," is None" )
#                points_by_id[points_by_id.iloc[:,0]==fgc_id].iloc[0,1] =temp_points
       
    fgc_shp = None
    lyr = None    
    
    return points_by_id
Beispiel #9
0
    def _tiger_to_tract(self, infile):
        """ Converts collection of Census Tiger files into a geopandas.GeoDataFrame of census tracts
            Modified from original at
            https://svn.osgeo.org/gdal/tags/1.4.3/gdal/pymod/samples/tigerpoly.py
        """

        class Module(object):
            def __init__(mod):
                mod.lines = {}
                mod.poly_line_links = {}

        outfile = 'tracts.shp'

        # Open the datasource to operate on.
        ds = ogr.Open(infile, update=0)
        poly_layer = ds.GetLayerByName('Polygon')

        # Create output file for the composed polygons.
        nad83 = osr.SpatialReference()
        nad83.SetFromUserInput('NAD83')

        shp_driver = ogr.GetDriverByName('ESRI Shapefile')
        shp_driver.DeleteDataSource(outfile)

        shp_ds = shp_driver.CreateDataSource(outfile)
        shp_layer = shp_ds.CreateLayer(
            'out', geom_type=ogr.wkbPolygon, srs=nad83)

        src_defn = poly_layer.GetLayerDefn()
        poly_field_count = src_defn.GetFieldCount()

        for fld_index in range(poly_field_count):
            src_fd = src_defn.GetFieldDefn(fld_index)

            fd = ogr.FieldDefn(src_fd.GetName(), src_fd.GetType())
            fd.SetWidth(src_fd.GetWidth())
            fd.SetPrecision(src_fd.GetPrecision())
            shp_layer.CreateField(fd)

        # Read all features in the line layer, holding just the geometry in a hash
        # for fast lookup by TLID.

        line_layer = ds.GetLayerByName('CompleteChain')
        line_count = 0

        modules_hash = {}

        feat = line_layer.GetNextFeature()
        geom_id_field = feat.GetFieldIndex('TLID')
        tile_ref_field = feat.GetFieldIndex('MODULE')
        while feat is not None:
            geom_id = feat.GetField(geom_id_field)
            tile_ref = feat.GetField(tile_ref_field)

            try:
                module = modules_hash[tile_ref]
            except:
                module = Module()
                modules_hash[tile_ref] = module

            module.lines[geom_id] = feat.GetGeometryRef().Clone()
            line_count = line_count + 1

            feat.Destroy()

            feat = line_layer.GetNextFeature()

        # Read all polygon/chain links and build a hash keyed by POLY_ID listing
        # the chains (by TLID) attached to it.

        link_layer = ds.GetLayerByName('PolyChainLink')

        feat = link_layer.GetNextFeature()
        geom_id_field = feat.GetFieldIndex('TLID')
        tile_ref_field = feat.GetFieldIndex('MODULE')
        lpoly_field = feat.GetFieldIndex('POLYIDL')
        rpoly_field = feat.GetFieldIndex('POLYIDR')

        link_count = 0

        while feat is not None:
            module = modules_hash[feat.GetField(tile_ref_field)]

            tlid = feat.GetField(geom_id_field)

            lpoly_id = feat.GetField(lpoly_field)
            rpoly_id = feat.GetField(rpoly_field)

            if lpoly_id == rpoly_id:
                feat.Destroy()
                feat = link_layer.GetNextFeature()
                continue

            try:
                module.poly_line_links[lpoly_id].append(tlid)
            except:
                module.poly_line_links[lpoly_id] = [tlid]

            try:
                module.poly_line_links[rpoly_id].append(tlid)
            except:
                module.poly_line_links[rpoly_id] = [tlid]

            link_count = link_count + 1

            feat.Destroy()

            feat = link_layer.GetNextFeature()

        # Process all polygon features.

        feat = poly_layer.GetNextFeature()
        tile_ref_field = feat.GetFieldIndex('MODULE')
        polyid_field = feat.GetFieldIndex('POLYID')

        degenerate_count = 0

        while feat is not None:
            module = modules_hash[feat.GetField(tile_ref_field)]
            polyid = feat.GetField(polyid_field)

            tlid_list = module.poly_line_links[polyid]

            link_coll = ogr.Geometry(type=ogr.wkbGeometryCollection)
            for tlid in tlid_list:
                geom = module.lines[tlid]
                link_coll.AddGeometry(geom)

            try:
                poly = ogr.BuildPolygonFromEdges(link_coll)

                if poly.GetGeometryRef(0).GetPointCount() < 4:
                    degenerate_count = degenerate_count + 1
                    poly.Destroy()
                    feat.Destroy()
                    feat = poly_layer.GetNextFeature()
                    continue

                feat2 = ogr.Feature(feature_def=shp_layer.GetLayerDefn())

                for fld_index in range(poly_field_count):
                    feat2.SetField(fld_index, feat.GetField(fld_index))

                feat2.SetGeometryDirectly(poly)

                shp_layer.CreateFeature(feat2)
                feat2.Destroy()

            except:
                warn('BuildPolygonFromEdges failed.')

            feat.Destroy()

            feat = poly_layer.GetNextFeature()

        if degenerate_count:
            warn('Discarded %d degenerate polygons.' % degenerate_count)

        # Cleanup

        shp_ds.Destroy()
        shp_ds = None
        ds.Destroy()
        ds = None

        # build a fully-qualified fips code and dissolve on it to create tract geographies
        gdf = gpd.read_file(outfile)

        if "CTBNA90" in gdf.columns:

            gdf = gdf.rename(columns={"CTBNA90": 'TRACT', "BLK90": "BLOCK"})

        gdf['STATE'] = gdf['STATE'].astype(str).str.rjust(2, "0")
        gdf['COUNTY'] = gdf['COUNTY'].astype(str).str.rjust(3, "0")
        gdf['TRACT'] = gdf['TRACT'].astype(str).str.rjust(6, "0")
        gdf['BLOCK'] = gdf['BLOCK'].astype(str).str.rjust(4, "0")
        gdf['fips'] = gdf.STATE + gdf.COUNTY + gdf.TRACT
        if self.geom == 'block':
            gdf['fips'] += gdf.BLOCK

        gdf = gdf.dropna(subset=['fips'])
        gdf.geometry = gdf.buffer(0)
        gdf = gdf.dissolve(by='fips')
        gdf.reset_index(inplace=True)

        shp_driver.DeleteDataSource(outfile)

        return gdf
Beispiel #10
0
def difference(f1, f2, out):
    try: 
        print("Difference between:")
        print("   ",f1)
        print("   ",f2)
        fgc_shp = ogr.Open(f1)
        lyr1 = fgc_shp.GetLayer() 
        
        fgc_shp2 = ogr.Open(f2)
        lyr2 = fgc_shp2.GetLayer()
    
        driver=ogr.GetDriverByName('ESRI Shapefile')
        ds=driver.CreateDataSource(out)
    
        diff_lyr = ds.CreateLayer('temp', lyr2.GetSpatialRef(), ogr.wkbMultiPolygon )
    #   diff_lyr = createFieldsFrom(lyr2, diff_lyr)
    
        
        union1 = ogr.Geometry(ogr.wkbMultiPolygon)
        for feat1 in lyr1:
            geom1 = feat1.GetGeometryRef()
            if geom1 != None: 
                union1 = union1.Union(geom1)
                 
            geom1 = None
            
        union2 = ogr.Geometry(ogr.wkbMultiPolygon)
        for feat2 in lyr2:
            geom2 = feat2.GetGeometryRef()
            if geom2 != None:        
                union2 = union2.Union(geom2) 
            geom2 = None
          
                
        union1 = union1.Buffer(0)
        union2 = union2.Buffer(0)
        
        print(union1.GetGeometryCount())
        
        diff = union1.Difference(union2)
        
        new_feat = ogr.Feature(diff_lyr.GetLayerDefn())
        new_feat.SetGeometry(diff)
        diff_lyr.CreateFeature(new_feat)   
    

#        union1 = ogr.Geometry(ogr.wkbMultiPolygon)
#        for feat1 in lyr1:
#            geom1 = feat1.GetGeometryRef()
#            fgc_shp2 = ogr.Open(f2)
#            lyr2 = fgc_shp2.GetLayer()
#            for feat2 in lyr2:   
#                geom2 = feat2.GetGeometryRef()
#                if geom1 != None  and geom2 != None:
##                    if geom2.Intersects(geom1) or geom2.Within(geom1) or geom2.Overlaps(geom1) or geom2.Crosses(geom1):
#                        diff = geom1.SymmetricDifference(geom2)
#                        if diff != None:
#                            union1.AddGeometry(diff)
##                            new_feat = ogr.Feature(diff_lyr.GetLayerDefn())
##                            new_feat.SetGeometry(diff)
##                            diff_lyr.CreateFeature(new_feat)
#                        
#                        geom2 = None
#                        new_feat = None
#                        diff=None
#            
#            geom1 = None
        
#        new_feat = ogr.Feature(diff_lyr.GetLayerDefn())
#        new_feat.SetGeometry(union1)
#        diff_lyr.CreateFeature(new_feat)
    
    except:
        print("exception thrown!")
        traceback.print_exc()
        

    new_feat= None
    union1 = None   
    union2 = None            
    diff_lyr = None
    fgc_shp = None
    fgc_shp2 = None
    ds = None
    lyr1 = None
    lyr2 = None
Beispiel #11
0
error_missing_str = "{0} geopackage must be specified either by {1} or --{0} argument"

if not areas_path:
    logging.error(error_missing_str.format(AREAS_ARG_NAME, AREAS_ENV_VAR_NAME))
    exit(1)

if not local_features_path:
    logging.error(
        error_missing_str.format(LOCAL_FEATURES_ARG_NAME,
                                 LOCAL_FEATURES_ENV_VAR_NAME))
    exit(1)
else:
    # application expects the env var alone to provide this path, so ensure it has the correct value
    os.environ[LOCAL_FEATURES_ENV_VAR_NAME] = local_features_path

datasource = ogr.Open(areas_path)
if not datasource:
    logging.error("Could not open {0}. Exiting".format(areas_path))
    exit(1)

if datasource.GetLayerCount() != 1:
    logging.error("Expected 1 layer but instead found {0}. Exiting".format(
        datasource.GetLayerCount()))
    exit(1)


def get_bounding_box(geom: ogr.Geometry) -> ogr.Geometry:
    return ogr.CreateGeometryFromWkt(
        f"POLYGON (({min_x} {min_y},{max_x} {min_y},{max_x} {max_y},{min_x} {max_y},{min_x} {min_y}))"
    )
def static_maps(
    source,  # source folder containing clone
    destination,  # destination folder
    inifile,  # ini file with various settings
    dem_in,  # path to digital elevation model (raster)
    rivshp,  # path to river network (line vector)
    catchshp,  # path to catchment polygon (polygon vector)
    gaugeshp=None,  # path to gauge point (point vector)
    landuse=None,  # path to land use / land cover (raster)
    soil=None,  # path to soil type (raster)
    lai=None,  # path to vegetation LAI (containing 12 GeoTiffs LAI00000.XXX.tif)
    other_maps=None,  # bracketed [] comma-separated list of paths to other maps that should be reprojected
    logfilename="wtools_static_maps.log",  # log file name
    verbose=True,
    clean=True,  # Clean the .xml files from static maps folder when finished
    alltouch=False,  # option to burn catchments "all touching".\nUseful when catchment-size is small compared to cellsize
    outlets=([], []),
):
    # parse other maps into an array
    if not other_maps == None:
        if type(other_maps) == str:
            print(other_maps)
            other_maps = (
                other_maps.replace(" ", "").replace("[", "").replace("]", "").split(",")
            )

    source = os.path.abspath(source)
    clone_tif = os.path.join(source, "mask.tif")
    clone_map = os.path.join(source, "mask.map")
    clone_shp = os.path.join(source, "mask.shp")
    clone_prj = os.path.join(source, "mask.prj")

    # open a logger, dependent on verbose print to screen or not
    logger, ch = wt.setlogger(logfilename, "WTOOLS", verbose)

    # create directories # TODO: check if workdir is still necessary, try to
    # keep in memory as much as possible

    # delete old files (when the source and destination folder are different)
    if np.logical_and(os.path.isdir(destination), destination is not source):
        shutil.rmtree(destination)
    if destination is not source:
        os.makedirs(destination)

    # Read mask
    if not (os.path.exists(clone_map)):
        logger.error(
            "Clone file {:s} not found. Please run create_grid first.".format(clone_map)
        )
        sys.exit(1)
    else:
        # set clone
        pcr.setclone(clone_map)
        # get the extent from clone.tif
        xax, yax, clone, fill_value = wt.gdal_readmap(clone_tif, "GTiff")
        trans = wt.get_geotransform(clone_tif)
        extent = wt.get_extent(clone_tif)
        xmin, ymin, xmax, ymax = extent
        zeros = np.zeros(clone.shape)
        ones = pcr.numpy2pcr(pcr.Scalar, np.ones(clone.shape), -9999)
        # get the projection from clone.tif
        srs = wt.get_projection(clone_tif)
        unit_clone = srs.GetAttrValue("UNIT").lower()

    # READ CONFIG FILE
    # open config-file
    if inifile is None:
        config = configparser.ConfigParser()
        config.optionxform = str
    else:
        config = wt.OpenConf(inifile)

    # read settings
    """ read parameters """
    minorder = wt.configget(config, "parameters", "riverorder_min", 3, datatype="int")
    try:
        percentiles_str = wt.configget(
            config, "parameters", "statisticmaps", "0, 100", datatype="str"
        )
        percentiles_split = percentiles_str.replace(" ", "").split(",")
        percentiles = np.array(percentiles_split, dtype="float")
    except configparser.NoOptionError:
        percentiles = [0.0, 100.0]
    # read the parameters for generating a temporary very high resolution grid
    if unit_clone == "degree":
        cellsize_hr = wt.configget(
            config, "parameters", "highres_degree", 0.0005, datatype="float"
        )
    elif (unit_clone == "metre") or (unit_clone == "meter"):
        cellsize_hr = wt.configget(
            config, "parameters", "highres_metre", 50, datatype="float"
        )

    cols_hr = int((float(xmax) - float(xmin)) / cellsize_hr + 2)
    rows_hr = int((float(ymax) - float(ymin)) / cellsize_hr + 2)
    hr_trans = (float(xmin), cellsize_hr, float(0), float(ymax), 0, -cellsize_hr)
    clone_hr = os.path.join(destination, "clone_highres.tif")
    # make a highres clone as well!
    wt.CreateTif(clone_hr, rows_hr, cols_hr, hr_trans, srs, 0)

    # read staticmap locations
    dem_map = wt.configget(config, "staticmaps", "dem", "wflow_dem.map")
    gauges_map = wt.configget(config, "staticmaps", "gauges", "wflow_gauges.map")
    landuse_map = wt.configget(config, "staticmaps", "landuse", "wflow_landuse.map")
    river_map = wt.configget(config, "staticmaps", "river", "wflow_river.map")
    outlet_map = wt.configget(config, "staticmaps", "outlet", "wflow_outlet.map")
    soil_map = wt.configget(config, "staticmaps", "soil", "wflow_soil.map")
    streamorder_map = wt.configget(
        config, "staticmaps", "streamorder", "wflow_streamorder.map"
    )
    subcatch_map = wt.configget(config, "staticmaps", "subcatch", "wflow_subcatch.map")

    # first add a missing value to dem_in
    ds = gdal.Open(dem_in, gdal.GA_Update)
    RasterBand = ds.GetRasterBand(1)
    fill_val = RasterBand.GetNoDataValue()

    if fill_val is None:
        RasterBand.SetNoDataValue(-9999)
    ds = None

    # reproject to clone map: see http://stackoverflow.com/questions/10454316/how-to-project-and-resample-a-grid-to-match-another-grid-with-gdal-python
    # resample DEM
    logger.info(
        "Resampling dem from {:s} to {:s}".format(
            os.path.abspath(dem_in), os.path.join(destination, dem_map)
        )
    )
    wt.gdal_warp(
        dem_in,
        clone_map,
        os.path.join(destination, dem_map),
        format="PCRaster",
        gdal_interp=gdalconst.GRA_Average,
    )
    # retrieve amount of rows and columns from clone
    # TODO: make windowstats applicable to source/target with different projections. This does not work yet.
    # retrieve srs from DEM
    try:
        srs_dem = wt.get_projection(dem_in)
    except:
        logger.warning("No projection found in DEM, assuming WGS 1984 lat long")
        srs_dem = osr.SpatialReference()
        srs_dem.ImportFromEPSG(4326)
    clone2dem_transform = osr.CoordinateTransformation(srs, srs_dem)
    # if srs.ExportToProj4() == srs_dem.ExportToProj4():

    wt.windowstats(
        dem_in,
        len(yax),
        len(xax),
        trans,
        srs,
        destination,
        percentiles,
        transform=clone2dem_transform,
        logger=logger,
    )

    ## read catchment shape-file to create catchment map
    src = rasterio.open(clone_tif)
    shapefile = fiona.open(catchshp, "r")
    catchment_shapes = [feature["geometry"] for feature in shapefile]
    image = features.rasterize(
        catchment_shapes, out_shape=src.shape, all_touched=True, transform=src.transform
    )
    catchment_domain = pcr.numpy2pcr(pcr.Ordinal, image.copy(), 0)

    ## read river shape-file and create burn layer
    shapefile = fiona.open(rivshp, "r")
    river_shapes = [feature["geometry"] for feature in shapefile]
    image = features.rasterize(
        river_shapes, out_shape=src.shape, all_touched=False, transform=src.transform
    )
    rivers = pcr.numpy2pcr(pcr.Nominal, image.copy(), 0)
    riverdem = pcr.scalar(rivers) * pcr.readmap(os.path.join(destination, dem_map))
    pcr.setglobaloption("lddin")
    riverldd = pcr.lddcreate(riverdem, 1e35, 1e35, 1e35, 1e35)

    riveroutlet = pcr.cover(pcr.ifthen(pcr.scalar(riverldd) == 5, pcr.scalar(1000)), 0)
    burn_layer = pcr.cover(
        (
            pcr.scalar(
                pcr.ifthen(pcr.streamorder(riverldd) > 1, pcr.streamorder(riverldd))
            )
            - 1
        )
        * 1000
        + riveroutlet,
        0,
    )

    outlets_x, outlets_y = outlets
    n_outlets = len(outlets_x)
    logger.info("Number of outlets: {}".format(n_outlets))
    if n_outlets >= 1:
        outlets_map_numbered = points_to_map(pcr.scalar(0), outlets_x, outlets_y, 0.5)
        outlets_map = pcr.boolean(outlets_map_numbered)
        # snap outlets to closest river (max 1 cell closer to river)
        outlets_map = pcr.boolean(
            pcr.cover(snaptomap(pcr.ordinal(outlets_map), rivers), 0)
        )

    ## create ldd per catchment
    logger.info("Calculating ldd")
    ldddem = pcr.scalar(clone_map)

    # per subcatchment, burn dem, then create modified dem that fits the ldd of the subcatchment
    # this ldd dem is merged over catchments, to create a global ldd that abides to the subcatchment boundaries
    for idx, shape in enumerate(catchment_shapes):
        logger.info(
            "Computing ldd for catchment "
            + str(idx + 1)
            + "/"
            + str(len(catchment_shapes))
        )
        image = features.rasterize(
            [shape], out_shape=src.shape, all_touched=True, transform=src.transform
        )
        catchment = pcr.numpy2pcr(pcr.Scalar, image.copy(), 0)
        dem_burned_catchment = (
            pcr.readmap(os.path.join(destination, dem_map))
            * pcr.scalar(catchment_domain)
            * catchment
        ) - burn_layer
        ldddem = pcr.cover(ldddem, dem_burned_catchment)

    wflow_ldd = pcr.lddcreate(ldddem, 1e35, 1e35, 1e35, 1e35)
    if n_outlets >= 1:
        # set outlets to pit
        wflow_ldd = pcr.ifthenelse(outlets_map, pcr.ldd(5), wflow_ldd)
        wflow_ldd = pcr.lddrepair(wflow_ldd)

    pcr.report(wflow_ldd, os.path.join(destination, "wflow_ldd.map"))

    # compute stream order, identify river cells
    streamorder = pcr.ordinal(pcr.streamorder(wflow_ldd))
    river = pcr.ifthen(streamorder >= pcr.ordinal(minorder), pcr.boolean(1))
    # find the minimum value in the DEM and cover missing values with a river with this value. Effect is none!! so now left out!
    # mindem = int(np.min(pcr.pcr2numpy(pcr.ordinal(os.path.join(destination, dem_map)),9999999)))
    # dem_resample_map = pcr.cover(os.path.join(destination, dem_map), pcr.scalar(river)*0+mindem)
    # pcr.report(dem_resample_map, os.path.join(destination, dem_map))
    pcr.report(streamorder, os.path.join(destination, streamorder_map))
    pcr.report(river, os.path.join(destination, river_map))

    # deal with your catchments
    if gaugeshp == None:
        logger.info("No gauges defined, using outlets instead")
        gauges = pcr.ordinal(
            pcr.uniqueid(
                pcr.boolean(pcr.ifthen(pcr.scalar(wflow_ldd) == 5, pcr.boolean(1)))
            )
        )
        pcr.report(gauges, os.path.join(destination, gauges_map))
    # TODO: Add the gauge shape code from StaticMaps.py (line 454-489)
    # TODO: add river length map (see SticMaps.py, line 492-499)

    # since the products here (river length fraction) are not yet used
    # this is disabled for now, as it also takes a lot of computation time
    if False:
        # report river length
        # make a high resolution empty map
        dem_hr_file = os.path.join(destination, "dem_highres.tif")
        burn_hr_file = os.path.join(destination, "burn_highres.tif")
        demburn_hr_file = os.path.join(destination, "demburn_highres.map")
        riv_hr_file = os.path.join(destination, "riv_highres.map")
        wt.gdal_warp(dem_in, clone_hr, dem_hr_file)
        # wt.CreateTif(riv_hr, rows_hr, cols_hr, hr_trans, srs, 0)
        # open the shape layer
        ds = ogr.Open(rivshp)
        lyr = ds.GetLayer(0)
        wt.ogr_burn(
            lyr,
            clone_hr,
            -100,
            file_out=burn_hr_file,
            format="GTiff",
            gdal_type=gdal.GDT_Float32,
            fill_value=0,
        )
        # read dem and burn values and add
        xax_hr, yax_hr, burn_hr, fill = wt.gdal_readmap(burn_hr_file, "GTiff")
        burn_hr[burn_hr == fill] = 0
        xax_hr, yax_hr, dem_hr, fill = wt.gdal_readmap(dem_hr_file, "GTiff")
        dem_hr[dem_hr == fill] = np.nan
        demburn_hr = dem_hr + burn_hr
        demburn_hr[np.isnan(demburn_hr)] = -9999
        wt.gdal_writemap(
            demburn_hr_file, "PCRaster", xax_hr, yax_hr, demburn_hr, -9999.0
        )
        pcr.setclone(demburn_hr_file)
        demburn_hr = pcr.readmap(demburn_hr_file)

        logger.info("Calculating ldd to determine river length")
        ldd_hr = pcr.lddcreate(demburn_hr, 1e35, 1e35, 1e35, 1e35)
        pcr.report(ldd_hr, os.path.join(destination, "ldd_hr.map"))
        pcr.setglobaloption("unitcell")
        riv_hr = pcr.scalar(pcr.streamorder(ldd_hr) >= minorder) * pcr.downstreamdist(
            ldd_hr
        )
        pcr.report(riv_hr, riv_hr_file)
        pcr.setglobaloption("unittrue")
        pcr.setclone(clone_map)
        logger.info("Computing river length")
        wt.windowstats(
            riv_hr_file,
            len(yax),
            len(xax),
            trans,
            srs,
            destination,
            stat="fact",
            transform=False,
            logger=logger,
        )
        # TODO: nothing happens with the river lengths yet. Need to decide how to use these

    # report outlet map
    pcr.report(
        pcr.ifthen(pcr.ordinal(wflow_ldd) == 5, pcr.ordinal(1)),
        os.path.join(destination, outlet_map),
    )

    # report subcatchment map
    subcatchment = pcr.subcatchment(wflow_ldd, gauges)
    pcr.report(pcr.ordinal(subcatchment), os.path.join(destination, subcatch_map))

    # Report land use map
    if landuse == None:
        logger.info(
            "No land use map used. Preparing {:s} with only ones.".format(
                os.path.join(destination, landuse_map)
            )
        )
        pcr.report(pcr.nominal(ones), os.path.join(destination, landuse_map))
    else:
        logger.info(
            "Resampling land use from {:s} to {:s}".format(
                os.path.abspath(landuse),
                os.path.join(destination, os.path.abspath(landuse_map)),
            )
        )
        wt.gdal_warp(
            landuse,
            clone_map,
            os.path.join(destination, landuse_map),
            format="PCRaster",
            gdal_interp=gdalconst.GRA_Mode,
            gdal_type=gdalconst.GDT_Int32,
        )

    # report soil map
    if soil == None:
        logger.info(
            "No soil map used. Preparing {:s} with only ones.".format(
                os.path.join(destination, soil_map)
            )
        )
        pcr.report(pcr.nominal(ones), os.path.join(destination, soil_map))
    else:
        logger.info(
            "Resampling soil from {:s} to {:s}".format(
                os.path.abspath(soil),
                os.path.join(destination, os.path.abspath(soil_map)),
            )
        )
        wt.gdal_warp(
            soil,
            clone_map,
            os.path.join(destination, soil_map),
            format="PCRaster",
            gdal_interp=gdalconst.GRA_Mode,
            gdal_type=gdalconst.GDT_Int32,
        )

    if lai == None:
        logger.info(
            "No vegetation LAI maps used. Preparing default maps {:s} with only ones.".format(
                os.path.join(destination, soil_map)
            )
        )
        pcr.report(pcr.nominal(ones), os.path.join(destination, soil_map))
    else:
        dest_lai = os.path.join(destination, "clim")
        os.makedirs(dest_lai)
        for month in range(12):
            lai_in = os.path.join(lai, "LAI00000.{:03d}".format(month + 1))
            lai_out = os.path.join(dest_lai, "LAI00000.{:03d}".format(month + 1))
            logger.info(
                "Resampling vegetation LAI from {:s} to {:s}".format(
                    os.path.abspath(lai_in), os.path.abspath(lai_out)
                )
            )
            wt.gdal_warp(
                lai_in,
                clone_map,
                lai_out,
                format="PCRaster",
                gdal_interp=gdalconst.GRA_Bilinear,
                gdal_type=gdalconst.GDT_Float32,
            )

    # report soil map
    if other_maps == None:
        logger.info("No other maps used. Skipping other maps.")
    else:
        logger.info("Resampling list of other maps...")
        for map_file in other_maps:
            logger.info(
                "Resampling a map from {:s} to {:s}".format(
                    os.path.abspath(map_file),
                    os.path.join(
                        destination,
                        os.path.splitext(os.path.basename(map_file))[0] + ".map",
                    ),
                )
            )
            wt.gdal_warp(
                map_file,
                clone_map,
                os.path.join(
                    destination,
                    os.path.splitext(os.path.basename(map_file))[0] + ".map",
                ),
                format="PCRaster",
                gdal_interp=gdalconst.GRA_Mode,
                gdal_type=gdalconst.GDT_Float32,
            )

    if clean:
        wt.DeleteList(glob.glob(os.path.join(destination, "*.xml")), logger=logger)
        wt.DeleteList(
            glob.glob(os.path.join(destination, "clim", "*.xml")), logger=logger
        )
        wt.DeleteList(glob.glob(os.path.join(destination, "*highres*")), logger=logger)