• 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 远程调用。。。看不出任何 内部细节。只能作罢。

     

  • 相关阅读:
    iOS 记录近期遇到的几个bug
    iOS转场动画封装
    iOS 页面滑动与标题切换颜色渐变的联动效果
    Realm数据持久化方案的简单介绍和使用(二)
    某互联网科技公司的一道逻辑面试题
    js获取本月,本季度,上个季度,本周,上周的起始和结束时间
    CSS样式说明
    a标签的样式
    CSS3的> 和@
    CSS中的position定位
  • 原文地址:https://www.cnblogs.com/ayanmw/p/2540198.html
Copyright © 2020-2023  润新知