Select to view content in your preferred language

How do you Query a Map Service in a Map Document?

2756
3
08-14-2014 11:59 AM
ThomasHasselbeck
Occasional Contributor

Hi All -

I'm building an Add-in for ArcMap (using C# and ArcObjects) that provides a custom dialog with a textbox that expects a parcel APN number; entered by the user. If the APN is valid, zoom to the location.  When I began developing this tool I took a subset of my Map Service parcel data and created a gdb.

I got everything working and assumed...(wrongly)... that I could simply change the CLSID reference in the code from working with geodatabase layers to  MapServer sublayer.  As I stated, this was wrong. It now appears that I have an invalid cast. Can anyone suggest how I might be able to save most of this code without having to rewrite it to work with a map service? The map service supports the Query operation, I suspect the answer lies within IQuery. On the positive side, I have created a tool that will successfully close ArcMap...rather quickly too I might add.

<Add-in code snippet>

            IMxDocument pMxDoc = ArcMap.Document;

            pMap = pMxDoc.FocusMap;

            IEnumLayer pEnumLayer = null;

            // string LayerCLSID = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}";

            string LayerCLSID = "{B059B902-5C7A-4287-982E-EF0BC77C6AAB}"; // IMapServerSublayer

            ESRI.ArcGIS.esriSystem.UID uid = new ESRI.ArcGIS.esriSystem.UIDClass();

            uid.Value = LayerCLSID;

            pEnumLayer = pMap.get_Layers(((ESRI.ArcGIS.esriSystem.UID)(uid)), true);

            pEnumLayer.Reset();

            ILayer layer = pEnumLayer.Next();

            ILayer selLayer = null;

            while (!(layer == null))

            {

                if (layer.Name == "Riverside Parcels")

                {

                    selLayer = layer;

                    string sqlStatement = "APN = '" + textBox1.Text + "'";

                    IFeatureSelection fSelection = selLayer as IFeatureSelection; //  <= **** Invalid Cast? ****

                    IQueryFilter qFilter = new QueryFilterClass();

                    esriSelectionResultEnum selectionResult = new esriSelectionResultEnum();

                    qFilter.WhereClause = sqlStatement;

                    fSelection.SelectFeatures(qFilter,selectionResult,false);

                }//closes if

                layer = pEnumLayer.Next();

             }//closes while

Thanks

Tom

Tags (3)
0 Kudos
3 Replies
ErinBrimhall
Deactivated User

Hi Thomas,

Interacting with a Map service layer is a bit different than if you were connecting to geodatabase objects directly.

The primary issue you're running into is that no class implementing IMapServerSublayer also implements IFeatureSelection, which is why your cast fails. 

To query the Map service layer:

  1. Cast your desired sub-layer as an IFind object.
  2. Invoke its Find method with the desired parameters (see example code further down)
  3. Find returns an IArray of IFeatureFindData objects, which expose a Feature property of type IFeature.
  4. Use the IFeature.Shape attribute to zoom to the result! (see example code further down)

// Query an IFind object "serviceLayer"       

string[] fieldName = new [] { "APN" };      

IArray results = serviceLayer.Find(textBox1.Text, false, fieldName, null);

       

...

// Zoom to the IFeatureFindData result object.

IFeatureFindData result = results.get_Element(0) as IFeatureFindData;

ArcMap.Document.ActiveView.Extent = result.Feature.Shape.Envelope;

I hope this info gets you moving in the right direction.

0 Kudos
ThomasHasselbeck
Occasional Contributor

Hi Erin -

Thanks for the response.

Since this was just one layer, no editing and the application is in house, I just added the SDE data directly to the MXD and used my original logic.  I didn't have time to investigate the paradigm of IMapServerSublayer.

Hopefully others will find value from this thread.


Thanks

Tom

0 Kudos
ErinBrimhall
Deactivated User

Very good.  Well, if you ever find yourself going back to the Map Service approach, this code should help. 

0 Kudos