第4章简单分布式空间数据库引擎的实现.docx
- 文档编号:14226374
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:33
- 大小:1.49MB
第4章简单分布式空间数据库引擎的实现.docx
《第4章简单分布式空间数据库引擎的实现.docx》由会员分享,可在线阅读,更多相关《第4章简单分布式空间数据库引擎的实现.docx(33页珍藏版)》请在冰点文库上搜索。
第4章简单分布式空间数据库引擎的实现
第1章 简单分布式空间数据库引擎的实现
目前已有的空间数据库引擎复杂的系统结构和高昂的价格,完全无法满足小型数据的处理,因此为了适应中小型软件的研发,我们设计了主要用于栅格数据和矢量数据的简单分布式空间数据库引擎(SimpleDistributedSpatialDatabaseEngine,SD_SDE),它不仅缩小了数据处理的空间,还简化了系统的结构,从空间数据分散的特性出发,在保证数据安全性的同时大大提升了数据处理的效率,常用于多层次的GIS。
首先,我们将具体介绍简单分布式空间数据库引擎的主要功能:
(1)数据的存储和提取
(2)通信接口
(3)空间数据信息的查询
(4)分布式管理
4.1数据存取实现
数据的存取作为该系统的最主要的功能,包括模型和结构的存取两个方面。
作为支持数据库引擎的重要支柱,我们将以第三章3.2节中所设计的空间数据模型为例,在数据库的选择上使用SQLServer2000和Oracle,对数据的存取操作进行具体的论述。
数据在存储时主要是通过表格的形式对信息进行记录。
4.1.1SD_SDE存储结构
4.1.1.1栅格数据存储结构
如何对SD_SDE的栅格数据进行存储,首先我们需要了解栅格数据的存储结构。
由于存储的方式是表格的形式,因此存储结构中一般有七张表格,分别是:
(1)栅格影像集表(rasterset)
(2)管理表(raster_admin)
(3)栅格影像数据块表(rasterblock)
(4)栅格影像图层表(rasterband)
(5)金字塔表(raster_pyramid)
(6)压缩表(rasterencode)
(7)栅格元数据表(rastermetadata)
当需要将图像数据进行存储时,一般流程是先在栅格影像集表中新增一个影响数据的记录,然后在其他六个表中也增加记录。
下面我们对存储结构中的七个表进行具体的解释说明:
(1)栅格影像集表:
当有新的影像数据被存储,栅格影像集表会对该数据编号,即ID(raster_id),ID中不仅有数据存储时间、拥有者等数据的各种信息,还能够作为桥梁,将其他表中的记录连接起来。
用户拥有对数据信息中的金字塔最高层级值和数据块的大小值自定义的权限。
(2)管理表:
数据通过ID与管理表实现信息的连接共享,因此当用户对数据库进行检索是,管理表会提供所有影像数据的各种详细的信息。
(3)栅格影像数据块表:
通过影像块来对数据进行存储,每个影像块都记录了影响块的方位、大小等信息。
(4)栅格影像图层表:
根据波段对影像数据进行分层,然后将每个图层的具体信息记录在表上。
图层往往由图层块组成,每个图层块都记录了影响的数据信息,为了方便记录,规定0表示影像块数据,1表示图层块数据。
(5)金字塔表:
可以根据用户查询的条件有针对性的提取数据,不仅减少了工作量还能够提高系统的运行速度。
金字塔表中记录的主要是金字塔每块的坐标、层级等信息,数据主要存储在金字塔块中。
(6)压缩表:
主要用于记录数据的大小方位等信息,通过对大量的数据进行压缩,节约了空间,大大提高了数据的传输速度,当用户需要提取数据信息时,压缩表会自动解压还原数据。
(7)栅格元数据表:
主要用于记录影像的尺寸分辨率等基本信息。
如图是栅格影像集表raster_set
字段名
类型
描述
raster_id
int
栅格影像id
name
char
栅格影像名称
date
datatime
入库时间
owner
char
所有者
pyramid
int
金字塔最高级别
blockheight
double
影像数据块的高度
blockwidth
double
影像数据块的宽度
description
varchar
备注
表4-2管理表raster_admin
字段名
类型
描述
admin_id
int
标示ID
raster_id
int
栅格影像id
name
char
栅格影像名称
description
varchar
备注
表4-3栅格影像数据块表raster_block
字段名
类型
描述
block_id
int
影像数据块号
xlcorner
double
影像数据块左下角坐标x
ylcorner
double
影像数据块左下角坐标y
blockrow
int
影像数据块所在行号
blockcol
int
影像数据块所在列号
blockdata
image
影像数据块存储数据
raster_id
int
栅格影像id
表4-4栅格影像图层表raster_band
字段名
类型
描述
level_id
int
影像图层id
raster_id
int
栅格影像id
cellsize
double
栅格影像分辨率
level_width
double
图层宽度
level_height
double
图层高度
description
varchar
分辨率备注
表4-5金字塔表raster_pyramid
字段名
类型
描述
pyramid_id
int
金字塔数据块块号
pxlcorner
double
左下角坐标x
pylcorner
double
左下角坐标y
pbrow
int
金字塔数据块所在行号
pbcol
int
金字塔数据块所在列号
plevel
int
图层金字塔等级
pblockdata
image
金字塔数据块存储数据
raster_id
int
栅格影像id
表4-6压缩表raster_encode
字段名
类型
描述
pyramid_id
int
数据块块号
pxlcorner
double
左下角坐标x
pylcorner
double
左下角坐标y
pbrow
int
数据块所在行号
pbcol
int
数据块所在列号
cellsize
double
分辨率
pblockdata
image
数据块存储数据
raster_id
int
栅格影像id
表4-7栅格元数据表raster_metadata
字段名
类型
描述
meta_id
int
标示ID
raster_id
int
栅格影像id
imagewidth
double
栅格影像宽度
imageheight
double
栅格影像高度
imagetype
int
栅格影像数据格式(如0代表遥感影像等)
cellsize
double
栅格影像分辨率
fillsize
double
文件大小
description
varchar
备注
下面描述的是各存储表之间的关系,如图4-1所示:
图4-1栅格数据存储表结构体系
4.1.1.2矢量数据存储结构
矢量数据的存储与栅格数据的存储基本相似,不同之处在于,矢量数据主要的储存对象主要有两种:
(1)几何数据:
在于数据的模型进行分析研究后,对空间的数据进行划分,最后储存在表中的形式是大字段。
(2)属性数据:
不需要转换或压缩,直接存储。
矢量数据结构中存储的表主要有四种:
(1)矢量数据集表(vector_set)
(2)管理表(vector_admin)
(3)要素表(vector_part)
(4)属性表(vector_attribute)
这四种数据表的相互配合,共同管理数据的存储。
下面具体介绍四个数据表的主要结构:
表4-8矢量数据集表vector_set
字段
类型
描述
vector_id
int
矢量数据的标示号
vector_name
char
矢量数据名称
vector_time
double
矢量数据入库时间
vector_owner
double
矢量数据所有者
description
varchar
其它备注信息
表4-9管理表vector_admin
字段名
类型
描述
admin_id
int
字段标示
vector_name
char
矢量数据名称
vector_id
int
矢量数据的标示号
description
varchar
其它备注信息
表4-10要素表vector_part
字段名
类型
描述
part_id
int
字段标示号
part_type
int
要素类型(0为点状,1为现状,2为面状)
Xmin
double
要素X坐标最小值
Xmax
double
要素X坐标最大值
Ymin
double
要素Y坐标最小值
Ymax
double
要素Y坐标最大值
part_data
image
要素的几何信息
vector_id
int
矢量数据的标示号
description
varchar
其它备注信息
表4-7属性表vector_attribute
字段名
类型
描述
attribute_id
int
字段标示
vector_size
int
矢量数据大小
vector_id
int
矢量数据的标示号
description
varchar
其它备注信息
矢量数据存储结构中各存储表之间的关系如图4-2所示:
图4-2矢量数据存储表结构体系
4.1.2SD_SDE存取接口
当用户对不同的数据库进行访问时,都可以通过SD_SDE接口。
本文以SQLServer2000和Oracle为例,用户可以通过统一的接口直接进入进行数据访问。
SD_SDE常用的管理数据库的工具为ADO(ActiveXDataObject)、SQL(StructuredQueryLanguage)等,实现数据库的创建、连接等操作。
例子中提供的接口是DLL中的ADO,在工程的stdafx.h文件中添加下面的编程语句:
#pragmawarning(disable:
4146)
#import"C:
\ProgramFiles\CommonFiles\System\ADO\msado15.d11"named_guidsrename("EOF","adoEOF"),rename("BOF","adoBOF")
#pragmawarning(default:
4146)
SD_SDE还设定了一个处理用户请求的统一接口ADOconn,常用的执行语言是SQL语句。
各种函数具有不同的作用:
(1)AfxOleInit()常用与以ADO作为对象的函数中,位置不同作用也就不同。
用在前面可以用于函数初始化,用在最后作为结束,即中断与数据库的连接。
(2)ExitConnect()表示释放m_pConnection,
(3)函数的环境是CoUninitialize()
(4)CoInitialize(NULL)用于前端表示函数的初始化。
,
在本文中我们采用CoInitialize(NULL)进行初始化。
图4-3ADOconn类关系描述
正如图4-3中数据库操作类的关系所示,在实现SD_SDE系统中主要的存取接口函数说明如下:
(1)接口函数OnInitADOconn用来连接数据库,并初始化ADO环境的。
函数参数为用户定义的数据库用户名,用户密码及数据库类型(0为SQLServer数据库,1为Oracle数据库)。
此函数提供了统一的数据库连接接口,函数首先判断用户所要连接的数据库类型,再调用ADO类的Open对数据库进行透明连接。
(2)接口函数GetRecordSet接口用于执行有返回记录集的SQL语句,返回类型是记录集智能指针_RecordsetPtr。
该函数首先创建记录集对象,在ADO中函数产生记录集对象,最后还要释放记录集指针。
(3)接口函数ExecuteSQL用于没有返回的SQL语句,例如create、delete、update等SQL语句。
该函数主要的语句是调用Connection对象的Execute方法,用Execute函数执行SQL语句。
(4)接口函数OpenrasterFile读取一幅遥感影像数据文件,记入内存,返回该文件在内存中的句柄,参数为影像文件名。
此函数完成了从外存中的文件数据转移到内存中的功能。
(5)函数Createtile负责把内存中的影像文件按256X256分成影像数据块,并把影像数据块的左下角坐标及影像数据块的行列号赋值给变量xlcorner,ylcorner,xlc,ylr,在此函数中要调用inserttile函数,负责把数据块存入数据库中。
函数Createtile首先计算影像数据中块的个数同时涉及不足的分块问题,计算出横向影像块个数Xtilenum和纵向影像块个数Ytilenum。
在此函数中还涉及到tiles类数组,tiles类用于分块的数据存储,将影像文件中的数据拷入进相应的分块中。
函数Createtile中调用了tiledatacopy函数获得并生成一个分块tile的象素值,其函数原型为:
voidtilecdatacopy(HANDLEhFile,DWORDlodwidthpixnum,DWORDk,DWORDn,DWORDcurrownum,DWORD&currowpos,floatlbc,float1br,DWORDminr,DWORDmaxr,DWORDminc,DWORDmaxc);
在tiledatacopy函数中,参数maxr,minr是表示该分块需要从该影像文件中拷贝数据的列数范围。
tiledatacopy先将影像文件中的像素值数据分别拷入对应的tile指针中。
(6)接口函数Inserttile把tilefile所指的影像数据块数据存入到数据表中,此函数中tilefile暂时不释放,还用于压缩函数,用于构建压缩表。
原型如下:
voidInserttile(LPBYTEtilefile,floatxlcorner,floatylconer,intxlc,intylr);
(7)函数Readtile_endcode中的传递参数为所需要影像数据块的行列号,函数中调用数据库访问类中的SQL语句执行函数GetRecordSet函数返回记录集数据,该函数把GetRecordSet函数返回的记录集数据转化为handle标示的内存数据提供给其它函数调用。
首先得到数据的大小1DataSize,并把把图像字段中的数据存入进varBLOB中,为全局变量分配必要的存储空间,为了得到指针值,在此函数外释放空间,复制数据到缓冲区m_pBuffer中。
4.1.3SD_SDE数据压缩和金字塔模型
影像数据存入数据库时,SD_SDE还另把一份压缩后的数据存入数据库,压缩数据可用在网络传输中,提高传输的速度。
本文采用JPEG2000压缩算法,SD_SDE借助于CxImage类的成员函数Encode进行压缩,该接口函数的原型为:
Encode(buffer,size,image_type);
该函数把image对象中的图像以type类型数据压缩并放到buffer缓冲区中。
其中image_type设置为CXIMAGE_FORMAT_JP2,代表为JPEG2000格式。
通过套接字接收道德数据进行解压缩,调用的成员函数为Decode,该函数原型如下:
Decode(buffer,size,image_type),参数意义和Encode相同。
在SD_SDE中多分辨率金字塔模型实现的接口函数原型如下:
voidtilepyramid(tiles&curtile,tiles&lastile,DWORD&curwidthpixnum,DWORD&lastwidthpixnum);
其中第一个参数curdle表示第i级金字塔数据,第二个参数lasttile表示第i-1级金字塔数据,curwidthpixnum为当前第i级金字塔的横向像素宽度,lastwidthpixnum为第i-1级金字塔横向像素宽度。
函数主要实现算法如下:
for(DWORDk=O;k {for(DWORDm=O;m {rcolor=O;gcolor;bcolor=0;//把像素RGB值变量进行初始化赋值 for(intn=O;n {//遍历用来重采样的levelsubnum*levelsubnum个像素,本文SD_SDE中采用四分之一重采样; rcolor=rcolor+lasttile.tilebit[(k*levelsubnum+n/levelsubnum)*lastwidthpixnum+m*levelsubnum+n*3]; gcolor=gcolor+lasttile.tilebit[(k*levelsubnum+n/levelsubnum)*lastwidthpixnum+m*levelsubnum+n*3+1]; bcolor=bcolor+lasttile.tilebit[(k*levelsubnum+n/levelsubnum)*lastwidthpixnum+m*levelsubnum+n*3+2];} //对求和后的rcolor,gcolor,bcolor进行求平均计算,并保存为当前第i级金字塔的数据 curdle.tilebit[k*curwidthpixnum+m]=(BYTE)(rcolor/(levelsubnum*levelsubnum)); curdle.tilebit[k*curwidthpixnum+m+1]=(BYTE)(gcolor/(levelsubnum*levelsubnum)); curdle.tilebit[k*curwidthpixnum+m+2]=(BYTE)(bcolor/(levelsubnum*levelsubnum));}} 4.2通信接口实现 该系统能够为服务器提供多种功能的服务,最主要的是Socket通信服务,即用户与服务器之间的数据传输,包括数据包的传输等。 在服务器的连接方面,通过使用多线连接技术,可以同时处理多个用户的请求,传输数据。 4.2.1SD_SDE通信体系结构 SD_SDE体系的应用服务端程序包含两个进程: 监听和服务。 该体系使用了客户端-服务器模式和多线程技术,较为高端。 其中监听进程主要是对来自客户端和其他分布式服务节点的请求进行监听,并将监听到的各种请求传送给服务进程。 服务进程是监听进程的下游进程,它主要处理监听进程发送过来的请求,进程会自动分析请求的类型,按照客户端请求和分布式参与节点请求的不同来分别处理。 当分析得出请求来自于客户端时,进程会自动识别出用户是否获得授权,当识别完毕,进程将会将有效信息加以转变,成为与关系型数据库管理系统相符的语句,然后将这些处理过的请求传送给下一环节——关系型数据库管理系统,进行二次转变,将这些信息传回客户端程序,此时客户端程序已经可以处理之。 倘或请求来自分布式参与阶段,服务进程也有一个专门的线程来分析处理该类型请求,下图4-4即是SD-SDE通信体系结构图: 图4-4通信体系结构 本文使用套接字Socket、RPC(RemoteProcedureCallProtocol,远程过程调用协议)远程过程调用思想来处理参与节点的通信。 其主要程序为,参与节点获得主服务器传送的消息后,参与节点上的函数借口处理信息遂被主服务器调用,在该信息被有效处理后,参与节点将处理完的信息反向传送给主服务器,该动作中使用应答消息功能。 想要获得一致性的消息架构,其分布式空间数据库引擎设置消息的结构当如下所示: structmessage_type{ BYTEmessage_direction: l,//求情为0,应答为1 message一type: 7,//消息类型 BYTEsubmessage_type;//子消息的类型 shortlength;//消息的长度; }; 结构公示中的变量含义请参阅变量右边解释,所有变量都是在消息的传送中确实使用的消息变量。 下面展示图4-5为SD_SDE的监听进程和服务进程服务流程: 图4-5进程服务流程图 4.2.2SD_SDE通信接口类 在SD_SDE数据通信体系中,想要实现客户端与服务端、主服务节点和参与节点两个关系之间的分布式通信,将消息机制及Scoket技术有效运用于服务进程中是最佳选择。 使用work线程方式处理能够使得服务进程可暂缓当前操作,转而处理其他信息,为操作留下缓冲时间,仿版接下来的异步传输。 各线程间的通信技术需要共享全局变量、消息等机制为其服务来实现,此类机制能够很快捷方便地搭建线程之间的联系。 在通信体系中,类是组成体系的主要部分,在客户端和服务端之间设置的类与Socket相互联系作用,共同搭建通信体系结构。 下图4-6为通信体系中服务通信类在服务端和客户端之间搭建的关系图。 从图中我们可看见,基础服务类CBaseServer主导操作,通过函数来处理数据和其他基础命令。 其下属为CServiceprocess,该部分主要掌管客户端彼此之间的操作。 而负责消息结构的则是CMessage,它属于消息基类。 CNode则是处理SocketAPI和CMessage类与CServiceprocess间交互的节点类。 CBaseSocket类和CListenprocess都是封装了基础的SocketAPI函数操作,它们之间的关系是承上启下。 CClient类中包含客户的用户名和密码等信息,属于客户类,该类主要通过CListenprocess类与CServiceprocess之间的交互实现其功能,验证密码即是一项主要功能。 图4-6通信体系类图 4.2.1SD_SDE异步传输及缓冲区设计 在本文中提到的异步传输方式建立在socket的传输平台上,具体说来有两个办法实现这种网络传送,首先,可以建立一套多方式多路线的技术平台,在这种境况下,即使数据传送的通道发生堵塞,也不会阻碍其他主要的通道。 在这种方式中用户永远处在主动地位。 其次,在socket基础上可以采用非堵塞的网络传输技术。 具体关于异步传输的相关设计方法可以参照第三章第六节的设计,流程图如3-9所示。 SD_SDE中异步缓冲区的结构设置为: structcache_struct{ FILE*pfile;//所对应的文件 char*phead_cache;//指向缓冲区首部 intposinfile;//缓冲区头部在相应文件中的位置 intposmove;//缓冲区的偏移量 intfpos;//缓冲区中的第一次修改位置 intlpos;//缓冲区中的最后修改位置 intdatalen;//缓冲区中的数据长度 intavail_data;//是否有数据可供读写,0为没有,1为有数据 inttake_data;//缓冲区中的数据是否已经被取走,0为没有,1为已取走 inttake_datay2;//缓冲区中数据是否已被数据库副本取走,0为未被副本主数据库副本取走,1为已被主数据库
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 简单 分布式 空间 数据库 引擎 实现