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 at 10.1SP1 with VS2010.

In my tool's ParameterInfo property I create an output GPParameter object of IGPParameterEdit.DataType GPLineTypeClass.

Then in the Execute() method I do work that creates an IPolyline that I want to stuff into that parameter's IGPParameter.Value property as an IGPValue.

PROBLEM 1: Using the typical

IGPValue outValue = gputils.MakeGPValueFromObject(myIPolyline) 

using the GPUtilities class's IGPUtilities interface causes an E_FAIL COM error. huh. How does one debug that? Well, try another way -

So I tried this instead:

IGPLine2 outValue = new GPLineClass();
outValue.Polyline = myIPolyline;
gpUtils.PackGPValue((IGPValue)outValue, outputParam);

PROBLEM 2: But I get an invalid cast exception on that first line:

System.InvalidCastException: Unable to cast COM object of type 'ESRI.ArcGIS.Geoprocessing.GPLineClass' to interface type 'ESRI.ArcGIS.Geoprocessing.IGPLine2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{1248339D-7B76-4A43-8FE0-752B1BF9D39A}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))

GPLineClass cannot be cast to IGPLine2. What! Documentation says this class implements this interface. I CAN cast it to IGPLine, but that interface is ridiculous - I'd have to disassemble the IPolyline and assign each vertex, and it won't work for multipart geometries.

SO - what is the secret sauce to stuff an IPolyline into an output parameter's value? And what the heck is up with that IGPLine2 thing?

Thanks!

share|improve this question
    
My suggestion would be to not output a polyline at all. You should output a polyline featureclass with one feature containing your polyline. –  Devdatta Tengshe Mar 12 '13 at 6:26
    
That is weird, if GPLine did not implement IGPLine2, then the line IGPLine2 outValue = new GPLineClass(); would not compile at all.. –  Petr Krebs Mar 12 '13 at 11:34
    
Are you targeting .Net framework 3.5? –  Jakub Mar 12 '13 at 14:23
    
thanks very much for feedback, all. yes, .NET 3.5, as I believe is the norm for 10.1? and I agree it is weird. it compiles, runs, and fails. some googling indicates others have problems like this on various interfaces too. Since yesterday I happended to encounter it on IGPPoint2/GPPointClass. Finally, I'm not so sure about the featureclass suggestion, the intent is to simply draw the result as a temporary graphic. –  MC5 Mar 12 '13 at 15:57

1 Answer 1

up vote 1 down vote accepted

If it weren't for that apparent bug casting a GPLine to IGPLine2, I would just return the polyline geometry in a GPLine output parameter.

Whatever. There is thankfully newish stuff in ArcObjects and the Silverlight API (3.1) for serializing to and deserializing from JSON (which of course the GP framework would have done under the hood anyway if I had been able to use a GPLine output parameter). It is a little inconvenient if you wanted to use it from a Desktop client, a minor thing in my case.

in the GP Tool, at the end of the Execute() method, serialize the geometry to JSON and assign it to the output parameter:

string traceresultjson = JsonSerializeGeometry(traceresult as IGeometry);
IGPString outValue = new GPStringClass();
outValue.Value = traceresultjson;
_gpUtilities.PackGPValue((IGPValue)outValue, resultParam);

Where _gpUtilities is an IGPUtilities instance of GPUtilitiesClass, and resultParam is the tool's output GPString IGPParameter set up in the tool's ParameterInfo property, and my JsonSerializeGeometry() method looks like:

protected string JsonSerializeGeometry(IGeometry geom)
{
    //see http://nicogis.blogspot.com/2012/04/json-arcobjects.html
    string json = "";
    IJSONWriter jsonWriter = new JSONWriterClass();
    jsonWriter.WriteToString();
    IJSONSerializer jsonSerializer = new JSONSerializerGdbClass();
    jsonSerializer.InitSerializer(jsonWriter, null);
    ((IExternalSerializerGdb)jsonSerializer).WriteGeometry(null, geom);
    json = Encoding.UTF8.GetString(jsonWriter.GetStringBuffer());
    Marshal.FinalReleaseComObject(jsonSerializer);
    jsonSerializer = null;
    Marshal.FinalReleaseComObject(jsonWriter);
    jsonWriter = null;

    return json;
}

In the Silverlight app consuming the service using the Geoprocessor class, deserialize the result in the Geoprocessor's ExecuteCompleted event handler:

string json = ((GPString)e.Results.OutParameters[0]).Value;
Geometry geom = Geometry.FromJson(json);
Graphic g = new Graphic() { Geometry = geom };
share|improve this answer
    
+1 Nice example of using jsonserializer. –  Kirk Kuykendall Apr 11 '13 at 22:10

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.