Beispiel #1
0
def shpext_to_boundary(in_shp, out_srs=None):
    """
    Read one feature class extent and create a boundary with that
    extent
    """

    from gasp.gt.prop.ext import get_ext
    from gasp.g.to import create_polygon

    # Get Extent
    ext = get_ext(in_shp)

    # Create points of the new boundary based on the extent
    boundary_points = [(ext[0], ext[3]), (ext[1], ext[3]), (ext[1], ext[2]),
                       (ext[0], ext[2]), (ext[0], ext[3])]
    polygon = create_polygon(boundary_points)

    if out_srs:
        from gasp.gt.prop.prj import get_epsg_shp

        in_srs = get_epsg_shp(in_shp)

        if in_srs != out_srs:
            from gasp.g.prj import prj_ogrgeom

            poly = prj_ogrgeom(polygon, in_srs, out_srs, api='shply')

            return poly

        else:
            return polygon
    else:
        return polygon
Beispiel #2
0
def get_ext(inFile, outEpsg=None):
    """
    Get Extent of any GIS Data
    
    return None if inFile is not a GIS File
    """

    from gasp.gt.prop.ff import check_isRaster, check_isShp

    if check_isRaster(inFile):
        from gasp.gt.prop.rst import rst_ext

        extent = rst_ext(inFile)

    else:
        if check_isShp(inFile):
            from gasp.gt.prop.feat import get_ext as gext

            extent = gext(inFile)

        else:
            return None

    if outEpsg:
        from gasp.gt.prop.prj import get_epsg

        fileEpsg = get_epsg(inFile)

        if not fileEpsg:
            raise ValueError('cannot get EPSG of input file')

        if fileEpsg != outEpsg:
            from gasp.g.to import new_pnt
            from gasp.g.prj import prj_ogrgeom

            bt_left = prj_ogrgeom(new_pnt(extent[0], extent[2]), fileEpsg,
                                  outEpsg)
            top_right = prj_ogrgeom(new_pnt(extent[1], extent[3]), fileEpsg,
                                    outEpsg)

            left, bottom = bt_left.GetX(), bt_left.GetY()
            right, top = top_right.GetX(), top_right.GetY()

            extent = [left, right, bottom, top]

    return extent
Beispiel #3
0
def bf_prop(buffer_shp, epsg_in, isFile=None):
    """
    Return the centroid and radius distance of one buffer geometry
    
    Centroid X, Y in the units of the buffer_shp;
    Radius in meters.
    
    Object return will be something like this:
    o = {
        'X': x_value,
        'Y': y_value,
        'R': radius_value
    }
    """

    from gasp.gt.prop.feat import get_cntr_bnd

    if isFile:
        from gasp.gt.attr import geom_by_idx

        BUFFER_GEOM = ogr.CreateGeometryFromWkt(geom_by_idx(buffer_shp, 0))

    else:
        BUFFER_GEOM = ogr.CreateGeometryFromWkt(buffer_shp)

    # Get x_center, y_center and dist from polygon geometry
    # TODO: Besides 4326, we need to include also the others geographic systems
    if int(epsg_in) == 4326:
        from gasp.g.prj import prj_ogrgeom

        BUFFER_GEOM_R = prj_ogrgeom(BUFFER_GEOM, epsg_in, 3857)

    else:
        BUFFER_GEOM_R = BUFFER_GEOM

    dist = get_buffer_radius(BUFFER_GEOM_R.ExportToWkt(), isFile=None)
    center = get_cntr_bnd(BUFFER_GEOM, isFile=None)

    return {'X': center.GetX(), 'Y': center.GetY(), 'R': dist}
Beispiel #4
0
def coords_to_boundary(topLeft, lowerRight, epsg, outEpsg=None):
    """
    Top Left and Lower Right to Boundary
    """

    from osgeo import ogr
    from gasp.g.to import create_polygon

    boundary_points = [(topLeft[0], topLeft[1]), (lowerRight[0], topLeft[1]),
                       (lowerRight[0], lowerRight[1]),
                       (topLeft[0], lowerRight[1]), (topLeft[0], topLeft[1])]

    # Create polygon
    polygon = create_polygon(boundary_points)

    # Convert SRS if outEPSG
    if outEpsg and epsg != outEpsg:
        from gasp.g.prj import prj_ogrgeom

        poly = prj_ogrgeom(polygon, epsg, outEpsg)

        return poly
    else:
        return polygon
Beispiel #5
0
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 gasp.g.to import new_pnt
    from gasp.g.prj 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 gasp.gt.attr 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
Beispiel #6
0
def geotweets_location(inGeom,
                       epsg_in,
                       keyword=None,
                       epsg_out=4326,
                       onlySearchAreaContained=True,
                       keyToUse=None):
    """
    Search data in Twitter and array with that data
    
    inGeom cloud be a shapefile with a single buffer feature or a dict like:
    inGeom = {
        x: x_value,
        y: y_value,
        r: dist (in meters)
    }
    or a list or a tuple:
    inGeom = [x, y, radius]
    """

    from shapely.geometry import Polygon, Point
    from geopandas import GeoDataFrame
    from gasp.gt.prop.feat.bf import getBufferParam

    x_center, y_center, dist = getBufferParam(inGeom, epsg_in, outSRS=4326)

    # Extract data from Twitter
    data = search_tweets(lat=y_center,
                         lng=x_center,
                         radius=float(dist) / 1000,
                         keyword=keyword,
                         NR_ITEMS=500,
                         only_geo=True,
                         key=keyToUse)

    try:
        if not data:
            return 0
    except:
        pass

    # Pandas to GeoPandas
    geoms = [Point(xy) for xy in zip(data.longitude, data.latitude)]
    data.drop(["latitude", "longitude"], axis=1, inplace=True)
    gdata = GeoDataFrame(data, crs={'init': 'epsg:4326'}, geometry=geoms)

    if onlySearchAreaContained:
        from shapely.wkt import loads
        from gasp.g.prj import prj_ogrgeom
        from gasp.g.gop.prox import xy_to_buffer

        # Check if all retrieve points are within the search area
        _x_center, _y_center, _dist = getBufferParam(inGeom,
                                                     epsg_in,
                                                     outSRS=3857)

        search_area = xy_to_buffer(float(_x_center), float(_y_center),
                                   float(_dist))
        search_area = prj_ogrgeom(search_area, 3857, 4326)
        search_area = loads(search_area.ExportToWkt())

        gdata["tst_geom"] = gdata["geometry"].intersects(search_area)
        gdata = gdata[gdata["tst_geom"] == True]

        gdata.reset_index(drop=True, inplace=True)

    gdata.drop("tst_geom", axis=1, inplace=True)

    if epsg_out != 4326:
        gdata = gdata.to_crs({'init': 'epsg:{}'.format(str(epsg_out))})

    return gdata
