Exemplo n.º 1
0
Arquivo: osm.py Projeto: zonakre/gasp
def download_by_boundary(input_boundary,
                         output_osm,
                         epsg,
                         area_threshold=None,
                         GetUrl=True):
    """
    Download data from OSM using a bounding box
    """

    import os
    from decimal import Decimal
    from gasp.prop.feat import feat_count
    from gasp.prop.ext import get_extent
    from gasp.web import get_file

    # Check number of features
    number_feat = feat_count(input_boundary)
    if number_feat != 1:
        raise ValueError(
            ('Your boundary has more than one feature. '
             'Only feature classes with one feature are allowed.'))

    # Check boundary area
    if area_threshold:
        from gasp.cpu.gdl import area_to_dic
        d_area = area_to_dic(input_boundary)
        if d_area[0] > area_threshold:
            raise ValueError('{} has more than than {} square meters'.format(
                os.path.basename(input_boundary), str(area_threshold)))

    # Get boundary extent
    left, right, bottom, top = get_extent(input_boundary, gisApi='ogr')

    if epsg != 4326:
        from gasp.to.geom import create_point
        from gasp.mng.prj import project_geom

        bottom_left = project_geom(create_point(left, bottom, api='ogr'),
                                   epsg,
                                   4326,
                                   api='ogr')

        top_right = project_geom(create_point(right, top, api='ogr'),
                                 epsg,
                                 4326,
                                 api='ogr')

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

    bbox_str = ','.join([str(left), str(bottom), str(right), str(top)])

    url = "http://overpass-api.de/api/map?bbox={box}".format(box=bbox_str)

    if GetUrl:
        return url

    osm_file = get_file(url, output_osm)

    return output_osm
Exemplo n.º 2
0
def shpext_to_boundary(inShp, outShp, epsg=None):
    """
    Read one feature class extent and create a boundary with that
    extent
    
    The outFile could be a Feature Class or one Raster Dataset
    """

    import os
    from gasp.oss import get_filename
    from gasp.to.geom import create_point
    from gasp.prop.ext import get_extent

    extent = get_extent(inShp, gisApi='ogr')

    # Create points of the new boundary based on the extent
    boundary_points = [
        create_point(extent[0], extent[3], api='ogr'),
        create_point(extent[1], extent[3], api='ogr'),
        create_point(extent[1], extent[2], api='ogr'),
        create_point(extent[0], extent[2], api='ogr'),
        create_point(extent[0], extent[3], api='ogr')
    ]

    # Get SRS for the output
    if not epsg:
        from gasp.prop.prj import get_shp_sref
        srs = get_shp_sref(inShp)

    else:
        from gasp.prop.prj import get_sref_from_epsg
        srs = get_sref_from_epsg(epsg)

    # Write new file
    shp = ogr.GetDriverByName(drv_name(outShp)).CreateDataSource(outShp)

    lyr = shp.CreateLayer(get_filename(outShp, forceLower=True),
                          srs,
                          geom_type=ogr.wkbPolygon)

    outDefn = lyr.GetLayerDefn()

    feat = ogr.Feature(outDefn)
    ring = ogr.Geometry(ogr.wkbLinearRing)

    for pnt in boundary_points:
        ring.AddPoint(pnt.GetX(), pnt.GetY())

    polygon = ogr.Geometry(ogr.wkbPolygon)
    polygon.AddGeometry(ring)

    feat.SetGeometry(polygon)
    lyr.CreateFeature(feat)

    feat.Destroy()
    shp.Destroy()

    return outShp
Exemplo n.º 3
0
def create_random_points(area_shp, number, out_random):
    """
    Return a dataset with several random points
    """
    
    from osgeo         import ogr
    from gasp.prop.ff  import drv_name
    from gasp.prop.ext import get_extent
    
    # Get extent
    left, right, bottom, top = get_extent(area_shp, gisApi='ogr')
    
    # To be continued
    """
Exemplo n.º 4
0
def fishnet(output,
            templateExtent,
            geomType='POLYGON',
            numRows=None,
            numColumns=None,
            cellWidth=None,
            cellHeight=None,
            labeling="NO_LABELS"):
    """
    Create a fishnet - rectangular cells
    
    Use fc or raster to assign a extent to the new fishnet
    """

    import os
    from gasp.prop.ext import rst_ext, get_extent
    from gasp.prop.ff import vector_formats, raster_formats
    from gasp.oss import get_fileformat

    templateFormat = get_fileformat(templateExtent)

    if templateFormat in vector_formats():
        xmin, xmax, ymin, ymax = get_extent(templateExtent, gisApi='arcpy')
    elif templateFormat in raster_formats():
        xmin, xmax, ymin, ymax = rst_ext(templateExtent, gisApi='arcpy')

    else:
        raise ValueError(('Could not identify if observerDataset '
                          'is a raster or a feature class'))

    arcpy.CreateFishnet_management(
        out_feature_class=output,
        origin_coord=' '.join([str(xmin), str(ymin)]),
        y_axis_coord=' '.join([str(xmin), str(ymin + 10.0)]),
        cell_width=cellWidth,
        cell_height=cellHeight,
        number_rows=numRows,
        number_columns=numColumns,
        labels=labeling,
        template=templateExtent,
        geometry_type=geomType)

    return output
Exemplo n.º 5
0
def download_by_boundary(input_boundary, output_osm, epsg, GetUrl=True):
    """
    Download data from OSM using a bounding box
    """

    import os
    from osgeo import ogr
    from gasp.web import get_file
    from gasp.oss import get_fileformat, get_filename

    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:

            left, right, bottom, top = (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:
            left, right, bottom, top = 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:
        # Check if we have a polygon
        geom_name = input_boundary.GetGeometryName()

        if geom_name == 'POLYGON' or geom_name == 'MULTIPOLYGON':
            # Get polygon extent
            left, right, bottom, top = input_boundary.GetEnvelope()

        else:
            raise ValueError(('Your boundary is a non POLYGON ogr Geometry '))

    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.prop.ff import check_isRaster
        isRst = check_isRaster(input_boundary)

        if isRst:
            from gasp.prop.ext import rst_ext

            # Get raster extent
            left, right, bottom, top = rst_ext(input_boundary)

        else:
            from gasp.prop.feat import feat_count
            from gasp.prop.ext import get_extent

            # Check number of features
            number_feat = feat_count(input_boundary, gisApi='ogr')
            if number_feat != 1:
                raise ValueError(
                    ('Your boundary has more than one feature. '
                     'Only feature classes with one feature are allowed.'))

            # Get boundary extent
            left, right, bottom, top = get_extent(input_boundary, gisApi='ogr')

    if epsg != 4326:
        from gasp.to.geom import create_point
        from gasp.mng.prj import project_geom

        bottom_left = project_geom(create_point(left, bottom, api='ogr'),
                                   epsg,
                                   4326,
                                   api='ogr')

        top_right = project_geom(create_point(right, top, api='ogr'),
                                 epsg,
                                 4326,
                                 api='ogr')

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

    bbox_str = ','.join([str(left), str(bottom), str(right), str(top)])

    url = "https://overpass-api.de/api/map?bbox={box}".format(box=bbox_str)

    if GetUrl:
        return url

    if get_fileformat(output_osm) != '.xml':
        output_osm = os.path.join(os.path.dirname(output_osm),
                                  get_filename(output_osm) + '.xml')

    osm_file = get_file(url, output_osm)

    return output_osm
Exemplo n.º 6
0
def service_area_as_sup_cst(networkDataset,
                            rdvName,
                            extentLyr,
                            originsLyr,
                            output,
                            epsg=3763,
                            REF_DISTANCE=3000,
                            NR_INTERVALS=20):
    """
    Create a Cost Distance Surface using Service Area Tool
    
    Same result of the Cost Distance tool but using Service Area Tool
    
    Supported by Google Maps API
    
    PROBLEM: REF_DISTANCE should be greater if the extent is higher.
    """

    import os

    from gasp.prop.ext import get_extent
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.to.shp.arcg import geomArray_to_fc
    from gasp.mob.arctbx.svarea import service_area_polygon
    from gasp.web.glg.distmatrix import get_max_dist

    if epsg != 4326:
        from gasp.mng.prj import project

    arcpy.env.overwriteOutput = True

    # Get extent
    minX, maxX, minY, maxY = get_extent(extentLyr, gisApi='arcpy')

    # Get Reference points through the boundary
    # Get North West to East
    north_west_east = [(minX, maxY)]
    # Get South West to East
    south_west_east = [(minX, minY)]
    c = minX
    while c < maxX:
        north_west_east.append((c, maxY))
        south_west_east.append((c, minY))
        c += REF_DISTANCE

    north_west_east.append((maxX, maxY))
    south_west_east.append((maxX, minY))

    # Get West North to South
    west_north_to_south = [(minX, maxY)]
    # Get East North to South
    east_north_to_south = [(maxX, maxY)]
    c = maxY
    while c > minY:
        west_north_to_south.append((minX, c))
        east_north_to_south.append((maxX, c))
        c -= REF_DISTANCE

    west_north_to_south.append((minX, minY))
    east_north_to_south.append((maxX, minY))

    south_west_east.reverse()
    west_north_to_south.reverse()

    # Export Ref Points to a file only to see the result
    REF_GEOM = north_west_east + east_north_to_south + \
        south_west_east + west_north_to_south
    line_array = [{'FID': 0, "GEOM": REF_GEOM}]

    REF_POINTS = os.path.join(os.path.dirname(output), 'extent.shp')
    geomArray_to_fc(line_array, REF_POINTS, "POLYLINE", epsg, overwrite=True)

    # Calculate time-distance between origins Lyr and reference points
    # Get Geom of originsLyr
    # Convert to WGS84
    if epsg != 4326:
        originsWGS = project(
            originsLyr,
            os.path.join(os.path.dirname(output), 'origins_wgs84.shp'), 4326)
    else:
        originsWGS = originsLyr

    origLyr = feat_lyr(originsWGS)
    origPoint = []
    for line in arcpy.SearchCursor(origLyr):
        pnt = line.Shape.centroid

        origPoint.append((pnt.X, pnt.Y))

    # Get WGS REF POINTS
    if epsg != 4326:
        refWGS = project(
            REF_POINTS, os.path.join(os.path.dirname(output),
                                     'extent_wgs.shp'), 4326)
    else:
        refWGS = REF_POINTS

    refPointsLyr = feat_lyr(refWGS)
    refPoints = []
    for line in arcpy.SearchCursor(refPointsLyr):
        geom = line.getValue("Shape")

        for vector in geom:
            for pnt in vector:
                pnt_str = str(pnt).split(' ')
                refPoints.append((pnt_str[0], pnt_str[1]))

    # From that distances, get time intervals
    max_distance = get_max_dist(origPoint, refPoints)
    INTERVAL_RANGE = int(round(max_distance / NR_INTERVALS, 0))

    c = 0
    INTERVALS = []
    for i in range(NR_INTERVALS):
        INTERVALS.append(c + INTERVAL_RANGE)
        c += INTERVAL_RANGE

    # Run Service Area Tool
    service_area_polygon(networkDataset, rdvName, INTERVALS, originsLyr,
                         output)

    return output
Exemplo n.º 7
0
def service_area_as_sup_cst2(networkDataset,
                             rdvName,
                             extentLyr,
                             originsLyr,
                             output,
                             epsg,
                             REF_DISTANCE=3000,
                             NR_INTERVALS=20):
    """
    Create a Cost Distance Surface using Service Area Tool
    
    Same result of the Cost Distance tool but using Service Area Tool
    
    Support by ArcGIS Closest Facility tool
    """

    import os
    from gasp.prop.ext import get_extent
    from gasp.cpu.arcg.mng.feat import vertex_to_point
    from gasp.cpu.arcg.mng.fld import field_statistics
    from gasp.cpu.arcg.geometry import geomArray_to_polyline_gon
    from gasp.mob.arctbx.closest import closest_facility
    from gasp.mob.arctbx.svarea import service_area_polygon

    arcpy.env.overwriteOutput = True

    # Get extent
    minX, maxX, minY, maxY = get_extent(extentLyr, gisApi='arcpy')

    # Get Reference points through the boundary
    # Get North West to East
    north_west_east = [(minX, maxY)]
    # Get South West to East
    south_west_east = [(minX, minY)]
    c = minX
    while c < maxX:
        north_west_east.append((c, maxY))
        south_west_east.append((c, minY))
        c += REF_DISTANCE

    north_west_east.append((maxX, maxY))
    south_west_east.append((maxX, minY))

    # Get West North to South
    west_north_to_south = [(minX, maxY)]
    # Get East North to South
    east_north_to_south = [(maxX, maxY)]
    c = maxY
    while c > minY:
        west_north_to_south.append((minX, c))
        east_north_to_south.append((maxX, c))
        c -= REF_DISTANCE

    west_north_to_south.append((minX, minY))
    east_north_to_south.append((maxX, minY))

    south_west_east.reverse()
    west_north_to_south.reverse()

    # Export Ref Points to a file only to see the result
    REF_GEOM = north_west_east + east_north_to_south + \
        south_west_east + west_north_to_south
    line_array = [{'FID': 0, "GEOM": REF_GEOM}]

    REF_LINE = os.path.join(os.path.dirname(output), 'extent.shp')
    geomArray_to_polyline_gon(line_array,
                              REF_LINE,
                              "POLYLINE",
                              epsg,
                              overwrite=True)

    # Ref Line to Ref Points
    REF_POINTS = vertex_to_point(
        REF_LINE, os.path.join(os.path.dirname(output), 'extent_pnt.shp'))

    REF_TABLE = os.path.join(os.path.dirname(output), 'time_ref_table.dbf')
    closest_facility(networkDataset,
                     rdvName,
                     originsLyr,
                     REF_POINTS,
                     REF_TABLE,
                     oneway_restriction=True)

    # Get Maximum Time Registed
    MAX_DIST = field_statistics(REF_TABLE, 'Total_Minu', 'MAX')[0]

    INTERVAL_RANGE = int(round(MAX_DIST / NR_INTERVALS, 0))

    c = 0
    INTERVALS = []
    for i in range(NR_INTERVALS):
        INTERVALS.append(c + INTERVAL_RANGE)
        c += INTERVAL_RANGE

    # Run Service Area Tool
    service_area_polygon(networkDataset, rdvName, INTERVALS, originsLyr,
                         output)

    return output
Exemplo n.º 8
0
def create_fishnet(boundary, fishnet, width=None, height=None, rowN=None, colN=None):
    """
    Create a Fishnet
    """
    
    import os
    from math          import ceil
    from gasp.oss      import get_filename
    from gasp.prop.ff  import drv_name
    from gasp.prop.ext import get_extent
    from gasp.prop.prj import get_shp_sref
    
    # Get boundary extent
    xmin, xmax, ymin, ymax = [float(x) for x in get_extent(boundary, gisApi='ogr')]
    
    if width and height:
        # Clean width and height
        if type(width) != float:
            try:
                # Convert to float
                width = float(width)
            except:
                raise ValueError(
                    'Width value is not valid. Please give a numeric value'
                )
    
        if type(height) != float:
            try:
                # Convert to float
                height = float(height)
            except:
                raise ValueError(
                    'Height value is not valid. Please give a numeric value'
                )
    
        # get rows number
        rows = ceil((ymax-ymin) / height)
        # get columns number
        cols = ceil((xmax-xmin) / width)
    
    else:
        if rowN and colN:
            rows = int(rowN); cols = int(colN)
            width = ceil((xmax-xmin) / rows)
            height = ceil((ymax-ymin) / cols)
        
        else:
            raise ValueError(
                "You must specify the width and height of fishnet cells or "
                "instead the number of rows and cols of fishnet"
            )
    
    # Create output file
    if not os.path.exists(os.path.dirname(fishnet)):
        raise ValueError('The path for the output doesn\'t exist')
    
    out_fishnet = ogr.GetDriverByName(drv_name(
        fishnet)).CreateDataSource(fishnet)
    fishnet_lyr = out_fishnet.CreateLayer(
        str(get_filename(fishnet)), srs=get_shp_sref(boundary),
        geom_type=ogr.wkbPolygon
    )
    
    feat_defn = fishnet_lyr.GetLayerDefn()
    
    # create grid cells
    # - start grid cell envelope -#
    ringXleftOrigin = xmin
    ringXrightOrigin = xmin + width
    ringYtopOrigin = ymax
    ringYbottomOrigin = ymax - height
    
    count_cols = 0
    while count_cols < cols:
        count_cols += 1
        
        # reset envelope for rows
        ringYtop = ringYtopOrigin
        ringYbottom = ringYbottomOrigin
        count_rows = 0
        
        while count_rows < rows:
            count_rows += 1
            
            ring = ogr.Geometry(ogr.wkbLinearRing)
            ring.AddPoint(ringXleftOrigin, ringYtop)
            ring.AddPoint(ringXrightOrigin, ringYtop)
            ring.AddPoint(ringXrightOrigin, ringYbottom)
            ring.AddPoint(ringXleftOrigin, ringYbottom)
            ring.AddPoint(ringXleftOrigin, ringYtop)
            poly = ogr.Geometry(ogr.wkbPolygon)
            poly.AddGeometry(ring)
            
            # add new geom to layer
            out_feature = ogr.Feature(feat_defn)
            out_feature.SetGeometry(poly)
            fishnet_lyr.CreateFeature(out_feature)
            out_feature = None
            
            # new envelope for next poly
            ringYtop = ringYtop - height
            ringYbottom = ringYbottom - height
        
        # new envelope for next poly
        ringXleftOrigin = ringXleftOrigin + width
        ringXrightOrigin = ringXrightOrigin + width
    
    out_fishnet.Destroy()
    
    return fishnet
Exemplo n.º 9
0
def points_as_grid(boundary, fishnet_pnt, width=None, height=None,
                   nr_cols=None, nr_rows=None):
    """
    Equivalent to the centroid of each cell of a fishnet grid
    """
    
    import os
    from math          import ceil
    from gasp.oss      import get_filename
    from gasp.prop.ff  import drv_name
    from gasp.prop.ext import get_extent
    from gasp.prop.prj import get_shp_sref
    
    # Get boundary extent
    xmin, xmax, ymin, ymax = get_extent(boundary, gisApi='ogr')
    
    # Clean width and height
    if width and height:
        if type(width) != float:
            try:
                # Convert to float
                width = float(width)
            except:
                raise ValueError(
                    'Width value is not valid. Please give a numeric value'
                )
        
        if type(height) != float:
            try:
                # Convert to float
                height = float(height)
            except:
                raise ValueError(
                    'Height value is not valid. Please give a numeric value'
                )
    
    else:
        if nr_cols and nr_rows:
            if type(nr_cols) != float:
                try:
                    # convert to float
                    nr_cols = float(nr_cols)
                except:
                    raise ValueError(
                        'Columns number value is not valid. Please give a numeric value'
                    )
            
            if type(nr_rows) != float:
                try:
                    nr_rows = float(nr_rows)
                except:
                    raise ValueError(
                        'Lines number value is not valid. Please give a numeric value'
                    )
            
            width = (xmax + xmin) / nr_cols
            height = (ymax + ymin) / nr_rows
        
        else:
            raise ValueError('Please giver numeric values to with/height or to nr_cols/nr_rows')
    
    # get rows number
    rows = ceil((ymax-ymin) / height)
    # get columns number
    cols = ceil((xmax-xmin) / width)
    
    # Create output file
    if not os.path.exists(os.path.dirname(fishnet_pnt)):
        return 'The path for the output doesn\'t exist'
    
    out_fishnet = ogr.GetDriverByName(drv_name(
        fishnet_pnt)).CreateDataSource(fishnet_pnt)
    fishnet_lyr = out_fishnet.CreateLayer(
        get_filename(fishnet_pnt), get_shp_sref(boundary),
        geom_type=ogr.wkbPoint
    )
    
    feat_defn = fishnet_lyr.GetLayerDefn()
    
    # create grid cells
    # - start grid cell envelope -#
    ringXleftOrigin = xmin
    ringXrightOrigin = xmin + width
    ringYtopOrigin = ymax
    ringYbottomOrigin = ymax - height
    
    count_cols = 0
    while count_cols < cols:
        count_cols += 1
        
        # reset envelope for rows
        ringYtop = ringYtopOrigin
        ringYbottom = ringYbottomOrigin
        count_rows = 0
        
        while count_rows < rows:
            count_rows += 1
            
            pnt = ogr.Geometry(ogr.wkbPoint)
            pnt.AddPoint(
                (ringXleftOrigin + ringXrightOrigin) / 2.0,
                (ringYbottom + ringYtop) / 2.0
            )
            
            # add new geom to layer
            out_feature = ogr.Feature(feat_defn)
            out_feature.SetGeometry(pnt)
            fishnet_lyr.CreateFeature(out_feature)
            out_feature = None
            
            # new envelope for next poly
            ringYtop = ringYtop - height
            ringYbottom = ringYbottom - height
        
        # new envelope for next poly
        ringXleftOrigin = ringXleftOrigin + width
        ringXrightOrigin = ringXrightOrigin + width
    
    out_fishnet.Destroy()
Exemplo n.º 10
0
def shpext_to_rst(inShp,
                  outRaster,
                  cellsize=None,
                  epsg=None,
                  invalidResultAsNone=None,
                  outEpsg=None):
    """
    Extent to raster
    
    if invalidResultAsNone - if for some reason something went wrong, the 
    result of this method will be a None Object if there is an error on the
    numpy array creation. If False, an error will be raised.
    """

    import os
    import numpy
    from osgeo import gdal
    from gasp.prop.ff import drv_name
    from gasp.prop.ext import get_extent

    cellsize = 10 if not cellsize else cellsize

    # Get extent
    try:
        left, right, bottom, top = get_extent(inShp, gisApi='ogr')
    except:
        left, right, bottom, top = inShp.GetEnvelope()

    if outEpsg and epsg and outEpsg != epsg:
        from gasp.to.geom import create_polygon, create_point
        from gasp.mng.prj import project_geom

        extGeom = project_geom(create_polygon([
            create_point(left, top, api='ogr'),
            create_point(right, top, api='ogr'),
            create_point(right, bottom, api='ogr'),
            create_point(left, bottom, api='ogr'),
            create_point(left, top, api='ogr')
        ]),
                               epsg,
                               outEpsg,
                               api='ogr')

        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 invalidResultAsNone:
        NEW_RASTER_ARRAY = numpy.zeros((rows, cols))
    else:
        try:
            NEW_RASTER_ARRAY = numpy.zeros((rows, cols))
        except:
            return None

    # Create new raster
    img = gdal.GetDriverByName(drv_name(outRaster)).Create(
        outRaster,
        cols,
        rows,
        1,
        #gdal.GDT_Int16
        gdal.GDT_Byte)

    img.SetGeoTransform((left, cellsize, 0, top, 0, -cellsize))

    band = img.GetRasterBand(1)

    band.WriteArray(NEW_RASTER_ARRAY)

    if epsg:
        from osgeo import osr

        rstSrs = osr.SpatialReference()
        rstSrs.ImportFromEPSG(epsg)
        img.SetProjection(rstSrs.ExportToWkt())

    band.FlushCache()

    return outRaster