擴充 ArcGIS Server 在移動平台/互連網應用的可達性
【環境】ArcGIS Server 9.3
在ArcGIS Server 9.3中煥然一新的ArcGIS MobileSDK讓ArcGIS Server的魅力延伸到了WindowsMobile平台上,填補了ArcGIS企業級移動平台應用的空白;稍後推出的ArcGIS API forFlex/JS又在讓ArcGIS在WebGIS領域濃妝重彩,帶來良好的使用者體驗。無疑,在ArcGIS ServerADF提供完善功能的同時,這些不同平台、快速開發、體驗良好的SDK和API擴充了ArcGIS的應用領域,深合以正合以奇勝的兵法之道。
然而,這幾支奇兵初次露面,未免有些青澀。ArcGIS Mobile SDK與WindowsMobile和.Net的死死綁定限制了它的應用範圍,市場份額遠大於WindowsMobile的Symbian+iPhone+RIM被華麗地無視了;而在互連網應用上,ArcGIS API forFlex構建與REST之上,也使得空間資料的提交被忽視,這在後Web2.0時代幾乎是不可被容忍的。本文討論的主要目標就是另闢蹊徑,在這些缺憾之處加以彌補,延伸ArcGIS Server的觸角,使之盡量可以擴充到各個平台、各個應用的死角。
本文主要涉及兩方面內容,一方面是資料的獲得,一方面是資料的提交。事實上關於資料的獲得我前面的一些文章(http://wu-yongfeng.blogspot.com/)已經有所闡述,這裡就簡而言之;而在資料提交上,本文將從REST出發,詳細敘述通過REST和Geoprocessing構建“萬能”的資料提交方法。
首先看一下資料的獲得,對於ArcGISServer強大的服務發布功能,獲得資料相當容易。比如我比較喜歡kml服務,你需要在(移動)用戶端或者其他地方需要處理的無非就是一個kmz(zip)的解壓縮問題,這幾乎在所有的平台上都有解決方案。當然,ArcGIS還提供很多的服務種類,你大可以選擇自己喜歡的類型。
對於資料的提交,我們最好需要一種不受SDK限制,不受防火牆限制的方法。好在ArcGISServer的核心就是服務,充分地利用這些服務是我們發揮想象的空間。這裡,我的方法是REST+GeoprocessingService。下面,讓我在Android平台上先走一遍這個技術流程:
首先,編寫一個python指令碼,實現根據參數儲存Feature到FeatureClass的功能:
import string, os, sys, locale, arcgisscripting
gp = arcgisscripting.create()
def createPoint(point, x, y):
try:
point.x = x
point.y = y
return point
except:
raise Exception, "Create point error."
try:
if len(sys.argv) < 2:
raise Exception, "No enough parameters."
outputFC = sys.argv[1]
inputString = sys.argv[2]
outDesc = gp.describe(outputFC)
shapefield = outDesc.ShapeFieldName
rows = gp.insertcursor(outputFC)
pnt = gp.createobject("point")
values = inputString.replace("\n", "").split(",")
row = rows.newrow()
pnt = createPoint(pnt, values[0], values[1])
row.SetValue(shapefield, pnt)
row.SetValue("CaseDetail", values[2])
rows.insertrow(row)
del rows
del row
except Exception, ErrorDesc:
if ErrorDesc[0] != "":
gp.AddError(str(ErrorDesc))
建立一個Toolbox,添加這個指令碼並命名為AddTrafficCase,給指令碼附上兩個參數:需要儲存的FeatureClass和傳入的字串(包含座標資訊和某欄位的屬性值)。這個時候你可以先測試一下功能是否正常。
在需要發布成Geoprocessing服務的Toolbox中的建立一個Model,加入這個AddTrafficCase指令碼,並定義Model的輸入參數(字串)和儲存到的FeatureClass,
當模型構建完成後,你可以將其發布成一個Geoprocessing服務。簡單起見,我這個模型是沒有傳回值、僅提交一個點資料的服務,當然,你可以做很多擴充,萬變不離其宗了。
讓我們開啟這個GP服務REST地址,檢查它的功能是否正常:
下面我在Android的Map組件上開發一個小Demo,可以點擊選擇當前的座標,再輸入一些字串作為資訊一起提交到ArcGIS Server上來。
比如在Android平台,通過輸入一些文本資訊,通過如下的REST URL可以提交使用者輸入的資訊:
String detail = editTextCaseDetail.getText().toString();
String strURL ="http://192.168.200.157/ArcGIS/rest/services/GPService/FeatureService/GPServer/AddTrafficCase/submitJob?String="+x+","+y+","+detail;
try
{
URL url = new URL(strURL);
HttpURLConnection uc = (HttpURLConnection)url.openConnection();
uc.connect();
uc.getInputStream();
}
catch(Exception e){}
串連這個URL以後可以查看相關的資料庫,可以看到剛才提交的資料已經被儲存到SDE中了:
下面讓我們在ArcGIS API for Flex中再走一下這個流程,其實本質是一致的:
var parms : Object = new Object();
parms.String = x+","+y+",這是Flex儲存的";
var geoprocessTask : Geoprocessor = new Geoprocessor();
geoprocessTask.url ="http://192.168.200.157/ArcGIS/rest/services/GPService/FeatureService/GPServer/AddTrafficCase";
geoprocessTask.submitJob( parms );
提交完成後查看一下結果:
從這兩個例子可以看到,通過ArcGIS Server的REST和GeoprocessingService的組合,可以在任何滿足連網條件的平台和應用上擷取和提交資料,而不局限於ArcGIS提供的SDK和API。也就是說,不管是移動平台、富網際網路應用或是其他互連網應用都可以採用這種“萬能”的方法進行空間資料的互動。我們不用為ArcGISServer目前提供的僅有幾個SDK和API而耿耿於懷,相信NIKE的這句斷語:一切皆有可能!