Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geosearch Multiple Providers of same type ? #20

Open
rylincoln opened this issue Apr 14, 2023 · 4 comments
Open

Geosearch Multiple Providers of same type ? #20

rylincoln opened this issue Apr 14, 2023 · 4 comments

Comments

@rylincoln
Copy link

Perhaps (probably?) I'm doing something wrong but here is my scenario.

Using the EsriLeafletGeoSearch plugin, we configure providers by passing an object who's keys are parsed into the provider type that esri-leaflet-geocoder supports.

so example object looks something like this:

                mapServiceProvider: {
                        token: token,
                        url: "https://server/server/rest/services/folder/service/MapServer",
                        layers: [21],
                        searchFields: ["id"],
                        label: "Feature X",
                        searchMode: "strict",
                        bufferRadius: 10,
                        maxResults: 20,
                        formatSuggestion: function (feature) {
                            return `${feature.properties.id}` || null;
                        },
                    },
              // mapServiceProvider: {
                    //     token: token,
                    //     url: "https://server/server/rest/services/folder/service/MapServer",
                    //     layers: [3],
                    //     searchFields: ["name", "id"],
                    //     label: "Feature Y",
                    //     searchMode: "startsWith",
                    //     bufferRadius: 10,
                    //     maxResults: 20,
                    //     formatSuggestion: function (feature) {
                    //         return `${feature.properties.id} ${feature.properties.name}` || null;
                    //     },
                    // },

Since the object is then parsed using Object.keys(object) to tell ELG which provider type we want being one of

  • arcgisOnlineProvider
  • featureLayerProvider
  • mapServiceProvider
  • geocodeServiceProvider

It appears to me that one cannot configure 2 or more of the same type of provider this way because you'd have to create an object with duplicate keys and I think the last one in wins.

In the ELG documentation here - it looks like it can support multiple providers of the same type maybe?
https://developers.arcgis.com/esri-leaflet/api-reference/controls/geosearch/#providers

But it looks like it would require us passing in an array of objects so we're not relying on the keys of an object for provider type and instead we use a key/value pair that defines the provider type.

So would that be changing things around here?

const providers = Object.keys(providersProp).map((provider) => {

Perhaps it would accept something like this example below to configure multiple of the same type of providers?

[
    {
        "type": "mapServiceProvider",
        "options": {
            "token": token,
            "url": "https://server/server/rest/services/folder/service/MapServer",
            "layers": [21],
            "searchFields": ["id"],
            "label": "Feature X",
            "searchMode": "strict",
            "bufferRadius": 10,
            "maxResults": 20,
            "formatSuggestion": function (feature) {
                return `${feature.properties.id}` || null;
            },
        }
    },
    {
        "type": "mapServiceProvider",
        "options": {
            "token": token,
            "url": "https://server/server/rest/services/folder/service/MapServer",
            "layers": [3],
            "searchFields": ["name", "id"],
            "label": "Feature X",
            "searchMode": "strict",
            "bufferRadius": 10,
            "maxResults": 20,
            "formatSuggestion": function (feature) {
                return `${feature.properties.id} ${feature.properties.name}` || null;
            },
        }
    },
]

Thanks for listening.

@rylincoln rylincoln changed the title Geosearch Multiple Providers of same type Geosearch Multiple Providers of same type ? Apr 14, 2023
@slutske22
Copy link
Owner

Interesting use case, I hadn't thought of that. Is the idea to have 2 different mapServiceProviders, with different urls? It looks like you are trying to use the same url, but with different searchFields and layers, which seems a bit redundant.

Anyway yes, this is a use case I hadn't considered and your suggestion to turn the prop into an array is a good one. I'll try to pubish a change when I get a chance.

@rylincoln
Copy link
Author

Yes, I'm using the same url, but different layers[] to search, more for a separate of concerns to simplify the formatSuggestions as the fields to search will be different for each layer.

@rylincoln
Copy link
Author

rylincoln commented Apr 14, 2023

FYI - I setup a component to solve for me now that I understand it more.

import { useEffect } from 'react'
import { useMap } from 'react-leaflet'
import * as ELG from 'esri-leaflet-geocoder'
import useArcGISToken from "../hooks/useArcGISToken";

const EsriLeafletGeoCoder = () => {
    const [token, error] = useArcGISToken();
    if (error) {
        console.log("error", error);
    }
    const map = useMap()

    useEffect(
        () => {
            if (token) {
                const layer21 = ELG.mapServiceProvider({
                    url: 'https://server.com/server/rest/services/folder/servicename/MapServer',
                    token: token,
                    layers: [21],
                    searchFields: ["id"],
                    label: "Layer 21",
                    searchMode: "strict",
                    bufferRadius: 10,
                    maxResults: 10,
                    formatSuggestion: function (feature) {
                        return `${feature.properties.id}` || null;
                    },
                });

                const layer3 = ELG.mapServiceProvider({
                    url: 'https://server.com/server/rest/services/folder/servicename/MapServer',
                    token: token,
                    layers: [3],
                    searchFields: ["id","name"],
                    label: "Layer 3",
                    searchMode: "startWith",
                    bufferRadius: 10,
                    maxResults: 10,
                    formatSuggestion: function (feature) {
                        console.log(feature)
                        return `${feature?.properties?.id} | ${feature?.properties?.name}` || null;
                    },
                });

                const GeoSearch = new ELG.Geosearch({
                    useMapBounds: false,
                    collapseAfterResult: false,
                    expanded: true,
                    providers: [layer21, layer3]
                })

                GeoSearch.addTo(map)

                return () => {
                    GeoSearch.remove()
                }
            } else {
                return () => {
                    console.log("no token")
                }
            }

        }
        , [map, token])

    return null

}

export default EsriLeafletGeoCoder

@slutske22
Copy link
Owner

That's one way to workaround, very nice.

Another may be just to grab a ref to the EsriLeafletGeosearch component and modify its options directly:

  const MyMap = () => {
    const [ref, setRef] = useState();

    useEffect(() => {
      if (ref){
        ref.options.providers = [provider1, provider2, etc];
      }
    }, [ref])

    return (
      <MapContainer>
        <EsriLeafletGeoSearch
          ref={ref}
          providers={{}}
          key={ARCGIS_API_KEY}
        />
      </MapContainer>
    );
  };

Not sure if you can modify those providers after the fact, its just another idea till I can patch this package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants