[ad_1]

About the author

Prince Chukwudire is a Frontend Engineer who would like to apply the pixel-perfect implementation of user-oriented UI designs and write unit tests to improve code …
More about Prince ↬

In this guide we will look at the concepts of forward geocoding and reverse geocoding. We will set up a mini-app that applies these concepts to specific locations using Mapbox and Vue.js 2.6.11 to achieve this.

Accurate accuracy and modularity are one of the advantages that make geocodes the perfect way to find a specific location.

In this guide we build a simple geocoding program from scratch using Vue.js and Mapbox. We cover the process from building the front scaffolding to building a geocoder to handle forward coding and reverse geocoding. To get the most out of this guide, you will need a basic understanding of JavaScript and Vue.js and how to make API calls.

What is geocoding?

Geocoding is the transformation of text-based locations into geographic coordinates (usually latitude and longitude) that indicate a location in the world.

Geocoding is of two types: forward and backward. Forward geocoding converts location texts to geographic coordinates, while reverse geocoding coordinates to location texts.

In other words, reverse geocoding changes 40.714224, -73.961452 to “277 Bedford Ave, Brooklyn”, and forward geocoding does the opposite, changing “277 Bedford Ave, Brooklyn” to 40.714224, -73.961452.

To provide more insight, we will set up a mini-web application that uses an interactive web map with custom markers to display location coordinates, which we will then decode to location texts.

Our app has the following basic features:

  • gives the user access to an interactive map display with a marker;
  • allows the user to move the marker at will while displaying coordinates;
  • returns a text-based location or location coordinates at the request of the user.

Set up project with Vue CLI

We use the kettle plate found in this repository. It contains a new project with the Vue CLI and yarn as package manager. You need to clone the repository. Ensure that from the geocoder/boilerplate branch.

Configure the file structure of the application

Next, we need to set up the file structure of our project. Rename the Helloworld.vue file in the directory of the component to Index.vue, and leave it blank for now. Go ahead and copy the following into the App.vue file:

<template>
  <div id="app">
    <!--Navbar Here -->
    <div>
      <nav>
        <div class="header">
          <h3>Geocoder</h3>
        </div>
      </nav>
    </div>
    <!--Index Page Here -->
    <index />
  </div>
</template>
<script>
import index from "./components/index.vue";
export default {
  name: "App",
  components: {
    index,
  },
};
</script>

Here we imported the recently renamed component locally and then registered. We’ve also added a navigation bar to enhance the aesthetics of our app.

We have a .env file to load the environmental variables. Go ahead and add one at the root of your workbook.

Install required packages and libraries

To launch the development process, we will need to install the required libraries. Here is a list you will use for this project:

  1. Mapbox GL JS
    This JavaScript library uses WebGL to render interactive maps vector rules and Mapbox.
  2. Mapbox-gl geocoder
    This Mapbox GL geocoder control will help with our forward geocoding.
  3. Dotenv
    We do not need to install it because it is pre-installed with Vue CLI. It helps us to understand environmental variables from a .env file in process.env. This way we can keep our configurations separate from our code.
  4. Axios
    This library will help us to make HTTP requests.

Install the packages in your CLI according to your package manager of your choice. If you are using Yarn, then complete the following command:

cd geocoder && yarn add mapbox-gl @mapbox/mapbox-gl-geocoder axios

If you use npm, execute it:

cd geocoder && npm i mapbox-gl @mapbox/mapbox-gl-geocoder axios --save

We first had to geocoder fold before executing the installation command.

Scaffold the front with Vue.js

Let’s go ahead and make a layout for our app. We need an element to house our map, a region to display the coordinates as we listen to the movement of the marker on the map, and something to display the location when we call the reverse geocoding API. We can contain it all within one card component.

Draw the following in your Index.vue file:

<template>
  <div class="main">
    <div class="flex">
      <!-- Map Display here -->
      <div class="map-holder">
        <div id="map"></div>
      </div>
      <!-- Coordinates Display here -->
      <div class="dislpay-arena">
        <div class="coordinates-header">
          <h3>Current Coordinates</h3>
          <p>Latitude:</p>
          <p>Longitude:</p>
        </div>
        <div class="coordinates-header">
          <h3>Current Location</h3>
          <div class="form-group">
            <input
              type="text"
              class="location-control"
              :value="location"
              readonly
            />
            <button type="button" class="copy-btn">Copy</button>
          </div>
          <button type="button" class="location-btn">Get Location</button>
        </div>
      </div>
    </div>
  </div>
</template>

Start your development server to see what we currently have. For stations:

yarn serve

Or for npm:

npm run serve

Our app should now look like this:

Tax Preview
Geocoding of app scaffold preview. (Big preview)

The empty spot to the left looks down. It must contain our map display. Let’s add it.

Interactive map display with Mapbox

The first thing we need to do is access the Mapbox GL and Geocoder libraries. We start through the Mapbox GL and Geocoder libraries in the Index.vue file.

import axios from "axios";
import mapboxgl from "mapbox-gl";
import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder";
import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";

Mapbox requires a unique access token to calculate map vectors. Get yours, and add it as an environmental variable in your .env file.

.env
VUE_APP_MAP_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

We also need to define features that will help put our map tiles together in our data institution. Add the following below where we entered the libraries:

export default {
  data() {
    return {
      loading: false,
      location: "",
      access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN,
      center: [0, 0],
      map: {},
    };
  },
}
  • The location property will be modeled on the input we have in our scaffolding. We will use this to handle reverse geocoding (ie to display a location from the coordinates).
  • The center property contains our coordinates (longitude and latitude). It is critical to put together our map tiles, as we will see soon.
  • The access_token property refers to our environmental variable, which we added earlier.
  • The map property serves as a constructor for our card component.

Let’s continue to create a method that outlines our interactive map with our leading geocoder in it. This method is our basic function, and acts as an intermediary between our component and Mapbox GL; we will call this method createMap. Add it below the data object:

mounted() {
  this.createMap()
},

methods: {
  async createMap() {
    try {
      mapboxgl.accessToken = this.access_token;
      this.map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        center: this.center,
        zoom: 11,
      });

    } catch (err) {
      console.log("map error", err);
    }
  },
},

To create our map, we specified a container containing the card, a style property for the display format of our card, and a center property to house our coordinates. The center property is an array type and holds the longitude and latitude.

Mapbox GL JS initializes our map based on these parameters on the page and returns a Map object to us. The Map object refers to the map on our page, while exposing methods and features that enable us to communicate with the map. We have stored this returned item in our data instance, this.map.

Send Geocoding With Mapbox Geocoder

Now we will add the geocoder and custom marker. The geocoder handles forward geocoding by transforming text-based locations into coordinates. It will appear in the form of a search input box added to our map.

Add the following under the this.map initialization we have above:

let geocoder =  new MapboxGeocoder({
    accessToken: this.access_token,
    mapboxgl: mapboxgl,
    marker: false,
  });

this.map.addControl(geocoder);

geocoder.on("result", (e) => {
  const marker = new mapboxgl.Marker({
    draggable: true,
    color: "#D80739",
  })
    .setLngLat(e.result.center)
    .addTo(this.map);
  this.center = e.result.center;
  marker.on("dragend", (e) => {
    this.center = Object.values(e.target.getLngLat());
  });
});

