Find Nearby Features SOAP Server Object Extension
arcgissamples\soe\FindNearbyFeaturesSOE.java
/* 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.
* 
*/
package arcgissamples.soe;

import java.io.IOException;
import java.net.UnknownHostException;

import com.esri.arcgis.carto.ILayerDescriptions;
import com.esri.arcgis.carto.LayerDescription;
import com.esri.arcgis.carto.LayerResultOptions;
import com.esri.arcgis.carto.Map;
import com.esri.arcgis.carto.MapServer;
import com.esri.arcgis.carto.QueryResult;
import com.esri.arcgis.carto.QueryResultOptions;
import com.esri.arcgis.carto.esriQueryResultFormat;
import com.esri.arcgis.geodatabase.FeatureClass;
import com.esri.arcgis.geodatabase.GeometryResultOptions;
import com.esri.arcgis.geodatabase.RecordSet;
import com.esri.arcgis.geodatabase.SpatialFilter;
import com.esri.arcgis.geodatabase.esriFeatureType;
import com.esri.arcgis.geodatabase.esriSpatialRelEnum;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.geometry.Polygon;
import com.esri.arcgis.interop.AutomationException;
import com.esri.arcgis.interop.extn.ArcGISExtension;
import com.esri.arcgis.interop.extn.ServerObjectExtProperties;
import com.esri.arcgis.server.IServerObjectExtension;
import com.esri.arcgis.server.IServerObjectHelper;
import com.esri.arcgis.server.SOAPRequestHandler;

@ArcGISExtension
@ServerObjectExtProperties(
  displayName = "Find Nearby Features",
  description = "Find Nearby Features using SOAP",
  supportsMSD = true
)
public class FindNearbyFeaturesSOE extends SOAPRequestHandler implements IServerObjectExtension, IFindFeatures
{
  private static final long serialVersionUID = 1L;
  private IServerObjectHelper soHelper;
  private MapServer mapServer;

  public FindNearbyFeaturesSOE() throws Exception {
    super();
  }

  /****************************************************************************************************************************
   * IServerObjectExtension methods:
   * This is a mandatory interface that must be supported by all SOEs. 
   * This interface is used by the Server Object to manage the lifetime of the SOE and includes 
   * two methods: init() and shutdown(). 
   * The Server Object cocreates the SOE and calls the init() method handing it a back reference 
   * to the Server Object via the Server Object Helper argument. The Server Object Helper implements 
   * a weak reference on the Server Object. The extension can keep a strong reference on the Server 
   * Object Helper (for example, in a member variable) but should not keep a strong reference 
   * on the Server Object. 
   *    
   * The log entries are merely informative and completely optional. 
   ****************************************************************************************************************************/
  /**
   * init() is called once, when the instance of the SOE is created. 
   */
  public void init(IServerObjectHelper soh) throws IOException, AutomationException
  {
    /*
     * An SOE should get the Server Object from the Server Object Helper in order to make any 
     * method calls on the Server Object and release the reference after making the method calls.
     */
    this.soHelper = soh;
    
    // get the Server Object (SO) this SOE is associated with
    this.mapServer = (MapServer) soHelper.getServerObject();    
  }

  /**
   * shutdown() is called once when the Server Object's context is being shut down and is 
   * about to go away.
   */
  public void shutdown() throws IOException, AutomationException
  {
    /*
     * The SOE should release its reference on the Server Object Helper.
     */
    this.soHelper = null;
    this.mapServer = null;
  }

  /*************************************************************************************
   * SOAP methods
   *************************************************************************************/
  public RecordSet findNearbyFeatures(int layerId, Point location, double distance) throws Exception
  {    
    try
    {
      String mapName = this.mapServer.getDefaultMapName();        
      Map map = (Map) this.mapServer.getMap(mapName);
      int layerCount = map.getLayerCount();
      
      //check if layer id is within bounds
      if(layerId >= layerCount)
      {
        throw new Exception("Invalid layer id provided. Please provide a layer id between 0 and " + (layerCount - 1) + 
            " as associated map service contains only " + layerCount + " layers.");
      }
      
      //get feature class      
      FeatureClass fc = new FeatureClass(this.mapServer.getDataSource(mapName, layerId));
      if(fc.getFeatureType() == esriFeatureType.esriFTSimple)
      {
        //calculate buffer pg for user specified point
        Polygon buffer = (Polygon) location.buffer(distance);
        
        if(buffer != null)
        {
          //intersect with feature class in map
          SpatialFilter spatialFilter = new SpatialFilter();
          spatialFilter.setGeometryByRef(buffer);
          spatialFilter.setSpatialRel(esriSpatialRelEnum.esriSpatialRelIntersects);
        
          //prepare result
          QueryResultOptions qResultOptions = new QueryResultOptions();
          qResultOptions.setFormat(esriQueryResultFormat.esriQueryResultRecordSetAsObject);
                  
          //send result back to client
          QueryResult queryResult = (QueryResult) this.mapServer.queryData(mapName, getTableDescription(this.mapServer, layerId), spatialFilter, qResultOptions);
          return (RecordSet) queryResult.getObject();          
        }        
      }
    }
    catch(java.lang.ClassCastException ce)//not a good idea
    {
      throw new Exception("Specified layer id (" + layerId + ") does not point to a feature layer. This SOE is designed to work only with feature layers.");
    }

    return null;
  }
  
  /*************************************************************************************
   * SOE Util methods
   *************************************************************************************/
    /**
     * 
     */
  private LayerDescription getTableDescription(MapServer mapServer, int layerID)
    {
        try
    {
      ILayerDescriptions layerDescriptions = mapServer.getServerInfo(mapServer.getDefaultMapName()).getDefaultMapDescription().getLayerDescriptions();
      int ldCount = layerDescriptions.getCount();

      for (int i = 0; i < ldCount; i++)
      {
          LayerDescription layerDescription = (LayerDescription) layerDescriptions.getElement(i);

          if (layerDescription.getID() == layerID)
          {
            LayerResultOptions resultOptions = new LayerResultOptions();
            
            GeometryResultOptions geomResultOptions = new GeometryResultOptions();
            geomResultOptions.setDensifyGeometries(true);
            
            resultOptions.setGeometryResultOptionsByRef(geomResultOptions);
            
            layerDescription.setLayerResultOptionsByRef(resultOptions);
            
              return layerDescription;
          }
      }
    }
    catch (AutomationException e)
    {
      e.printStackTrace();
    }
    catch (UnknownHostException e)
    {
      e.printStackTrace();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    
    return null;
    }
}