Exemplo n.º 1
0
def transform_geojson_wgs_to_epsg(geojson, EPSG):
    
    """
    Takes a geojson dictionary and converts it from WGS84 (EPSG:4326) to desired EPSG
    
    Parameters
    ----------
    geojson: dict
        a geojson dictionary containing a 'geometry' key, in WGS84 coordinates
    EPSG: int
        numeric code for the EPSG coordinate referecnce system to transform into
        
    Returns
    -------
    transformed_geojson: dict
        a geojson dictionary containing a 'coordinates' key, in the desired CRS
        
    """

    geojson_geom = geojson['geometry']
    polygon = ogr.CreateGeometryFromJson(str(geojson_geom))

    source = osr.SpatialReference()
    source.ImportFromEPSG(4326)

    target = osr.SpatialReference()
    target.ImportFromEPSG(EPSG)

    transform = osr.CoordinateTransformation(source, target)
    polygon.Transform(transform)
    
    transformed_geojson = eval(polygon.ExportToJson())

    return transformed_geojson
Exemplo n.º 2
0
def Create_Geometry_from_GeoJSON(geojson):
    from osgeo import ogr

    geojson = """{"type":"Point","coordinates":[108420.33,753808.59]}"""
    point = ogr.CreateGeometryFromJson(geojson)
    print("%d,%d" % (point.GetX(), point.GetY()))
    return point
Exemplo n.º 3
0
 def create_feature(self, layer, featureDict, expected_type, srs=None):
     try:
         geom_dict = featureDict["geometry"]
         if not geom_dict:
             raise EsriFeatureLayerException("No Geometry Information")
         geom_type = geom_dict["type"]
         feature = ogr.Feature(layer.GetLayerDefn())
         coords = self.get_geom_coords(geom_dict)
         f_json = json.dumps({"type": geom_type, "coordinates": coords})
         geom = ogr.CreateGeometryFromJson(f_json)
         if geom and srs:
             geom.Transform(srs)
         if geom and expected_type != geom.GetGeometryType():
             geom = ogr.ForceTo(geom, expected_type)
         if geom and expected_type == geom.GetGeometryType(
         ) and geom.IsValid():
             feature.SetGeometry(geom)
             for prop, val in featureDict["properties"].items():
                 name = str(SLUGIFIER(prop)).encode('utf-8')
                 value = val
                 if value and layer.GetLayerDefn().GetFieldIndex(
                         name) != -1:
                     feature.SetField(name, value)
             layer.CreateFeature(feature)
     except Exception as e:
         logger.error(e)
Exemplo n.º 4
0
def concatenateControlPoints(projects, outputFolder):

    spatialRef = None
    cpList = []

    for proj in projects:
        controlPointsPath = proj['project'].getpath('Control_Points')
        vid = proj['visit']

        cpShp = Shapefile(controlPointsPath)
        visitCPList = cpShp.featuresToShapely()
        spatialRef = cpShp.spatialRef

        for aPoint in visitCPList:
            cpItems = {}
            cpItems['geometry'] = aPoint['geometry']
            cpItems['fields'] = {}

            cpItems['fields']['VisitID'] = int(vid)
            cpItems['fields']['PointNum'] = getFieldValue(
                aPoint['fields'], [
                    'Point_Numb', 'POINT_NUMB', 'PointNumb', 'POINT_NUM',
                    'POINT'
                ])
            cpItems['fields']['Code'] = getFieldValue(
                aPoint['fields'], ['DESCRIPTIO', 'Descriptio', 'Code'])
            cpItems['fields']['Type'] = getFieldValue(aPoint['fields'],
                                                      ['Type', 'TYPE'])

            cpList.append(cpItems)

    outputPath = os.path.join(outputFolder, "AllVisitControlPoints.shp")
    print "Writing combined control points to {0}".format(outputPath)
    outShape = Shapefile()
    outShape.create(outputPath, spatialRef, geoType=ogr.wkbPointZM)

    outShape.createField("ID", ogr.OFTInteger)
    outShape.createField("VisitID", ogr.OFTInteger)
    outShape.createField("PointNum", ogr.OFTString)
    outShape.createField("Code", ogr.OFTString)
    outShape.createField("Type", ogr.OFTString)

    id = 1
    for aCP in cpList:

        featureDefn = outShape.layer.GetLayerDefn()
        outFeature = ogr.Feature(featureDefn)
        ogrPolygon = ogr.CreateGeometryFromJson(
            json.dumps(mapping(aCP['geometry'])))
        outFeature.SetGeometry(ogrPolygon)
        outFeature.SetField('ID', id)
        id += 1

        for fieldName, fieldValue in aCP['fields'].iteritems():
            outFeature.SetField(fieldName, fieldValue)

        outShape.layer.CreateFeature(outFeature)
    def _create_base_map(self, ):
        '''
        Deal with different types way to define the AOI, if none is specified, then the image bound is used.
        '''
        if self.aoi is not None:
            if os.path.exists(self.aoi):
                try:
                    g = gdal.Open(self.aoi)
                    subprocess.call([
                        'gdaltindex', '-f', 'GeoJSON',
                        self.toa_dir + '/AOI.json', self.aoi
                    ])
                except:
                    try:
                        g = ogr.Open(self.aoi)
                    except:
                        raise IOError(
                            'AOI file cannot be opened by gdal, please check it or transform into format can be opened by gdal'
                        )
            else:
                try:
                    g = ogr.CreateGeometryFromJson(aoi)
                except:
                    try:
                        g = ogr.CreateGeometryFromGML(aoi)
                    except:
                        try:
                            g = ogr.CreateGeometryFromWkt(aoi)
                        except:
                            try:
                                g = ogr.CreateGeometryFromWkb(aoi)
                            except:
                                raise IOError(
                                    'The AOI has to be one of GeoJSON, GML, Wkt or Wkb.'
                                )
                gjson_str = '''{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":%s}]}''' % g.ExportToJson(
                )

                with open(self.toa_dir + '/AOI.json', 'wb') as f:
                    f.write(gjson_str)
        if not os.path.exists(self.toa_dir + '/AOI.json'):
            subprocess.call([
                'gdaltindex', '-f', 'GeoJSON', self.toa_dir + '/AOI.json',
                self.toa_bands[0]
            ])
            self.logger.warning(
                'AOI is not created and full band extend is used')
            self.aoi = self.toa_dir + '/AOI.json'
        else:
            self.aoi = self.toa_dir + '/AOI.json'

        if self.pixel_res is None:
            self.pixel_res = abs(
                gdal.Open(self.toa_bands[0]).GetGeoTransform()[1])

        self.psf_xstd = 260 / self.pixel_res
        self.psf_ystd = 340 / self.pixel_res
