扩展 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的这句断语:一切皆有可能!