曹忠
摘要:數(shù)據(jù)耦合是應(yīng)用系統(tǒng)開(kāi)放與互連的重要保障機(jī)制,也是系統(tǒng)數(shù)據(jù)共享關(guān)鍵技術(shù)。本文作者結(jié)合基于WebGis的應(yīng)用程序開(kāi)發(fā)實(shí)踐,探討Arcgis Server9.2平臺(tái)上的GIS數(shù)據(jù)與常見(jiàn)外部數(shù)據(jù)源之間進(jìn)行松散數(shù)據(jù)耦合的方法與過(guò)程,給出具體的代碼實(shí)現(xiàn)流程,以期對(duì)同類應(yīng)用開(kāi)發(fā)提供一定的指導(dǎo)與借鑒作用。
關(guān)鍵詞:數(shù)據(jù)耦合;Arcgis Server9.2平臺(tái);GIS應(yīng)用;實(shí)現(xiàn)策略
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2017)01-0224-03
Abstract:Data Coupling is a very important mechanism in Applications open and interconnected. It is else a key technology about system data sharing. The article based on Development practices in WebGis Applications, Discussed the Methods and Process in loosely data coupling about Gis data and common External data sources, and provide specific code and implementation process, wish to provide some guidance and reference in The development of similar applications.
Key words:Data Coupling; Arcgis Server9.2; Gis Application; Implementation strategy
1 引言
GIS[1-2]是一個(gè)時(shí)空一體的綜合業(yè)務(wù)應(yīng)用系統(tǒng)[5],地理信息系統(tǒng)中的所使用的數(shù)據(jù)一般包括GIS本身數(shù)據(jù)與外部數(shù)據(jù),本身數(shù)據(jù)是指GIS地圖中所帶的空間位置數(shù)據(jù)、拓?fù)潢P(guān)系數(shù)據(jù)、基本屬性數(shù)據(jù),當(dāng)然還包括部分存儲(chǔ)在外部數(shù)據(jù)庫(kù)(如Oracle數(shù)據(jù)庫(kù))中的擴(kuò)展屬性數(shù)據(jù),也叫基礎(chǔ)數(shù)據(jù)或系統(tǒng)數(shù)據(jù)[1-2]。外部數(shù)據(jù)則是指所有可能與GIS地圖空間數(shù)據(jù)發(fā)生關(guān)系的各種應(yīng)用系統(tǒng)的數(shù)據(jù),也叫擴(kuò)展數(shù)據(jù)或外延數(shù)據(jù),是GIS系統(tǒng)集成其他已有應(yīng)用系統(tǒng)數(shù)據(jù)信息,充分發(fā)揮GIS功能的平臺(tái)特性的數(shù)據(jù)來(lái)源。ArcGIS Server是基于服務(wù)器的計(jì)算和空間服務(wù)的GIS基礎(chǔ)平臺(tái),系統(tǒng)在支持高性能Web制圖功能的同時(shí),還提供了充分利用ArcGIS空間分析工具和功能實(shí)現(xiàn)的、面向服務(wù)的解決方案,為構(gòu)建功能強(qiáng)大的企業(yè)應(yīng)用軟件提供了基礎(chǔ)支持[3-4]。
在GIS平臺(tái)中,就涉及一個(gè)如何調(diào)用外部數(shù)據(jù)、如何進(jìn)行有效的數(shù)據(jù)關(guān)聯(lián)的問(wèn)題,這就是數(shù)據(jù)共享問(wèn)題,而數(shù)據(jù)共享機(jī)制是開(kāi)放系統(tǒng)的前提與基礎(chǔ),是網(wǎng)絡(luò)綜合應(yīng)用平臺(tái)的發(fā)展方向[4]。本文結(jié)合開(kāi)發(fā)省際警務(wù)GIS平臺(tái)的項(xiàng)目實(shí)踐,較系統(tǒng)地介紹GIS平臺(tái)數(shù)據(jù)與外部數(shù)據(jù)進(jìn)行耦合關(guān)聯(lián)的三種方式,并具體介紹每一種方式的技術(shù)實(shí)現(xiàn)方法。
2 圖數(shù)耦合機(jī)制
數(shù)據(jù)耦合的主要目的是將地理信息系統(tǒng)中的內(nèi)部數(shù)據(jù)和外部應(yīng)用程序的數(shù)據(jù)建立出映射關(guān)系,主要包括:(1)一對(duì)一關(guān)系:GIS基礎(chǔ)數(shù)據(jù)記錄與外部應(yīng)用數(shù)據(jù)記錄間通過(guò)關(guān)鍵字段建立起一對(duì)一關(guān)系;(2)一對(duì)多關(guān)系:GIS是空間分層數(shù)據(jù),有時(shí)一個(gè)點(diǎn)可表示一個(gè)位置(或一個(gè)對(duì)象),對(duì)象GIS基礎(chǔ)數(shù)據(jù)的對(duì)象名與外部數(shù)據(jù)的記錄間建立起一對(duì)多的關(guān)系。如GIS地圖中的一個(gè)小區(qū)點(diǎn)對(duì)象,可通過(guò)小區(qū)點(diǎn)對(duì)象的名稱屬性與人口數(shù)據(jù)表中的居住地地址關(guān)聯(lián),就建立了一對(duì)多的關(guān);(3) 個(gè)體關(guān)聯(lián):對(duì)于GIS中的特殊實(shí)體對(duì)象,可能只能與外部數(shù)據(jù)庫(kù)中的實(shí)體對(duì)象聯(lián)系起來(lái),就必須要建立實(shí)體關(guān)聯(lián)。如要將贛江實(shí)體與贛江水文數(shù)據(jù)庫(kù)聯(lián)系起來(lái),而與其他的河流無(wú)關(guān);(4)行為關(guān)聯(lián):實(shí)際上這是建立兩個(gè)應(yīng)用程序的接口,由GIS系統(tǒng)中某個(gè)對(duì)象的特定行為激發(fā)外部應(yīng)用系統(tǒng)的相應(yīng)操作。
對(duì)于上面的描述的關(guān)聯(lián),實(shí)質(zhì)上就是構(gòu)建GIS數(shù)據(jù)與外部數(shù)據(jù)之間的三種關(guān)聯(lián)模式:結(jié)構(gòu)(屬性)關(guān)聯(lián)、數(shù)據(jù)關(guān)聯(lián)和行為關(guān)聯(lián)。結(jié)構(gòu)關(guān)聯(lián)是指在數(shù)據(jù)表的結(jié)構(gòu)層建立起關(guān)聯(lián)關(guān)系,以達(dá)到表間的所有數(shù)據(jù)都建立起對(duì)應(yīng)關(guān)系;而數(shù)據(jù)關(guān)聯(lián)則是建立起空間表中某個(gè)對(duì)象與外部的聯(lián)系,行為關(guān)聯(lián)則是建立GIS特定對(duì)象上的某個(gè)操作所產(chǎn)生的外部應(yīng)用程序行為。
3 數(shù)據(jù)耦合流程
數(shù)據(jù)關(guān)聯(lián)的實(shí)現(xiàn)流程,主要包括以下幾個(gè)步驟:
1)先設(shè)計(jì)好關(guān)聯(lián)模型(是結(jié)構(gòu)關(guān)聯(lián)、數(shù)據(jù)關(guān)聯(lián)還是行為關(guān)聯(lián))
2)選擇需要關(guān)聯(lián)的Map控件數(shù)據(jù)/Geodatabase數(shù)據(jù)對(duì)象;
3)選擇需要關(guān)聯(lián)的外部數(shù)據(jù)源或外部程序;
4)確定關(guān)聯(lián)關(guān)系并存入關(guān)聯(lián)數(shù)據(jù)表中;
5)寫入用戶工作日志。
在省警Gis信息平臺(tái)中有關(guān)結(jié)構(gòu)耦合與數(shù)據(jù)耦合設(shè)置的界面如圖二、三所示。
對(duì)于內(nèi)部關(guān)聯(lián)的數(shù)據(jù)來(lái)源于當(dāng)前GIS應(yīng)用程序內(nèi)部,可從map控件中獲??;外部關(guān)聯(lián)條件應(yīng)先獲取已設(shè)置好的數(shù)據(jù)源,可通過(guò)ODBC面版來(lái)設(shè)置關(guān)系數(shù)據(jù)源;對(duì)于結(jié)構(gòu)關(guān)聯(lián)屬性之間必定是相等的關(guān)系;對(duì)于內(nèi)部和外部關(guān)聯(lián)條件設(shè)置時(shí),各控件間應(yīng)建立有連動(dòng)機(jī)制,即選擇數(shù)據(jù)源后,數(shù)據(jù)表的下拉列表中只有選中數(shù)據(jù)源的表格,而選擇數(shù)據(jù)表后,屬性字段也必須建立連動(dòng)機(jī)制。
4 數(shù)據(jù)耦合實(shí)現(xiàn)的關(guān)鍵技術(shù)
4.1對(duì)Arcgis Server中的圖層、字段及數(shù)據(jù)的獲取方式
要?jiǎng)?chuàng)建內(nèi)部數(shù)據(jù)和外部數(shù)據(jù)間的耦合,首先獲取需要進(jìn)行查詢的內(nèi)部圖源,檢查當(dāng)前程序是否支持ArcGIS中的查詢函數(shù)。如果支持則調(diào)用GetQueryableLayers圖層查詢函數(shù)對(duì)圖層進(jìn)行遍歷,最后讀取圖層名并對(duì)圖層選擇下拉列表框ddlLayer進(jìn)行填充。
ESRI.ArcGIS.ADF.Web.DataSources.ImapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(0);
ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource; //獲取內(nèi)部數(shù)據(jù)源
bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
if (supported)
{
ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
string[] lids;
string[] lnames;
qfunc.GetQueryableLayers(null, out lids, out lnames);//調(diào)用GetQueryableLayers函數(shù)
for (int i = 0; i < lnames.Length; i++)//對(duì)圖層進(jìn)行遍歷
{ ddlLayer.Items.Add(lnames[i]); }//對(duì)圖層選擇下拉列表框進(jìn)行填充
}
…
String[] pFields = qfunc.GetFields(null, lids[layer_index]);
for (int i = 0; i < pFields.Length; i++)//對(duì)圖層的屬性字段進(jìn)行編歷
{this.ddlField.Items.Add(pFields[i].ToString());}//對(duì)屬性字段選擇下拉列表框進(jìn)行填充
…
sc.Add(this.ddlField.SelectedItem.Text.Trim());//獲取所要查詢數(shù)據(jù)的字段
pQF.SubFields = sc;
DataTable DT = pQueryFun.Query(null,lids[Convert.ToInt32(Session["CurrentLayer"])], pQF);//把數(shù)據(jù)存儲(chǔ)到臨時(shí)表DT中
Session.Remove("CurrentLayer");
int n = DT.Rows.Count;
for (int i = 0; i < n; i++)//對(duì)數(shù)據(jù)進(jìn)行遍歷
{this.ddlObject.Items.Add(DT.Rows[i][this.ddlField.SelectedItem.Text.Trim()].ToString());
}
4.2 外部數(shù)據(jù)源連接技術(shù)
在準(zhǔn)備好了需要進(jìn)行耦合的內(nèi)部數(shù)據(jù)外,還要對(duì)外部數(shù)據(jù)源進(jìn)行連接準(zhǔn)備,包括設(shè)置連接對(duì)象、讀取表名及讀取字段結(jié)構(gòu)等步驟,以連接Oracle10g為例進(jìn)行說(shuō)明:
(1) 連接Oracle數(shù)據(jù)庫(kù):
OracleConnection conn = new OracleConnection("Data Source=" + txtInstance.Text + ";User ID=" + txtUser.Text + ";Password=" + txtPwd.Text + ";Unicode=True;");
(2) 讀取Oracle表名:
OracleCommand cmd = new OracleCommand("select table_name from all_tables where table_name not like '%$%'", conn);
OracleDataReader odr = cmd.ExecuteReader();
this.ddlTable.DataSource = odr;
this.ddlTable.DataTextField = "table_name";
(3) 讀取Oracle表的字段名:
OracleCommand cmd = new OracleCommand("select A.column_name from user_tab_columns A where A.Table_Name='" + this.ddlTable.SelectedItem.Value + "'", conn);
OracleDataReader odr1 = cmd.ExecuteReader();
this.ddlProperty.DataSource = odr1;
this.ddlProperty.DataTextField = "COLUMN_NAME";
4.3 耦合條件生成
首先獲取關(guān)聯(lián)圖層和關(guān)聯(lián)信息內(nèi)容,其中關(guān)聯(lián)信息內(nèi)容在結(jié)構(gòu)關(guān)聯(lián)中指圖層結(jié)構(gòu)字段,在數(shù)據(jù)關(guān)聯(lián)和行為關(guān)聯(lián)中指地圖中的對(duì)象名稱。通過(guò)關(guān)聯(lián)圖層和關(guān)聯(lián)信息內(nèi)容判斷之前數(shù)據(jù)庫(kù)中是否存有該條記錄,若有,則直接獲取該條記錄的內(nèi)部關(guān)聯(lián)編號(hào);若沒(méi)有,則在原最大內(nèi)部關(guān)聯(lián)編號(hào)上加一,得到新記錄的內(nèi)部關(guān)聯(lián)編號(hào),并把格式統(tǒng)一為000X,如果內(nèi)部關(guān)聯(lián)信息表沒(méi)記錄,那么就把第一條記錄的內(nèi)部關(guān)聯(lián)編號(hào)設(shè)為0001。最后把內(nèi)部關(guān)聯(lián)編號(hào)、關(guān)聯(lián)圖層、關(guān)聯(lián)信息內(nèi)容等插入到內(nèi)部關(guān)聯(lián)信息表中。
gltcbh = this.ddlLayer.SelectedItem.Value;//關(guān)聯(lián)圖層
glxxnr = this.ddlObject.SelectedItem.Value;//關(guān)聯(lián)信息內(nèi)容
OracleConnection conn = OracleDB.createConnection();
try
{
conn.Open();
string strSelect_nbgl = "select nbglbh from nbglxxb where gltcbh='" + gltcbh + "' and glxxnr='" + glxxnr + "'";
…
//沒(méi)有讀到則建立新的內(nèi)部關(guān)聯(lián)編號(hào)插入
string strSelect = "select nbglbh from nbglxxb";
OracleDataAdapter sda = new OracleDataAdapter(strSelect, conn);
DataSet ds = new DataSet();
sda.Fill(ds);
…
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "insert into nbglxxb values('" + nbglbh1 + "','" + gltcbh + "','" + glxxnr + "','"+txt_dx.Text+"')";
cmd.ExecuteNonQuery();
5 結(jié)束語(yǔ)
通過(guò)數(shù)據(jù)耦合的方式的設(shè)置,使本系統(tǒng)地理空間數(shù)據(jù)與外部相關(guān)的信息數(shù)據(jù)之間建立了增強(qiáng)型的聯(lián)系,一方面,極大地?cái)U(kuò)展了系統(tǒng)原本擁有的信息量,為用戶查詢提供了更豐富的信息資源。同時(shí),也為外界系統(tǒng)共享本系統(tǒng)的內(nèi)容數(shù)據(jù)提供了一個(gè)良好的接口,為本系統(tǒng)成為一個(gè)真正開(kāi)放共享的資源平臺(tái)的一部分奠定了相應(yīng)的技術(shù)基礎(chǔ)。
從另一方面,GIS本身是一個(gè)時(shí)空系統(tǒng)[5][6],通過(guò)數(shù)據(jù)耦合等數(shù)據(jù)共享機(jī)制的探討,對(duì)拓寬GIS系統(tǒng)數(shù)據(jù)的來(lái)源提供了另一思路,希望對(duì)后期同類軟件的開(kāi)發(fā)提供一定的借鑒與參考作用。
參考文獻(xiàn):
[1]陳顯軍,等.基于.NET的組件式WebGIS系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].現(xiàn)代計(jì)算機(jī),2012(17).
[2]謝安濤,唐建智,許文波.基于Hibernate Spatial構(gòu)建松散耦合地圖服務(wù)的技術(shù)方法[J].地理信息世界,2010(3).
[3]趙自力, 王東華, 周曉光.基于ArcGIS Server的網(wǎng)絡(luò)GIS應(yīng)用系統(tǒng)開(kāi)發(fā)[J].遙感信息2007(1).
[4]吳功和, 叢明日.基于ArcGIS Server的分布式GIS應(yīng)用[J].測(cè)繪科學(xué)技術(shù)學(xué)報(bào),2006,23(1).
[5]王洪偉, 張立朝, 張海東.分布式ArcGIS Server體系結(jié)構(gòu)的研究與開(kāi)發(fā)[J].測(cè)繪科學(xué)技術(shù)學(xué)報(bào),2007,24(2).
[6]CSDN-浩淼的天空ArcGIS Engine簡(jiǎn)介
http://blog.csdn.net/chiangbt/archive/2008/08/06/2775151.aspx
[7]林廣發(fā). 基于事件的時(shí)空數(shù)據(jù)模型研究[J].測(cè)繪學(xué)報(bào),2004(3).
[8]龔健雅.GIS中面向?qū)ο蟮臅r(shí)空數(shù)據(jù)模型[J].測(cè)繪學(xué)報(bào),1997(4).