mapsuber-apih3s2

How to find the locations (indices whose lat long co-ordinates are stored in geo-json format) within 5 Km radius of a h3 index in h3-js?


I'm creating a hyper local delivery service app . I can only receive order if there is a store within 5 km radius from the user . I stored the store locations in geojson format . Is there a function in h3-js which will take radius , array of stores , h3 index and then give back the list of stores which are within 5 km range from the given h3 index . or how can i implement this using h3-js?


Solution

  • There are a few different parts here:

    Pick a resolution: Pick an H3 resolution for lookup. Finer res means more accuracy but more memory usage. Res 8 is roughly a few city blocks in size.

    Indexing Data: To use H3 for the radius lookup, you need to index the stores by H3 index. If you want this to be efficient, you'd be better off indexing all the stores ahead of time. How you do this is up to you; one easy way in JS might be to create a map of id arrays:

    const lookupIndexes = stores.features.reduce((map, feature) => {
      const [lon, lat] = feature.geometry.coordinates;
      const h3Index = h3.geoToH3(lat, lon, res);
      if (!map[h3Index]) map[h3Index] = [];
      map[h3Index].push(feature.id);
      return map;
    }, {})
    

    Perform the lookup: To search, index your search location and get all the H3 indexes within some radius. You can use the h3.edgeLength function to get the approximate radius of a cell at your current resolution.

    const origin = h3.geoToH3(searchLocation.lat, searchLocation.lon, res);
    const radius = kmToRadius(searchRadiusKm, res);
    
    // Find all the H3 indexes to search
    const lookupIndexes = h3.kRing(origin, radius);
    
    // Find all points of interest in those indexes
    const results = lookupIndexes.reduce(
      (output, h3Index) => [...output, ...(lookupMap[h3Index] || [])], 
    []);
    

    See a working example on Observable

    Caveats: This is not a true radius search. The k-ring is a roughly hexagonal shape centered on the origin. This is good enough for many use cases, and much faster than a traditional Haversine radius search, especially if you have many rows to search over. But if you care about the exact distance H3 might not be appropriate (or, in some cases, H3 might be fine, but you might want the indexes inside a "true" circle - one option here is to convert your circle to a close-to-circular polygon, then get the indexes via h3.polyfill).