Select to view content in your preferred language

How to use a Spatial Analysis Service - FindNearest with JS api

4899
13
Jump to solution
03-04-2014 12:10 PM
deleted-user-VeZur_n9o0OZ
Deactivated User
Hello all,

I've seen similar questions to this but nothing with my specific symptoms so I've started a new thread. I'm trying to use the FindNearest Spatial Analysis Service. I have an AGOL org account, and am using a private webmap which requires me to login.

https://developers.arcgis.com/rest/analysis/api-reference/find-nearest.htm
https://developers.arcgis.com/javascript/jsapi/geoprocessor-amd.html#submitjob

Through a combination of the above resources I've put together some code to submit a job. My job fails with the following errors relating to my input params...

ERROR 000735: analysisLayer: Value is required arcgis.js:62 ERROR 000735: nearLayer: Value is required arcgis.js:62 Failed. 


What am I doing wrong?

 var gp = new Geoprocessor("http://analysis.arcgis.com/arcgis/rest/services/tasks/GPServer/FindNearest");             var _params = {                 "analysisLayer": {                     "url": "https://services1.arcgis.com/fcrLbZIfZI20fNqr/arcgis/rest/services/rig_subset_4326/FeatureServer/0"                     //"url": "http://10.4.164.20:6080/arcgis/rest/services/RigPlanner/RigPlanner_server/MapServer/0"                     //"filter" : "filter"                 },                 "NearLayer": {                     "layerDefinition": {                         "geometryType": "esriGeometryPoint",                         "fields": [                             {                                 "name": "Id",                                 "type": "esriFieldTypeOID",                                 "alias": "Id"                             }                         ]},                     "featureSet": {                         "geometryType": "esriGeometryPoint",                         "spatialReference": {                             "wkid": 4326                         },                         "features": [                             {                                 "geometry": {                                     "x": -94.00,                                     "y": 28.00                                 },                                 "attributes": {                                     "Id": 1                                 }                             }                         ]}                 },                 "maxCount": 10,                 "measurementType": "StraightLine",                 //"searchCutoff": 44,                 //"searchCutoffUnits": "Kilometers"                 "f": "json"             }             gp.submitJob(_params, completeCallback, statusCallback, errorCallback);


Also, how would I get the required authentication if I make my webmap and feature service public? Portal class?


Thanks,
James
0 Kudos
1 Solution

Accepted Solutions
derekswingley1
Deactivated User
We might have a problem with how we're serializing your parameters. Try using JSON.stringify to convert your values for analysisLayer and nearLayer to strings. Something like:

var _params = {   "analysisLayer": JSON.stringify({     "layerDefinition": {       "geometryType": "esriGeometryPoint",       "fields": [{         "name": "Id",         "type": "esriFieldTypeOID",         "alias": "Id"       }]     },     "featureSet": {       "geometryType": "esriGeometryPoint",       "spatialReference": {         "wkid": 4326       },       "features": [{         "geometry": {           "x": -95.00,           "y": 28.00         },         "attributes": {           "Id": 1         }       }]     }   }),   "nearLayer": JSON.stringify({     "layerDefinition": {       "geometryType": "esriGeometryPoint",       "fields": [{         "name": "Id",         "type": "esriFieldTypeOID",         "alias": "Id"       }]     },     "featureSet": {       "geometryType": "esriGeometryPoint",       "spatialReference": {         "wkid": 4326       },       "features": [{         "geometry": {           "x": -94.00,           "y": 28.00         },         "attributes": {           "Id": 1         }       }]     }   }),   "maxCount": 10,   "measurementType": "StraightLine",   //"searchCutoff": 44,   //"searchCutoffUnits": "Kilometers"   "f": "json" }

View solution in original post

0 Kudos
13 Replies
Nicholas-Furness
Esri Regular Contributor
Hey James.

Apologies for the previous answer. I skim read your question and missed that you were using the Spatial Analysis Service 😮

I haven't actually used the Geoprocessor task with the Analysis GP Service at analysis.arcgis.com. It seems to be a wrapper around the Network Analyst task found at route.arcgis.com to allow the request to be queued in the GP Tasks queue that's part of AGOL Analysis (and seems to parameterize some things that get built into lower-level parameters to the underlying NA service).

You will need to populate the "serviceToken" property on "analysisLayer". Also, it should probably be "nearLayer" and not "NearLayer".

Failing that, the approach I've taken in the past is to hit the Closest Facility Task directly at http://route.arcgis.com/arcgis/rest/services/World/ClosestFacility/NAServer/ClosestFacility_World/

In that case, your analysis layer URL needs to be a full query, not just the service end point and to include a token if the service is private.

For example, this works in the sample I posted up at https://github.com/nixta/PhillyParksDemo:

http://services.arcgis.com/OfH668nDRN7tbJh0/arcgis/rest/services/Markets%20close%20to%20parks/FeatureServer/0/query?where=1%3D1&returnGeometry=true&outFields=OBJECTID&outSR=102100&f=json

See also the documentation here under the "facilities" required parameter - there's an example URL right at the end:

{
    "url": "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Network/USA/MapServer/1/query?where=1%3D1&outFields=Name,RouteName&f=json"
}


Hope this helps. And sorry again!

Nick.
0 Kudos
deleted-user-VeZur_n9o0OZ
Deactivated User
Thanks Nick,

I wanted to take the token stuff out of the equation so I just supplied the params object with 2 featureCollections each with one point for analysisLayer and nearLayer. I still recieve the same messages from the completeCallBack saying my params are both missing.

ERROR 000735: analysisLayer: Value is required arcgis.js:62
ERROR 000735: nearLayer: Value is required arcgis.js:62
Failed.

I wonder whats up with the JSON _params object I'm supplying. I think it's exactly as described in the documentation
https://developers.arcgis.com/rest/analysis/api-reference/find-nearest.htm

Maybe I shouldn't be using the Geoprocessor at all.


 var gp = new Geoprocessor("http://analysis.arcgis.com/arcgis/rest/services/tasks/GPServer/FindNearest");
            var _params = {
                "analysisLayer": {
                    "layerDefinition": {
                        "geometryType": "esriGeometryPoint",
                        "fields": [
                            {
                                "name": "Id",
                                "type": "esriFieldTypeOID",
                                "alias": "Id"
                            }
                        ]},
                    "featureSet": {
                        "geometryType": "esriGeometryPoint",
                        "spatialReference": {
                            "wkid": 4326
                        },
                        "features": [
                            {
                                "geometry": {
                                    "x": -95.00,
                                    "y": 28.00
                                },
                                "attributes": {
                                    "Id": 1
                                }
                            }
                        ]}
                },
//                {
//                    "url": "https://services1.arcgis.com/fcrLbZIfZI20fNqr/arcgis/rest/services/rig_subset_4326/FeatureServer/0"
//                    //"filter" : "filter"
//                },
                "nearLayer": {
                    "layerDefinition": {
                        "geometryType": "esriGeometryPoint",
                        "fields": [
                            {
                                "name": "Id",
                                "type": "esriFieldTypeOID",
                                "alias": "Id"
                            }
                        ]},
                    "featureSet": {
                        "geometryType": "esriGeometryPoint",
                        "spatialReference": {
                            "wkid": 4326
                        },
                        "features": [
                            {
                                "geometry": {
                                    "x": -94.00,
                                    "y": 28.00
                                },
                                "attributes": {
                                    "Id": 1
                                }
                            }
                        ]}
                },
                "maxCount": 10,
                "measurementType": "StraightLine",
                //"searchCutoff": 44,
                //"searchCutoffUnits": "Kilometers"
                "f": "json"
            }
            gp.submitJob(_params, completeCallback, statusCallback, errorCallback);
0 Kudos
derekswingley1
Deactivated User
We might have a problem with how we're serializing your parameters. Try using JSON.stringify to convert your values for analysisLayer and nearLayer to strings. Something like:

var _params = {   "analysisLayer": JSON.stringify({     "layerDefinition": {       "geometryType": "esriGeometryPoint",       "fields": [{         "name": "Id",         "type": "esriFieldTypeOID",         "alias": "Id"       }]     },     "featureSet": {       "geometryType": "esriGeometryPoint",       "spatialReference": {         "wkid": 4326       },       "features": [{         "geometry": {           "x": -95.00,           "y": 28.00         },         "attributes": {           "Id": 1         }       }]     }   }),   "nearLayer": JSON.stringify({     "layerDefinition": {       "geometryType": "esriGeometryPoint",       "fields": [{         "name": "Id",         "type": "esriFieldTypeOID",         "alias": "Id"       }]     },     "featureSet": {       "geometryType": "esriGeometryPoint",       "spatialReference": {         "wkid": 4326       },       "features": [{         "geometry": {           "x": -94.00,           "y": 28.00         },         "attributes": {           "Id": 1         }       }]     }   }),   "maxCount": 10,   "measurementType": "StraightLine",   //"searchCutoff": 44,   //"searchCutoffUnits": "Kilometers"   "f": "json" }
0 Kudos
deleted-user-VeZur_n9o0OZ
Deactivated User
Thanks Derek - Success! My GP process now succeeds if I JSON.Stringify() my params

The next hurdle was accessing the results. I was having some difficulty with my tokens. Unless I give my esriRequest the content object with the token, I'm unable to access the results. Even though the same token parameter is appended by default. Both tokens are the same. Anyhow - it works with the below code

            gp.submitJob(_params, completeCallback, statusCallback, errorCallback);
        });
        function completeCallback(jobInfo) {
            var url = "http://analysis.arcgis.com/arcgis/rest/services/tasks/GPServer/FindNearest/jobs/" + jobInfo.jobId + "/results/nearestLayer";
            var token = esri.id.credentials[1].token;
            console.log(token);
            var nearRigs = esriRequest({
                url: url,
                //will be unable to access results if left out:
                content: { f: "json", token: token}
            }, {
                disableIdentityLookup: true
            });
            nearRigs.then(function (data) {
                console.log("Data: ", data); // print the data to browser's console
            }, function (error) {
                console.log("Error: ", error.message);
            });
        }
0 Kudos
derekswingley1
Deactivated User
That's good news! Thanks for following up.

What do you mean by "Even though the same token parameter is appended by default"?
0 Kudos
deleted-user-VeZur_n9o0OZ
Deactivated User
I mean the ?token=.... param is added to the url regardless of whether I include the following line or not:
content: { f: "json", token: token}


I've just realised that I can leave out the content obj if i include the f=json param in the url

        function completeCallback(jobInfo) {
            var url = "http://analysis.arcgis.com/arcgis/rest/services/tasks/GPServer/FindNearest/jobs/" + jobInfo.jobId + "/results/nearestLayer?f=json";
            var token = esri.id.credentials[1].token;
            console.log(token);
            var nearRigs = esriRequest({
                url: url
                //content: { f: "json", token: token}
            });
            nearRigs.then(function (data) {
                console.log("Data: ", data); // print the data to browser's console
            }, function (error) {
                console.log("Error: ", error.message);
            });
        }
0 Kudos
GaneshSolai_Sambandam
Regular Contributor
Hi James
Could please post your sample codes in JS fiddle for the find nearest functionality?

At the moment, I can't find any sample codes in the ESRI javascript api for find nearest features.

https://developers.arcgis.com/rest/a...nd-nearest.htm

Do we need to have  an AGOL account to use this service? or is this any free developer account to this service.

At the moment, I am developing my own geoprocessing service using model builder to create my own custom service to integrate into my application.



http://forums.arcgis.com/threads/103522-NearAnalysis-Geoprocessing-Service-arcgis-javascript-api

Please read above thread,

I will post some model builder sample later this week.

thanks
ganesh
0 Kudos
deleted-user-VeZur_n9o0OZ
Deactivated User
Ganesh,

Sure: http://jsfiddle.net/geo_james/uDX9a/1/

A free developer AGOL account works fine. I was considering my own GP model if I couldn't get this to work but we eventually cracked it. Thanks to Derek.

Cheers,
James
0 Kudos
GaneshSolai_Sambandam
Regular Contributor
Hi James
Thank you very much for your code. Can you provide some working sample code, at the moment, I can't see how it works. If you can provide this, that would be really good.

One more thing, I have built my Geoprocessing model to find nearest feature from the input location in model builder and published them  as a geoprocessing service. The model works perfectly well in ARCGIS desktop.  when I published them as a geoprocessing service, and tested the service with REST end points in arcgis server using submit Job Operation, I got the following error. Basically, the error reports that NearFeature layers doesn't exist, but in reality it does exist in the map and it has hard coded and the  second issue is the output datasets -from the geoprocessing service reports that the data already exist. Actually, I have checked the Overwrite Outputs of geoprocessing operations in  Arccatalog and ArcMap before building the model.

The model overwrites output datasets and finds all near feature layers when it is run from Arcmap. However, when it is run from REST end points, it causes errors saying data already exist or not found.

Have anyone come across this issue when publishing them as a geoprocessing service. Anyhelp would be much appreciated.




Job Details: Model
Check Job Details:   
Return Messages:   True    False 
 

View In:   Google Earth

Job ID: j4b4f0182872145a093f614736caf1486

Job Status: esriJobFailed

Job Messages:


esriJobMessageTypeInformative: Submitted.
esriJobMessageTypeInformative: Executing...
esriJobMessageTypeInformative:
esriJobMessageTypeWarning: WARNING 000725: KCC_InputFeature_GenerateNea8: Dataset C:\arcgisserver\python\FindFeatures2\Features.gdb\KCC_InputFeature_GenerateNea8 already exists.
esriJobMessageTypeError: The value does not exist. The value does not exist. The value does not exist. ERROR 000732: Near Features: Dataset GuidedWalks;KCC_PROMOTED_ROUTEZ_2;KCC_COUNTRYPARKZ does not exist or is not supported ERROR 000732: Join Features: Dataset KCC_COUNTRYPARKZ does not exist or is not supported ERROR 000732: Join Features: Dataset KCC_PROMOTED_ROUTEZ_2 does not exist or is not supported ERROR 000732: Join Features: Dataset GuidedWalks does not exist or is not supported WARNING 000725: Output Dataset: Dataset C:\arcgisserver\python\FindFeatures2\Features.gdb\KCC_InputFeature_GenerateNea8 already exists.
esriJobMessageTypeError: Failed.


Regards
Ganesh


Ganesh,

Sure: http://jsfiddle.net/geo_james/uDX9a/1/

A free developer AGOL account works fine. I was considering my own GP model if I couldn't get this to work but we eventually cracked it. Thanks to Derek.

Cheers,
James
0 Kudos