带有明确边界的地理要素,如城市,可以用矢量数据进行很好的表示。但是,连续的数据(如高程数据)则不行。如果在山区,在所有具有相同高程的区域边界绘制一个多边形是非常困难的。但是,可以使用不同的多边形来区分不同的海拔范围。许多种类的数据非常适合于用矢量进行表示。例如,道路图上的要素,道路用线段表示,市县用多边形表示,而城市根据地图比例尺的不同,用点或者多边形表示。地图上所有的要素都有可能用点、线、面来表达。
矢量数据非常适合用于制作地图,但也存在一些不足。如,绘制显示时,如何进行缩放,才能达到更好的显示效果。
海岸线悖论
英国数学家Lewis Fry Richardson是第一位量测陆地海岸线的人。但量测的过程并不那么容易,因为最终的量测结果完全取决于选取的比例尺度。例如,一个具有多个海峡的宽广海岸线,旁边有一条道路。试想一下,沿着这条道路开车,使用汽车的里程表测量距离,然后走出车沿着来的路往回走。但是,徒步时,是沿着海峡的边缘曲线,而道路不是。很容易想出,走的路程比开车要远,因为走了很多弯路。同样的道理也适用于量测整个海岸线,因为如果以较小的增量进行量测,可以量测更多的变化。在量测英国海岸线时,使用50千米的增量要比100千米的增量所量测出的最终长度多600千米。
Shapefile是储存矢量数据的一种通用格式。但其并不是一个单独的文件。它至少需要3个二进制的文件,包括:1个主文件(.shp),1个索引文件(.shx),储存几何信息,和1个dBASE(.dbf)表,来储存属性数据,并且需要确保这三个文件都储存在同一个文件夹中。
另一种格式是GeoJSON,都是纯文本文件,可以使用在任何文本编辑器中。一个GeoJSON只包含1个文件,储存所有必要的信息。
例如:在线geojson数据格式地图
手动绘制地图
OGR简单要素库是地理空间数据抽象库( Geospatial Data Abstraction Library,GDAL)的一部分,它是一个非常流行的用于读写空间数据的开源库。GDAL的OGR部分具有读写许多不同矢量数据格式的功能。OGR还允许你创建和操作要素的几何形状、编辑其属性值、基于属性值或空间位置对矢量数据进行筛选,而且它还提供数据分析能力。
GDAL库最初是用C和C ++编写的,但它与其他几种语言,包括Python,做了绑定,所以尽管这些代码没有用Python进行重写,但它为Python中使用GDAL/OGR库提供了接口。因此,要想在Python中使用GDAL, 需要安装GDAL库以及相应的Python绑定。
此数据源中包含多个子图层对象,每一个图层代表数据源中的一个数据集,Shapefile只包含一个数据集(一个图层),但SpatiaLite包含多个。无论一个数据源有多少个数据集,每一个数据集都被OGR认为是一个图层。
一个数据源由一个或多个图层组成。
Arcgis中属性表,每一行代表一个要素,每一列代表一个属性字段:
用于输出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
python -m pip install --upgrade pip;
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
镜像下载:(速度快,稳定,亲测有效)
pip install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com numpy
安装方法:
在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)
由Arcgis打开一个Shapefile格式的数据集,其中包含的一个全球数据集。
通过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
方法:查看要素的具体偏移值,也就是要素编号(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())
使用print_attributes函数输出属性值信息:
print_attributes(lyr_or_fn, [n], [fields], [geom], [reset] )
输出文件前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()函数可用用于查看小数据量的属性信息,不用于查看大数据的信息
ospybook包含可以进行数据空间可视化的类,所以涉及到Python的matplotlib模块。绘制显示数据,需要先创建VectorPlotter类的新实例。交互模式时,绘制数据会立刻显示出来;不是交互模式时,绘制完数据后,需要调用draw函数。
plot函数:
plot(self, geom_or_lyr, [symbol], [name], [kwargs])
由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()