Python地理数据处理 三:矢量数据的读写(一)

1. 矢量数据

  带有明确边界的地理要素,如城市,可以用矢量数据进行很好的表示。但是,连续的数据(如高程数据)则不行。如果在山区,在所有具有相同高程的区域边界绘制一个多边形是非常困难的。但是,可以使用不同的多边形来区分不同的海拔范围。许多种类的数据非常适合于用矢量进行表示。例如,道路图上的要素,道路用线段表示,市县用多边形表示,而城市根据地图比例尺的不同,用点或者多边形表示。地图上所有的要素都有可能用点、线、面来表达。
  矢量数据非常适合用于制作地图,但也存在一些不足。如,绘制显示时,如何进行缩放,才能达到更好的显示效果。

海岸线悖论
  英国数学家Lewis Fry Richardson是第一位量测陆地海岸线的人。但量测的过程并不那么容易,因为最终的量测结果完全取决于选取的比例尺度。例如,一个具有多个海峡的宽广海岸线,旁边有一条道路。试想一下,沿着这条道路开车,使用汽车的里程表测量距离,然后走出车沿着来的路往回走。但是,徒步时,是沿着海峡的边缘曲线,而道路不是。很容易想出,走的路程比开车要远,因为走了很多弯路。同样的道理也适用于量测整个海岸线,因为如果以较小的增量进行量测,可以量测更多的变化。在量测英国海岸线时,使用50千米的增量要比100千米的增量所量测出的最终长度多600千米。

  Shapefile是储存矢量数据的一种通用格式。但其并不是一个单独的文件。它至少需要3个二进制的文件,包括:1个主文件(.shp),1个索引文件(.shx),储存几何信息,和1个dBASE(.dbf)表,来储存属性数据,并且需要确保这三个文件都储存在同一个文件夹中。
1个Shapefile文件  另一种格式是GeoJSON,都是纯文本文件,可以使用在任何文本编辑器中。一个GeoJSON只包含1个文件,储存所有必要的信息。
例如:在线geojson数据格式地图
在这里插入图片描述
GeoJSON文件格式
手动绘制地图

2. OGR

  OGR简单要素库是地理空间数据抽象库( Geospatial Data Abstraction Library,GDAL)的一部分,它是一个非常流行的用于读写空间数据的开源库。GDAL的OGR部分具有读写许多不同矢量数据格式的功能。OGR还允许你创建操作要素的几何形状、编辑其属性值、基于属性值或空间位置对矢量数据进行筛选,而且它还提供数据分析能力。
  GDAL库最初是用C和C ++编写的,但它与其他几种语言,包括Python,做了绑定,所以尽管这些代码没有用Python进行重写,但它为Python中使用GDAL/OGR库提供了接口。因此,要想在Python中使用GDAL, 需要安装GDAL库以及相应的Python绑定。

OGR类结构
  此数据源中包含多个子图层对象,每一个图层代表数据源中的一个数据集,Shapefile只包含一个数据集(一个图层),但SpatiaLite包含多个。无论一个数据源有多少个数据集,每一个数据集都被OGR认为是一个图层。
  一个数据源由一个或多个图层组成。
  Arcgis中属性表,每一行代表一个要素,每一列代表一个属性字段:

属性表

2.1 ogrinfo

  用于输出OGR支持的矢量数据的信息。
  出现的错误有:
在这里插入图片描述
  解决方法:把osgeo\gdalplugins文件夹下的ogr_FileGDB.dll 移动 到 osgeo文件夹下就可以了。
移动
  查看参数信息:
在这里插入图片描述
  查看支持的格式(部分):
在这里插入图片描述
  不仅告诉你OGR的版本带有哪些驱动程序,还告诉你每个驱动程序是否支持读写操作。
  可以通过Python决定哪些驱动程序可用,用交互式环境(IDLE)进行检测。首先,导入osgeo包内的OGR模块,再使用ogr.GetDriverByName查找一个特定的驱动程序:

>>> from osgeo import ogr
>>> driver = ogr.GetDriverByName('GeoJSON')  # GeoJSON不需要区分大小写
>>> print(driver)
<osgeo.ogr.Driver; proxy of <Swig Object of type 'OGRDriverShadow *' at 0x0000013B3CBE8840> 

  错误示范:

