How to use GDAL/OGR to open the vector and output the point data within the rectangle outside each face

Keywords: Attribute Python

How to use GDAL/OGR to open the vector and output the layer data range and each employee feature range

The main purpose of this paper is: sometimes we need to get the external rectangle range of vector data, but a layer data has several surface elements, if we get the overall external rectangle for processing, it will cause a large amount of data; then we judge the external rectangle one by one; then we generate point data according to the external rectangle range.

1) How to use GDAL/OGR to open the vector and output the layer data range and each employee feature range
2) Generate point data according to the rectangle range and pixel size

0. Conception

Source:
Data form, there is a face layer data,


One grid data:

I need to extract the point data in each face layer from the vector face data. The interval size of the point data is the pixel size of the grid data, that is, the figure above. The point data to be extracted is:


Zoom in to see this kind of point data:

1. arcmap view data attribute information

First, open my data with arcmap, and view the range and attribute information of the data:

2. Output the extent of the extent bounding rectangle for each data

Getextend() function is used to get the layer data range;
To get the range of elements, you need to cycle each element, and then use the GetEnvelope() function;

#How to use GDAL/OGR to open the vector file, read the property sheet fields, and change the data range and the range of each employee feature
import ogr,sys,os
import numpy as np

os.chdir('D:/20200309/shujushouji/python+jupyternoterbook/zuoye1(1)/6 Grid data operation/shiyan')

#Set up the driver and open the vector file
driver = ogr.GetDriverByName('ESRI Shapefile')
ds = driver.Open('polygon.shp', 0)
if ds is None:
  print("Could not open", 'sites.shp')
  sys.exit(1)
#Get Atlas
layer = ds.GetLayer()

#Number of elements
numFeatures = layer.GetFeatureCount()
print("Feature count: "+str(numFeatures))

#Scope of acquisition
extent = layer.GetExtent()
print("Extent:", extent)
print("UL:", extent[0],extent[3])
print("LR:", extent[1],extent[2])

#Get elements
#feature = layer.GetNextFeature()
 
#Loop each element attribute
for i in range(numFeatures):
  feature = layer.GetNextFeature()
  #Get properties of field 'id'
  id = feature.GetField('type')
  #Get space properties
  print(id)
  geometry = feature.GetGeometryRef()
  #x = geometry.GetX()
  polygonextent=geometry.GetEnvelope()
  print(geometry.GetEnvelope())
  #print(y)

  #y = geometry.GetY()
  print("UL:", polygonextent[0],polygonextent[3])
  print("LR:", polygonextent[1],polygonextent[2])
  

3. Generate point data according to the outer rectangular range

The following code is generated by sampling and generating point s according to the external rectangle of polygon's ext;
It involves the knowledge that gdal reads the grid data, obtains the starting coordinates and pixel sizes of the upper left corner of the image, and the spatial coordinates of the external rectangular range obtained by finding vectors, converts the spatial coordinates into the row and column numbers of the image, and then circularly generates the vector point data, and writes it into the vector file.

# Get it first polygon.shp The range of the outer rectangle and the coordinate point; then convert the coordinate point to the row and column number of the grid, only for sample_ The grid area within the region is used to turn the grid to point
%matplotlib inline
import matplotlib.pyplot as plt
from shapely.geometry import Point
import geopandas as gpd
import ogr,sys,os
from pyproj import Transformer
import numpy as np
from osgeo import gdal

os.chdir('D:/20200309/shujushouji/python+jupyternoterbook/zuoye1(1)/shiyan/polygon')


#Set up the driver and open the vector file
driver = ogr.GetDriverByName('ESRI Shapefile')
dsshp = driver.Open('sample_regions.shp', 0)
if dsshp is None:
  print("Could not open", 'sites.shp')
  sys.exit(1)
#Get Atlas
layer = dsshp.GetLayer()

#Number of elements
numFeatures = layer.GetFeatureCount()
print("Feature count: "+str(numFeatures))

def world2Pixel(geotransform, x, y):
    originX = geotransform[0]
    originY = geotransform[3]
    pixelWidth = geotransform[1]
    pixelHeight = geotransform[5]
    line = int((y-originY)/pixelHeight)+1
    column = int((x-originX)/pixelWidth)+1
    return (line,column)
def Pixel2world(geotransform, line, column):
    originX = geotransform[0]
    originY = geotransform[3]
    pixelWidth = geotransform[1]
    pixelHeight = geotransform[5]
    x = column*pixelWidth + originX - pixelWidth/2
    y = line*pixelHeight + originY - pixelHeight/2
    return(x,y)

ds = gdal.Open( "D:/20200309/shujushouji/python+jupyternoterbook/zuoye1(1)/6 Grid data operation/landsat8_20180523/20180523.img" )

geotransform = ds.GetGeoTransform()

 
# Get spatial coordinate range 
extent = layer.GetExtent()
print("Extent:", extent)
print("UL:", extent[0],extent[3])
print("LR:", extent[1],extent[2])

# Research area will be acquired polygon.shp The number of rows and columns converted into grid data 
linex1,columny1 = world2Pixel(geotransform, extent[0],extent[3])
print(f"linex1:{linex1}")
print(f"columny1:{columny1}")

linex2,columny2 = world2Pixel(geotransform,extent[1],extent[2])
print(f"linex2:{linex2}")
print(f"columny2:{columny2}")


points = []
for i in range(linex1,linex2):
    for j in range(columny1,columny2):
        x,y = Pixel2world(geotransform,i+1,j+1)
        point = Point((x,y))
        points.append(point)
gdf = gpd.GeoDataFrame()
gdf["geometry"] = points

#Assign the coordinate system of grid data to the point data of the region of interest
print(ds.GetProjection())
gdf.crs=ds.GetProjection()
gdf.to_file("D:/20200309/shujushouji/python+jupyternoterbook/zuoye1(1)/6 Grid data operation/test/d_points1.shp") 
gdf.plot()

Posted by kwong on Fri, 19 Jun 2020 01:22:19 -0700