1

I try to create a (point)-feature in an existing Layer via ArcGIS Automation.

I can create the Feature but when I call feature.Store() I get an

HRESULT: 0x80010105 (RPC_E_SERVERFAULT)

error.

If I just edit an existing feature that I got from a SearchCursor it works flawlessly.

My application is a WinForms .Net 4.5 programm.

I get a connection to a running ArcMap Instance via IAppRot->IAppRef->IApplication->IDocument.

From the IDocument I get a reference to a specific Layer where I need to add a feature. After that it is very basic stuff:

IFeatureClass featureClass = ((IFeatureLayer)i_Layer).FeatureClass;
IFeature newObject = featureClass.CreateFeature();
// Assign a geometry to the feature 
newObject.Shape = geom;
newObject.Store();

Store allways fails with the RPC_E_SERVERFAULT Exception.

I also tried to create the feature via IFeatureCursor->IFeatureBuffer but then it fails with the same error on

featureCursor.InsertFeature(featureBuffer);

Starting an Edit-Session for this operation has no effect. It just fails later when calling

workspaceEdit.StopEditing(true); 

I tried with ArcGIS 10.5 and 10.3 but the results are the same.

Other automation tasks like moving the map, setting layer-visibilities or even editing existing features work perfectly.

I read the introduction on ArcGIS automation in the documentation and learned about application's process space and "IObjectFactory".

Do I have to use that somehow to create the new Feature?

How can I do that?

Or is there something else that I am doing wrong?

EDIT:

As requested: The table definition doesn't seem to make a difference. I tried with featureclasses that have multiple fields and assigned values to the fields via

newObject.Value[index] = somevalue;

But now my tests use a featureclass that has only the fields "objectid" and "shape". The results are allways the same.

EDIT 2:

As requested: The geometry is created like this:

IGeometry geom = new PointClass();
((IPoint)geom).X = x;
((IPoint)geom).Y = y;

The x and y values are guaranteed to be within the featureclass bounds.

The featureclass is in an file-geodatabase. Z and M values are not activated for the featureclass.

  • It may be an issue with you using .Net 4.5, especially if you are developing for ArcMap 10.3 have a look at the system requirements here. – Hornbydd Mar 7 '18 at 10:28
  • I used 10.3 only to verify that it isn't a bug in 10.5. Development is on ArcGIS 10.5.1 with VS2015 and c# .Net4.5. According to the system requirements that is ok for 10.5. – steloe Mar 7 '18 at 10:33
  • Your code sample is fragmentary. It's extremely rare that a feature class would be lacking any attributes at all. Please Edit the question to clarify the table definition. – Vince Mar 7 '18 at 11:34
  • 2
    Are you sure the geometry is valid? It may be worth trying to assign the geometry using the Shape of an already existing feature on the feature class. The RPC_E_SERVERFAULT error is about as useful as E_FAIL in my experience. – danielm Mar 7 '18 at 18:11
  • 1
    There's nothing I can see wrong with your code, but don't relax just yet, what feature storage are you using? Is this SDE data or one of the geodatabase types? @danielm might be close, if your geometry is invalid SDE will spit it out - and return some sort of vague error message.. other possibilities include failing to set the spatial reference (properly!), not assigning Z or M values where they're expected and not making Z aware (or M aware) using IZaware (IMaware) or assigning the wrong geometry type... I would need to see more about how you're creating geom before setting newObject.Shape – Michael Stimson Mar 8 '18 at 6:13
1

I thought that was the likely culprit.

I would create a new point, set the X and Y with PutCoords and the spatial reference from the feature class as IGeoDataset:

IPoint newPoint = new PointClass(); // a new IPoint 
newPoint.PutCoords(X,Y);            // set the X and Y at the same time
// set the correct spatial reference from your feature class
newPoint.SpatialReference = (featureClass as IGeoDataset).SpatialReference;
newObject.Shape = (IGeometry)newPoint;

Your method using IObjectFactory I have not seen previously; I know that the method shown in the code block works, for both IFeature.Store and IFeatureCursor.InsertFeature, in edit or not. The differences between these methods is subtle, Storing is slower than Inserting at runtime but you should create a new geometry object for each call to store conversely if you're using an insert cursor you can recycle the same geometry object for multiple insert calls.

When considering to be editing or not, I would check the EditState of IEditor, if it is esriEditState.esriStateEditing then call StartOperation and StopOperation to allow an undo and fit in with the current operational state; interestingly, if you are editing and do not call Start/Stop operation and subsequently close the MXD without performing other edits ArcMap will not ask you if you want to save edits. If your data is in a topology or geometric network you must be editing and bracket your operation with Start/Stop operation - even if your code is running outside of ArcMap, finding out if your feature class participates in a network or topology is another challenge entirely.

  • 1
    The IObjectFactory is necessary, because my code runs in a seperate Exe that only connects to ArcGIS. When I create new Objects (new PointClass), instead of just getting references to Objects from the running ArcMap instance, the new Objects are not in the ArcMap Process space. That leads to the error. The "automating ArcGIS" documentation explains that pretty good. – steloe Mar 9 '18 at 7:38
  • That isn't something that I've delved into much, I have created standalone EXE processes using Esri objects, created by the ArcObjects template... with AoInitialize etc. and have never needed to use an IObjectFactory, you've introduced me to a new concept. Can you explain about your application environment, is this a server/client relationship? What is it about your standalone that makes its environment different to the standalone applications that I have written? Just for my own curiosity... – Michael Stimson Mar 9 '18 at 11:27
  • The program is a simple desktop exe. No server/client. I also didn't need that concept before in any program that connected with arcmap. Perhaps becaus I only used references to already existing objects in ArcMap process space. This time I explicitly created a new esri object via "IPoint point = new PointClass()" that has no reference to any existing object in the arcmap process space. As the article "automating ArcGIS" explains, this leads to the problem that the new object is created in the wrong (the one from my exe) memory space. 1/2 – steloe Mar 9 '18 at 15:52
  • 2/2 If you only create objects out of existing esri objects like this "IFeature newObject = featureClass.CreateFeature();" the new feature gets created in arcmap process space. No problem here. – steloe Mar 9 '18 at 15:54
1

The comments from danielm and michael stimson got me on the right track: the problem came from the geometry object.

I changed the geometry part to this:

((IPoint)newObject.Shape).X = x;
((IPoint)newObject.Shape).Y = y;

and now it works. I will try to reasearch what is wrong with my original approach but for now I can work with this.


I did further test on this subject. It appears I didn't fully get my lesson out of the "automating ArcGIS" article in the ArcObjects SDK documentation. The problem with creating a new IGeometry Object and assigning it to the new feature is that the new feature resides within the ArcMap process space and my new IGeometry resides in the process space of my standalone-application.

Following the documentation I now create my IGeometry via the IObjectFactory:

IObjectFactory objFactory = m_application as IObjectFactory;
//Use reflection to get ClsID of PointClass.
Type pointClassType = typeof(PointClass);
string typeClsID = pointClassType.GUID.ToString("B");

IPoint esriProcessSpacePoint = (IPoint)objFactory.Create(typeClsID);
esriProcessSpacePoint.X = x;
esriProcessSpacePoint.Y = y;

newObject.Shape = (IGeometry)esriProcessSpacePoint;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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