smeijer / leaflet-geosearch

A geocoding/address-lookup library supporting various api providers.
https://smeijer.github.io/leaflet-geosearch/
MIT License
1.04k stars 273 forks source link

Adding own search data (Question) #162

Closed RyanMarshall5765 closed 6 years ago

RyanMarshall5765 commented 6 years ago

Hello, I was just wondering if there is a way to use this for my existing markers. Is this only to search places within the OSM database? Thanks for any info.

RyanMarshall5765 commented 6 years ago

Found something that does what I wanted. Closing issue.

smeijer commented 6 years ago

A custom provider could fix this issue. Just hit the search against your own data, and return the matched results.

RyanMarshall5765 commented 6 years ago

Thank you very much for your response. I like your documentation compared to the other one so I would love to still use yours. Could you clarify "Hit the search against your own data" part? Trying to figure out how to write my own provider right now. College really does not prepare you for what this actually entails haha.

smeijer commented 6 years ago

I would advise on checking the providers included in this libary: https://github.com/smeijer/leaflet-geosearch/blob/develop/src/providers/

But basically; the only thing you need is an class with a search method, that returns a promise which resolves to an result array. Sounds exciting? Well, more basic, an async search that returns an array.

class MyProvider {
  async search({ query }) {
    return [{
      x: Number,                      // lon
      y: Number,                      // lat
      label: String,                  // formatted address
      bounds: [
        [Number, Number],             // s, w - lat, lon
        [Number, Number],             // n, e - lat, lon
      ],
    }]
  }
}

Add to leaflet:

const searchControl = new GeoSearchControl({
  provider: new MyProvider(),
});

const map = new L.Map('map');
map.addControl(searchControl);

How you fetch/query your data, is up to you. But I guess you already have the data somewhere, as you need it to be able to add the markers to the map. So don't try to query the markers, query the source data instead.

RyanMarshall5765 commented 6 years ago

I was able to figure out how to get this semi-functional.

However, should it be auto filtering when I am searching or do I have to implement that myself? (Example: Looking for "New York" I type "Z" then "New York" should not be listed but type "N" then "New York" shows.)

Also, all results bring me to the same marker. Is this something to do with how I am returning the Coordinates?

Below is the code I wrote for the Provider:

import { geojson } from "../data/places.js";

class Provider {
  parse(data) {
    return Object.values(data).map(value => {
      if (value) {
        return typeof value === "object" ? this.parse(value) : value;
      }
      return null;
    });
  }

  nameContent(feature) {
    const name = feature.properties.place.names[0];
    return name ? this.parse(name) : null;
  }

  async search() {
    return geojson.features.map(feature => ({
      x: feature.geometry.coordinates[0],
      y: feature.geometry.coordinates[1],
      label: this.nameContent(feature)
    }));
  }
}

export default Provider;

Thank you for any assistance that you can provide.

smeijer commented 6 years ago

The searching is something that you should implement in the search method. Providers should send a search string to an api. The API sends only the matching results. The provider than returns this result to leaflet-geosearch to show it to the user.

Depending on the data in your places.js file, it shouldn't be that hard. The general idea is:

  async search({ query }) {
    return geojson.features
      .filter(feature => feature.properties.names[0].indexOf(query) > -1)
      .map(feature => ({
        x: feature.geometry.coordinates[0],
        y: feature.geometry.coordinates[1],
        label: this.nameContent(feature)
      }));
  }

Note that I don't know the structure of your names property. It's just an example. Try to compare the properties of the feature against the query there.