Exemplo n.º 6
0
 def gml2json(self, gml):
     json_out = {
         "type": "FeatureCollection",
         "features": [],
     }
     geom_crs = None
     tree = etree.fromstring(gml)
     nsmap = tree.nsmap
     tag_name = lambda t: t.tag.split("{%s}" % nsmap[t.prefix])[-1]
     for feature in tree.getiterator("{%s}featureMember" % nsmap["gml"]):
         json_feature = {
             "type": "Feature",
             "properties": {},
             "geometry": None,
         }
         for layer in feature.iterfind('{%s}*' % nsmap["ms"]):
             json_feature["properties"]["layer"] = tag_name(layer)
             wfs_id = layer.get("{%s}id" % nsmap["gml"], None)
             if wfs_id and self.map_name_use:
                 wfs_id = u"{0}.{1}".format(self.map_name_use, wfs_id)
             json_feature["properties"]["id"] = wfs_id
             for prop in layer.iterfind('{%s}*' % nsmap["ms"]):
                 get_prop = True
                 for geom in prop.iterfind("{%s}*" % nsmap["gml"]):
                     get_prop = False
                     geom_crs = geom.get("srsName", None)
                     ogr_geom = ogr.CreateGeometryFromGML(
                         etree.tostring(geom))
                     if isinstance(ogr_geom, ogr.Geometry):
                         json_feature["geometry"] = json.loads(
                             ogr_geom.ExportToJson())
                         if geom_crs:
                             json_feature["geometry"][
                                 "crs"] = self.create_json_crs(geom_crs)
                         if self.out_geom:
                             ogr_geom = ogr.CreateGeometryFromJson(
                                 str(
                                     json.dumps(json_feature["geometry"],
                                                ensure_ascii=False)))
                             if self.out_geom == "gml":
                                 json_feature[
                                     "geometry"] = ogr_geom.ExportToGML()
                             elif self.out_geom == "wkt":
                                 json_feature[
                                     "geometry"] = ogr_geom.ExportToWkt()
                             else:
                                 raise Exception(
                                     'out_geom="{} is not valid (None,gml,wkt)use"'
                                     .format(self.out_geom))
                 if get_prop:
                     json_feature["properties"][tag_name(prop)] = prop.text
             json_out["features"].append(json_feature)
     if geom_crs:
         json_out["crs"] = self.create_json_crs(geom_crs)
     if self.debug:
         self.echo2json(json_out)
     return json_out
Exemplo n.º 7
0
def queryRegion(data):

    # Get data from web app
    d = {'property':'default', 'reducer':'default', 'format':'json'}
    d.update(data)

    dataset = d['dataset'].strip()
    property = d['property'].strip()
    reducer = d['reducer']
    region = d['region']
    format = d['format']
    dates = json.loads(d['date'])
    
    # Input normalization
    if isinstance(dates, basestring):
        dates = [dates]
    dates = [parseDate(x) for x in dates]
    
    if isinstance(reducer, basestring):
        reducer = [x.strip() for x in reducer.split(',')]
    
    # Read Metadata
    metadata = readMetadata(dataset)
    
    # Update defaults from metadata
    if d['property'] == 'default':
        d['property'] = metadata['default-property']
    if d['reducer'] == 'default':
        d['reducer'] == metadata['default-reducer']
    
    # Presume a geojson srs of EPSG:4326
    geom = ogr.CreateGeometryFromJson(region.encode('utf-8'))
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)
    geom.AssignSpatialReference(srs)
    
    # Get raster path
    rasterfn = getDatasetPath(dataset) + '/{property}.vrt'.format(property=property)
    
    # Determine required bands
    bandDates = metadata['band-dates']
    bands = selectBandsByDate(dates, bandDates)
    values = fetchRegion(geom, rasterfn, bands)
    
    response = {'dataset':dataset,
                'property':property,
                }
    out = {str(bandDates[x]):values[x] for x in values}
    
    for r in reducer:
        response[r] = reduce(out, r)
    
    if format == 'yaml':
        return yaml.dump(response)
    else:
        return json.dumps(response)
Exemplo n.º 8
0
    def shapelyToFeatures(self, shplyFeat, outShp, spatialRef, geoType):
        self.create(outShp, spatialRef, geoType)
        featureDefn = self.layer.GetLayerDefn()
        outFeature = ogr.Feature(featureDefn)
        ogrJsonDump = ogr.CreateGeometryFromJson(json.dumps(
            mapping(shplyFeat)))
        outFeature.SetGeometry(ogrJsonDump)
        self.layer.CreateFeature(outFeature)

        return outFeature
Exemplo n.º 9
0
 def transform_geom(self, geometry): 
     if  geometry.find('{') >= 0 :           
         geom = ogr.CreateGeometryFromJson(geometry)
     else:
         geom = ogr.CreateGeometryFromWkt(geometry)
          
     if self.transform is not None:
         geom.Transform(self.transform) 
     
     return geom 
Exemplo n.º 10
0
def createPoint(point_json, shp_name, field):
    '''
	生成点shp文件
	输入:
	point_json:描述点的geojson文件
	name:要生成的shp文件名
	field:shp文件中的字段名及数据类型 {字段1:类型1,字段2:类型2,字段3:类型3}

	常见数据类型:ogr.OFTString ogr.OFTReal ogr.OFTInteger
	'''
    # 设置shapefile驱动
    gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
    gdal.SetConfigOption("SHAPE_ENCODING", "gbk")
    driver = ogr.GetDriverByName("ESRI Shapefile")

    # 创建数据源
    data_source = driver.CreateDataSource(shp_name)

    # 创建空间参考,WGS84
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)

    # 创建图层
    layer = data_source.CreateLayer("point", srs, ogr.wkbPoint)  # 带坐标系文件
    # 设置字段
    for field_name, field_type in field.items():
        if len(field_name) > 10:
            fn = ogr.FieldDefn(field_name[0:10], field_type)
        else:
            fn = ogr.FieldDefn(field_name, field_type)
        #数据类型为str时,设置字段长度
        if field_type == ogr.OFTString:
            fn.SetWidth(128)
        layer.CreateField(fn)

    for point in point_json['features']:
        # 创建特征
        feature = ogr.Feature(layer.GetLayerDefn())
        # 和设置字段内容进行关联  ,从数据源中写入数据
        for field_name, _ in field.items():
            if len(field_name) > 10:
                feature.SetField(field_name[0:10],
                                 point['properties'][field_name])
            else:
                feature.SetField(field_name, point['properties'][field_name])

        # 生成点坐标
        point_geo = ogr.CreateGeometryFromJson(str(point['geometry']))
        feature.SetGeometry(point_geo)
        # 添加点
        layer.CreateFeature(feature)
        # 关闭 特征
        feature = None
    # 关闭数据
    data_source = None
Exemplo n.º 11
0
 def filter_spat_buffer(self, 
                        propertyname=None, 
                        coord=None, 
                        radius=None, 
                        epsg_code=None, 
                        epsg_code_measure=3857):
     if isinstance(coord, (list, tuple)) and isinstance(radius, (int, float)):
         # lat <-> lon
         coord = [
             coord[-1], 
             coord[0]
         ]
         in_srs = osr.SpatialReference()
         in_srs.ImportFromEPSG(int(epsg_code["crs"]["properties"]["code"]))
         out_srs = osr.SpatialReference()
         out_srs.ImportFromEPSG(int(epsg_code_measure))
         # detect type coordinate system
         if out_srs.ExportToPCI()[1] != "METRE":
             raise Exception("'epsg_code_measure' is not geometric coordinate system")
         json_geom = {
             "type": "Point",
             "coordinates": coord
         }
         json_geom.update(epsg_code)
         # transform to measure epsg code 
         transform = osr.CoordinateTransformation(in_srs, out_srs)
         ogr_geom = ogr.CreateGeometryFromJson(
             json.dumps(
                 json_geom, 
                 ensure_ascii=False
             )
         )
         ogr_geom.Transform(transform)
         # create buffer
         gml_geom = ogr_geom.Buffer(radius*2).ExportToGML()
         prop_name = u"<ogc:PropertyName>{}</ogc:PropertyName>".format(
             self.geom_property_cap
         )
         return u"<ogc:Intersects>{0}{1}</ogc:Intersects>".format(
             prop_name, 
             gml_geom
         )
     elif not propertyname and not coord and not radius:
         return {
             "coord": [
                 "Latitude point", 
                 "Longitude point", 
                 ],
             "radius": "radius in meters",
             "epsg_code_measure": "epsg code for radius measuring, default 3857",
             "epsg_code": "epsg code projection",
         }
     else:
         raise Exception("Filter buffer: error")
Exemplo n.º 12
0
def overlapping_polygon_area(polys):
    """

    Parameters
    ----------
    polys : list
            of polygon object with a __geo_interface__

    Returns
    -------
    area : float
           The area of the intersecting polygons
    """
    geom = json.dumps(polys[0].__geo_interface__)
    intersection = ogr.CreateGeometryFromJson(geom)
    for p in polys[1:]:
        geom = json.dumps(p.__geo_interface__)
        geom = ogr.CreateGeometryFromJson(geom)
        intersection = intersection.Intersection(geom)
    area = intersection.GetArea()
    return area
Exemplo n.º 13
0
def convertGeometry(geom, srs):
    import ogr
    import osr
    in_ref = osr.SpatialReference()
    in_ref.SetFromUserInput(srs)
    out_ref = osr.SpatialReference()
    out_ref.SetFromUserInput('EPSG:4326')

    g = ogr.CreateGeometryFromJson(json.dumps(geom))
    g.AssignSpatialReference(in_ref)
    g.TransformTo(out_ref)
    return json.loads(g.ExportToJson())
Exemplo n.º 14
0
def transform_from_wgs_poly(geo_json, EPSGa):

    polygon = ogr.CreateGeometryFromJson(str(geo_json))

    source = osr.SpatialReference()
    source.ImportFromEPSG(4326)

    target = osr.SpatialReference()
    target.ImportFromEPSG(EPSGa)

    transform = osr.CoordinateTransformation(source, target)
    polygon.Transform(transform)

    return eval(polygon.ExportToJson())
Exemplo n.º 15
0
def writeShapeToShapeFile(outputPath, aPolygon, spatialRef):

    # Write the polygon to ShapeFile (note: ShapeFile handles deleting existing file)
    outShape = Shapefile()
    outShape.create(outputPath, spatialRef, geoType=ogr.wkbPolygon)
    outShape.createField("ID", ogr.OFTInteger)

    # The main centerline gets written first
    featureDefn = outShape.layer.GetLayerDefn()
    outFeature = ogr.Feature(featureDefn)
    ogrPolygon = ogr.CreateGeometryFromJson(json.dumps(mapping(aPolygon)))
    outFeature.SetGeometry(ogrPolygon)
    outFeature.SetField('ID', 1)
    outShape.layer.CreateFeature(outFeature)
Exemplo n.º 16
0
    def handle(self, **options):
        import time
        #start_time = time.time()
        #self.method_one(options)
        #print("--- %s seconds ---" % (time.time() - start_time))

        #start_time = time.time()
        #self.method_two(options)
        #print("--- %s seconds ---" % (time.time() - start_time))

        #print 'Dataset was written.'

        output = options['output'][0]
        path = options['path'][0]

        #self.method_by_block(path, output)
        # set up the shapefile driver
        driver = ogr.GetDriverByName(str("ESRI Shapefile"))

        # create the data source
        data_source = driver.CreateDataSource(str(output))

        # create the spatial reference, WGS84
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(4326)

        # create the layer
        layer = data_source.CreateLayer(str("volcanoes"),
                                        srs,
                                        geom_type=ogr.wkbPolygon)
        layer.CreateField(ogr.FieldDefn(str("code"), ogr.OFTInteger))
        geom_type = ogr.wkbPolygon

        for state in get_rapideye_footprints_from_state('Chiapas'):

            feature = ogr.Feature(layer.GetLayerDefn())
            feature.SetField(str("code"), int(state[0]))
            b = bytes(state[1])
            print state[1]
            point = ogr.CreateGeometryFromJson(str(state[1]))

            # Set the feature geometry using the point
            feature.SetGeometry(point)
            layer.CreateFeature(feature)
            # Dereference the feature
            feature = None
            print state
        print output
        data_source = None
Exemplo n.º 17
0
def geoJSONToShp(inJSON):
    # assumes WGS 84
    # read poly from json
    poly = ogr.CreateGeometryFromJson(inJSON)
    # create a new shapefile to insert the new geometry into
    # https://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html#create-a-new-shapefile-and-add-data
    driver = ogr.GetDriverByName('ESRI Shapefile')
    tmp_dir = config.path_website + '/project/html/sites/all/modules/lsf_subscription/cgi-bin/shp_tmp/'
    #'/var/vsites/www.landsatfact.com/project/html/sites/all/modules/lsf_subscription/cgi-bin/shp_tmp/'
    #    tmp_dir=r'H:\SPA_Secure\Geospatial\LandsatFACT\code\reduce\shapes'
    outShp = os.path.join(tmp_dir, 'tmp.shp')

    if os.path.exists(outShp):
        driver.DeleteDataSource(outShp)

    # Create the output shapefile
    target_srs = osr.SpatialReference()
    target_srs.ImportFromEPSG(4326)
    dataSource = driver.CreateDataSource(outShp)
    outLayer = dataSource.CreateLayer("tmp",
                                      target_srs,
                                      geom_type=ogr.wkbMultiPolygon)

    # Add an ID field
    idField = ogr.FieldDefn("id", ogr.OFTInteger)
    outLayer.CreateField(idField)

    # Create the feature and set values
    featureDefn = outLayer.GetLayerDefn()
    feature = ogr.Feature(featureDefn)
    feature.SetGeometry(poly)
    feature.SetField("id", 0)
    outLayer.CreateFeature(feature)

    # create an ESRI.prj file, https://pcjericks.github.io/py-gdalogr-cookbook/projection.html
    target_srs.MorphToESRI()
    prj = os.path.join(
        os.path.split(outShp)[0],
        os.path.splitext(os.path.basename(outShp))[0] + '.prj')
    file = open(prj, 'w')
    file.write(target_srs.ExportToWkt())
    # Close and clean up neeeded to make sure shp is written
    file.close()
    dataSource.Destroy()
    # be careful with the order of clean (e.g., can't destroy feature until poly is dereferenced)
    geom = poly = driver = dataSource = target_srs = outLayer = file = feature = featureDefn = None
    return (countVertices(outShp))
