Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am new to ArcGIS and I am trying to create an Add-In button which can

  1. figure out which polygons are selected and
  2. query the selected polygons to generate a report on the underlying metadata (similar to the Identify tool).

I had a look at this article, which helped with finding the selected feature layer, but I haven't been able to progress much further.

Any help would be much appreciated.

Update:

At the moment all I have is a one-liner. Here is some pseudo code of what I would like to do:

var featureLayer = ArcMap.Document.CurrentContentsView.SelectedItem as IFeatureLayer;
var selectedFeatures = featureLayer.SelectedFeatures;

// A list to contain the info available in Identify tool (not sure what this is called)
var featuresAttributes = new List<FeatureAttributes>();

// For each selected polygon
foreach(var feature in selectedFeatures)
    featuresAttributes.Add(feature.Attributes);

// Go off and generate some report based on the selected polygon attributes
MyReportGenerator.CreateReport(featuresAttributes); 
share|improve this question
    
Could you be more specific about where you're getting stuck? How far along is your code and what is the next step? –  Nathanus Nov 9 '11 at 22:35
    
@Nathanus Thanks for the comment. I've updated my post. –  Andre Nov 10 '11 at 7:23
    
I don't think you mean metadata when you say metadata. I think you just mean data, or feature attributes. –  blah238 Nov 10 '11 at 7:57
    
Attributes might be better. Changing... –  Andre Nov 10 '11 at 9:04
    
@Andre, What type of info are you wanting to generate from your report, statistics, list of selected features + statistics? Also, do you have a desired file type for your report, eg. dbf, xls, rdf, txt...? –  artwork21 Nov 10 '11 at 13:44

2 Answers 2

up vote 3 down vote accepted

You can use dictionaries for this type of thing. There are more memory efficient ways of doing this (by just storing field names once), but this might get you started.

public void TestGetSelection()
{
    var dict = GetSelection(ArcMap.Document.FocusMap.get_Layer(0) as IFeatureLayer);
    foreach (KeyValuePair<int, Dictionary<string, object>> kvp in dict)
    {
        Debug.Print("{0} {1}", kvp.Key, kvp.Value["State_Name"]);
    }
}

public static Dictionary<int, Dictionary<string, object>> GetSelection(IFeatureLayer fLayer)
{
    // return a dictionary containing one dictionaries for each selected
    // feature where the contained dictionary is keyed by the field name
    var dict = new Dictionary<int, Dictionary<string, object>>();
    ICursor cur = null;
    try
    {
        ((IFeatureSelection)fLayer).SelectionSet.Search(null, false, out cur);
        IRow row;
        while ((row = cur.NextRow()) != null)
        {
            dict.Add(row.OID, RowToDict(row));
        }
    }
    catch
    {
        throw;
    }
    finally
    {
        if (cur != null)
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cur);
    }
    return dict;
}

public static Dictionary<string, object> RowToDict(IRow row)
{
    var dict = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
    for (int i = 0; i < row.Fields.FieldCount; i++)
    {
        var fld = row.Fields.get_Field(i);
        if (row.get_Value(i) is DBNull)
        {
            // todo: maybe special treatment of nulls here ...
        }
        if(fld.Type != esriFieldType.esriFieldTypeGeometry)
            dict.Add(fld.Name, row.get_Value(i));
    }
    return dict;
}
share|improve this answer
    
Shot Kirk! I'll give this a go. –  Andre Nov 11 '11 at 7:35

One option would be to use the report writer, create report command (ArcMap Command), see code below:

   public void ExecuteCmd2()
{

    try {
        UID pUID = new UID();
        ICommandItem pCmdItem = default(ICommandItem);
        // Use the GUID of the Save command
        pUID.Value = "{CDC6F22A-7DD1-490F-8FDE-4357C621BBDF}";
        // or you can use the ProgID
        // pUID.Value = "ESRI.ArcGIS.ReportWriter.CreateReportCommand"
        pUID.SubType = 3;
        pCmdItem = m_App.Document.CommandBars.Find(pUID);
        pCmdItem.Execute();
    } catch (Exception ex) {
        MessageBox.Show("Caught an unspecified error in the calling code: " + System.Environment.NewLine + ex.ToString());
    }

}

There is an option within one of the dialogs to narrow the report to only selected features. Also, in ArcGIS 10.1 it looks like ESRI may have some reporting functions in python.

http://forums.arcgis.com/threads/42876-Creating-Report-with-Python-in-ArcGIS-10

share|improve this answer
    
What does Constants.vbCrLf call? –  Nathanus Nov 10 '11 at 19:17
    
@Nathanus, Thanks I updated "Constants.vbCrLf" to "System.Environment.NewLine". –  artwork21 Nov 10 '11 at 21:42
    
Oh, I get it, Carriage Return / Line Feed. –  Nathanus Nov 10 '11 at 22:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.