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

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

多级部署下的SuperMap iServer 2.0 JS 聚合功能(一)_第1张图片

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

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

文中中记录了作者采用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做的一些服务聚合,功能共享的工作,供参考。

你可能感兴趣的:(server)