Exemplo n.º 18
0
def get_random_point(shp):
    with fiona.open(shp) as src:
        geom = src[0]['geometry']
        geom = json.dumps(geom)
        polygon = ogr.CreateGeometryFromJson(geom)
        # print(polygon)

    env = polygon.GetEnvelope()
    xmin, ymin, xmax, ymax = env[0], env[2], env[1], env[3]
    point = ogr.Geometry(ogr.wkbPoint)
    point.AddPoint(random.uniform(xmin, xmax),
                   random.uniform(ymin, ymax))

    long = point.GetX()
    lat = point.GetY()

    random_point = ee.Geometry.Point([long, lat])
    return random_point
Exemplo n.º 19
0
 def create_feature(self, layer, featureDict, expected_type, srs=None):
     created = False
     try:
         geom_dict = featureDict["geometry"]
         if not geom_dict:
             raise EsriFeatureLayerException("No Geometry Information")
         geom_type = geom_dict["type"]
         feature = ogr.Feature(layer.GetLayerDefn())
         coords = self.get_geom_coords(geom_dict)
         f_json = json.dumps({"type": geom_type, "coordinates": coords})
         geom = ogr.CreateGeometryFromJson(f_json)
         if geom and srs:
             geom.Transform(srs)
         if geom and expected_type != geom.GetGeometryType():
             geom = ogr.ForceTo(geom, expected_type)
         if geom and expected_type == geom.GetGeometryType(
         ) and geom.IsValid():
             feature.SetGeometry(geom)
             for prop, val in featureDict["properties"].items():
                 name = str(SLUGIFIER(prop))
                 value = val
                 if value and layer.GetLayerDefn().GetFieldIndex(
                         name) != -1:
                     # replace id/code with mapped valued for subtypes
                     if prop in self.esri_serializer.subtypes_fields:
                         type_field_value = featureDict["properties"][
                             self.esri_serializer.subtype_field_name]
                         # It is supposed to find the value, but check in case the data is not correct
                         if value in self.esri_serializer.subtypes[
                                 type_field_value][prop]:
                             value = self.esri_serializer.subtypes[
                                 type_field_value][prop][value]
                     # It is supposed to find the value, but check in case the data is not correct
                     elif prop in self.esri_serializer.fields_domains \
                             and value in self.esri_serializer.fields_domains[prop]:
                         # replace id/code with mapped value for domain coded values
                         value = self.esri_serializer.fields_domains[prop][
                             value]
                     feature.SetField(name, value)
             created = layer.CreateFeature(feature) == ogr.OGRERR_NONE
     except Exception as e:
         logger.error('Failed to create feature', e)
     return created
Exemplo n.º 20
0
    def read_by_geom(self, wgs_geometry, tif_file):
        '''
        获取空间范围内的数据,在调用该函数之前先调用 info_by_geom 或 info_by_bbox,将返回的结果中的 tif_file 和 wgs_geometry 属性作为参数。

        geom_info:矢量掩膜范围,必须包含 geometry 和 tif_file, geometry 必须为经纬度ogr.geometry的 wkt 或 geojson,例如:
            {
                'wgs_geometry': 'POLYGON ((115.0 40.222408112063,115.0 40.3643188487053,115.312252122152 40.5,115.5 40.5,115.5 40.3046486467168,115.387540328212 40.2805104337424,115.0 40.222408112063))',
                'tif_file': /mnt/LandsatGrids/LANDSAT/L5/121/44/2011/20110202/50_475/L5-TM-121-044-20110202-LSR-B2_50_475.tif
            }

        '''

        # TODO: the format of wgs_geometry should be checked first
        # if len(wgs_geometry) > GEOM_MAX_SIZE:
        #     raise EGeomTooLarge()
        if type(wgs_geometry) is ogr.Geometry:
            return self._read_by_geom(wgs_geometry, tif_file)
        else:
            wgs_geometry = ogr.CreateGeometryFromJson(wgs_geometry)
            return self._read_by_geom(wgs_geometry, tif_file)
Exemplo n.º 21
0
def create_shape_from_json(id, json, output_directory):
    '''
    Given a json string containing coordinates, this method creates a shape file.
    '''
    create_directory_path(output_directory)
    filename = create_filename(output_directory, '%s.shp' % id)
    shape = Data(filename)
    if is_file(filename):
        shape.driver.DeleteDataSource(filename)
    data_source = shape.driver.CreateDataSource(filename)
    spatial_reference = osr.SpatialReference()
    spatial_reference.ImportFromEPSG(4326)    
    layer = data_source.CreateLayer(str('layer'), spatial_reference, geom_type=ogr.wkbPolygon)
    layer.CreateField(ogr.FieldDefn(str('id'), ogr.OFTString))
    feature = ogr.Feature(layer.GetLayerDefn())
    feature.SetField(str('id'), str(id))
    geometry = ogr.CreateGeometryFromJson(str(json))
    feature.SetGeometry(geometry)
    layer.CreateFeature(feature)
    shape.close()
    return shape
Exemplo n.º 22
0
def process_mask(name, mask_file, smpl=None):
    contour_file = f'{WORK_DIR}/{name}_countour.geojson'
    contour_wgs_file = f'{WORK_DIR}/{name}_countour_wgs.geojson'
    subprocess.call("gdal_contour -i 10 -f GeoJSON".split(' ') +
                    [mask_file, contour_file])

    simplify_opt = ["-simplify", f'{smpl}'] if smpl else []
    subprocess.call([
        "ogr2ogr", "-f", "GeoJSON", "-t_srs", "EPSG:4326", contour_wgs_file,
        contour_file
    ] + simplify_opt)

    with open(contour_wgs_file) as data_file:
        contours = json.load(data_file)

    features = contours['features']

    good_features = []
    for f in features:
        coords = f['geometry']['coordinates']

        geom = {'type': 'Polygon', 'coordinates': [coords]}
        poly = ogr.CreateGeometryFromJson(json.dumps(geom))
        area = poly.GetArea()

        good_features.append({
            "type": "Feature",
            "geometry": geom,
            "properties": {
                "name": f'{len(good_features) + 1}'
            }
        })

    store(f'{WORK_DIR}/{name}_final.geojson', {
        "type": "FeatureCollection",
        "features": good_features
    })
Exemplo n.º 23
0
def storeinshp(osm_results, dst_shp):
    # create the new shp
    dr = ogr.GetDriverByName("ESRI Shapefile")
    ds = dr.CreateDataSource(dst_shp)
    sr = osr.SpatialReference()
    sr.SetFromUserInput('EPSG:4326')
    lyr = ds.CreateLayer("polygon", sr, ogr.wkbPolygon)

    for geojson in osm_results['features']:
        id = geojson['id']
        geometry = geojson['geometry']

        if geometry['type'] == 'LineString':
            geometry = {
                'type': 'Polygon',
                'coordinates': [geometry['coordinates']]
            }

        corner_points = json.dumps(geometry)

        # geom_json = json.dumps(geom_json)
        geom = ogr.CreateGeometryFromJson(corner_points)

        ffd = ogr.FeatureDefn()
        fgd = ogr.GeomFieldDefn()
        fgd.name = id
        fgd.type = ogr.wkbPolygon
        ffd.AddGeomFieldDefn(fgd)

        fpd = ogr.FieldDefn()
        fpd.name = geojson['properties']
        fpd.type = ogr.OFTString
        ffd.AddFieldDefn(fpd)

        feat = ogr.Feature(ffd)
        feat.SetGeometry(geom)
        lyr.CreateFeature(feat)
