Find nearest feature in MMPK layer to a point while offline

1057
3
Jump to solution
04-22-2021 03:18 PM
KevinCheriyan
Occasional Contributor

I'm working on an AppStudio app that works offline. The app's webmap is created from an MMPK and contains a point layer that the user can interact with.

Here's what I want to do: 

I want to click on the map (outside the layer and its features) and find the geographically nearest point feature in the layer to the point that I clicked. 

This seems like a pretty reasonable thing to want to do, but the GeometryEngine doesn't perform well in this scenario due to the large number of point features in this layer. Here's what I've tried or thought about trying, but doesn't work.

1. 

  • Create a buffer polygon for a fixed distance around the point that I click.
  • Find all features in the feature layer that intersects with buffer polygon.
  • Find distances between original point and each of the intersected features.
  • Sort these distances to find the feature that is closest to the point that I clicked on. 

This doesn't work because my feature layer has 120,000 point features. If I iterate through each of them to check if they intersect with my buffer polygon, it can take a LONG time. 

2. I've thought about using ClosestFacilityTask, but this requires an online connection. So not an option for me. 

Ideally, I guess I would've liked a Runtime method I can call where I input in these parameters: 1) original point's geometry and 2) feature layer. This would return a single feature that is closest to my point. But this is not a Runtime feature AFAIK.

Does anyone else have any ideas on how to proceed here? Any help appreciated. 


--------------------------------------------------
Application Developer, GeoMarvel
0 Kudos
1 Solution

Accepted Solutions
JamesBallard1
Esri Regular Contributor

Hi @KevinCheriyan.

Thanks for reaching out to the Runtime team. Unfortunately there's nothing that will do exactly like you're wanting to do. However there are some tweaks we can recommend to your workflow (which is quite good) that might help.

When you do the feature query to get the features in your buffered polygon, you can run a queryFeaturesCount to "walk in" your buffer area to reduce the number of features. So for instance if your search will return 10,000 features (getting the count should be quick), you can reduce the size of your polygon buffer area until you get a reasonable number of features to check with the GeometryEngine, perhaps 100 or less. This will require testing to find the sweet spot. It's also possible your features as so densely packed that you can't get only 100. As I said, it will require some testing.

>This doesn't work because my feature layer has 120,000 point features. If I iterate through each of them to check if they intersect with my buffer polygon, it can take a LONG time. 

Just to clarify, but when you do your query with your buffer geometry, you should get a subset of features and not need to iterate all 120,000 features.

So my recommendation would be to slightly tweak your workflow as follows:

1. When the mouse is clicked, create a buffer polygon (size will come from testing).

2. Set that polygon as the geometry on your QueryParameters (https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-queryparameters.html#geome...)

3. First run a queryFeatureCount task to see how many features are in your polygon area: https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-featuretable.html#queryFea... 

4. Walk that in to get a reasonable number of features

5. Then proceed with queryFeatures to get your set of features: https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-featuretable.html#queryFea...

6. Iterate through them with GeometryEngine to determine which feature is nearest to the clicked point.

 

Let us know if that help.

View solution in original post

3 Replies
JamesBallard1
Esri Regular Contributor

Hi @KevinCheriyan.

Thanks for reaching out to the Runtime team. Unfortunately there's nothing that will do exactly like you're wanting to do. However there are some tweaks we can recommend to your workflow (which is quite good) that might help.

When you do the feature query to get the features in your buffered polygon, you can run a queryFeaturesCount to "walk in" your buffer area to reduce the number of features. So for instance if your search will return 10,000 features (getting the count should be quick), you can reduce the size of your polygon buffer area until you get a reasonable number of features to check with the GeometryEngine, perhaps 100 or less. This will require testing to find the sweet spot. It's also possible your features as so densely packed that you can't get only 100. As I said, it will require some testing.

>This doesn't work because my feature layer has 120,000 point features. If I iterate through each of them to check if they intersect with my buffer polygon, it can take a LONG time. 

Just to clarify, but when you do your query with your buffer geometry, you should get a subset of features and not need to iterate all 120,000 features.

So my recommendation would be to slightly tweak your workflow as follows:

1. When the mouse is clicked, create a buffer polygon (size will come from testing).

2. Set that polygon as the geometry on your QueryParameters (https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-queryparameters.html#geome...)

3. First run a queryFeatureCount task to see how many features are in your polygon area: https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-featuretable.html#queryFea... 

4. Walk that in to get a reasonable number of features

5. Then proceed with queryFeatures to get your set of features: https://developers.arcgis.com/qt/qml/api-reference/qml-esri-arcgisruntime-featuretable.html#queryFea...

6. Iterate through them with GeometryEngine to determine which feature is nearest to the clicked point.

 

Let us know if that help.

KevinCheriyan
Occasional Contributor

Thanks @JamesBallard1! This looks promising. I didn't realize there was a geometry property in QueryParameters that I could set. 

And I could see how I'll be working with significantly less features to iterate through if I'm working with the intersected subset of features.

I'll give this a go and post a reply on how it goes.


--------------------------------------------------
Application Developer, GeoMarvel
0 Kudos
KevinCheriyan
Occasional Contributor

This worked great! Thanks for the suggestion.


--------------------------------------------------
Application Developer, GeoMarvel