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'm working on code to open a 3rd party data file and convert it into a collection of features in a custom layer based on FeatureLayer. I have had no issue importing the data itself (nodal data for each 'cell' as a feature, such as elevation).

Because the data files are on average rather large (10k+ cells), I'm using a cursor implementation with an IFeatureBuffer that is filled with each cell one at a time. However, when I try to set the geometry of the cell via IFeatureBuffer like so,

IGeometry cellGeometry = getCellGeometry(cell);

featureBuffer.Shape = cellGeometry;

I subsequently get the error "Item not found in this collection" called on the second line. My first thought was that I was creating the cell geometry incorrectly in some way, so I tested it by creating a simple point as the geometry. This failed with the same error. I next thought it might be an issue with ZAware. I tried setting it to both ((IZAware)cellGeometry).ZAware = true; and ((IZAware)cellGeometry).ZAware = false; with the same issue both times.

I'm thinking it might have to do with how the fields in the FeatureClass were setup, but I'm quite stuck at the moment.

UPDATE:

I've tried updating how the fields are created to fix any issues that may exist therein, and the issue remains. The fields are generated like so,

    {
        if (this.ImportedField == null)
        {
            return null;
        }

        IObjectClassDescription fcDesc;
        if (this.DatasetType == esriDatasetType.esriDTTable)
            fcDesc = new ObjectClassDescriptionClass();
        else
            fcDesc = new FeatureClassDescriptionClass();

        IFields fields = fcDesc.RequiredFields;
        IFieldsEdit fieldsEdit = (IFieldsEdit)fields;

        //Setup shape field
        IField shapeField = fields.Field[fields.FindField("Shape")];
        IFieldEdit shapeFieldEdit = (IFieldEdit)shapeField;
        shapeFieldEdit.Name_2 = "SHAPE";
        shapeFieldEdit.AliasName_2 = "SHAPE";
        shapeFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
        shapeFieldEdit.Length_2 = 0;
        shapeFieldEdit.Precision_2 = 0;
        shapeFieldEdit.Scale_2 = 0;
        shapeFieldEdit.IsNullable_2 = true;
        shapeFieldEdit.Required_2 = true;
        shapeFieldEdit.Editable_2 = true;
        shapeFieldEdit.Domain_2 = null;
        shapeFieldEdit.DomainFixed_2 = true;
        shapeFieldEdit.GeometryDef_2 = BuildGeometryDefinition(BuildGenericSpatialReference(true), esriGeometryType.esriGeometryPolygon, true, false);

        var fieldNames = this.ImportedField.CoordinateData.ScalarData.Select(nodeData => nodeData.Name).ToList();
        fieldNames.AddRange(this.ImportedField.CellData.ScalarData.Select(cellData => cellData.Name));

        //Add fields from ImportedField
        foreach (var fieldName in fieldNames)
        {
            IFieldEdit fieldEdit = new FieldClass();
            fieldEdit.Length_2 = 1;
            fieldEdit.Name_2 = fieldName;
            fieldEdit.Type_2 = esriFieldType.esriFieldTypeSingle;
            fieldsEdit.AddField(fieldEdit);
        }

        return fields as IFields;
    }
share|improve this question
    
FYI, This issue isn't related to my implementation of a custom layer. In test cases where I simply add the FeatureClass to a generic FeatureLayer, the same thing occurs. –  DBaker Sep 1 '10 at 18:14
    
Are you able to interactively edit the featureclass using arcmap? –  Kirk Kuykendall Sep 2 '10 at 18:14
    
Yes, I can Add/Delete fields from the FeatureClass in ArcMap and ArcScene without any issue. –  DBaker Sep 2 '10 at 23:29
add comment

2 Answers 2

up vote 0 down vote accepted

Finally found the solution. For whatever reason, the Shape field must be set before any of the other fields.

This DOES NOT WORK:

IGeometry cellGeometry = getCellGeometry(cell);

featureBuffer.Shape = cellGeometry;

But for some reason this DOES:

*featureBuffer.Shape = cellGeometry;

IGeometry cellGeometry = getCellGeometry(cell);*

share|improve this answer
    
This really shouldn't be required, so I added a bug tag to your question. –  Kirk Kuykendall Sep 7 '10 at 2:02
add comment

When setting up geometric fields for feature classes, you have to define the entire IGeometryDef for it, and be sure that it is correct.

EDIT: I'm not sure if this is the exact problem, but here's a taste how I build fields.

My guess is that you are trying to access the geometry field whereas it doesn't fully exists.

This code I use works:

    public static IField2 BuildGeometryField(ISpatialReference spatialReference,esriGeometryType geometryType,bool hasZ, bool hasM)
    {
        IGeometryDef geometryDefinition = GeometryDefinitionBuilder.BuildGeometryDefinition(spatialReference,
            geometryType,hasZ,hasM);

        IField2 field = BuildField("SHAPE","SHAPE",esriFieldType.esriFieldTypeGeometry,0,0,0,false,true,null,false,geometryDefinition);

        return field;
    }

  public static IField2 BuildField(string fieldName, string fieldAlias, esriFieldType fieldType, int fieldLength, int fieldPrecision, int fieldScale,
        bool isNullable, bool isRequired, IDomain fieldDomain, bool isDomainFixed, IGeometryDef geometryDefinition)
    {
        if (String.IsNullOrEmpty(fieldName))
            throw new ArgumentException(GeometryMessages.FieldNameNullOrEmpty);

        if (String.IsNullOrEmpty(fieldAlias))
            fieldAlias = fieldName;

        if (fieldType == esriFieldType.esriFieldTypeString)
        {
            fieldScale = 0;
            fieldPrecision = 0;
        }

        IField2 field = new FieldClass();
        IFieldEdit2 fieldEdit = field as IFieldEdit2;

        fieldEdit.Name_2 = fieldName;
        fieldEdit.AliasName_2 = fieldAlias;
        fieldEdit.Type_2 = fieldType;
        fieldEdit.Length_2 = fieldLength;

        fieldEdit.Precision_2 = fieldPrecision;
        fieldEdit.Scale_2 = fieldScale;

        fieldEdit.IsNullable_2 = isNullable;
        fieldEdit.Required_2 = isRequired;

        fieldEdit.Editable_2 = true;

        if (fieldDomain != null)
        {
            fieldEdit.Domain_2 = fieldDomain;
            fieldEdit.DomainFixed_2 = isDomainFixed;
        }

        if (geometryDefinition != null)
            fieldEdit.GeometryDef_2 = geometryDefinition;

        return field;
    }
share|improve this answer
    
I do essentially this, but I do it via editing (I generate the fields using RequiredField). Could that be the issue? –  DBaker Sep 2 '10 at 23:37
add comment

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.