当前位置:文档之家› 空间数据库设计报告

空间数据库设计报告

空间数据库设计报告一、设计思想本次空间数据库设计是基于SQL sever2008开放的外挂式空间数据库管理系统。

基于传统的关系型数据库外挂式的空间数据库系统的关键在于SDE的设计与实现,SDE在用户和异构空间数据库之间提供了一个开放的接口。

用户可以通过SDE服务来实现对空间数据的读取、插入、更新和删除的基本操作,还可以基于SDE实现对空间数据的分析功能,如拓扑关系的查询、缓冲区分析、叠加分析、、合并和切分等。

SDE同时提供了链接DBMS数据库的接口,与数据库的操作都是在这个上面进行交互的。

1.1 数据的存储1.1.1 几何数据的存储把GIS数据放在RDBMS中,但是一般的RDBMS都没有提供GIS的数据类型(如点、线、多边形、以及这些feature之间的拓扑关系和投影坐标等相关信息),RDBMS只提供了少量的数据类型支持:int,float,double,Blob,Long ,char等,一般都是数字,字符串和二进制数据几种。

并且RDBMS不仅没有提供对GIS数据类型的存储,也没有提供对这些基础类型的操作(如:判断包含关系,相邻、相交、求差、距离、最短路径等)。

在本次数据库设计中,成功的完成了对点线面的数据的存储和相关的读取、插入、更新和删除以及可视化的显示的功能。

此处的存储是基于SQLsever2008进行的,具体的存储结构如下表所示:其中Point表中包含Point的空间信息,即空间的点的x,y坐标。

由于当个点的只有相当于独立地物才会有相关的属性信息,本次在操作的时候并没有在存储的表中添加相应的属性信息。

一条线是由很多个小线段的组成的,因此在存储的时候,每个边都有一个独立的ID,每条边是由起点和终点链接起来的,因此在在这个表中只需要存储相应的点的ID即可,一般的线都是具有相关的属性信息的,故在本次设计中添加了线的属性信息,咋通过SDE对空间数据查询的时候便可以很方便的看到边的属性。

的存储一样,按照每条边两个点来存储,而是将所有的边的序列来形成一个字符串来链接,然后再通过边表来操纵点表,最后完成查询信息。

每一个多边形都有相关的属性说明。

1.1.2 属性数据的存储属性数据和结合数据的关联是通过几何数据的ID来识别的,属性数据也是存储在一个表中的,相应的没有几何类型都有自己的几何属性说明。

1.1.3 几何数据和属性数据的说明在上述的设计中,在几何数据的表中设置了相应的一些数据说明,其实其按照严格意义上来将就是属性数据,这是方便说明数据的信息,对于一些几何类型承载的信息比较的复杂的数据相应的也是设计了专门的属性数据表,同几何数据的ID来进行级联操作,如对数据的读取、更新、插入或者是删除等。

1.2 数据的维护和管理。

1.2.1 空间数据的维护空间数据的维护包括几何数据和空间几何数据的增加、更新、删除、维护等操作。

本次实习所完成的系统已经成功实现了对空间数据点、线和面类型的操作。

本次实现中,将对点、线和面的数据维护分别封装在不同的类中,用户可以通过SDE来完成从SQL中取出数据,并且对数据进行相应的维护。

下面就对点线面的实现分别做以介绍。

1.2.1.1 点的维护在空间数据库中,点的几何信息的存储就是完成X、Y坐标的存储即可,同样对数据的操作就是只需要完成相应的点的坐标的操作即可。

数据库中点的存储已经做过相应的介绍,现在就封装为数据引擎的设计做以说明。

首先将点数据类型封装为一个类,类中分别定义与点的查询、插入和删除对应的函数,在每次调用这些函数的时候,都是调用一个唯一的接口来对数据库进行来接的。

////////////////定义数据源连接字符串变量并赋值///////////////CString g_strConnect=_T("DSN=S_DataBasechenxiong;UIN=sa;PWD=sa");//数据源链接字符串CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}上述通过CDatabase提供了链接数据库的接口,在每个要素封装的类中,都提供了与该类的接口,以此链接数据库。

