Esri / arcgis-rest-js

compact, modular JavaScript wrappers for the ArcGIS REST API
https://developers.arcgis.com/arcgis-rest-js/
Apache License 2.0
347 stars 119 forks source link

Abstraction for spatial queries #827

Open bertday opened 3 years ago

bertday commented 3 years ago

Hi,

Thank you for your hard work on this project!

I installed the feature layer package expecting there would be some sort of interface for performing spatial queries that's more convenient than calling the REST API itself (which is pretty onerous IMO), along the lines of:

const data = await queryFeatures({
  intersects: {
    // geojson or wkt here
  }
});

or perhaps by chaining, like queryFeatures(...).intersects(...).

esri-leaflet has this and it's great—the only thing is I'm not using Leaflet, so it doesn't really make sense for my use case.

Just a suggestion, thank you again!

gavinr commented 3 years ago

Thanks for the suggestion @rbrtmrtn. I think there are maybe 2 separate requests here:

1. Chaining helper

This is an example of the type of interface from Esri Leaflet you're referring to, correct? Having something like .intersects(...) that sets the geometry AND the spatialRel (code in Esri Leaflet)

There is some prior art for this pattern in ArcGIS REST JS: SearchQueryBuilder (code). In theory we could follow this pattern to provide something for Feature Layer Queries as well (taking inspiration from the Esri Leaflet solution) - @patrickarlt did you have any thoughts on this?

2. GeoJSON/WKT as input

// geojson or wkt here

I think here you're asking to be able to pass in GeoJSON or WKT as the geometry - is that correct?

  1. For GeoJSON, you can do conversion using the terraformer/arcgis library. Should we incorporate that into ArcGIS REST JS? I'm not sure ... open to debate here.
  2. For WKT, I'm not as familiar with this conversion, but I suspect you can find a library to convert WKT to GeoJSON and then use the steps above after that.
jgravois commented 3 years ago

hey @rbrtmrtn and @gavinr! 👋

Should we incorporate that into ArcGIS REST JS?

I'd say no. a demo that shows how to use both libraries together would be a better call.

WKT to GeoJSON - https://github.com/terraformer-js/terraformer/tree/master/packages/wkt 🤗

edit: actually i believe https://www.npmjs.com/package/wkx is even faster 🐎

bertday commented 3 years ago

Thank you for following up @gavinr, and always good to get your thoughts @jgravois 👋

To sum up my use case, I most often use the ArcGIS REST API to fetch a polygon (usually a land parcel) from one feature service, and then query another feature service to get points that fall inside (basic point-in-poly).

The pain point for me is that I do this just infrequently enough that I always forget how to construct the REST API query 😆 esri-leaflet made this a lot easier because it gave me an interface that fit my mental model of:

I was considerably more productive with that vs. having to build a (pretty verbose) set of query params like:

const res = await axios.get(
        'https://<some_server>/rest/services/<some_service>/FeatureServer/0/query',
        {
          params: {
            where: '1=1',
            outFields: '*',
            f: 'json',
            outSR: '4326',
            geometry: `{"x":${lng},"y":${lat},"spatialReference":{"wkid":4326}}`,
            geometryType: 'esriGeometryPoint',
            inSR: '4326',
            spatialRel: 'esriSpatialRelWithin',
            returnGeometry: 'true',
          },
        }
      );

(Granted that's a raw HTTP request and not using arcgis-rest-js, but I found the abstractions to be pretty thin when it came to spatial joins. Maybe I just need to go back over the docs.)

I mentioned chaining but I'm not sure I had any specific ideas around how to implement this—just that I think the biggest gain would be boiling the boilerplate above down to just the type of spatial operation (intersects, contains, etc.) and a criterion geometry.

I hope that's helpful, and feel free to let me know if I can explain any of that better! Thanks again for all your hard work and dedication with this library!

patrickarlt commented 3 years ago

TL;DR we should really do a FeatureQueryBuilder to better support spatial queries.


I think we should absolutely so something like FeatureQueryBuilder for queryFeatures. This is exactly what I had in mind when I wrote SearchQueryBuilder in the first place I just never got around to expanding the concept to other APIs. In my mind (currently) the whole point of ArcGIS REST JS is to abstract all the hard parts of dealing with ArcGIS APIs this has generally meant increasing the level of abstraction we handle in the library

  1. Abstract basics of the request/response cycle, error handling and processing, parameter encoded, ect... arcgis-rest-request
  2. Abstract authentication and security, i.e. arcgis-rest-auth
  3. Abstract basic transactional API endpoints. i.e. arcgis-rest-portal, arcgis-rest-geocoding, ect...
  4. Abstract complex API endpoints and concepts, i.e. SearchQueryBuilder, long running geoprocessing tasks, ect...

Most of us (maintainers) are actually pretty fine at level 3 where we simply wrap the existing API endpoints and call it day, but I think there are some methods and processes (spatial queries, geoprocessing, advanced routing) that require more abstraction.

Artboard