Exemplo n.º 24
0
def gen_zonalstats(zones_json, raster):
    """
    Generator function that yields the statistics of a raster dataset
    within each polygon (zone) of a vector dataset.

    :param zones_json: Polygons in GeoJSON format
    :param raster: Raster dataset
    :return: Polygons with additional properties for calculated raster stats.
    """
    # Open data
    raster = get_dataset(raster)
    if type(zones_json) is str:
        shp = ogr.Open(zones_json)
        zones_json = json.loads(zones_json)
    else:
        shp = ogr.Open(json.dumps(zones_json))

    lyr = shp.GetLayer()

    # Get raster georeference info
    transform = raster.GetGeoTransform()
    xOrigin = transform[0]
    yOrigin = transform[3]
    pixelWidth = transform[1]
    pixelHeight = transform[5]

    # Reproject vector geometry to same projection as raster
    sourceSR = lyr.GetSpatialRef()
    targetSR = osr.SpatialReference()
    targetSR.ImportFromWkt(raster.GetProjectionRef())
    coordTrans = osr.CoordinateTransformation(sourceSR, targetSR)
    # TODO: Use a multiprocessing pool to process features more quickly
    for feature in zones_json['features']:
        geom = ogr.CreateGeometryFromJson(json.dumps(feature['geometry']))
        if sourceSR.ExportToWkt() != targetSR.ExportToWkt():
            geom.Transform(coordTrans)

        # Get extent of feat
        if geom.GetGeometryName() == 'MULTIPOLYGON':
            count = 0
            pointsX = []
            pointsY = []
            for polygon in geom:
                ring = geom.GetGeometryRef(count).GetGeometryRef(0)
                numpoints = ring.GetPointCount()
                for p in range(numpoints):
                    lon, lat, z = ring.GetPoint(p)
                    if abs(lon) != float('inf'):
                        pointsX.append(lon)
                    if abs(lat) != float('inf'):
                        pointsY.append(lat)
                count += 1
        elif geom.GetGeometryName() == 'POLYGON':
            ring = geom.GetGeometryRef(0)
            numpoints = ring.GetPointCount()
            pointsX = []
            pointsY = []
            for p in range(numpoints):
                lon, lat, z = ring.GetPoint(p)
                if abs(lon) != float('inf'):
                    pointsX.append(lon)
                if abs(lat) != float('inf'):
                    pointsY.append(lat)
        else:
            raise GaiaException(
                "ERROR: Geometry needs to be either Polygon or Multipolygon")

        xmin = min(pointsX)
        xmax = max(pointsX)
        ymin = min(pointsY)
        ymax = max(pointsY)

        # Specify offset and rows and columns to read
        xoff = int((xmin - xOrigin) / pixelWidth)
        yoff = int((yOrigin - ymax) / pixelWidth)
        xcount = int((xmax - xmin) / pixelWidth) + 1
        ycount = int((ymax - ymin) / pixelWidth) + 1

        # Create memory target raster
        target_ds = gdal.GetDriverByName('MEM').Create('', xcount, ycount, 1,
                                                       gdal.GDT_Byte)
        target_ds.SetGeoTransform((
            xmin,
            pixelWidth,
            0,
            ymax,
            0,
            pixelHeight,
        ))

        # Create for target raster the same projection as for the value raster
        raster_srs = osr.SpatialReference()
        raster_srs.ImportFromWkt(raster.GetProjectionRef())
        target_ds.SetProjection(raster_srs.ExportToWkt())

        # Rasterize zone polygon to raster
        gdal.RasterizeLayer(target_ds, [1], lyr, burn_values=[1])

        # Read raster as arrays
        banddataraster = raster.GetRasterBand(1)
        try:
            dataraster = banddataraster.ReadAsArray(xoff, yoff, xcount,
                                                    ycount).astype(numpy.float)
        except AttributeError:
            # Nothing within bounds, move on to next polygon
            properties = feature[u'properties']
            for p in [
                    'count', 'sum', 'mean', 'median', 'min', 'max', 'stddev'
            ]:
                properties[p] = None
            yield feature
        else:
            # Get no data value of array
            noDataValue = banddataraster.GetNoDataValue()
            if noDataValue:
                # Updata no data value in array with new value
                dataraster[dataraster == noDataValue] = numpy.nan

            bandmask = target_ds.GetRasterBand(1)
            datamask = bandmask.ReadAsArray(0, 0, xcount,
                                            ycount).astype(numpy.float)

            # Mask zone of raster
            zoneraster = numpy.ma.masked_array(dataraster,
                                               numpy.logical_not(datamask))

            properties = feature['properties']
            properties['count'] = zoneraster.count()
            properties['sum'] = numpy.nansum(zoneraster)
            if type(properties['sum']) == MaskedConstant:
                # No non-null values for raster data in polygon, skip
                for p in ['sum', 'mean', 'median', 'min', 'max', 'stddev']:
                    properties[p] = None
            else:
                properties['mean'] = numpy.nanmean(zoneraster)
                properties['min'] = numpy.nanmin(zoneraster)
                properties['max'] = numpy.nanmax(zoneraster)
                properties['stddev'] = numpy.nanstd(zoneraster)
                median = numpy.ma.median(zoneraster)
                if hasattr(median, 'data') and not numpy.isnan(median.data):
                    properties['median'] = median.data.item()
            yield (feature)
Exemplo n.º 25
0
def gdal_clip(raster_input, raster_output, polygon_json, nodata=0):
    """
    This function will subset a raster by a vector polygon.
    Adapted from the GDAL/OGR Python Cookbook at
    https://pcjericks.github.io/py-gdalogr-cookbook

    :param raster_input: raster input filepath
    :param raster_output: raster output filepath
    :param polygon_json: polygon as geojson string
    :param nodata: nodata value for output raster file
    :return: GDAL Dataset
    """
    def image_to_array(i):
        """
        Converts a Python Imaging Library array to a
        gdalnumeric image.
        """
        a = gdalnumeric.numpy.fromstring(i.tobytes(), 'b')
        a.shape = i.im.size[1], i.im.size[0]
        return a

    def world_to_pixel(geoMatrix, x, y):
        """
        Uses a gdal geomatrix (gdal.GetGeoTransform()) to calculate
        the pixel location of a geospatial coordinate
        """
        ulX = geoMatrix[0]
        ulY = geoMatrix[3]
        xDist = geoMatrix[1]
        pixel = int((x - ulX) / xDist)
        line = int((ulY - y) / xDist)
        return (pixel, line)

    src_image = get_dataset(raster_input)
    # Load the source data as a gdalnumeric array
    src_array = src_image.ReadAsArray()
    src_dtype = src_array.dtype

    # Also load as a gdal image to get geotransform
    # (world file) info
    geo_trans = src_image.GetGeoTransform()
    nodata_values = []
    for i in range(src_image.RasterCount):
        nodata_value = src_image.GetRasterBand(i + 1).GetNoDataValue()
        if not nodata_value:
            nodata_value = nodata
        nodata_values.append(nodata_value)

    # Create an OGR layer from a boundary GeoJSON geometry string
    if type(polygon_json) == dict:
        polygon_json = json.dumps(polygon_json)
    poly = ogr.CreateGeometryFromJson(polygon_json)

    # Convert the layer extent to image pixel coordinates
    min_x, max_x, min_y, max_y = poly.GetEnvelope()
    ul_x, ul_y = world_to_pixel(geo_trans, min_x, max_y)
    lr_x, lr_y = world_to_pixel(geo_trans, max_x, min_y)

    # Calculate the pixel size of the new image
    px_width = int(lr_x - ul_x)
    px_height = int(lr_y - ul_y)

    clip = src_array[ul_y:lr_y, ul_x:lr_x]

    # create pixel offset to pass to new image Projection info
    xoffset = ul_x
    yoffset = ul_y

    # Create a new geomatrix for the image
    geo_trans = list(geo_trans)
    geo_trans[0] = min_x
    geo_trans[3] = max_y

    # Map points to pixels for drawing the
    # boundary on a blank 8-bit,
    # black and white, mask image.
    raster_poly = Image.new("L", (px_width, px_height), 1)
    rasterize = ImageDraw.Draw(raster_poly)
    geometry_count = poly.GetGeometryCount()
    for i in range(0, geometry_count):
        points = []
        pixels = []
        pts = poly.GetGeometryRef(i)
        if pts.GetPointCount() == 0:
            pts = pts.GetGeometryRef(0)
        for p in range(pts.GetPointCount()):
            points.append((pts.GetX(p), pts.GetY(p)))
        for p in points:
            pixels.append(world_to_pixel(geo_trans, p[0], p[1]))
        rasterize.polygon(pixels, 0)
    mask = image_to_array(raster_poly)

    # Clip the image using the mask
    clip = gdalnumeric.numpy.choose(mask,
                                    (clip, nodata_value)).astype(src_dtype)

    # create output raster
    raster_band = raster_input.GetRasterBand(1)
    output_driver = gdal.GetDriverByName('MEM')
    output_dataset = output_driver.Create('', clip.shape[1], clip.shape[0],
                                          raster_input.RasterCount,
                                          raster_band.DataType)
    output_dataset.SetGeoTransform(geo_trans)
    output_dataset.SetProjection(raster_input.GetProjection())
    gdalnumeric.CopyDatasetInfo(raster_input,
                                output_dataset,
                                xoff=xoffset,
                                yoff=yoffset)
    bands = raster_input.RasterCount
    if bands > 1:
        for i in range(bands):
            outBand = output_dataset.GetRasterBand(i + 1)
            outBand.SetNoDataValue(nodata_values[i])
            outBand.WriteArray(clip[i])
    else:
        outBand = output_dataset.GetRasterBand(1)
        outBand.SetNoDataValue(nodata_values[0])
        outBand.WriteArray(clip)

    if raster_output:
        output_driver = gdal.GetDriverByName('GTiff')
        outfile = output_driver.CreateCopy(raster_output, output_dataset,
                                           False)
        logger.debug(str(outfile))
        outfile = None

    return output_dataset
Exemplo n.º 26
0
def run_miningrehab_app(ds):
    """
    Plots an interactive map of the mining case-study area and allows
    the user to draw polygons. This returns plots of the fractional cover value
    of bare soil, green vegetation and brown vegetation in the polygon area.
    Last modified: January 2020

    inputs
    ds - data set containing masked Fractional Cover data from Landsat 8
    """

    # Suppress warnings
    warnings.filterwarnings("ignore")

    # Update plotting functionality through rcParams
    mpl.rcParams.update({"figure.autolayout": True})

    # Define the bounding box that will be overlayed on the interactive map
    # The bounds are hard-coded to match those from the loaded data
    geom_obj = {
        "type": "Feature",
        "properties": {
            "style": {
                "stroke": True,
                "color": "red",
                "weight": 4,
                "opacity": 0.8,
                "fill": True,
                "fillColor": False,
                "fillOpacity": 0,
                "showArea": True,
                "clickable": True,
            }
        },
        "geometry": {
            "type":
            "Polygon",
            "coordinates": [[
                [116.630731, -34.434517],
                [116.630731, -34.426512],
                [116.648123, -34.426512],
                [116.648123, -34.434517],
                [116.630731, -34.434517],
            ]],
        },
    }

    # Create a map geometry from the geom_obj dictionary
    # center specifies where the background map view should focus on
    # zoom specifies how zoomed in the background map should be
    loadeddata_geometry = ogr.CreateGeometryFromJson(str(geom_obj["geometry"]))
    loadeddata_center = [
        loadeddata_geometry.Centroid().GetY(),
        loadeddata_geometry.Centroid().GetX(),
    ]
    loadeddata_zoom = 15

    # define the study area map
    studyarea_map = Map(
        layout=widgets.Layout(width="480px", height="600px"),
        center=loadeddata_center,
        zoom=loadeddata_zoom,
        basemap=basemaps.Esri.WorldImagery,
    )

    # define the drawing controls
    studyarea_drawctrl = DrawControl(
        polygon={"shapeOptions": {
            "fillOpacity": 0
        }},
        marker={},
        circle={},
        circlemarker={},
        polyline={},
    )

    # add drawing controls and data bound geometry to the map
    studyarea_map.add_control(studyarea_drawctrl)
    studyarea_map.add_layer(GeoJSON(data=geom_obj))

    # Index to count drawn polygons
    polygon_number = 0

    # Define widgets to interact with
    instruction = widgets.Output(layout={"border": "1px solid black"})
    with instruction:
        print("Draw a polygon within the red box to view plots of "
              "the fractional cover values of bare, green and "
              "non-green cover for the area over time.")

    info = widgets.Output(layout={"border": "1px solid black"})
    with info:
        print("Plot status:")

    fig_display = widgets.Output(layout=widgets.Layout(
        width="50%"  # proportion of horizontal space taken by plot
    ))

    with fig_display:
        plt.ioff()
        fig, ax = plt.subplots(3, 1, figsize=(9, 9))

        for axis in ax:
            axis.set_ylim([0, 1])

    colour_list = plt.rcParams["axes.prop_cycle"].by_key()["color"]

    # Function to execute each time something is drawn on the map
    def handle_draw(self, action, geo_json):
        nonlocal polygon_number

        #         info.clear_output(wait=True)  # wait=True reduces flicker effect
        #         with info:
        #             print("Plot status: entered handle draw")

        # Execute behaviour based on what the user draws
        if geo_json["geometry"]["type"] == "Polygon":

            # Convert the drawn geometry to pixel coordinates
            geom_selectedarea = transform_geojson_wgs_to_epsg(
                geo_json,
                EPSG=3577  # hard-coded to be same as case-study data
            )

            # Construct a mask to only select pixels within the drawn polygon
            mask = rasterio.features.geometry_mask(
                [geom_selectedarea for geoms in [geom_selectedarea]],
                out_shape=ds.geobox.shape,
                transform=ds.geobox.affine,
                all_touched=False,
                invert=True,
            )

            masked_ds = ds.where(mask)
            masked_ds_mean = masked_ds.mean(dim=["x", "y"], skipna=True)

            colour = colour_list[polygon_number % len(colour_list)]

            # Add a layer to the map to make the most recently drawn polygon
            # the same colour as the line on the plot
            studyarea_map.add_layer(
                GeoJSON(
                    data=geo_json,
                    style={
                        "color": colour,
                        "opacity": 1,
                        "weight": 4.5,
                        "fillOpacity": 0.0,
                    },
                ))

            # Add Fractional cover plots to app
            masked_ds_mean.BS.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[0])
            masked_ds_mean.PV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[1])
            masked_ds_mean.NPV.interpolate_na(
                dim="time", method="nearest").plot.line("-", ax=ax[2])

            # reset titles back to custom
            ax[0].set_ylabel("Bare cover")
            ax[1].set_ylabel("Green cover")
            ax[2].set_ylabel("Non-green cover")

            # refresh display
            fig_display.clear_output(
                wait=True)  # wait=True reduces flicker effect
            with fig_display:
                display(fig)

            # Update plot info
            info.clear_output(wait=True)  # wait=True reduces flicker effect
            with info:
                print("Plot status: polygon added to plot")

            # Iterate the polygon number before drawing another polygon
            polygon_number = polygon_number + 1

        else:
            info.clear_output(wait=True)
            with info:
                print("Plot status: this drawing tool is not currently "
                      "supported. Please use the polygon tool.")

    # call to say activate handle_draw function on draw
    studyarea_drawctrl.on_draw(handle_draw)

    with fig_display:
        # TODO: update with user friendly something
        display(widgets.HTML(""))

    # Construct UI:
    #  +-----------------------+
    #  | instruction           |
    #  +-----------+-----------+
    #  |  map      |  plot     |
    #  |           |           |
    #  +-----------+-----------+
    #  | info                  |
    #  +-----------------------+
    ui = widgets.VBox(
        [instruction,
         widgets.HBox([studyarea_map, fig_display]), info])
    display(ui)
