def pnts_to_boundary(pntShp, outBound, distMeters): """ Create a boundary from Point using a tolerance in meters """ from osgeo import ogr from glass.pys.oss import fprop from glass.g.prop import drv_name from glass.g.gobj import new_pnt from glass.g.prop.prj import get_shp_sref SRS = get_shp_sref(pntShp) shp = ogr.GetDriverByName(drv_name(pntShp)).Open(pntShp) lyr = shp.GetLayer() outShp = ogr.GetDriverByName(drv_name(outBound)).CreateDataSource(outBound) outLyr = outShp.CreateLayer(fprop(outBound, 'fn', forceLower=True), SRS, geom_type=ogr.wkbPolygon) outDefn = outLyr.GetLayerDefn() for feat in lyr: __feat = ogr.Feature(outDefn) ring = ogr.Geometry(ogr.wkbLinearRing) geom = feat.GetGeometryRef() X, Y = geom.GetX(), geom.GetY() boundary_points = [ new_pnt(X - distMeters, Y + distMeters), # Topleft new_pnt(X + distMeters, Y + distMeters), # TopRight new_pnt(X + distMeters, Y - distMeters), # Lower Right new_pnt(X - distMeters, Y - distMeters), # Lower Left new_pnt(X - distMeters, Y + distMeters) ] for pnt in boundary_points: ring.AddPoint(pnt.GetX(), pnt.GetY()) polygon = ogr.Geometry(ogr.wkbPolygon) polygon.AddGeometry(ring) __feat.SetGeometry(polygon) outLyr.CreateFeature(__feat) feat.Destroy() __feat = None ring = None polygon = None shp.Destroy() outShp.Destroy() return outBound
def get_ext(inFile, outEpsg=None): """ Get Extent of any GIS Data return None if inFile is not a GIS File """ from glass.g.prop import check_isRaster, check_isShp if check_isRaster(inFile): from glass.g.prop.rst import rst_ext extent = rst_ext(inFile) else: if check_isShp(inFile): from glass.g.prop.feat import get_ext as gext extent = gext(inFile) else: return None if outEpsg: from glass.g.prop.prj import get_epsg fileEpsg = get_epsg(inFile) if not fileEpsg: raise ValueError('cannot get EPSG of input file') if fileEpsg != outEpsg: from glass.g.gobj import new_pnt from glass.g.prj.obj import prj_ogrgeom bt_left = prj_ogrgeom(new_pnt(extent[0], extent[2]), fileEpsg, outEpsg, api='ogr' if outEpsg != 4326 else 'shapely') top_right = prj_ogrgeom( new_pnt(extent[1], extent[3]), fileEpsg, outEpsg, api='ogr' if outEpsg != 4326 else 'shapely') left, bottom = bt_left.GetX(), bt_left.GetY() right, top = top_right.GetX(), top_right.GetY() extent = [left, right, bottom, top] return extent
def xy_to_buffer(x, y, radius): """ XY Coordinates to Buffer Geometry """ from glass.g.gobj import new_pnt pnt = new_pnt(x, y) return pnt.Buffer(int(round(float(radius), 0)))
def get_random_point(minX, maxX, minY, maxY): """ Create a Single Random Point """ import random from glass.g.gobj import new_pnt x = minX + (random.random() * (maxX - minX)) y = minY + (random.random() * (maxY - minY)) pnt = new_pnt(x, y) return pnt
def getBufferParam(inArea, inAreaSRS, outSRS=4326): """ Get Buffer X, Y Center and radius in any SRS (radius in meteres). Check the type of the 'inArea' Object and return the interest values. inArea could be a file, dict, list or tuple """ import os from osgeo import ogr from glass.g.gobj import new_pnt from glass.g.prj.obj import prj_ogrgeom TYPE = type(inArea) if TYPE == str: # Assuming that inArea is a file # Check if exists if os.path.exists(inArea): if os.path.isfile(inArea): from glass.g.tbl.filter import geom_by_idx # Get Geometry object BUFFER_GEOM = geom_by_idx(inArea, 0) # To outSRS if int(inAreaSRS) != outSRS: BUFFER_GEOM = prj_ogrgeom( ogr.CreateGeometryFromWkt(BUFFER_GEOM), inAreaSRS, outSRS).ExportToWkt() # Get x_center, y_center and radius xyr = bf_prop(BUFFER_GEOM, outSRS, isFile=None) x_center, y_center, dist = str(xyr['X']), str(xyr['Y']), str( xyr['R']) else: raise ValueError('The given path exists but it is not a file') else: raise ValueError('The given path doesn\'t exist') elif TYPE == dict: X = 'x' if 'x' in inArea else 'X' if 'X' in inArea else \ 'lng' if 'lng' in inArea else None Y = 'y' if 'x' in inArea else 'Y' if 'Y' in inArea else \ 'lat' if 'lat' in inArea else None R = 'r' if 'r' in inArea else 'R' if 'R' in inArea else \ 'rad' if 'rad' in inArea else 'RADIUS' if 'RADIUS' in inArea \ else 'radius' if 'radius' in inArea else None if not X or not Y or not R: raise ValueError( ('The keys used to identify the buffer properties ' 'are not valid! ' 'Please choose one of the following keys groups: ' 'x, y, r; ' 'X, Y, R; ' 'lat, lng, rad')) else: x_center, y_center, dist = (str(inArea[X]), str(inArea[Y]), str(inArea[R])) if inAreaSRS != outSRS: pnt_wgs = prj_ogrgeom(new_pnt(x_center, y_center), inAreaSRS, outSRS) x_center, y_center = (pnt_wgs.GetX(), pnt_wgs.GetY()) elif TYPE == list or TYPE == tuple: x_center, y_center, dist = inArea if inAreaSRS != outSRS: pnt_wgs = prj_ogrgeom(new_pnt(x_center, y_center), inAreaSRS, outSRS) x_center, y_center = (pnt_wgs.GetX(), pnt_wgs.GetY()) else: raise ValueError( ('Please give a valid path to a shapefile or a tuple, dict or ' 'list with the x, y and radius values')) return x_center, y_center, dist
def ogr_buffer(geom, radius, out_file, srs=None): """ For each geometry in the input, this method create a buffer and store it in a vetorial file Accepts files or lists with geom objects as inputs """ import os from osgeo import ogr from glass.g.prj import def_prj from glass.g.prop import drv_name from glass.g.prop.prj import get_sref_from_epsg from glass.g.gp.prox.bfing.obj import draw_buffer # Create output buffer_shp = ogr.GetDriverByName( drv_name(out_file)).CreateDataSource(out_file) buffer_lyr = buffer_shp.CreateLayer( os.path.splitext(os.path.basename(out_file))[0], get_sref_from_epsg(srs) if srs else None, geom_type=ogr.wkbPolygon) featDefn = buffer_lyr.GetLayerDefn() if type(geom) == list: for g in geom: feat = ogr.Feature(featDefn) feat.SetGeometry(draw_buffer(g, radius)) buffer_lyr.CreateFeature(feat) feat = None buffer_shp.Destroy() elif type(geom) == dict: if 'x' in geom and 'y' in geom: X = 'x' Y = 'y' elif 'X' in geom and 'Y' in geom: X = 'X' Y = 'Y' else: raise ValueError(('Your geom dict has invalid keys. ' 'Please use one of the following combinations: ' 'x, y; ' 'X, Y')) from glass.g.gobj import new_pnt feat = ogr.Feature(featDefn) g = new_pnt(geom[X], geom[Y]) feat.SetGeometry(draw_buffer(g, radius)) buffer_lyr.CreateFeature(feat) feat = None buffer_shp.Destroy() if srs: def_prj(out_file, epsg=srs) elif type(geom) == str: # Check if the input is a file if os.path.exists(geom): inShp = ogr.GetDriverByName(drv_name(geom)).Open(geom, 0) lyr = inShp.GetLayer() for f in lyr: g = f.GetGeometryRef() feat = ogr.Feature(featDefn) feat.SetGeometry(draw_buffer(g, radius)) buffer_lyr.CreateFeature(feat) feat = None buffer_shp.Destroy() inShp.Destroy() if srs: def_prj(out_file, epsg=srs) else: def_prj(out_file, template=geom) else: raise ValueError('The given path does not exist') else: raise ValueError('Your geom input is not valid') return out_file
def ext_to_rst(topLeft, btRight, outRst, cellsize=None, epsg=None, outEpsg=None, invalidResultAsNull=None, rstvalue=None): """ Extent to Raster """ import numpy from osgeo import gdal from glass.g.prop import drv_name left, top = topLeft right, bottom = btRight cellsize = 10 if not cellsize else cellsize if outEpsg and epsg and outEpsg != epsg: from glass.g.gobj import new_pnt from glass.g.gobj import create_polygon from glass.g.prj.obj import prj_ogrgeom extGeom = prj_ogrgeom( create_polygon([ new_pnt(left, top), new_pnt(right, top), new_pnt(right, bottom), new_pnt(left, bottom), new_pnt(left, top) ]), epsg, outEpsg) epsg = outEpsg left, right, bottom, top = extGeom.GetEnvelope() # Get row and cols number rows = (float(top) - float(bottom)) / cellsize cols = (float(right) - float(left)) / cellsize rows = int(rows) if rows == int(rows) else int(rows) + 1 cols = int(cols) if cols == int(cols) else int(cols) + 1 if not invalidResultAsNull: if not rstvalue: NEW_RST_ARRAY = numpy.zeros((rows, cols)) else: NEW_RST_ARRAY = numpy.full((rows, cols), rstvalue) else: try: if not rstvalue: NEW_RST_ARRAY = numpy.zeros((rows, cols)) else: NEW_RST_ARRAY = numpy.full((rows, cols), rstvalue) except: return None # Create new Raster img = gdal.GetDriverByName(drv_name(outRst)).Create( outRst, cols, rows, 1, gdal.GDT_Byte) img.SetGeoTransform((left, cellsize, 0, top, 0, -cellsize)) band = img.GetRasterBand(1) band.WriteArray(NEW_RST_ARRAY) if epsg: from osgeo import osr rstSrs = osr.SpatialReference() rstSrs.ImportFromEPSG(epsg) img.SetProjection(rstSrs.ExportToWkt()) band.FlushCache() return outRst
def download_by_boundary(input_boundary, folder_out, osm_name, epsg, GetUrl=True, db_name=None, geomCol=None, justOneFeature=None): """ Download data from OSM using a bounding box """ import os from osgeo import ogr from glass.pys.web import get_file from glass.pys.oss import os_name OS_NAME = os_name() EXTENTS = [] if db_name and geomCol: """ Assuming input_boundary is a PostgreSQL Table """ from glass.pys import obj_to_lst from glass.g.prop.gql import tbl_ext for t in obj_to_lst(input_boundary): EXTENTS.append(tbl_ext(db_name, t, geomCol)) else: if type(input_boundary) == dict: if 'top' in input_boundary and 'bottom' in input_boundary \ and 'left' in input_boundary and 'right' in input_boundary: EXTENTS.append([ input_boundary['left'],input_boundary['right'], input_boundary['bottom'], input_boundary['top'] ]) else: raise ValueError(( 'input_boundary is a dict but the keys are not correct. ' 'Please use left, right, top and bottom as keys' )) elif type(input_boundary) == list: if len(input_boundary) == 4: EXTENTS.append(input_boundary) else: raise ValueError(( 'input boundary is a list with more than 4 objects. ' 'The list should be like: ' 'l = [left, right, bottom, top]' )) elif type(input_boundary) == ogr.Geometry: EXTENTS.append(input_boundary.GetEnvelope()) else: # Assuming input boundary is a file #Check if file exists if not os.path.exists(input_boundary): raise ValueError(( "Sorry, but the file {} does not exist inside the folder {}!" ).format( os.path.basename(input_boundary), os.path.dirname(input_boundary) )) # Check if is a raster from glass.g.prop import check_isRaster isRst = check_isRaster(input_boundary) # Get EPSG if not epsg: from glass.g.prop.prj import get_epsg epsg = get_epsg(input_boundary) if isRst: from glass.g.prop.rst import rst_ext # Get raster extent EXTENTS.append(rst_ext(input_boundary)) else: from glass.g.prop import drv_name # Todo: check if it is shape # Open Dataset inSrc = ogr.GetDriverByName(drv_name( input_boundary)).Open(input_boundary) lyr = inSrc.GetLayer() i = 1 for feat in lyr: geom = feat.GetGeometryRef() featext = geom.GetEnvelope() EXTENTS.append(featext) if justOneFeature: break if epsg != 4326: from glass.g.gobj import new_pnt from glass.g.prj.obj import prj_ogrgeom for i in range(len(EXTENTS)): bottom_left = prj_ogrgeom(new_pnt( EXTENTS[i][0], EXTENTS[i][2]), epsg, 4326) top_right = prj_ogrgeom(new_pnt( EXTENTS[i][1], EXTENTS[i][3]), epsg, 4326) left , bottom = bottom_left.GetX(), bottom_left.GetY() right, top = top_right.GetX() , top_right.GetY() EXTENTS[i] = [left, right, bottom, top] #url = "https://overpass-api.de/api/map?bbox={}" url = "https://lz4.overpass-api.de/api/interpreter?bbox={}" RESULTS = [] for e in range(len(EXTENTS)): bbox_str = ','.join([str(p) for p in EXTENTS[e]]) if GetUrl: RESULTS.append(url.format(bbox_str)) continue if len(EXTENTS) == 1: outOsm = os.path.join(folder_out, osm_name + '.xml') else: outOsm = os.path.join(folder_out, "{}_{}.xml".format(osm_name, str(e))) osm_file = get_file( url.format(bbox_str), outOsm, useWget=None if OS_NAME == 'Windows' else None ) RESULTS.append(osm_file) return RESULTS[0] if len(RESULTS) == 1 else RESULTS
def adjust_ext_to_snap(outExt, snapRst): """ Adjust extent for a output raster to snap with other raster """ from glass.g.prop import check_isShp, check_isRaster from glass.g.prop.rst import rst_ext, get_cellsize from glass.g.gobj import new_pnt, create_polygon # Check if outExt is a raster or not isRst = check_isRaster(outExt) if isRst: shpAExt = rst_ext(outExt) else: isShp = check_isShp(outExt) if isShp: from glass.g.prop.feat import get_ext shpAExt = get_ext(outExt) else: raise ValueError( ("outExt value should be a path to a SHP or to a Raster file")) # Check if snapRst is a raster isRst = check_isRaster(snapRst) if not isRst: raise ValueError(("snapRst should be a path to a raster file")) # Get snapRst Extent snapRstExt = rst_ext(snapRst) # Get cellsize csize = get_cellsize(snapRst) # Find extent point of outExt inside the two extents # This will be used as pseudo origin snapRstPnt = [ new_pnt(snapRstExt[0], snapRstExt[3]), new_pnt(snapRstExt[1], snapRstExt[3]), new_pnt(snapRstExt[1], snapRstExt[2]), new_pnt(snapRstExt[0], snapRstExt[2]), new_pnt(snapRstExt[0], snapRstExt[3]), ] poly_snap_rst = create_polygon(snapRstPnt) outExtPnt = { 'top_left': new_pnt(shpAExt[0], shpAExt[3]), 'top_right': new_pnt(shpAExt[1], shpAExt[3]), 'bottom_right': new_pnt(shpAExt[1], shpAExt[2]), 'bottom_left': new_pnt(shpAExt[0], shpAExt[2]) } out_rst_pseudo = {} for pnt in outExtPnt: out_rst_pseudo[pnt] = outExtPnt[pnt].Intersects(poly_snap_rst) pseudoOrigin = outExtPnt['top_left'] if out_rst_pseudo['top_left'] else \ outExtPnt['bottom_left'] if out_rst_pseudo['bottom_left'] else \ outExtPnt['top_right'] if out_rst_pseudo['top_right'] else \ outExtPnt['bottom_right'] if out_rst_pseudo['bottom_right'] else None if not pseudoOrigin: raise ValueError(('Extents doesn\'t have overlapping areas')) pseudoOriginName = 'top_left' if out_rst_pseudo['top_left'] else \ 'bottom_left' if out_rst_pseudo['bottom_left'] else \ 'top_right' if out_rst_pseudo['top_right'] else \ 'bottom_right' if out_rst_pseudo['bottom_right'] else None # Get out Raster Shape n_col = int((shpAExt[1] - shpAExt[0]) / csize) n_row = int((shpAExt[3] - shpAExt[2]) / csize) # Get Output Raster real origin/top left yName, xName = pseudoOriginName.split('_') if xName == 'left': # Obtain left of output Raster left_out_rst = snapRstExt[0] + (csize * int( (shpAExt[0] - snapRstExt[0]) / csize)) else: # obtain right of output Raster right_out_rst = snapRstExt[1] - (csize * int( (snapRstExt[1] - shpAExt[1]) / csize)) # Use right to obtain left coordinate left_out_rst = right_out_rst - (n_col * csize) if yName == 'top': # Obtain top of output Raster top_out_rst = snapRstExt[3] - (csize * int( (snapRstExt[3] - shpAExt[3]) / csize)) else: # obtain bottom of output raster bot_out_rst = snapRstExt[2] + (csize * int( (shpAExt[2] - snapRstExt[2]) / csize)) # use bottom to find the top of the output raster top_out_rst = bot_out_rst + (n_row * csize) return left_out_rst, top_out_rst, n_row, n_col, csize