在开始之前,先运行:
import sqlite3 as sqlite
conn = sqlite.connect(":memory:")
conn.enable_load_extension(True)
conn.execute('SELECT load_extension("mod_spatialite")')
cursor = conn.cursor()
cursor.execute('''
select MakePoint(391390, 5817855);
''')
for rec in cursor: print(rec)
(b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00x\xe3\x17A\x00\x00\x00\xc0\x7f1VA\x00\x00\x00\x00x\xe3\x17A\x00\x00\x00\xc0\x7f1VA|\x01\x00\x00\x00\x00\x00\x00\x00x\xe3\x17A\x00\x00\x00\xc0\x7f1VA\xfe',)
cursor.execute('''
SELECT MakeLine(MakePoint(20,50), MakePoint(19.95,49.98));''')
for rec in cursor: print(rec)
(b'\x00\x01\x00\x00\x00\x0033333\xf33@=\n\xd7\xa3p\xfdH@\x00\x00\x00\x00\x00\x004@\x00\x00\x00\x00\x00\x00I@|\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x004@\x00\x00\x00\x00\x00\x00I@33333\xf33@=\n\xd7\xa3p\xfdH@\xfe',)
cursor.execute('''
SELECT AsText(MakeLine(MakePoint(20,50), MakePoint(19.95,49.98)));''')
for rec in cursor: print(rec)
('LINESTRING(20 50, 19.95 49.98)',)
现在执行第一个查询。
conn = sqlite.connect("spalite.db")
conn.enable_load_extension(True)
conn.execute('SELECT load_extension("mod_spatialite")')
cursor = conn.cursor()
sql = 'SELECT name , AsText(Geometry) from prov_capital limit 5'
cursor.execute(sql)
<sqlite3.Cursor at 0x7f914ce857c0>
for x in cursor:
print(x)
('乌鲁木齐', 'POINT(87.576106 43.781766)') ('拉萨', 'POINT(91.163128 29.710353)') ('西宁', 'POINT(101.797123 36.593385)') ('兰州', 'POINT(103.584065 36.118845)') ('成都', 'POINT(104.035277 30.714088)')
AsText()
是SpatiaLite 函数, 它返回 Geometry 字段的 WKT 值。 在前面,
我们使用 HEX()
函数返回无法查阅的二进制数据。 现在, AsText()
函数返回有用,且是易于理解的字符串。
点是最简单的 Geometry 类,且它只由一对 [X, Y]
坐标构成。
下面我们使用不同的方式来执行前面的查询。
sql = 'SELECT name , X(Geometry), Y(Geometry) FROM prov_capital limit 5;'
cursor.execute(sql)
<sqlite3.Cursor at 0x7f914ce857c0>
for x in cursor:
print(x)
('乌鲁木齐', 87.57610577000008, 43.78176563200003) ('拉萨', 91.16312837700008, 29.710352750000027) ('西宁', 101.79712276100008, 36.59338523400004) ('兰州', 103.58406526900006, 36.11884538500004) ('成都', 104.03527735800009, 30.714088160000074)
SpatiaLite的 X()
函数,返回点的 X 坐标。 Y()
函数返回点的 Y
坐标。
使用下面的 Geometry格式转换函数:
sql = "SELECT HEX(GeomFromText('POINT(10 20) '));"
cursor.execute(sql)
<sqlite3.Cursor at 0x7f914ce857c0>
for rec in cursor:
print(rec)
('00010000000000000000000024400000000000003440000000000000244000000000000034407C0100000000000000000024400000000000003440FE',)
sql = "SELECT HEX(AsBinary(GeomFromText('POINT(10 20) ')));"
cursor.execute(sql)
<sqlite3.Cursor at 0x7f914ce857c0>
for rec in cursor:
print(rec)
('010100000000000000000024400000000000003440',)
sql = "SELECT AsText(GeomFromWKB(X'010100000000000000000024400000000000003440'));"
cursor.execute(sql)
<sqlite3.Cursor at 0x7f914ce857c0>
for rec in cursor:
print(rec)
('POINT(10 20)',)
- SpatiaLite的函数
GeomFromText()
返回使用内部BLOB
方式表示的几何图形; - 函数
AsBinary()
返回WKB(Well Known Binary)表示的几何图形; - 函数
GeomFromWKB()
将WKB的值,转换成对应的内部BLOB的值。
WKB是实现了OpenGIS规范的一种表示方法
import sqlite3 as sqlite
conn = sqlite.connect("spalite.db")
conn.enable_load_extension(True)
conn.execute('SELECT load_extension("mod_spatialite.so")')
<sqlite3.Cursor at 0x7f914ce84440>
cursor = conn.cursor()
sql = "SELECT ogc_fid, AsText(Geometry) FROM hyd2_4l limit 5"
cursor.execute(sql)
--------------------------------------------------------------------------- OperationalError Traceback (most recent call last) Cell In[18], line 2 1 sql = "SELECT ogc_fid, AsText(Geometry) FROM hyd2_4l limit 5" ----> 2 cursor.execute(sql) OperationalError: no such table: hyd2_4l
for rec in cursor: print(rec)
LINESTRING 是另一个 GEOMETRY 类,并由许多点组成。 在上面你得到一个非常简单的 LINESTRING ,使用四个顶点来表示线。 在实际的GIS数据中,为数以千计的顶点组成的线计数并不简单。
为了更进一步了解,我们来看下面的例子。
sql = '''SELECT ogc_fid, NumPoints(Geometry), GLength(Geometry) ,Dimension(Geometry),
GeometryType(Geometry) FROM hyd2_4l ORDER BY NumPoints(Geometry) DESC LIMIT 5'''
cursor.execute(sql)
[print(x) for x in cursor]
SpatiaLite 的 NumPoint()
函数返回线几何要素的顶点的数目。 GLength()
函数返回以地图单位计算的线几何类型的几何长度。 Dimension()
函数返回任何一种几何类的维度(对线来讲是1)。 GeometryType()
函数返回任何 Geometry 类型的值。
下面我们来看更多的函数。
sql = '''SELECT ogc_fid, NumPoints(Geometry),
AsText(StartPoint(Geometry)), Y(PointN(Geometry, 2))
FROM hyd2_4l ORDER BY NumPoints(Geometry) DESC LIMIT 5'''
cursor = cursor.execute(sql)
[print(x) for x in cursor]
sql = 'SELECT name, AsText(Geometry) FROM region_popu WHERE ogc_fid=52'
cursor.execute(sql)
for x in cursor: print(x[0], x[1][:50])
POLYGON 是另外一个GEOMETRY类。 POLYGON 是一个非常简单的多边形,且只有此部的环(没有内部的洞)。 要注意,POLYGON可以包含何意数据的洞, 通过内部环分隔开来。
外部环是一个简单的 LINESTRING (内部洞也是 LINESTRING )。 注意 POLYGON 是一个闭合的几何类型, POLYGON的第一个点与最后一个点的位置是完全相同的。
sql = '''SELECT Area(Geometry), AsText(Centroid(Geometry)),
Dimension(Geometry), GeometryType(Geometry) FROM region_popu
ORDER BY Area(Geometry) DESC LIMIT 5'''
cursor.execute(sql)
[print(x) for x in cursor]
在前面我们使用了 SpatiaLite 的 Dimension()
函数与 GeometryType()
函数。
对于 POLYGON 类型,这两个函数的意义与其他都是一样的。 SpatiaLite的
Area()
函数返回多边形的几何面积, Centroid()
函数返回多边形几何要素的质心。
sql = '''SELECT ogc_fid, NumInteriorRings(Geometry),
NumPoints(ExteriorRing(Geometry)),
NumPoints(InteriorRingN(Geometry, 1))
FROM region_popu ORDER BY NumInteriorRings(Geometry) DESC LIMIT 5'''
cursor.execute(sql)
[print(x) for x in cursor]
SpatiaLite 的 ExteriorRing()
函数返回给定几何要素的外部线环。
任何有效的多边形要素必须要有一个外部线环,并且这个线环是闭合的。
SpatiaLite 的 NumInteriorRings()
函数返回多边形中内部洞的数目可以是一个有效的多边形可以有一些洞,也可以没有。
SpatiaLite 的 InteriorRingN()
函数以 LINESTRING 的格式返回第 N
个内部洞。 每个洞都以相对索引来标识:第一个的索引值是1,
第二个的索引值是2,其余依次类推。
ring
一个 LINESTRING, 所以我们可以使用 NumPoints()
函数来获取相关的顶点的数目。
在无效的要素上,则返回结果为NULL
。
查看多边形的坐标
sql = '''SELECT AsText(InteriorRingN(Geometry, 1)),
AsText(PointN(InteriorRingN(Geometry, 1), 4)),
X(PointN(InteriorRingN(Geometry, 1), 5))
FROM region_popu WHERE ogc_fid=2'''
cursor.execute(sql)
for x in cursor: print(x)
我们已经在前面遇到过用法了。
对于POLYGON来说,它变得更加乏味,但仍然容易理解。
例如,为了获得最后一列,我们使用了 InteriorRingN()
来获取第一个内部环,
然后通过 PointN()
获得第五个顶点。
最后我们可以调用 X()
、 Y()
来获取坐标值。
更多的类型
点、线、面是 GEOMETRY 中的基本类。 但是 GEOMETRY 也支持复杂类。
- MULTIPOINT 是属于同一个实体的两个或更多点的集合。
- MULTILINESTRING 是两个或更多线状要素。
- MULTIPOLYGON 是两个或更多多边形要素。
- GEOMETRYCOLLECTION 是包含多种要素类型的集合。
对于上面这些类型就不进行更多说明了。总体来讲, 这个类型比基本的类型会多一些性质。
- SpatiaLite 的
NumGeometries()
函数返回集合中元素的数目。 GeometryN()
函数返回集合中的第N
个元素。GLength()
函数由MULTILINESTRING
集合中所有线状要素组成的各单独长度的和。Area()
函数返回MULTIPOLYGON
集中中所有多边形要素的单独面积的和。Centroid()
函数返回MULTIPOLYGON
的平均质心。
import sqlite3 as sqlite
conn = sqlite.connect("spalite.db")
conn.enable_load_extension(True)
conn.execute('SELECT load_extension("mod_spatialite.so")')
cursor = conn.cursor()
下面是所有 GEOMETRY 类的基本属性:
sql = '''SELECT Name, AsText(Envelope(Geometry)) FROM region_popu LIMIT 5'''
cursor.execute(sql)
for x in cursor:
print(x)
SpatiaLite 的 Envelope()
函数总是返回给定多边形的最小边界矩形。
(Minimum Bounding Rectangle - MBR)。
最小边界矩形由5个点组成(第一个点与最后一个点是相同的)。 需要注意,
在不同的投影方式,同一多边形的最小边界矩形是不一样的(包括形状、大小与方向)。
MBR 也被称为矩形边界框(bounding boxes, BBOX)
有效的点如下所示。
- POINT #1: minX,minY
- POINT #2: maxX,minY
- POINT #3: maxX,maxY
- POINT #4: minX,maxY
- POINT #5: minX,minY
MBR 在使用中是比较特别的。 通过 MBR, 可以对多边形的空间关系进行简单与大致的分析。 由于 MBR 计算起来非常快, 所以在提高数据处理速度中得到了广泛的应用。
到目前,通过前面的实例,对于空间数据处理的基本核心有了基本的了解。