2

We have a geoprocessing service that has been in limbo for 6 months. Finally after a great decision to eliminate one element of the service, we got it working this week. I am now at the point where I can 'kill' the service call by just passing the polygons like a light bulb turned on and off. So it seems this is focused now on how I pass the polygon to the service. I've looked at it until I'm blue in the face and cannot see anything wrong with it. The symptoms are as follows:

  The server service receives the call.  It gets the bulk data just fine.
  The server service locates the class to call and creates an instance.
  Parameter info is called and it starts to process the parameters for calling Execute
  It returns Fail.

I figured all of that out by putting the server logging in Debug mode. So now the bombardment of code. This takes the origin point, targets, and blockages (the polygons) and preps them for calling the service.

Point origin = (Point)GeometryOperations.Project(Point.CreateFromLatitudeLongitude(Convert.ToDouble(SelectedStation["lat"]), Convert.ToDouble(SelectedStation["long"])), ESRI.ArcGISExplorer.Geometry.CoordinateSystem.ProjectedCoordinateSystems.World.WGS1984WebMercatorAuxiliarySphere);
List<Point> targets = chosen.Select(location => (Point)GeometryOperations.Project(Point.CreateFromLatitudeLongitude(location.Latitude, location.Longitude), ESRI.ArcGISExplorer.Geometry.CoordinateSystem.ProjectedCoordinateSystems.World.WGS1984WebMercatorAuxiliarySphere)).ToList();
BlockagesAndDelays bandd = Functions.GetBlockagesAndDelays();
List<Polygon> blockages = new List<Polygon>();
foreach (Polygon item in bandd.Blockages)
{
    blockages.Add((Polygon)GeometryOperations.Project(item, ESRI.ArcGISExplorer.Geometry.CoordinateSystem.ProjectedCoordinateSystems.World.WGS1984WebMercatorAuxiliarySphere));
}

helper.UpdateMessage("Calling service");
double[] results = Geoprocessing.GetLaunchPointDistanceToTargets(helper, origin, targets.ToArray(), blockages.ToArray());

The method called now converts the raw data into the format to send to the server and makes the call. Here is where I may be screwing up somehow.

using (CalculateDistances_GPServer service = new CalculateDistances_GPServer())
{
try
{
    List<double> results = new List<double>();
    progressDialog.UpdateMessage("Establishing parameters");

    service.Url = Functions.GetGPServiceEndpoint("CalculateDistances");
    CalculateDistances.GPToolInfo toolinfo = service.GetToolInfo("Calculate Distances");
    CalculateDistances.GPParameterInfo[] parameters = toolinfo.ParameterInfo;
    CalculateDistances.GPFeatureRecordSetLayer firstParameterLayer =
        (CalculateDistances.GPFeatureRecordSetLayer) parameters[0].Value;
    CalculateDistances.GPFeatureRecordSetLayer secondParameterLayer =
        (CalculateDistances.GPFeatureRecordSetLayer) parameters[1].Value;
    CalculateDistances.GPFeatureRecordSetLayer thirdParameterLayer =
        (CalculateDistances.GPFeatureRecordSetLayer)parameters[2].Value;

    CalculateDistances.PointN newPoint =
        SoapConverter.GeometryToSoap<Point, CalculateDistances.PointN>(launchPoint);
    CalculateDistances.Record[] firstParameter = new CalculateDistances.Record[1];
    object[] recordValues = new object[2];
    recordValues[0] = 1;                // OBJECTID
    recordValues[1] = newPoint;         // SHAPE
    firstParameter[0] = new CalculateDistances.Record {Values = recordValues};
    firstParameterLayer.RecordSet.Records = firstParameter;

    CalculateDistances.Record[] secondParameter = new CalculateDistances.Record[targets.Length];
    for (int index = 0; index < targets.Length; index++)
    {
        CalculateDistances.PointN targetPoint =
            SoapConverter.GeometryToSoap<Point, CalculateDistances.PointN>(targets[index]);
        recordValues = new object[2];
        recordValues[0] = index+1;        // OBJECTID
        recordValues[1] = targetPoint;    // SHAPE
        secondParameter[index] = new CalculateDistances.Record {Values = recordValues};
    }
    secondParameterLayer.RecordSet.Records = secondParameter;

    CalculateDistances.Record[] thirdParameter = new CalculateDistances.Record[blockages.Length];
    for (int index = 0; index < blockages.Length; index++)
    {
        recordValues = new object[2];
        CalculateDistances.PolygonN blockageArea =
            SoapConverter.GeometryToSoap<ESRI.ArcGISExplorer.Geometry.Polygon, CalculateDistances.PolygonN>(blockages[index]);
        recordValues[0] = index + 1;        // OBJECTID
        recordValues[1] = blockageArea;     // SHAPE
        thirdParameter[index] = new CalculateDistances.Record { Values = recordValues };
    }
    thirdParameterLayer.RecordSet.Records = thirdParameter;

    CalculateDistances.GPValue[] values = {firstParameterLayer, secondParameterLayer, thirdParameterLayer};
    progressDialog.UpdateMessage("Calling service");
    string jobId = service.SubmitJob(toolinfo.Name, values, null, null);
    CalculateDistances.esriJobStatus jobStatus = service.GetJobStatus(jobId);

Can anyone see what is messed up?

1

The parameter for passing a polygon needs two other ESRI fields populated in the parameter list. If the fields are not present (even if they have no meaningful value) then the ESRI service will return a FAIL result without any logs or exceptions.

for (int fieldIndex = 0; fieldIndex < fieldArray.FieldArray.Count(); fieldIndex++)
{
    if (fieldArray.FieldArray[fieldIndex].Name == "OBJECTID")
    recordValues[fieldIndex] = index + 1;
else if (fieldArray.FieldArray[fieldIndex].Name == "SHAPE")
    recordValues[fieldIndex] = blockageArea;
else if (fieldArray.FieldArray[fieldIndex].Name == "SHAPE_Area")  // additional field needed
    recordValues[fieldIndex] = 0.0;
else if (fieldArray.FieldArray[fieldIndex].Name == "SHAPE_Length")  // additional field needed
    recordValues[fieldIndex] = 0.0;
}

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.