├── .gitignore ├── 02 ├── chengdu-xinglong-lake.tif └── gdal_clip.py ├── 03 ├── 03 │ ├── shdemo.dbf │ ├── shdemo.prj │ ├── shdemo.shp │ └── shdemo.shx └── shpdemo.py ├── 04 └── shpcliptifdemo.py ├── 05 └── tif.c ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /02/chengdu-xinglong-lake.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dennishucd/gdal100/586deefed6a8ecdf55c122a882bbcd565634c488/02/chengdu-xinglong-lake.tif -------------------------------------------------------------------------------- /02/gdal_clip.py: -------------------------------------------------------------------------------- 1 | import gdal 2 | 3 | # 读取要切的原图 4 | in_ds = gdal.Open("chengdu-xinglong-lake.tif") 5 | print("open tif file succeed") 6 | 7 | # 读取原图中的每个波段 8 | in_band1 = in_ds.GetRasterBand(1) 9 | in_band2 = in_ds.GetRasterBand(2) 10 | in_band3 = in_ds.GetRasterBand(3) 11 | 12 | # 定义切图的起始点坐标(相比原点的横坐标和纵坐标偏移量) 13 | offset_x = 100 # 这里是随便选取的,可根据自己的实际需要设置 14 | offset_y = 100 15 | 16 | # 定义切图的大小(矩形框) 17 | block_xsize = 400 # 行 18 | block_ysize = 400 # 列 19 | 20 | # 从每个波段中切需要的矩形框内的数据(注意读取的矩形框不能超过原图大小) 21 | out_band1 = in_band1.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize) 22 | out_band2 = in_band2.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize) 23 | out_band3 = in_band3.ReadAsArray(offset_x, offset_y, block_xsize, block_ysize) 24 | 25 | # 获取Tif的驱动,为创建切出来的图文件做准备 26 | gtif_driver = gdal.GetDriverByName("GTiff") 27 | 28 | # 创建切出来的要存的文件(3代表3个不都按,最后一个参数为数据类型,跟原文件一致) 29 | out_ds = gtif_driver.Create('clip.tif', block_xsize, block_ysize, 3, in_band1.DataType) 30 | print("create new tif file succeed") 31 | 32 | # 获取原图的原点坐标信息 33 | ori_transform = in_ds.GetGeoTransform() 34 | if ori_transform: 35 | print (ori_transform) 36 | print("Origin = ({}, {})".format(ori_transform[0], ori_transform[3])) 37 | print("Pixel Size = ({}, {})".format(ori_transform[1], ori_transform[5])) 38 | 39 | # 读取原图仿射变换参数值 40 | top_left_x = ori_transform[0] # 左上角x坐标 41 | w_e_pixel_resolution = ori_transform[1] # 东西方向像素分辨率 42 | top_left_y = ori_transform[3] # 左上角y坐标 43 | n_s_pixel_resolution = ori_transform[5] # 南北方向像素分辨率 44 | 45 | # 根据反射变换参数计算新图的原点坐标 46 | top_left_x = top_left_x + offset_x * w_e_pixel_resolution 47 | top_left_y = top_left_y + offset_y * n_s_pixel_resolution 48 | 49 | # 将计算后的值组装为一个元组,以方便设置 50 | dst_transform = (top_left_x, ori_transform[1], ori_transform[2], top_left_y, ori_transform[4], ori_transform[5]) 51 | 52 | # 设置裁剪出来图的原点坐标 53 | out_ds.SetGeoTransform(dst_transform) 54 | 55 | # 设置SRS属性(投影信息) 56 | out_ds.SetProjection(in_ds.GetProjection()) 57 | 58 | # 写入目标文件 59 | out_ds.GetRasterBand(1).WriteArray(out_band1) 60 | out_ds.GetRasterBand(2).WriteArray(out_band2) 61 | out_ds.GetRasterBand(3).WriteArray(out_band3) 62 | 63 | # 将缓存写入磁盘 64 | out_ds.FlushCache() 65 | print("FlushCache succeed") 66 | 67 | # 计算统计值 68 | # for i in range(1, 3): 69 | # out_ds.GetRasterBand(i).ComputeStatistics(False) 70 | # print("ComputeStatistics succeed") 71 | 72 | del out_ds 73 | 74 | print("End!") 75 | 76 | 77 | -------------------------------------------------------------------------------- /03/03/shdemo.dbf: -------------------------------------------------------------------------------- 1 | wA3nameC2 polygon1 -------------------------------------------------------------------------------- /03/03/shdemo.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]] -------------------------------------------------------------------------------- /03/03/shdemo.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dennishucd/gdal100/586deefed6a8ecdf55c122a882bbcd565634c488/03/03/shdemo.shp -------------------------------------------------------------------------------- /03/03/shdemo.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dennishucd/gdal100/586deefed6a8ecdf55c122a882bbcd565634c488/03/03/shdemo.shx -------------------------------------------------------------------------------- /03/shpdemo.py: -------------------------------------------------------------------------------- 1 | import shapefile 2 | from osgeo import osr 3 | 4 | # 定义shp文件名及存储路径 5 | shp_filename = "03/shdemo.shp" 6 | 7 | # 创建shp文件 8 | shp = shapefile.Writer(shp_filename) 9 | 10 | # 设置shp的类型为多边形 11 | shp.shapeType = 5 # POLYGON = 5 12 | 13 | shp.field('name', 'C') 14 | 15 | # 把多边形的点依次加入,注意:多边形的坐标为顺时针,孔的坐标为逆时针 16 | # 注意:一个shp文件中通常可能存在多个多边形,比如表达孔的情况 17 | shp.poly([[[104.09151077270508,30.404748814079547],[104.08854961395264,30.402268893432442], 18 | [ 104.09206867218016,30.40034413549041],[104.09442901611328,30.40297216090944], 19 | [104.09151077270508,30.404748814079547]]]) 20 | shp.record('polygon1') 21 | shp.close() 22 | 23 | # 创建空间参考信息 24 | spatial_ref = osr.SpatialReference() 25 | spatial_ref.ImportFromEPSG(4326) 26 | 27 | file = open('03/shdemo.prj', 'w') 28 | file.write(spatial_ref.ExportToWkt()) 29 | file.close() -------------------------------------------------------------------------------- /04/shpcliptifdemo.py: -------------------------------------------------------------------------------- 1 | from osgeo import gdal, gdalnumeric, ogr 2 | from PIL import Image, ImageDraw 3 | 4 | # 将图像转为数组 5 | def imageToArray(i): 6 | a = gdalnumeric.fromstring(i.tobytes(), 'b') 7 | a.shape = i.im.size[1], i.im.size[0] 8 | return a 9 | 10 | # 将数组转为图像 11 | def arrayToImage(a): 12 | i = Image.frombytes('L', (a.shape[1], a.shape[0]), a.astype('b')) 13 | return i 14 | 15 | # 将经纬度坐标转为像素坐标 16 | def world2Pixel(geoMatrix, x, y): 17 | ulX = geoMatrix[0] 18 | ulY = geoMatrix[3] 19 | xDist = geoMatrix[1] 20 | yDist = geoMatrix[5] 21 | 22 | pixel = int((x - ulX) / xDist) 23 | line = int((ulY - y) / yDist) 24 | 25 | return (abs(pixel), abs(line)) 26 | 27 | 28 | # 第一步:准备好要切的tif图、shp文件及输出的文件名 29 | tif_file = "chengdu-xinglong-lake.tif" # 原始的tif图 30 | shp_file = "xing/xing.shp" # 要切的shape file 31 | clipped_file = "clipped.tif" # 最后切出来的tif图名字 32 | 33 | # 第二步:将tif文件读取为numpy.ndarray 34 | srcArray = gdalnumeric.LoadFile(tif_file) 35 | 36 | # 第三步:读取tif文件中的仿信息 37 | in_ds = gdal.Open(tif_file) 38 | geoTrans = in_ds.GetGeoTransform() 39 | print (geoTrans) 40 | 41 | # 第四步:读取shp文件中的图层从而获取要切取部分的extent 42 | shapef = ogr.Open(shp_file) 43 | lyr = shapef.GetLayer() 44 | minX, maxX, minY, maxY = lyr.GetExtent() 45 | print (111, minX, maxX, minY, maxY) 46 | 47 | # 第五步:将要切取部分的大地坐标转为像素坐标 48 | ulX, ulY = world2Pixel(geoTrans, minX, maxY) 49 | lrX, lrY = world2Pixel(geoTrans, maxX, minY) 50 | 51 | # 计算clip出来图的宽和高 52 | pxWidth = abs(int(lrX - ulX)) 53 | pxHeight = abs(int(lrY - ulY)) 54 | 55 | # 从原图中切出来,但这个时候还是矩形的 56 | clip = srcArray[:, ulY:lrY, ulX:lrX] 57 | 58 | geoTrans = list(geoTrans) 59 | 60 | # 更新左上角的坐标,相当于更新设置切后的tif图的仿射信息 61 | geoTrans[0] = minX 62 | geoTrans[3] = maxY 63 | 64 | # 下面主要是构造mask 65 | points = [] 66 | pixels = [] 67 | poly = lyr.GetNextFeature() 68 | geom = poly.GetGeometryRef() 69 | pts = geom.GetGeometryRef(0) 70 | for p in range(pts.GetPointCount()): 71 | points.append((pts.GetX(p), pts.GetY(p))) 72 | print (str(pts.GetX(p))+","+str(pts.GetY(p))) 73 | 74 | for p in points: 75 | pixels.append(world2Pixel(geoTrans, p[0], p[1])) 76 | 77 | rasterPoly = Image.new("L", (pxWidth, pxHeight), 1) 78 | 79 | rasterize = ImageDraw.Draw(rasterPoly) 80 | rasterize.polygon(pixels, 0) 81 | 82 | mask = imageToArray(rasterPoly) 83 | 84 | # 按照多边形来切 85 | clip = gdalnumeric.choose(mask, (clip, 0)) 86 | 87 | # 创建切后图的tif文件 88 | gtif_driver = gdal.GetDriverByName('GTiff') 89 | out_ds = gtif_driver.Create(clipped_file, pxWidth, pxHeight, 3, in_ds.GetRasterBand(1).DataType) 90 | 91 | # 设置切出来的tif图的仿射信息和参考系统 92 | out_ds.SetGeoTransform(geoTrans) 93 | out_ds.SetProjection(in_ds.GetProjection()) 94 | 95 | # 写入目标文件 96 | out_ds.GetRasterBand(1).WriteArray(clip[0]) 97 | out_ds.GetRasterBand(2).WriteArray(clip[1]) 98 | out_ds.GetRasterBand(3).WriteArray(clip[2]) 99 | 100 | # 将缓存写入磁盘 101 | out_ds.FlushCache() 102 | print("FlushCache succeed") -------------------------------------------------------------------------------- /05/tif.c: -------------------------------------------------------------------------------- 1 | #include "gdal.h" 2 | #include "cpl_conv.h" 3 | 4 | int main() 5 | { 6 | GDALDriverH hDriver; 7 | GDALDatasetH hSrcDS; 8 | GDALRasterBandH hSrcBand; 9 | 10 | char *pszSrcFilename = "030E30N.tif"; 11 | double adfGeoTransform[6]; 12 | 13 | GDALAllRegister(); 14 | 15 | hSrcDS = GDALOpen(pszSrcFilename, GA_ReadOnly); 16 | if( hSrcDS == NULL ) 17 | { 18 | printf("error, file not found. \n"); 19 | } 20 | 21 | int iRasterXSize = GDALGetRasterXSize(hSrcDS); 22 | int iRasterYSize = GDALGetRasterYSize(hSrcDS); 23 | 24 | printf("The input file size is %dx%d.\n", iRasterXSize, iRasterYSize); 25 | 26 | hDriver = GDALGetDatasetDriver(hSrcDS); 27 | 28 | hSrcBand = GDALGetRasterBand( hSrcDS, 1); 29 | 30 | GDALGetGeoTransform(hSrcDS, adfGeoTransform); 31 | 32 | for (int i=0; i<6; i++) 33 | { 34 | printf("%f.\n", adfGeoTransform[i]); 35 | } 36 | 37 | printf("pixel value:\n"); 38 | 39 | for (int i=0; i