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

Module(Mapbox): Custom Geocoder component #23

Open
erictuvesson opened this issue Sep 20, 2023 · 0 comments
Open

Module(Mapbox): Custom Geocoder component #23

erictuvesson opened this issue Sep 20, 2023 · 0 comments
Labels
documentation Improvements or additions to documentation

Comments

@erictuvesson
Copy link
Contributor

Improve documentation

Link

https://docs.noodl.net/2.9/library/modules/mapbox/guides/geocoder/

Describe the improvement

We should create a page descripting how to create a custom Geocoder / Address search component.

Additional context

Here is an example:
https://mapbox-module-test.sandbox.noodl.app/geocoding-api

image

Search:

// Define the expected inputs for the script
Script.Inputs = {
  Query: "string",
};

// Define the expected outputs for the script
Script.Outputs = {
  Items: "array",
  Searched: "signal",
};

// Set the endpoint URL for the Mapbox geocoding API
const ENDPOINT = 'https://api.mapbox.com/geocoding/v5/mapbox.places';

// Define an asynchronous function to make the API request
async function makeRequest() {
  // Get the Mapbox access token from Noodl project settings
  const access_token = Noodl.getProjectSettings().mapboxAccessToken;
  
  // Encode the search query to be URL-safe
  const search_text = encodeURIComponent(Script.Inputs.Query);

  // Define query parameters for the API request
  // 
  // Playground by Mapbox to test out all the features:
  // https://docs.mapbox.com/playground/geocoding
  //
  // Here is a list of all the different possible types:
  //  - address
  //  - country
  //  - region
  //  - postcode
  //  - district
  //  - place
  //  - neighborhood
  //  - locality
  //  - poi
  const queryParams = {
    access_token, // Provide the access token
    proximity: [Script.Inputs.lng, Script.Inputs.lat].join(','), // Bias results towards user's location
    limit: 5, // Maximum number of results to return
    // types: ["address"].join(","), // Filter results to include only addresses
    // fuzzyMatch: true // Enable approximate matching
    language: 'en-GB'
  };

  // Construct the query string from the query parameters
  const query = Object.keys(queryParams)
    .filter((key) => !!queryParams[key]) // Filter out empty values
    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
    .join('&');

  // Make the API request and get the response as JSON
  const response = await fetch(`${ENDPOINT}/${search_text}.json?${query}`);
  const json = await response.json();

  // Map the API response to an array of search results
  const items = json.features.map((x) => Noodl.Object.create({
    text: x.text,
    place_name: x.place_name,
    // Convert the array of [latitude, longitude] to a Geopoint
    center: { latitude: x.center[0], longitude: x.center[1] }
  }));

  Script.Outputs.Items = items;
  Script.Outputs.Searched();
}

Script.Signals = {
  Search() {
    makeRequest();
  },
};

Center to the clicked item:

const items = Inputs.Items;
const itemId = Inputs.ItemId;

const item = items.find((x) => x.id === itemId);
if (!item) throw new Error("Cannot find clicked item.");

// The center geopoint of the clicked item.
const geopoint = item.center;

const mapboxObject = Inputs.MapboxObject;
if (!mapboxObject) throw new Error("Mapbox Object is invalid.");

mapboxObject.flyTo({
    center: [geopoint.latitude, geopoint.longitude],
    essential: true,
    zoom: 15
});

The repeater item is just a button that is outputting a Click signal.

@erictuvesson erictuvesson added the documentation Improvements or additions to documentation label Sep 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant