<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:ic="http://www.supermap.com/iclient/2010" xmlns:is="http://www.supermap.com/iserverjava/2010" xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script> <![CDATA[ import com.supermap.extend.*; import com.supermap.web.core.geometry.GeoPoint; import com.supermap.web.core.Point2D; import mx.controls.Alert; import mx.controls.Text; import mx.events.FlexEvent; import mx.rpc.AsyncResponder; import mx.rpc.events.ResultEvent; [Bindable] private var mapUrl:String; //与服务端交互,获取服务返回的结果 protected function button1_clickHandler(event:MouseEvent):void { var params:DatasetsListParameter = new DatasetsListParameter(); params.datasource = "World"; var service:DatasetsListService = new DatasetsListService("http://localhost:8090/iserver/services/data-world/rest/data/datasources/"); service.processAsync(params,new AsyncResponder(this.result,this.error,null)); } //与服务端交互成功时调用的处理函数 private function result(object:DatasetsListResult, mark:Object = null):void { var strDatasetsNames:Array = object.datasetName; var str:String = ""; for(var i :int = 0 ; i < strDatasetsNames.length;i++ ) { str = str + strDatasetsNames[i] + "\n"; } var point1:Point2D = new Point2D(); var txt:Text = new Text(); txt.text = str; point1.x = 116.38; point1.y = 39.9; this.map.infoWindow.content = txt; this.map.infoWindow.closeButtonVisible = false; this.map.infoWindow.label = "数据源World中数据集列表:"; this.map.infoWindow.show(point1); } //与服务端交互失败时调用的处理函数 private function error(object:Object, mark:Object = null):void { Alert.show("与服务端交互失败", null, 4, this); } ]]> </fx:Script> <!--添加地图--> <ic:Map id="map" scales="{[1.25e-9, 2.5e-9, 5e-9, 1e-8, 2e-8, 4e-8, 8e-8, 1.6e-7, 3.205e-7, 6.4e-7]}"> <is:DynamicRESTLayer url="http://localhost:8090/iserver/services/map-world/rest/maps/World Map"> </is:DynamicRESTLayer> </ic:Map> <!--操作窗口--> <s:controlBarContent> <s:HGroup height="100%" verticalCenter="0" verticalAlign="middle" gap="10" left="10" top="5" bottom="5"> <s:Button label="获取World中数据集列表" height="26" fontFamily="宋体" click="button1_clickHandler(event)" fontSize="15" fontWeight="bold"/> </s:HGroup> </s:controlBarContent> </s:Application>
SuperMap iClient Flex开发包除了能够支持SuperMap iServer Java 内置GIS服务,还具有客户端开发包的扩展能力,实现与SuperMap iServer Java服务端的领域空间信息服务进行对接或者对接其他第三方服务,本文以扩展一个获取数据源的数据集列表的服务为例简要介绍一下扩展开发。
客户端扩展开发流程
SuperMap iClient Flex客户端提供扩展服务的API方便SuperMap iClient Flex对接新服务,SuperMap iClient Flex扩展开发主要流程为:
- 1. 创建服务参数类
服务参数类是为了让开发人员直接调用SuperMap iClient Flex客户端设置参数,而不需要关注如何编码转换、构造复杂的URL等细节过程。
- 2. 创建结果类
发送HTTP请求后返回的结果一般为服务器端和客户端约定的数据格式,解析这个数据格式会让开发人员陷入复杂的各种格式的理解与掌握中,而无法关注业务及互操作。因此直接把结果参数封装为开发人员熟悉的客户端对象,通过查询API即可了解其组成并进行解析。
- 3. 创建服务类
服务类主要用于调用服务参数类,发送HTTP请求,获取返回结果类。把服务参数类及结果类进行调度,完成特定的功能需求。
扩展开发实例
下面通过SuperMap iClient for Flex中扩展一个服务类,实现与数据源的数据集列表REST接口对接。可以直接调用客户端扩展的接口获取SuperMap iServer Java数据源的数据集列表服务。开发环境为Adobe Flash Builder 4。
1、创建服务参数类
在创建服务参数类时,要根据服务器端接口进行设计,获取数据源中数据集列表服务只支持GET操作,因此本例仅扩展对GET操作的对接。
获取数据源的数据集列表服务需要传递一个参数数据源名字即可,因此设计服务参数类如下。
package com.supermap.extend { public class DatasetsListParameter { //数据源名 private var _datasource : String; public function DatasetsListParameter() { } public function get datasource():String { return _datasource; } public function set datasource(value:String):void { _datasource = value; } } }
2、 创建结果类
结果类,对服务端返回结果进行封装。由于SuperMap iServer Java 服务端返回结果支持多种格式,默认是JSON而SuperMap iClient for Flex直接解析JSON对象给使用带来不方便,所以直接封装一个结果对象,将服务端返回的结果JSON串转为结果对象,便于开发使用。
坐标转换结果类代码如下:
package com.supermap.extend { public class DatasetsListResult { //数据集个数 private var _datasetCount:int; //数据集名字列表 private var _datasetName:Array ; public function DatasetsListResult() { } public function get datasetName():Array { return _datasetName; } public function set datasetName(value:Array):void { _datasetName = value; } public function get datasetCount():int { return _datasetCount; } public function set datasetCount(value:int):void { _datasetCount = value; } } }
3、 创建服务类
服务类负责构造请求参数、与GIS服务交互,发送客户端请求及处理返回结果。SuperMap iClient for Flex为方便对接服务端扩展服务,提供ServiceBase接口,开发人员仅需继承该类并实现其基本方法,重新构造请求参数及处理返回结果。坐标转换服务类代码如下:
package com.supermap.extend { import com.adobe.serialization.json.JSON; import com.adobe.utils.StringUtil; import com.supermap.web.core.*; import com.supermap.web.serialization.json.JSONDecoder; import com.supermap.web.service.ServiceBase; import com.supermap.web.utils.*; import flashx.textLayout.tlf_internal; import mx.rpc.AsyncToken; import mx.rpc.IResponder; import mx.utils.StringUtil; public class DatasetsListService extends ServiceBase { //返回结果 private var _lastResult:DatasetsListResult = new DatasetsListResult(); override public function DatasetsListService(url:String) { super(url); } public function processAsync(parameters:DatasetsListParameter, responder:IResponder=null):AsyncToken { if (parameters == null) { this.handleStringError("参数为空", null); return null; } //获取参数 var datasourceName:String = parameters.datasource; //编码处理,如果数据源名是中文需要编码,编码函数encodeURI //http://localhost:8090/iserver/services/data-world/rest/data/datasources/World/datasets.rjson //构造请求URL var extendURL:String = encodeURI(datasourceName)+"/datasets.json"; if(this.url.charAt(this.url.length - 1) != "/") { extendURL = this.url + "/" + extendURL ; } return sendURL(extendURL, null, responder, this.handleDecodedObject); } private function handleDecodedObject(object:Object, asyncToken:AsyncToken):void { var responder:IResponder;//结果解析 var jsonObj:Object= object; var datasetsResult:DatasetsListResult = new DatasetsListResult(); datasetsResult.datasetCount = jsonObj.datasetCount; datasetsResult.datasetName = jsonObj.datasetNames; this._lastResult =datasetsResult; for each (responder in asyncToken.responders) { responder.result(_lastResult); } } } }
4、 扩展接口的调用
前面介绍了客户端开发包封装服务接口的实现方法,下面将介绍利用客户端封装的接口实现坐标转换服务的调用。首先创建Flex项目FlexGetDatasetList,然后添加地图窗体;其次引用前面创建的as包(直接在拷贝包文件到新建的Flex项目中即可);然后添加一个Button按钮,并给Button按钮添加button1_clickHandler(event:MouseEvent)响应事件,页面代码如下: