Version: 10.2.1c and 10.2.1c SP3 |
ArcFM Engine Overview > ArcFM Engine Customizations > Search Strategies > Search Strategy Code Sample |
This sample is the code for the XY Coordinates locator included with the product installation. This search method allows you to locate features by their location on the map. Either enter coordinates manually, or use the XY tool to click a point on the map and enter the coordinates of that point in the X and Y fields.
Product Availability: ArcFM Desktop, ArcFM Engine
References:
Esri.ArcGIS.Carto, Esri.ArcGIS.Display, Esri.ArcGIS.Geodatabase, Esri.ArcGIS.Geometry, Esri.ArcGIS.System, Miner.Framework, Miner.Framework.Engine, Miner.Interop.Framework, Miner.Interop.FrameworkUI, Miner.System, System, System.Drawing, System.Windows.Forms |
|
Search StrategyThe Search Strategy is the portion that performs the search and returns search results.
IMMSearchStrategy contains only the Find method. The Find method returns an IMMSearchResults object that contains the search results.
The ExtractSettings method extracts the property set provided by IMMSearchConfiguration and uses this information to perform the search.
The Stopped property is used to stop the search when the user clicks the Stop button on the Locator user interface.
The ExecuteFind method executes the find.
The BuildSearchGeometry method returns an IGeometry object that determines the search area.
The IEnumLayer method returns the feature layers that reside within the search area.
The LocateFeature method returns an ICursor object that contains a collection of the features located as a result of the search.
The TableAlreadySearched method returns a boolean value indicating whether the table has been previously searched.
The AddCursorToResults method takes the cursor created by the LocateFeature method and adds it to the results.
The GetQueryDefinition method...
The GetFeatureClass method takes an ILayer object and returns an IFeatureClass object.
C# |
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; } } } |
Search Strategy UI
The SetXYToolImage method sets the image displayed as the cursor when the user clicks the XY tool to select a point on the map.
The GetUserSettings method gets the settings (e.g., X and Y coordinate values) from the user interface and provides them as an IMMSearchConfiguration object.
The GetCoordsFromXYTool method populates the X and Y fields using the points on the map at which the user clicks with the XY tool.
The InitializeStrategyUI method takes a map and initializes the search strategy.
The Priority property allows you to set the order in which your search strategy appears in the list of search strategies on the Locator tool user interface.
The Reset method clears the user interface in preparation for the next search.
The SearchStrategy property takes an IMMSearchStrategy object. This object contains the Find method that executes the search.
The GetSearchConfiguration takes the information gathered by the GetUserSettings method and provides an IMMSearchConfiguration object. This may include information such as options (e.g., AutoZoom and AutoSelect).
Registers the user interface component in the MMLocatorSearchStrategyUI category. If the UI is not registered in this component category, it will not appear in the list of search strategies (locators) on the Locator tool.
C# Sample |
Copy Code
|
---|---|
using System; using System.ComponentModel; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using Miner.ComCategories; using Miner.Framework.Search; using Miner.Interop; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; namespace Miner.Samples.Search.Strategies { [ClassInterface(ClassInterfaceType.None)] [Guid("5F24275E-9A43-4adc-B462-4DD6170C2FB6")] [ProgId("MinerDeveloperSamples.SampleXYSearchUI")] [ComponentCategory(ComCategory.MMLocatorSearchStrategyUI)] public class XYSearchUI : System.Windows.Forms.UserControl, IMMSearchStrategyUI { private IMap _map; private IActiveView _activeView; private IScreenDisplay _screenDisplay; private DecimalConverter _converter = new DecimalConverter(); private IObjectClass _classFilter = null; private string _caption = "Sample XY Search"; private int _priority = 0; private System.Windows.Forms.TextBox txtXCoord; private System.Windows.Forms.TextBox txtYCoord; private System.Windows.Forms.TextBox txtDistance; private System.Windows.Forms.Label lblX; private System.Windows.Forms.Label lblY; private System.Windows.Forms.Button btnXYTool; private System.Windows.Forms.Label lblDistance; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null; public XYSearchUI() { try { // This call is required by the Windows.Forms Form Designer. InitializeComponent(); SetXYToolImage(); } catch (Exception xcp) { MessageBox.Show("Failure in Ctor: " + xcp.ToString()); } } /// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.txtXCoord = new System.Windows.Forms.TextBox(); this.txtYCoord = new System.Windows.Forms.TextBox(); this.txtDistance = new System.Windows.Forms.TextBox(); this.lblX = new System.Windows.Forms.Label(); this.lblY = new System.Windows.Forms.Label(); this.lblDistance = new System.Windows.Forms.Label(); this.btnXYTool = new System.Windows.Forms.Button(); this.SuspendLayout(); // // txtXCoord // this.txtXCoord.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.txtXCoord.Location = new System.Drawing.Point(56, 8); this.txtXCoord.Name = "txtXCoord"; this.txtXCoord.Size = new System.Drawing.Size(100, 20); this.txtXCoord.TabIndex = 0; this.txtXCoord.Text = "000000"; // // txtYCoord // this.txtYCoord.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.txtYCoord.Location = new System.Drawing.Point(56, 40); this.txtYCoord.Name = "txtYCoord"; this.txtYCoord.Size = new System.Drawing.Size(100, 20); this.txtYCoord.TabIndex = 1; this.txtYCoord.Text = "111111"; this.txtYCoord.WordWrap = false; // // txtDistance // this.txtDistance.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.txtDistance.Location = new System.Drawing.Point(16, 96); this.txtDistance.Name = "txtDistance"; this.txtDistance.Size = new System.Drawing.Size(100, 20); this.txtDistance.TabIndex = 2; this.txtDistance.Text = "22222"; // // lblX // this.lblX.Location = new System.Drawing.Point(8, 8); this.lblX.Name = "lblX"; this.lblX.Size = new System.Drawing.Size(40, 16); this.lblX.TabIndex = 3; this.lblX.Text = "X:"; this.lblX.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // lblY // this.lblY.Location = new System.Drawing.Point(8, 40); this.lblY.Name = "lblY"; this.lblY.Size = new System.Drawing.Size(40, 16); this.lblY.TabIndex = 2; this.lblY.Text = "Y:"; this.lblY.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // // lblDistance // this.lblDistance.Location = new System.Drawing.Point(16, 72); this.lblDistance.Name = "lblDistance"; this.lblDistance.Size = new System.Drawing.Size(144, 16); this.lblDistance.TabIndex = 1; this.lblDistance.Text = "Search Distance:"; this.lblDistance.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // btnXYTool // this.btnXYTool.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.btnXYTool.Location = new System.Drawing.Point(168, 16); this.btnXYTool.Name = "btnXYTool"; this.btnXYTool.Size = new System.Drawing.Size(32, 32); this.btnXYTool.TabIndex = 0; this.btnXYTool.TabStop = false; this.btnXYTool.Click += new System.EventHandler(this.btnXYTool_Click); // // XYSearchUI // this.Controls.Add(this.btnXYTool); this.Controls.Add(this.lblDistance); this.Controls.Add(this.lblY); this.Controls.Add(this.lblX); this.Controls.Add(this.txtDistance); this.Controls.Add(this.txtYCoord); this.Controls.Add(this.txtXCoord); this.Name = "XYSearchUI"; this.Size = new System.Drawing.Size(216, 128); this.Load += new System.EventHandler(this.XYSearchUI_Load); this.ResumeLayout(false); this.PerformLayout(); } #endregion #region Private Methods private void SetXYToolImage() { try { Bitmap xyBmp = new Bitmap(GetType().Assembly.GetManifestResourceStream("Miner.Samples.XYSearchStrategy.XYPointerTool.bmp")); xyBmp.MakeTransparent(xyBmp.GetPixel(0,0)); btnXYTool.Image = xyBmp; } catch (Exception xcp) { MessageBox.Show("Failed to set image" + xcp.ToString()); } } private IMMSearchConfiguration GetUserSettings() { Decimal x = (Decimal) _converter.ConvertFromString(txtXCoord.Text); Decimal y = (Decimal) _converter.ConvertFromString(txtYCoord.Text); Decimal d = (Decimal) _converter.ConvertFromString(txtDistance.Text); double X = (double) Convert.ToDouble(x); double Y = (double) Convert.ToDouble(y); double D = (double) Convert.ToDouble(d); if (D <= 1) D = 1; IPropertySet properties = new PropertySetClass(); properties.SetProperty("Map", _map); properties.SetProperty("XCoord", X); properties.SetProperty("YCoord", Y); properties.SetProperty("Distance", D); properties.SetProperty("ObjectClass", _classFilter); IMMSearchConfiguration config = new SearchConfiguration(); if (null == config) return null; config.SearchParameters = properties; return config; } private void GetCoordsFromXYTool() { IPoint point = null; IGeometry geom = new PointClass(); IRubberBand rb = new RubberPointClass(); if (rb.TrackExisting(_screenDisplay, null, geom)) { point = rb.TrackNew(_screenDisplay, null) as IPoint; } if (point != null) { txtXCoord.Text = point.X.ToString(); txtYCoord.Text = point.Y.ToString(); txtDistance.Focus(); } } #endregion #region IMMSearchStrategyUI Members public void InitializeStrategyUI(ESRI.ArcGIS.Carto.IMap pMap, ESRI.ArcGIS.Geodatabase.IObjectClass pClassFilter) { _map = pMap; _activeView = pMap as IActiveView; _screenDisplay = _activeView.ScreenDisplay; _classFilter = pClassFilter; } public void Deactivated() { } public int Priority { get { return _priority; } } public void Reset() { txtXCoord.Text = ""; txtYCoord.Text = ""; txtDistance.Text = ""; } public IMMSearchStrategy SearchStrategy { get { IMMSearchStrategy strategy = new XYSearch() as IMMSearchStrategy; if (null == strategy) { throw new Exception("Failed to create new SampleXYSearch"); } return strategy; } } public string Caption { get { return _caption; } } public IMMSearchConfiguration GetSearchConfiguration(mmSearchOptionFlags optionFlags) { return GetUserSettings(); } public void Shutdown() { //do nothing } public string COMProgID { get { return null; } } public IMMResultsProcessor ResultsProcessor { get { return null; } } #endregion #region User Interface Events private void btnXYTool_Click(object sender, System.EventArgs e) { try { System.Windows.Forms.Cursor xyCursor = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream("Miner.Samples.XYSearchStrategy.XYSearchCursor.cur")); this.Cursor = xyCursor; GetCoordsFromXYTool(); } catch (Exception xcp) { MessageBox.Show("Failed to process XYTool click" + xcp.ToString()); // dont throw! } finally { this.Cursor = Cursors.Default; } } #endregion private void XYSearchUI_Load(object sender, EventArgs e) { } } } |