2008年12月23日星期二

扩展 ArcGIS Server 在移动平台/互联网应用的可达性

其姊妹篇《扩展 ArcGIS Server 在移动平台/互联网应用的可达性补遗 —— 使用WFS-T

【环境】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的触角,使之尽量可以扩展到各个平台、各个应用的死角。

本文主要涉及两方面内容,一方面是数据的获得,一方面是数据的提交。事实上关于数据的获得我前面的一些文章已经有所阐述,这里就简而言之;而在数据提交上,本文将从REST出发,详细叙述通过REST和Geoprocessing构建“万能”的数据提交方法。

首先看一下数据的获得,对于ArcGISServer强大的服务发布功能,获得数据相当容易。比如我比较喜欢kml服务,你需要在(移动)客户端或者其他 地方需要处理的无非就是一个kmz(zip)的解压缩问题,这几乎在所有的平台上都有解决方案。当然,ArcGIS还提供很多的服务种类,你大可以选择自 己喜欢的类型。

下面是一个Android的应用,地图采用了Google Map组件,底图是Google卫星影像图,再次基础上叠加ArcGIS Server发布的kml服务,关于如何从ArcGIS Server获得kmz并进行解析,详细可查看我的另外一篇文章:http://wu-yongfeng.blogspot.com/2008/10/androidkml.html

对于数据的提交,我们最好需要一种不受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){}


点击确定提交以后,刷新Map以后,我们可以看到地图上多了一个事件点,点击这个事件点,出现提示信息——刚才在文本框中输入的“arcgis”:

下面让我们在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。也就是说,不管是移动平台、富因特网应用或是其他互联网应用都可以采用这种“万能”的方法进行空间数据的交互。在移动 领域,除了Android,移动市场份额最大的Symbian也已经选择了开源,可以看到以后在移动平台上进行开发绝非难事,通过本文你或许也可以感觉 到,ArcGISServer完全可以在这些地方大展身手。我们不用为ArcGISServer目前提供的仅有几个SDK和API而耿耿于怀,相信 LINING的这句断语:一切皆有可能!

2 条评论:

匿名 说...

arcgis server for java 的平台是不是现在还不支持移动开发阿,为什么安装后没有mobile SDK、runtime等

牛魔王 说...

SDK只在ArcGIS Server for .Net里有