ArcFM Engine Developer Guide
SampleXYSearch.cs Code

Resource Center Home

Search Strategy Developer Sample (C#)

SampleXYSearch.cs

 

Copy Code
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections;
using Miner.Interop;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;

namespace Miner.Samples.Search.Strategies
{
 /// <summary>
 /// XY Search Strategy
 /// Configuration file must include these properties:
 ///  (IMap) "Map" 
 ///  (double) "XCoord" 
 ///  (double) "YCoord"
 ///  (double) "Distance"
 ///  (IObjectClass) "ObjectClass"
 /// </summary>
 [ClassInterface(ClassInterfaceType.None)]
 [Guid("E52A4CFA-651A-46a0-BD9E-B0213BDE19AA")]
 [ProgId("MinerDeveloperSamples.SampleXYSearch")]
 public class XYSearch : IMMSearchStrategy
 {
  
  private string _featureLayerClassID = "{40A9E885-5533-11D0-98BE-00805F7CED21}";
  private IMMRowSearchResults _results;
  private Hashtable _tableHash;
  private IMMSearchControl _searchControl;
  private double _xCoord;
  private double _yCoord;
  private double _distance;
  private IMap _map;
  private IObjectClass _classFilter;
  public XYSearch(){} // no constructor req'd.
  #region IMMSearchStrategy Members
  public IMMSearchResults Find(IMMSearchConfiguration pSearchConfig, IMMSearchControl searchControl)
  {
   _searchControl = searchControl;
   ExtractSettings(pSearchConfig);
   ExecuteFind();
   if (Stopped)
   {
    return null;
   }
   else
   {
    return _results as IMMSearchResults; 
   }
  }
  #endregion
  private void ExtractSettings(IMMSearchConfiguration config)
  {
   if (null == config) throw new InvalidOperationException("Null IMMSearchConfiguration; find cannot proceed.");
   
   IPropertySet properties = config.SearchParameters as IPropertySet;
   
   if (null == properties) throw new InvalidOperationException("No PropertySet in IMMSearchConfiguration; find cannot proceed.");
   
   _map = (IMap) properties.GetProperty("Map");
   _xCoord = (double) properties.GetProperty("XCoord");
   _yCoord = (double) properties.GetProperty("YCoord");
   _distance = (double) properties.GetProperty("Distance");
   _classFilter = (IObjectClass) properties.GetProperty("ObjectClass");
   if (_distance < 1) 
   {
    _distance = 1;
   }
  }
  private bool Stopped
  {
   get
   {
    if (_searchControl != null)
    {
     return _searchControl.Stopped;
    }
    else
    {
     return false;
    }
   }
  }
  private void ExecuteFind()
  { 
   // todo: Use filters for map production.

   // We track the tables that we have visited to eliminate 
   // duplicates.  Create a hash with the number of tables
   // we may hit.  Note that LayerCount only returns the 
   // count of top-level layers, NOT those that are buried 
   // under groups - thus the doubling factor here:
   int appxNumberOfActualLayers = _map.LayerCount * 2;
   _tableHash = new Hashtable(appxNumberOfActualLayers);
   IGeometry searchArea = BuildSearchGeometry();
   
   IEnumLayer layers = GetFeatureLayers();
   layers.Reset();
   ILayer layer = layers.Next();
   while (layer != null)
   {
    if (Stopped) break;
    if (layer.Valid)
    {
     ICursor cursor = LocateFeatures(layer, searchArea);
     AddCursorToResults(cursor);
    }
    layer = layers.Next();
   }
   // no need to persist the table data; clear it out.
   _tableHash.Clear();
  }
  private IGeometry BuildSearchGeometry()
  {
   IPoint center = new PointClass();
   center.X = _xCoord;
   center.Y = _yCoord;
   ICircularArc circle = new CircularArcClass();
   IConstructCircularArc makeCircle = circle as IConstructCircularArc;
   makeCircle.ConstructCircle(center, _distance, true);
   return circle as IGeometry;
  }
  private IEnumLayer GetFeatureLayers()
  {
   ESRI.ArcGIS.esriSystem.UID filterUID = new ESRI.ArcGIS.esriSystem.UIDClass();
   filterUID.Value = _featureLayerClassID;
   return _map.get_Layers(filterUID, true);
  }
  private ICursor LocateFeatures(ILayer layer, IGeometry searchArea)
  {
   IFeatureClass featClass = GetFeatureClass(layer);
   if (featClass == null) return null;
   ISpatialFilter filter = new SpatialFilterClass();
   filter.Geometry = searchArea.Envelope;
   filter.GeometryField = featClass.ShapeFieldName;
   filter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
   filter.WhereClause += GetQueryDefinition(layer);
   IObjectClass oc = featClass as IObjectClass;
   ITable table = oc as ITable; 
   
   ICursor cursor = null;
   // Due to grouped layers, we may be hitting the same 
   // table twice.  Check here if we have already checked
   // this one - we do not want to duplicate results.
   if (TableAlreadySearched(table)) return cursor;
   try
   {
    cursor = table.Search(filter, false);
   }
   catch
   {
    //notify user with a pretty msg that the search failed:
    Resourcer res = new Resourcer();
    string msg = "Failed Table Search";
    string title = "Sample XY Search";
    MessageBox.Show(msg, title);
   }
   return cursor;
  }
  private bool TableAlreadySearched(ITable table)
  {
   if (!_tableHash.Contains(table))
   {
    _tableHash.Add(table, null);
    return false;
   }
   else
   {
    return true;
   }
  }
  private void AddCursorToResults(ICursor cursor)
  {
   // simply take a cursor, and add it to the 
   // internal _results object.
   
   if (cursor == null) return;
   if (_results == null)
   {
    _results = new Miner.Framework.Search.RowSearchResults();
   }
   _results.AddCursor(cursor, false);
  }
  private string GetQueryDefinition(ILayer layer)
  {
   if (layer == null) return null;
   
   IFeatureLayerDefinition flDef = layer as IFeatureLayerDefinition;
   if (null == flDef) return null;
   string queryDef = flDef.DefinitionExpression;
   if (queryDef != null && queryDef.Length > 0)
   {
    queryDef = "(" + queryDef + ")"; 
   }
   
   return queryDef;
  }
  private IFeatureClass GetFeatureClass(ILayer layer)
  {
   if (layer == null || !layer.Valid) return null;
   IFeatureLayer featLyr = layer as IFeatureLayer;
   if (featLyr == null) return null;
   return featLyr.FeatureClass;
  }
 }
}

 

 


Send Comment to ArcFMdocumentation@schneider-electric.com