如何把GIS(地理信息)迁移至DWS——抛转引玉
1 概述
DWS可以通过postgis插件实现对gis类数据支撑,这里不做过多介绍,今天主要谈一下如何将其他系统的gis类数据迁移至DWS中。
目前通用的迁移方式还是针对各个数据库的GIS类数据转换为shape格式,再将其转换为各数据库适用方式。 由于postgis插件已提供shape类型数据转换功能,这里主要以oracle举例,来看一个比较简单的实现oracle spatial数据迁移至DWS中的方法。 此种方式非最佳方式,仅供参考。
迁移流程图
转换流程图如下,oracle中地理数据使用spatial函数处理,这里针对oracle中的地理数据称为spatial类型。迁移过程汇总需要通过工具将spatial数据需要转换为标准格式shape类型,再由shape类型再转换为DWS对应的SQL,最后通过SQL将数据插入DWS中。
2 特别说明
l 暂无脚本化方案,需人工操作
Oracle中spatial类型需要借助windows软件进行抽取、转换,同时转换后的shape类型需要借助postgis插件工具进行再转换为SQL文件。故需要将数据文件在windows平台与linux平台进行转存。
l 转换后的SQL脚本需要人工写脚本进行二次处理
转换后的SQL内容中涉及建表、查询部分需要针对双引号进行替换处理,否则可能引起DWS中的表名被特殊化(区分大小写);
涉及数据量较大的文件,需要将insert values语句通过脚本方式(暂不提供,需自行编写)解析为平面文件,通过gds、copy等方式快速加载入库。
l 相关软件需自行下载
Oracle客户端、pl/sql develop、FME 软件等需要自行下载。
3 前期准备
3.1 oracle客户端
l oracle客户端
64位oracle windows 客户端下载地址如下,注意配置tnsnames.ora,具体安装方式不做介绍。
https://www.oracle.com/database/technologies/112010-win64soft.html
下面为精简版oracle客户端,配置环境变量后依照提示重启电脑生效。
https://www.jb51.net/database/575444.html
l oracle客户端工具
为方便查询oracle数据,建议同步安装PL/SQL Developer ,该工具依赖 32位oracle 客户端。
3.2 FME
该工具是加拿大Safe Software公司开发的空间数据转换处理系统,这里单独使用其转换功能。下载地址如下(亦可搜索中文版):
3.3 postgis for DWS
为DWS 安装postgis 插件,具体可参考产品手册。
4 数据迁移流程
4.1 转换oracle spatial 数据到 shape类型(工具FME)
1、 打开FME Workbench 程序
2、 添加1个reader
3、 reader中设置format为 “Oracle Spatial Object”,点击Parameter键入链接信息。
4、 输入oracle链接信息后,点击表,选择要处理的表(支持多选)
5、 添加writer,选择格式为Esri Shapefile,同时添加文件路径。
6、 根据表中内容判断数据类型,选择对应类型。这里原表中SHAPE.SDO_GTYPE是2003 对应多边形(具体见附录介绍)。
7、 创建完成后,将reader向writer链接起来,作为一个流程。
8、 正常情况下都是绿色箭头,证明已自动对应。否则点击连接线添加atrributerenamer,并在其中输入提示部分的对应字段使之映射起来。
9、 点击run,运行作业。
10、 此时在目录下会生成3个文件。dbf、shp、shx。截止到此已将oracle spatial数据转换为shape类型。11操作开始属于数据展示,不需要做。
11、 打开inspector,选择报错的shp文件后,可对shp文件进行解析展示。(依照图片操作或从开始菜单打开)
展示如下(数据已隐藏,上图是数据解析后的多边形地图信息)
4.2 shape 类型数据转 SQL
1、 Ruby 用户进入$GAUSSHOME/bin 目录下。
2、 使用shp2pgsql工具将shape文件转为DWS可识别的SQL文件。具体参考帮助信息。
3、 转换后的SQL信息如下(数据保护,仅展示部分不涉密数据):
4.3 SQL 数据插入 DWS
此步骤略。登录后执行SQL即可,注意表名默认使用双引号包围,需要批量替换删除。
若数据量较大,该方式入库性能会较低。可手动编写脚本对insert values数据转为平面文件,再通过gds、copy等方式加载入库。
5 总结
l 根据在测结果显示,oracle spatial数据类型可转存到DWS
现场测试SHAPE.SDO_GTYPE类型为2001、2002、2003 均通过,可正常存入DWS。
l 涉及地理数据的表一般不大,理论上可通过程序直接读取后插入。
6 附录
6.1 Oracle Spatial的类型介绍
https://www.cnblogs.com/steer-life/p/sdo_geometry.html
SDO_GTYPE值是有四位数字组成的,有4位数字构成 dltt
· d:表示几何的维数。如二维、三维对应的d=2和d=3;
· l:标识三维线状参考系统(Linear referencing system,LRS)几何体的LRS度量维,即哪一维含度量值(measure value),可能的取值为3、4,对于非LRS几何体或者以ORACLE SPATIAL默认的最后一维为LRS度量维,则l取值为0;
· tt:定义了地理对象的类型。现在使用从00到07,如tt=01代表为单点;
下面就是t=2的二维几何类型,SDO_GTYPE参数值具体如下:
组合值含义如下:
6.2 Oracle Spatial介绍(含数据构造):
https://www.cnblogs.com/qiaojun/articles/9901552.html
Oracle Spatial由一坨的对象数据类型,类型方法,操作子,函数与过程组合而成。一个地理对象作为一个SDO_GEOMETRY对象保存在表的一个字段里。空间索引则由普通的DDL和DML语句来建立与维护。
创建表: CREATE TABLE cola_markets
( mkt_id NUMBER PRIMARY KEY,
name VARCHAR2(32),
shape SDO_GEOMETRY
);
插入数据:
INSERT INTO cola_markets
VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data ) );
INSERT INTO cola_markets VALUES(
2,
'cola_b',
SDO_GEOMETRY( 2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1) ) );
INSERT INTO cola_markets VALUES(
3,
'cola_c',
SDO_GEOMETRY( 2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,1), -- one polygon (exterior polygon ring)
SDO_ORDINATE_ARRAY(3,3, 6,3, 6,5, 4,5, 3,3) ) );
INSERT INTO cola_markets VALUES(
4,
'cola_d',
SDO_GEOMETRY( 2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,4), -- one circle
SDO_ORDINATE_ARRAY(8,7, 10,9, 8,11) ) );
更新视图:
USER_SDO_GEOM_METADATA INSERT INTO user_sdo_geom_metadata (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
VALUES ( 'cola_markets', 'shape', SDO_DIM_ARRAY( -- 20X20 grid SDO_DIM_ELEMENT('X', 0, 20, 0.005), SDO_DIM_ELEMENT('Y', 0, 20, 0.005) ), NULL -- SRID );
创建空间索引:
CREATE INDEX cola_spatial_idx ON cola_markets(shape) INDEXTYPE IS MDSYS.SPATIAL_INDEX; -- Preceding statement created an R-tree index.
这样在mapguide下就可以preview空间数据信息.
下面来说一下其中最关键的一些object:
( SDO_GEOMETRY对象类型 在Spatial中,地理对象的描述是放在一个单独的类型为SDO_GEOMETRY的字段中的。任何有这个字段的表,都至少要定义一个其它主键字段。
Oracle Spatial定义的SDO_GEOMETRY类型为:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY);
当然Spatial也定义了SDO_POINT_TYPE, SDO_ELEM_INFO_ARRAY, 和 SDO_ORDINATE_ARRAY类型:
CREATE TYPE sdo_point_type AS OBJECT (
X NUMBER,
Y NUMBER,
Z NUMBER);
CREATE TYPE sdo_elem_info_array AS VARRAY (1048576) of NUMBER;
CREATE TYPE sdo_ordinate_array AS VARRAY (1048576) of NUMBER;
因为SDO_ORDINATE_ARRAY最大为1048576,所以SDO_GEOMETRY对象的顶点数量就依赖于它的维度,二维为524288,三维为349525,四维只有262144个顶点了。
注意:
对于一个给定的层(同一字段),所有的地理对象必须都是相同的维度,不能将二维与三维的数据放在一个层里。
如果你使用四位的SDO_ETYPE那么,你也要使用四位的SDO_GTYPE。
)
SDO_GEOMETRY Object Type
2.1 SDO_GTYPE dltt
d:维数
l:linear referencing system (LRS)
tt:Geometry type
00 UNKNOWN_GEOMETRY
01 POINT
02 LINE or CURVE
03 POLYGON
04 COLLECTION
05 MULTIPOINT
06 MULTILINE or MULTICURVE
07 MULTIPOLYGON
2.2 SDO_SRID
确认coordinate system,此值为SDO_COORD_REF_SYS表中的SRID值。此值也被插入到USER_SDO_GEOM_METADATA视图中。
2.3 SDO_POINT
(1)SDO_ELEM_INFO and SDO_ORDINATES are both null
(2)SDO_POINT attribute is non-null
结论:存储坐标
2.4 SDO_ELEM_INFO
用来解释存储在SDO_ORDINATES属性中的坐标信息。
SDO_STARTING_OFFSET:SDO_ORDINATES中的offset min为1
SDO_ETYPE: 1, 2, 1003, and 2003 simple elements; 3 polygon ring; 4, 1005, and 2005 compound elements
SDO_INTERPRETATION
2.5 SDO_ORDINATES
长数组,存放空间对象的坐标
2.6 Usage Considerations
SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT 用来检查几何对象的一致性。
1.1 SDO_GEOMETRY字段详解
Oracle Spatial的空间数据都存储在空间字段sdo_Geometry中,理解sdo_Geometry是编写Oracle Spatial程序的关键。sdo_Geometry是按照Open GIS规范定义的一个对象,其原始的创建方式如下所示:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES SDO_ORDINATE_ARRAY);
该对象由五个部分组成,各部分的意义如下表所示:
字段名
|
类型
|
描述
|
SDO_GTYPE
|
NUMBER
|
几何对象的类型
|
SDO_SRID
|
NUMBER
|
几何对象的坐标系
|
SDO_POINT
|
SDO_POINT_TYPE
|
表示几何类型为点的几何对象
|
SDO_ELEM_INFO
|
SDO_ELEM_INFO_ARRAY
|
是一个可变长度的数组,每3个数作为一个元素单位,用于解释坐标是如何存储在SDO_ORDINATES中的
|
SDO_ORDINATES
|
SDO_ORDINATE_ARRAY
|
是一个可变长度的数组,用于存储几何对象的真实坐标,该数组的类型为NUMBER型
|
表1.1.1 sdo_geometry 各组成部分的意义
① SDO_GTYPE
是一个NUMBER型的数值,用来定义存储几何对象的类型。SDO_GTYPE是一个4个数字的整数,其格式为dltt,其中d表示几何对象的维数;l表示三维线性参考系统中的线性参考值,当d为3维或者4维时需要设置该值,一般情况下为空;tt为几何对象的类型,Oracle Spatial定义了7种类型的几何类型,目前,tt使用了00到07,其中08到99是Oracle Spatial保留的数字,以备将来几何对象扩展所用。下表描述了Oracle Spatia1支持的几何对象类型。
数值 几何类型 描述
DL00 用于存放自定义类型的几何对象
DL01 点 几何对象包含一个点
DL02 直线或曲线 几何对象由直线或曲线段组成
DL03 多边形 几何对象包含一个多边形,该多边形可以含有洞
DL04 复合形状集 点、线、多边形超集,可包含所有类型
DL05 复合点 几何对象由一个点或多个点组成
DL06 复合线或曲线 几何对象由一条线或多条线组成
DL07 复合多边形 几何对象可以包含多个外环、多个不相交的多边形
DL08 - 99 Oracle Spatial 暂且保留
表1.1.2 Oracle Spatia1支持的几何对象类型
② SDO_SRID
SDO_SRID也是一个NUMBER型的数值,它用于标识与几何对象相关的空间坐标系。如果SDO_SRID为空(null),则表示没有坐标系与该几何对象相关;如果该值不为空,则该值必须为MDSYS.CS_SRS表中SRID字段的一个值,在创建含有几何对象的表时,这个值必须加入到描述空间数据表元数据的USER_SDO_GEOM_METADATA视图的SRID字段中。对于我们通常使用国际标准的Longitude/Latitude(8307),Oracle Spatial规定,一个几何字段中的所有几何对象都必须为相同的SDO_SRID值。
③ SDO_POINT
SDO_POINT是一个包含三维坐标X,Y,Z数值信息的对象,用于表示几何类型为点的几何对象。如果SDO_ELEM_INFO和SDO_ORDINATES数组都为空,则SDO_POINT中的X,Y,Z为点对象的坐标值,否则,sdo_Point的值将被忽略(用NULL表示)。Oracle Spatial强烈要求用SDO_POINT存储空间实体为点类型空间数据,这样可以极大的优化Oracle Spatial的存储性能和查询效率。
④ SDO_ELEM_INFO
SDO_ELEM_INFO是一个可变长度的数组,每3个数作为一个元素单位,用于表示坐标是如何存储在SDO_ORDINATES数组中的。本文把组成一个元素的3个数称为3元组。一个3元组包含以下3部分的内容:
◇ SDO_STARTING_OFFSET SDO_STARTING_OFFSET 表明每个几何元素的第一个坐标在SDO_ORDINATES数组中的存储位置。它的值从1开始,逐渐增加。
◇ SDO_ETYPE SDO_ETYPE 用于表示几何对象中每个组成元素的几何类型。当它的值为1, 2, 1003和2003时,表明这个几何元素为简单元素。如果SDO_ETYPE为1003,表明该多边形为外环(第一个数为1表示外环),坐标值以逆时针存储;如果SDO_ETYPE为2003,表明该多边形为内环(第一个数为2表示内环),坐标值以顺时针存储。当SDO_ETYPE为4, 1005和2005时,表明这个几何元素为复杂元素。它至少包含一个3元组用以说明该复杂元素具有多少个几何简单元素。同样,1005表示多边形为外环,坐标值以逆时针存储;2005表示多边形为内环,坐标值以顺时针存储。
◇ SDO_INTERPRETATION SDO_INTERPRETATION具有两层含义,具体的作用由SDO_ETYPE是否为复杂元素决定。如果SDO_ETYPE是复杂元素(4, 1005和2005),则SDO_INTERPRETATION表示它后面有几个子3元组属于这个复杂元素。如果SDO_ETYPE是简单元素(1, 2, 1003和2003),则SDO_INTERPRETATION表示该元素的坐标值在SDO_ORDINATES中是如何排列的。 需要注意的是,对于复杂元素来说,组成它的子元素是连续的,一个子元素的最后一个点是下一个子元素的起点。最后一个子元素的最后一个坐标要么与下一个元素的SDO_STARTING_OFFSET值减1所对应的坐标相同,要么是整个SDO_ORDINATES数组的最后一个坐标。SDO_ETYPE和SDO_INTERPRETATION之间的关系如下表:
SDO_ETYPE SDO_INTERPRETATION 描述说明
0 任意值 用于自定义类型,Oracle Spatial不支持
1 1 点类型
1 n > 1 具有n个点的点集合
2 1 由直线段组成的线串
2 2 由弧线段组成的线串,一个弧线段由起点、弧线上任意一点和终点组成,相邻两个弧线段的接点只需要存储一次
1003 2003 1 由直线段组成的多边形,起点和终点必须相同
1003 2003 2 由弧线段组成的多边形,起点和终点必须相同。一个弧线段由起点、弧线上任意一点和终点组成,相邻两个弧线段的接点只需要存储一次
1003 2003 3 矩形:由左下角和右上角两点确定
1003 2003 4 圆:由圆周上的三个点组成
4 n >1 由直线段和弧线段组成的复合线,n表示复合线的相邻子元素的个数,子元素的SDO_ETYPE必须为2,一个子元素的最后一点是下一子元素的第一个点,并且该点不能重复
1005 2005 n >1 由直线段和弧线段组成的复合多边形,n表示复合线的相邻子元素的个数,子元素的SDO_ETYPE必须为2,一个子元素的最后一点是下一子元素的第一个点,并且该点不能重复。多边形的起点和终点必须相同
表1.1.3
SDO_ETYPE和SDO_INTERPRETATION 的组合关系
⑤ SDO_ORDINATES
SDO_ORDINATES是一个可变长度的数组,用于存储几何对象的实际坐标,是一个最大长度为1048576,类型为Number的数组。
SDO_ORDINATES必须与sdo_Elem_Info数组配合使用,才具有实际意义。SDO_ORDINATES的坐标存储方式由几何对象的维数决定,如果几何对象为二维,则SDO_ORDINATES的坐标以{ x1, y1, x2, y2, …}顺序排列,如果几何对象为三维,则SDO_ORDINATES的坐标以{x1, y1, z1, x2, y2, z2, …}的顺序排列。
实例说明 下面用实例来进一步说明SDO_GEOMETRY对象的使用方法。
① 一个带洞的多边形
• SDO_GTYPE = 2003,表示几何对象是一个二维的多边形。
• SDO_SRID = NULL,在二维情况下不需设置线性参考值。
• SDO_POINT = NULL,表示几何对象不是点类型。
• SDO_ELEM_INFO = (1,1003,1, 19,2003,1),有两个三元组元素(1,1003,1) 和(19,2003,1),按照先后顺序,在(1,1003,1)中,“1”表示该子元素的起点为SDO_ORDINATES数组中的第1个值,“1003”表示该元素为多边形外环,“1”表示该多边形由直线组成;在(19,2003,1)中,“19”表示该子元素的起点为SDO_ORDINATES数组中的第15个值,“2003”表示该元素为多边形内环,“1”表示该多边形由直线组成。
• SDO_ORDINATES = (2,4, 4,3, 10,3, 13,5, 13,9, 11,13, 5,13, 2,11, 2,4, 7,5, 7,10, 10,10, 10,5, 7,5)。外环坐标以逆时针排列,内环坐标以顺时针排列。
② 一个直线段与弧线段组成的复合线串
• SDO_GTYPE = 2002,表示几何对象是一个二维的线串。
• SDO_SRID = NULL,在二维情况下不需设置线性参考值。
• SDO_POINT = NULL,表示几何对象不是点类型。
• SDO_ELEM_INFO = (1,4,2, 1,2,1, 3,2,2),有三个三元组元素(1,4,2)(1,2,1) 和(3,2,2),按照先后顺序,(1,4,2)表示该线串为复合线串,它由下面两个三元组描述的子元素组成;在(1,2,1)中,“1”表示该子元素的起点为SDO_ORDINATES数组中的第1个值,“2”表示该元素为线,“1”表示这段线由直线组成;在(3,2,2)中,“3”表示该子元素的起点为SDO_ORDINATES数组中的第3个值,“2”表示该元素为线,“2”表示这段线由弧线段组成。
• SDO_ORDINATES = (10,10, 10,14, 6,10, 14,10),坐标(10,14)是直线段和弧线段的连接点,没有重复存储。
③ 一个直线段与弧线段组成的复合多边形
• SDO_GTYPE = 2003,表示几何对象是一个二维的多边形。
• SDO_SRID = NULL,在二维情况下不需设置线性参考值。
• SDO_POINT = NULL,表示几何对象不是点类型。
• SDO_ELEM_INFO = (1,1005,2, 1,2,1, 5,2,2),有三个三元组元素(1,2005,2)(1,2,1) 和(5,2,2),按照先后顺序,(1,2005,2)表示该多边形为复合多边形,它由下面两个三元组描述的子元素组成;在(1,2,1)中,“1”表示该子元素的起点为SDO_ORDINATES数组中的第1个值,“2”表示该元素为线,“1”表示这段线由直线组成;在(5,2,2)中,“5”表示该子元素的起点为SDO_ORDINATES数组中的第5个值,“2”表示该元素为线,“2”表示这段线由弧线段组成。
• SDO_ORDINATES = (6,10, 10,1, 14,10, 10,14, 6,10),坐标(14,10)是直线段和弧线段的连接点,没有重复存储。 在Oracle Spatial中,可以运用SQL语句进行几何数据的各种操作,例如: 创建一个oralce数据库名为Data1:
Create Table Data1( mktID integer,//第几号目标
Name char(20), //目标名称
Shape SDO_GEOMETRY //目标的空间数据 );
把上例中的复合多边形插入数据库Data1:
Insert into Datal values( 1, //编号
‘复合多边形’, //名称
MDSYS.SDO_GEOME1RY(2003,NULL,NULL, //空间数据
MDSYS.SDO_ELEM _INFO_ARRAY( 1, 1005, 2, 1, 2, 1, 5, 2, 2 ),
MDSYS.SDO_ORDINATES_ARRAY(6,10, 10,1, 14,10, 10,14, 6,10) );
- 点赞
- 收藏
- 关注作者
评论(0)