12. 矢量要素的重构

[sec:vectstruk]

在GRASS 中矢量要素进行了全面的修改,包含一个新的矢量格式,它去掉了 中的限制。因此,在概述里我们会介绍许多有趣的创新和改变。

12.1. GRASS 的新特性

[subsec:features]

矢量的几何属性:

  • 支持外部的“简单要素”,如SHAPE或PostGIS,不需要提前导入(通过建立’’虚拟映射’’,只有读取权限);
  • GRASS与OGR支持的矢量格式间的导入和导出;
  • 为了减少计算时间(如:建立拓朴结构,中的)而增加的’’空间索引’’。

数据库管理:

  • 属性存储在DBMS中(基于SQL的接口,用于dBase、PostgreSQL、MySQL和ODBC);
  • 属性存储在内部的dBase文件(默认)或外部的DBMS中;
  • 要素可以与一个或多个外部数据库表进行连接;
  • 可以创建3D矢量(如:TINs,CAD图),并可以用NVIZ来显示。

模块:

  • 支持SQL查询/选择,例如,和;
  • 可以在查询中直接更新属性(如:可以改变用直接连接的属性);
  • 基于DGLIB (Directed Graph Library)的矢量网络分析;
  • 新的GUI数字化模块;
  • 通过OGR可以输出为Shapefile,DGN,TIGER,MapInfo和GML2;
  • 通过’窗体库’实现了用户界面友好的模块管理;
  • 新的GIS管理器();

为了熟悉新的矢量要素的使用,下面的章节主要着眼于GRASS 的创新 – 尤其是几何形状和属性的管理。

12.2. 几何形状的管理

[subsec:vectgeo]

几何形状的管理在GRASS 中彻底地改变了。作为标准设置,几何形状存储为新的GRASS特有的矢量格式(“自有格式”)。基本设置可以更改,因此现有的PostGIS,Shapefile和其它OGR支持的格式也能存储和处理。

[H]

image [abb:varchitek]

为了更好地理解,我们会介绍不同的、当前支持的矢量格式的使用。我们使用了FRIDA项目的自由地理数据(请参阅)。

12.2.1. 处理OGR格式

由于OGR支持的实现,现在可以使用众多的矢量格式。OGR支持格式的详细列表可以在第[tab:vecimp]章的页中找到,也可在OGR的主页上找到。

在GRASS中可以直接使用ESRI的Shapefile。为了这一目的需要使用新的内建模块,它会在GRASS和OGR源间建立必要的连接。在此过程中会为非拓朴数据自动建立GRASS内部的伪拓朴信息,这样一来这些数据也可以进行网络分析。注意,在使用时GRASS对数据是只读的,它会比导入的数据读取要慢一些:

# Create a SHAPE link
v.external dsn=./gdf/shapes/layer=frida_stras out=frida_stras_ext

# Display SHAPE
d.vect frida_stras_ext

# Query SHAPE
d.what.vect frida_stras_ext

如果要更改数据,那么OGR数据源必须导入为GRASS自有的格式:

g.copy vect=frida_stras_ext,frida_stras_int
v.digit frida_stras_int

要完成这一任务,您可以通过来拷贝已经加载的地图,也可以用导入数据集(请参阅[sec:vectimport])。

同样地,所有OGR支持的格式都能够在GRASS中使用且/或导入。

PostGIS也能够通过UMN mapserver的接口使用,所以通过PostGIS和UMN mapserver在互联网上展示GRASS的成果图是很容易的。

12.2.2. 在DBMS之外创建几何形状

[subsubsec:dbmsgeo]

如果坐标对(X/Y)和属性存储为DBF、CSV、MS-Excel、PostgreSQL等,那么可以用它们在GRASS中生成地图。本例中使用’mydb’数据库(存储在PostgreSQL)中的’stations’表:

v.in.db driver=pg database="host=localhost,dbname=mydb,user=postgres" \
        table=stations x=east y=north z=quota key=ID output=stations

如果dBase表中没有ID字段,那么您需要用其它的程序(如Openoffice.org)创建一个递增的ID数值。

12.2.3. 使用XY或XYZ文本文件创建几何形状

[subsubsec:txtgeo]

如果XY或XYZ坐标存储为简单的ASCII文本’coords.txt’,那么可以用下面的方法创建2D或3D地图:

  1. 2D地图的例子:
  1664619|5103481
  1664473|5095782
  1664273|5101919
  1663427|5105234
  1663709|5102614

# Import to GRASS:
cat coords.txt | v.in.ascii out=my2dmap

# Supplementation of missing category values for attaching
# attributes later
v.category in=my2dmap out=my2dmap_final op=add
v.category my2dmap_final op=report
  1. 3D地图的例子:
  1664619|5103481|445.1
  1664473|5095782|534.2
  1664273|5101919|532.9
  1663427|5105234|454.4
  1663709|5102614|525.7

