多级部署下的SuperMap iServer 2.0 JS 聚合功能(一)

话说现在做GIS项目用SuperMap iServer的逐渐增多,而SuperMap iServer具备“服务聚合”的能力,这对于我们的实际应用带来了新的价值,所以有必要研究研究。其实用过ArcGIS Server的朋友或许对于数据/服务熔合有些印象,就是将不同来源的数据/服务mashup在一起来显示,不过现在由于一些大型系统的建设来说,通常是两级/三级部署应用,如图。

那么在这样的部署下,上级系统需要发布全局性信息,并且能够保持与下级系统之间的信息共享与交互;下级系统则维护自身的数据和系统,并且开展本地有特色的系统应用。

说到数据共享和互操作,就引到本文的话题了,也就是利用服务接口实现数据共享,功能共享。

文中中记录了作者采用SuperMap iServer Java SDK尝试数据与功能聚合的一些内容,供大家参考。

 1、数据共享

通常我们考虑的是用OGC服务来做,而且现在GIS的客户端都提供了这种能力,也就是在客户端实现数据mashup,这不是本文的重点,不过贴一段我用SuperMap iServer Java JS接口中的TiledMapLayer做的数据共享,至于原因,主要是因为这样共享的数据是已经经过配置的地图,相对WMS SLD来说容易上手些。

SuperMap.TiledMapLayer
 1 var mapControl;
 2 var params = new Object();
 3 function onPageLoad(){
 4     SuperMap.Resource.ins = new SuperMap.Resource();
 5     SuperMap.Resource.ins.setLanguage("Chinese");
 6     var contextPath = "http://localhost:7080/test/";
 7     SuperMap.Committer.handler = contextPath + "commonhandler";
 8     
 9     params.contextPath = contextPath;
10     params.mapHandler = params.contextPath + "maphandler";
11 
12     params.mapName = "World";
13     params.mapServicesAddress = "localhost";
14     params.mapServicesPort = 8600;
15     params.imageFormat = "png";
16     params.buffer=1;
17 
18     mapControl = new SuperMap.UI.MapControl(document.getElementById("mapcontrol1Div"));
19     mapControl.set_params(params);
20     
21     mapControl.initialize();
22 }
23 function addTiledMapLayer(){
24     var tiledMapLayerParam = new Object();
25     tiledMapLayerParam.mapHandler = "http://192.168.44.125:7080/demo/maphandler";
26     tiledMapLayerParam.mapName = "World";
27     var map = mapControl.getMap();
28     var tiledMapLayer = new SuperMap.TiledMapLayer(null, tiledMapLayerParam, map);
29     tiledMapLayer.set_id("tiledMapLayer");
30     tiledMapLayer.opacity = 50;
31     map.addLayer(tiledMapLayer);
32     mapControl.refreshMapControl();
33 }
34 function removeTiledMapLayer(layerName){
35     var map = mapControl.getMap();
36     if(layerName && layerName.trim()!=""){
37         var layerID = layerName ;
38         var containerID =  mapControl.get_mapDiv().id + "_" + layerID +"_Div";
39         if(mapControl.get_mapDiv()){
40             var layerContainer = document.getElementById(containerID);
41             if(layerContainer){
42                 mapControl.get_mapDiv().removeChild(layerContainer);
43             }
44         }
45         if(map.get_imageLayers()){
46             var length = map.get_imageLayers().length;
47             for(var i = length - 1 ; i >= 0 ; i-- ) {
48                 var layer = map.get_imageLayers()[i];
49                 if(layer.get_id() && layer.get_id() == layerID){
50                     map.get_imageLayers().splice(i,1);
51                 }
52             }
53         }
54     }
55 };

2、功能共享

现在做功能层面的共享,可以考虑用XML WebService来做,不过如果是多级部署都采用一个GIS平台,又希望GIS系统之间实现功能共享的话,建议使用其提供的原生服务来实现功能共享,因为这样的效率会高很多。

用SuperMap iServer Java的SDK来实现各地GIS系统之间的功能,还需要改点SDK的源代码(其js SDK代码是开源的,那么我就改点代码)。

首先看看调用查询功能,这个功能主要是为了实现在两地地图服务聚合后,本系统查询聚合地图源数据的内容。为什么搞的这么麻烦呢?因为本系统的数据服务中没有你想查询的数据内容,只能向聚合过来的源系统发送查询请求来实现,请看代码:

聚合后SQL查询聚合数据
 1 function sqlqueryTiledMapLayer(){
 2     var queryParam = new SuperMap.QueryParam();
 3     queryParam.expectCount = 100;
 4     layerParam = new SuperMap.QueryLayerParam();
 5     layerParam.name = "World@world";
 6     layerParam.sqlParam = new SuperMap.SqlParam();
 7     layerParam.sqlParam.whereClause = "";
 8     queryParam.queryLayerParams = new Array();
 9     queryParam.queryLayerParams.push(layerParam);
10     //queryParam.customParams用来传递一些聚合服务的源Url和地图名称,从而帮助Ajax请求向源系统发送
11     queryParam.customParams = new Array();
12     queryParam.customParams.push("TiledMapLayer");
13     queryParam.customParams.push("World");
14     queryParam.customParams.push("http://192.168.44.125:7080/demo/commonhandler");
15     var needHighlight = true;
16     var map = mapControl.getMap();
17     map.queryBySql(queryParam, needHighlight, onQueryComplete, onError);
18 }
19 function onQueryComplete(resultSets){
20     alert(resultSets.totalCount);
21 }
22 function onError(msg){
23     alert(msg);
24 }

 有了这些还不够,上面的代码只是系统功能,下面还需要改改SuperMap.Map.js中_queryBase内容,因为_queryBase是直接用于向后台提交请求的接口,而源代码中_queryBase提交请求的地址都是本地系统的iServer服务地址,可是我们要查询的数据是来自于聚合服务的系统,因此这里写点代码,让请求能够发向上面代码中设置的地址去:

SuperMap.Map.js
 1 _queryBase:function(methodName, paramNames, paramValues, onComplete, onError, userContext){
 2     ......
 3     ......
 4         onCompleteArray.push(onQueryComplete);
 5         ///////////////////////////////////////////////////////////////////
 6         ///////////////////////////////////////////////////////////////////
 7         var tiledMapName;
 8         var tiledUrl;
 9         if(paramValues[0].customParams != null && paramValues[0].customParams.length > 0){
10             var customParams = paramValues[0].customParams;
11             if(customParams[0== "TiledMapLayer"){
12                 tiledMapName = customParams[1];
13                 tiledUrl = customParams[2];
14                 SuperMap.Committer.commitAjax(tiledMapName, tiledUrl, methodName, paramNames, paramValues, false, onCompleteArray, onError, userContext);
15             }else{
16                 SuperMap.Committer.commitAjax(this._params.mapName, this.queryUrl, methodName, paramNames, paramValues, false, onCompleteArray, onError, userContext);
17             }
18         }
19         ///////////////////////////////////////////////////////////////////
20         ///////////////////////////////////////////////////////////////////
    ......
    ......

ok,查询的请求发送到了该发送的地址了。

 下面看看编辑功能,思路上和查询的实现过程差不多,直接看代码:

聚合后编辑聚合数据
 1 function addEntityTiledMapLayer(){
 2     var layername = "World@world";
 3     var layertype = 5;
 4     var needHighlight = true;
 5     var customParam = new Array();
 6     customParam.push("TiledMapLayer");
 7     customParam.push("World");
 8     customParam.push("http://192.168.44.125:7080/demo/commonhandler");
 9     var addEntityAction = new SuperMap.UI.AddEntityAction(layername, layertype, needHighlight, onAddEntityComplete, onError, customParam);
10     mapControl.set_action(addEntityAction);
11 }
12 function onAddEntityComplete(editResult){
13     if(editResult.succeed)    alert("succeed");
14     else alert("failed");
15 }

然后修改两个文件,其中一个是SuperMap.UI.Action.js,另一个还是SuperMap.Map.js ,这里以增加地物为例

代码
SuperMap.UI.AddEntityAction=function(layerName, layerType, needHighlight, onComplete, onError, customParam){
    
this._customParam = customParam;
    ......
    ......
        SuperMap.UI.AddEntityAction.prototype
={
            ......
            ......    
            _onAddEntityComplete:
function(editResult){
                ......
                ......        
            onClick:
function(e){
                ......
                ......    
               
this._mapControl.getMap().addEntity(this._layerName, entity, this._needHighlight, onAddEntityCompleteDelegate, this._onError, this._customParam);
                ......
                ......        
            onDblClick:
function(e){
                ......
                ......    
               
this._mapControl.getMap().addEntity(this._layerName, entity, this._needHighlight, onAddEntityCompleteDelegate, this._onError, this._customParam);
                ......
                ......    
                
this._mapControl.getMap()._t = new Date().getTime();
               
this._mapControl.getMap().addEntity(this._layerName, entity, this._needHighlight, onAddEntityCompleteDelegate, this._onError, this._customParam);
    ......
    ......            
};
SuperMap.Map.js
_editBase:function(mapName, methodName, paramNames, paramValues, onComplete, onError, userContext){
        ......
        
var lockID = new Date().getTime().toString() + Math.floor(Math.random( )*1000000000);
        paramNames.push(
"lockID");
        paramValues.push(lockID);
        
///////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////
        var tiledMapName;
        
var tiledUrl;
        
if(paramValues[3!= null && paramValues[3].length > 0){
            
var customParam = paramValues[3];
            
if(customParam[0== "TiledMapLayer"){
                tiledMapName 
= customParam[1];
                tiledUrl 
= customParam[2];
                SuperMap.Committer.commitAjax(tiledMapName, tiledUrl, methodName, paramNames, paramValues, 
false, onCompleteArray, onError, userContext);
            }
else{
                SuperMap.Committer.commitAjax(mapName, 
this.queryUrl, methodName, paramNames, paramValues, false, onCompleteArray, onError, userContext);
            }
        }
        
///////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////

ok,这样编辑功能也完成了。

3、其他说明

(1)功能聚合可以做到查询系列、编辑系统和专题图系列,这里没有列出专题图,因为我也没有考虑好究竟怎样实现比较理想;

(2)关于功能共享(数据互操作)的安全性,这是系统建设必须要考虑的,上面实现的代码没有包含权限管理的内容,建议采用SuperMap提供的扩展Map机制,使用Session来进行权限管理。

(3)文中的代码没有详细的注释,也没有仔细整理过,是直接贴上来的,可能存在漏洞,请谅解。

以上就是利用SuperMap iServer Java 2.0 JS SDK做的一些服务聚合,功能共享的工作,供参考。

Author:dulvyizhihua
原文地址:https://www.cnblogs.com/dulvyizhihua/p/1616965.html