Exemplo n.º 27
0
 def onAddLayersClick(self):
     try:
         # On parcourt les champs géographiques recensés
         for geoField in self.connector.getGeoFields():
             index = geoField["index"]
             type = geoField["type"]
             field = geoField["field"]
             geotype = geoField["geotype"]
             # On préparer les tableaux
             features = {
                 "MultiPoint": [],
                 "MultiLineString": [],
                 "MultiPolygon": []
             }
             # On parcourt les résultats
             hits = self.connector.getHits(index, type)
             if len(hits) > 0:
                 # Si on va récupérer des geo_point
                 if geotype == "geo_point":
                     for hit in hits:
                         try:
                             # On construit une feature et on l'ajoute au tableau
                             geoPoint = hit["_source"][field]
                             wkt = ""
                             if isinstance(geoPoint, str) or isinstance(
                                     geoPoint, unicode):
                                 coordinates = geoPoint.split(",")
                                 wkt = "POINT(" + coordinates[
                                     1] + " " + coordinates[0] + ")"
                             elif isinstance(geoPoint, dict):
                                 wkt = "POINT(" + geoPoint[
                                     "lon"] + " " + geoPoint["lat"] + ")"
                             elif isinstance(geoPoint, list):
                                 wkt = "POINT(" + geoPoint[
                                     1] + " " + geoPoint[0] + ")"
                             feature = QgsFeature()
                             feature.setGeometry(QgsGeometry.fromWkt(wkt))
                             features["MultiPoint"].append(feature)
                         except KeyError:
                             pass
                 # Si on va récupérer des geo_shape
                 elif geotype == "geo_shape":
                     for hit in hits:
                         try:
                             # On construit une feature et on l'ajoute au tableau
                             geom = hit["_source"][field]
                             geometry = ogr.CreateGeometryFromJson(
                                 json.dumps(geom))
                             wkt = geometry.ExportToWkt()
                             feature = QgsFeature()
                             feature.setGeometry(QgsGeometry.fromWkt(wkt))
                             geomtype = geom["type"].lower()
                             if "point" in geomtype:
                                 features["MultiPoint"].append(feature)
                             if "line" in geomtype:
                                 features["MultiLineString"].append(feature)
                             if "polygon" in geomtype:
                                 features["MultiPolygon"].append(feature)
                         except KeyError:
                             pass
                 # S'il y a au moins une géométrie exploitable qui a été récupérée dans ce champ
                 if len(features["MultiPoint"]) + len(
                         features["MultiLineString"]) + len(
                             features["MultiPolygon"]) > 0:
                     # On crée un groupe de couches
                     name = "[@ " + self.connector.getUrl(
                     ) + "] /" + index + "/" + type + "/" + field
                     group = QgsProject.instance().layerTreeRoot().addGroup(
                         name)
                     # On crée les couches vectorielles et on les ajoute à la carte
                     for geomtype in features:
                         if len(features[geomtype]) > 0:
                             # On crée la couche vectorielle
                             layer = QgsVectorLayer(
                                 geomtype + "?crs=EPSG:4326",
                                 geomtype[5:] + "s", "memory")
                             provider = layer.dataProvider()
                             # On ajoute le tableau de features à la couche
                             provider.addFeatures(features[geomtype])
                             layer.updateExtents()
                             # On ajoute la couche au groupe
                             QgsMapLayerRegistry.instance().addMapLayer(
                                 layer, False)
                             group.addLayer(layer)
         self.connector.clearGeoFields()
         self.iface.messageBar().pushMessage(
             "ElasticSearch Connector",
             u"Les couches ont été ajoutées",
             level=QgsMessageBar.INFO,
             duration=5)
         # On ferme la popup
         self.oncloseDlgClick()
     except ESConnectorException, e:
         self.iface.messageBar().pushMessage("ElasticSearch Connector",
                                             str(e),
                                             level=QgsMessageBar.CRITICAL,
                                             duration=5)
Exemplo n.º 28
0
            wgs_geojson_moved = {
                'coordinates': [corner_points_moved],
                'type': 'Polygon'
            }
            wgs_geojson_moved = json.dumps(wgs_geojson_moved)

            # wgs to utm
            utm_geojson_moved = {
                'coordinates': [wgs2utm.transform_points(corner_points_moved)],
                'type': 'Polygon'
            }
            utm_geojson_moved = json.dumps(utm_geojson_moved)

            # 6 create polygon geometry
            wgs_geom = ogr.CreateGeometryFromJson(wgs_geojson_moved)
            wgs_geom_polygon = ogr.ForceToPolygon(wgs_geom)
            utm_geom = ogr.CreateGeometryFromJson(utm_geojson_moved)

            # 7 create feature
            wgs_feat = ogr.Feature(wgs_layerDefn)
            wgs_feat.SetGeometry(wgs_geom)
            wgs_feat.SetField('GridID', '%s_%s' % (zone, id))
            # wgs_feat.SetGeomField('the_geom', wgs_geom)

            utm_feat = ogr.Feature(utm_layerDefn)
            utm_feat.SetGeometry(utm_geom)
            utm_feat.SetField('GridID', '%s_%s' % (zone, id))

            # 8 save feature
            wgs_lyr.CreateFeature(wgs_feat)
