zoukankan      html  css  js  c++  java
  • arcgis sample代码之SOE示例代码Length Calculator Server Object Extension的源码分析

    This Server Object Extension calculates lengths of all street (polyline) features in the associated map service and can be accessed by a client application through DCOM. 

    这个服务器对象扩展SOE可以计算在指定的地图服务中的所有街道(折线)的长度,并且可以通过客户端应用程序使用DCOM来访问。

    此SOE没有实现rest和soap接口,所以在启用此SOE后,在地图服务的rest网页无法看到这个功能。他只能通过客户端使用DCOM来访问。其功能是 计算Streets地图图层de要素类的长度。默认在portLand地图有此地图图层,其他的地图服务如果没有这个要素类是会报错的。当然也可以更改源码改为其他的地图图层。

    下面就是主要的源码:

        MapServer mapServer = null;
            mapServer = (MapServer) soHelper.getServerObject();
    
    
        /****************************************************************************************************************************
         * ICalculateLength method: This is a custom interface. It exposes 1 method:
         * calculateLength()
         ****************************************************************************************************************************/
        /**
         * Calculates length of all polylines
         */
        public double calculateLength() throws Exception {
            
            // Get index of layer containing all locations
            Map map = (Map) this.mapServer.getMap("Layers");
            FeatureClass streetsFC = new FeatureClass(this.mapServer.getDataSource(this.mapServer.getDefaultMapName(), getLayerIndex(map, "Streets")));
    
            // count num of features
            int numFeatures = streetsFC.featureCount(null);
            IFeatureCursor featureCursor = streetsFC.search(null, true);
    
            // calculate length of each feature and add up
            double totalLength = 0.0;
            for (int i = 0; i < numFeatures; i++) {
                IFeature feature = featureCursor.nextFeature();
                Polyline polyline = (Polyline) feature.getShape();
                totalLength += polyline.getLength();
            }
    
            return totalLength;
        }
    
        /************************************************************************
         * Util methods
         ************************************************************************/
        /**
         * Retrieves ID of a layer in MapEJB based on its name
         * 
         * @param mapServer
         * @param layerName
         * @return
         */
        private int getLayerIndex(Map map, String layerName) throws IOException, AutomationException {
            int layerID = -1;
    
            for (int i = 0; i < map.getLayerCount(); i++) {
                String name = map.getLayer(i).getName();
                if (layerName.equalsIgnoreCase(name)) {
                    layerID = i;
                    break;
                }
            }
    
            if (layerID < 0) {
                serverLog.addMessage(4, 8000, "Could not find layer " + layerName + " in " + map.getName());
                throw new RuntimeException("Could not find layer " + layerName + " in " + map.getName());
            }
    
            return layerID;
        }

    通过 soHelper.getServerObject();获得mapserver对象,在通过mapserver的getMap("Layers")获得Map对象,通过Mapserver的getDataSource方法获得一个FeatureClass对象,再根据FeatureClass的一个游标获得feature对象,因而获得polyline feature的length,遍历累计相加,返回结果。

    我更感兴趣的是:客户端如何通过DCOM来调用这个Length Calculator Server Object Extension

    /* Copyright 2010 ESRI
    * 
    * All rights reserved under the copyright laws of the United States
    * and applicable international laws, treaties, and conventions.
    * 
    * You may freely redistribute and use this sample code, with or
    * without modification, provided you include the original copyright
    * notice and use restrictions.
    * 
    * See the use restrictions at &lt;your ArcGIS install location&gt;/DeveloperKit10.0/userestrictions.txt.
    * 
    */
    package arcgissamples.soe.client;
    
    
    import arcgissamples.soe.ICalculateLength;
    
    import com.esri.arcgis.carto.MapServer;
    import com.esri.arcgis.server.IServerObjectExtension;
    import com.esri.arcgis.server.IServerObjectExtensionManager;
    import com.esri.arcgis.server.ServerConnection;
    import com.esri.arcgis.server.ServerContext;
    import com.esri.arcgis.server.ServerObjectManager;
    import com.esri.arcgis.system.ServerInitializer;
    
    public class LengthCalculatorClient {
        private static String serverName, domainName, userName, password, serviceName;
        private static ServerConnection connection;
    
        public static void main(String[] args) {
            try {
                if (args.length != 5) {
                    System.out.println("Wrong Usage. For correct usage, see following: \n"
                            + "\nUsage: LengthCalculatorClient [server name] [domain name] [user name] [password] [map service name]\n\n"
                        + "[server name]\tSpecifies name of ArcGIS Server\n" + "[domain name]\tSpecifies domain name of user\n"
                        + "[user name]\tSpecifies user name\n" + "[password]\tSpecifies user password\n" 
                        + "[map service name]\tSpecifies name of map service\n");
                    
                    System.exit(1);
                } else {
                    // connect to Server
                    serverName = args[0];
                    domainName = args[1];
                    userName = args[2];
                    password = args[3];
                    serviceName = args[4];
    
                    ServerInitializer serverInit = new ServerInitializer();
                    serverInit.initializeServer(domainName, userName, password);
    
                    System.out.print("Connecting to ArcGIS Server " + serverName + "...");
                    connection = new ServerConnection();
                    connection.connect(serverName);
                    System.out.println("Done.");
    
                    // Retrieve the SOM to get ServerContext and the Map Server Object
                    System.out.print("Retrieving Server Object Manager.");
                    ServerObjectManager som = new ServerObjectManager(connection.getServerObjectManager());
                    System.out.println("Done.");
    
                    System.out.print("Creating Server Context...");
                    String soeName = "LengthCalculatorSOE";
                    ServerContext serverContext = new ServerContext(som.createServerContext(serviceName, "MapServer"));
                    MapServer mapServer = (MapServer) serverContext.getServerObject();
                    System.out.println("Done.");
    
                    // Access the soe through the IServerObjectExtensionManager
                    System.out.println("Creating instance of SOE..");
                    IServerObjectExtensionManager extnMgr = (IServerObjectExtensionManager) mapServer;
                    IServerObjectExtension calculatorSOE = extnMgr.findExtensionByTypeName(soeName);
                    System.out.println("Done.");
    
                    // Consume the SOE
                    System.out.println("\nInvoking SOE's calculateLength() method...");
                    ICalculateLength mySOE = (ICalculateLength) calculatorSOE;
                    System.out.println("Total Length returned by SOE: " + mySOE.calculateLength());
    
                    // releasing connection
                    System.out.print("\nDisconnecting " + serverName + "...");
                    connection.release();
                    System.out.println("Done.");
                }
            } catch (Exception e) {
                try {
                    connection.release();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
    
                e.printStackTrace();
            }
        }
    }

    这个java 程序 居然可以不用engine的许可,就调用ao的类。。

    传递几个参数:serverName:localhost domainName:127.0.0.1 userName:arcgismanager password:arcgismanager serviceName:portland。username和password貌似没啥必要。不清楚。

    通过 new ServerConnection();然后一步一步的获得了Mapserver对象,继而获得SOE对象,最后强制转换为ICalculateLength的SOE对象,直接调用calculatgeLength方法直接得到结果了,貌似跟本地程序一样,这就是 传说中的 DCOM 远程调用。。。看不出任何 内部细节。只能作罢。

     

  • 相关阅读:
    day7 面向对象 静态方法 类方法 属性方法 类的特殊成员方法 元类 反射 异常处理
    day6 面向对象 封装 继承 多态 类与实例在内存中的关系 经典类和新式类
    day5 time datetime random os sys shutil json pickle shelve xml configparser hashlib subprocess logging re正则 python计算器
    kafka常用操作命令
    linux基础
    django学习1——初识web应用程序
    mysql数据库(三)——pymysql模块
    mysql数据库(二)——表的查询
    mysql数据库(一)
    Python常用模块——re模块
  • 原文地址:https://www.cnblogs.com/ayanmw/p/2540198.html
Copyright © 2011-2022 走看看