def shp_to_json(base_path, shp_path, name): """ Conversion helper function uses ogr to project shapefiles and convert them to GeoJSON, and returns the filesystem path to the result. """ print " -- Projecting shapefile to WGS-84 and converting to JSON" # define ogr drivers shp_driver = ogr.GetDriverByName('ESRI Shapefile') json_driver = ogr.GetDriverByName('GeoJSON') # define the input layer shp = shp_driver.Open(shp_path) shp_lyr = shp.GetLayer() # create the output layer json_path = os.path.join(base_path, name + ".geojson") if os.path.exists(json_path): json_driver.DeleteDataSource(json_path) json = json_driver.CreateDataSource(json_path) json_lyr = json.CreateLayer(json_path, geom_type=ogr.wkbMultiPolygon) json_lyr_defn = json_lyr.GetLayerDefn() # create the CoordinateTransformation json_ref = osr.SpatialReference() json_ref.ImportFromEPSG(4326) coord_trans = osr.CoordinateTransformation(shp_lyr.GetSpatialRef(), json_ref) # add fields to output layer shp_lyr_defn = shp_lyr.GetLayerDefn() for i in range(0, shp_lyr_defn.GetFieldCount()): field_defn = shp_lyr_defn.GetFieldDefn(i) json_lyr.CreateField(field_defn) # loop through the input features shp_feat = shp_lyr.GetNextFeature() while shp_feat: # reproject the input geometry geom = shp_feat.GetGeometryRef() geom.Transform(coord_trans) # create a new feature json_feat = ogr.Feature(json_lyr_defn) # set the feature's geometry and attributes json_feat.SetGeometry(geom) for i in range(0, json_lyr_defn.GetFieldCount()): json_feat.SetField( json_lyr_defn.GetFieldDefn(i).GetNameRef(), shp_feat.GetField(i)) # add new feature to output Layer json_lyr.CreateFeature(json_feat) # destroy the features and get the next input feature json_feat.Destroy() shp_feat.Destroy() shp_feat = shp_lyr.GetNextFeature() # close the datasets shp.Destroy() json.Destroy() return json_path
geom_type=geom_type('ContourLIne10.shp')) # use the input FieldDefn to add a field to the output fieldDefn = inLayer.GetFeature(0).GetFieldDefnRef('id') outLayer.CreateField(fieldDefn) # get the FeatureDefn for the output layer featureDefn = outLayer.GetLayerDefn() # loop through the input features cnt = 0 inFeature = inLayer.GetNextFeature() while inFeature: # create a new feature outFeature = ogr.Feature(featureDefn) outFeature.SetGeometry(inFeature.GetGeometryRef()) outFeature.SetField('id', inFeature.GetField('id')) # add the feature to the output layer outLayer.CreateFeature(outFeature) # destroy the features inFeature.Destroy() outFeature.Destroy() # increment cnt and if we have to do more then keep looping cnt = cnt + 1 if cnt < 10000: inFeature = inLayer.GetNextFeature() else:
def SunlightDurationEstimation(skyImgFolder,outputSunpathFolder,timeLst,shpfile): ''' # This is function is used to calculate the sunlight duration based on # the sun trajectories and the classified sky images, save the result as shpfile # --------------The duration of sunlight--------------------- # Copyright (C) Xiaojiang Li, MIT Senseable City Lab # First version March 21st, 2017 Parameters: skyImg: the input sky image timeList: the time series, timeList = [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] shpfile: the output shapefile to store the distribution of sunlight duration ''' from PIL import Image import numpy as np import urllib import os, os.path import math from pysolar.solar import get_altitude, get_azimuth import gdal,ogr,osr # create a shpafile to save the sun duration driver = ogr.GetDriverByName("ESRI Shapefile") if os.path.exists(shpfile): driver.DeleteDataSource(shpfile) data_source = driver.CreateDataSource(shpfile) targetSpatialRef = osr.SpatialReference() targetSpatialRef.ImportFromEPSG(4326) outLayer = data_source.CreateLayer("SunDur",targetSpatialRef, ogr.wkbPoint) sunDur = ogr.FieldDefn('sundur', ogr.OFTReal) panoId = ogr.FieldDefn('panoid', ogr.OFTString) outLayer.CreateField(sunDur) outLayer.CreateField(panoId) # loop all the sky image in the folder for skyimg in os.listdir(skyImgFolder): skyImgFile = os.path.join(skyImgFolder,skyimg) # read GSV panorama images basename = os.path.basename(skyImgFile)[:-4] print ('The basename of the file is:', basename) fields = basename.split(' - ') panoID = fields[0] lon = float(fields[1]) lat = float(fields[2]) #month = fields[3][-2:] point = ogr.Geometry(ogr.wkbPoint) point.AddPoint(lon, lat) # the output filename skyImgName = '%s_sky.jpg'%(basename) sunpathFisheyeName = '%s_sunpath.tif'%(basename) outputSkyImgFile = os.path.join(outputSunpathFolder,skyImgName) outputSunpathImageFile = os.path.join(outputSunpathFolder,sunpathFisheyeName) ## ESTIMATE THE DURATION OF DIRECT SUNLIGHT skyImg = np.array(Image.open(skyImgFile)) [rows,cols] = skyImg.shape # the duration hours of sunlight hours = 0 for i in range(len(timeLst)): #print ('The time is:',timeLst[i]) currentTime = timeLst[i] # flag whether one site is under the shade 0 or not 1 flag = 1 # calculate the position of sun based on the coordinate and the time information sunele = get_altitude(lat, lon, currentTime) #print ('----',lat,lon,currentTime) #print ('The sun elevation is:', sunele) sunele = sunele*np.pi/180.0 azimuth = abs(get_azimuth(lat, lon, currentTime)) + 180 if azimuth > 360: azimuth = azimuth - 360 #print ('The azimuth of the sun is:', azimuth) azimuth = azimuth*np.pi/180.0 + 0.5*np.pi # BASED ON THE AZIMUTH AND SUN ELEVATION TO LOCATE THE CORRESPODING PIXELS ON THE FISHEYE IMAGE R = int(0.5*rows) # get the r in the polar coordinate if sunele < 0: flag = 0 sunele = 0 # differnet way to put the sunpath in the fisheye image r = 2*R*(0.5*np.pi - sunele)/np.pi # the distrance between different degree is equal # get the coordinate of the point on the fisheye images px = int(r*math.cos(azimuth) + int(0.5*cols)) - 1 py = int(int(0.5*rows) - r*math.sin(azimuth)) - 1 # if the x,y is out of the hemispherical images radi = math.sqrt((px - 0.5*cols)**2 + (py - 0.5*rows)**2) #print ('The radius is:=================', radi) if radi >= 0.5*cols: flag = 0 # check whether the site is located on the clear sky or the obstructions buff = 10 boundXl = px - buff if boundXl < 0: boundXl = 0 boundXu = px + buff if boundXu > cols - 1: boundXu = rows - 1 boundYl = py - buff if boundYl < 0: boundYl = 0 boundYu = py + buff if boundYu > rows - 1: boundYu = cols - 1 # create a circle like sun postion for x in range(boundXl,boundXu): for y in range(boundYl, boundYu): # calculate the distance between the pixel with the center dist = math.sqrt((x - px)**2 + (y - py)**2) if dist < buff: if skyImg[y,x] < 1 and flag == 1: flag = 0 skyImg[y,x] = 125 continue continue if flag == 1: hours = hours + 0.1 ## imgSunpath = Image.fromarray(skyImg) ## imgSunpath.save(outputSunpathImageFile) ## del imgSunpath print ('The duration of the hours is:----------',hours) del skyImg # create feature and set the attribute values featureDefn = outLayer.GetLayerDefn() outFeature = ogr.Feature(featureDefn) # set the geometrical feature outFeature.SetGeometry(point) outFeature.SetField('sundur',hours) outFeature.SetField('panoid',panoID) # push the feature to the layer outLayer.CreateFeature(outFeature) outFeature.Destroy() data_source.Destroy()
def HandleTile(t, shp, dstdir, csvpath, args, exclude_list): otxtpath = os.path.join( dstdir, "%s_%s_orig.txt" % (os.path.basename(csvpath)[:-4], t.name)) mtxtpath = os.path.join( dstdir, "%s_%s_ortho.txt" % (os.path.basename(csvpath)[:-4], t.name)) if os.path.isfile(otxtpath) and os.path.isfile( mtxtpath) and args.overwrite is False: logger.info("Tile %s processing files already exist" % t.name) else: logger.debug("Tile %s" % (t.name)) t_srs = osr.SpatialReference() t_srs.ImportFromEPSG(t.epsg) #### Open Shp shpd, shpn = os.path.split(shp) shpbn, shpe = os.path.splitext(shpn) ds = ogr.Open(shp) if ds is None: logger.warning("Open failed") else: lyr = ds.GetLayerByName(shpbn) #### attribute filter for online images if args.online_only: lyr.SetAttributeFilter('STATUS = "online"') s_srs = lyr.GetSpatialRef() #logger.debug(str(s_srs)) logger.debug(str(t.geom)) if not t_srs.IsSame(s_srs): ict = osr.CoordinateTransformation(t_srs, s_srs) ct = osr.CoordinateTransformation(s_srs, t_srs) lyr.ResetReading() feat = lyr.GetNextFeature() imginfo_list1 = [] while feat: iinfo = ImageInfo(feat, "RECORD", srs=s_srs) if iinfo.geom is not None and iinfo.geom.GetGeometryType( ) == ogr.wkbPolygon: if not t_srs.IsSame(s_srs): iinfo.geom.Transform(ct) if iinfo.geom.Intersect(t.geom): if iinfo.scene_id in exclude_list: logger.debug( "Scene in exclude list, excluding: %s" % iinfo.srcfp) elif args.online_only and not os.path.isfile( iinfo.srcfp): logger.warning( "Scene does not exist, excluding: {0}".format( iinfo.srcfp)) else: logger.debug( "Intersect %s, %s: %s" % (iinfo.scene_id, iinfo.srcfp, str(iinfo.geom))) imginfo_list1.append(iinfo) feat = lyr.GetNextFeature() ds = None logger.info("Number of intersects in tile %s: %i" % (t.name, len(imginfo_list1))) if len(imginfo_list1) > 0: if args.nosort is False: #### Get mosaic parameters logger.debug("Getting mosaic parameters") params = getMosaicParameters(imginfo_list1[0], args) #### Remove images that do not match ref logger.debug("Setting image pattern filter") imginfo_list2 = filterMatchingImages(imginfo_list1, params) logger.info("Number of images matching filter: %i" % (len(imginfo_list2))) #### Sort by quality logger.debug("Sorting images by quality") imginfo_list3 = [] for iinfo in imginfo_list2: iinfo.getScore(params) if iinfo.score > 0: imginfo_list3.append(iinfo) imginfo_list3.sort(key=lambda x: x.score) if args.build_shp: ####################################################### #### Create Shp shp = os.path.join( dstdir, "%s_%s_imagery.shp" % (os.path.basename(csvpath)[:-4], t.name)) logger.debug("Creating shapefile of geoms: %s" % shp) fields = [("IMAGENAME", ogr.OFTString, 100), ("SCORE", ogr.OFTReal, 0)] OGR_DRIVER = "ESRI Shapefile" ogrDriver = ogr.GetDriverByName(OGR_DRIVER) if ogrDriver is None: logger.debug("OGR: Driver %s is not available" % OGR_DRIVER) sys.exit(-1) if os.path.isfile(shp): ogrDriver.DeleteDataSource(shp) vds = ogrDriver.CreateDataSource(shp) if vds is None: logger.debug("Could not create shp") sys.exit(-1) shpd, shpn = os.path.split(shp) shpbn, shpe = os.path.splitext(shpn) lyr = vds.CreateLayer(shpbn, t_srs, ogr.wkbPolygon) if lyr is None: logger.debug("ERROR: Failed to create layer: %s" % shpbn) sys.exit(-1) for fld, fdef, flen in fields: field_defn = ogr.FieldDefn(fld, fdef) if fdef == ogr.OFTString: field_defn.SetWidth(flen) if lyr.CreateField(field_defn) != 0: logger.debug( "ERROR: Failed to create field: %s" % fld) for iinfo in imginfo_list3: logger.debug("Image: %s" % (iinfo.srcfn)) feat = ogr.Feature(lyr.GetLayerDefn()) feat.SetField("IMAGENAME", iinfo.srcfn) feat.SetField("SCORE", iinfo.score) feat.SetGeometry(iinfo.geom) if lyr.CreateFeature(feat) != 0: logger.debug( "ERROR: Could not create feature for image %s" % iinfo.srcfn) else: logger.debug("Created feature for image: %s" % iinfo.srcfn) feat.Destroy() #### Overlay geoms and remove non-contributors logger.debug("Overlaying images to determine contributors") contribs = [] for i in xrange(0, len(imginfo_list3)): iinfo = imginfo_list3[i] basegeom = iinfo.geom for j in range(i + 1, len(imginfo_list3)): iinfo2 = imginfo_list3[j] geom2 = iinfo2.geom if basegeom.Intersects(geom2): basegeom = basegeom.Difference(geom2) if basegeom is None or basegeom.IsEmpty(): #logger.debug("Broke after %i comparisons" %j) break if basegeom is None: logger.debug("Function Error: %s" % iinfo.srcfp) elif basegeom.IsEmpty(): logger.debug( "Removing non-contributing image: %s" % iinfo.srcfp) else: basegeom = basegeom.Intersection(t.geom) if basegeom is None: logger.debug("Function Error: %s" % iinfo.srcfp) elif basegeom.IsEmpty(): logger.debug( "Removing non-contributing image: %s" % iinfo.srcfp) else: contribs.append(iinfo.srcfp) elif args.nosort is True: contribs = image_list logger.info("Number of contributing images: %i" % (len(contribs))) if len(contribs) > 0: #### Write textfiles if not os.path.isdir(dstdir): os.makedirs(dstdir) otxtpath = os.path.join( dstdir, "%s_%s_orig.txt" % (os.path.basename(csvpath)[:-4], t.name)) mtxtpath = os.path.join( dstdir, "%s_%s_ortho.txt" % (os.path.basename(csvpath)[:-4], t.name)) otxt = open(otxtpath, 'w') mtxt = open(mtxtpath, 'w') for contrib in contribs: if not os.path.isfile(contrib): logger.warning("Image does not exist: %s" % (contrib)) otxt.write("%s\n" % contrib) m_fn = "{0}_u08{1}{2}.tif".format( os.path.splitext(os.path.basename(contrib))[0], args.stretch, t.epsg) mtxt.write( os.path.join(dstdir, 'orthos', t.name, m_fn) + "\n") otxt.close()
def polygonize(): global currentchunk global totalsubsets global base_name currentchunk = 0 totalsubsets = 0 outputgdal = dir_base_name + "-gdal-tmp.tif" # QGIS POLYGONIZE print "" print "Polygonizing (coarse):" print "----------------------" shapefile = dir_base_name + '.shp' if (not os.path.isfile(shapefile)): command = 'gdal_polygonize.py ' + outputgdal + ' -f "ESRI Shapefile" ' + shapefile + ' ' + base_name logging.debug(command) # print command os.system(command) # Split resulting megapolygon file into smaller chunks # most code from: http://cosmicproject.org/OGR/cris_example_write.html print "" print "Splitting megapolygon file into chunks" print "--------------------------------------" ##### # 2 get the shapefile driver driver = ogr.GetDriverByName('ESRI Shapefile') # 3 open the input data source and get the layer inDS = driver.Open(shapefile, 0) #shows cover at given points if inDS is None: print 'Could not open shapefile' sys.exit(1) inLayer = inDS.GetLayer() # 5 get the FieldDefn's for the id and cover fields in the input shapefile feature = inLayer.GetFeature(0) idFieldDefn = feature.GetFieldDefnRef('DN') # 7 loop through the input features inFeature = inLayer.GetNextFeature() while inFeature: if currentchunk == 0 or currentchunk >= chunksize: currentchunk = 0 totalsubsets = totalsubsets + 1 # this is a new temp file # 4 create a new data source and layer fn = dir_base_name + '-tmp-' + str(totalsubsets) + '.shp' if os.path.exists(fn): driver.DeleteDataSource(fn) outDS = driver.CreateDataSource(fn) if outDS is None: print 'Could not create temp shapefile' sys.exit(1) outLayer = outDS.CreateLayer(base_name, geom_type=ogr.wkbPolygon) #create new field in the output shapefile outLayer.CreateField(idFieldDefn) # 6 get the FeatureDefn for the output layer featureDefn = outLayer.GetLayerDefn() # create a new feature outFeature = ogr.Feature( featureDefn) #using featureDefn created in step 6 # set the geometry geom = inFeature.GetGeometryRef() outFeature.SetGeometry(geom) #move it to the new feature # set the attributes DN = inFeature.GetField('DN') outFeature.SetField('DN', DN) #move it to the new feature # add the feature to the output layer outLayer.CreateFeature(outFeature) # destroy the output feature outFeature.Destroy() # destroy the input feature and get a new one inFeature.Destroy() inFeature = inLayer.GetNextFeature() currentchunk = currentchunk + 1 # close the data sources inDS.Destroy() outDS.Destroy() #flush out the last changes here print "" print "Produced " + str(totalsubsets) + " temporary shapefiles" print ""
def main(outputGridfn,xmin,xmax,ymin,ymax,gridHeight,gridWidth): # convert sys.argv to float xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) gridWidth = float(gridWidth) gridHeight = float(gridHeight) # get rows rows = ceil((ymax-ymin)/gridHeight) # get columns cols = ceil((xmax-xmin)/gridWidth) # start grid cell envelope ringXleftOrigin = xmin ringXrightOrigin = xmin + gridWidth ringYtopOrigin = ymax ringYbottomOrigin = ymax-gridHeight # create output file outDriver = ogr.GetDriverByName('ESRI Shapefile') if os.path.exists(outputGridfn): os.remove(outputGridfn) outDataSource = outDriver.CreateDataSource(outputGridfn) outLayer = outDataSource.CreateLayer(outputGridfn,geom_type=ogr.wkbPolygon ) featureDefn = outLayer.GetLayerDefn() # create grid cells countcols = 0 while countcols < cols: countcols += 1 # reset envelope for rows ringYtop = ringYtopOrigin ringYbottom =ringYbottomOrigin countrows = 0 while countrows < rows: countrows += 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 outFeature = ogr.Feature(featureDefn) outFeature.SetGeometry(poly) outLayer.CreateFeature(outFeature) outFeature.Destroy # new envelope for next poly ringYtop = ringYtop - gridHeight ringYbottom = ringYbottom - gridHeight # new envelope for next poly ringXleftOrigin = ringXleftOrigin + gridWidth ringXrightOrigin = ringXrightOrigin + gridWidth # Close DataSources outDataSource.Destroy()
def createFishnet(outputGridfn, xmin, xmax, ymin, ymax, gridHeight, gridWidth, crsNum=4326): ''' Create a fishnet shapefile inside the defined coordinates outputGridfn: output shapefile to hold the grid xmin,xmax,ymin,ymax: coordinates for the extent of the fishnet gridHeight,gridWidth: dimensions of the grid cells in the outpout fishnet ''' #Define projection testSR = osr.SpatialReference() res = testSR.ImportFromEPSG(crsNum) if res != 0: raise RuntimeError(repr(res) + ': could not import from EPSG') # convert sys.argv to float xmin = float(xmin) xmax = float(xmax) ymin = float(ymin) ymax = float(ymax) gridWidth = float(gridWidth) gridHeight = float(gridHeight) # get rows rows = ceil((ymax - ymin) / gridHeight) # get columns cols = ceil((xmax - xmin) / gridWidth) # start grid cell envelope ringXleftOrigin = xmin ringXrightOrigin = xmin + gridWidth ringYtopOrigin = ymax ringYbottomOrigin = ymax - gridHeight # create output file outDriver = ogr.GetDriverByName('ESRI Shapefile') if os.path.exists(outputGridfn): os.remove(outputGridfn) outDataSource = outDriver.CreateDataSource(outputGridfn) outLayer = outDataSource.CreateLayer(outputGridfn, testSR, geom_type=ogr.wkbPolygon) featureDefn = outLayer.GetLayerDefn() # create grid cells countcols = 0 while countcols < cols: countcols += 1 # reset envelope for rows ringYtop = ringYtopOrigin ringYbottom = ringYbottomOrigin countrows = 0 while countrows < rows: countrows += 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 outFeature = ogr.Feature(featureDefn) outFeature.SetGeometry(poly) outLayer.CreateFeature(outFeature) outFeature.Destroy # new envelope for next poly ringYtop = ringYtop - gridHeight ringYbottom = ringYbottom - gridHeight # new envelope for next poly ringXleftOrigin = ringXleftOrigin + gridWidth ringXrightOrigin = ringXrightOrigin + gridWidth # Close DataSources outDataSource.Destroy()
def main(use_random_set_of_input_points, number_of_random_points, input_samples, input_samples_point_shapefile_output_path, voronoi_polygons_shapefile_output_path, geogr_sr_text): voronoi_polygon_areas = [] """ We use +- 179.999999 rather than +- 180 deg lon to indicate a date line since -180 deg lon is sometimes automatically converted to +180 deg lon by GDAL/OGR. """ if use_random_set_of_input_points == True: """ Generate random Points """ randomness_generate_random_points(number_of_random_points) input_samples = random_points if len(input_samples) < 20: print "Need minimum of 20 points for the construction of Voronoi polygons." exit() input_craters_scipy = numpy.array([]) voronoi_out_polygons_geogr_sr = osr.SpatialReference() voronoi_out_polygons_geogr_sr.ImportFromWkt(geogr_sr_text) """ Generate Shapefiles """ # Craters driver = ogr.GetDriverByName('Esri Shapefile') points_data_source = driver.CreateDataSource(input_samples_point_shapefile_output_path) points_layer = points_data_source.CreateLayer('Voronoi_Points', voronoi_out_polygons_geogr_sr, geom_type = ogr.wkbPoint) # Voronoi Polygons driver = ogr.GetDriverByName('Esri Shapefile') voronoi_polygon_data_source = driver.CreateDataSource(voronoi_polygons_shapefile_output_path) voronoi_polygon_layer = voronoi_polygon_data_source.CreateLayer('Voronoi_Polygons', voronoi_out_polygons_geogr_sr, geom_type = ogr.wkbPolygon) area_field_defn = ogr.FieldDefn("Area", ogr.OFTReal) voronoi_polygon_layer.CreateField(area_field_defn) """ Project geographic coordinates to coordinates in 3D space [-1,1] """ point = ogr.Geometry(ogr.wkbPoint) point.AssignSpatialReference(voronoi_out_polygons_geogr_sr) for input_crater in input_samples: input_crater_X = input_crater[0] input_crater_Y = input_crater[1] point.AddPoint(input_crater_X, input_crater_Y) input_crater_X = math.pi*input_crater_X/180 # Convert to radians input_crater_Y = math.pi*input_crater_Y/180 input_crater_Y -= 1.570795765134 # subtract 90 degrees (in radians) input_crater_X_3D = math.sin(input_crater_Y) * math.cos(input_crater_X) input_crater_Z_3D = math.cos(input_crater_Y) input_crater_Y_3D = math.sin(input_crater_Y) * math.sin(input_crater_X) input_craters_scipy = numpy.append(input_craters_scipy, [[input_crater_X_3D, input_crater_Y_3D, input_crater_Z_3D]]) points_featureDefn = points_layer.GetLayerDefn() points_feature = ogr.Feature(points_featureDefn) points_feature.SetGeometry(point) points_layer.CreateFeature(points_feature) input_craters_scipy.resize((len(input_samples), 3)) # reshape numpy array """ Calculate Voronoi diagrams on a sphere in 3D space. This only generates vertices on the sphere. Polygon edges cut the sphere's interior. """ sphere_center_coordinates = numpy.array([0, 0, 0]) sphere_radius = 1 spherical_voronoi = SphericalVoronoi(input_craters_scipy, sphere_radius, sphere_center_coordinates) spherical_voronoi.sort_vertices_of_regions() """ Main part of geodesic Voronoi polygon generation: Calculate spherical coordinates of each Voronoi Polygon and save geometries. """ voronoi_count = 0 for spherical_voronoi_region_3D in spherical_voronoi.regions: voronoi_vertex_count = 1 voronoi_polygon_area = 0 voronoi_out_polygons = ogr.Geometry(ogr.wkbPolygon) voronoi_out_polygons.AssignSpatialReference(voronoi_out_polygons_geogr_sr) """ Calculate geographic coordinates of polygon vertices """ lons = [] lats = [] for spherical_voronoi_vertex_3D in spherical_voronoi.vertices[spherical_voronoi_region_3D]: spherical_voronoi_vertex_3D_X = spherical_voronoi_vertex_3D[0] spherical_voronoi_vertex_3D_Y = spherical_voronoi_vertex_3D[1] spherical_voronoi_vertex_3D_Z = spherical_voronoi_vertex_3D[2] spherical_voronoi_vertex_lon = math.degrees(math.atan(spherical_voronoi_vertex_3D_Y/spherical_voronoi_vertex_3D_X)) """ Account for atan ambiguity. Otherwise, polygon vertices would all be on the nearside. """ if spherical_voronoi_vertex_3D_X > 0: spherical_voronoi_vertex_lon -= 180 if spherical_voronoi_vertex_lon < -180: spherical_voronoi_vertex_lon += 360 spherical_voronoi_vertex_lat = math.degrees(math.asin(spherical_voronoi_vertex_3D_Z)) """ Add vertex to lons[] and lats[] """ lons.append(spherical_voronoi_vertex_lon) lats.append(spherical_voronoi_vertex_lat) if voronoi_vertex_count == 1: spherical_voronoi_end_vertex_lon = spherical_voronoi_vertex_lon spherical_voronoi_end_vertex_lat = spherical_voronoi_vertex_lat voronoi_vertex_count += 1 """ Close ring """ lons.append(spherical_voronoi_end_vertex_lon) lats.append(spherical_voronoi_end_vertex_lat) """ define reprojections from input craters (center of voronoi polygon) """ center_voronoi_polygon_X = input_samples[voronoi_count][0] center_voronoi_polygon_Y = input_samples[voronoi_count][1] voronoi_LAEA_text = 'PROJCS["PROJECTED_LAMBERT_AEA",'+str(voronoi_out_polygons_geogr_sr)+',PROJECTION["Lambert_Azimuthal_Equal_Area"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["central_meridian",'+str(center_voronoi_polygon_X)+'],PARAMETER["latitude_of_origin",'+str(center_voronoi_polygon_Y)+'],UNIT["Meter",1.0]]' voronoi_LAEA_sr = osr.SpatialReference() voronoi_LAEA_sr.ImportFromWkt(voronoi_LAEA_text) voronoi_geogr_text = re.sub('(PRIMEM)(.*)(,)', r'\1["Reference_Meridian",' + str(center_voronoi_polygon_X) + '],', str(voronoi_out_polygons_geogr_sr)) voronoi_geogr_sr = osr.SpatialReference() voronoi_geogr_sr.ImportFromWkt(voronoi_geogr_text) """ define reprojections """ geogr_to_proj_voronoi = osr.CoordinateTransformation(voronoi_out_polygons_geogr_sr, voronoi_LAEA_sr) proj_voronoi_to_geogr = osr.CoordinateTransformation(voronoi_LAEA_sr, voronoi_out_polygons_geogr_sr) proj_voronoi_to_geogr_voronoi = osr.CoordinateTransformation(voronoi_LAEA_sr, voronoi_geogr_sr) geogr_voronoi_to_proj_voronoi = osr.CoordinateTransformation(voronoi_geogr_sr, voronoi_LAEA_sr) """ define polygons that eventually become a voronoi polygon """ voronoi_ring = ogr.Geometry(ogr.wkbLinearRing) voronoi_ring.AssignSpatialReference(voronoi_out_polygons_geogr_sr) voronoi_ring_dateline_intersection = ogr.Geometry(ogr.wkbLinearRing) voronoi_ring_dateline_intersection.AssignSpatialReference(voronoi_out_polygons_geogr_sr) major_axis = voronoi_out_polygons_geogr_sr.GetSemiMajor() minor_axis = voronoi_out_polygons_geogr_sr.GetSemiMinor() flattening = (major_axis-minor_axis) / major_axis """ Use vertices of voronoi polygons to calculate geodesic polygon edges. """ voronoi_vertex_lat_lon_count = 0 voronoi_date_line_intersection_count = 0 for voronoi_vertex_lon in lons: voronoi_vertex_lat = lats[voronoi_vertex_lat_lon_count] if voronoi_vertex_lat_lon_count+1 < len(lons): voronoi_next_vertex_lat = lats[voronoi_vertex_lat_lon_count+1] voronoi_next_vertex_lon = lons[voronoi_vertex_lat_lon_count+1] if voronoi_vertex_lat_lon_count+1 >= len(lons): if voronoi_date_line_intersection_count % 2 == 0: voronoi_ring.AddPoint(lons[0], lats[0]) if voronoi_date_line_intersection_count % 2 == 1: voronoi_ring_dateline_intersection.AddPoint(lons[0], lats[0]) continue if voronoi_date_line_intersection_count % 2 == 0: voronoi_ring.AddPoint(voronoi_vertex_lon, voronoi_vertex_lat) if voronoi_date_line_intersection_count % 2 == 1: voronoi_ring_dateline_intersection.AddPoint(voronoi_vertex_lon, voronoi_vertex_lat) """ Get distance and azimuth between voronoi vertices. """ inverse_vincenty(flattening, major_axis, voronoi_vertex_lat, voronoi_vertex_lon, voronoi_next_vertex_lat, voronoi_next_vertex_lon) geodesic_distance_between_voronoi_vertices = geodesic_distance_crater_area azimuth_between_voronoi_vertices = direction12 distance_geodesic_polygon_vertices = 0 geodesic_voronoi_vertices_count = 0 """ Mark scipy voronoi vertex as 'previous vertex' in geodesic edge calculation. This is done to consider Date Line intersections that occur between the voronoi vertex and the first geodesic vertex (less than 15 km away). """ if geodesic_voronoi_vertices_count == 0: previous_voronoi_geodesic_vertex_X = voronoi_vertex_lon previous_voronoi_geodesic_vertex_Y = voronoi_vertex_lat """ Divide distance between vertices into 15 km segments and get coordinates of vertices. Vertices from geodesic distances are added to voronoi_ring. """ geodesic_distance_voronoi_vertices = 15000 """ When vertices of a polygon are closer than the segment length of the geodesic vertices, the distance between geodesic vertices is reduced to one fifth of the distance between the vertices (to get additional vertex in between). When start and end vertex of a polygon are close to the date line on either hemisphere, this would cause the program to believe that there is a polar intersection (because there is only one date line intersection present due to the missing additional vertices over the second date line intersection) resulting in wrong voronoi polygons. """ if geodesic_distance_crater_area < geodesic_distance_voronoi_vertices: geodesic_distance_voronoi_vertices = geodesic_distance_crater_area/5 """ When the current or the next vertex is very close to the date line, make sure that the distance between the geodesic vertices in between is lower than that. If not considered, a date line intersection would be recognized as a polar intersection because the second date line overlap would not occur as planned. If either vertex is <-170 deg lon or >170 deg lon (10 deg lon can be very short close to the poles), check distance to date line and if either distance is lower than the geodesic distance to calculate the vertices in between, modify the geodesic distance. """ voronoi_date_line_correction_lon_1 = 170 voronoi_date_line_correction_lon_2 = -170 """ Close to the poles, a vertex is considered very close to the date line when it is closer than +- 150 deg lon. """ if voronoi_vertex_lat > 89 or voronoi_vertex_lat < -89: voronoi_date_line_correction_lon_1 = 150 voronoi_date_line_correction_lon_2 = -150 if voronoi_vertex_lon < voronoi_date_line_correction_lon_2 or voronoi_next_vertex_lon < voronoi_date_line_correction_lon_2 or voronoi_vertex_lon > voronoi_date_line_correction_lon_1 or voronoi_next_vertex_lon > voronoi_date_line_correction_lon_1: if voronoi_vertex_lon > voronoi_date_line_correction_lon_1 or voronoi_next_vertex_lon > voronoi_date_line_correction_lon_1: shapely_dateline = LineString([(180, 90),(180, 0),(180, -90)]) if voronoi_vertex_lon < voronoi_date_line_correction_lon_2 or voronoi_next_vertex_lon < voronoi_date_line_correction_lon_2: shapely_dateline = LineString([(-180, 90),(-180, 0),(-180, -90)]) """ Find closest point on Date Line and get geodesic distance. """ shapely_voronoi_vertex = Point(voronoi_vertex_lon, voronoi_vertex_lat) shapely_next_voronoi_vertex = Point(voronoi_next_vertex_lon, voronoi_next_vertex_lat) voronoi_vertex_closest_point_on_dateline = shapely_dateline.interpolate(shapely_dateline.project(shapely_voronoi_vertex)) voronoi_next_vertex_closest_point_on_dateline = shapely_dateline.interpolate(shapely_dateline.project(shapely_next_voronoi_vertex)) voronoi_vertex_closest_point_on_dateline_ogr = ogr.CreateGeometryFromWkt(voronoi_vertex_closest_point_on_dateline.wkt) voronoi_next_vertex_closest_point_on_dateline_ogr = ogr.CreateGeometryFromWkt(voronoi_next_vertex_closest_point_on_dateline.wkt) voronoi_vertex_closest_point_on_dateline_ogr_X = voronoi_vertex_closest_point_on_dateline_ogr.GetX() voronoi_vertex_closest_point_on_dateline_ogr_Y = voronoi_vertex_closest_point_on_dateline_ogr.GetY() voronoi_next_vertex_closest_point_on_dateline_ogr_X = voronoi_next_vertex_closest_point_on_dateline_ogr.GetX() voronoi_next_vertex_closest_point_on_dateline_ogr_Y = voronoi_next_vertex_closest_point_on_dateline_ogr.GetY() inverse_vincenty(flattening, major_axis, voronoi_vertex_lat, voronoi_vertex_lon, voronoi_vertex_closest_point_on_dateline_ogr_Y, voronoi_vertex_closest_point_on_dateline_ogr_X) distance_voronoi_vertex_closest_point_on_dateline = geodesic_distance_crater_area inverse_vincenty(flattening, major_axis, voronoi_next_vertex_lat, voronoi_next_vertex_lon, voronoi_next_vertex_closest_point_on_dateline_ogr_Y, voronoi_next_vertex_closest_point_on_dateline_ogr_X) distance_next_voronoi_vertex_closest_point_on_dateline = geodesic_distance_crater_area """ Check whether the current or the next vertex is closest to the date line. """ minimum_distance_current_and_next_voronoi_vertex_to_dateline = min(distance_voronoi_vertex_closest_point_on_dateline, distance_next_voronoi_vertex_closest_point_on_dateline) """ Use closest distance to the date line to modify the distance between the geodesic vertices for such polygon sections. """ if minimum_distance_current_and_next_voronoi_vertex_to_dateline < 2 * geodesic_distance_voronoi_vertices: geodesic_distance_voronoi_vertices = minimum_distance_current_and_next_voronoi_vertex_to_dateline/5 while geodesic_distance_between_voronoi_vertices > geodesic_distance_voronoi_vertices: distance_geodesic_polygon_vertices += geodesic_distance_voronoi_vertices geodesic_distance_between_voronoi_vertices -= geodesic_distance_voronoi_vertices direct_vincenty(flattening, major_axis, [[voronoi_vertex_lon, voronoi_vertex_lat, azimuth_between_voronoi_vertices, 0, 0]], distance_geodesic_polygon_vertices, 1) voronoi_geodesic_vertex_X = buffer_vertices_list[0][0] voronoi_geodesic_vertex_Y = buffer_vertices_list[0][1] """ Consideration of Date Line intersections. If the voronoi polygon crosses the Date Line, the voronoi polygon is merged from individual polygons voronoi_ring and voronoi_ring_dateline_intersection to avoid Date Line ambiguity. """ """ Polygons that intersect the date line cross the date line twice, polygons that intersect the poles intersect the date line once """ """ detect intersection with date line """ voronoi_dateline_intersection = False if previous_voronoi_geodesic_vertex_X <= 179.999999 and voronoi_geodesic_vertex_X > 179.999999 or previous_voronoi_geodesic_vertex_X > 179.999999 and voronoi_geodesic_vertex_X <= 179.999999:# or previous_voronoi_start_vertex_X <= 179.999999 and voronoi_geodesic_vertex_X > 179.999999 or previous_voronoi_start_vertex_X > 179.999999 and voronoi_geodesic_vertex_X <= 179.999999: voronoi_dateline_intersection = True voronoi_dateline_hemisphere = "East" dateline_voronoi = ogr.Geometry(ogr.wkbLineString) dateline_voronoi.AssignSpatialReference(voronoi_out_polygons_geogr_sr) dateline_voronoi.AddPoint(179.999999, 90) dateline_voronoi.AddPoint(179.999999, -90) if previous_voronoi_geodesic_vertex_X >= -179.999999 and voronoi_geodesic_vertex_X < -179.999999 or previous_voronoi_geodesic_vertex_X < -179.999999 and voronoi_geodesic_vertex_X >= -179.999999:# or previous_voronoi_start_vertex_X >= -179.999999 and voronoi_geodesic_vertex_X < -179.999999 or previous_voronoi_start_vertex_X < -179.999999 and voronoi_geodesic_vertex_X >= -179.999999: voronoi_dateline_intersection = True voronoi_dateline_hemisphere = "West" dateline_voronoi = ogr.Geometry(ogr.wkbLineString) dateline_voronoi.AssignSpatialReference(voronoi_out_polygons_geogr_sr) dateline_voronoi.AddPoint(-179.999999, 90) dateline_voronoi.AddPoint(-179.999999, -90) if voronoi_dateline_intersection == True: voronoi_date_line_intersection_count += 1 previous_current_voronoi_vertex_line = ogr.Geometry(ogr.wkbLineString) previous_current_voronoi_vertex_line.AssignSpatialReference(voronoi_out_polygons_geogr_sr) previous_current_voronoi_vertex_line.AddPoint(previous_voronoi_geodesic_vertex_X, previous_voronoi_geodesic_vertex_Y) previous_current_voronoi_vertex_line.AddPoint(voronoi_geodesic_vertex_X, voronoi_geodesic_vertex_Y) voronoi_dateline_intersection_point = previous_current_voronoi_vertex_line.Intersection(dateline_voronoi) voronoi_dateline_intersection_point_X = voronoi_dateline_intersection_point.GetX() voronoi_dateline_intersection_point_Y = voronoi_dateline_intersection_point.GetY() """ add date line intersection point to voronoi_ring """ if voronoi_date_line_intersection_count % 2 == 1: voronoi_ring.AddPoint(voronoi_dateline_intersection_point_X, voronoi_dateline_intersection_point_Y) """ When crossing to the other hemisphere for the first time, the new polygon longitude must always be -179.999999 if it crosses from west to east and +179.999999 when crossing from east to west. This is the first intersection point with the date line. """ if voronoi_dateline_hemisphere == "East": voronoi_dateline_intersection_point_X = -179.999999 if voronoi_dateline_hemisphere == "West": voronoi_dateline_intersection_point_X = +179.999999 if voronoi_date_line_intersection_count % 2 == 0: voronoi_ring.AddPoint(voronoi_dateline_intersection_point_X, voronoi_dateline_intersection_point_Y) """ When crossing back to the other hemisphere, the new polygon longitude must always be +179.999999 if it crosses from west to east and -179.999999 when crossing from east to west. This is the second intersection point with the date line. """ if voronoi_date_line_intersection_count % 2 == 0: if voronoi_dateline_hemisphere == "East": voronoi_dateline_intersection_point_X = 179.999999 if voronoi_dateline_hemisphere == "West": voronoi_dateline_intersection_point_X = -179.999999 """ add intersection point to second voronoi ring, voronoi_ring_dateline_intersection """ voronoi_ring_dateline_intersection.AddPoint(voronoi_dateline_intersection_point_X, voronoi_dateline_intersection_point_Y) if voronoi_date_line_intersection_count % 2 == 1: old_voronoi_dateline_intersection_point_X = voronoi_dateline_intersection_point_X old_voronoi_dateline_intersection_point_Y = voronoi_dateline_intersection_point_Y """ when entering back to the other hemisphere, add voronoi_ring_dateline_intersection to the voronoi polygon and create a new voronoi_ring_dateline_intersection polygon in case there is another date line intersection """ if voronoi_date_line_intersection_count % 2 == 0: """ add first date line intersection point to close ring """ """ When crossing back to the other hemisphere, the new polygon longitude must always be +179.999999 if it crosses from west to east and -179.999999 when crossing from east to west. This is the closing point for the polygon (the first intersection point). """ if voronoi_dateline_hemisphere == "East": old_voronoi_dateline_intersection_point_X = 179.999999 if voronoi_dateline_hemisphere == "West": old_voronoi_dateline_intersection_point_X = -179.999999 voronoi_ring_dateline_intersection.AddPoint(old_voronoi_dateline_intersection_point_X, old_voronoi_dateline_intersection_point_Y) """ add voronoi_ring_dateline_intersection to voronoi polygon """ voronoi_out_polygons.AddGeometry(voronoi_ring_dateline_intersection) """ get area of voronoi_ring_dateline_intersection. area of voronoi polygon is summed.""" voronoi_ring_dateline_intersection.Transform(geogr_to_proj_voronoi) voronoi_ring_dateline_intersection_area = voronoi_ring_dateline_intersection.GetArea() voronoi_ring_dateline_intersection.Transform(proj_voronoi_to_geogr) voronoi_polygon_area += voronoi_ring_dateline_intersection_area """ Create a new empty voronoi_ring_dateline_intersection in case there is another date line intersection coming up. """ voronoi_ring_dateline_intersection = ogr.Geometry(ogr.wkbLinearRing) voronoi_ring_dateline_intersection.AssignSpatialReference(voronoi_out_polygons_geogr_sr) """ remember current vertex """ previous_voronoi_geodesic_vertex_X = voronoi_geodesic_vertex_X previous_voronoi_geodesic_vertex_Y = voronoi_geodesic_vertex_Y """ Correct coordinates so that lon is between -179.999999 and +179.999999 deg, to avoid 'jumps' in polygons. Values outside this range are still used to determine the presence of date line intersections and the calculation of geodesic coordinates (Vincenty) """ if voronoi_geodesic_vertex_X < -179.999999: voronoi_geodesic_vertex_X += 360 if voronoi_geodesic_vertex_X > 179.999999: voronoi_geodesic_vertex_X -= 360 """ Vertices from geodesic distance calculations are added either to voronoi_ring (no date line intersection) or voronoi_ring_dateline_intersection (date line intersection). """ if voronoi_date_line_intersection_count % 2 == 0: voronoi_ring.AddPoint(voronoi_geodesic_vertex_X, voronoi_geodesic_vertex_Y) if voronoi_date_line_intersection_count % 2 == 1: voronoi_ring_dateline_intersection.AddPoint(voronoi_geodesic_vertex_X, voronoi_geodesic_vertex_Y) geodesic_voronoi_vertices_count += 1 voronoi_vertex_lat_lon_count += 1 """ Here, the processing of a voronoi polygon is finished. If during processing there was only one intersection with the dateline and no crossing back over the date line, the current voronoi polygon intersects the poles. Here, we draw a new polygon from the voronoi_ring and voronoi_ring_dateline_intersection vertices. We check whether there is a north pole or south pole intersection and add the respective pole and the longitudinally-ordered vertices to the polar intersection voronoi polygon. """ if voronoi_date_line_intersection_count % 2 == 1: """ get all vertices in voronoi_ring and voronoi_ring_dateline_intersection and sort them according to their longitudes """ voronoi_polar_intersection_vertices = [] for voronoi_polar_vertex in range(0, voronoi_ring_dateline_intersection.GetPointCount()): voronoi_polar_vertex_coordinates = voronoi_ring_dateline_intersection.GetPoint(voronoi_polar_vertex) voronoi_polar_vertex_lon = voronoi_polar_vertex_coordinates[0] voronoi_polar_vertex_lat = voronoi_polar_vertex_coordinates[1] voronoi_polar_intersection_vertices.append([voronoi_polar_vertex_lon, voronoi_polar_vertex_lat]) for voronoi_polar_vertex in range(0, voronoi_ring.GetPointCount()): voronoi_polar_vertex_coordinates = voronoi_ring.GetPoint(voronoi_polar_vertex) voronoi_polar_vertex_lon = voronoi_polar_vertex_coordinates[0] voronoi_polar_vertex_lat = voronoi_polar_vertex_coordinates[1] voronoi_polar_intersection_vertices.append([voronoi_polar_vertex_lon, voronoi_polar_vertex_lat]) voronoi_polar_intersection_vertices = sorted(voronoi_polar_intersection_vertices, key=lambda coordinates: coordinates[0]) """ find pole that is closest to the impact crater - we assume that this indicates whether this is an intersection with the north pole or the south pole """ inverse_vincenty(flattening, major_axis, center_voronoi_polygon_Y, center_voronoi_polygon_X, 89.99999, 0) distance_crater_north_pole = geodesic_distance_crater_area inverse_vincenty(flattening, major_axis, center_voronoi_polygon_Y, center_voronoi_polygon_X, -89.99999, 0) distance_crater_south_pole = geodesic_distance_crater_area if distance_crater_north_pole <= distance_crater_south_pole: voronoi_polar_vertex_Y = 89.99999 if distance_crater_north_pole > distance_crater_south_pole: voronoi_polar_vertex_Y = -89.99999 """ Draw a new polygon (voronoi_ring) for polar intersections. The poles and date lines are not exactly at +- 179.999999 deg lon or +-90 deg lat. Date lines are sometimes automatically converted from -179.999999 to +179.999999 degrees in OGR which is not very helpful in this case. Polar intersections may result in gaps if the latitude is set to +- 90 deg. """ voronoi_ring = ogr.Geometry(ogr.wkbLinearRing) voronoi_ring.AssignSpatialReference(voronoi_out_polygons_geogr_sr) voronoi_ring.AddPoint(-179.99999, voronoi_polar_vertex_Y) # closest pole for voronoi_polar_intersection_vertex in voronoi_polar_intersection_vertices: voronoi_polar_intersection_vertex_X = voronoi_polar_intersection_vertex[0] voronoi_polar_intersection_vertex_Y = voronoi_polar_intersection_vertex[1] if voronoi_polar_intersection_vertex_X == -179.999999: voronoi_polar_intersection_vertex_X = -179.99999 if voronoi_polar_intersection_vertex_X == 179.999999: voronoi_polar_intersection_vertex_X = 179.99999 voronoi_ring.AddPoint(voronoi_polar_intersection_vertex_X, voronoi_polar_intersection_vertex_Y) voronoi_ring.AddPoint(179.99999, voronoi_polar_vertex_Y) # closest pole voronoi_count += 1 print voronoi_count print "---" """ Get area of voronoi_ring. The total area is eventually summed from voronoi_ring and voronoi_ring_dateline_intersection due to inaccurate area measurements when one polygon intersects the date line intersections. """ voronoi_ring.Transform(geogr_to_proj_voronoi) voronoi_ring_area = voronoi_ring.GetArea() voronoi_ring.Transform(proj_voronoi_to_geogr) voronoi_polygon_area += voronoi_ring_area voronoi_polygon_areas.append(voronoi_polygon_area) """ Add geometry to shapefile """ voronoi_out_polygons.AddGeometry(voronoi_ring) voronoi_polygons_featureDefn = voronoi_polygon_layer.GetLayerDefn() voronoi_polygon_feature = ogr.Feature(voronoi_polygons_featureDefn) voronoi_polygon_feature.SetGeometry(voronoi_out_polygons) voronoi_polygon_feature.SetField("Area", voronoi_polygon_area) voronoi_polygon_layer.CreateFeature(voronoi_polygon_feature) print "Done."
def point2Shp(poiBunch, valueArray, fn, pt_lyrName_w, ref_lyr=False): ds = ogr.Open(fn, 1) # '''参考层,用于空间坐标投影,字段属性等参照''' # ref_lyr=ds.GetLayer(ref_lyr) # ref_sr=ref_lyr.GetSpatialRef() # print(ref_sr) # ref_schema=ref_lyr.schema #查看属性表字段名和类型 # for field in ref_schema: # print(field.name,field.GetTypeName()) '''建立新的datasource数据源''' sf_driver = ogr.GetDriverByName('ESRI Shapefile') sfDS = os.path.join(fn, r'sf') # if os.path.exists(sfDS): # sf_driver.DeleteDataSource(sfDS) pt_ds = sf_driver.CreateDataSource(sfDS) if pt_ds is None: sys.exit('Could not open{0}'.format(sfDS)) '''建立新layer层''' if pt_ds.GetLayer(pt_lyrName_w): pt_ds.DeleteLayer(pt_lyrName_w) spatialRef = osr.SpatialReference() spatialRef.SetWellKnownGeogCS( "WGS84") #需要注意直接定义大地坐标未"WGS84",而未使用参考层提取的坐标投影系统 pt_lyr = pt_ds.CreateLayer(pt_lyrName_w, spatialRef, ogr.wkbPoint) # pt_lyr=pt_ds.CreateLayer(pt_lyrName_w,ref_sr,ogr.wkbPoint) '''配置字段,名称以及类型和相关参数''' # pt_lyr.CreateFields(ref_schema) LatFd = ogr.FieldDefn("origiLat", ogr.OFTReal) LatFd.SetWidth(20) LatFd.SetPrecision(3) pt_lyr.CreateField(LatFd) LatFd.SetName("origiLong") pt_lyr.CreateField(LatFd) # pt_lyr.CreateFields(ref_schema) preFd = ogr.FieldDefn("poi", ogr.OFTInteger) pt_lyr.CreateField(preFd) preFd.SetName("cluster") pt_lyr.CreateField(preFd) # stationName=ogr.FieldDefn("stationN",ogr.OFTString) # pt_lyr.CreateField(stationName) # preFd.SetName("ObservTime") # pt_lyr.CreateField(preFd) # '''建立feature空特征和设置geometry几何类型''' print(pt_lyr.GetLayerDefn()) pt_feat = ogr.Feature(pt_lyr.GetLayerDefn()) # idx=0 for i in tqdm(range(valueArray.shape[0])): #循环feature # print(key) '''设置几何体''' #pt_ref=feat.geometry().Clone() converCoordiGCJ = cc.bd09togcj02(dataBunch.data[i][1], dataBunch.data[i][0]) converCoordiGPS84 = cc.gcj02towgs84(converCoordiGCJ[0], converCoordiGCJ[1]) # print(wdCoordiDicSingle[key][1],wdCoordiDicSingle[key][0]) # print(converCoordiGPS84[0], converCoordiGPS84[1]) wkt = "POINT(%f %f)" % (converCoordiGPS84[0], converCoordiGPS84[1]) # wkt="POINT(%f %f)" % (dataBunch.data[i][0], dataBunch.data[i][1]) newPt = ogr.CreateGeometryFromWkt(wkt) #使用wkt的方法建立点 pt_feat.SetGeometry(newPt) '''设置字段值''' # for i_field in range(feat.GetFieldCount()): # pt_feat.SetField(i_field,feat.GetField(i_field)) pt_feat.SetField("origiLat", dataBunch.data[i][0]) pt_feat.SetField("origiLong", dataBunch.data[i][1]) # print(wdDicComplete[key]['20140901190000']) pt_feat.SetField("poi", int(dataBunch.target[i])) # pt_feat.SetField("cluster", int(valueArray[i])) # print(idx,int(valueArray[idx]),pt_ref.GetX()) # idx+=1 '''根据设置的几何体和字段值,建立feature。循环建立多个feature特征''' pt_lyr.CreateFeature(pt_feat) del ds
def CreatePointFeature_ogr(outputShapefile, LonLst, LatLst, panoIDlist, panoDateList, greenViewList, lyrname): """ Create a shapefile based on the template of inputShapefile This function will delete existing outpuShapefile and create a new shapefile containing points with panoID, panoDate, and green view as respective fields. Parameters: outputShapefile: the file path of the output shapefile name, example 'd:\greenview.shp' LonLst: the longitude list LatLst: the latitude list panoIDlist: the panorama id list panoDateList: the panodate list greenViewList: the green view index result list, all these lists can be generated from the function of 'Read_GVI_res' Copyright(c) Xiaojiang Li, Senseable city lab last modified by Xiaojiang li, MIT Senseable City Lab on March 27, 2018 """ import ogr import osr # create shapefile and add the above chosen random points to the shapfile driver = ogr.GetDriverByName("ESRI Shapefile") # create new shapefile if os.path.exists(outputShapefile): driver.DeleteDataSource(outputShapefile) data_source = driver.CreateDataSource(outputShapefile) targetSpatialRef = osr.SpatialReference() targetSpatialRef.ImportFromEPSG(4326) outLayer = data_source.CreateLayer(lyrname, targetSpatialRef, ogr.wkbPoint) numPnt = len(LonLst) print('the number of points is:', numPnt) if numPnt > 0: # create a field idField = ogr.FieldDefn('PntNum', ogr.OFTInteger) panoID_Field = ogr.FieldDefn('panoID', ogr.OFTString) panoDate_Field = ogr.FieldDefn('panoDate', ogr.OFTString) greenView_Field = ogr.FieldDefn('greenView', ogr.OFTReal) outLayer.CreateField(idField) outLayer.CreateField(panoID_Field) outLayer.CreateField(panoDate_Field) outLayer.CreateField(greenView_Field) for idx in range(numPnt): #create point geometry point = ogr.Geometry(ogr.wkbPoint) # in case of the returned panoLon and PanoLat are invalid if len(LonLst[idx]) < 3: continue point.AddPoint(float(LonLst[idx]), float(LatLst[idx])) # Create the feature and set values featureDefn = outLayer.GetLayerDefn() outFeature = ogr.Feature(featureDefn) outFeature.SetGeometry(point) outFeature.SetField('PntNum', idx) outFeature.SetField('panoID', panoIDlist[idx]) outFeature.SetField('panoDate', panoDateList[idx]) if len(greenViewList) == 0: outFeature.SetField('greenView', -999) else: outFeature.SetField('greenView', float(greenViewList[idx])) outLayer.CreateFeature(outFeature) outFeature.Destroy() data_source.Destroy() else: print('You created a empty shapefile')
def import_file(self, *args, **kwargs): """ Loads data that has been uploaded into whatever format we need for serving. Expects kwarg "configuration_options" which is a list of dicts, one for each layer to import. each dict must contain "upload_layer_id" referencing the UploadLayer being imported and must contain "index" which is a 0-based index to identify which layer from the file is being referenced. and can contain an optional "layer_name" to assign a custom name. "layer_name" may be ignored if it is already in use. """ filename = self.file self.completed_layers = [] err = GdalErrorHandler() gdal.PushErrorHandler(err.handler) gdal.UseExceptions() configuration_options = kwargs.get('configuration_options', [{ 'index': 0 }]) # Configuration options should be a list at this point since the # importer can process multiple layers in a single import if isinstance(configuration_options, dict): configuration_options = [configuration_options] # Ensure that upload_layer_id exists in configuration for each layer nbad_config = 0 for co in configuration_options: if 'upload_layer_id' not in co: nbad_config += 1 if nbad_config > 0: msg = '{} of {} configs missing upload_layer_id'.format( nbad_config, len(configuration_options)) logger.critical(msg) raise Exception(msg) # --- Resolve any disparity between automatically-assigned UploadLayer.layer_name and layer_name in # configuration options. # If layer_name is present in configuration_options either update UploadLayer.layer_name to match if it's unique # or update configuration_options' 'layer_name' to match value in UploadLayer.layer_name if it's not unique. with db.transaction.atomic(): upload_layer_ids = [ co['upload_layer_id'] for co in configuration_options ] upload_layers = UploadLayer.objects.filter(id__in=upload_layer_ids) upload_layers_by_id = {ul.id: ul for ul in upload_layers} for co in configuration_options: ul = upload_layers_by_id[co['upload_layer_id']] if co.get('layer_name') is None: co['layer_name'] = ul.layer_name elif co['layer_name'] != ul.layer_name: if UploadLayer.objects.filter( layer_name=co['layer_name']).exists(): co['layer_name'] = ul.layer_name else: ul.layer_name = co['layer_name'] ul.save() data, inspector = self.open_source_datastore(filename, *args, **kwargs) datastore_layers = inspector.describe_fields() if len(datastore_layers) == 0: logger.debug('No Dataset found') layers_info = [] # It looks like this code allowed users to configure a portion of layers in the file by specifying an # index or a 'layer_name' option. I'm not sure if lookups by 'layer_name' are still being used anywhere. # 'layer_name' now specifies the name to give to a layer on import to geonode. If the previous # behavior is needed, add a 'internal_layer_name' value to the configuration options using the name # of the layer the file uses. lookup_fields = ['index', 'internal_layer_name'] for layer_configuration in configuration_options: lookup_found = False for lf in lookup_fields: if lf in layer_configuration: lookup_found = True break if not lookup_found: logger.warn( 'No recognized layer lookup field provided in configuration options, should be one of {}' .format(lookup_fields)) continue for datastore_layer in datastore_layers: for lf in lookup_fields: if (lf in datastore_layer and lf in layer_configuration and datastore_layer.get(lf) == layer_configuration.get(lf)): # This update will overwrite the layer_name passed in configuration_options, stash the # intended name so we can correct it. msg = 'Will configure layer from file {} identifed by field "{}" with value {}'\ .format(self.file, lf, layer_configuration[lf]) logger.info(msg) intended_layer_name = layer_configuration.get( 'layer_name') layer_configuration.update(datastore_layer) if intended_layer_name: layer_configuration.update( {'layer_name': intended_layer_name}) else: msg = ( 'layer_name not provided in configuration options, will use name provided ' 'by inspector which will likely lead to name collisions' ) logger.warn(msg) layers_info.append(layer_configuration) for layer_options in layers_info: if layer_options['layer_type'] == 'tile' and layer_options.get( 'driver', '').lower() == 'gpkg': # No special processing is needed on import, the only thing needed is a copy of the # file which was made on upload. Config for publishing is done # in handlers.mapproxy.publish_handler.MapProxyGPKGTilePublishHandler self.completed_layers.append( [layer_options['layer_name'], layer_options]) elif layer_options['layer_type'] == 'raster': """ File is a raster, we need to convert into optimized GeoTiff and skip any further testing or loading into target_store """ # Increment filename to make sure target doesn't exists filedir, filebase = os.path.split(filename) outfile = "{}/{}.tif".format( filedir, layer_options['layer_name'].lower()) fileout = increment_filename( os.path.join(RASTER_FILES, outfile)) raster_import(layer_options['path'], fileout) self.completed_layers.append([fileout, layer_options]) elif layer_options['layer_type'] == 'vector': target_file, _ = self.open_target_datastore(self.target_store) target_create_options = [] # Prevent numeric field overflow for shapefiles https://trac.osgeo.org/gdal/ticket/5241 if target_file.GetDriver().GetName() == 'PostgreSQL': target_create_options.append('PRECISION=NO') target_create_options.append('OVERWRITE=YES') # Hack for CSV ingest into postgres. When using COPY, OGR prepends a bad newline to each feature if data.GetDriver().ShortName.lower() == 'csv': os.environ["PG_USE_COPY"] = "false" else: os.environ["PG_USE_COPY"] = "true" layer_options['modified_fields'] = {} layer = data.GetLayer(layer_options.get('index')) layer_name = layer_options['layer_name'] layer_geom_type = self.get_layer_type(layer, data) srs = layer.GetSpatialRef() # default the layer to 4326 if a spatial reference is not provided if not srs: srs = osr.SpatialReference() srs.ImportFromEPSG(4326) # pass the srs authority code to handlers if srs.AutoIdentifyEPSG() == 0: layer_options['srs'] = '{0}:{1}'.format( srs.GetAuthorityName(None), srs.GetAuthorityCode(None)) else: # layer_options['srs'] = convert_wkt_to_epsg(srs.ExportToWkt()) layer_ids = [] for configuration_option in configuration_options: layer_ids = [configuration_option['upload_layer_id']] layer_id = layer_ids[0] layer_path = os.path.dirname(filename) original_layer_name = layer.GetName() layer_options['srs'] = reproject_coordinate_system( original_layer_name, layer_name, layer, layer_path) data, inspector = self.open_source_datastore( filename, *args, **kwargs) target_file, _ = self.open_target_datastore( self.target_store) layer = data.GetLayer(layer_options.get('index')) srs = layer.GetSpatialRef() logger.info('Creating dataset "{}" from file "{}"'.format( layer_name, target_file)) target_layer = self.create_target_dataset( target_file, str(layer_name), srs, layer_geom_type, options=target_create_options) # adding fields to new layer layer_definition = ogr.Feature(layer.GetLayerDefn()) source_fid = None wkb_field = 0 for i in range(layer_definition.GetFieldCount()): field_def = layer_definition.GetFieldDefnRef(i) if field_def.GetName() == target_layer.GetFIDColumn( ) and field_def.GetType() != 0: field_def.SetType(0) if field_def.GetName() != 'wkb_geometry': target_layer.CreateField(field_def) new_name = target_layer.GetLayerDefn().GetFieldDefn( i - wkb_field).GetName() old_name = field_def.GetName() if new_name != old_name: layer_options['modified_fields'][ old_name] = new_name if old_name == target_layer.GetFIDColumn( ) and not layer.GetFIDColumn(): source_fid = i else: wkb_field = 1 if wkb_field is not 0: layer.SetIgnoredFields(['wkb_geometry']) for feature in layer: if feature and feature.geometry(): if not layer.GetFIDColumn(): feature.SetFID(-1) if feature.geometry().GetGeometryType() != target_layer.GetGeomType() and \ target_layer.GetGeomType() in range(4, 7): if target_layer.GetGeomType() == 5: conversion_function = ogr.ForceToMultiLineString elif target_layer.GetGeomType() == 4: conversion_function = ogr.ForceToMultiPoint else: conversion_function = ogr.ForceToMultiPolygon geom = ogr.CreateGeometryFromWkb( feature.geometry().ExportToWkb()) feature.SetGeometry(conversion_function(geom)) if source_fid is not None: feature.SetFID(feature.GetField(source_fid)) for field in range(0, feature.GetFieldCount()): if feature.GetFieldType(field) == ogr.OFTString: try: feature.GetField(field).decode('utf8') except UnicodeDecodeError: feature.SetField( field, decode(feature.GetField(field))) except AttributeError: continue try: target_layer.CreateFeature(feature) except err as e: logger.error('Create feature failed: {0}'.format( gdal.GetLastErrorMsg())) raise e layer.ResetReading() self.completed_layers.append( [target_layer.GetName(), layer_options]) else: msg = 'Unexpected layer type: "{}"'.format( layer_options['layer_type']) logger.error(msg) raise Exception(msg) return self.completed_layers
if out_data_source is None: print('Could not create %s' % (out_vect)) ################################################## CREATE SHAPEFILE LAYER WITH NEW PROJECTION # Step 5.1: Create shapefile layer with the spatial reference of the raster file out_vect_layer = out_data_source.CreateLayer('transform_point', rast_sr_object, ogr.wkbPoint) # Step 5.2: Run a function that creates fields inside the table of the output vector file out_vect_layer.CreateFields(vect_layer.schema) # Step 5.3: Create a variable that produces a layer definition for the output file out_defn = out_vect_layer.GetLayerDefn() # Step 5.4: Create a variable that produces features through the layer definition of the output file out_feat = ogr.Feature(out_defn) # *Step 5.5: Create a loop that goes over every feature in the layer and changes the spatial reference for in_feat in vect_layer: geom = in_feat.geometry() geom.Transform(transform_point_sr) out_feat.SetGeometry(geom) # Add a loop inside the loop to include the attributes in the new file for i in range(in_feat.GetFieldCount()): value = in_feat.GetField(i) out_feat.SetField(i, value) out_vect_layer.CreateFeature(out_feat) ################################################## DELETE OUTPUT DATA SOURCE
def main(env,gridHeight=0.005,gridWidth=0.005): dictionary_1={} # convert sys.argv to float xmin = float(env[0]) xmax = float(env[1]) ymin = float(env[2]) ymax = float(env[3]) gridWidth = float(gridWidth) gridHeight = float(gridHeight) # get rows rows = ceil((ymax-ymin)/gridHeight) # get columns cols = ceil((xmax-xmin)/gridWidth) # start grid cell envelope ringXleftOrigin = xmin ringXrightOrigin = xmin + gridWidth ringYtopOrigin = ymax ringYbottomOrigin = ymax-gridHeight # create output file spatialReference = osgeo.osr.SpatialReference() spatialReference.SetWellKnownGeogCS("WGS84") driver = osgeo.ogr.GetDriverByName("ESRI Shapefile") print "Creating Directory For ShapeFile " folderLocation, folderName = creating_directory() name = input("enter shape file name") dstPath = os.path.join(folderLocation, "%s.shp" % name) dstFile = driver.CreateDataSource("%s" % dstPath) dstLayer = dstFile.CreateLayer("layer", spatialReference) numField = input( "Enter the required number of fields\ attributes in a layer other than FieldID, Longitude, Latitude") fieldDef = osgeo.ogr.FieldDefn("FieldID", osgeo.ogr.OFTString) fieldDef.SetWidth(10) dstLayer.CreateField(fieldDef) featureDefn = dstLayer.GetLayerDefn() # create grid cells countcols = 0 while countcols < cols: countcols += 1 # reset envelope for rows ringYtop = ringYtopOrigin ringYbottom =ringYbottomOrigin countrows = 0 while countrows < rows: countrows += 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) dictionary_1[(countcols,countrows)]=(ringXleftOrigin,ringXrightOrigin,ringYtop,ringYbottom) # add new geom to layer outFeature = ogr.Feature(featureDefn) outFeature.SetGeometry(poly) outFeature.SetField("FieldID", str((countcols,countrows))) dstLayer.CreateFeature(outFeature) outFeature.Destroy() # new envelope for next poly ringYtop = ringYtop - gridHeight ringYbottom = ringYbottom - gridHeight # new envelope for next poly ringXleftOrigin = ringXleftOrigin + gridWidth ringXrightOrigin = ringXrightOrigin + gridWidth # Save and close DataSources dstFile.Destroy() return dictionary_1
def identifyIntersectionsSec(in_shp_pth, out_shp_pth, id_field="IDInters"): """ VERY SLOW FOR LARGE SHAPEFILES Identifies intersections between polygons of a shapefile. Writes intersections specfied output path. :param in_shp_pth: Input shapefile of polygons. :param out_pth: Output path to which the intersections are written. Input filename will be extended by "_intersections". :return: No object returned, but shapefile will be written to disc. """ import os import ogr import vector import general in_shp = ogr.Open(in_shp_pth, 0) in_lyr = in_shp.GetLayer() fname_lst = vector.getFieldNames(in_shp) copy_shp, copy_lyr = vector.copyLayerToMemory(in_lyr) drv_shp = ogr.GetDriverByName('ESRI Shapefile') in_sr = in_lyr.GetSpatialRef() in_lyr_defn = in_lyr.GetLayerDefn() if os.path.exists(out_shp_pth): drv_shp.DeleteDataSource(out_shp_pth) inters_shp = drv_shp.CreateDataSource(out_shp_pth) lyr_name = os.path.splitext(os.path.split(out_shp_pth)[1])[0] geom_type = ogr.wkbPolygon inters_lyr = inters_shp.CreateLayer(lyr_name, in_sr, geom_type=geom_type) for i in range(0, in_lyr_defn.GetFieldCount()): field_def = in_lyr_defn.GetFieldDefn(i) inters_lyr.CreateField(field_def) # inters_lyr.CreateField(ogr.FieldDefn('ID', ogr.OFTInteger64)) if 'IDInters' not in fname_lst: inters_lyr.CreateField(ogr.FieldDefn('IDInters', ogr.OFTString)) inters_lyr_defn = inters_lyr.GetLayerDefn() num_fields = inters_lyr_defn.GetFieldCount() id_inters_lst = [] for feat_curr in in_lyr: id1 = feat_curr.GetField(id_field) id1 = general.orderAndConcatItems(id1) # print("FEATURE: {}".format(id1)) geom_curr = feat_curr.GetGeometryRef() copy_lyr.SetSpatialFilter(geom_curr) for feat_nb in copy_lyr: id2 = feat_nb.GetField(id_field) id2 = general.orderAndConcatItems(id2) ids_comb = id1 + '_' + id2 id_inters = general.orderAndConcatItems(ids_comb) geom_nb = feat_nb.geometry() if id1 != id2: # print("Neighbouring features: {}".format(id2)) if geom_nb.Intersects(geom_curr): intersection = geom_nb.Intersection(geom_curr) if intersection == None: area_inters = 0 else: geom_type = intersection.GetGeometryName() if geom_type not in [ 'POLYGON', 'MULTIPOLYGON' ]: # in ['MULTILINESTRING', 'POINT', 'LINESTRING','MULTIPOINT']: #alternatively intersection = None area_inters = 0 else: area_inters = round(intersection.Area(), 2) else: intersection = None area_inters = 0 ## if the id of the intersection is not already in the list and its area is bigger than 0 ## then add this feature to the intersection layer if area_inters > 0.00 and id_inters not in id_inters_lst: intersection = intersection.Buffer(0) intersection = intersection.MakeValid() wkt_inters = intersection.ExportToWkt() poly = ogr.CreateGeometryFromWkt(wkt_inters) out_feat = ogr.Feature(inters_lyr_defn) out_feat.SetGeometry(poly) for fname in fname_lst: if fname != "ID": ind = fname_lst.index(fname) attr = feat_curr.GetField(fname) out_feat.SetField(ind, attr) ind = fname_lst.index("ID") out_feat.SetField(ind, id1) ind = fname_lst.index("IDInters") out_feat.SetField(ind, id_inters) inters_lyr.CreateFeature(out_feat) ouf_feat = None id_inters_lst.append(id_inters) else: pass copy_lyr.SetSpatialFilter(None) copy_lyr.ResetReading() in_lyr.ResetReading() inters_lyr.ResetReading() del copy_shp, copy_lyr del inters_shp, inters_lyr del in_shp, in_lyr
def ogr_kml_write_1(): if ogrtest.kml_drv is None: return 'skip' srs = osr.SpatialReference() srs.SetWellKnownGeogCS('WGS72') ds = ogr.GetDriverByName('KML').CreateDataSource('tmp/kml.kml') lyr = ds.CreateLayer('test_wgs72', srs = srs) dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT (2 49)')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' if dst_feat.GetGeometryRef().ExportToWkt() != 'POINT (2 49)': print(dst_feat.GetGeometryRef().ExportToWkt()) gdaltest.post_reason('CreateFeature changed the geometry.') return 'fail' dst_feat.Destroy() lyr = ds.CreateLayer('test_wgs84') dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetField('name', 'my_name') dst_feat.SetField('description', 'my_description') dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT (2 49)')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT (2 49 1)')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('LINESTRING (0 1,2 3)')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 1,2 3,4 5,0 1),(0 1,2 3,4 5,0 1))')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('MULTIPOINT (2 49,2 49)')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('MULTILINESTRING ((0 1,2 3),(0 1,2 3))')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('MULTIPOLYGON (((0 1,2 3,4 5,0 1),(0 1,2 3,4 5,0 1)),((0 1,2 3,4 5,0 1),(0 1,2 3,4 5,0 1)))')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() dst_feat = ogr.Feature( lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('GEOMETRYCOLLECTION (POINT (2 49 1),LINESTRING (0 1,2 3))')) if lyr.CreateFeature( dst_feat ) != 0: gdaltest.post_reason('CreateFeature failed.') return 'fail' dst_feat.Destroy() ds.Destroy() return 'success'
def createShapefile(segmented, complete_path_metadata, complete_path_vector): filename = basename(complete_path_png) name = os.path.splitext(filename)[0].encode('utf-8') image = gdal.Open(complete_path_metadata) #driver = ogr.GetDriverByName('ESRI Shapefile') driver = ogr.GetDriverByName('GeoJSON') if (os.path.isfile(complete_path_vector)): os.remove(complete_path_vector) ds = driver.CreateDataSource(complete_path_vector) if (ds == None): logging.info( ">>>> Problems with vector file {}. Polygonization interrupted!". format(complete_path_vector)) return srs = osr.SpatialReference() srs.ImportFromWkt(image.GetProjection()) _area_pix = ogr.FieldDefn('area-pix', ogr.OFTReal) _class = ogr.FieldDefn('class', ogr.OFTString) gt_classes = getClassesGT(segmented, hypes) classesAndGeometries = {} for k in range(len(gt_classes)): imageSegmented = getImageByClass(segmented, gt_classes[k], classes) imageSegmentedInGray = cv2.cvtColor(imageSegmented, cv2.COLOR_RGB2GRAY) thresh = cv2.threshold(imageSegmentedInGray, 127, 255, 0)[1] im2, corners, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) geometries = createGeometries(corners, hierarchy, image) classesAndGeometries[gt_classes[k]] = geometries layer = ds.CreateLayer(name, srs, ogr.wkbPolygon) layer.CreateField(_area_pix) layer.CreateField(_class) for key, value in classesAndGeometries.items(): for g in range(len(value)): featureDefn = layer.GetLayerDefn() feature = ogr.Feature(featureDefn) # the area of the feature in square units of the spatial reference system in use area = value[g].GetArea() if (area == 0): continue feature.SetGeometry(value[g]) feature.SetField('area-pix', float(area)) feature.SetField('class', str(key)) #more attributes could be inserted here layer.CreateFeature(feature) logging.info(">>>> Vector file of image {} created!".format(filename))
def HandleTile(t, src, dstdir, csvpath, args, exclude_list): otxtpath = os.path.join( dstdir, "{}_{}_orig.txt".format(os.path.basename(csvpath)[:-4], t.name)) mtxtpath = os.path.join( dstdir, "{}_{}_ortho.txt".format(os.path.basename(csvpath)[:-4], t.name)) if os.path.isfile(otxtpath) and os.path.isfile( mtxtpath) and args.overwrite is False: logger.info("Tile %s processing files already exist", t.name) else: logger.info("Tile %s", t.name) t_srs = osr.SpatialReference() t_srs.ImportFromEPSG(t.epsg) #### Open mfp dsp, lyrn = utils.get_source_names(src) ds = ogr.Open(dsp) if ds is None: logger.error("Open failed") else: lyr = ds.GetLayerByName(lyrn) if not lyr: raise RuntimeError( "Layer {} does not exist in dataset {}".format(lyrn, dsp)) else: s_srs = lyr.GetSpatialRef() #logger.debug(str(s_srs)) #logger.debug(str(t.geom)) tile_geom_in_s_srs = t.geom.Clone() if not t_srs.IsSame(s_srs): ict = osr.CoordinateTransformation(t_srs, s_srs) ct = osr.CoordinateTransformation(s_srs, t_srs) tile_geom_in_s_srs.Transform(ict) # if the geometry crosses meridian, split it into multipolygon (else this breaks SetSpatialFilter) if utils.doesCross180(tile_geom_in_s_srs): logger.debug( "tile_geom_in_s_srs crosses 180 meridian; splitting to multiple polygons..." ) tile_geom_in_s_srs = utils.getWrappedGeometry( tile_geom_in_s_srs) lyr.ResetReading() lyr.SetSpatialFilter(tile_geom_in_s_srs) feat = lyr.GetNextFeature() imginfo_list1 = [] while feat: iinfo = mosaic.ImageInfo(feat, "RECORD", srs=s_srs) if iinfo.geom is not None and iinfo.geom.GetGeometryType( ) in (ogr.wkbPolygon, ogr.wkbMultiPolygon): if not t_srs.IsSame(s_srs): iinfo.geom.Transform(ct) ## fix self-intersection errors caused by reprojecting over 180 temp = iinfo.geom.Buffer( 0.1 ) # assumes a projected coordinate system with meters or feet as units iinfo.geom = temp if iinfo.geom.Intersects(t.geom): if iinfo.scene_id in exclude_list: logger.debug( "Scene in exclude list, excluding: %s", iinfo.srcfp) elif not os.path.isfile(iinfo.srcfp): logger.warning( "Scene path is invalid, excluding %s (path = %s)", iinfo.scene_id, iinfo.srcfp) elif args.require_pan: srcfp = iinfo.srcfp srcdir, mul_name = os.path.split(srcfp) if iinfo.sensor in ["WV02", "WV03", "QB02"]: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "GE01": if "_5V" in mul_name: pan_name_base = srcfp[:-24].replace( "M0", "P0") candidates = glob.glob(pan_name_base + "*") candidates2 = [ f for f in candidates if f.endswith(('.ntf', '.NTF', '.tif', '.TIF')) ] if len(candidates2) == 0: pan_name = '' elif len(candidates2) == 1: pan_name = os.path.basename( candidates2[0]) else: pan_name = '' logger.error( '%i panchromatic images match the multispectral image name ' '%s', len(candidates2), mul_name) else: pan_name = mul_name.replace("-M", "-P") elif iinfo.sensor == "IK01": pan_name = mul_name.replace("blu", "pan") pan_name = mul_name.replace("msi", "pan") pan_name = mul_name.replace("bgrn", "pan") pan_srcfp = os.path.join(srcdir, pan_name) if not os.path.isfile(pan_srcfp): logger.debug( "Image does not have a panchromatic component, excluding: %s", iinfo.srcfp) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) else: logger.debug("Intersect %s, %s: %s", iinfo.scene_id, iinfo.srcfp, str(iinfo.geom)) imginfo_list1.append(iinfo) feat = lyr.GetNextFeature() ds = None logger.info("Number of intersects in tile %s: %i", t.name, len(imginfo_list1)) if len(imginfo_list1) > 0: #### Get mosaic parameters logger.debug("Getting mosaic parameters") params = mosaic.getMosaicParameters(imginfo_list1[0], args) #### Remove images that do not match ref logger.debug("Setting image pattern filter") imginfo_list2 = mosaic.filterMatchingImages( imginfo_list1, params) logger.info("Number of images matching filter: %i", len(imginfo_list2)) if args.nosort is False: #### Sort by quality logger.debug("Sorting images by quality") imginfo_list3 = [] for iinfo in imginfo_list2: iinfo.getScore(params) if iinfo.score > 0: imginfo_list3.append(iinfo) # sort so highest score is last imginfo_list3.sort(key=lambda x: x.score) else: imginfo_list3 = list(imginfo_list2) #### Overlay geoms and remove non-contributors logger.debug("Overlaying images to determine contributors") contribs = mosaic.determine_contributors( imginfo_list3, t.geom, args.min_contribution_area) logger.info("Number of contributing images: %i", len(contribs)) if len(contribs) > 0: if args.build_shp: ####################################################### #### Create Shp shp = os.path.join( dstdir, "{}_{}_imagery.shp".format(args.mosaic, t.name)) logger.debug("Creating shapefile of geoms: %s", shp) fields = [("IMAGENAME", ogr.OFTString, 100), ("SCORE", ogr.OFTReal, 0)] OGR_DRIVER = "ESRI Shapefile" ogrDriver = ogr.GetDriverByName(OGR_DRIVER) if ogrDriver is None: logger.debug("OGR: Driver %s is not available", OGR_DRIVER) sys.exit(-1) if os.path.isfile(shp): ogrDriver.DeleteDataSource(shp) vds = ogrDriver.CreateDataSource(shp) if vds is None: logger.debug("Could not create shp") sys.exit(-1) shpd, shpn = os.path.split(shp) shpbn, shpe = os.path.splitext(shpn) lyr = vds.CreateLayer(shpbn, t_srs, ogr.wkbPolygon) if lyr is None: logger.debug("ERROR: Failed to create layer: %s", shpbn) sys.exit(-1) for fld, fdef, flen in fields: field_defn = ogr.FieldDefn(fld, fdef) if fdef == ogr.OFTString: field_defn.SetWidth(flen) if lyr.CreateField(field_defn) != 0: logger.debug( "ERROR: Failed to create field: %s", fld) for iinfo, geom in contribs: logger.debug("Image: %s", iinfo.srcfn) feat = ogr.Feature(lyr.GetLayerDefn()) feat.SetField("IMAGENAME", iinfo.srcfn) feat.SetField("SCORE", iinfo.score) feat.SetGeometry(geom) if lyr.CreateFeature(feat) != 0: logger.debug( "ERROR: Could not create feature for image %s", iinfo.srcfn) else: logger.debug("Created feature for image: %s", iinfo.srcfn) feat.Destroy() #### Write textfiles if not os.path.isdir(dstdir): os.makedirs(dstdir) otxtpath = os.path.join( dstdir, "{}_{}_orig.txt".format(args.mosaic, t.name)) mtxtpath = os.path.join( dstdir, "{}_{}_ortho.txt".format(args.mosaic, t.name)) otxt = open(otxtpath, 'w') mtxt = open(mtxtpath, 'w') for iinfo, geom in contribs: if not os.path.isfile(iinfo.srcfp): logger.warning("Image does not exist: %s", iinfo.srcfp) otxt.write("{}\n".format(iinfo.srcfp)) m_fn = "{0}_u08{1}{2}.tif".format( os.path.splitext(iinfo.srcfn)[0], args.stretch, t.epsg) mtxt.write( os.path.join(dstdir, 'ortho', t.name, m_fn) + "\n") otxt.close()
def create_grid(base_shp, out_grid, distance_line): """ Function to build a grid with the same extend that input shapefile (base_shp) :param base_shp: Reference shapefile :type base_shp: str :param out_grid: Path of the output grid :type out_grid: str :param distance_line: Distance between every line in meter :type distance_line: int """ # import ogr variable data_source = ogr.GetDriverByName('ESRI Shapefile').Open(base_shp, 0) if data_source is None: print('Could not open file') sys.exit(1) shp_ogr = data_source.GetLayer() # Extract extent extent_shp = shp_ogr.GetExtent() # Coordinate to build a set of line in a list nb_x = int(ceil((extent_shp[1] - extent_shp[0]) / float(distance_line))) nb_y = int(ceil((extent_shp[3] - extent_shp[2]) / float(distance_line))) # Projection # Import input shapefile projection srsObj = shp_ogr.GetSpatialRef() # Conversion to syntax ESRI srsObj.MorphToESRI() ## Remove the output shapefile if it exists if os.path.exists(out_grid): data_source.GetDriver().DeleteDataSource(out_grid) out_ds = data_source.GetDriver().CreateDataSource(out_grid) if out_ds is None: print('Could not create file') sys.exit(1) # Specific output layer out_layer = out_ds.CreateLayer(str(out_grid), srsObj, geom_type=ogr.wkbLineString) # Add a integer field (ID) new_field = ogr.FieldDefn("ID", 0) out_layer.CreateField(new_field) # Feature for the ouput shapefile featureDefn = out_layer.GetLayerDefn() # Loop on the number of line nb_x next nb_y cnt = 0 for l in range(nb_x): # Define line string line = ogr.Geometry(ogr.wkbLineString) # Add a line line.AddPoint(extent_shp[0] + l * float(distance_line), extent_shp[3]) line.AddPoint(extent_shp[0] + l * float(distance_line), extent_shp[2]) # Create a new polygon out_feature = ogr.Feature(featureDefn) # Set the polygon geometry and attribute out_feature.SetGeometry(line) out_feature.SetField("ID", int(cnt)) cnt = cnt + 1 # Append polygon to the output shapefile out_layer.CreateFeature(out_feature) # Destroy polygons out_feature.Destroy() for l in range(nb_y): # Define line string line = ogr.Geometry(ogr.wkbLineString) # Add a line line.AddPoint(extent_shp[0], extent_shp[3] - l * float(distance_line)) line.AddPoint(extent_shp[1], extent_shp[3] - l * float(distance_line)) # Create a new polygon out_feature = ogr.Feature(featureDefn) # Set the polygon geometry and attribute out_feature.SetGeometry(line) out_feature.SetField("ID", int(cnt)) cnt = cnt + 1 # Append polygon to the output shapefile out_layer.CreateFeature(out_feature) # Destroy polygons out_feature.Destroy() # Close data out_ds.Destroy() return 0
def ogr_csv_13(): if gdaltest.csv_ds is None: return 'skip' gdaltest.csv_tmpds = ogr.Open( 'tmp/csvwrk', update=1 ) # AS_WKT options = ['GEOMETRY=AS_WKT',] lyr = gdaltest.csv_tmpds.CreateLayer( 'as_wkt', options = options ) field_defn = ogr.FieldDefn( 'ADATA', ogr.OFTString ) lyr.CreateField(field_defn) field_defn.Destroy() dst_feat = ogr.Feature( feature_def = lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 2)')) dst_feat.SetField('ADATA', 'avalue') lyr.CreateFeature( dst_feat ) dst_feat.Destroy() # AS_XY options = ['GEOMETRY=AS_XY','CREATE_CSVT=YES'] lyr = gdaltest.csv_tmpds.CreateLayer( 'as_xy', options = options ) field_defn = ogr.FieldDefn( 'ADATA', ogr.OFTString ) lyr.CreateField(field_defn) field_defn.Destroy() dst_feat = ogr.Feature( feature_def = lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 2)')) dst_feat.SetField('ADATA', 'avalue') lyr.CreateFeature( dst_feat ) dst_feat.Destroy() # Nothing will be written in the x or y field dst_feat = ogr.Feature( feature_def = lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('LINESTRING(1 2,3 4)')) dst_feat.SetField('ADATA', 'avalue') lyr.CreateFeature( dst_feat ) dst_feat.Destroy() # AS_YX options = ['GEOMETRY=AS_YX','CREATE_CSVT=YES'] lyr = gdaltest.csv_tmpds.CreateLayer( 'as_yx', options = options ) field_defn = ogr.FieldDefn( 'ADATA', ogr.OFTString ) lyr.CreateField(field_defn) field_defn.Destroy() dst_feat = ogr.Feature( feature_def = lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 2)')) dst_feat.SetField('ADATA', 'avalue') lyr.CreateFeature( dst_feat ) dst_feat.Destroy() # AS_XYZ options = ['GEOMETRY=AS_XYZ','CREATE_CSVT=YES'] lyr = gdaltest.csv_tmpds.CreateLayer( 'as_xyz', options = options ) field_defn = ogr.FieldDefn( 'ADATA', ogr.OFTString ) lyr.CreateField(field_defn) field_defn.Destroy() dst_feat = ogr.Feature( feature_def = lyr.GetLayerDefn() ) dst_feat.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 2 3)')) dst_feat.SetField('ADATA', 'avalue') lyr.CreateFeature( dst_feat ) dst_feat.Destroy() ####################################################### # Closes everything and reopen gdaltest.csv_tmpds.Destroy() gdaltest.csv_tmpds = None gdaltest.csv_tmpds = ogr.Open( 'tmp/csvwrk' ) # Test AS_WKT lyr = gdaltest.csv_tmpds.GetLayerByName('as_wkt') expect = [ 'POINT (1 2)' ] tr = ogrtest.check_features_against_list( lyr,'WKT',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 'avalue' ] tr = ogrtest.check_features_against_list( lyr,'ADATA',expect) if not tr: return 'fail' # Test AS_XY lyr = gdaltest.csv_tmpds.GetLayerByName('as_xy') if lyr.GetLayerDefn().GetFieldDefn(0).GetName() != 'X': return 'fail' expect = [ 1, None ] tr = ogrtest.check_features_against_list( lyr,'X',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 2, None ] tr = ogrtest.check_features_against_list( lyr,'Y',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 'avalue','avalue' ] tr = ogrtest.check_features_against_list( lyr,'ADATA',expect) if not tr: return 'fail' # Test AS_YX lyr = gdaltest.csv_tmpds.GetLayerByName('as_yx') if lyr.GetLayerDefn().GetFieldDefn(0).GetName() != 'Y': return 'fail' expect = [ 1 ] tr = ogrtest.check_features_against_list( lyr,'X',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 2 ] tr = ogrtest.check_features_against_list( lyr,'Y',expect) if not tr: return 'fail' # Test AS_XYZ lyr = gdaltest.csv_tmpds.GetLayerByName('as_xyz') if lyr.GetLayerDefn().GetFieldDefn(0).GetName() != 'X': return 'fail' expect = [ 1 ] tr = ogrtest.check_features_against_list( lyr,'X',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 2 ] tr = ogrtest.check_features_against_list( lyr,'Y',expect) if not tr: return 'fail' lyr.ResetReading() expect = [ 3 ] tr = ogrtest.check_features_against_list( lyr,'Z',expect) if not tr: return 'fail' return 'success'
def ogr_rfc35_mem_2(): lyr = gdaltest.rfc35_mem_ds.GetLayer(0) if lyr.TestCapability(ogr.OLCReorderFields) != 1: return 'fail' feat = ogr.Feature(lyr.GetLayerDefn()) feat.SetField(0, 'foo3') feat.SetField(1, 'bar3_01234') feat.SetField(2, 'baz3_0123456789') feat.SetField(3, 'baw3_012345678901234') lyr.CreateFeature(feat) feat = None if lyr.ReorderField(1,3) != 0: return 'fail' ret = Check(lyr, ['foo5', 'baz15', 'baw20', 'bar10']) if ret != 'success': return ret lyr.ReorderField(3,1) ret = Check(lyr, ['foo5', 'bar10', 'baz15', 'baw20']) if ret != 'success': return ret lyr.ReorderField(0,2) ret = Check(lyr, ['bar10', 'baz15', 'foo5', 'baw20']) if ret != 'success': return ret lyr.ReorderField(2,0) ret = Check(lyr, ['foo5', 'bar10', 'baz15', 'baw20']) if ret != 'success': return ret lyr.ReorderField(0,1) ret = Check(lyr, ['bar10', 'foo5', 'baz15', 'baw20']) if ret != 'success': return ret lyr.ReorderField(1,0) ret = Check(lyr, ['foo5', 'bar10', 'baz15', 'baw20']) if ret != 'success': return ret lyr.ReorderFields([3,2,1,0]) ret = Check(lyr, ['baw20', 'baz15', 'bar10', 'foo5']) if ret != 'success': return ret lyr.ReorderFields([3,2,1,0]) ret = Check(lyr, ['foo5', 'bar10', 'baz15', 'baw20']) if ret != 'success': return ret gdal.PushErrorHandler('CPLQuietErrorHandler') ret = lyr.ReorderFields([0,0,0,0]) gdal.PopErrorHandler() if ret == 0: return 'fail' return 'success'
def write(self,geom_dict,path,sr=None): """Write a list of geometry dictionaries (similar to that returned by :func:`~ocgis.ShpCabinet.get_geoms`) to disk. :param geom_dict: The list of geometry dictionaries. :type geom_dict: list of dict :param path: The absolute path to the output file. :type path: str :param sr: The spatial reference for the output. Defaults to WGS84. :type sr: :class:`osgeo.osr.SpatialReference` :rtype: str path to output file. """ from ocgis.conv.csv_ import OcgDialect # path = self.get_path() if sr is None: sr = osr.SpatialReference() sr.ImportFromEPSG(4326) dr = ogr.GetDriverByName('ESRI Shapefile') ds = dr.CreateDataSource(path) if ds is None: raise IOError('Could not create file on disk. Does it already exist?') arch = CreateGeometryFromWkb(geom_dict[0]['geom'].wkb) layer = ds.CreateLayer('lyr',srs=sr,geom_type=arch.GetGeometryType()) headers = self.get_headers(geom_dict) build = True for dct,geom in self.get_converter_iterator(geom_dict): if build: csv_path = path.replace('.shp','.csv') csv_f = open(csv_path,'w') writer = csv.writer(csv_f,dialect=OcgDialect) writer.writerow(headers) ogr_fields = self._get_ogr_fields_(headers,dct) for of in ogr_fields: layer.CreateField(of.ogr_field) feature_def = layer.GetLayerDefn() build = False try: row = [dct[h.lower()] for h in headers] except KeyError: row = [] for h in headers: try: x = dct[h] except KeyError: x = dct[h.lower()] row.append(x) writer.writerow(row) feat = ogr.Feature(feature_def) for o in ogr_fields: args = [o.ogr_name,None] try: args[1] = dct[o.ogr_name.lower()] except KeyError: args[1] = dct[o.ogr_name] # args = [o.ogr_name,o.convert(dct[o.ogr_name.lower()])] try: feat.SetField(*args) except NotImplementedError: args[1] = str(args[1]) feat.SetField(*args) feat.SetGeometry(ogr.CreateGeometryFromWkb(geom.wkb)) layer.CreateFeature(feat) ds = None csv_f.close() return(path)
def shp_reproject(srcName, tgtName, epsg=26910): ''' shp_reproject() - Project a shapefile to another shapefile in <spatRef> coordinate system. Parameters ---------- srcName : str input shapefile name tgtName : str output shapefile name epsg : int, default=26910 (NAD 83 UTM 10, CA) EPSG projection Returns ------- nothing ''' import os import osr import ogr # Set target spatial reference tgt_spatRef = osr.SpatialReference() tgt_spatRef.ImportFromEPSG(epsg) # Source shapefile driver = ogr.GetDriverByName('ESRI Shapefile') src = driver.Open(srcName, 0) srcLyr = src.GetLayer() src_spatRef = srcLyr.GetSpatialRef() # Source spatial reference # Target shapefile - delete if it's already there. if os.path.exists(tgtName): driver.DeleteDataSource(tgtName) tgt = driver.CreateDataSource(tgtName) lyrName = os.path.splitext(tgtName)[0] tgtLyr = tgt.CreateLayer(lyrName, geom_type=ogr.wkbPoint) # Layer definition featDef = srcLyr.GetLayerDefn() # Spatial Transform trans = osr.CoordinateTransformation(src_spatRef, tgt_spatRef) # Reproject and copy features srcFeat = srcLyr.GetNextFeature() while srcFeat: geom = srcFeat.GetGeometryRef() geom.Transform(trans) feature = ogr.Feature(featDef) feature.SetGeometry(geom) tgtLyr.CreateFeature(feature) feature.Destroy() srcFeat.Destroy() srcFeat = srcLyr.GetNextFeature() src.Destroy() tgt.Destroy() # Create the prj file tgt_spatRef.MorphToESRI() # Convert geometry to ESRI WKT format prj = open(lyrName + '.prj', 'w') prj.write(tgt_spatRef.ExportToWkt()) prj.close() # Just copy dbf contents over rather than rebuild the dbf using the # ogr API since we're not changing anything. srcDbf = os.path.splitext(srcName)[0] + '.dbf' tgtDbf = lyrName + '.dbf' shutil.copyfile(srcDbf, tgtDbf) return
def test_gdal_rasterize_1(): if test_cli_utilities.get_gdal_rasterize_path() is None: return 'skip' # Setup working spatial reference #sr_wkt = 'LOCAL_CS["arbitrary"]' #sr = osr.SpatialReference( sr_wkt ) sr = osr.SpatialReference() sr.ImportFromEPSG(32631) sr_wkt = sr.ExportToWkt() # Create a raster to rasterize into. target_ds = gdal.GetDriverByName('GTiff').Create( 'tmp/rast1.tif', 100, 100, 3, gdal.GDT_Byte ) target_ds.SetGeoTransform( (1000,1,0,1100,0,-1) ) target_ds.SetProjection( sr_wkt ) # Close TIF file target_ds = None # Create a layer to rasterize from. rast_ogr_ds = \ ogr.GetDriverByName('MapInfo File').CreateDataSource( 'tmp/rast1.tab' ) rast_lyr = rast_ogr_ds.CreateLayer( 'rast1', srs=sr ) layer_defn = rast_lyr.GetLayerDefn() field_defn = ogr.FieldDefn('foo') rast_lyr.CreateField(field_defn) field_defn.Destroy() # Add a polygon. wkt_geom = 'POLYGON((1020 1030,1020 1045,1050 1045,1050 1030,1020 1030))' feat = ogr.Feature( rast_lyr.GetLayerDefn() ) feat.SetGeometryDirectly( ogr.Geometry(wkt = wkt_geom) ) rast_lyr.CreateFeature( feat ) # Add feature without geometry to test fix for #3310 feat = ogr.Feature( rast_lyr.GetLayerDefn() ) rast_lyr.CreateFeature( feat ) # Add a linestring. wkt_geom = 'LINESTRING(1000 1000, 1100 1050)' feat = ogr.Feature( rast_lyr.GetLayerDefn() ) feat.SetGeometryDirectly( ogr.Geometry(wkt = wkt_geom) ) rast_lyr.CreateFeature( feat ) # Close file rast_ogr_ds.Destroy() # Run the algorithm. gdaltest.runexternal(test_cli_utilities.get_gdal_rasterize_path() + ' -b 3 -b 2 -b 1 -burn 200 -burn 220 -burn 240 -l rast1 tmp/rast1.tab tmp/rast1.tif') # Check results. target_ds = gdal.Open('tmp/rast1.tif') expected = 6452 checksum = target_ds.GetRasterBand(2).Checksum() if checksum != expected: print(checksum) gdaltest.post_reason( 'Did not get expected image checksum' ) return 'fail' target_ds = None return 'success'
def kmz_converter(): # open the input KMZ file kmz_file = str(sys.argv[1]) data_source = open_kmz(kmz_file) # create the output shapefiles points_shp_name = set_output_filename(kmz_file, 'points') lines_shp_name = set_output_filename(kmz_file, 'lines') polygons_shp_name = set_output_filename(kmz_file, 'polygons') points_datastore = create_output_datastore(points_shp_name) points_layer = create_output_layer(points_datastore, ogr.wkbMultiPoint) add_fields(points_layer) lines_datastore = create_output_datastore(lines_shp_name) lines_layer = create_output_layer(lines_datastore, ogr.wkbMultiLineString) add_fields(lines_layer) polygons_datastore = create_output_datastore(polygons_shp_name) polygons_layer = create_output_layer(polygons_datastore, ogr.wkbMultiPolygon) add_fields(polygons_layer) # loop through the layers feature_counter = 0 points_counter = 0 lines_counter = 0 polygons_counter = 0 layer_count = data_source.GetLayerCount() for i in range(0, layer_count): layer = data_source.GetLayer(i) layer_info = {} layer_info['feature_count'] = layer.GetFeatureCount() layer_info['name'] = layer.GetName() # loop through the features in each layer for feature in layer: feature_counter += 1 geom = feature.GetGeometryRef() geom_type = geom.GetGeometryName() field_names = ['Name', 'descriptio', 'icon', 'snippet'] if geom_type in ('POINT', 'MULTIPOINT'): points_counter += 1 layer_defn = points_layer.GetLayerDefn() out_feature = ogr.Feature(layer_defn) out_geom = ogr.ForceToMultiPoint(geom) elif geom_type in ('LINESTRING', 'MULTILINESTRING'): lines_counter += 1 layer_defn = lines_layer.GetLayerDefn() out_feature = ogr.Feature(layer_defn) out_geom = ogr.ForceToMultiLineString(geom) elif geom_type in ('POLYGON', 'MULTIPOLYGON'): polygons_counter += 1 layer_defn = polygons_layer.GetLayerDefn() out_feature = ogr.Feature(layer_defn) out_geom = ogr.ForceToMultiPolygon(geom) else: continue # convert to 2D out_geom.FlattenTo2D() # set the output feature geometry out_feature.SetGeometry(out_geom) # set the output feature attributes for field_name in field_names: try: out_feature.SetField(field_name, feature.GetField(field_name)) except: pass out_feature.SetField('layer_name', layer.GetName()) out_feature.SetField('id', feature_counter) # write the output feature to shapefile if geom_type in ('POINT', 'MULTIPOINT'): points_layer.CreateFeature(out_feature) elif geom_type in ('LINESTRING', 'MULTILINESTRING'): lines_layer.CreateFeature(out_feature) elif geom_type in ('POLYGON', 'MULTIPOLYGON'): polygons_layer.CreateFeature(out_feature) # clear the output feature variable out_feature = None # reset the layer reading in case it needs to be re-read later layer.ResetReading() print layer_info['name'], feature_counter # print counts print '\nSUMMARY COUNTS' print "Feature count: %s" % feature_counter print "Points count: %s" % points_counter print "Lines count: %s" % lines_counter print "Polygons count: %s" % polygons_counter # cleanup points_datastore = None points_layer = None lines_datastore = None lines_layer = None polygons_datastore = None polygons_layer = None # remove empty output shapefiles driver = ogr.GetDriverByName('ESRI Shapefile') if points_counter == 0: driver.DeleteDataSource(points_shp_name) if lines_counter == 0: driver.DeleteDataSource(lines_shp_name) if polygons_counter == 0: driver.DeleteDataSource(polygons_shp_name)
def consolidate(inputfile): # Now combine all subsets into a macroset # 4 create a new data source and layer fn = dir_base_name + '-traced.shp' # 2 get the shapefile driver driver = ogr.GetDriverByName('ESRI Shapefile') # 3 open the input data source and get the layer shapefile = dir_base_name + '.shp' inDS = driver.Open(shapefile, 0) #shows cover at given points if inDS is None: print 'Could not open shapefile' sys.exit(1) inLayer = inDS.GetLayer() # 5 get the FieldDefn's for the id and cover fields in the input shapefile feature = inLayer.GetFeature(0) idFieldDefn = feature.GetFieldDefnRef('DN') if os.path.exists(fn): driver.DeleteDataSource(fn) outDS = driver.CreateDataSource(fn) if outDS is None: print 'Could not create final shapefile' sys.exit(1) outLayer = outDS.CreateLayer(base_name, geom_type=ogr.wkbPolygon) #create new field in the output shapefile outLayer.CreateField(idFieldDefn) # 6 get the FeatureDefn for the output layer featureDefn = outLayer.GetLayerDefn() # new field definitions for this shapefile # color definition colorDefn = ogr.FieldDefn("Color", ogr.OFTInteger) colorDefn.SetWidth(2) colorDefn.SetPrecision(0) outLayer.CreateField(colorDefn) # dot count definition dotCountDefn = ogr.FieldDefn("DotCount", ogr.OFTInteger) dotCountDefn.SetWidth(2) dotCountDefn.SetPrecision(0) outLayer.CreateField(dotCountDefn) # dot type definition dotTypeDefn = ogr.FieldDefn("DotType", ogr.OFTInteger) dotTypeDefn.SetWidth(1) dotTypeDefn.SetPrecision(0) outLayer.CreateField(dotTypeDefn) # cross count definition crossCountDefn = ogr.FieldDefn("CrossCount", ogr.OFTInteger) crossCountDefn.SetWidth(2) crossCountDefn.SetPrecision(0) outLayer.CreateField(crossCountDefn) # cross data definition crossDataDefn = ogr.FieldDefn("CrossData", ogr.OFTString) crossDataDefn.SetWidth(255) outLayer.CreateField(crossDataDefn) # add lat/lon as OFTReal attributes outLayer.CreateField(ogr.FieldDefn("CentroidY", ogr.OFTReal)) outLayer.CreateField(ogr.FieldDefn("CentroidX", ogr.OFTReal)) polygonfiles = [] for files in os.listdir(path): if files.endswith(".shp") and files.find('-polygon') != -1: polygonfile = path + "/" + files # apply a projection so gdalwarp doesnt complain polygonfilename = files[:files.find(".shp")] os.system("cp " + dir_base_name + ".prj " + path + "/" + polygonfilename + ".prj") extractedfile = path + "/" + polygonfilename + "-extracted.tif" # extract bitmap from original command = "gdalwarp -q -t_srs EPSG:3785 -cutline " + polygonfile + " -crop_to_cutline -of GTiff " + inputfile + " " + extractedfile logging.debug(command) # print command os.system(command) # calculate color # shrink to 1x1 and find value # logging.debug( string.join(["convert", "-quiet", os.path.abspath(extractedfile), "-resize", "1x1","txt:-"]) ) # pixelvalue = subprocess.Popen(["convert", "-quiet", os.path.abspath(extractedfile), "-resize", "1x1","txt:-"], stdout=subprocess.PIPE).communicate()[0] # pattern = re.compile(r"0,0: \(([\s0-9]*),([\s0-9]*),([\s0-9]*).*") # values = pattern.findall(pixelvalue) extractedpath = os.path.abspath(extractedfile) if os.path.exists(extractedpath) == False: continue values = average_color(extractedpath) if len(values) > 0: red = int(values[0]) green = int(values[1]) blue = int(values[2]) nearest = 100000 nearestcolor = [] nearestcolorindex = -1 for i, color in enumerate(basecolors): dred = (color[0] - red) * (color[0] - red) dgreen = (color[1] - green) * (color[1] - green) dblue = (color[2] - blue) * (color[2] - blue) dist = dred + dgreen + dblue if dist < nearest: nearest = dist nearestcolor = color nearestcolorindex = i # only add if NOT paper if nearestcolor != basecolors[0]: # check for dots circle_data = cv_feature_detect(extractedfile) # add to array polygonfiles.append( [polygonfile, nearestcolorindex, circle_data]) else: logging.debug("Ignored (paper color): " + polygonfilename + "\n") else: logging.debug("Ignored (regex match error): " + polygonfilename + "\n") for files in polygonfiles: # 3 open the input data source and get the layer tempfile = files[ 0] #dir_base_name + '-tmp-' + str(currentsubset) + '-traced.shp' inDS = driver.Open(tempfile, 0) #shows cover at given points if inDS is None: print 'Could not open temporary shapefile' break inLayer = inDS.GetLayer() # 7 loop through the input features inFeature = inLayer.GetNextFeature() while inFeature: # create a new feature outFeature = ogr.Feature( featureDefn) #using featureDefn created in step 6 # set the geometry geom = inFeature.GetGeometryRef() outFeature.SetGeometry(geom) #move it to the new feature DN = inFeature.GetField('DN') outFeature.SetField('DN', DN) #move it to the new feature outFeature.SetField('Color', int(files[1])) outFeature.SetField('DotCount', int(files[2]["count"])) outFeature.SetField('DotType', int(files[2]["is_outline"])) outFeature.SetField('CrossCount', int(files[2]["cross_count"])) outFeature.SetField('CrossData', str(files[2]["cross_data"])) source_srs = osr.SpatialReference() source_srs.ImportFromEPSG(3785) # NOTE: notice this is hardcoded target_srs = osr.SpatialReference() target_srs.ImportFromEPSG(4326) # NOTE: notice this is hardcoded transform = osr.CoordinateTransformation(source_srs, target_srs) centroid = geom.Centroid() centroid.Transform(transform) outFeature.SetField('CentroidY', centroid.GetY()) outFeature.SetField('CentroidX', centroid.GetX()) # outFeature.SetField('circle_count', files[2]["circle_count"]) # outFeature.SetField('circle_type', files[2]["is_outline"]) # add the feature to the output layer outLayer.CreateFeature(outFeature) # destroy the output feature outFeature.Destroy() # destroy the input feature and get a new one inFeature.Destroy() inFeature = inLayer.GetNextFeature() # close the data sources inDS.Destroy() outDS.Destroy() #flush out the last changes here print "" print "Applying projection file to result..." print "-------------------------------------" os.system("cp " + dir_base_name + ".prj " + dir_base_name + "-traced.prj")
#create spatial reference srs = osr.SpatialReference() #in this case wgs84 srs.ImportFromEPSG(4326) #create kml layer as point data with wgs84 as spatial reference layer = data_source.CreateLayer(layer_name, srs, ogr.wkbPoint) #create "Name" column for attribute table and set type as string field_name = ogr.FieldDefn("Name", ogr.OFTString) field_name.SetWidth(24) layer.CreateField(field_name) #create point geometry point = ogr.Geometry(ogr.wkbPoint) #add point into point geometry point.AddPoint(longitude, latitude) #create a feature feature = ogr.Feature(layer.GetLayerDefn()) #set feature geometry feature.SetGeometry(point) #add field "Name" to feature feature.SetField("Name", 'point_one') #create feature in layer layer.CreateFeature(feature)
def create(self): """ | Generate the fishnet dataset, based on the code at | https://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html#create-fishnet-grid """ gdal.UseExceptions() try: # Get bounding values aoi = self.bbox if self.lad: # Get the bounds from a (list of) Local Authority District boundary(s)/all self.logger.info('Get boundary from list of LAD codes...') try: kvp = { 'lad_codes': ','.join(self.lad), 'export_format': 'geojson', 'year': 2016 } api = '{}/{}/{}'.format(Config.get('NISMOD_DB_API_URL'), 'boundaries', 'lads') auth_username = Config.get('NISMOD_DB_USERNAME') auth_password = Config.get('NISMOD_DB_PASSWORD') r = requests.get(api, params=kvp, auth=(auth_username, auth_password)) # Note: should be able to simply read r.json() into a GeoDataFrame, however it throws a ValueError # 'Mixing dicts with non-Series may lead to ambiguous ordering' which makes very little sense to me! # So we do it a roundabout way via the recipe at # https://gis.stackexchange.com/questions/225586/reading-raw-data-into-geopandas self.logger.info('NISMOD API call completed') gdf = geopandas.read_file(BytesIO(r.content)) aoi = gdf.total_bounds except ValueError: raise xmin, ymin, xmax, ymax = [float(value) for value in aoi] self.logger.info( 'Fishnet bounds : xmin {}, ymin {}, xmax {}, ymax {}'.format( xmin, ymin, xmax, ymax)) grid_width = grid_height = float(self.netsize) # Number of rows x columns rows = ceil((ymax - ymin) / grid_height) cols = ceil((xmax - xmin) / grid_width) self.logger.info('Fishnet has {} rows and {} columns'.format( rows, cols)) # Start grid cell envelope ring_x_left_origin = xmin ring_x_right_origin = xmin + grid_width ring_y_top_origin = ymax ring_y_bottom_origin = ymax - grid_height out_driver = ogr.GetDriverByName(self.outformat) output_file = self.outfile if output_file is None: # Stream the data to memory output_file = '/vsimem/{}.geojson'.format(uuid.uuid4().hex) else: # Create output file if not path.isabs(output_file): # Relative path => so prepend data directory (does NOT handle making subdirectories here) data_dir = Config.get('DATA_DIRECTORY') self.logger.info( 'Relative path supplied, assume relative to data directory {}' .format(data_dir)) output_file = path.join(data_dir, output_file) else: # Absolute path => ensure all directories are present before writing try: makedirs(path.dirname(output_file), exist_ok=True) except OSError: self.logger.warning( 'Failed to create subdirectory for output file') raise # Delete any pre-existing version of output file if path.exists(output_file): remove(output_file) out_data_source = out_driver.CreateDataSource(output_file) srs = osr.SpatialReference() srs.ImportFromEPSG(27700) out_layer = out_data_source.CreateLayer(output_file, srs=srs, geom_type=ogr.wkbPolygon) # Add a FID field id_field = ogr.FieldDefn('FID', ogr.OFTInteger) out_layer.CreateField(id_field) feature_defn = out_layer.GetLayerDefn() # Create grid cells fid = 1 countcols = 0 while countcols < cols: countcols += 1 #self.logger.info('Generating column {}...'.format(countcols)) # Reset envelope for rows ring_y_top = ring_y_top_origin ring_y_bottom = ring_y_bottom_origin countrows = 0 while countrows < rows: countrows += 1 #self.logger.info('Row {}'.format(countrows)) ring = ogr.Geometry(ogr.wkbLinearRing) ring.AddPoint(ring_x_left_origin, ring_y_top) ring.AddPoint(ring_x_right_origin, ring_y_top) ring.AddPoint(ring_x_right_origin, ring_y_bottom) ring.AddPoint(ring_x_left_origin, ring_y_bottom) ring.AddPoint(ring_x_left_origin, ring_y_top) poly = ogr.Geometry(ogr.wkbPolygon) poly.AddGeometry(ring) # Add new geom to layer out_feature = ogr.Feature(feature_defn) out_feature.SetGeometry(poly) out_feature.SetField('FID', fid) out_layer.CreateFeature(out_feature) out_feature = None fid += 1 # New envelope for next poly ring_y_top = ring_y_top - grid_height ring_y_bottom = ring_y_bottom - grid_height # New envelope for next poly ring_x_left_origin = ring_x_left_origin + grid_width ring_x_right_origin = ring_x_right_origin + grid_width # Save and close data sources out_data_source = None fishnet_output = None if self.outfile is None: # Read the memory buffer GeoJSON into Python dict structure memfile_json = self.read_file(output_file).decode('utf-8') fishnet_output = loads(memfile_json) else: fishnet_output = output_file self.logger.info('Finished writing fishnet output') return fishnet_output except: self.logger.warning(traceback.format_exc()) return None
for i in range(0, in_layer_def.GetFieldCount()): field_def = in_layer_def.GetFieldDefn(i) output_shp_layer.CreateField(field_def) # get the output layer's feature definition output_layer_def = output_shp_layer.GetLayerDefn() # loop through the input features in_feature = in_shp_layer.GetNextFeature() while in_feature: # get the input geometry geom = in_feature.GetGeometryRef() # reproject the geometry geom.Transform(coord_trans) # create a new feature output_feature = ogr.Feature(output_layer_def) # set the geometry and attribute output_feature.SetGeometry(geom) for i in range(0, output_layer_def.GetFieldCount()): output_feature.SetField(output_layer_def.GetFieldDefn(i).GetNameRef(), in_feature.GetField(i)) # add the feature to the shapefile output_shp_layer.CreateFeature(output_feature) # destroy the features and get the next input feature output_feature.Destroy() in_feature.Destroy() in_feature = in_shp_layer.GetNextFeature() # close the shapefiles input_shp.Destroy() output_shp_dataset.Destroy()
def DirectDiffuseRadiationEst(skyImgFolder,skymapfile,timeLst,shpfile): ''' # This is function is used to calculate the direct and diffuse solar radiation based on the classified hemisperhical photos and save the result direct and diffused solar radiation as a shpfile # ---------The direct and the diffuse solar radiation------------- # Copyright (C) Xiaojiang Li, MIT Senseable City Lab # First version March 22ed, 2017 Parameters: skyImgFolder: the input sky image folder timeList: the time series, timeList = [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] shpfile: the output shapefile to store the distribution of sunlight duration ''' from PIL import Image import numpy as np import urllib import os, os.path import math from pysolar.solar import get_altitude, get_azimuth import gdal,ogr,osr # create a shpafile to save the sun duration driver = ogr.GetDriverByName("ESRI Shapefile") if os.path.exists(shpfile): driver.DeleteDataSource(shpfile) data_source = driver.CreateDataSource(shpfile) targetSpatialRef = osr.SpatialReference() targetSpatialRef.ImportFromEPSG(4326) outLayer = data_source.CreateLayer("Radiation",targetSpatialRef, ogr.wkbPoint) direct = ogr.FieldDefn('direct', ogr.OFTReal) diffuse = ogr.FieldDefn('diffuse', ogr.OFTReal) panoId = ogr.FieldDefn('panoid', ogr.OFTString) outLayer.CreateField(direct) outLayer.CreateField(diffuse) outLayer.CreateField(panoId) # loop all the sky image in the folder for skyimg in os.listdir(skyImgFolder): skyImgFile = os.path.join(skyImgFolder,skyimg) basename = os.path.basename(skyImgFile)[:-4] fields = basename.split(' - ') panoID = fields[0] lon = float(fields[1]) lat = float(fields[2]) # calculate the direct radiation directRadiation = DirectRadiationEst(skyImgFile,timeLst) # calculate the diffuse radiation diffuseRadiation = DiffuseRadiationEst(skyImgFile,skymapfile) print ('The direct and diffuser radiation are:',panoID,directRadiation,diffuseRadiation) # add point feature point = ogr.Geometry(ogr.wkbPoint) point.AddPoint(lon, lat) # create feature and set the attribute values featureDefn = outLayer.GetLayerDefn() outFeature = ogr.Feature(featureDefn) # set the geometrical feature outFeature.SetGeometry(point) outFeature.SetField('direct',directRadiation) outFeature.SetField('diffuse',diffuseRadiation) outFeature.SetField('panoid',panoID) # push the feature to the layer outLayer.CreateFeature(outFeature) outFeature.Destroy() data_source.Destroy()
def add_feature(self, row, source_srs=None): import datetime gdal.UseExceptions() geometry = self.get_geometry(row) if source_srs is not None and source_srs != self.source_srs: self.source_srs = self._get_srs(source_srs) self.transform = osr.CoordinateTransformation( self.source_srs, self.srs) if self.layer is None: type_ = geometry.GetGeometryType() self.layer = self.ds.CreateLayer(self.name, self.srs, type_, options=self.ds._layer_options) if self.layer is None: raise Exception("Failed to create layer {} in {}".format( self.name, self.path)) self.load_schema(self.layer) feature = ogr.Feature(self.layer.GetLayerDefn()) if isinstance(row, dict): for i, c in enumerate(self.table.columns): if i not in self.geo_col_pos or c.name in [ 'x', 'y', 'lat', 'lon' ]: v = row.get(c.name, False) if v is not False and isinstance(v, basestring): try: v = str( v.decode('latin1').encode('utf_8' ) if v else None) except Exception: raise if v is not False: if isinstance(v, datetime.date): feature.SetField(str(c.name), v.year, v.month, v.day, 0, 0, 0, 0) elif isinstance(v, datetime.datetime): feature.SetField(str(c.name), v.year, v.month, v.day, v.hour, v.minute, v.second, 0) else: feature.SetField(str(c.name), str(v)) elif c.default: try: feature.SetField(str(c.name), c.python_type(c.default)) except: raise else: raise Exception("Can only handle dict rows") if self.transform: geometry.Transform(self.transform) feature.SetGeometryDirectly(geometry) if self.layer.CreateFeature(feature) != 0: raise FeatureError('Failed to add feature: {}: geometry={}'.format( gdal.GetLastErrorMsg(), geometry.ExportToWkt())) feature.Destroy()