Here we first made a new instance of a geocoder using the ‘MapboxGeocoder’ constructor. It initializes a geocoder based on the provided parameters and returns an object, exposed to methods and events. The ‘accessToken’ property refers to our Mapbox access token, and ‘mapboxgl’ refers to the [map library](https://docs.mapbox.com/#maps) currently in use. The core of our app is the custom tag; the geocoder has standard one. However, it does not give us all the adjustments we need; therefore, we eliminated it. Going further, we passed our newly created encoder as a parameter to the ‘addControl’ method, exposed to us by our map object. `addControl` accepts ‘control’ as a parameter. To create our personal tag, we used an event exposed to us by our encoder. The ‘on’ listener can subscribe to events that take place within the geocoder. It accepts different [events](https://github.com/mapbox/mapbox-gl-geocoder/blob/master/API.md#on) as parameters. We listen to the ‘result’ event, which is fired when an input is set. In a nutshell, on ‘result’, our brand designer creates a tag, based on the parameters we have provided (a drag trait and color, in this case). It returns an object that we use the ‘setLngLat’ method to get our coordinates. We add the custom tag to our existing map using the ‘addTo’ method. Finally, we update the property ‘center’ in our case with the new coordinates. We also need to track the movement of our personal marker. We achieved this by using the ‘bearing’ event listener and updating our property ‘center’ with the current coordinates. Let’s update the template to indicate our interactive map and geocoder. Update the coordinates display section in our template with the following:

<div class="coordinates-header">
  <h3>Current Coordinates</h3>
  <p>Latitude: {{ center[0] }}</p>
  <p>Longitude: {{ center[1] }}</p>
</div>

Remember how we always updated ourselves center property following an event? We display the coordinates here based on the current value.

Insert the following CSS file to enhance the aesthetics of our app head part of the index.html file. Place this file in the public folder.

<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />

Our app should now look like this:

Send geocoding preview
Send preview for geocoding. (Big preview)

Reverse Geocode Location with Mapbox API

Now we’ll handle reverse geocoding of our coordinates to text based locations. Let’s write a method that handles it and activate it with the Get Location button in our template.

Reverse Geocoding in Mapbox is handled by the Reverse Geocoding API. Accept it longitude, latitude, en access token as request parameters. This call returns an answer load – usually with different details. Our concern is the first object in the features array, where the inverse geocoded location is.

We need to create a function that longitude, latitude and access_token from where we want to get Mapbox API. We need to send them to get the details of the location.

Finally, we must location property in our case with the value of the place_name key in the object.

Among the createMap() function, let’s add a new function that handles what we want. This is what it should look like:

async getLocation() {
  try {
    this.loading = true;
    const response = await axios.get(
      `https://api.mapbox.com/geocoding/v5/mapbox.places/${this.center[0]},${this.center[1]}.json?access_token=${this.access_token}`
    );
    this.loading = false;
    this.location = response.data.features[0].place_name;
  } catch (err) {
    this.loading = false;
    console.log(err);
  }
},

This feature makes a GET request to the Mapbox API. The answer contains place_name – the name of the selected place. We get it from the answer and then set it as the value of this.location.

If you do, we need to edit and configure the button that will call the feature we created. We use a click listener of the event – what the getLocation method when a user clicks on it. Go ahead and edit the button component below.

<button
  type="button"
  :disabled="loading"
  :class="{ disabled: loading }"
  class="location-btn"
  @click="getLocation"
>
  Get Location
</button>

As a cherry on the cake, let’s attach a function to copy the displayed location to the clipboard. Just add it below the getLocation function:

copyLocation() {
  if (this.location) {
    navigator.clipboard.writeText(this.location);
    alert("Location Copied")
  }
  return;
},

Work the Copy button component to activate it:

<button type="button" class="copy-btn" @click="copyLocation">

Closure

In this guide, we looked at geocoding using Mapbox. We’ve built a geocoding app that converts text-based locations to coordinates, displays the location on an interactive map, and converts coordinates to text-based locations, at the user’s request. This guide is just the beginning. Much more can be achieved with the geocoding APIs, such as changing the presentation of the map using the different card styles provided by Mapbox.

Resources

Smashing Editorial
(ks, vf, yk, il, al)

[ad_2]

Source link