Beispiel #7
0
def photos_location(buffer_shp,
                    epsg_in,
                    keyword=None,
                    epsg_out=4326,
                    onlySearchAreaContained=True,
                    keyToUse=None):
    """
    Search for data in Flickr and return a array with the same data
    
    buffer_shp cloud be a shapefile with a single buffer feature or a dict
    like:
    buffer_shp = {
        x: x_value,
        y: y_value,
        r: dist (in meters)
    }
    or a list or a tuple:
    buffer_shp = [x, y, radius]
    """

    import pandas
    from shapely.geometry import Polygon, Point
    from shapely.wkt import loads
    from geopandas import GeoDataFrame
    from gasp.g.gop.prox import xy_to_buffer
    from gasp.gt.prop.feat.bf import getBufferParam
    from gasp.g.prj import prj_ogrgeom

    x_center, y_center, dist = getBufferParam(buffer_shp, epsg_in, outSRS=4326)

    # Retrive data from Flickr
    photos = search_photos(lat=y_center,
                           lng=x_center,
                           radius=float(dist) / 1000,
                           keyword=keyword,
                           apiKey=keyToUse)

    try:
        if not photos:
            # Return noData
            return 0
    except:
        pass

    photos['longitude'] = photos['longitude'].astype(float)
    photos['latitude'] = photos['latitude'].astype(float)

    geoms = [Point(xy) for xy in zip(photos.longitude, photos.latitude)]
    gdata = GeoDataFrame(photos, crs={'init': 'epsg:4326'}, geometry=geoms)

    if onlySearchAreaContained:
        _x_center, _y_center, _dist = getBufferParam(buffer_shp,
                                                     epsg_in,
                                                     outSRS=3857)
        # Check if all retrieve points are within the search area
        search_area = xy_to_buffer(float(_x_center), float(_y_center),
                                   float(_dist))
        search_area = prj_ogrgeom(search_area, 3857, 4326)
        search_area = loads(search_area.ExportToWkt())

        gdata["tst_geom"] = gdata["geometry"].intersects(search_area)
        gdata = gdata[gdata["tst_geom"] == True]

        gdata.reset_index(drop=True, inplace=True)

    gdata["fid"] = gdata["id"]

    if "url_l" in gdata.columns.values:
        gdata["url"] = gdata["url_l"]
    else:
        gdata["url"] = 'None'

    gdata["description"] = gdata["_content"]

    # Drop irrelevant fields
    cols = list(gdata.columns.values)
    delCols = []

    for col in cols:
        if col != 'geometry' and  col != 'description' and \
            col != 'fid' and col != 'url' and col != 'datetaken' \
            and col != 'dateupload' and col != 'title':
            delCols.append(col)
        else:
            continue

    gdata.drop(delCols, axis=1, inplace=True)

    if epsg_out != 4326:
        gdata = gdata.to_crs({'init': 'epsg:{}'.format(str(epsg_out))})

    return gdata
Beispiel #8
0
def ext_to_rst(topLeft,
               btRight,
               outRst,
               cellsize=None,
               epsg=None,
               outEpsg=None,
               invalidResultAsNull=None):
    """
    Extent to Raster
    """

    import os
    import numpy
    from osgeo import ogr, gdal
    from gasp.gt.prop.ff import drv_name

    left, top = topLeft
    right, bottom = btRight

    cellsize = 10 if not cellsize else cellsize

    if outEpsg and epsg and outEpsg != epsg:
        from gasp.g.to import new_pnt
        from gasp.g.to import create_polygon
        from gasp.g.prj 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)

        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:
        NEW_RST_ARRAY = numpy.zeros((rows, cols))
    else:
        try:
            NEW_RST_ARRAY = numpy.zeros((rows, cols))
        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
Beispiel #9
0
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 gasp.to.web  import get_file
    from gasp.pyt.oss import os_name
    
    OS_NAME = os_name()
    
    EXTENTS = []
    
    if db_name and geomCol:
        """
        Assuming input_boundary is a PostgreSQL Table
        """
        
        from gasp.pyt      import obj_to_lst
        from gasp.gql.prop 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 gasp.gt.prop.ff import check_isRaster
            isRst = check_isRaster(input_boundary)
        
            # Get EPSG
            if not epsg:
                from gasp.gt.prop.prj import get_epsg
            
                epsg = get_epsg(input_boundary)
        
            if isRst:
                from gasp.gt.prop.rst import rst_ext
            
                # Get raster extent
                EXTENTS.append(rst_ext(input_boundary))
        
            else:
                from gasp.gt.prop.ff 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 gasp.g.to  import new_pnt
        from gasp.g.prj 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