Exemplo n.º 29
0
def gen_zonalstats(zones_json, raster):

    # Open data
    raster = get_dataset(raster)
    shp = None
    if type(zones_json) is str:
        shp = ogr.Open(zones_json)
        zones_json = json.loads(zones_json)
    else:
        shp = ogr.Open(json.dumps(zones_json))

    lyr = shp.GetLayer()

    # Get raster georeference info
    transform = raster.GetGeoTransform()
    xOrigin = transform[0]
    yOrigin = transform[3]
    pixelWidth = transform[1]
    pixelHeight = transform[5]

    # Reproject vector geometry to same projection as raster
    sourceSR = lyr.GetSpatialRef()
    targetSR = osr.SpatialReference()
    targetSR.ImportFromWkt(raster.GetProjectionRef())
    coordTrans = osr.CoordinateTransformation(sourceSR, targetSR)

    for feature in zones_json['features']:
        geom = ogr.CreateGeometryFromJson(json.dumps(feature['geometry']))
        geom.Transform(coordTrans)

        # Get extent of feat
        if (geom.GetGeometryName() == 'MULTIPOLYGON'):
            count = 0
            pointsX = []
            pointsY = []
            for polygon in geom:
                geomInner = geom.GetGeometryRef(count)
                ring = geomInner.GetGeometryRef(0)
                numpoints = ring.GetPointCount()
                for p in range(numpoints):
                    lon, lat, z = ring.GetPoint(p)
                    pointsX.append(lon)
                    pointsY.append(lat)
                count += 1
        elif (geom.GetGeometryName() == 'POLYGON'):
            ring = geom.GetGeometryRef(0)
            numpoints = ring.GetPointCount()
            pointsX = []
            pointsY = []
            for p in range(numpoints):
                lon, lat, z = ring.GetPoint(p)
                pointsX.append(lon)
                pointsY.append(lat)

        else:
            raise GaiaException(
                "ERROR: Geometry needs to be either Polygon or Multipolygon")

        xmin = min(pointsX)
        xmax = max(pointsX)
        ymin = min(pointsY)
        ymax = max(pointsY)

        # Specify offset and rows and columns to read
        xoff = int((xmin - xOrigin) / pixelWidth)
        yoff = int((yOrigin - ymax) / pixelWidth)
        xcount = int((xmax - xmin) / pixelWidth) + 1
        ycount = int((ymax - ymin) / pixelWidth) + 1

        # Create memory target raster
        target_ds = gdal.GetDriverByName('MEM').Create('', xcount, ycount, 1,
                                                       gdal.GDT_Byte)
        target_ds.SetGeoTransform((
            xmin,
            pixelWidth,
            0,
            ymax,
            0,
            pixelHeight,
        ))

        # Create for target raster the same projection as for the value raster
        raster_srs = osr.SpatialReference()
        raster_srs.ImportFromWkt(raster.GetProjectionRef())
        target_ds.SetProjection(raster_srs.ExportToWkt())

        # Rasterize zone polygon to raster
        gdal.RasterizeLayer(target_ds, [1], lyr, burn_values=[1])

        # Read raster as arrays
        banddataraster = raster.GetRasterBand(1)
        dataraster = banddataraster.ReadAsArray(xoff, yoff, xcount,
                                                ycount).astype(numpy.float)

        bandmask = target_ds.GetRasterBand(1)
        datamask = bandmask.ReadAsArray(0, 0, xcount,
                                        ycount).astype(numpy.float)

        # Mask zone of raster
        zoneraster = numpy.ma.masked_array(dataraster,
                                           numpy.logical_not(datamask))

        properties = feature['properties']
        properties['count'] = zoneraster.count()
        properties['sum'] = zoneraster.sum()
        properties['mean'] = zoneraster.mean()
        properties['median'] = numpy.median(zoneraster)
        properties['min'] = zoneraster.min()
        properties['max'] = zoneraster.max()
        properties['stddev'] = zoneraster.std()
        yield (feature)
Exemplo n.º 30
0
def sample(raster, input, output, n_samples, epsg=3310):
    '''
    :param raster: the raster data from which sample will be taken
    :param input: boundary of the sample area
    :param output: location of sample points
    :param n_samples: samples taken from the pixels
    :return: Data Frame
    '''

    # check data type
    dataType = os.path.basename(input).split('.')[1]

    if dataType == "shp":

        driver = ogr.GetDriverByName("ESRI Shapefile")
        file = driver.Open(input, 0)
        layer = file.GetLayer()
        env = layer.GetExtent()
        polygon = ogr.Geometry(ogr.wkbGeometryCollection)
        xmin, ymin, xmax, ymax = env[0], env[2], env[1], env[3]


        for feature in layer:
            geom = feature.GetGeometryRef()
            ring = geom.GetGeometryRef(0)
            polygon.AddGeometry(ring)


    else:

        #get boundary values from json
        with open(input) as f:
            data = json.load(f)
        for feature in data['features']:
            geom = feature['geometry']
            geom = json.dumps(geom)
            polygon = ogr.CreateGeometryFromJson(geom)

        env = polygon.GetEnvelope()
        xmin, ymin, xmax, ymax = env[0], env[2], env[1], env[3]



    # Read raster
    src_ds = gdal.Open(raster)
    geoT = src_ds.GetGeoTransform()


    num_points = n_samples
    counter = 0
    rows = []

    # write random points to vector-point
    multipoint = ogr.Geometry(ogr.wkbMultiPoint)
    outDriver = ogr.GetDriverByName("ESRI Shapefile")
    outDataSource = outDriver.CreateDataSource(output)
    outLayer = outDataSource.CreateLayer(output, geom_type=ogr.wkbPoint)



    for i in range(0, num_points):
        i += 1

        '''
        If random point (i) is inside the boundary: 
        store the location and extract pixel values
        '''

        point = ogr.Geometry(ogr.wkbPoint)
        point.AddPoint(random.uniform(xmin, xmax),
                       random.uniform(ymin, ymax))


        if point.Within(polygon):
            multipoint.AddGeometry(point)
            counter += 1

            featureDefn = outLayer.GetLayerDefn()
            outFeature = ogr.Feature(featureDefn)
            outFeature.SetGeometry(point)
            outLayer.CreateFeature(outFeature)

            mx, my = point.GetX(), point.GetY()
            px = int((mx - geoT[0]) / geoT[1])
            py = int((my - geoT[3]) / geoT[5])
            xcount = 1
            ycount = 1


            ext = []

            # Extract pixels values for all bands
            for i in range(0, src_ds.RasterCount):
                i += 1
                dump = src_ds.GetRasterBand(i).ReadAsArray(px, py, xcount, ycount)
                extract = [x for x in dump if x != None]
                result = extract[0]
                ext.append(result[0])
            rows.append(ext)


    # Return data frame
    df = pd.DataFrame(rows)


    # Create projection (prj file)
    spatialRef = osr.SpatialReference()
    spatialRef.ImportFromEPSG(epsg)


    spatialRef.MorphToESRI()
    prj_full_path = os.path.split(output)
    prj_path = os.path.split(output)[0]
    prj_file_name = os.path.split(output)[1]


    prj_full_path = os.path.basename(output).split('.')[0]
    k = prj_full_path + '.prj'
    file = open(k, 'w')
    r = os.path.join(prj_path, k)
    file = open(r, 'w')


    file.write(spatialRef.ExportToWkt())
    file.close()


    # write to csv
    text = prj_full_path + '.txt'
    r = os.path.join(prj_path, text)
    df.to_csv(r)



    return df