├── .github └── workflows │ └── mkdocs.yml ├── LICENSE ├── README.md ├── docs ├── assets │ ├── image-20200309152509219.png │ ├── quarter1.png │ ├── quarter4.png │ ├── quarter6.png │ └── quarter9.png ├── css │ └── img.css ├── images │ ├── logo-blue.svg │ └── logo.svg ├── index.md ├── 一般使用.md ├── 几何.md ├── 投影.md ├── 栅格图层.md └── 矢量图层.md └── mkdocs.yml /.github/workflows/mkdocs.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: mkdocs 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the master branch 8 | push: 9 | branches: [ master ] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | # This workflow contains a single job called "build" 17 | build: 18 | # The type of runner that the job will run on 19 | runs-on: ubuntu-latest 20 | 21 | # Steps represent a sequence of tasks that will be executed as part of the job 22 | steps: 23 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 24 | - uses: actions/checkout@v2 25 | - uses: actions/setup-python@v2 26 | with: 27 | python-version: 3.x 28 | - run: pip install mkdocs-material 29 | - run: mkdocs gh-deploy --force -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 llc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python GDAL/OGR 中文手册 2 | 3 | 本项目是翻译项目,英文项目地址:https://github.com/pcjericks/py-gdalogr-cookbook 4 | 5 | -------------------------------------------------------------------------------- /docs/assets/image-20200309152509219.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luolingchun/py-gdalogr-cookbook-zh/d068a6ce54262f9915c47a41f723b09755fff236/docs/assets/image-20200309152509219.png -------------------------------------------------------------------------------- /docs/assets/quarter1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luolingchun/py-gdalogr-cookbook-zh/d068a6ce54262f9915c47a41f723b09755fff236/docs/assets/quarter1.png -------------------------------------------------------------------------------- /docs/assets/quarter4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luolingchun/py-gdalogr-cookbook-zh/d068a6ce54262f9915c47a41f723b09755fff236/docs/assets/quarter4.png -------------------------------------------------------------------------------- /docs/assets/quarter6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luolingchun/py-gdalogr-cookbook-zh/d068a6ce54262f9915c47a41f723b09755fff236/docs/assets/quarter6.png -------------------------------------------------------------------------------- /docs/assets/quarter9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luolingchun/py-gdalogr-cookbook-zh/d068a6ce54262f9915c47a41f723b09755fff236/docs/assets/quarter9.png -------------------------------------------------------------------------------- /docs/css/img.css: -------------------------------------------------------------------------------- 1 | 2 | p img { 3 | box-shadow: 0 0 10px #333743f0; 4 | } 5 | 6 | .md-header { 7 | background-image: linear-gradient(to right, #0250c5 0%, #d43f8d 100%); 8 | opacity: 0.9; 9 | } -------------------------------------------------------------------------------- /docs/images/logo-blue.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/images/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 2 | --8<-- "README.md" -------------------------------------------------------------------------------- /docs/一般使用.md: -------------------------------------------------------------------------------- 1 | # GDAL/OGR一般使用 2 | 3 | ## 检测安装 4 | 5 | ```python 6 | from osgeo import gdal 7 | ``` 8 | 9 | ## 查看版本 10 | 11 | ```python 12 | gdal.VersionInfo('VERSION_NUM') 13 | 14 | # '2040100' 15 | ``` 16 | 17 | ## 开启python异常 18 | 19 | 默认情况下,发生错误时,GDAL/OGR Python绑定不会引发异常。相反,它们返回错误值(例如None),并将错误消息写入sys.stdout。你可以通过调用UseExceptions()函数来开启异常: 20 | 21 | ```python 22 | from osgeo import gdal 23 | 24 | # 开启异常 25 | gdal.UseExceptions() 26 | 27 | # 打开不存在的数据集 28 | ds = gdal.Open('test.tif') 29 | 30 | # 开启异常前 31 | ERROR 4: test.tif: No such file or directory 32 | # 开启异常后 33 | RuntimeError Traceback (most recent call last) 34 | in 35 | ----> 1 gdal.Open("test.tif") 36 | 37 | c:\program files\python37\lib\site-packages\osgeo\gdal.py in Open(*args) 38 | 3114 def Open(*args): 39 | 3115 """Open(char const * utf8_path, GDALAccess eAccess) -> Dataset""" 40 | -> 3116 return _gdal.Open(*args) 41 | 3117 42 | 3118 def OpenEx(*args, **kwargs): 43 | 44 | RuntimeError: test.tif: No such file or directory 45 | ``` 46 | 47 | 你可以在运行的任何时候使用以下命令禁用GDAL/OGR异常: 48 | 49 | ```python 50 | gdal.DontUseExceptions() 51 | ``` 52 | 53 | ## 安装GDAL OGR错误处理 54 | 55 | 安装GDAL错误处理程序功能,以捕获GDAL错误、类和消息。仅适用于GDAL 1.10以上的版本。 56 | 57 | ```python 58 | from osgeo import ogr, osr, gdal 59 | 60 | # GDAL错误处理方法 61 | def gdal_error_handler(err_class, err_num, err_msg): 62 | errtype = { 63 | gdal.CE_None:'None', 64 | gdal.CE_Debug:'Debug', 65 | gdal.CE_Warning:'Warning', 66 | gdal.CE_Failure:'Failure', 67 | gdal.CE_Fatal:'Fatal' 68 | } 69 | err_msg = err_msg.replace('\n',' ') 70 | err_class = errtype.get(err_class, 'None') 71 | print('Error Number: %s' % (err_num)) 72 | print('Error Type: %s' % (err_class)) 73 | print('Error Message: %s' % (err_msg)) 74 | 75 | if __name__=='__main__': 76 | 77 | # 安装错误处理 78 | gdal.PushErrorHandler(gdal_error_handler) 79 | 80 | # 抛出一个假的错误 81 | gdal.Error(1, 2, 'test error') 82 | 83 | # 卸载错误处理 84 | gdal.PopErrorHandler() 85 | ``` 86 | 87 | -------------------------------------------------------------------------------- /docs/几何.md: -------------------------------------------------------------------------------- 1 | # 几何 2 | 3 | ## 创建点 4 | 5 | ```python 6 | from osgeo import ogr 7 | point = ogr.Geometry(ogr.wkbPoint) 8 | point.AddPoint(1198054.34, 648493.09) 9 | print(point.ExportToWkt()) 10 | ``` 11 | 12 | ## 创建线 13 | 14 | ```python 15 | from osgeo import ogr 16 | line = ogr.Geometry(ogr.wkbLineString) 17 | line.AddPoint(1116651.439379124, 637392.6969887456) 18 | line.AddPoint(1188804.0108498496, 652655.7409537067) 19 | line.AddPoint(1226730.3625203592, 634155.0816022386) 20 | line.AddPoint(1281307.30760719, 636467.6640211721) 21 | print(line.ExportToWkt()) 22 | ``` 23 | 24 | ## 创建多边形 25 | 26 | ```python 27 | from osgeo import ogr 28 | 29 | # 创建环 30 | ring = ogr.Geometry(ogr.wkbLinearRing) 31 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 32 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 33 | ring.AddPoint(1214704.933941905, 641092.8288590391) 34 | ring.AddPoint(1228580.428455506, 682719.3123998424) 35 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 36 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 37 | 38 | # 创建多边形 39 | poly = ogr.Geometry(ogr.wkbPolygon) 40 | poly.AddGeometry(ring) 41 | 42 | print(poly.ExportToWkt()) 43 | ``` 44 | 45 | ## 创建带洞的多边形 46 | 47 | ```python 48 | from osgeo import ogr 49 | 50 | # 创建内环 51 | outRing = ogr.Geometry(ogr.wkbLinearRing) 52 | outRing.AddPoint(1154115.274565847, 686419.4442701361) 53 | outRing.AddPoint(1154115.274565847, 653118.2574374934) 54 | outRing.AddPoint(1165678.1866605144, 653118.2574374934) 55 | outRing.AddPoint(1165678.1866605144, 686419.4442701361) 56 | outRing.AddPoint(1154115.274565847, 686419.4442701361) 57 | 58 | # 创建外环 59 | innerRing = ogr.Geometry(ogr.wkbLinearRing) 60 | innerRing.AddPoint(1149490.1097279799, 691044.6091080031) 61 | innerRing.AddPoint(1149490.1097279799, 648030.5761158396) 62 | innerRing.AddPoint(1191579.1097525698, 648030.5761158396) 63 | innerRing.AddPoint(1191579.1097525698, 691044.6091080031) 64 | innerRing.AddPoint(1149490.1097279799, 691044.6091080031) 65 | 66 | # 创建多边形 67 | poly = ogr.Geometry(ogr.wkbPolygon) 68 | poly.AddGeometry(outRing) 69 | poly.AddGeometry(innerRing) 70 | 71 | print(poly.ExportToWkt()) 72 | ``` 73 | 74 | ## 创建多部件点 75 | 76 | ```python 77 | from osgeo import ogr 78 | 79 | multipoint = ogr.Geometry(ogr.wkbMultiPoint) 80 | 81 | point1 = ogr.Geometry(ogr.wkbPoint) 82 | point1.AddPoint(1251243.7361610543, 598078.7958668759) 83 | multipoint.AddGeometry(point1) 84 | 85 | point2 = ogr.Geometry(ogr.wkbPoint) 86 | point2.AddPoint(1240605.8570339603, 601778.9277371694) 87 | multipoint.AddGeometry(point2) 88 | 89 | point3 = ogr.Geometry(ogr.wkbPoint) 90 | point3.AddPoint(1250318.7031934808, 606404.0925750365) 91 | multipoint.AddGeometry(point3) 92 | 93 | print(multipoint.ExportToWkt()) 94 | ``` 95 | 96 | ## 创建多部件线 97 | 98 | ```python 99 | from osgeo import ogr 100 | 101 | multiline = ogr.Geometry(ogr.wkbMultiLineString) 102 | 103 | line1 = ogr.Geometry(ogr.wkbLineString) 104 | line1.AddPoint(1214242.4174581182, 617041.9717021306) 105 | line1.AddPoint(1234593.142744733, 629529.9167643716) 106 | multiline.AddGeometry(line1) 107 | 108 | line1 = ogr.Geometry(ogr.wkbLineString) 109 | line1.AddPoint(1184641.3624957693, 626754.8178616514) 110 | line1.AddPoint(1219792.6152635587, 606866.6090588232) 111 | multiline.AddGeometry(line1) 112 | 113 | print(multiline.ExportToWkt()) 114 | ``` 115 | 116 | ## 创建多部件多边形 117 | 118 | ```python 119 | from osgeo import ogr 120 | 121 | multipolygon = ogr.Geometry(ogr.wkbMultiPolygon) 122 | 123 | # 创建环 #1 124 | ring1 = ogr.Geometry(ogr.wkbLinearRing) 125 | ring1.AddPoint(1204067.0548148106, 634617.5980860253) 126 | ring1.AddPoint(1204067.0548148106, 620742.1035724243) 127 | ring1.AddPoint(1215167.4504256917, 620742.1035724243) 128 | ring1.AddPoint(1215167.4504256917, 634617.5980860253) 129 | ring1.AddPoint(1204067.0548148106, 634617.5980860253) 130 | 131 | # 创建多边形 #1 132 | poly1 = ogr.Geometry(ogr.wkbPolygon) 133 | poly1.AddGeometry(ring1) 134 | multipolygon.AddGeometry(poly1) 135 | 136 | # 创建环 #2 137 | ring2 = ogr.Geometry(ogr.wkbLinearRing) 138 | ring2.AddPoint(1179553.6811741155, 647105.5431482664) 139 | ring2.AddPoint(1179553.6811741155, 626292.3013778647) 140 | ring2.AddPoint(1194354.20865529, 626292.3013778647) 141 | ring2.AddPoint(1194354.20865529, 647105.5431482664) 142 | ring2.AddPoint(1179553.6811741155, 647105.5431482664) 143 | 144 | # 创建多边形 #2 145 | poly2 = ogr.Geometry(ogr.wkbPolygon) 146 | poly2.AddGeometry(ring2) 147 | multipolygon.AddGeometry(poly2) 148 | 149 | print(multipolygon.ExportToWkt()) 150 | ``` 151 | 152 | ## 创建几何集合 153 | 154 | ```python 155 | from osgeo import ogr 156 | 157 | # 创建几何集合 158 | geomcol = ogr.Geometry(ogr.wkbGeometryCollection) 159 | 160 | # 添加点 161 | point = ogr.Geometry(ogr.wkbPoint) 162 | point.AddPoint(-122.23, 47.09) 163 | geomcol.AddGeometry(point) 164 | 165 | # 添加线 166 | line = ogr.Geometry(ogr.wkbLineString) 167 | line.AddPoint(-122.60, 47.14) 168 | line.AddPoint(-122.48, 47.23) 169 | geomcol.AddGeometry(line) 170 | 171 | print(geomcol.ExportToWkt()) 172 | ``` 173 | 174 | ## 从WKT创建几何 175 | 176 | ```python 177 | from osgeo import ogr 178 | 179 | wkt = "POINT (1120351.5712494177 741921.4223245403)" 180 | point = ogr.CreateGeometryFromWkt(wkt) 181 | print("%d,%d" % (point.GetX(), point.GetY())) 182 | ``` 183 | 184 | ## 从GeoJSON创建几何 185 | 186 | ```python 187 | from osgeo import ogr 188 | 189 | geojson = """{"type":"Point","coordinates":[108420.33,753808.59]}""" 190 | point = ogr.CreateGeometryFromJson(geojson) 191 | print("%d,%d" % (point.GetX(), point.GetY())) 192 | ``` 193 | 194 | ## 从GML创建几何 195 | 196 | ```python 197 | from osgeo import ogr 198 | 199 | gml = """108420.33,753808.59""" 200 | point = ogr.CreateGeometryFromGML(gml) 201 | print("%d,%d" % (point.GetX(), point.GetY())) 202 | ``` 203 | 204 | ## 从WKB创建几何 205 | 206 | ```python 207 | from osgeo import ogr 208 | from base64 import b64decode 209 | 210 | wkb = b64decode("AIAAAAFBMkfmVwo9cUEjylouFHrhAAAAAAAAAAA=") 211 | point = ogr.CreateGeometryFromWkb(wkb) 212 | print("%d,%d" % (point.GetX(), point.GetY())) 213 | ``` 214 | 215 | ## 计算点的个数 216 | 217 | ```python 218 | from osgeo import ogr 219 | 220 | wkt = "LINESTRING (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 221 | geom = ogr.CreateGeometryFromWkt(wkt) 222 | print("Geometry has %i points" % (geom.GetPointCount())) 223 | ``` 224 | 225 | ## 计算几何个数 226 | 227 | ```python 228 | from osgeo import ogr 229 | 230 | wkt = "MULTIPOINT (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 231 | geom = ogr.CreateGeometryFromWkt(wkt) 232 | print("Geometry has %i geometries" % (geom.GetGeometryCount())) 233 | ``` 234 | 235 | ## 迭代几何 236 | 237 | ```python 238 | from osgeo import ogr 239 | 240 | wkt = "MULTIPOINT (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 241 | geom = ogr.CreateGeometryFromWkt(wkt) 242 | for i in range(0, geom.GetGeometryCount()): 243 | g = geom.GetGeometryRef(i) 244 | print("%i). %s" %(i, g.ExportToWkt())) 245 | ``` 246 | 247 | ## 迭代点 248 | 249 | ```python 250 | from osgeo import ogr 251 | 252 | wkt = "LINESTRING (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 253 | geom = ogr.CreateGeometryFromWkt(wkt) 254 | for i in range(0, geom.GetPointCount()): 255 | # GetPoint 返回一个元俄日不是一个Geometry 256 | pt = geom.GetPoint(i) 257 | print("%i). POINT (%d %d)" %(i, pt[0], pt[1])) 258 | ``` 259 | 260 | ## 几何缓冲区 261 | 262 | ```python 263 | from osgeo import ogr 264 | 265 | wkt = "POINT (1198054.34 648493.09)" 266 | pt = ogr.CreateGeometryFromWkt(wkt) 267 | bufferDistance = 500 268 | poly = pt.Buffer(bufferDistance) 269 | print("%s buffered by %d is %s" % (pt.ExportToWkt(), bufferDistance, poly.ExportToWkt())) 270 | ``` 271 | 272 | ## 计算包围盒 273 | 274 | ```python 275 | from osgeo import ogr 276 | 277 | wkt = "LINESTRING (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 278 | geom = ogr.CreateGeometryFromWkt(wkt) 279 | # GetEnvelope 饭hi一个元组 (minX, maxX, minY, maxY) 280 | env = geom.GetEnvelope() 281 | print("minX: %d, minY: %d, maxX: %d, maxY: %d" %(env[0],env[2],env[1],env[3])) 282 | ``` 283 | 284 | ## 计算面积 285 | 286 | ```python 287 | from osgeo import ogr 288 | 289 | wkt = "POLYGON ((1162440.5712740074 672081.4332727483, 1162440.5712740074 647105.5431482664, 1195279.2416228633 647105.5431482664, 1195279.2416228633 672081.4332727483, 1162440.5712740074 672081.4332727483))" 290 | poly = ogr.CreateGeometryFromWkt(wkt) 291 | print("Area = %d" % poly.GetArea()) 292 | ``` 293 | 294 | ## 计算长度 295 | 296 | ```python 297 | from osgeo import ogr 298 | 299 | wkt = "LINESTRING (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)" 300 | geom = ogr.CreateGeometryFromWkt(wkt) 301 | print("Length = %d" % geom.Length()) 302 | ``` 303 | 304 | ## 获得几何类型 305 | 306 | ```python 307 | from osgeo import ogr 308 | 309 | wkts = [ 310 | "POINT (1198054.34 648493.09)", 311 | "LINESTRING (1181866.263593049 615654.4222507705, 1205917.1207499576 623979.7189589312, 1227192.8790041457 643405.4112779726, 1224880.2965852122 665143.6860159477)", 312 | "POLYGON ((1162440.5712740074 672081.4332727483, 1162440.5712740074 647105.5431482664, 1195279.2416228633 647105.5431482664, 1195279.2416228633 672081.4332727483, 1162440.5712740074 672081.4332727483))" 313 | ] 314 | 315 | for wkt in wkts: 316 | geom = ogr.CreateGeometryFromWkt(wkt) 317 | print(geom.GetGeometryName()) 318 | ``` 319 | 320 | ## 计算几何相交 321 | 322 | ```python 323 | from osgeo import ogr 324 | 325 | wkt1 = "POLYGON ((1208064.271243039 624154.6783778917, 1208064.271243039 601260.9785661874, 1231345.9998651114 601260.9785661874, 1231345.9998651114 624154.6783778917, 1208064.271243039 624154.6783778917))" 326 | wkt2 = "POLYGON ((1199915.6662253144 633079.3410163528, 1199915.6662253144 614453.958118695, 1219317.1067437078 614453.958118695, 1219317.1067437078 633079.3410163528, 1199915.6662253144 633079.3410163528)))" 327 | 328 | poly1 = ogr.CreateGeometryFromWkt(wkt1) 329 | poly2 = ogr.CreateGeometryFromWkt(wkt2) 330 | 331 | intersection = poly1.Intersection(poly2) 332 | 333 | print(intersection.ExportToWkt()) 334 | ``` 335 | 336 | ## 计算几何并集 337 | 338 | ```python 339 | from osgeo import ogr 340 | 341 | wkt1 = "POLYGON ((1208064.271243039 624154.6783778917, 1208064.271243039 601260.9785661874, 1231345.9998651114 601260.9785661874, 1231345.9998651114 624154.6783778917, 1208064.271243039 624154.6783778917))" 342 | wkt2 = "POLYGON ((1199915.6662253144 633079.3410163528, 1199915.6662253144 614453.958118695, 1219317.1067437078 614453.958118695, 1219317.1067437078 633079.3410163528, 1199915.6662253144 633079.3410163528)))" 343 | 344 | poly1 = ogr.CreateGeometryFromWkt(wkt1) 345 | poly2 = ogr.CreateGeometryFromWkt(wkt2) 346 | 347 | union = poly1.Union(poly2) 348 | 349 | print(poly1) 350 | print(poly2) 351 | print(union.ExportToWkt()) 352 | ``` 353 | 354 | ## 输出几何到GeoJSON 355 | 356 | 有两个选项可从几何图形创建GeoJSON。 357 | 358 | 你可以创建一个新的GeoJSON文件,也可以直接将几何图形导出到Json并进行打印,这两个选项将在下面说明。 359 | 360 | ```python 361 | from osgeo import ogr 362 | 363 | # 创建测试多边形 364 | ring = ogr.Geometry(ogr.wkbLinearRing) 365 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 366 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 367 | ring.AddPoint(1214704.933941905, 641092.8288590391) 368 | ring.AddPoint(1228580.428455506, 682719.3123998424) 369 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 370 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 371 | poly = ogr.Geometry(ogr.wkbPolygon) 372 | poly.AddGeometry(ring) 373 | 374 | # 创建输出驱动 375 | outDriver = ogr.GetDriverByName('GeoJSON') 376 | 377 | # 创建输出GeoJSON 378 | outDataSource = outDriver.CreateDataSource('test.geojson') 379 | outLayer = outDataSource.CreateLayer('test.geojson', geom_type=ogr.wkbPolygon ) 380 | 381 | # 创建要素定义 382 | featureDefn = outLayer.GetLayerDefn() 383 | 384 | # 创建新要素 385 | outFeature = ogr.Feature(featureDefn) 386 | 387 | # 设置新几何 388 | outFeature.SetGeometry(poly) 389 | 390 | # 添加要素到图层 391 | outLayer.CreateFeature(outFeature) 392 | 393 | # 释放要素 394 | outFeature = None 395 | 396 | # 保存关闭数据源 397 | outDataSource = None 398 | ``` 399 | 400 | ```python 401 | from osgeo import ogr 402 | 403 | # 创建测试多边形 404 | ring = ogr.Geometry(ogr.wkbLinearRing) 405 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 406 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 407 | ring.AddPoint(1214704.933941905, 641092.8288590391) 408 | ring.AddPoint(1228580.428455506, 682719.3123998424) 409 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 410 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 411 | poly = ogr.Geometry(ogr.wkbPolygon) 412 | poly.AddGeometry(ring) 413 | 414 | geojson = poly.ExportToJson() 415 | print(geojson) 416 | ``` 417 | 418 | ## 输出几何到WKT 419 | 420 | ```python 421 | from osgeo import ogr 422 | 423 | # 创建测试几何 424 | ring = ogr.Geometry(ogr.wkbLinearRing) 425 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 426 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 427 | ring.AddPoint(1214704.933941905, 641092.8288590391) 428 | ring.AddPoint(1228580.428455506, 682719.3123998424) 429 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 430 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 431 | geom_poly = ogr.Geometry(ogr.wkbPolygon) 432 | geom_poly.AddGeometry(ring) 433 | 434 | # 输出几何到WKT 435 | wkt = geom_poly.ExportToWkt() 436 | print(wkt) 437 | ``` 438 | 439 | ## 输出几何到KML 440 | 441 | ```python 442 | from osgeo import ogr 443 | 444 | # 创建测试几何 445 | ring = ogr.Geometry(ogr.wkbLinearRing) 446 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 447 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 448 | ring.AddPoint(1214704.933941905, 641092.8288590391) 449 | ring.AddPoint(1228580.428455506, 682719.3123998424) 450 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 451 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 452 | geom_poly = ogr.Geometry(ogr.wkbPolygon) 453 | geom_poly.AddGeometry(ring) 454 | 455 | kml = geom_poly.ExportToKML() 456 | print(kml) 457 | ``` 458 | 459 | ## 输出几何到WKB 460 | 461 | ```python 462 | from osgeo import ogr 463 | 464 | # 创建测试几何 465 | ring = ogr.Geometry(ogr.wkbLinearRing) 466 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 467 | ring.AddPoint(1161053.0218226474, 667456.2684348812) 468 | ring.AddPoint(1214704.933941905, 641092.8288590391) 469 | ring.AddPoint(1228580.428455506, 682719.3123998424) 470 | ring.AddPoint(1218405.0658121984, 721108.1805541387) 471 | ring.AddPoint(1179091.1646903288, 712782.8838459781) 472 | geom_poly = ogr.Geometry(ogr.wkbPolygon) 473 | geom_poly.AddGeometry(ring) 474 | 475 | # 输出几何到WKB 476 | wkb = geom_poly.ExportToWkb() 477 | print(wkb) 478 | ``` 479 | 480 | ## 强制多边形到多部件多边形 481 | 482 | ```python 483 | from osgeo import ogr 484 | 485 | # 创建测试几何 486 | poly_wkt= "POLYGON ((1179091.164690328761935 712782.883845978067257,1161053.021822647424415 667456.268434881232679,1214704.933941904921085 641092.828859039116651,1228580.428455505985767 682719.312399842427112,1218405.065812198445201 721108.180554138729349,1179091.164690328761935 712782.883845978067257))" 487 | geom_poly = ogr.CreateGeometryFromWkt(poly_wkt) 488 | 489 | # 强制多边形到多部件多边形 490 | if geom_poly.GetGeometryType() == ogr.wkbPolygon: 491 | geom_poly = ogr.ForceToMultiPolygon(geom_poly) 492 | # 如果迭代要素只是为了更新几何(geometry),可以使用feature.SetGeometryDirectly(geom_poly) 493 | 494 | # 输出几何到WKT 495 | wkt = geom_poly.ExportToWkt() 496 | print(wkt) 497 | ``` 498 | 499 | ## 四等分多边形并创建质心 500 | 501 | ```python 502 | from osgeo import ogr 503 | 504 | # 创建多边形 505 | poly_Wkt= "POLYGON((-107.42631019589980212 40.11971708125970082,-107.42455436683293613 40.12061219666851741,-107.42020981542387403 40.12004414402532859,-107.41789122063043749 40.12149008687303819,-107.41419947746419439 40.11811617239460048,-107.41915181585792993 40.11761695654455906,-107.41998470913324581 40.11894245264452508,-107.42203317637793702 40.1184088144647788,-107.42430674991324224 40.1174448122981957,-107.42430674991324224 40.1174448122981957,-107.42631019589980212 40.11971708125970082))" 506 | geom_poly = ogr.CreateGeometryFromWkt(poly_Wkt) 507 | ``` 508 | 509 | ![quarter1](./assets/quarter1.png) 510 | 511 | ```python 512 | # Create 4 square polygons 513 | geom_poly_envelope = geom_poly.GetEnvelope() 514 | minX = geom_poly_envelope[0] 515 | minY = geom_poly_envelope[2] 516 | maxX = geom_poly_envelope[1] 517 | maxY = geom_poly_envelope[3] 518 | 519 | ''' 520 | coord0----coord1----coord2 521 | | | | 522 | coord3----coord4----coord5 523 | | | | 524 | coord6----coord7----coord8 525 | ''' 526 | coord0 = minX, maxY 527 | coord1 = minX+(maxX-minX)/2, maxY 528 | coord2 = maxX, maxY 529 | coord3 = minX, minY+(maxY-minY)/2 530 | coord4 = minX+(maxX-minX)/2, minY+(maxY-minY)/2 531 | coord5 = maxX, minY+(maxY-minY)/2 532 | coord6 = minX, minY 533 | coord7 = minX+(maxX-minX)/2, minY 534 | coord8 = maxX, minY 535 | 536 | ringTopLeft = ogr.Geometry(ogr.wkbLinearRing) 537 | ringTopLeft.AddPoint_2D(*coord0) 538 | ringTopLeft.AddPoint_2D(*coord1) 539 | ringTopLeft.AddPoint_2D(*coord4) 540 | ringTopLeft.AddPoint_2D(*coord3) 541 | ringTopLeft.AddPoint_2D(*coord0) 542 | polyTopLeft = ogr.Geometry(ogr.wkbPolygon) 543 | polyTopLeft.AddGeometry(ringTopLeft) 544 | 545 | 546 | ringTopRight = ogr.Geometry(ogr.wkbLinearRing) 547 | ringTopRight.AddPoint_2D(*coord1) 548 | ringTopRight.AddPoint_2D(*coord2) 549 | ringTopRight.AddPoint_2D(*coord5) 550 | ringTopRight.AddPoint_2D(*coord4) 551 | ringTopRight.AddPoint_2D(*coord1) 552 | polyTopRight = ogr.Geometry(ogr.wkbPolygon) 553 | polyTopRight.AddGeometry(ringTopRight) 554 | 555 | 556 | ringBottomLeft = ogr.Geometry(ogr.wkbLinearRing) 557 | ringBottomLeft.AddPoint_2D(*coord3) 558 | ringBottomLeft.AddPoint_2D(*coord4) 559 | ringBottomLeft.AddPoint_2D(*coord7) 560 | ringBottomLeft.AddPoint_2D(*coord6) 561 | ringBottomLeft.AddPoint_2D(*coord3) 562 | polyBottomLeft = ogr.Geometry(ogr.wkbPolygon) 563 | polyBottomLeft.AddGeometry(ringBottomLeft) 564 | 565 | 566 | ringBottomRight = ogr.Geometry(ogr.wkbLinearRing) 567 | ringBottomRight.AddPoint_2D(*coord4) 568 | ringBottomRight.AddPoint_2D(*coord5) 569 | ringBottomRight.AddPoint_2D(*coord8) 570 | ringBottomRight.AddPoint_2D(*coord7) 571 | ringBottomRight.AddPoint_2D(*coord4) 572 | polyBottomRight = ogr.Geometry(ogr.wkbPolygon) 573 | polyBottomRight.AddGeometry(ringBottomRight) 574 | ``` 575 | 576 | ![quarter4](./assets/quarter4.png) 577 | 578 | ```python 579 | # 对四个方格多边形求交 580 | quaterPolyTopLeft = polyTopLeft.Intersection(geom_poly) 581 | quaterPolyTopRight = polyTopRight.Intersection(geom_poly) 582 | quaterPolyBottomLeft = polyBottomLeft.Intersection(geom_poly) 583 | quaterPolyBottomRight = polyBottomRight.Intersection(geom_poly) 584 | ``` 585 | 586 | ![_images/quarter6.png](./assets/quarter6.png) 587 | 588 | ```python 589 | # 创建质心 590 | centroidTopLeft = quaterPolyTopLeft.Centroid() 591 | centroidTopRight = quaterPolyTopRight.Centroid() 592 | centroidBottomLeft = quaterPolyBottomLeft.Centroid() 593 | centroidBottomRight = quaterPolyBottomRight.Centroid() 594 | ``` 595 | 596 | ![_images/quarter9.png](./assets/quarter9.png) -------------------------------------------------------------------------------- /docs/投影.md: -------------------------------------------------------------------------------- 1 | # 投影 2 | 3 | ## 创建投影 4 | 5 | ```python 6 | from osgeo import osr 7 | spatialRef = osr.SpatialReference() 8 | spatialRef.ImportFromEPSG(4326) #WGS84 9 | ``` 10 | 11 | ## 重投影 12 | 13 | ```python 14 | from osgeo import ogr 15 | from osgeo import osr 16 | 17 | source = osr.SpatialReference() 18 | source.ImportFromEPSG(2927) 19 | 20 | target = osr.SpatialReference() 21 | target.ImportFromEPSG(4326) 22 | 23 | transform = osr.CoordinateTransformation(source, target) 24 | 25 | point = ogr.CreateGeometryFromWkt("POINT (1120351.57 741921.42)") 26 | point.Transform(transform) 27 | 28 | print (point.ExportToWkt()) 29 | ``` 30 | 31 | ## 获取投影 32 | 33 | ```python 34 | from osgeo import ogr, osr 35 | driver = ogr.GetDriverByName('ESRI Shapefile') 36 | dataset = driver.Open(r'./data/test.shp') 37 | 38 | # 图层 39 | layer = dataset.GetLayer() 40 | spatialRef = layer.GetSpatialRef() 41 | # 几何 42 | feature = layer.GetNextFeature() 43 | geom = feature.GetGeometryRef() 44 | spatialRef = geom.GetSpatialReference() 45 | ``` 46 | 47 | ## 重投影图层 48 | 49 | ```python 50 | from osgeo import ogr, osr 51 | import os 52 | 53 | driver = ogr.GetDriverByName('ESRI Shapefile') 54 | 55 | # 输入空间参考 56 | inSpatialRef = osr.SpatialReference() 57 | inSpatialRef.ImportFromEPSG(2927) 58 | 59 | # 输出空间参考 60 | outSpatialRef = osr.SpatialReference() 61 | outSpatialRef.ImportFromEPSG(4326) 62 | 63 | # 创建坐标转换 64 | coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef) 65 | 66 | # 输入图层 67 | inDataSet = driver.Open(r'./data/test.shp') 68 | inLayer = inDataSet.GetLayer() 69 | 70 | # 创建输出图层 71 | outputShapefile = r'./data/test_4326.shp' 72 | if os.path.exists(outputShapefile): 73 | driver.DeleteDataSource(outputShapefile) 74 | outDataSet = driver.CreateDataSource(outputShapefile) 75 | outLayer = outDataSet.CreateLayer( 76 | "test_4326", 77 | geom_type=ogr.wkbMultiPolygon, 78 | srs=outSpatialRef # 输出prj文件 79 | ) 80 | 81 | # 添加字段 82 | inLayerDefn = inLayer.GetLayerDefn() 83 | for i in range(0, inLayerDefn.GetFieldCount()): 84 | fieldDefn = inLayerDefn.GetFieldDefn(i) 85 | outLayer.CreateField(fieldDefn) 86 | 87 | outLayerDefn = outLayer.GetLayerDefn() 88 | 89 | # 遍历要素 90 | inFeature = inLayer.GetNextFeature() 91 | while inFeature: 92 | # 获取几何 93 | geom = inFeature.GetGeometryRef() 94 | # 重投影几何 95 | geom.Transform(coordTrans) 96 | # 创建要素 97 | outFeature = ogr.Feature(outLayerDefn) 98 | # 设置几何、属性 99 | outFeature.SetGeometry(geom) 100 | for i in range(0, outLayerDefn.GetFieldCount()): 101 | outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), inFeature.GetField(i)) 102 | # 添加要素 103 | outLayer.CreateFeature(outFeature) 104 | # 取消引用 105 | outFeature = None 106 | inFeature = inLayer.GetNextFeature() 107 | 108 | # 保存并关闭 109 | inDataSet = None 110 | outDataSet = None 111 | ``` 112 | 113 | ## 输出投影 114 | 115 | ```python 116 | from osgeo import ogr, osr 117 | driver = ogr.GetDriverByName('ESRI Shapefile') 118 | dataset = driver.Open(r'./data/test_4326.shp') 119 | layer = dataset.GetLayer() 120 | spatialRef = layer.GetSpatialRef() 121 | 122 | spatialRef.ExportToWkt() 123 | spatialRef.ExportToPrettyWkt() 124 | spatialRef.ExportToPCI() 125 | spatialRef.ExportToUSGS() 126 | spatialRef.ExportToXML() 127 | ``` 128 | 129 | ## 创建ESRI投影文件 130 | 131 | ```python 132 | from osgeo import ogr, osr 133 | 134 | spatialRef = osr.SpatialReference() 135 | spatialRef.ImportFromEPSG(26912) 136 | 137 | spatialRef.MorphToESRI() 138 | file = open('yourshpfile.prj', 'w') 139 | file.write(spatialRef.ExportToWkt()) 140 | file.close() 141 | ``` 142 | 143 | -------------------------------------------------------------------------------- /docs/栅格图层.md: -------------------------------------------------------------------------------- 1 | # 栅格图层 2 | 3 | ## 关闭栅格数据 4 | 5 | ```python 6 | from osgeo import gdal 7 | 8 | # 打开数据 9 | ds = gdal.Open('test.tif') 10 | 11 | # 关闭数据(非必须) 12 | ds = None 13 | ``` 14 | 15 | ## 获取元数据 16 | 17 | ``` 18 | from osgeo import gdal 19 | gtif = gdal.Open( "merge.tif" ) 20 | print (gtif.GetMetadata()) 21 | ``` 22 | 23 | ## 波段融合 24 | 25 | ```python 26 | from osgeo import gdal 27 | # 打开数据 28 | ds1=gdal.Open("LM51130321998341HAJ00_B1.TIF") 29 | ds2=gdal.Open("LM51130321998341HAJ00_B2.TIF") 30 | ds3=gdal.Open("LM51130321998341HAJ00_B3.TIF") 31 | ds4=gdal.Open("LM51130321998341HAJ00_B4.TIF") 32 | # 获取波段 33 | b1=ds1.GetRasterBand(1) 34 | b2=ds1.GetRasterBand(1) 35 | b3=ds1.GetRasterBand(1) 36 | b4=ds1.GetRasterBand(1) 37 | # 创建数据 38 | driver=gdal.GetDriverByName("GTiff") 39 | out_ds=driver.Create('merge.tif',ds1.RasterXSize,ds1.RasterYSize,4,gdal.GDT_Byte) 40 | # 设置坐标和投影 41 | out_ds.SetGeoTransform(ds1.GetGeoTransform()) 42 | out_ds.SetProjection(ds1.GetProjection()) 43 | 44 | ob1=out_ds.GetRasterBand(1) 45 | ob2=out_ds.GetRasterBand(2) 46 | ob3=out_ds.GetRasterBand(3) 47 | ob4=out_ds.GetRasterBand(4) 48 | # 写入数据 49 | ob1.WriteArray(b1.ReadAsArray()) 50 | ob2.WriteArray(b2.ReadAsArray()) 51 | ob3.WriteArray(b3.ReadAsArray()) 52 | ob4.WriteArray(b4.ReadAsArray()) 53 | 54 | out_ds=None 55 | ``` 56 | 57 | ## 获取波段 58 | 59 | ```python 60 | from osgeo import gdal 61 | import sys 62 | # 允许python异常 63 | gdal.UseExceptions() 64 | 65 | try: 66 | src_ds = gdal.Open( "merge.tif" ) 67 | except RuntimeError as e: 68 | print(e) 69 | sys.exit(1) 70 | 71 | try: 72 | srcband = src_ds.GetRasterBand(1) 73 | except RuntimeError as e: 74 | # 试一下 GetRasterBand(10) 75 | print(e) 76 | sys.exit(1) 77 | ``` 78 | 79 | ## 遍历波段 80 | 81 | ```python 82 | from osgeo import gdal 83 | import sys 84 | 85 | src_ds = gdal.Open( "merge.tif" ) 86 | 87 | print ("波段个数: ", src_ds.RasterCount) 88 | for band in range( src_ds.RasterCount ): 89 | band += 1 90 | print ("获取波段: ", band) 91 | srcband = src_ds.GetRasterBand(band) 92 | if srcband is None: 93 | continue 94 | 95 | stats = srcband.GetStatistics( True, True ) 96 | if stats is None: 97 | continue 98 | 99 | print ("[ STATS ] = Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f" % ( \ 100 | stats[0], stats[1], stats[2], stats[3] )) 101 | ``` 102 | 103 | ## 获取波段信息 104 | 105 | ```python 106 | from osgeo import gdal 107 | import sys 108 | gdal.UseExceptions() 109 | 110 | 111 | def main( band_num, input_file ): 112 | src_ds = gdal.Open( input_file ) 113 | 114 | try: 115 | srcband = src_ds.GetRasterBand(band_num) 116 | except RuntimeError as e: 117 | print( e) 118 | sys.exit(1) 119 | 120 | 121 | print ("[ NO DATA VALUE ] = ", srcband.GetNoDataValue()) 122 | print ("[ MIN ] = ", srcband.GetMinimum()) 123 | print ("[ MAX ] = ", srcband.GetMaximum()) 124 | print ("[ SCALE ] = ", srcband.GetScale()) 125 | print( "[ UNIT TYPE ] = ", srcband.GetUnitType()) 126 | ctable = srcband.GetColorTable() 127 | 128 | if ctable is None: 129 | print ('No ColorTable found') 130 | sys.exit(1) 131 | 132 | print ("[ COLOR TABLE COUNT ] = ", ctable.GetCount()) 133 | for i in range( 0, ctable.GetCount() ): 134 | entry = ctable.GetColorEntry( i ) 135 | if not entry: 136 | continue 137 | print ("[ COLOR ENTRY RGB ] = ", ctable.GetColorEntryAsRGB( i, entry )) 138 | 139 | main( 1,"merge.tif" ) 140 | ``` 141 | 142 | ## 多边形化栅格波段 143 | 144 | ```python 145 | from osgeo import gdal, ogr 146 | import sys 147 | 148 | gdal.UseExceptions() 149 | 150 | src_ds = gdal.Open( "test.tif" ) 151 | 152 | srcband = src_ds.GetRasterBand(3) 153 | 154 | dst_layername = "POLYGONIZED_STUFF" 155 | drv = ogr.GetDriverByName("ESRI Shapefile") 156 | dst_ds = drv.CreateDataSource( dst_layername + ".shp" ) 157 | dst_layer = dst_ds.CreateLayer(dst_layername, srs = None ) 158 | 159 | gdal.Polygonize( srcband, None, dst_layer, -1, [], callback=None ) 160 | ``` 161 | 162 | ## 栅格化矢量数据 163 | 164 | ```python 165 | from osgeo import gdal, ogr 166 | 167 | # 定义像素大小和无效值 168 | pixel_size = 25 169 | NoData_value = -9999 170 | 171 | vector_fn = 'test.shp' 172 | 173 | raster_fn = 'test.tif' 174 | 175 | # 打开数据并读取范围 176 | source_ds = ogr.Open(vector_fn) 177 | source_layer = source_ds.GetLayer() 178 | x_min, x_max, y_min, y_max = source_layer.GetExtent() 179 | 180 | x_res = int((x_max - x_min) / pixel_size) 181 | y_res = int((y_max - y_min) / pixel_size) 182 | target_ds = gdal.GetDriverByName('GTiff').Create(raster_fn, x_res, y_res, 1, gdal.GDT_Byte) 183 | target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size)) 184 | band = target_ds.GetRasterBand(1) 185 | band.SetNoDataValue(NoData_value) 186 | 187 | # 栅格化 188 | gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[0]) 189 | ``` 190 | 191 | ## 用shapefile裁剪栅格 192 | 193 | ```python 194 | from osgeo import gdal, gdalnumeric, ogr, osr 195 | from PIL import Image, ImageDraw 196 | import os, sys 197 | gdal.UseExceptions() 198 | 199 | 200 | def imageToArray(i): 201 | """ 202 | Image转换为数组. 203 | """ 204 | a=gdalnumeric.fromstring(i.tostring(),'b') 205 | a.shape=i.im.size[1], i.im.size[0] 206 | return a 207 | 208 | def arrayToImage(a): 209 | """ 210 | 数组转换为Image. 211 | """ 212 | i=Image.fromstring('L',(a.shape[1],a.shape[0]), 213 | (a.astype('b')).tostring()) 214 | return i 215 | 216 | def world2Pixel(geoMatrix, x, y): 217 | """ 218 | 用地理仿射变换计算像素坐标 219 | """ 220 | ulX = geoMatrix[0] 221 | ulY = geoMatrix[3] 222 | xDist = geoMatrix[1] 223 | yDist = geoMatrix[5] 224 | rtnX = geoMatrix[2] 225 | rtnY = geoMatrix[4] 226 | pixel = int((x - ulX) / xDist) 227 | line = int((ulY - y) / xDist) 228 | return (pixel, line) 229 | 230 | # 231 | # EDIT: this is basically an overloaded 232 | # version of the gdal_array.OpenArray passing in xoff, yoff explicitly 233 | # so we can pass these params off to CopyDatasetInfo 234 | # 235 | def OpenArray( array, prototype_ds = None, xoff=0, yoff=0 ): 236 | ds = gdal.Open( gdalnumeric.GetArrayFilename(array) ) 237 | 238 | if ds is not None and prototype_ds is not None: 239 | if type(prototype_ds).__name__ == 'str': 240 | prototype_ds = gdal.Open( prototype_ds ) 241 | if prototype_ds is not None: 242 | gdalnumeric.CopyDatasetInfo( prototype_ds, ds, xoff=xoff, yoff=yoff ) 243 | return ds 244 | 245 | def histogram(a, bins=range(0,256)): 246 | """ 247 | Histogram function for multi-dimensional array. 248 | a = array 249 | bins = range of numbers to match 250 | """ 251 | fa = a.flat 252 | n = gdalnumeric.searchsorted(gdalnumeric.sort(fa), bins) 253 | n = gdalnumeric.concatenate([n, [len(fa)]]) 254 | hist = n[1:]-n[:-1] 255 | return hist 256 | 257 | def stretch(a): 258 | """ 259 | Performs a histogram stretch on a gdalnumeric array image. 260 | """ 261 | hist = histogram(a) 262 | im = arrayToImage(a) 263 | lut = [] 264 | for b in range(0, len(hist), 256): 265 | # step size 266 | step = reduce(operator.add, hist[b:b+256]) / 255 267 | # create equalization lookup table 268 | n = 0 269 | for i in range(256): 270 | lut.append(n / step) 271 | n = n + hist[i+b] 272 | im = im.point(lut) 273 | return imageToArray(im) 274 | 275 | def main( shapefile_path, raster_path ): 276 | # 读取数据到数组 277 | srcArray = gdalnumeric.LoadFile(raster_path) 278 | 279 | # 获取地理仿射变换 280 | srcImage = gdal.Open(raster_path) 281 | geoTrans = srcImage.GetGeoTransform() 282 | 283 | # 获取矢量图层 284 | shapef = ogr.Open(shapefile_path) 285 | lyr = shapef.GetLayer( os.path.split( os.path.splitext( shapefile_path )[0] )[1] ) 286 | poly = lyr.GetNextFeature() 287 | 288 | # 获取范围 289 | minX, maxX, minY, maxY = lyr.GetExtent() 290 | ulX, ulY = world2Pixel(geoTrans, minX, maxY) 291 | lrX, lrY = world2Pixel(geoTrans, maxX, minY) 292 | 293 | # 计算像素大小 294 | pxWidth = int(lrX - ulX) 295 | pxHeight = int(lrY - ulY) 296 | 297 | clip = srcArray[:, ulY:lrY, ulX:lrX] 298 | 299 | # 300 | # 像素偏移 301 | # 302 | xoffset = ulX 303 | yoffset = ulY 304 | print ("Xoffset, Yoffset = ( %f, %f )" % ( xoffset, yoffset )) 305 | 306 | # 创建新的仿射变换 307 | geoTrans = list(geoTrans) 308 | geoTrans[0] = minX 309 | geoTrans[3] = maxY 310 | 311 | # Map points to pixels for drawing the 312 | # boundary on a blank 8-bit, 313 | # black and white, mask image. 314 | points = [] 315 | pixels = [] 316 | geom = poly.GetGeometryRef() 317 | pts = geom.GetGeometryRef(0) 318 | for p in range(pts.GetPointCount()): 319 | points.append((pts.GetX(p), pts.GetY(p))) 320 | for p in points: 321 | pixels.append(world2Pixel(geoTrans, p[0], p[1])) 322 | rasterPoly = Image.new("L", (pxWidth, pxHeight), 1) 323 | rasterize = ImageDraw.Draw(rasterPoly) 324 | rasterize.polygon(pixels, 0) 325 | mask = imageToArray(rasterPoly) 326 | 327 | # Clip the image using the mask 328 | clip = gdalnumeric.choose(mask, \ 329 | (clip, 0)).astype(gdalnumeric.uint8) 330 | 331 | # This image has 3 bands so we stretch each one to make them 332 | # visually brighter 333 | for i in range(3): 334 | clip[i,:,:] = stretch(clip[i,:,:]) 335 | 336 | # Save new tiff 337 | # 338 | # EDIT: instead of SaveArray, let's break all the 339 | # SaveArray steps out more explicity so 340 | # we can overwrite the offset of the destination 341 | # raster 342 | # 343 | ### the old way using SaveArray 344 | # 345 | # gdalnumeric.SaveArray(clip, "OUTPUT.tif", format="GTiff", prototype=raster_path) 346 | # 347 | ### 348 | # 349 | gtiffDriver = gdal.GetDriverByName( 'GTiff' ) 350 | if gtiffDriver is None: 351 | raise ValueError("Can't find GeoTiff Driver") 352 | gtiffDriver.CreateCopy( "OUTPUT.tif", 353 | OpenArray( clip, prototype_ds=raster_path, xoff=xoffset, yoff=yoffset ) 354 | ) 355 | 356 | # Save as an 8-bit jpeg for an easy, quick preview 357 | clip = clip.astype(gdalnumeric.uint8) 358 | gdalnumeric.SaveArray(clip, "OUTPUT.jpg", format="JPEG") 359 | 360 | gdal.ErrorReset() 361 | 362 | 363 | if __name__ == '__main__': 364 | 365 | # 366 | # example run : $ python clip.py //.shp //.tif 367 | # 368 | if len( sys.argv ) < 2: 369 | print "[ ERROR ] you must two args. 1) the full shapefile path and 2) the full raster path" 370 | sys.exit( 1 ) 371 | 372 | main( sys.argv[1], sys.argv[2] ) 373 | ``` 374 | 375 | ## 区域统计 376 | 377 | ```python 378 | import gdal, ogr, osr, numpy 379 | import sys 380 | 381 | 382 | def zonal_stats(feat, input_zone_polygon, input_value_raster): 383 | 384 | # Open data 385 | raster = gdal.Open(input_value_raster) 386 | shp = ogr.Open(input_zone_polygon) 387 | lyr = shp.GetLayer() 388 | 389 | # Get raster georeference info 390 | transform = raster.GetGeoTransform() 391 | xOrigin = transform[0] 392 | yOrigin = transform[3] 393 | pixelWidth = transform[1] 394 | pixelHeight = transform[5] 395 | 396 | # Reproject vector geometry to same projection as raster 397 | sourceSR = lyr.GetSpatialRef() 398 | targetSR = osr.SpatialReference() 399 | targetSR.ImportFromWkt(raster.GetProjectionRef()) 400 | coordTrans = osr.CoordinateTransformation(sourceSR,targetSR) 401 | feat = lyr.GetNextFeature() 402 | geom = feat.GetGeometryRef() 403 | geom.Transform(coordTrans) 404 | 405 | # Get extent of feat 406 | geom = feat.GetGeometryRef() 407 | if (geom.GetGeometryName() == 'MULTIPOLYGON'): 408 | count = 0 409 | pointsX = []; pointsY = [] 410 | for polygon in geom: 411 | geomInner = geom.GetGeometryRef(count) 412 | ring = geomInner.GetGeometryRef(0) 413 | numpoints = ring.GetPointCount() 414 | for p in range(numpoints): 415 | lon, lat, z = ring.GetPoint(p) 416 | pointsX.append(lon) 417 | pointsY.append(lat) 418 | count += 1 419 | elif (geom.GetGeometryName() == 'POLYGON'): 420 | ring = geom.GetGeometryRef(0) 421 | numpoints = ring.GetPointCount() 422 | pointsX = []; pointsY = [] 423 | for p in range(numpoints): 424 | lon, lat, z = ring.GetPoint(p) 425 | pointsX.append(lon) 426 | pointsY.append(lat) 427 | 428 | else: 429 | sys.exit("ERROR: Geometry needs to be either Polygon or Multipolygon") 430 | 431 | xmin = min(pointsX) 432 | xmax = max(pointsX) 433 | ymin = min(pointsY) 434 | ymax = max(pointsY) 435 | 436 | # Specify offset and rows and columns to read 437 | xoff = int((xmin - xOrigin)/pixelWidth) 438 | yoff = int((yOrigin - ymax)/pixelWidth) 439 | xcount = int((xmax - xmin)/pixelWidth)+1 440 | ycount = int((ymax - ymin)/pixelWidth)+1 441 | 442 | # Create memory target raster 443 | target_ds = gdal.GetDriverByName('MEM').Create('', xcount, ycount, 1, gdal.GDT_Byte) 444 | target_ds.SetGeoTransform(( 445 | xmin, pixelWidth, 0, 446 | ymax, 0, pixelHeight, 447 | )) 448 | 449 | # Create for target raster the same projection as for the value raster 450 | raster_srs = osr.SpatialReference() 451 | raster_srs.ImportFromWkt(raster.GetProjectionRef()) 452 | target_ds.SetProjection(raster_srs.ExportToWkt()) 453 | 454 | # Rasterize zone polygon to raster 455 | gdal.RasterizeLayer(target_ds, [1], lyr, burn_values=[1]) 456 | 457 | # Read raster as arrays 458 | banddataraster = raster.GetRasterBand(1) 459 | dataraster = banddataraster.ReadAsArray(xoff, yoff, xcount, ycount).astype(numpy.float) 460 | 461 | bandmask = target_ds.GetRasterBand(1) 462 | datamask = bandmask.ReadAsArray(0, 0, xcount, ycount).astype(numpy.float) 463 | 464 | # Mask zone of raster 465 | zoneraster = numpy.ma.masked_array(dataraster, numpy.logical_not(datamask)) 466 | 467 | # Calculate statistics of zonal raster 468 | return numpy.average(zoneraster),numpy.mean(zoneraster),numpy.median(zoneraster),numpy.std(zoneraster),numpy.var(zoneraster) 469 | 470 | 471 | def loop_zonal_stats(input_zone_polygon, input_value_raster): 472 | 473 | shp = ogr.Open(input_zone_polygon) 474 | lyr = shp.GetLayer() 475 | featList = range(lyr.GetFeatureCount()) 476 | statDict = {} 477 | 478 | for FID in featList: 479 | feat = lyr.GetFeature(FID) 480 | meanValue = zonal_stats(feat, input_zone_polygon, input_value_raster) 481 | statDict[FID] = meanValue 482 | return statDict 483 | 484 | def main(input_zone_polygon, input_value_raster): 485 | return loop_zonal_stats(input_zone_polygon, input_value_raster) 486 | 487 | 488 | if __name__ == "__main__": 489 | 490 | # 491 | # Returns for each feature a dictionary item (FID) with the statistical values in the following order: Average, Mean, Medain, Standard Deviation, Variance 492 | # 493 | # example run : $ python grid.py .shp xmin xmax ymin ymax gridHeight gridWidth 494 | # 495 | 496 | if len( sys.argv ) != 3: 497 | print "[ ERROR ] you must supply two arguments: input-zone-shapefile-name.shp input-value-raster-name.tif " 498 | sys.exit( 1 ) 499 | print 'Returns for each feature a dictionary item (FID) with the statistical values in the following order: Average, Mean, Medain, Standard Deviation, Variance' 500 | print main( sys.argv[1], sys.argv[2] ) 501 | ``` 502 | 503 | ## 从数组创建栅格 504 | 505 | ```python 506 | import gdal, ogr, os, osr 507 | import numpy as np 508 | 509 | 510 | def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array): 511 | 512 | cols = array.shape[1] 513 | rows = array.shape[0] 514 | originX = rasterOrigin[0] 515 | originY = rasterOrigin[1] 516 | 517 | driver = gdal.GetDriverByName('GTiff') 518 | outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Byte) 519 | outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight)) 520 | outband = outRaster.GetRasterBand(1) 521 | outband.WriteArray(array) 522 | outRasterSRS = osr.SpatialReference() 523 | outRasterSRS.ImportFromEPSG(4326) 524 | outRaster.SetProjection(outRasterSRS.ExportToWkt()) 525 | outband.FlushCache() 526 | 527 | 528 | def main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array): 529 | # 反转数组 530 | reversed_arr = array[::-1] 531 | # 数组转栅格 532 | array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,reversed_arr) 533 | 534 | 535 | if __name__ == "__main__": 536 | rasterOrigin = (-123.25745,45.43013) 537 | pixelWidth = 10 538 | pixelHeight = 10 539 | newRasterfn = 'test.tif' 540 | array = np.array([[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 541 | [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 542 | [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1], 543 | [ 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1], 544 | [ 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1], 545 | [ 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1], 546 | [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1], 547 | [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 548 | [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 549 | [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]) 550 | 551 | 552 | main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array) 553 | ``` 554 | 555 | ## 替换无效值 556 | 557 | ```python 558 | import gdal, ogr, osr, os 559 | import numpy as np 560 | 561 | def raster2array(rasterfn): 562 | raster = gdal.Open(rasterfn) 563 | band = raster.GetRasterBand(1) 564 | return band.ReadAsArray() 565 | 566 | def getNoDataValue(rasterfn): 567 | raster = gdal.Open(rasterfn) 568 | band = raster.GetRasterBand(1) 569 | return band.GetNoDataValue() 570 | 571 | def array2raster(rasterfn,newRasterfn,array): 572 | raster = gdal.Open(rasterfn) 573 | geotransform = raster.GetGeoTransform() 574 | originX = geotransform[0] 575 | originY = geotransform[3] 576 | pixelWidth = geotransform[1] 577 | pixelHeight = geotransform[5] 578 | cols = raster.RasterXSize 579 | rows = raster.RasterYSize 580 | 581 | driver = gdal.GetDriverByName('GTiff') 582 | outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Float32) 583 | outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight)) 584 | outband = outRaster.GetRasterBand(1) 585 | outband.WriteArray(array) 586 | outRasterSRS = osr.SpatialReference() 587 | outRasterSRS.ImportFromWkt(raster.GetProjectionRef()) 588 | outRaster.SetProjection(outRasterSRS.ExportToWkt()) 589 | outband.FlushCache() 590 | 591 | 592 | rasterfn = 'test.tif' 593 | newValue = 0 594 | newRasterfn = 'testNew.tif' 595 | 596 | # 栅格转数组 597 | rasterArray = raster2array(rasterfn) 598 | 599 | # 获取无效值 600 | noDataValue = getNoDataValue(rasterfn) 601 | 602 | # 更新无效值 603 | rasterArray[rasterArray == noDataValue] = newValue 604 | 605 | # 数组转栅格 606 | array2raster(rasterfn,newRasterfn,rasterArray) 607 | ``` -------------------------------------------------------------------------------- /docs/矢量图层.md: -------------------------------------------------------------------------------- 1 | # 矢量图层 2 | 3 | ## 删除文件 4 | 5 | ```python 6 | from osgeo import ogr 7 | import os 8 | 9 | DriverName = "ESRI Shapefile" # e.g.: GeoJSON, ESRI Shapefile 10 | FileName = 'test.shp' 11 | driver = ogr.GetDriverByName(DriverName) 12 | if os.path.exists(FileName): 13 | driver.DeleteDataSource(FileName) 14 | ``` 15 | 16 | ## 获取OGR驱动列表 17 | 18 | ```python 19 | import ogr 20 | cnt = ogr.GetDriverCount() 21 | formatsList = [] # Empty List 22 | 23 | for i in range(cnt): 24 | driver = ogr.GetDriver(i) 25 | driverName = driver.GetName() 26 | if not driverName in formatsList: 27 | formatsList.append(driverName) 28 | 29 | formatsList.sort() # 排序 30 | 31 | print(formatsList) 32 | ``` 33 | 34 | ## 驱动是否可用 35 | 36 | ```python 37 | from osgeo import ogr 38 | 39 | ## Shapefile 是否可用? 40 | driverName = "ESRI Shapefile" 41 | drv = ogr.GetDriverByName( driverName ) 42 | if drv is None: 43 | print("%s 驱动不可用.\n" % driverName) 44 | else: 45 | print ("%s 驱动可用.\n" % driverName) 46 | 47 | ## PostgreSQL 是否可用? 48 | driverName = "PostgreSQL" 49 | drv = ogr.GetDriverByName( driverName ) 50 | if drv is None: 51 | print ("%s 驱动不可用.\n" % driverName) 52 | else: 53 | print ("%s 驱动可用.\n" % driverName) 54 | 55 | ## File GeoDatabase 是否可用? 56 | driverName = "FileGDB" 57 | drv = ogr.GetDriverByName( driverName ) 58 | if drv is None: 59 | print ("%s 驱动不可用.\n" % driverName) 60 | else: 61 | print ("%s 驱动可用.\n" % driverName) 62 | 63 | ## SDE 是否可用? 64 | driverName = "SDE" 65 | drv = ogr.GetDriverByName( driverName ) 66 | if drv is None: 67 | print ("%s 驱动不可用.\n" % driverName) 68 | else: 69 | print ("%s 驱动可用.\n" % driverName) 70 | ``` 71 | 72 | ## 获取shapefile要素个数 73 | 74 | ```python 75 | import os 76 | from osgeo import ogr 77 | 78 | daShapefile = r"/test.shp" 79 | 80 | driver = ogr.GetDriverByName('ESRI Shapefile') 81 | 82 | dataSource = driver.Open(daShapefile, 0) # 0 只读. 1 读写. 83 | 84 | # 检查数据源是否有效. 85 | if dataSource is None: 86 | print ('不能打开 %s' % (daShapefile)) 87 | else: 88 | print ('打开 %s' % (daShapefile)) 89 | layer = dataSource.GetLayer() 90 | featureCount = layer.GetFeatureCount() 91 | print ("%s 要素个数: %d" % (os.path.basename(daShapefile),featureCount)) 92 | ``` 93 | 94 | ## 获取PostGIS图层 95 | 96 | ```python 97 | from osgeo import ogr 98 | 99 | databaseServer = "localhost" 100 | databaseName = "test2020" 101 | databaseUser = "postgres" 102 | databasePW = "123456" 103 | 104 | 105 | connString = "PG: host=%s dbname=%s user=%s password=%s" %(databaseServer,databaseName,databaseUser,databasePW) 106 | 107 | conn = ogr.Open(connString) 108 | 109 | layerList = [] 110 | for i in conn: 111 | daLayer = i.GetName() 112 | if not daLayer in layerList: 113 | layerList.append(daLayer) 114 | 115 | layerList.sort() 116 | 117 | for j in layerList: 118 | print(j) 119 | 120 | # 关闭连接 121 | conn = None 122 | ``` 123 | 124 | ## 获取PostGIS图层的要素 125 | 126 | ```python 127 | from osgeo import ogr 128 | import sys 129 | 130 | databaseServer = "localhost" 131 | databaseName = "test2020" 132 | databaseUser = "postgres" 133 | databasePW = "123456" 134 | connString = "PG: host=%s dbname=%s user=%s password=%s" % (databaseServer,databaseName,databaseUser,databasePW) 135 | 136 | def GetPGLayer( lyr_name ): 137 | conn = ogr.Open(connString) 138 | 139 | lyr = conn.GetLayer( lyr_name ) 140 | if lyr is None: 141 | sys.exit( 1 ) 142 | 143 | featureCount = lyr.GetFeatureCount() 144 | print ("%s 要素个数 : %d" % ( lyr_name , featureCount )) 145 | 146 | # 关闭连接 147 | conn = None 148 | 149 | 150 | if __name__ == '__main__': 151 | GetPGLayer( "test" ) 152 | ``` 153 | 154 | ## 获取ESRI GDB图层 155 | 156 | ```python 157 | import sys 158 | from osgeo import ogr 159 | 160 | ogr.UseExceptions() 161 | 162 | driver = ogr.GetDriverByName("OpenFileGDB") 163 | 164 | # opening the FileGDB 165 | try: 166 | gdb = driver.Open("/sparse.gdb", 0) 167 | except Exception as e: 168 | print(e) 169 | sys.exit() 170 | 171 | featsClassList = [] 172 | 173 | # 获取图层 174 | for featsClass_idx in range(gdb.GetLayerCount()): 175 | featsClass = gdb.GetLayerByIndex(featsClass_idx) 176 | featsClassList.append(featsClass.GetName()) 177 | 178 | featsClassList.sort() 179 | 180 | for featsClass in featsClassList: 181 | print (featsClass) 182 | ``` 183 | 184 | ## 加载数据到内存 185 | 186 | ```python 187 | from osgeo import ogr 188 | 189 | # 打开输入数据源 190 | indriver=ogr.GetDriverByName('SQLite') 191 | srcdb = indriver.Open('/poly_spatialite.sqlite',0) 192 | 193 | # 创建内存输出数据源 194 | outdriver=ogr.GetDriverByName('MEMORY') 195 | source=outdriver.CreateDataSource('memData') 196 | 197 | # 打开内存数据 198 | tmp=outdriver.Open('memData',1) 199 | 200 | # 复制图层到内存 201 | poly_mem=source.CopyLayer(srcdb.GetLayer('poly'),'poly',['OVERWRITE=YES']) 202 | 203 | # 新的图层可直接被访问,poly_mem 或者 source.GetLayer('poly'): 204 | layer=source.GetLayer('poly') 205 | for feature in layer: 206 | feature.SetField('area',1) 207 | ``` 208 | 209 | ## 遍历要素 210 | 211 | ```python 212 | from osgeo import ogr 213 | import os 214 | 215 | shapefile = "/test.shp" 216 | driver = ogr.GetDriverByName("ESRI Shapefile") 217 | dataSource = driver.Open(shapefile, 0) 218 | layer = dataSource.GetLayer() 219 | 220 | for feature in layer: 221 | print( feature.GetField("area")) 222 | layer.ResetReading() 223 | ``` 224 | 225 | ## 遍历要素几何 226 | 227 | ```python 228 | from osgeo import ogr 229 | import os 230 | 231 | shapefile = "/test.shp" 232 | driver = ogr.GetDriverByName("ESRI Shapefile") 233 | dataSource = driver.Open(shapefile, 0) 234 | layer = dataSource.GetLayer() 235 | 236 | for feature in layer: 237 | geom = feature.GetGeometryRef() 238 | # 获取质心 239 | print (geom.Centroid().ExportToWkt()) 240 | ``` 241 | 242 | ## 过滤属性 243 | 244 | ```python 245 | from osgeo import ogr 246 | import os 247 | 248 | shapefile = "/test.shp" 249 | driver = ogr.GetDriverByName("ESRI Shapefile") 250 | dataSource = driver.Open(shapefile, 0) 251 | layer = dataSource.GetLayer() 252 | 253 | layer.SetAttributeFilter("area = 5268.813") 254 | 255 | for feature in layer: 256 | print (feature.GetField("area")) 257 | ``` 258 | 259 | ## 空间过滤 260 | 261 | ```python 262 | from osgeo import ogr 263 | import os 264 | 265 | shapefile = "/test.shp" 266 | driver = ogr.GetDriverByName("ESRI Shapefile") 267 | dataSource = driver.Open(shapefile, 0) 268 | layer = dataSource.GetLayer() 269 | 270 | wkt = "POLYGON ((479386 4764749,481098 4764226,480772 4763114,478681 4763159,479386 4764749))" 271 | layer.SetSpatialFilter(ogr.CreateGeometryFromWkt(wkt)) 272 | 273 | for feature in layer: 274 | print (feature.GetField("area")) 275 | ``` 276 | 277 | ## 获取要素字段 278 | 279 | ```python 280 | from osgeo import ogr 281 | 282 | daShapefile = r"/test.shp" 283 | 284 | dataSource = ogr.Open(daShapefile) 285 | daLayer = dataSource.GetLayer(0) 286 | layerDefinition = daLayer.GetLayerDefn() 287 | 288 | 289 | for i in range(layerDefinition.GetFieldCount()): 290 | fieldName = layerDefinition.GetFieldDefn(i).GetName() 291 | fieldTypeCode = layerDefinition.GetFieldDefn(i).GetType() 292 | fieldType = layerDefinition.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode) 293 | fieldWidth = layerDefinition.GetFieldDefn(i).GetWidth() 294 | GetPrecision = layerDefinition.GetFieldDefn(i).GetPrecision() 295 | 296 | print (fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)) 297 | ``` 298 | 299 | ## 获取PostGIS图层字段 300 | 301 | ```python 302 | from osgeo import ogr 303 | import sys 304 | 305 | databaseServer = "localhost" 306 | databaseName = "test2020" 307 | databaseUser = "postgres" 308 | databasePW = "123456" 309 | connString = "PG: host=%s dbname=%s user=%s password=%s" %(databaseServer,databaseName,databaseUser,databasePW) 310 | 311 | 312 | def GetPGLayerFields( lyr_name ): 313 | conn = ogr.Open(connString) 314 | 315 | lyr = conn.GetLayer( lyr_name ) 316 | if lyr is None: 317 | sys.exit( 1 ) 318 | 319 | lyrDefn = lyr.GetLayerDefn() 320 | 321 | 322 | for i in range( lyrDefn.GetFieldCount() ): 323 | fieldName = lyrDefn.GetFieldDefn(i).GetName() 324 | fieldTypeCode = lyrDefn.GetFieldDefn(i).GetType() 325 | fieldType = lyrDefn.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode) 326 | fieldWidth = lyrDefn.GetFieldDefn(i).GetWidth() 327 | GetPrecision = lyrDefn.GetFieldDefn(i).GetPrecision() 328 | 329 | print (fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)) 330 | 331 | 332 | if __name__ == '__main__': 333 | GetPGLayerFields( "test" ) 334 | ``` 335 | 336 | ## 获取图层能力 337 | 338 | ```python 339 | from osgeo import ogr 340 | 341 | ds = ogr.Open("/test.shp",0) 342 | layer = ds.GetLayer() 343 | capabilities = [ 344 | ogr.OLCRandomRead, 345 | ogr.OLCSequentialWrite, 346 | ogr.OLCRandomWrite, 347 | ogr.OLCFastSpatialFilter, 348 | ogr.OLCFastFeatureCount, 349 | ogr.OLCFastGetExtent, 350 | ogr.OLCCreateField, 351 | ogr.OLCDeleteField, 352 | ogr.OLCReorderFields, 353 | ogr.OLCAlterFieldDefn, 354 | ogr.OLCTransactions, 355 | ogr.OLCDeleteFeature, 356 | ogr.OLCFastSetNextByIndex, 357 | ogr.OLCStringsAsUTF8, 358 | ogr.OLCIgnoreFields 359 | ] 360 | 361 | print("图层能力:") 362 | for cap in capabilities: 363 | print(" %s = %s" % (cap, layer.TestCapability(cap))) 364 | ``` 365 | 366 | ## WFS图层和遍历要素 367 | 368 | ```python 369 | import sys 370 | 371 | from osgeo import ogr, osr, gdal 372 | 373 | # 获取WFS驱动 374 | wfs_drv = ogr.GetDriverByName('WFS') 375 | 376 | # 加快查询多图层WFS服务 377 | gdal.SetConfigOption('OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN', 'NO') 378 | 379 | # 设置分页的配置。适用于WFS 2.0服务以及WFS 1.0和1.1以及其他一些服务。 380 | gdal.SetConfigOption('OGR_WFS_PAGING_ALLOWED', 'YES') 381 | gdal.SetConfigOption('OGR_WFS_PAGE_SIZE', '10000') 382 | 383 | url = 'http://sampleserver6.arcgisonline.com/arcgis/services/SampleWorldCities/MapServer/WFSServer' 384 | wfs_ds = wfs_drv.Open('WFS:' + url) 385 | if not wfs_ds: 386 | sys.exit('错误: 不能打开 WFS 数据源') 387 | else: 388 | pass 389 | 390 | # 遍历图层 391 | for i in range(wfs_ds.GetLayerCount()): 392 | layer = wfs_ds.GetLayerByIndex(i) 393 | srs = layer.GetSpatialRef() 394 | print ('Layer: %s, Features: %s, SR: %s...' % (layer.GetName(), layer.GetFeatureCount(), srs.ExportToWkt()[0:50])) 395 | 396 | # 遍历要素 397 | feat = layer.GetNextFeature() 398 | while feat is not None: 399 | feat = layer.GetNextFeature() 400 | # do something more.. 401 | feat = None 402 | 403 | # 获取指定图层 404 | layer = wfs_ds.GetLayerByName("esri:World") 405 | if not layer: 406 | sys.exit('错误:不能找到图层:esri:World') 407 | else: 408 | pass 409 | ``` 410 | 411 | ## 设置HTTP代理 412 | 413 | ```python 414 | import sys 415 | 416 | from osgeo import ogr, osr, gdal 417 | 418 | server = 'proxy.example.com' 419 | port = 3128 420 | 421 | # 设置代理 422 | gdal.SetConfigOption('GDAL_HTTP_PROXY', server + ':' + port) 423 | 424 | # 没有用户名或密码的NTLM设置代理身份验证选项,因此单点登录有效 425 | gdal.SetConfigOption('GDAL_PROXY_AUTH', 'NTLM') 426 | gdal.SetConfigOption('GDAL_HTTP_PROXYUSERPWD', ' : ') 427 | 428 | ds = ogr.Open('http://featureserver/cities/.geojson') 429 | if not ds: 430 | sys.exit('ERROR: can not open GeoJSON datasource') 431 | lyr = ds.GetLayer('OGRGeoJSON') 432 | for feat in lyr: 433 | geom = feat.GetGeometryRef() 434 | print( geom.ExportToWkt()) 435 | ``` 436 | 437 | ## 读取CSV经纬度作为OGRVRTLayer 438 | 439 | GDAL/OGR具有[虚拟格式规范](https://gdal.org/drivers/vector/vrt.html),该规范允许你从诸如CSV之类的平面表派生图层——它的功能远不止于此,因此请继续阅读。在下面的示例中,我们正在读取带有X、Y列和值的CSV。该CSV文件由XML文件包装,该XML文件将其描述为OGR层。以下是所有必要的部分和一个脚本,该脚本读取XML文件并打印出点的几何形状。 440 | 441 | CSV文件: 442 | 443 | ``` 444 | ID,X,Y 445 | 1,-127.234343,47.234325 446 | 2,-127.003243,46.234343 447 | 3,-127.345646,45.234324 448 | 4,-126.234324,44.324234 449 | ``` 450 | 451 | XML文件 452 | 453 | ```xml 454 | 455 | 456 | example.csv 457 | example 458 | wkbPoint 459 | WGS84 460 | 461 | 462 | 463 | ``` 464 | 465 | ```python 466 | from osgeo import ogr 467 | ogr.UseExceptions() 468 | 469 | inDataSource = ogr.Open("example_wrapper.vrt") 470 | lyr = inDataSource.GetLayer('example') 471 | for feat in lyr: 472 | geom = feat.GetGeometryRef() 473 | print (geom.ExportToWkt()) 474 | ``` 475 | 476 | ## 计算范围 477 | 478 | ```python 479 | from osgeo import ogr 480 | import os 481 | 482 | # Get a Layer's Extent 483 | inShapefile = "states.shp" 484 | inDriver = ogr.GetDriverByName("ESRI Shapefile") 485 | inDataSource = inDriver.Open(inShapefile, 0) 486 | inLayer = inDataSource.GetLayer() 487 | extent = inLayer.GetExtent() 488 | 489 | # 创建多边形 490 | ring = ogr.Geometry(ogr.wkbLinearRing) 491 | ring.AddPoint(extent[0],extent[2]) 492 | ring.AddPoint(extent[1], extent[2]) 493 | ring.AddPoint(extent[1], extent[3]) 494 | ring.AddPoint(extent[0], extent[3]) 495 | ring.AddPoint(extent[0],extent[2]) 496 | poly = ogr.Geometry(ogr.wkbPolygon) 497 | poly.AddGeometry(ring) 498 | 499 | # 保存到新的shp文件 500 | outShapefile = "new.shp" 501 | outDriver = ogr.GetDriverByName("ESRI Shapefile") 502 | 503 | # 如果存在,先删除 504 | if os.path.exists(outShapefile): 505 | outDriver.DeleteDataSource(outShapefile) 506 | 507 | # 创建数据源 508 | outDataSource = outDriver.CreateDataSource(outShapefile) 509 | outLayer = outDataSource.CreateLayer("new", geom_type=ogr.wkbPolygon) 510 | 511 | # 添加ID字段 512 | idField = ogr.FieldDefn("id", ogr.OFTInteger) 513 | outLayer.CreateField(idField) 514 | 515 | # 创建要素 516 | featureDefn = outLayer.GetLayerDefn() 517 | feature = ogr.Feature(featureDefn) 518 | feature.SetGeometry(poly) 519 | feature.SetField("id", 1) 520 | outLayer.CreateFeature(feature) 521 | feature = None 522 | 523 | # 保存并关闭 524 | inDataSource = None 525 | outDataSource = None 526 | ``` 527 | 528 | ## 计算凸包 529 | 530 | ![image-20200309152509219](./assets/image-20200309152509219.png) 531 | 532 | ```python 533 | from osgeo import ogr 534 | import os 535 | 536 | # 获得图层 537 | inShapefile = "test.shp" 538 | inDriver = ogr.GetDriverByName("ESRI Shapefile") 539 | inDataSource = inDriver.Open(inShapefile, 0) 540 | inLayer = inDataSource.GetLayer() 541 | 542 | # 几何集合 543 | geomcol = ogr.Geometry(ogr.wkbGeometryCollection) 544 | for feature in inLayer: 545 | geomcol.AddGeometry(feature.GetGeometryRef()) 546 | 547 | # 计算凸包 548 | convexhull = geomcol.ConvexHull() 549 | 550 | # 保存 551 | outShapefile = "test_convexhull.shp" 552 | outDriver = ogr.GetDriverByName("ESRI Shapefile") 553 | 554 | # 如果存在,先删除 555 | if os.path.exists(outShapefile): 556 | outDriver.DeleteDataSource(outShapefile) 557 | 558 | # 输出 559 | outDataSource = outDriver.CreateDataSource(outShapefile) 560 | outLayer = outDataSource.CreateLayer("test_convexhull", geom_type=ogr.wkbPolygon) 561 | 562 | # 添加ID字段 563 | idField = ogr.FieldDefn("id", ogr.OFTInteger) 564 | outLayer.CreateField(idField) 565 | 566 | # 创建要素 567 | featureDefn = outLayer.GetLayerDefn() 568 | feature = ogr.Feature(featureDefn) 569 | feature.SetGeometry(convexhull) 570 | feature.SetField("id", 1) 571 | outLayer.CreateFeature(feature) 572 | feature = None 573 | 574 | # 保存并关闭 575 | inDataSource = None 576 | outDataSource = None 577 | ``` 578 | 579 | ## 计算质心 580 | 581 | ```python 582 | from osgeo import ogr 583 | import os 584 | 585 | ogr.UseExceptions() 586 | 587 | # 输入图层 588 | inShapefile = "test.shp" 589 | inDriver = ogr.GetDriverByName("ESRI Shapefile") 590 | inDataSource = inDriver.Open(inShapefile, 0) 591 | inLayer = inDataSource.GetLayer() 592 | 593 | # 输出图层 594 | outShapefile = "test_centroids.shp" 595 | outDriver = ogr.GetDriverByName("ESRI Shapefile") 596 | 597 | # 如果存在,先删除 598 | if os.path.exists(outShapefile): 599 | outDriver.DeleteDataSource(outShapefile) 600 | 601 | outDataSource = outDriver.CreateDataSource(outShapefile) 602 | outLayer = outDataSource.CreateLayer("test_centroids", geom_type=ogr.wkbPoint) 603 | 604 | # 添加字段 605 | inLayerDefn = inLayer.GetLayerDefn() 606 | for i in range(0, inLayerDefn.GetFieldCount()): 607 | fieldDefn = inLayerDefn.GetFieldDefn(i) 608 | outLayer.CreateField(fieldDefn) 609 | 610 | # 获得要素定义 611 | outLayerDefn = outLayer.GetLayerDefn() 612 | 613 | # 添加要素 614 | for i in range(0, inLayer.GetFeatureCount()): 615 | # 输入要素 616 | inFeature = inLayer.GetFeature(i) 617 | # 输出要素 618 | outFeature = ogr.Feature(outLayerDefn) 619 | # 设置字段值 620 | for i in range(0, outLayerDefn.GetFieldCount()): 621 | outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), inFeature.GetField(i)) 622 | # 设置质心几何 623 | geom = inFeature.GetGeometryRef() 624 | inFeature = None 625 | centroid = geom.Centroid() 626 | outFeature.SetGeometry(centroid) 627 | # 添加新要素 628 | outLayer.CreateFeature(outFeature) 629 | outFeature = None 630 | 631 | # 保存并关闭 632 | inDataSource = None 633 | outDataSource = None 634 | ``` 635 | 636 | ## 创建新的shp数据并添加数据 637 | 638 | ```python 639 | import osgeo.ogr as ogr 640 | import osgeo.osr as osr 641 | import csv,os 642 | 643 | # 使用字典读取数据 644 | reader = csv.DictReader(open("volcano_data.txt","r"), 645 | delimiter='\t', 646 | quoting=csv.QUOTE_NONE) 647 | 648 | # 驱动 649 | outShapefile="volcanoes.shp" 650 | driver = ogr.GetDriverByName("ESRI Shapefile") 651 | 652 | if os.path.exists(outShapefile): 653 | driver.DeleteDataSource(outShapefile) 654 | 655 | # 创建数据源 656 | data_source = driver.CreateDataSource(outShapefile) 657 | 658 | # 创建空间参考 WGS84 659 | srs = osr.SpatialReference() 660 | srs.ImportFromEPSG(4326) 661 | 662 | # 创建图层 663 | layer = data_source.CreateLayer("volcanoes", srs, ogr.wkbPoint) 664 | 665 | # 添加字段 666 | field_name = ogr.FieldDefn("Name", ogr.OFTString) 667 | field_name.SetWidth(24) 668 | layer.CreateField(field_name) 669 | field_region = ogr.FieldDefn("Region", ogr.OFTString) 670 | field_region.SetWidth(24) 671 | layer.CreateField(field_region) 672 | layer.CreateField(ogr.FieldDefn("Latitude", ogr.OFTReal)) 673 | layer.CreateField(ogr.FieldDefn("Longitude", ogr.OFTReal)) 674 | layer.CreateField(ogr.FieldDefn("Elevation", ogr.OFTInteger)) 675 | 676 | # 处理文本 677 | for row in reader: 678 | # 创建要素 679 | feature = ogr.Feature(layer.GetLayerDefn()) 680 | # 设置属性字段 681 | feature.SetField("Name", row['Name']) 682 | feature.SetField("Region", row['Region']) 683 | feature.SetField("Latitude", row['Latitude']) 684 | feature.SetField("Longitude", row['Longitude']) 685 | feature.SetField("Elevation", row['Elevation']) 686 | 687 | # 创建WKT 688 | wkt = "POINT(%f %f)" % (float(row['Longitude']) , float(row['Latitude'])) 689 | 690 | # 创建点 691 | point = ogr.CreateGeometryFromWkt(wkt) 692 | 693 | # 设置几何 694 | feature.SetGeometry(point) 695 | # 添加要素 696 | layer.CreateFeature(feature) 697 | # 删除引用 698 | feature = None 699 | 700 | # 保存关闭 701 | data_source = None 702 | ``` 703 | 704 | ## 从WKT创建PostGIS表 705 | 706 | ```python 707 | import ogr, osr 708 | 709 | database = 'test2020' 710 | usr = 'postgres' 711 | pw = '123456' 712 | table = 'testtest' 713 | 714 | wkt = "POINT (1120351.5712494177 741921.4223245403)" 715 | point = ogr.CreateGeometryFromWkt(wkt) 716 | 717 | connectionString = "PG:dbname='%s' user='%s' password='%s'" % (database,usr,pw) 718 | ogrds = ogr.Open(connectionString) 719 | 720 | srs = osr.SpatialReference() 721 | srs.ImportFromEPSG(4326) 722 | 723 | layer = ogrds.CreateLayer(table, srs, ogr.wkbPoint, ['OVERWRITE=YES'] ) 724 | 725 | layerDefn = layer.GetLayerDefn() 726 | 727 | feature = ogr.Feature(layerDefn) 728 | feature.SetGeometry(point) 729 | 730 | layer.StartTransaction() 731 | layer.CreateFeature(feature) 732 | feature = None 733 | layer.CommitTransaction() 734 | ``` 735 | 736 | ## 过滤和选择 737 | 738 | ```sh 739 | ogr2ogr -f "ESRI Shapefile" junkmob.shp -select area -where "area = 5268.813" test.shp 740 | 741 | # 该命令读取parcel_address.shp并生成junkmob.shp,area=5268.813输出area列 742 | ``` 743 | 744 | ```python 745 | from osgeo import ogr 746 | import os, sys 747 | 748 | def main( field_name_target ): 749 | # 输入图层 750 | inShapefile = "test.shp" 751 | inDriver = ogr.GetDriverByName("ESRI Shapefile") 752 | inDataSource = inDriver.Open(inShapefile, 0) 753 | inLayer = inDataSource.GetLayer() 754 | inLayer.SetAttributeFilter("area = 5268.813") 755 | 756 | # 创建输出图层 757 | outShapefile = os.path.join( os.path.split( inShapefile )[0], "junkmob.shp" ) 758 | outDriver = ogr.GetDriverByName("ESRI Shapefile") 759 | 760 | # 存在,先删除 761 | if os.path.exists(outShapefile): 762 | outDriver.DeleteDataSource(outShapefile) 763 | 764 | # 创建输出shp 765 | outDataSource = outDriver.CreateDataSource(outShapefile) 766 | out_lyr_name = os.path.splitext( os.path.split( outShapefile )[1] )[0] 767 | outLayer = outDataSource.CreateLayer( out_lyr_name, geom_type=ogr.wkbMultiPolygon ) 768 | 769 | # 添加字段 770 | inLayerDefn = inLayer.GetLayerDefn() 771 | for i in range(0, inLayerDefn.GetFieldCount()): 772 | fieldDefn = inLayerDefn.GetFieldDefn(i) 773 | fieldName = fieldDefn.GetName() 774 | if fieldName not in field_name_target: 775 | continue 776 | outLayer.CreateField(fieldDefn) 777 | 778 | # 要素定义 779 | outLayerDefn = outLayer.GetLayerDefn() 780 | 781 | # 添加要素 782 | for inFeature in inLayer: 783 | # 创建要素 784 | outFeature = ogr.Feature(outLayerDefn) 785 | 786 | # 添加字段 787 | for i in range(0, outLayerDefn.GetFieldCount()): 788 | fieldDefn = outLayerDefn.GetFieldDefn(i) 789 | fieldName = fieldDefn.GetName() 790 | if fieldName not in field_name_target: 791 | continue 792 | 793 | outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), 794 | inFeature.GetField(i)) 795 | 796 | # 设置几何 797 | geom = inFeature.GetGeometryRef() 798 | outFeature.SetGeometry(geom.Clone()) 799 | # 创建要素 800 | outLayer.CreateFeature(outFeature) 801 | outFeature = None 802 | 803 | # 保存关闭 804 | inDataSource = None 805 | outDataSource = None 806 | 807 | 808 | main( ["AREA","EAS_ID"]) 809 | ``` 810 | 811 | ## 合并图层 812 | 813 | ```python 814 | import os, ogr, osr 815 | 816 | outputMergefn = 'merge.shp' 817 | directory = "/Users/UserName/Downloads/" 818 | fileStartsWith = 'test' 819 | fileEndsWith = '.shp' 820 | driverName = 'ESRI Shapefile' 821 | geometryType = ogr.wkbPolygon 822 | 823 | out_driver = ogr.GetDriverByName( driverName ) 824 | if os.path.exists(outputMergefn): 825 | out_driver.DeleteDataSource(outputMergefn) 826 | out_ds = out_driver.CreateDataSource(outputMergefn) 827 | out_layer = out_ds.CreateLayer(outputMergefn, geom_type=geometryType) 828 | 829 | fileList = os.listdir(directory) 830 | 831 | for file in fileList: 832 | if file.startswith(fileStartsWith) and file.endswith(fileEndsWith): 833 | print file 834 | ds = ogr.Open(directory+file) 835 | lyr = ds.GetLayer() 836 | for feat in lyr: 837 | out_feat = ogr.Feature(out_layer.GetLayerDefn()) 838 | out_feat.SetGeometry(feat.GetGeometryRef().Clone()) 839 | out_layer.CreateFeature(out_feat) 840 | out_feat = None 841 | out_layer.SyncToDisk() 842 | ``` 843 | 844 | ## 获取OSM街道名称 845 | 846 | TODO:测试 847 | 848 | ```python 849 | import ogr 850 | 851 | ds = ogr.Open('test.osm') 852 | layer = ds.GetLayer() 853 | 854 | nameList = [] 855 | for feature in layer: 856 | if feature.GetField("highway") != None: 857 | name = feature.GetField("name") 858 | if name != None and name not in nameList: 859 | nameList.append(name) 860 | 861 | print (nameList) 862 | ``` 863 | 864 | ## 创建鱼网 865 | 866 | ```python 867 | import os, sys 868 | import ogr 869 | from math import ceil 870 | 871 | 872 | def main(outputGridfn,xmin,xmax,ymin,ymax,gridHeight,gridWidth): 873 | xmin = float(xmin) 874 | xmax = float(xmax) 875 | ymin = float(ymin) 876 | ymax = float(ymax) 877 | gridWidth = float(gridWidth) 878 | gridHeight = float(gridHeight) 879 | 880 | # get rows 881 | rows = ceil((ymax-ymin)/gridHeight) 882 | # get columns 883 | cols = ceil((xmax-xmin)/gridWidth) 884 | 885 | # start grid cell envelope 886 | ringXleftOrigin = xmin 887 | ringXrightOrigin = xmin + gridWidth 888 | ringYtopOrigin = ymax 889 | ringYbottomOrigin = ymax-gridHeight 890 | 891 | # create output file 892 | outDriver = ogr.GetDriverByName('ESRI Shapefile') 893 | if os.path.exists(outputGridfn): 894 | os.remove(outputGridfn) 895 | outDataSource = outDriver.CreateDataSource(outputGridfn) 896 | outLayer = outDataSource.CreateLayer(outputGridfn,geom_type=ogr.wkbPolygon ) 897 | featureDefn = outLayer.GetLayerDefn() 898 | 899 | # create grid cells 900 | countcols = 0 901 | while countcols < cols: 902 | countcols += 1 903 | 904 | # reset envelope for rows 905 | ringYtop = ringYtopOrigin 906 | ringYbottom =ringYbottomOrigin 907 | countrows = 0 908 | 909 | while countrows < rows: 910 | countrows += 1 911 | ring = ogr.Geometry(ogr.wkbLinearRing) 912 | ring.AddPoint(ringXleftOrigin, ringYtop) 913 | ring.AddPoint(ringXrightOrigin, ringYtop) 914 | ring.AddPoint(ringXrightOrigin, ringYbottom) 915 | ring.AddPoint(ringXleftOrigin, ringYbottom) 916 | ring.AddPoint(ringXleftOrigin, ringYtop) 917 | poly = ogr.Geometry(ogr.wkbPolygon) 918 | poly.AddGeometry(ring) 919 | 920 | # add new geom to layer 921 | outFeature = ogr.Feature(featureDefn) 922 | outFeature.SetGeometry(poly) 923 | outLayer.CreateFeature(outFeature) 924 | outFeature = None 925 | 926 | # new envelope for next poly 927 | ringYtop = ringYtop - gridHeight 928 | ringYbottom = ringYbottom - gridHeight 929 | 930 | # new envelope for next poly 931 | ringXleftOrigin = ringXleftOrigin + gridWidth 932 | ringXrightOrigin = ringXrightOrigin + gridWidth 933 | 934 | # Save and close DataSources 935 | outDataSource = None 936 | 937 | 938 | if __name__ == "__main__": 939 | 940 | # 941 | # example run : $ python grid.py .shp xmin xmax ymin ymax gridHeight gridWidth 942 | # 943 | 944 | if len( sys.argv ) != 8: 945 | print "[ ERROR ] you must supply seven arguments: output-shapefile-name.shp xmin xmax ymin ymax gridHeight gridWidth" 946 | sys.exit( 1 ) 947 | 948 | main( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7] ) 949 | ``` 950 | 951 | ## 面转线 952 | 953 | ```python 954 | import ogr, os 955 | 956 | def poly2line(input_poly,output_line): 957 | 958 | source_ds = ogr.Open(input_poly) 959 | source_layer = source_ds.GetLayer() 960 | 961 | # polygon2geometryCollection 962 | geomcol = ogr.Geometry(ogr.wkbGeometryCollection) 963 | for feat in source_layer: 964 | geom = feat.GetGeometryRef() 965 | ring = geom.GetGeometryRef(0) 966 | geomcol.AddGeometry(ring) 967 | 968 | # geometryCollection2shp 969 | shpDriver = ogr.GetDriverByName("ESRI Shapefile") 970 | if os.path.exists(output_line): 971 | shpDriver.DeleteDataSource(output_line) 972 | outDataSource = shpDriver.CreateDataSource(output_line) 973 | outLayer = outDataSource.CreateLayer(output_line, geom_type=ogr.wkbMultiLineString) 974 | featureDefn = outLayer.GetLayerDefn() 975 | outFeature = ogr.Feature(featureDefn) 976 | outFeature.SetGeometry(geomcol) 977 | outLayer.CreateFeature(outFeature) 978 | outFeature = None 979 | 980 | def main(input_poly,output_line): 981 | poly2line(input_poly,output_line) 982 | 983 | if __name__ == "__main__": 984 | input_poly = 'test_polygon.shp' 985 | output_line = 'test_line.shp' 986 | 987 | main(input_poly,output_line) 988 | ``` 989 | 990 | ## 创建缓冲区 991 | 992 | ```python 993 | import ogr, os 994 | 995 | def createBuffer(inputfn, outputBufferfn, bufferDist): 996 | inputds = ogr.Open(inputfn) 997 | inputlyr = inputds.GetLayer() 998 | 999 | shpdriver = ogr.GetDriverByName('ESRI Shapefile') 1000 | if os.path.exists(outputBufferfn): 1001 | shpdriver.DeleteDataSource(outputBufferfn) 1002 | outputBufferds = shpdriver.CreateDataSource(outputBufferfn) 1003 | bufferlyr = outputBufferds.CreateLayer(outputBufferfn, geom_type=ogr.wkbPolygon) 1004 | featureDefn = bufferlyr.GetLayerDefn() 1005 | 1006 | for feature in inputlyr: 1007 | ingeom = feature.GetGeometryRef() 1008 | geomBuffer = ingeom.Buffer(bufferDist) 1009 | 1010 | outFeature = ogr.Feature(featureDefn) 1011 | outFeature.SetGeometry(geomBuffer) 1012 | bufferlyr.CreateFeature(outFeature) 1013 | outFeature = None 1014 | 1015 | def main(inputfn, outputBufferfn, bufferDist): 1016 | createBuffer(inputfn, outputBufferfn, bufferDist) 1017 | 1018 | 1019 | if __name__ == "__main__": 1020 | inputfn = 'test.shp' 1021 | outputBufferfn = 'testBuffer.shp' 1022 | bufferDist = 10.0 1023 | 1024 | main(inputfn, outputBufferfn, bufferDist) 1025 | ``` 1026 | 1027 | ## 栅格化矢量图层 1028 | 1029 | ```python 1030 | import ogr, gdal 1031 | 1032 | vector_fn = 'test.shp' 1033 | 1034 | # 定义像素大小和无效值 1035 | pixel_size = 25 1036 | NoData_value = 255 1037 | 1038 | # 打开数据源,读取数据范围 1039 | source_ds = ogr.Open(vector_fn) 1040 | source_layer = source_ds.GetLayer() 1041 | source_srs = source_layer.GetSpatialRef() 1042 | x_min, x_max, y_min, y_max = source_layer.GetExtent() 1043 | 1044 | # 创建目标数据源 1045 | x_res = int((x_max - x_min) / pixel_size) 1046 | y_res = int((y_max - y_min) / pixel_size) 1047 | target_ds = gdal.GetDriverByName('MEM').Create('', x_res, y_res, gdal.GDT_Byte) 1048 | target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size)) 1049 | band = target_ds.GetRasterBand(1) 1050 | band.SetNoDataValue(NoData_value) 1051 | 1052 | # 栅格化 1053 | gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[1]) 1054 | 1055 | # 读取为数组 1056 | array = band.ReadAsArray() 1057 | print (array) 1058 | ``` 1059 | 1060 | ## 面转点 1061 | 1062 | TODO:测试 1063 | 1064 | ```python 1065 | import ogr, gdal 1066 | import numpy as np 1067 | import os 1068 | 1069 | polygon_fn = 'test.shp' 1070 | 1071 | # Define pixel_size which equals distance betweens points 1072 | pixel_size = 10 1073 | 1074 | # Open the data source and read in the extent 1075 | source_ds = ogr.Open(polygon_fn) 1076 | source_layer = source_ds.GetLayer() 1077 | x_min, x_max, y_min, y_max = source_layer.GetExtent() 1078 | 1079 | # Create the destination data source 1080 | x_res = int((x_max - x_min) / pixel_size) 1081 | y_res = int((y_max - y_min) / pixel_size) 1082 | target_ds = gdal.GetDriverByName('GTiff').Create('temp.tif', x_res, y_res, gdal.GDT_Byte) 1083 | target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size)) 1084 | band = target_ds.GetRasterBand(1) 1085 | band.SetNoDataValue(255) 1086 | 1087 | # Rasterize 1088 | gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[1]) 1089 | 1090 | # Read as array 1091 | array = band.ReadAsArray() 1092 | 1093 | raster = gdal.Open('temp.tif') 1094 | geotransform = raster.GetGeoTransform() 1095 | 1096 | # Convert array to point coordinates 1097 | count = 0 1098 | roadList = np.where(array == 1) 1099 | multipoint = ogr.Geometry(ogr.wkbMultiPoint) 1100 | for indexY in roadList[0]: 1101 | indexX = roadList[1][count] 1102 | geotransform = raster.GetGeoTransform() 1103 | originX = geotransform[0] 1104 | originY = geotransform[3] 1105 | pixelWidth = geotransform[1] 1106 | pixelHeight = geotransform[5] 1107 | Xcoord = originX+pixelWidth*indexX 1108 | Ycoord = originY+pixelHeight*indexY 1109 | point = ogr.Geometry(ogr.wkbPoint) 1110 | point.AddPoint(Xcoord, Ycoord) 1111 | multipoint.AddGeometry(point) 1112 | count += 1 1113 | 1114 | # Write point coordinates to Shapefile 1115 | shpDriver = ogr.GetDriverByName("ESRI Shapefile") 1116 | if os.path.exists('points.shp'): 1117 | shpDriver.DeleteDataSource('points.shp') 1118 | outDataSource = shpDriver.CreateDataSource('points.shp') 1119 | outLayer = outDataSource.CreateLayer('points.shp', geom_type=ogr.wkbMultiPoint) 1120 | featureDefn = outLayer.GetLayerDefn() 1121 | outFeature = ogr.Feature(featureDefn) 1122 | outFeature.SetGeometry(multipoint) 1123 | outLayer.CreateFeature(outFeature) 1124 | outFeature = None 1125 | 1126 | # Remove temporary files 1127 | os.remove('temp.tif') 1128 | ``` -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: python GDAL/OGR 中文手册 2 | site_url: https://luolingchun.github.io/py-gdalogr-cookbook-zh 3 | site_description: 本项目是翻译项目,英文项目地址:https://github.com/pcjericks/py-gdalogr-cookbook 4 | site_author: llc 5 | 6 | repo_url: https://github.com/luolingchun/py-gdalogr-cookbook-zh 7 | repo_name: 'GitHub' 8 | 9 | markdown_extensions: 10 | - admonition 11 | - codehilite: 12 | guess_lang: false 13 | linenums: false 14 | - toc: 15 | permalink: true 16 | - footnotes 17 | - meta 18 | - def_list 19 | - pymdownx.arithmatex 20 | - pymdownx.betterem: 21 | smart_enable: all 22 | - pymdownx.caret 23 | - pymdownx.critic 24 | - pymdownx.details 25 | - pymdownx.emoji: 26 | emoji_generator: !!python/name:pymdownx.emoji.to_png 27 | - pymdownx.inlinehilite 28 | - pymdownx.magiclink 29 | - pymdownx.mark 30 | - pymdownx.smartsymbols 31 | - pymdownx.superfences 32 | - pymdownx.tasklist 33 | - pymdownx.tilde 34 | - pymdownx.snippets 35 | 36 | 37 | theme: 38 | name: material 39 | language: 'zh' 40 | logo: images/logo.svg 41 | favicon: images/logo-blue.svg 42 | palette: 43 | - media: "(prefers-color-scheme: light)" 44 | scheme: default 45 | toggle: 46 | icon: material/weather-sunny 47 | name: 黑 48 | - media: "(prefers-color-scheme: dark)" 49 | scheme: slate 50 | toggle: 51 | icon: material/weather-night 52 | name: 亮 53 | features: 54 | - navigation.tracking 55 | - navigation.top 56 | - navigation.expand 57 | - search.suggest 58 | - search.highlight 59 | - search.share 60 | 61 | plugins: 62 | - search 63 | 64 | extra_css: 65 | - css/img.css 66 | 67 | nav: 68 | - 主页: index.md 69 | - 一般使用: 一般使用.md 70 | - 几何: 几何.md 71 | - 矢量图层: 矢量图层.md 72 | - 栅格图层: 栅格图层.md 73 | - 投影: 投影.md 74 | 75 | --------------------------------------------------------------------------------