>>> driver = ogr.GetDriverByName('shapefile') # 正确的名字为:Esri shapefile
>>> print(driver)
None

2.2 升级pip命令(补充)

  1. 不要直接win+R然后cmd,而是要选择“开始”—“Windows系统”—“命令提示符”—右键“以管理员身份运行”!!!
python -m pip install --upgrade pip;
  1. 管理员身份运行命令提示符后,使用镜像下载升级!!!
python -m pip install --upgrade pip -i https://pypi.douban.com/simple

升级成功
延迟问题:raise ReadTimeoutError(self._pool, None, ‘Read timed out.’)

pip install --index-url https://pypi.douban.com/simple <model>
 
如:pip install --index-url https://pypi.douban.com/simple opencv-python

或者:

pip --default-timeout=100 install -U pip

镜像下载:(速度快,稳定,亲测有效)

  1. 清华镜像:https://pypi.tuna.tsinghua.edu.cn/simple
  2. 阿 里: http://mirrors.aliyun.com/pypi/simple
  3. 中科大: http://pypi.mirrors.ustc.edu.cn/simple
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com numpy

2.3 ospybook 1.0——Python可视化地理数据

  1. 优势:可以帮助你不用打开其他软件程序,就可以可视化数据
  2. 缺点:交互性差

安装方法:

  1. 安装包:ospybook-1.0文件夹下(下载地址:http://manning.com/garrard/?a_aid=geopy&a_bid=c3bae5be)
  2. 安装,定位到setup.py目录打开命令行运行:python setup.py build
  3. 再运行:python setup.py install

 在ospybook模块中将可用的驱动列表输出:

>>> import ospybook as pb  #  使用ospybook模块
>>> pb.print_drivers()     #  输出可用的驱动列表
ESRIC (readonly)
FITS (read/write)
PCIDSK (read/write)
netCDF (read/write)
PDS4 (read/write)
VICAR (read/write)
JP2OpenJPEG (readonly)
JPEG2000 (readonly)
PDF (read/write)
MBTiles (read/write)
BAG (read/write)
EEDA (readonly)
OGCAPI (readonly)
DB2ODBC (read/write)
ESRI Shapefile (read/write)
MapInfo File (read/write)

3. 矢量数据读取

  由Arcgis打开一个Shapefile格式的数据集,其中包含的一个全球数据集。
ne_50m_populated_places.shp
属性数据表
  通过Python进行输出:

import sys
from osgeo import ogr

fn = r'E:\Google\GIS\osgeopy data\global\ne_50m_populated_places.shp'
ds = ogr.Open(fn, 0) # ds = data source,0:表示以只读模式打开文件,1或True:表示以编辑模式打开
if ds is None:  # 确保shapefile文件不为空,可正常打开
    sys.exit('Could not open {0}.'.format(fn))
lyr = ds.GetLayer(0) # 获取图层索引,从0开始,不提供参数时,默认返回第1个图层

i = 0  # 从数据源中取回第1个图层,并遍历此图层中的前5个要素
for feat in lyr:

    
    pt = feat.geometry() # 获得几何对象
    x = pt.GetX()        # 获得坐标位置
    y = pt.GetY()

    # 获得属性值
    name = feat.GetField('NAME')
    pop = feat.GetField('POP_MAX')
    # pop = feat.GetFieldAsString('POP_MAX')  #  数据转换
    # pop = feat.GetFieldAsInteger('POP_MAX')
    print(name, pt, pop, x, y)
    i += 1
    if i == 5:
        break
del ds  # 删除ds变量,强制关闭文件
Bombo POINT (32.5332995248648 0.583299105614628) 75000 32.533299524864844 0.5832991056146284
Fort Portal POINT (30.2750016159794 0.671004121125236) 42670 30.27500161597942 0.671004121125236
Potenza POINT (15.7989964956403 40.6420021300982) 69060 15.798996495640267 40.642002130098206
Campobasso POINT (14.6559965589219 41.562999118644) 50762 14.655996558921856 41.56299911864397
Aosta POINT (7.31500259570618 45.7370010670723) 34062 7.315002595706176 45.7370010670723

3.1 访问特定要素

  方法:查看要素的具体偏移值,也就是要素编号(FIDs),偏移值从0开始,用于表示要素在这个数据集中所在的位置。
  获取图层中的最后一个要素:

>>> num_features = lyr.GetFeatureCount()
>>> last_feature = lyr.GetFeature(num_features - 1)
>>> print(last_feature.NAME)
Hong Kong

  当前要素:使用ResetReading()函数调用

import os
import sys
from osgeo import ogr
data_dir = r'E:\Google chrome\Download\GIS with python\osgeopy-data\osgeopy-data\osgeopy-data-washington\osgeopy-data'

fn = os.path.join(data_dir, 'Washington', 'large_cities.geojson')
ds = ogr.Open(fn, 0)
lyr = ds.GetLayer(0)
print('First loop')
for feat in lyr:
    print(feat.GetField('Name'), feat.GetField('Population'))

print('Second loop')
lyr.ResetReading() # This is the important line.
for feat in lyr:
    pt = feat.geometry()
    print(feat.GetField('Name'), pt.GetX(), pt.GetY())

3.2 查看数据

3.2.1 查看属性

  使用print_attributes函数输出属性值信息:

print_attributes(lyr_or_fn, [n], [fields], [geom], [reset] )
  1. lyr_or_fn 可以是一个图层,也可以是一个数据源路径。如果是一个数据源,使用的是第一个图层。
  2. n 是一个可选值,用于设置输出记录数目,默认输出所有数值。
  3. fields 是一个可选值,用于设置输出结果中包含的属性字段列表,默认包括所有字段。
  4. geom是一个可选的布尔值,用于设置是否输出几何要素类型,默认为True。
  5. reset是一个可选的布尔值,用于设置在输出数值之前,是否重置到第一条记录,默认为true。

  输出文件前3个城市的名字和人口:

>>> import ospybook as pb
>>> fn = r'E:\Google chrome\Download\GIS with python\osgeopy-data\osgeopy-data\osgeopy-data-global\osgeopy-data\global\ne_50m_populated_places.shp'
>>> pb.print_attributes(fn, 3, ['NAME', 'POP_MAX'] )

FID    Geometry                  NAME           POP_MAX    
0      POINT (32.533, 0.583)     Bombo          75000      
1      POINT (30.275, 0.671)     Fort Portal    42670      
2      POINT (15.799, 40.642)    Potenza        69060      
3 of 1249 features

  pb.print_attributes()函数可用用于查看小数据量的属性信息,不用于查看大数据的信息

3.2.2 绘制空间数据

  ospybook包含可以进行数据空间可视化的类,所以涉及到Python的matplotlib模块。绘制显示数据,需要先创建VectorPlotter类的新实例。交互模式时,绘制数据会立刻显示出来;不是交互模式时,绘制完数据后,需要调用draw函数。
  plot函数:

plot(self, geom_or_lyr, [symbol], [name], [kwargs])
  1. geom_or_lyr 可是是一个要素对象、图层或者指向一个数据源的路径。如果是一个数据源,数据源中的第一个图层会被绘制显示
  2. symbol是一个可选值,用于设置几何要素的符号样式
    1. fill=False:空心多边形
    2. “bo”:蓝色圆圈
    3. “rs”:正方形
    4. “b-” :蓝线
    5. “r–”: 虚线(每个单元是横的)
    6. “g” :虚线(每个单元是竖的)
  3. name是一个可选值,用于为数据设定名称,以便后期可以访问它
  4. kwargs是一个可选值,通过关键字进行指定。kwargs经常被用作一个不确定数量的关键字参数(an indeterminate number of keyword arguments)的缩写

matplotlib

由matplotlib绘制地图:

>>> import os
>>> os.chdir(r'E:\Google chrome\Download\global') #  更改工作目录,可直接使用该文件夹下的文件名,而不需要从新键入整个目录
>>> from ospybook.vectorplotter import VectorPlotter
>>> vp = VectorPlotter(True)  #  创建一个交互式绘图面板
>>> from matplotlib.pyplot import *     # 此处需要导入matplotlib模块进行绘图
>>> vp.plot('ne_50m_admin_0_countries.shp', fill=False)  # fill参数使文件用空心多边形表示
>>> vp.plot('ne_50m_populated_places.shp', 'bo')  # bo表示蓝色圆圈
>>> vp.draw()

显示结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/amyniez/article/details/113061835