Import to GRASS:
cat coords.txt | v.in.ascii -z out=my3dmap

# Supplementation of missing category values for attaching
# attributes later
v.category in=my3dmap out=my3dmap_final op=add
v.category my3dmap_final op=report

可以用来赋属性值。

12.3. 属性的管理

[subsec:vectatt]

GRASS 中的属性管理完全地改变了。GRASS 中的’dig_cats/’结构不再存在。所有的属性现在都存储在数据库表中,并通过DBMI (Database Management Interface)与几何形状连接。现在可以使用下面的DBMI驱动:

  • DBF(默认)
  • PostgreSQL数据库
  • MySQL数据库
  • 通过ODBC连接RDBMS(如:Oracle、MySQL、PostgreSQL等)

矢量地图与属性表的连接在GRASS内部定义为’dbln’文件,这是一个ASCII文件,存储在矢量地图的文件夹中。当地图导入GRASS时生成这个文件。 如果后来生成了一个表,那么需要用将新的连接添加到该文件中。当前的连接可以用命令来验证。

可以在矢量地图和属性表间建立连接,因此每个表可以连接到不同的图层上:

v.db.connect map=vectormap table=attribute1 layer=2
v.db.connect map=vectormap table=attribute2 layer=3
v.db.connect -p vectormap

在[intersect]中我们会举一个例子。

注意:

有一点十分得重要,在删除矢量地图的时候,所有’dbln’文件中的属性表(即与地图相连接的表)都会被删除。为了避免这种情况,我们可以为每个属性表做一个拷贝,然后将拷贝连接到矢量地图上,而不是原始属性表。

db.copy from_driver=dbf from_table=origtable to_driver=dbf \
to_table=copytable

用下面的命令改变当前的数据库设置:

在GRASS中模块完全独立于,它只允许修改属性表。dbf格式是默认值,可以用下面的命令来设置:

db.connect driver=dbf database='$GISDBASE/$LOCATION_NAME/$MAPSET/dbf/'

由于属性数据可以存储在外部数据库(如PostgreSQL)中,所以必然要有用户的管理。模块控制着数据库,并且将它的信息存储在中。

组的管理也是需要的。可能是下面的情况:

Location -> database
Mapset -> database-scheme
UNIX-User -> database-user
UNIX-Group -> database-group

现在,可以对不同的地图集和区域赋予不同的权限。在GRASS中可以使用。

请记住,Unix用户和数据库用户必须手工地进行同步。当删除一个Unix用户的时候,相应的数据库用户也必须由管理员手工地删除,这一点很重要。

12.3.1. 显示属性

[sec:printatt]

在控制台中提供了属性数据的基本报告。所有属性数据以定义的字段分隔符显示出来。

# Print attributes of vector-map roads
v.db.select map=roads fs="|"
cat|label
0|no data
1|interstate
2|primary highway, hard surface
3|secondary highway, hard surface
4|light-duty road, improved surface
5|unimproved road

12.3.2. 添加属性

[sec:addatt]

模块可以为矢量对象添加有用的属性,包括:

  • 明确的类别值,只要它原来不存在(cat, means IDs)
  • 坐标对(coords)
  • 多边形的面积(area)
  • 矢量线的长度(length)
  • 每个类别的要素数目(count)
  • 左右限制区域的类别(sides)
  • 查询的结果(query)

但是,必须在属性表中添加额外的字段(对于点坐标需要添加两个字段)。这可以使用其他软件(如OpenOffice)来完成,也可以直接在GRASS中完成:

# create additional integer-column (in dBASE format):
echo "ALTER TABLE <vectormap> ADD COLUMN <column> integer" | db.execute

# Add vector length:
v.to.db map=<vectormap> option=length units=meters col1=<column>

# Query for verification:
echo "SELECT * FROM <vectormap>" | db.select

12.3.3. 操作属性

[sec:manipulatevect]

GRASS也能够操作矢量的属性。通过SQL命令’UPDATE’,根据不同的查询条件,我们可以更新相应的属性:

# update column area larger than 200:
echo "UPDATE <table> SET attribute1 = 2 WHERE area > 200"| db.execute

如果属性存储在PostgreSQL中,那么可以通过命令行工具(来自postgres)使用更多的SQL命令。

我们也可以基于计算的结果来更新记录。上面的例子可以作如下修改:

# update column area larger than 200
# based on calculations:
echo "UPDATE <table> SET area = (area*1000) WHERE \
        area > 200"| psql -d <PG-database>

我们也可以交互式地操作属性。用模块打开并查询矢量文件。属性将显示在独立的弹出窗口中,在这里我们可以用鼠标选择并编辑属性。

QGIS中新设计的GRASS插件提供了另一种编辑GRASS矢量文件的方法。该软件的简要描述在第[sec:qgis]章中。