相应函数的声明:void dlgPoint::OnBnClickedButtonquerypoint()//查询点void dlgPoint::OnBnClickedButtoninsert()//插入一个点void dlgPoint::OnBnClickedButtondelete()//删除点的操作1.2.1.2 线的维护线的操作和点的操作有点类似,由于线中存储的是点的ID,因此在具体的实现的时候有所不同。

无论在执行对线的删除或者是对线的增加,其实质上都是对点的操作。

链接数据的方式与点的一样,不做过多的介绍。

CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}具体的函数声明如下:void dlgEdge::OnBnClickedButtonQueryEdge()//查询边表函数void dlgEdge::OnBnClickedButtonAddEdge()//添加边void dlgEdge::OnBnClickedButtonDeleteEdge()//删除边的操作1.2.1.3 面的维护对面的操作大致与上面两种要素类似,在具体实现的时候也离不开另外两种要素,例如在查询的时候,首先应该得到的是面的ID,通过面的ID得到边的一系列字符串,通过读取字符串的每一个字符来得到相应的边的ID,最后通过边的ID来得到相应的点的信息,最后还是实现对点的操作。

链接数据库的方式与上面的类似,此处不做过多的介绍。

CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}具体函数的声明如下所示:void dlgArea::OnBnClickedButtonQueryArea()//查看面的属性void dlgArea::OnBnClickedButtoninsert()//插入一个面void dlgArea::OnBnClickedButtondelete()//删除一个面1.2.2 空间数据的管理能够通过图形用户界面实现对空间数据库的管理,支持图形显示及编辑交互、支持对地理数据图层的管理(图层的增、删、改、枚举)。

本次设计中,设计了对点线面操作的用户界面,通过用户界面可以实现对几何要素的显示和相应的几何要素的属性的操作,以及对几何要素的增加、删除、修改和读取等。

在查询的过程中,由于时间的原因,对各种数据的查询并没有设计好相应的索引,而是直接查询的,这是本次实习的第一个缺陷。

初次之外,图层的分层显示也是一个没有实现的,因此在此基础上形成的分析功能如buffer、叠加、网络分析都没有实现,在设计过程中尝试过使用ArcGIS Engine来实现相应的分析功能,功能模块虽然可以实现,但是在具体数据存储这一块就出现了bug,由于自身的积累的问题,并没有是实现相应的操作,下面就本次实习实现的功能做一介绍。

1.2.2.1 点的管理用户操作界面如下图所示:如上图所示,编辑框是相应的输入要插入点的信息,右边的功能按钮实现了对点的查询、插入和删除的操作。

上述实现的是插入一个点的操作,由于要对数据库进行操作,故在实现时要对数据库进行链接。

可以查看一下SQL sever表中,里面更新了点的编号为16的点,如下图所示:点的可视化操作,点的可视化是在单文档中使用绘图工具实现的如下图所示,由于点比较少,所以看的不是很清楚,下图中红色椭圆圈表示显示的点:1.2.2.1 线的管理用户管理界面如下所示:上图所显示的是有对插入边的一些信息的编辑,同时也给出了相应的对边的查询(上图已经是实现了所有边的查询),同时可以进行添加和删除操作。

List中给出了边的ID和起始点的ID和相应的点的描述。

其他功能不做一一显示,下面就线的绘制进行演示:1.2.2.3 面的管理面操作的用户界面:如上图所示,编辑框提供了对面的插入的操作,输入面的相关的编号,面所包含的边的编号所构成的字符串以及对面所包含的描述,上图已经进行了对面的查询操作。

下面就面的删除和插入做一操作。

