Greetings everyone,
I'm trying to execute a Closest Facility Task using the ArcGIS location service in the following link
https://route-api.arcgis.com/arcgis/rest/services/World/ClosestFacility/NAServer/ClosestFacility_World
I've run the following code to query the features used as facilities
private void queryAvailableWaterPoints() {
if (hasGeodatabaseLoad) {
for (Layer layer : mMapView.getMap().getOperationalLayers()) {
if (layer.getName().equals("Pontos_de_Água")) {
// queryAvailableWaterPoints is already working
FeatureLayer featureLayer = (FeatureLayer) layer;
FeatureTable featureTable = featureLayer.getFeatureTable();
featureTable.loadAsync();
featureTable.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
QueryParameters query = new QueryParameters();
query.setWhereClause("Capacidade > 500 AND Tipo LIKE 'Autotanque'");
query.setMaxFeatures(0);
final ListenableFuture<FeatureQueryResult> queryFeaturesAsync = featureTable.queryFeaturesAsync(query);
queryFeaturesAsync.addDoneListener(() -> {
try {
FeatureQueryResult result = queryFeaturesAsync.get();
Iterator<Feature> resultIterator = result.iterator();
int numFeatures = 0;
ArrayList<Facility> mFacilities = new ArrayList<>();
ArrayList<Incident> mIncidents = new ArrayList<>();
// Loop through the diffrent water points and add them as facilities
while (resultIterator.hasNext()) {
Feature feature = resultIterator.next();
numFeatures++;
}
// Store the water points as Facilities for the 'Find closest facility to an incident' task
mFacilities.add(new Facility((Point) feature.getGeometry()));
}
// Store the user's current location as Incident for the 'Find closest facility to an incident' task
mIncidents.add(new Incident(new Point(location.getLongitude(), location.getLatitude(), mMapView.getSpatialReference())));
// Enable the closeRoute button and disable the remaining ActionBar buttons
enableDisableRouteMode(true);
//createProgressDialog();
executeClosestFacilityTask(mFacilities, mIncidents);
Log.i("feature", String.valueOf(numFeatures));
} catch (Exception e) {
Log.i("FeatureQueryResult", "There was an error");
}
});
}
});
}
}
} else {
Toast.makeText(mContext, "Carregue a base de dados", Toast.LENGTH_SHORT).show();
}
}
After this, I stored them as Facilities and the user location as an Incident.
In the executeClosestFacilityTask method, I ran the following code
private void executeClosestFacilityTask(ArrayList<Facility> mFacilities, ArrayList<Incident> mIncidents) {
// task to find the closest route between an incident and a facility
mClosestFacilityTask = new ClosestFacilityTask(this, getString(R.string.closest_facility));
mClosestFacilityTask.loadAsync();
mClosestFacilityTask.addDoneLoadingListener(() -> {
if (mClosestFacilityTask.getLoadStatus() == LoadStatus.LOADED) {
ListenableFuture<ClosestFacilityParameters> closestFacilityParametersFuture = mClosestFacilityTask.createDefaultParametersAsync();
closestFacilityParametersFuture.addDoneListener(() -> {
try {
mClosestFacilityParameters = closestFacilityParametersFuture.get();
// set new parameters to find route
Log.i("mFacilities", String.valueOf(mFacilities.size()));
Log.i("mIncidents", String.valueOf(mIncidents.size()));
mClosestFacilityParameters.setFacilities(mFacilities);
mClosestFacilityParameters.setIncidents(mIncidents);
mClosestFacilityParameters.setReturnRoutes(true);
mClosestFacilityParameters.setOutputSpatialReference(mMapView.getSpatialReference());
// mClosestFacilityParameters.setPointBarriers(pointBarriers);
// mClosestFacilityParameters.setPolylineBarriers(polylineBarriers);
// mClosestFacilityParameters.setPolygonBarriers(polygonBarriers);
// solve closest facilities
try {
// use the task to solve for the closest facility
ListenableFuture<ClosestFacilityResult> closestFacilityTaskResult = mClosestFacilityTask
.solveClosestFacilityAsync(mClosestFacilityParameters);
closestFacilityTaskResult.addDoneListener(() -> {
try {
ClosestFacilityResult closestFacilityResult = closestFacilityTaskResult.get();
// find the closest facility for each incident
for (int i = 0; i < mIncidents.size(); i++) {
if (closestFacilityResult.getRankedFacilityIndexes(i).size() > 0) {
// get the index of the closest facility to incident
Integer closestFacilityIndex = closestFacilityResult.getRankedFacilityIndexes(i).get(0);
// get the route to the closest facility
ClosestFacilityRoute closestFacilityRoute = closestFacilityResult.getRoute(closestFacilityIndex, i);
// display the route on the graphics overlay
mRouteOverlay.getGraphics().add(new Graphic(closestFacilityRoute.getRouteGeometry()));
// Hide the ProgressDialog
hideProgressDialog();
}
}
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
} catch (Exception ex) {
String error = "Error solving the closest facility task: " + ex.getMessage();
Toast.makeText(getApplicationContext(), error, Toast.LENGTH_LONG).show();
Log.e("tag", error);
}
} catch (ExecutionException | InterruptedException e) {
String error = "Error generating parameters: " + e.getMessage();
Log.e("error", error);
}
});
} else {
String error = "Closest facility task failed to load: " + mClosestFacilityTask.getLoadError().getCause();
Log.e("error", error);
Toast.makeText(this, "Tarefa 'Calcular ponto de água mais próximo' falhou'", Toast.LENGTH_LONG).show();
}
});
}
which yield the following error
com.example.testsample2 W java.util.concurrent.ExecutionException: com.esri.arcgisruntime.io.JsonEmbeddedException: Unable to complete operation.
2022-11-23 16:36:55.686 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.concurrent.b.get(SourceFile:18)
2022-11-23 16:36:55.686 7879-7879 System.err com.example.testsample2 W at com.example.testsample2.MainActivity.lambda$executeClosestFacilityTask$0$com-example-testsample2-MainActivity(MainActivity.java:902)
2022-11-23 16:36:55.686 7879-7879 System.err com.example.testsample2 W at com.example.testsample2.MainActivity$$ExternalSyntheticLambda5.run(Unknown Source:6)
2022-11-23 16:36:55.686 7879-7879 System.err com.example.testsample2 W at android.os.Handler.handleCallback(Handler.java:938)
2022-11-23 16:36:55.687 7879-7879 System.err com.example.testsample2 W at android.os.Handler.dispatchMessage(Handler.java:99)
2022-11-23 16:36:55.687 7879-7879 System.err com.example.testsample2 W at android.os.Looper.loopOnce(Looper.java:201)
2022-11-23 16:36:55.687 7879-7879 System.err com.example.testsample2 W at android.os.Looper.loop(Looper.java:288)
2022-11-23 16:36:55.687 7879-7879 System.err com.example.testsample2 W at android.app.ActivityThread.main(ActivityThread.java:7839)
2022-11-23 16:36:55.688 7879-7879 System.err com.example.testsample2 W at java.lang.reflect.Method.invoke(Native Method)
2022-11-23 16:36:55.688 7879-7879 System.err com.example.testsample2 W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
2022-11-23 16:36:55.689 7879-7879 System.err com.example.testsample2 W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2022-11-23 16:36:55.689 7879-7879 System.err com.example.testsample2 W Caused by: com.esri.arcgisruntime.io.JsonEmbeddedException: Unable to complete operation.
2022-11-23 16:36:55.689 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException$b.a(SourceFile:43)
2022-11-23 16:36:55.690 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException$b.deserialize(SourceFile:1)
2022-11-23 16:36:55.690 7879-7879 System.err com.example.testsample2 W at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
2022-11-23 16:36:55.690 7879-7879 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:991)
2022-11-23 16:36:55.691 7879-7879 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:956)
2022-11-23 16:36:55.692 7879-7879 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:905)
2022-11-23 16:36:55.692 7879-7879 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:876)
2022-11-23 16:36:55.693 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException.fromJson(SourceFile:1)
2022-11-23 16:36:55.693 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.l.b(SourceFile:3)
2022-11-23 16:36:55.693 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.m.a(SourceFile:61)
2022-11-23 16:36:55.695 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.m.a(SourceFile:2)
2022-11-23 16:36:55.695 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c.a(SourceFile:169)
2022-11-23 16:36:55.696 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c.f(SourceFile:1)
2022-11-23 16:36:55.696 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.r.x(SourceFile:1)
2022-11-23 16:36:55.697 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.r.d(SourceFile:1)
2022-11-23 16:36:55.697 7879-7879 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c$a.call(SourceFile:1)
2022-11-23 16:36:55.697 7879-7879 System.err com.example.testsample2 W at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-11-23 16:36:55.698 7879-7879 System.err com.example.testsample2 W at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-11-23 16:36:55.699 7879-7879 System.err com.example.testsample2 W at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-11-23 16:36:55.699 7879-7879 System.err com.example.testsample2 W at java.lang.Thread.run(Thread.java:920)
I've tried to understand what is causing this bug but can't figure out.
If someone can help me into understanding what is behind this, I'll greatly thank and appreciate.
Thank you.
Cheers
HI,
This seems to be an error coming from the service itself.
Few questions:
1. What are using to authenticate the service. API Keys or Named User ?
2. Is the error happening on the `solveClosestFacilityAsync` ?
3. Does the following samples work for you ?
https://github.com/Esri/arcgis-runtime-samples-android/tree/main/java/find-closest-facility-to-an-in...
https://github.com/Esri/arcgis-runtime-samples-android/tree/main/java/find-closest-facility-to-multi...
If the samples work and your code has issues, we might need go through the Esri support and look into the request parameters being sent here for the solve operation.
Thanks
Rama
Thank you for the answer.
1. API Key
2. Yes.
3. I will try next week the official example with my API Key to see if the same error is returned or not.
I will post here if everything went smoothly or not. If yes, than the error was in the code.
Cheers
Sample might be using a different service, so don't forget to switch.
Also as per Doc, the service being used should be used for short transactions,
https://developers.arcgis.com/documentation/mapping-apis-and-services/routing/closest-facility-routi...
How many facilities and incidents do you typically use?
Thanks
Rama
So apparently I'm still getting some strange bug.
So I tried changing from the San Diego closest facility service to the generic one.
Everything worked well for the San Diego area, but as soon as I was outside San Diego, I got an error saying 'Incident not within the San Diego Area!'
I don't understand since I'm not using the San Diego closest facility service but rather the normal one.
San Diego closest facility service
<string name="san_diego_network_service_url">https://sampleserver6.arcgisonline.com/arcgis/rest/services/NetworkAnalysis/SanDiego/NAServer/ClosestFacility</string>
Generic Closest Facility location service.
<string name="closest_facility">https://route-api.arcgis.com/arcgis/rest/services/World/ClosestFacility/NAServer/ClosestFacility_World</string>
I changed from
mClosestFacilityTask = new ClosestFacilityTask(this, getString(R.string.san_diego_network_service_url));
To this
mClosestFacilityTask = new ClosestFacilityTask(this, getString(R.string.closest_facility));
Thus, for some reason, I'm apparently still using the San Diego Closest Facility service because it says I'm outside San Diego. Or something else that I'm missing ..!
P.S. I used the code from this sample
Cheers
Please ignore the error.
I realized the code was written to output that SanDiego message no matter the error.
After changing to get the real cause of the error, I received this message that I previously received
2022-12-13 18:37:22.808 12829-12829 System.err com.example.testsample2 W java.util.concurrent.ExecutionException: com.esri.arcgisruntime.io.JsonEmbeddedException: Unable to complete operation.
2022-12-13 18:37:22.808 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.concurrent.b.get(SourceFile:18)
2022-12-13 18:37:22.809 12829-12829 System.err com.example.testsample2 W at com.example.testsample2.MainActivity.lambda$populateParametersAndSolveRoute$2$com-example-testsample2-MainActivity(MainActivity.java:899)
2022-12-13 18:37:22.809 12829-12829 System.err com.example.testsample2 W at com.example.testsample2.MainActivity$$ExternalSyntheticLambda13.run(Unknown Source:4)
2022-12-13 18:37:22.809 12829-12829 System.err com.example.testsample2 W at android.os.Handler.handleCallback(Handler.java:938)
2022-12-13 18:37:22.812 12829-12829 System.err com.example.testsample2 W at android.os.Handler.dispatchMessage(Handler.java:99)
2022-12-13 18:37:22.813 12829-12829 System.err com.example.testsample2 W at android.os.Looper.loopOnce(Looper.java:201)
2022-12-13 18:37:22.813 12829-12829 System.err com.example.testsample2 W at android.os.Looper.loop(Looper.java:288)
2022-12-13 18:37:22.814 12829-12829 System.err com.example.testsample2 W at android.app.ActivityThread.main(ActivityThread.java:7839)
2022-12-13 18:37:22.814 12829-12829 System.err com.example.testsample2 W at java.lang.reflect.Method.invoke(Native Method)
2022-12-13 18:37:22.814 12829-12829 System.err com.example.testsample2 W at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
2022-12-13 18:37:22.819 12829-12945 EGL_emulation com.example.testsample2 D app_time_stats: avg=99.62ms min=12.52ms max=351.34ms count=10
2022-12-13 18:37:22.823 12829-12829 System.err com.example.testsample2 W at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
2022-12-13 18:37:22.823 12829-12829 System.err com.example.testsample2 W Caused by: com.esri.arcgisruntime.io.JsonEmbeddedException: Unable to complete operation.
2022-12-13 18:37:22.823 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException$b.a(SourceFile:43)
2022-12-13 18:37:22.824 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException$b.deserialize(SourceFile:1)
2022-12-13 18:37:22.824 12829-12829 System.err com.example.testsample2 W at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
2022-12-13 18:37:22.826 12829-12829 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:991)
2022-12-13 18:37:22.826 12829-12829 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:956)
2022-12-13 18:37:22.827 12829-12829 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:905)
2022-12-13 18:37:22.827 12829-12829 System.err com.example.testsample2 W at com.google.gson.Gson.fromJson(Gson.java:876)
2022-12-13 18:37:22.828 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.io.JsonEmbeddedException.fromJson(SourceFile:1)
2022-12-13 18:37:22.829 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.l.b(SourceFile:3)
2022-12-13 18:37:22.830 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.m.a(SourceFile:61)
2022-12-13 18:37:22.830 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.m.a(SourceFile:2)
2022-12-13 18:37:22.831 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c.a(SourceFile:169)
2022-12-13 18:37:22.831 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c.f(SourceFile:1)
2022-12-13 18:37:22.831 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.r.x(SourceFile:1)
2022-12-13 18:37:22.833 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.r.d(SourceFile:1)
2022-12-13 18:37:22.833 12829-12829 System.err com.example.testsample2 W at com.esri.arcgisruntime.internal.io.handler.request.c$a.call(SourceFile:1)
2022-12-13 18:37:22.840 12829-12829 System.err com.example.testsample2 W at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-12-13 18:37:22.842 12829-12829 System.err com.example.testsample2 W at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2022-12-13 18:37:22.842 12829-12829 System.err com.example.testsample2 W at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2022-12-13 18:37:22.846 12829-12829 System.err com.example.testsample2 W at java.lang.Thread.run(Thread.java:920)
One interesting phenomenon is that by checking my ArcGIS for Developers dashboard, I can see my account is consuming the Closest Facility service thus the error could be in handling the result.
Hope I was clear and I'm sorry for the confusion
You are seeing the error 'Incident not within the San Diego Area!' , because you are still getting the unable to complete operation from the service and hence the toast message hardcoded in the sample,
I just tried switching the sample to use generic Closest Facility location service and that seemed to work fine with the sample for me using my API Key
<string name="closest_facility">https://route-api.arcgis.com/arcgis/rest/services/World/ClosestFacility/NAServer/ClosestFacility_World</string>
If your api key doesn't have scope to perform closestfacility task, it should have failed even to load the closesfacilitytask. But looks like you were able to load the task but unable to solve closest facility operation.
Do you use Charles or fiddler to track network traffic? If so you can see the http request parameters thats causing service to throw the error.
Thanks
Rama
Thank you for the answer.
I'm sorry but my reply didn't appear. I noticed the San Diego message was hard-coded and that was not the problem. The problem was probably in handling the message from the closest facility service since in my ArcGIS for Developers Dashboard I could see that I was requesting the Closest Facility service.
As you can see in the picture attached, my API KEY has the Closest Facility service activated thus that shouldn't cause the problem.
What is that Charles or Fiddler network traffic tracker? Is it some feature of Android Studio?
Thanks
Yes, you seem to have the required scope for the api key.
Charles (on Mac) or Fiddler (on Windows) are network traffic debug tools. You can also reach out to Esri Support to debug this further.
Typically we see that error on the solveClosestFacility operation when there are missing facilities or incidents etc in the request parameters. It is weird that the sample is not working for you after switching to generic Closest Facility location service.
Thanks
Rama
I thank you very much for all the support you've given me on this issue.
I honestly don't know any potential reason that is causing this bug. In the past, I used a custom Network Dataset and had no problem. The San Diego closest facility service is also working now, so something else is happening.
Anyway, I will close this issue because matter of fact I intend to use a custom Network Dataset so no need to worry about not making the Closest Facility location service work.
I really appreciate your help.
Cheers