面的插入面的删除删除后的显示下面进行面的显示操作,与线的显示不同,对面进行了相应的填充:二、工程实现1.1工作环境SQL server 2008以及VS 20101.2 点的封装的工程代码对点要素的封装的相应的函数描述:// dlgPoint 消息处理程序//////////////////////////定义一个链接数据库的变量///////////////////////extern CString g_strConnect;/////////////////////查询点的属性//////////////////////////////void dlgPoint::OnBnClickedButtonquerypoint(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}myList.ModifyStyle(0,LVS_SHOWSELALWAYS);myList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES| LVS_EX_TWOCLICKACTIVATE);myList.SetBkColor(RGB(247,247,255));myList.SetTextColor(RGB(0,0,0));myList.SetTextBkColor(RGB(247,247,255));for(int i=0;i<3;i++){myList.DeleteColumn(0);}myList.DeleteAllItems();myList.InsertColumn(0,_T("PID"), LVCFMT_LEFT,100);//在list中插入三列myList.InsertColumn(1,_T("x"), LVCFMT_LEFT,100);myList.InsertColumn(2,_T("y"), LVCFMT_LEFT,100);CString strSQL;CRecordset p_DBSet(&p_DB);strSQL="select * from POINT";//查询所有的点的信息p_DBSet.Open(CRecordset::snapshot,strSQL,CRecordset::readOnly);int nIndex = 0;CString strVal;while(!p_DBSet.IsEOF()){p_DBSet.GetFieldValue(_T("PID"),strVal);//获取点的IDmyList.InsertItem(nIndex,strVal);p_DBSet.GetFieldValue(_T("x"),strVal);//获取点的x坐标strVal.TrimRight();myList.SetItemText(nIndex,1,strVal);p_DBSet.GetFieldValue(_T("y"),strVal);//获取点的y坐标strVal.TrimRight();myList.SetItemText(nIndex,2,strVal);nIndex++;p_DBSet.MoveNext();}p_DBSet.Close();//UpdateData();// TODO: 在此添加控件通知处理程序代码}//////////////////////////插入一个点///////////////void dlgPoint::OnBnClickedButtoninsert(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(true);CString strSQL;if(m_pare(_T(""))==0){MessageBox(_T("点的ID不能为空"),_T("错误信息"),MB_OK|MB_ICONERROR);}CString a;a="insert into POINT values('";//插入点的每个坐标和IDa+=m_strID;a+="','";a+=m_strPointX;a+="','";a+=m_strPointY;a+="')";strSQL=a;p_DB.ExecuteSQL(strSQL);p_mitTrans();p_DB.Close();OnBnClickedButtonquerypoint();UpdateData(false);// TODO: 在此添加控件通知处理程序代码}/////////////////////////删除点的操作////////////////////void dlgPoint::OnBnClickedButtondelete(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(TRUE);CString strSQL;//寻找当前选中的记录位置///POSITION pos=myList.GetFirstSelectedItemPosition();if(pos==NULL){MessageBox(_T("请先选中一条记录"),_T("错误信息"),MB_OK|MB_ICONERROR);return ;}//获取当前记录的位置//-int m_ncurPoint=myList.GetNextSelectedItem(pos);//获取当前选中的记录Book//CString PID=myList.GetItemText(m_ncurPoint,0);TRY{strSQL="delete from POINT where PID='";strSQL+=PID;strSQL+="'";p_DB.ExecuteSQL(strSQL);p_mitTrans();}CATCH_ALL(e){TCHAR tc_ErrorMSg[255];e->GetErrorMessage(tc_ErrorMSg,255);CString str_HitMsg;//此处为错误消息//MessageBox(str_HitMsg,_T("错误信息"),MB_OK|MB_ICONERROR);p_DB.Rollback();p_DB.Close();return ;}END_CATCH_ALLOnBnClickedButtonquerypoint();//UpdateData(false);p_DB.Close();// TODO: 在此添加控件通知处理程序代码}1.3 线的封装的工程代码// dlgEdge 消息处理程序//////////////////////////定义一个链接数据库的变量///////////////////////extern CString g_strConnect;//////////////////////////////////查询边表函数/////////////////////////void dlgEdge::OnBnClickedButtonQueryEdge(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}m_List.ModifyStyle(0,LVS_SHOWSELALWAYS);m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES| LVS_EX_TWOCLICKACTIVATE);m_List.SetBkColor(RGB(247,247,255));m_List.SetTextColor(RGB(0,0,0));m_List.SetTextBkColor(RGB(247,247,255));for(int i=0;i<4;i++){m_List.DeleteColumn(0);}m_List.DeleteAllItems();m_List.InsertColumn(0,_T("EID"), LVCFMT_LEFT,100);m_List.InsertColumn(1,_T("Start"), LVCFMT_LEFT,100);m_List.InsertColumn(2,_T("End"), LVCFMT_LEFT,100);m_List.InsertColumn(3,_T("EAttribute"), LVCFMT_LEFT,100);CString strSQL;CRecordset p_DBSet(&p_DB);strSQL="select * from Edge";p_DBSet.Open(CRecordset::snapshot,strSQL,CRecordset::readOnly);int nIndex = 0;CString strVal;while(!p_DBSet.IsEOF()){p_DBSet.GetFieldValue(_T("EID"),strVal);m_List.InsertItem(nIndex,strVal);p_DBSet.GetFieldValue(_T("Start"),strVal);strVal.TrimRight();m_List.SetItemText(nIndex,1,strVal);p_DBSet.GetFieldValue(_T("End"),strVal);strVal.TrimRight();m_List.SetItemText(nIndex,2,strVal);p_DBSet.GetFieldValue(_T("EAttribute"),strVal);strVal.TrimRight();m_List.SetItemText(nIndex,3,strVal);nIndex++;p_DBSet.MoveNext();}p_DBSet.Close();// TODO: 在此添加控件通知处理程序代码}//////////////////////添加边///////////////////////void dlgEdge::OnBnClickedButtonAddEdge(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(true);CString strSQL;if(m_pare(_T(""))==0){MessageBox(_T("边的ID不能为空"),_T("错误信息"),MB_OK|MB_ICONERROR);}CString a;//strSQL="insert into POINT values('"+m_strID+"','"+m_strPointX+"','"+m_strPointY+"')";a="insert into Edge values('";a+=m_strEID;a+="','";a+=m_strSID;a+="','";a+=m_streID;a+="','";a+=m_strEA;a+="')";strSQL=a;//////////////////////////////////////////////////////////////////p_DB.ExecuteSQL(strSQL);p_mitTrans();p_DB.Close();OnBnClickedButtonQueryEdge();UpdateData(false);// TODO: 在此添加控件通知处理程序代码}///////////////////////////////删除边的操作////////////////////////void dlgEdge::OnBnClickedButtonDeleteEdge(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(TRUE);CString strSQL;//寻找当前选中的记录位置///POSITION pos=m_List.GetFirstSelectedItemPosition();if(pos==NULL){MessageBox(_T("请先选中一条记录"),_T("错误信息"),MB_OK|MB_ICONERROR);return ;}//获取当前记录的位置//int m_ncurEdge=m_List.GetNextSelectedItem(pos);//获取当前选中的记录Book//CString m_strSeletetedEID=m_List.GetItemText(m_ncurEdge,0);TRY{strSQL="delete from Edge where EID='";strSQL+=m_strSeletetedEID;strSQL+="'";p_DB.ExecuteSQL(strSQL);p_mitTrans();}CATCH_ALL(e){TCHAR tc_ErrorMSg[255];e->GetErrorMessage(tc_ErrorMSg,255);CString str_HitMsg;//此处为错误消息//MessageBox(str_HitMsg,_T("错误信息"),MB_OK|MB_ICONERROR);p_DB.Rollback();p_DB.Close();return ;}END_CATCH_ALLOnBnClickedButtonQueryEdge();//UpdateData(false);p_DB.Close();// TODO: 在此添加控件通知处理程序代码}1.4 面的封装的工程代码// dlgArea 消息处理程序//////////////////////////定义一个链接数据库的变量///////////////////////extern CString g_strConnect;//////////////////////////查看面的属性//////////////////////////////////void dlgArea::OnBnClickedButtonQueryArea(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}m_list.ModifyStyle(0,LVS_SHOWSELALWAYS);m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES| LVS_EX_TWOCLICKACTIVATE);m_list.SetBkColor(RGB(247,247,255));m_list.SetTextColor(RGB(0,0,0));m_list.SetTextBkColor(RGB(247,247,255));for(int i=0;i<3;i++){m_list.DeleteColumn(0);}m_list.DeleteAllItems();m_list.InsertColumn(0,_T("AID"), LVCFMT_LEFT,100);m_list.InsertColumn(1,_T("EStr"), LVCFMT_LEFT,100);m_list.InsertColumn(2,_T("Attribute"), LVCFMT_LEFT,100);CString strSQL;CRecordset p_DBSet(&p_DB);strSQL="select * from Area";p_DBSet.Open(CRecordset::snapshot,strSQL,CRecordset::readOnly);int nIndex = 0;CString strVal;while(!p_DBSet.IsEOF()){p_DBSet.GetFieldValue(_T("AID"),strVal);m_list.InsertItem(nIndex,strVal);p_DBSet.GetFieldValue(_T("EStr"),strVal);strVal.TrimRight();m_list.SetItemText(nIndex,1,strVal);p_DBSet.GetFieldValue(_T("Attribute"),strVal);strVal.TrimRight();m_list.SetItemText(nIndex,2,strVal);nIndex++;p_DBSet.MoveNext();}p_DBSet.Close();// TODO: 在此添加控件通知处理程序代码}////////////////////////插入一个面//////////////////////////////////////void dlgArea::OnBnClickedButtoninsert(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(true);CString strSQL;if(m_pare(_T(""))==0){MessageBox(_T("边的ID不能为空"),_T("错误信息"),MB_OK|MB_ICONERROR);}CString a;//strSQL="insert into POINT values('"+m_strID+"','"+m_strPointX+"','"+m_strPointY+"')";a="insert into Area values('";a+=m_strAreaID;a+="','";a+=m_strAedge;a+="','";a+=m_strAttribute;a+="')";strSQL=a;//////////////////////////////////////////////////////////////////p_DB.ExecuteSQL(strSQL);p_mitTrans();p_DB.Close();OnBnClickedButtonQueryArea();UpdateData(false);// TODO: 在此添加控件通知处理程序代码// TODO: 在此添加控件通知处理程序代码}////////////////////////删除一个面/////////////////////////////////////void dlgArea::OnBnClickedButtondelete(){CDatabase p_DB;BOOL bReturn =p_DB.OpenEx(g_strConnect,0);if(bReturn==FALSE||!p_DB.BeginTrans())//数据库请求传送数据{MessageBox((LPCTSTR)"访问数据库失败!",(LPCTSTR)"错误信息!",MB_OK|MB_ICONERROR);p_DB.Close();return;}UpdateData(TRUE);CString strSQL;//寻找当前选中的记录位置///POSITION pos=m_list.GetFirstSelectedItemPosition();if(pos==NULL){MessageBox(_T("请先选中一条记录"),_T("错误信息"),MB_OK|MB_ICONERROR);return ;}//获取当前记录的位置//int m_ncurAID=m_list.GetNextSelectedItem(pos);//获取当前选中的记录Book//CString m_strSeletetedAID=m_list.GetItemText(m_ncurAID,0);TRY{strSQL="delete from Area where AID='";strSQL+=m_strSeletetedAID;strSQL+="'";p_DB.ExecuteSQL(strSQL);p_mitTrans();}CATCH_ALL(e){TCHAR tc_ErrorMSg[255];e->GetErrorMessage(tc_ErrorMSg,255);CString str_HitMsg;//此处为错误消息//MessageBox(str_HitMsg,_T("错误信息"),MB_OK|MB_ICONERROR);p_DB.Rollback();p_DB.Close();return ;}END_CATCH_ALLOnBnClickedButtonQueryArea();//UpdateData(false);p_DB.Close();// TODO: 在此添加控件通知处理程序代码}1.5 要素可视化实现在显示的过程是使用计算机图形学中的知识来显示相应的点线面的。

相关主题