<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BT</title>
    <description>The latest articles on DEV Community by BT (@breteiko).</description>
    <link>https://dev.to/breteiko</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F507507%2F4fa0ac12-6005-4c68-9d5a-52633558315e.png</url>
      <title>DEV Community: BT</title>
      <link>https://dev.to/breteiko</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/breteiko"/>
    <language>en</language>
    <item>
      <title>The Benefits of Geocoding and Structuring Your Address Data</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Sat, 28 Nov 2020 22:53:06 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/the-benefits-of-geocoding-and-structuring-your-address-data-2805</link>
      <guid>https://dev.to/tomtomdevs/the-benefits-of-geocoding-and-structuring-your-address-data-2805</guid>
      <description>&lt;h4&gt;
  
  
  An Easy Way for Developers to Clean Up Address Data
&lt;/h4&gt;

&lt;p&gt;Address information is one of the most commonly collected forms of data for companies across the world. It is also data that can easily be collected and stored in inaccurate or incomplete form.&lt;/p&gt;

&lt;p&gt;Street names might be misspelled. Zip Codes could be left out when addresses are entered. Multiple customers could have the same name, creating uncertainty about which addresses map to which people. These are just some of the data quality errors that could appear in address information.&lt;/p&gt;

&lt;p&gt;Fortunately, there is an easy way for developers to clean up address data, without having to purchase complex data quality tools or get Ph.D.s in data engineering. That solution is the TomTom Online Search API, which provides a structured geocoding call that can clean up address data. It also provides accurate latitude and longitude information that can take the place of unformatted raw data in order to deliver greater accuracy and exactitude.&lt;/p&gt;

&lt;p&gt;This article explains how to get started with the TomTom Online Search API for address validation and data cleanup. We’ll discuss the benefits of geocoding and properly formatting your address data, then walk through a sample address cleanup program that leverages the structured geocoding API call from TomTom.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Benefits of Geocoding and Structuring Your Address Data
&lt;/h4&gt;

&lt;p&gt;As described above, it’s not uncommon whaen requesting data via an online form to run into issues with the validity of the requested data. This holds true in the case of requesting address data from a customer.Misspellings, incorrect capitalization and missing fields can cause obvious issues. Imagine a situation where a company reads from this database in order to perform a mailing to all customers who provided their address data. This company would want the mailing to make its way to the correct destination, but when viewing the list of addresses, the addresses may have misspellings that could result in delivery failures. Structuring address data properly would provide an essential fix for this issue.&lt;/p&gt;

&lt;p&gt;Through the use of the Online Search product from TomTom, an organization can pass the provided address data into the structured geocoding API call, and if they’ve received enough relevant address data to narrow down the search, they can receive the actual (properly formatted) address that will allow them to perform a mailing without any issues. In addition, the address will be geocoded, and they will have the ability to store the latitude and longitude along with the associated address in their database.&lt;/p&gt;

&lt;p&gt;Geocoding provides several benefits that are undeniable in today’s day and age—many of which stem from an organization’s ability to analyze their customer base on a geographical level. Instead of simply staring at lines of address data on a page, they can instead look at a map of locations that may provide valuable insight into their market. Maybe their business is more successful in some parts of a particular city than others, and mapping data can help them discover where to focus their efforts. Or maybe they’ve cornered the market in one portion of a city, but there are neighborhoods that have critical similarities where the market remains untapped. Geocoding can assist in helping to analyze customer data in both of these cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting Started with the TomTom Online Search API
&lt;/h4&gt;

&lt;p&gt;The first step towards utilizing structured geocoding from TomTom is to get set up with the TomTom Online Search API. Visiting the &lt;a href="https://developer.tomtom.com/user/register"&gt;TomTom For Developers&lt;/a&gt; website and registering will bring you to a dashboard where you can select the option to add a new application. Providing an application name and selecting the Online Search product will provide you with an API key for use with the Online Search API.&lt;/p&gt;

&lt;p&gt;After you received your API key, you are ready to develop your application that has access to the structured geocoding method for cleaning up geocoding addresses. An invaluable resource throughout development of an application that leverages the Online Search product from TomTom is the online documentation for the resource, located &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation?utm_medium=articles&amp;amp;utm_source=premium&amp;amp;utm_campaign=ent_mapsapi_reviews-showcases_paid&amp;amp;utm_content=dm_showcase_address-data-cleaning_2018"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Simple Java Implementation
&lt;/h4&gt;

&lt;p&gt;So let’s take a look at a sample program that utilizes the structured geocoding API call from TomTom Online Search. In an effort to demonstrate the capability of this API call, I’ve developed a simple Java implementation where a CSV input file acts as our unformatted address database, and a CSV output file acts as our formatted address database. From the input file we will read in each address, line by line, and provide the input as part of the structured geocoding request. Each address in the input file contains misspellings, missing fields. or even both.No latitude and longitude are stored for any address in the input file.&lt;/p&gt;

&lt;p&gt;Below, you will see a screenshot from &lt;em&gt;FormatAddresses.java.&lt;/em&gt; Class variables are set up for the API key as well as the CSV field separator (comma delimited), the new line separator(for use in writing to the output file), the headers for output file formatting and the input and output filenames with the path.For the sake of simplicity, I have written the functionality for the sample program right in the main method for the class, and we can simply run our program from our IDE.&lt;/p&gt;

&lt;p&gt;The first thing we do in the main method is to create and open our output file and write our headers to the first line of the output file. Once we’ve appended our new line character at the end of the first line, we can ensure that we are now ready to write a formatted address to our output, which is simulating a formatted address database table.The next step is to read in our first line and instantiate a string array splitting on the comma delimiter.This will form an array where each position holds a field from the line in the input file.After this, we pass our string array to the constructor for UnformattedAddress.java, where we create an object that organizes our unformatted fields into attributes of a Java object which can then be passed to the HTTP GET request (our API call).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public class FormatAddresses {
  private static final String API_KEY = "YOUR-API-KEY-GOES-HERE";
  private static final String SEPARATOR = ",";
  private static final String NEW_LINE_SEPARATOR = "\n";
  private static final String HEADERS = "streetNumber, streetName, municipality, countryTertiarySubdivision, countrySecondarySubdivision, countrySubdivision, postalCode";
  private static final String INPUT_FILENAME = "C:/documents/Addresses.csv";
  private static final String OUTPUT_FILENAME = "C:/documents/FormattedAddresses.csv"
  public static void main(String[] args) {
    BufferedReader br = null;
    String line = "";
    try {
      FileWriter fileWriter = new FileWriter(OUTPUT_FILENAME);
      fileWriter.append(HEADERS);
      fileWriter.append(NEW_LINE_SEPARATOR);
      br = new BufferedReader(new FileReader(INPUT_FILENAME));
      while ((line = br.readLine()) != null) {
        String[] unformattedAddressArray = line.split(SEPARATOR);
        UnformattedAddress unformattedAddress = new UnformattedAddress(unformattedAddressArray);
        URL url = new URL("https://api.tomtom.com/search/2/structuredGeocode.JSON"
                  + "?key=" + URLEncoder.encode(API_KEY, "UTF-8")
                  + "&amp;amp;countryCode=" + URLEncoder.encode("US", "UTF-8")
                  + "&amp;amp;streetNumber=" + URLEncoder.encode(unformattedAddress.getStreetNumber(), "UTF-8")
                  + "streetName=" + URLEncoder.encode(unformattedAddress.getStreetName(), "UTF-8")
                  + "&amp;amp;municipality=" + URLEncoder.encode(unformattedAddress.getMunicipality(), "UTF-8")
                  + "&amp;amp;countrySecondarySubdivision=" + URLEncoder.encode(unformattedAddress.getCountrySecondarySubdivision(), "UTF-8")
                  + "&amp;amp;countrySubdivision=" + URLEncoder.encode(unformnattedAddress.getCountrySubdivision(), "UTF-8")
                  + "&amp;amp;postalCode=" + URLEncoder.encode(unformattedAddress.getPostalCode(), "UTF-8"));
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        InputStream in = new BufferedInputStream(conn.getInputStream());
        String output = readStream(in);
        JSONObject jsonObject = (JSONObject) new JSONParser().parse(output.toString());
        JSONArray results = (JSONArray) jsonObject.get("results");
        for(JSONObject result : results) {
          JSONObject address = (JSONObject)result.get("address");
          JSONObject position = (JSONObject)result.get("position");
          FormattedAddress formattedAddress = new FormattedAddress(address, position);
          writeFormattedAddress(formattedAddress, fileWriter);
        }
        fileWriter.flush();
        fileWriter.close();
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (Parseexception e) {
        e.printStackTrace();
      } finally {
        br.close();
      }
    }
  }
  /** remainder of class omitted */
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we have instantiated our unformatted address object, we can create our URL that we will use for the request.As you can see in the documentation for the API call, there are several parameters required to perform the structured geocoding call, and many more that are optional.&lt;/p&gt;

&lt;p&gt;Those that are required include the following, which we provide when we build our URL object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base URL&lt;/strong&gt;: api.tomtom.com/search/&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Number&lt;/strong&gt;: 2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response format&lt;/strong&gt;: I have chosen JSON for this particular example. JSONP, JS and XML are also valid options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country Code&lt;/strong&gt;: In my example, I’ll be using US for the country code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Key&lt;/strong&gt;:You can insert the API key provided to you when you added your application through the TomTom developer dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following are the optional request parameters I provided in my particular example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Street Number&lt;/strong&gt;:The street number of the address, if provided in the input file, will be added to the API request. If not, then I will pass an empty string to the call.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Street Name&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Municipality&lt;/strong&gt;: City or town, if provided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country Secondary Subdivision&lt;/strong&gt;:County, if provided.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Country Subdivision&lt;/strong&gt;:The state in which the address is located.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postal Code&lt;/strong&gt;: Zip Code, if provided.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As shown in the code above, the URL for the request is built using the above parameters. (For more information on additional request parameters that may be leveraged, please visit the documentation.)&lt;/p&gt;

&lt;p&gt;The next step in my example was to send the HTTP request, parse the JSON response and build a formatted address object, which we can then leverage to write to our output file (simulated clean database). Please see the code below to see how I put these words into action:&lt;/p&gt;

&lt;p&gt;Take the following input, for example, taken from the first line in my input file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Street Number&lt;/strong&gt;: 4&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Street Name&lt;/strong&gt;: Yawkey&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Municipality&lt;/strong&gt;: Boston&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postal Code&lt;/strong&gt;: 2215&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is, of course, the address for Fenway Park. Yet it is incomplete. After providing these fields from the input to the request for the appropriate parameters, I am met with the following JSON response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  {   
   "summary":{   
      "query":"4 02215 yawkey boston", 
      "queryType":"NON_NEAR", 
      "queryTime":42, 
      "numResults":1, 
      "offset":0, 
      "totalResults":1, 
      "fuzzyLevel":1, 
      "geoBias":{   
         "lat":42.34528579930702, 
         "lon":-71.10655 
      } 
   }, 
   "results":[   
      {   
         "type":"Point Address", 
         "id":"US/PAD/p0/2532244", 
         "score":11.1, 
         "dist":670.4458521397014, 
         "address":{   
            "streetNumber":"4", 
            "streetName":"Yawkey Way, Jersey St", 
            "municipalitySubdivision":"Boston, Fenway", 
            "municipality":"Boston, Boston University, Kenmore", 
            "countrySecondarySubdivision":"Suffolk", 
            "countryTertiarySubdivision":"Boston", 
            "countrySubdivision":"MA", 
            "postalCode":"02215", 
            "extendedPostalCode":"022159103", 
            "countryCode":"US", 
            "country":"United States Of America", 
            "countryCodeISO3":"USA", 
            "freeformAddress":"4 Yawkey Way, Boston, MA 02215", 
            "countrySubdivisionName":"Massachusetts" 
         }, 
         "position":{   
            "lat":42.34679, 
            "lon":-71.09865 
         }, 
         "viewport":{   
            "topLeftPoint":{   
               "lat":42.34769, 
               "lon":-71.09987 
            }, 
            "btmRightPoint":{   
               "lat":42.34589, 
               "lon":-71.09743 
            } 
         }, 
         "entryPoints":[   
            {   
               "type":"main", 
               "position":{   
                  "lat":42.34671, 
                  "lon":-71.09889 
               } 
            } 
         ] 
      } 
   ] 
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Due to the fact that I am only interested in saving certain fields to my output “database,” I retrieve only the position and address data located at the root level in the result array. As you can see, that provides me with full address data as well as a freeform address field, in addition to the geocoding data (latitude and longitude) for Fenway Park. I simply write this address and position data to my output file and move on to the next record in the input file. Another field that may be of interest in the geocoding realm is the entry points array provided for each result. The precise location of the main entryway is given, which could be invaluable, depending upon what one is hoping to achieve by retrieving this data.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;Unformatted address data is a common challenge. TomTom Online Search’s geocoding request feature offers an easy-to-use solution for cleaning address data and building a database of geocoded locations—and then makes it available via simple HTTP GET requests&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on developer.tomtom.com/blog. The original author is &lt;a href="https://developer.tomtom.com/blog/author/scott-fitzpatrick"&gt;Scott Fitzpatrick&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>javascript</category>
      <category>geocoding</category>
      <category>java</category>
    </item>
    <item>
      <title>Displaying Multiple Locations Using TomTom's Maps SDK</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Thu, 26 Nov 2020 15:48:40 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/displaying-multiple-locations-using-tomtom-s-maps-sdk-2aol</link>
      <guid>https://dev.to/tomtomdevs/displaying-multiple-locations-using-tomtom-s-maps-sdk-2aol</guid>
      <description>&lt;p&gt;The TomTom Maps SDK allows for location-based application development on &lt;a href="https://developer.tomtom.com/maps-sdk-web"&gt;web apps&lt;/a&gt;, &lt;a href="https://developer.tomtom.com/maps-sdk-ios"&gt;iOS&lt;/a&gt; and &lt;a href="https://developer.tomtom.com/maps-sdk-android"&gt;Android&lt;/a&gt;. It provides easy access to millions of data points collected by TomTom, maps functions for web apps, location search, and more, and is compatible with both web-based and native mobile app platforms.&lt;/p&gt;

&lt;p&gt;In this article, we walk through using the TomTom Maps SDK by exploring some ways in which its SDK API call can be leveraged to show the location of several entities on a map at once. The article also demonstrates how best to enhance map usage by leveraging additional features and API calls available on the app development portal. It also explains the process of customizing map vector style and features so that you can start building location-based apps.&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting Started
&lt;/h4&gt;

&lt;p&gt;It is both free and easy as a developer to sign up to use the TomTom API and SDK. Simply visit the &lt;a href="https://developer.tomtom.com/?utm_medium=articles&amp;amp;utm_source=premium&amp;amp;utm_campaign=ent_mapsapi_reviews-showcases_paid&amp;amp;utm_content=dm_review_fuzzy-search_2018"&gt;TomTom for Developers&lt;/a&gt; site and register by clicking the link in the top right corner of the page. The developer dashboard grants access to create new apps and API keys, and several apps can be created at once.&lt;/p&gt;

&lt;p&gt;Merely adding an application and requesting access to the Maps Display API product will prompt TomTom to provide a non-expiring API key for use with the Map Display API. Users receive 2,500 free API transactions per day to support the application and have access to free maps and traffic flow tiles when using &lt;a href="https://developer.tomtom.com/freemaps"&gt;Mobile Maps SDK&lt;/a&gt; for Android™ and iOS. (Note, if 2,500 API transactions per day is not enough, more transactions can be purchased by visiting My Credits screen in the developer dashboard.)&lt;/p&gt;

&lt;h4&gt;
  
  
  Download the Map SDK
&lt;/h4&gt;

&lt;p&gt;The TomTom Maps SDK is available for download for free on the &lt;a href="https://developer.tomtom.com/maps-sdk-web/downloads"&gt;TomTom for Developers portal&lt;/a&gt;. Unzip it and save it in the project folder.&lt;/p&gt;

&lt;h4&gt;
  
  
  Displaying a Map
&lt;/h4&gt;

&lt;p&gt;To get our feet wet with the map SDK, let’s start with something simple: Displaying a map on an application, with no particular place in the map focus. Below is the code to do this (note that you’ll first need the app to have been created on the developer portal because the API key created will be required).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var map = tomtom.L.map('map', {
    key: '&amp;lt;your-api-key&amp;gt;',
    basePath: '&amp;lt;your-tomtom-sdk-base-path&amp;gt;',
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As shown below, the script points to the path of the downloaded SDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OHCL0fzL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/h7t4h71rywgvb300xqr0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OHCL0fzL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/h7t4h71rywgvb300xqr0.png" alt="Alt Text" width="297" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every map should focus on a particular point to add more context to the map. For this example, the coordinate HQ is placed on the map.&lt;/p&gt;

&lt;p&gt;Geo coordinates can be added as an array of latitudes and longitudes. A zoom option level of 15 is also included. Here’s a sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var HQ= [9.0548, 7.4856];
var map = tomtom.L.map('map', {
    key: '&amp;lt;your-api-key&amp;gt;',
    basePath: '&amp;lt;your-tomtom-sdk-base-path&amp;gt;',
    center: HQ
    zoom: 15
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aXzV_qAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/5c6spava0hsd3z8ikdqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aXzV_qAA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/5c6spava0hsd3z8ikdqc.png" alt="Alt Text" width="273" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding a Marker to a Map
&lt;/h4&gt;

&lt;p&gt;Markers are used to indicate the location of particular coordinates on a map.TomTom provides a simple API to enable developers to add attributes to a map. The marker also helps to give more detailed information about points in pop-ups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var Hqmarker = tomtom.L.marker(HQ).addTo(map);
Hqmarker.bindPopup ("COMPANY HQ").openPopup();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F5dRcEk---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/3nnrjuxq3zwqfp8w42g5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F5dRcEk---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/3nnrjuxq3zwqfp8w42g5.png" alt="Alt Text" width="235" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The same process can be repeated to add multiple locations to a map, as you can see in the following image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1nzXfa45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/s2rdvrq7h8so7phrd4ey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1nzXfa45--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/s2rdvrq7h8so7phrd4ey.png" alt="Alt Text" width="315" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing the process, you can add more points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FTCVY-n3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/a7e1a5xkznrvevar2lc4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FTCVY-n3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/a7e1a5xkznrvevar2lc4.png" alt="Alt Text" width="332" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting Important Details
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Location and geo-coordinates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TomTom provides an API to obtain the geo-coordinates of any location. The simplest way to obtain these coordinates is through TomTom’s &lt;a href="https://developer.tomtom.com/content/search-api-explorer"&gt;API Explorer&lt;/a&gt;. The Fuzzy Search API section helps to retrieve location coordinates using the common address.&lt;/p&gt;

&lt;p&gt;Take the sample address &lt;strong&gt;2311 North Los Robles Avenue, Pasadena, California, USA&lt;/strong&gt; and place it in a query field; clear other pre-populated fields when this query is executed. The response data returns coordinates in the following format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;position&amp;gt;
    &amp;lt;lat&amp;gt;37.36729&amp;lt;/lat&amp;gt;
    &amp;lt;lon&amp;gt;-121.91595&amp;lt;/lon&amp;gt;
&amp;lt;/position&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that you should not use special HTML characters (like '$','?',&amp;amp;','#') in any address.&lt;/p&gt;

&lt;h4&gt;
  
  
  Loading Multiple Coordinates at Once
&lt;/h4&gt;

&lt;p&gt;In a production environment, it would not be practical to add every new location to a map with a new line of code. The coordinate can be added in a loop and added to the map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var companyAssets = [ [ 52.373627, 4.902642 ], [ 52.3659, 4.927198 ], [ 52.347878, 4.893488 ], [ 52.349447, 4.858433 ] ];
companyAssets.forEach (function (child) {
    tomtom.L.marker (child).addTo(map);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Dark Skin Map Display
&lt;/h4&gt;

&lt;p&gt;The default maps come in both light and dark skins. You can switch between different skins using ‘style’ in the map initialization, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; var map = tomtom.L.map ('map', {
    . . .
    center :HQ,
    style: 'night',
    . . .
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vWgVPKRB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qj0zwkjy7o8w1ceb4407.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWgVPKRB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/qj0zwkjy7o8w1ceb4407.png" alt="Alt Text" width="317" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Styling the Map
&lt;/h4&gt;

&lt;p&gt;TomTom Vector maps properties such as fill colors, line styles, thickness, etc., which are defined in an editable JSON file. (The necessary file can be downloaded &lt;a href="https://developer.tomtom.com/maps-sdk-web/functional-examples#vector-map-style-altering"&gt;here&lt;/a&gt;.) More detailed documentation on available property &lt;a href="https://www.mapbox.com/mapbox-gl-js/style-spec/"&gt;specifications&lt;/a&gt; can be found here. Rather than edit manually, generating the style using &lt;a href="https://maputnik.github.io/editor/"&gt;Maputnik editor&lt;/a&gt;, a visual map designer is an easier approach .&lt;/p&gt;

&lt;p&gt;Vector maps are made up of tiles and schema ; a tile is used to serve data on the map and the schema determines how the data is structured. The client determines how to present this data to the end-user using a style (for example, use of color and features like 2D areas, roads, ocean, and more.&lt;/p&gt;

&lt;p&gt;Using the Maputnik editor, developers can customize and view map features. (For example, you could change an ocean background to red in place of the conventional blue.)&lt;/p&gt;

&lt;h4&gt;
  
  
  Getting Started with Map Customization
&lt;/h4&gt;

&lt;p&gt;To start creating your custom style, you can download the basic main style &lt;a href="https://developer.tomtom.com/maps-sdk-web/functional-examples#vector-map-style-altering"&gt;here&lt;/a&gt;. You’ll be required to add your TomTom API key.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cCb9CiLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/4xb0pzxrq55mq3puw9zn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cCb9CiLK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/4xb0pzxrq55mq3puw9zn.png" alt="Alt Text" width="602" height="219"&gt;&lt;/a&gt;&lt;br&gt;
The first step is to upload a file containing a style definition to Maputnik. Click on the "Open" button. (Adding your API key in the initial stage can help skip several manual processes.)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HfoaytYh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/btngvpp2dd4a0vox1kgd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HfoaytYh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/btngvpp2dd4a0vox1kgd.png" alt="Alt Text" width="602" height="309"&gt;&lt;/a&gt;&lt;br&gt;
The picture above shows a customized map where the water background has been changed to black.&lt;/p&gt;

&lt;p&gt;The left-hand side of the Maputnik editor shows the map’s feature layers, with applicable customizations. You’ll also see the properties that can be customized. The right-hand side shows the live preview of the changes.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KPrRe4Ap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/ewejcxkcw3xmkf6i2oql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KPrRe4Ap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/ewejcxkcw3xmkf6i2oql.png" alt="Alt Text" width="602" height="325"&gt;&lt;/a&gt;&lt;br&gt;
At any point, the newly customized style can be exported from the editor and tested.&lt;/p&gt;

&lt;p&gt;You can test the style from &lt;a href="https://developer.tomtom.com/maps-sdk-web/functional-examples#vector-map-style-altering"&gt;here&lt;/a&gt;. Upload the modified style (click on the "Choose File" button) and view the results.&lt;/p&gt;
&lt;h4&gt;
  
  
  Putting it All Together: Real-World Mapping Example
&lt;/h4&gt;

&lt;p&gt;In production, an API endpoint may be created to return the list of coordinates for every asset owned by the company and intended to be rendered on the map.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uRp9OTqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/k4hacgrggvg2chg0xi41.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uRp9OTqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/i/k4hacgrggvg2chg0xi41.png" alt="Alt Text" width="602" height="292"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var AbujaZone = [
    {Address:"HQ",Coordinate: [9.0548, 7.4856]},
    {Address:"SUB HQ",Coordinate: [9.0600, 7.4899 ]},
    {Address:"ABUJA A",Coordinate: [9.0509, 7.4931 ]},
    {Address:"ABUJA B",Coordinate: [9.046, 7.4873 ]}
    {Address:"ABUJA C", Coordinate: [9.0530, 7.4793 ]}
    {Address:"NEW CONSTRUCTION",Coordinate:[9.0650, 7.4924 ]},
    {Address:"ABUJA E", Coordinate: [9.0650, 7.4734 ]}
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each entity returned is an object of address and coordinate. It is possible to return a more detailed object like the status of the machine or asset, opening time, etc. depending on what is required for the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AbujaZone.forEach(function (child) {
    tomtom.L.marker(child.Coordinate)
    .addTo(map)
    .bindPopup(child.Address)
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project in the screenshot switches between two different locations: Lagos and the Abuja zone. To specify the marker icon for each location, add the icon option (highlighted below) to the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LagosZone.forEach (function (child) {
    tomtom.L.marker (child.Coordinate, {
        icon: child.iconPath
    }).addTo(map)
    .bindPopup(child.Address)
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;This article has explored ways to add multiple locations to a map and customize the map view, and it has examined the use of markers and vector map feature displays. The official TomTom documentation provides a complete list of available features and options.&lt;/p&gt;

&lt;p&gt;The TomTom API offers a full location-based toolbox, with loads of features to build fully functional location-based apps, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traffic API&lt;/strong&gt;: Traffic information can be displayed via the Traffic API in different styles and flavors. Traffic Flow or Traffic Incident information can be overlaid on top of TomTom maps to visualize the congestion level, traffic jams, road work, blocked roads, closures, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maps Display API&lt;/strong&gt;: The Maps Display API enables static and interactive maps to be displayed in any mobile and/or web application. TomTom real-time map-making technology provides users with the most accurate and up-to-date maps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing API&lt;/strong&gt;: The Routing API enables planning a route from A to B, considering both historical and real-time traffic conditions. As a result, applications can provide users with highly accurate travel times and live updated travel information and route instructions for multiple transportation types, such as car, truck, bicycle, and pedestrian.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search API&lt;/strong&gt;: The Search API enables geocoding and searching for an address or place. By using fuzzy matching algorithms and auto-completion, the Search API provides an excellent query interface for interacting directly with end-users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're developing for a GPS data-based enterprise-level mobile application similar to Uber, Google Maps, Yelp, FourSquare , or Pokemon Go, or a new app in the dating, weather, social media, augmented reality, or fitness category, this can be a very useful set of tools.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on developer.tomtom.com/blog. The original author is &lt;a href="https://developer.tomtom.com/blog/author/john-odey"&gt;John Odey&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>mapping</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Last-Mile Logistics: A Developer’s Point of View</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Fri, 20 Nov 2020 04:50:43 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/last-mile-logistics-a-developer-s-point-of-view-1mb7</link>
      <guid>https://dev.to/tomtomdevs/last-mile-logistics-a-developer-s-point-of-view-1mb7</guid>
      <description>&lt;p&gt;In logistics and mobility businesses, many common mapping and routing challenges are related to the "last-mile." This refers to exactly what it sounds like: mapping and routing a delivery or transport service to its final destination. &lt;/p&gt;

&lt;p&gt;Traditionally, last-mile logistics meant two kinds of fairly simple planning: either organizing static routes that delivery trucks run through every day, stopping for a precompiled list of package drop offs, or making individual trips to deliver things like meals or prescriptions. &lt;/p&gt;

&lt;p&gt;What makes last-mile logistics complicated is that the highest concentration of last-mile deliveries occur in urban areas, where vans or other delivery vehicles have to deal with road restrictions, densely packed streets, limited parking, apartment buildings, unexpected traffic conditions, and so on. Even in suburban areas, traffic conditions can vary wildly between highly congested and free flowing on an hourly basis.&lt;/p&gt;

&lt;p&gt;Recently, last-mile logistics has become much more dynamic. The growth of e-commerce use cases — from consumer goods to food delivery to ride-share services — means last-mile logistics has become much more fluid. &lt;/p&gt;

&lt;p&gt;Since the last mile is based on the destination, it only becomes a known part of the equation when an order is placed. The fleet manager must deal with solving a much more complex problem than moving known goods from one point to many. They must be concerned with where the pickup is, the vehicle requirements, parking and delivery entrance locations — among many variables — to solve what has become a dynamic problem. &lt;/p&gt;

&lt;p&gt;On top of that, customer expectations regarding estimated time of arrival (ETA) have changed drastically. Five years ago, you were happy to place an order and know “it will come on Saturday” or "in about 30 minutes." Today, in many areas, customers have learned to expect overnight deliveries of packages. For health and safety reasons, many families have turned to grocery and meal deliveries, and want to know within a few minutes when to expect delivery.&lt;/p&gt;

&lt;p&gt;With much easier access to location technology and the ability to track drivers and packages in real time, ETAs can be accurate to within a minute. This raises customer expectations and fleet managers need to adjust their approach, taking this capability into account. &lt;/p&gt;

&lt;p&gt;These use cases and customer expectations provide an opportunity for developers to create applications that reduce fleet costs, increase customer satisfaction, and meet compliance with committed service levels. &lt;/p&gt;

&lt;p&gt;In this article, we cover the major components of last-mile logistics and the part that mapping and location management play. For example, what happens if you order lunch, or special order a book delivery?&lt;/p&gt;

&lt;h4&gt;
  
  
  Fleet Routing and Route Efficiency
&lt;/h4&gt;

&lt;p&gt;In the more complex world of the delivery and on-demand environment we must consider routing fleet vehicles to the pickup point — say, a restaurant — then to a delivery point, and then perhaps to the next pickup or delivery point in the chain, and so on. It's a constantly fluid chain of next last-mile destinations. &lt;/p&gt;

&lt;p&gt;Routing simply means finding the best path to a destination — a delivery address or rider pickup location. It's a simple solution we've all used to find directions to a destination. However, in a delivery scenario, you might have to generate routes for multiple deliveries, taking into account route efficiency and estimated time of arrival (ETA) to make sure deliveries arrive when expected. &lt;/p&gt;

&lt;p&gt;For example, consider food delivery: time from the kitchen to the customer needs to be a consideration to ensure timely delivery of hot meals. ETA lets you tell the customer when to expect delivery, so they know when to break for lunch or listen for a knock at the door.&lt;/p&gt;

&lt;p&gt;On the business planning side, another important routing consideration is how multiple stops can affect routing efficiency. For example, it’s more efficient if a food delivery service can make deliveries to several customers in a single trip.&lt;/p&gt;

&lt;h4&gt;
  
  
  Last-Mile Delivery and Accurate Geocoding
&lt;/h4&gt;

&lt;p&gt;End locations — all the stops en route — are the destinations of last-mile logistics. These are generally fixed locations that need geocoding — translating descriptions or addresses into coordinates that can be mapped. Coordinates of delivery locations — or pickup locations in the realm of ridesharing — are crucial elements of accurate routing and route planning. &lt;/p&gt;

&lt;p&gt;On-demand fleet applications need to provide the geocoded coordinates for the restaurants, the customer locations, and even the vehicles in the delivery fleet. For a third-party food delivery service, for example, these locations come in as order descriptions with customer delivery addresses. Geocoding services can automatically translate those customer addresses into map coordinates behind the scenes, creating automatic dispatching, routing, and delivery detail reports for drivers.&lt;/p&gt;

&lt;p&gt;That's how the lunch to-go service takes your lunch order, knows where to deliver it, and can provide a clear, quick route to the driver. Geocoding for last-mile delivery can also provide additional information for accurate service including nearby landmarks, parking, and delivery entrance details.&lt;/p&gt;

&lt;h4&gt;
  
  
  Geofencing for Delivery Notifications
&lt;/h4&gt;

&lt;p&gt;Another key capability for last-mile delivery applications is the ability to know when a delivery is about to happen. Location-aware applications can list delivery locations and route deliveries with estimated delivery times — also known as estimated time of arrival (ETA) — based on historical speed and traffic pattern data. &lt;/p&gt;

&lt;p&gt;Knowing exactly when a delivery is nearing its destination is valuable information. It reflects the dynamic traffic conditions of an unpredictable world for confirmation of ETA. It gives fleet managers real-time updates of delivery progress and fleet position. It also enables applications to generate alerts and notifications that let the customer know dinner is almost here.&lt;/p&gt;

&lt;p&gt;Geofencing means creating a virtual fence or boundary on a map — say for example, a boundary defining a neighborhood or a circle with a radius of 1 kilometer from a delivery destination. Geofencing technology enables applications to then fire events related to tracked objects entering or leaving a geofenced area.  &lt;/p&gt;

&lt;p&gt;A common application of geofencing is creating a fence around a destination — say 1 to 5 miles around a warehouse or the destination for a pizza delivery. When the delivery vehicle crosses the fence, an app could send an alert to the warehouse to get ready staging forklifts for unloading, shortening vehicle turnaround time. Or it could send an alert to the hungry customer that the pizza is nearby and they should get ready to answer the door.&lt;/p&gt;

&lt;p&gt;Another use case is fleet monitoring. Geofences limits the map area under consideration, turning hundreds of individual fleet vehicle or delivery locations into insights for the business like if any vehicle in the fleet are in an unsafe situation (deviated from route or entered a restricted area) or to see how many vehicles are servicing a specific area. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.tomtom.com/industries/fleet-management-logistics/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RAd8E6aP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/f0q9q6j1sgshirgbua60.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tools for Last-Mile Application Development
&lt;/h4&gt;

&lt;p&gt;To create last-mile logistics applications for parcel delivery, you'll need understand and use these services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Map display to create engaging application interfaces&lt;/li&gt;
&lt;li&gt;Search and geocoding to find coordinates of delivery locations&lt;/li&gt;
&lt;li&gt;Routing (including traffic and ETAs) for efficient transit times and for calculating the optimal route&lt;/li&gt;
&lt;li&gt;Vehicle tracking to keep an eye on your fleet&lt;/li&gt;
&lt;li&gt;Geofencing for alerts, notifications, and business insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TomTom provides easy-to-use APIs that let software developers incorporate these services into effective fleet management applications for on-demand businesses. Let's look at some of the technologies you can use to quickly build sophisticated apps.&lt;/p&gt;

&lt;p&gt;Maps may seem simple, but the effort involved in creating and maintaining a map is not. An effective map service like the TomTom &lt;a href="https://developer.tomtom.com/maps-api/maps-api-documentation"&gt;Map Display API&lt;/a&gt; and &lt;a href="https://developer.tomtom.com/maps-sdk-web-js/documentation"&gt;Maps SDKs for Web&lt;/a&gt;, &lt;a href="https://developer.tomtom.com/maps-sdk-android"&gt;Android&lt;/a&gt;, and &lt;a href="https://developer.tomtom.com/maps-sdk-ios"&gt;iOS&lt;/a&gt; make it easy to display maps in your application. With a few lines of code you can have a clear, interactive map that includes customizable styling, markers, routes, and the ability to add your own data overlays.&lt;/p&gt;

&lt;p&gt;The TomTom &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation"&gt;Search API&lt;/a&gt; provides services for location search, geocoding, reverse geocoding, and more, including features targeted for electric vehicle (EV) fleets.&lt;/p&gt;

&lt;p&gt;Search gives the user the ability to find a desination. Users can search the data underlying the geocodes to discover information including entrance location and hours of business.&lt;/p&gt;

&lt;p&gt;Routing APIs take into account not only the directions for getting to a location, they also allow you to control for variables such as time, traffic congestion, and tolls. For accuracy, routing services need to provide up-to-date data. For example, routing services provide the ETA information necessary when you have to incorporate service levels into your applications. The TomTom &lt;a href="https://developer.tomtom.com/routing-api/routing-api-documentation"&gt;Routing API&lt;/a&gt; provides capabilities for advanced routing with options for vehicle, cargo, and road types — which might be useful for cases routing larger vehicles or hazardous loads. &lt;/p&gt;

&lt;p&gt;Because on-demand and parcel delivery businesses often want to operate as nimbly as possible, real-time intelligence about current fleet positions helps every next step in the process: routing and rerouting vehicles to provide efficient service. Vehicle tracking can also help with driver safety, by revealing whether a driver was exceeding the speed limit or changing lanes erratically. &lt;/p&gt;

&lt;p&gt;Vehicle tracking has uses in both real-time and analytics applications. Developers can use the TomTom &lt;a href="https://developer.tomtom.com/location-history-api/location-history-api-documentation"&gt;Location History services&lt;/a&gt; to capture and report fleet vehicle locations over time, providing the basis for business analysis and fleet planning applications.&lt;/p&gt;

&lt;p&gt;The TomTom &lt;a href="https://developer.tomtom.com/geofencing-api/geofencing-api-documentation"&gt;Geofencing API&lt;/a&gt; lets you create geofences for use with other services such as routing, location history, or generating alerts and notifications with the &lt;a href="https://developer.tomtom.com/notifications-api/notifications-api-documentation"&gt;Notifications API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each of these functions lets application developers embed mapping functionality into their applications and improve last-mile logistics effectiveness.&lt;/p&gt;

&lt;h4&gt;
  
  
  Wrapping Up
&lt;/h4&gt;

&lt;p&gt;As you've seen here, "last-mile logistics" has always been parts of the logistics equation — it's just getting packages, groceries, meals, or any other delivery to its destination. &lt;/p&gt;

&lt;p&gt;With the increase in the number of companies offering delivery services, from one-day-fulfillment to grocery delivery to ride services, the ability to optimize costs, increase customer satisfaction, and meet compliance with committed service levels is important to business success. &lt;/p&gt;

&lt;p&gt;TomTom provides APIs that connect application developers to the services they need to tackle all the details of last-mile delivery efficiency in real time — from routing that takes into account speed and traffic, to accurate ETAs, to notifications, to details like entrance location.  &lt;/p&gt;

&lt;p&gt;Next time you order a lunch delivery, consider all of the last-mile delivery technologies we've discussed that make it possible to get from order to hot meal — from geocoding your address, to giving the driver an efficient route, to getting your lunch hot and on time. &lt;/p&gt;

&lt;p&gt;For more information, visit &lt;a href="https://developer.tomtom.com/"&gt;https://developer.tomtom.com/&lt;/a&gt; and register for your free access.&lt;/p&gt;

&lt;h3&gt;
  
  
  To read more about TomTom solutions for fleet management, check out this related article: &lt;a href="https://developer.tomtom.com/blog/build-different/using-tomtom-location-services-develop-fleet-logistics-applications"&gt;Using TomTom Location Services to Develop Fleet Logistics Applications&lt;/a&gt;.
&lt;/h3&gt;

&lt;p&gt;Happy mapping!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on &lt;a href="https://developer.tomtom.com/blog"&gt;https://developer.tomtom.com/blog&lt;/a&gt;. The original author is &lt;a href="https://developer.tomtom.com/blog/author/julija-babre"&gt;Julija Babre&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mapping</category>
      <category>fleemanagement</category>
      <category>geocoding</category>
      <category>geofencing</category>
    </item>
    <item>
      <title>Autocomplete and Suggestions with the Search API</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Wed, 18 Nov 2020 05:26:31 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/autocomplete-and-suggestions-with-the-search-api-232k</link>
      <guid>https://dev.to/tomtomdevs/autocomplete-and-suggestions-with-the-search-api-232k</guid>
      <description>&lt;h4&gt;
  
  
  Autocomplete and Suggestion With The Seacrch API
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3rtV6uf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0gvu1e0qv84oznaazryc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3rtV6uf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0gvu1e0qv84oznaazryc.png" alt="Alt Text" width="880" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We previously discussed the TomTom Search API a bit with our previous article, &lt;a href="https://developer.tomtom.com/blog/decoded/understanding-fuzzy-search"&gt;Understanding Fuzzy Search&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today we are going to dive a little bit deeper and discuss our &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation/autocomplete"&gt;Search Autocomplete API&lt;/a&gt;, a feature that allows you provide more meaningful results to your users without the need to track them.*&lt;/p&gt;

&lt;p&gt;The autocomplete endpoint complements the ‘type ahead’ parameter in the Fuzzy search by providing related categories that the user might be looking for. Let’s review the explanation of this parameter from the documentation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sS_Wtavq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8yci96hbmc2tn7a34gux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sS_Wtavq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8yci96hbmc2tn7a34gux.png" alt="Alt Text" width="880" height="92"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And when the search enters in Predictive Mode it provides also more matching results.&lt;/p&gt;

&lt;h4&gt;
  
  
  First, the Technical Aspects of the API
&lt;/h4&gt;

&lt;p&gt;The documentation for this endpoint can be found in the developer portal: &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation/autocomplete"&gt;https://developer.tomtom.com/search-api/search-api-documentation/autocomplete&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;This REST API Call uses HTTPS-GET and has minimum parameters: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zz6rHRuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cd8xovjrbt2vulafba3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zz6rHRuu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/cd8xovjrbt2vulafba3w.png" alt="Screen Shot 2020-11-17 at 8.53.36 PM" width="822" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we start looking for wine stores.  So, I start typing “wine”, and at the 4th character we decide to provide some suggestions. Since I am in Madrid, a sample call will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.tomtom.com/search/2/autocomplete/wine.json?key=&amp;lt;Your_API_Key&amp;gt;&amp;amp;language=en-GB&amp;amp;lat=40.41687&amp;amp;lon=3.70356 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding my private API key with the call, I get these results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "context": {
    "inputQuery": "wine",
    "geoBias": {
      "position": {
        "lat": 40.41687,
        "lon": 3.70356
      }
    }
  },
  "results": [
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine &amp;amp; Spirits",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9361025",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
{
      "segments": [
        {
          "type": "category",
          "value": "Wine Bar",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9379007",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
    {
      "segments": [
        {
          "type": "category",
          "value": "Winery",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "7349",
          "matchedAlternativeName": "Wine"
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s examine the results: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I see 3 sections. &lt;/li&gt;
&lt;li&gt;All of them are of the type “category”.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;According to the documentation, we can get 3 different types of results: Brands, Categories and Plaintext. &lt;/p&gt;

&lt;p&gt;For example, if we search for the term “jim” - assuming this refers to several brands, we can observe:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.tomtom.com/search/2/autocomplete/jim.json?key=&amp;lt;API KEY&amp;gt;&amp;amp;language=en-GB&amp;amp;limit=10 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "context": {
    "inputQuery": "jim"
  },
  "results": [
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jim Thompson",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Pizza",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy John's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
{
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Chung's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Choo",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several brands represented here based on our input; if we keep typing and we make a following query with “jimm”, we see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "context": {
    "inputQuery": "jimm"
  },
  "results": [
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Pizza",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy John's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Chung's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
{
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Choo",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Killer Prawns",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the brand “Jim Thompson” is gone from the list after tacking on more of the letter “m”, and we have a new “Jimmy’s Killer Prawns” brand name. &lt;/p&gt;

&lt;p&gt;Returning to our original query (wine), as specified in the documentation, I get only 5 results by default. I think I am going to need more than that for my users, so maybe I'll try 10 next time. &lt;/p&gt;

&lt;p&gt;Getting back to my first attempt, I already added some optional parameters (Lat and Long of most central place in Madrid: La Puerta del Sol). Next, we will go through some optional parameters. &lt;/p&gt;

&lt;h4&gt;
  
  
  Optional Parameters
&lt;/h4&gt;

&lt;p&gt;Let’s take a look at the optional parameters: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BXjEOGtX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r3u8vxyi9zc25a0jrvw3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BXjEOGtX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/r3u8vxyi9zc25a0jrvw3.png" alt="Screen Shot 2020-11-17 at 9.04.07 PM" width="808" height="402"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;So, let’s see what we get if we exchange the location area for the country (ES=Spain) and add a limit of 10 results. &lt;/p&gt;

&lt;p&gt;My new URL looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://api.tomtom.com/search/2/autocomplete/wine.json?key=&amp;lt;API_KEY&amp;gt;&amp;amp;language=en-GB&amp;amp;countrySet=ES&amp;amp;limit=10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this time I get the following result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "context": {
    "inputQuery": "wine"
  },
  "results": [
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine Bar",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9379007",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine &amp;amp; Spirits",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9361025",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
{
      "segments": [
        {
          "type": "category",
          "value": "Winery",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "7349",
          "matchedAlternativeName": "Wine"
        }
      ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And… it is exactly the same as before!  At least I see consistency. (These categories are in the DataBase for Spain.) With these 3 categories, I can present them to the user and if any of those are selected, we can take the “id” provided in the Segment and perform a normal POI category search. In this case I see that the category “&lt;code&gt;Wine &amp;amp; Spirits&lt;/code&gt;" is the closest to what I want. &lt;/p&gt;

&lt;p&gt;I’ll make a quick category search and see what I get. &lt;/p&gt;

&lt;p&gt;We’ll use the POI search documentation here: &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation-search/category-search"&gt;https://developer.tomtom.com/search-api/search-api-documentation-search/category-search&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This time we are going to use the [lat, lon] for “Puerta del Sol” as a Bias guideline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https:// https://api.tomtom.com/search/2/categorySearch/.json?key=&amp;lt;API_KEY&amp;gt;&amp;amp;lat=40.41687&amp;amp;lon=-3.70356&amp;amp;categorySet=9361025 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we check the results, let’s examine this URL closely: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I didn’t pass any text in the query: I want all possible POIs in this category and close to this location. &lt;/li&gt;
&lt;li&gt;The Category is added in the optional parameter “categorySet” &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now this REST API Call gave some interesting results, and since it returns a minimum of 10, is good enough to present to the user. &lt;/p&gt;

&lt;p&gt;Let’s see the first item in the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "type": "POI",
  "id": "ES/POI/p0/1486801",
  "score": 1.21439,
  "dist": 295.90900560698543,
  "info": "search:ta:724009006287107-ES",
  "poi": {
    "name": "David Borda Juan Oscar",
    "categorySet": [
      {
        "id": 9361025
      }
    ],
    "categories": [
      "food drinks: wine spirits",
      "shop"
    ],
    "classifications": [
      {
        "code": "SHOP",
        "names": [
          {
            "nameLocale": "en-US",
            "name": "food drinks: wine spirits"
          },
          {
            "nameLocale": "en-US",
            "name": "shop"
          }
        ]
      }
    ]
  },
  "address": {
    "streetNumber": "9",
    "streetName": "Calle del Príncipe",
    "municipalitySubdivision": "Madrid",
    "municipality": "Madrid",
    "countrySecondarySubdivision": "Madrid",
    "countrySubdivision": "Comunidad de Madrid",
    "postalCode": "28012",
    "countryCode": "ES",
    "country": "España",
    "countryCodeISO3": "ESP",
    "freeformAddress": "Calle del Príncipe 9, 28012 Madrid",
    "localName": "Madrid"
  },
  "position": {
    "lat": 40.41593,
    "lon": -3.70029
  },
  "viewport": {
    "topLeftPoint": {
      "lat": 40.41683,
      "lon": -3.70147
    },
    "btmRightPoint": {
      "lat": 40.41503,
      "lon": -3.69911
    }
  },
  "entryPoints": [
    {
      "type": "main",
      "position": {
        "lat": 40.41593,
        "lon": -3.70035
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see there is a wealth of information related to this POI (Point of Interest), but point your attention to the the field named “categories”. This is an array of assigned categories that this Place relates to. If I can present this to the user, he or she can refine the autocomplete search to be improved in the future.&lt;/p&gt;

&lt;h4&gt;
  
  
  End Notes
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation/autocomplete"&gt;Autocomplete feature in the TomTom Search&lt;/a&gt; is an extremely valuable addition to the rest of our APIs. We saw in this small example how easy it can be to provide continuous search results to your application, so that the user can narrow their focus and get more specific results.  &lt;/p&gt;

&lt;p&gt;Check out the many possibilities in our developer portal: developer.tomtom.com and don’t forget to add questions and comments in our forum: devforum.tomtom.com. &lt;/p&gt;

&lt;p&gt;Happy mapping… and searching! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;*Note&lt;/strong&gt;: Privacy protection is paramount for TomTom, and all APIs available in the developer portal (developer.tomtom.com) keep this policy so your users can be reassured that all data collected is only to make our APIs better (and with your consent), and only out of necessity to perform the actions you require in your application.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on &lt;a href="https://developer.tomtom.com/blog"&gt;https://developer.tomtom.com/blog&lt;/a&gt;. The original author is &lt;a href="https://developer.tomtom.com/blog/author/magdalena-korczynska"&gt;Magdalena Korczynska&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>mapping</category>
      <category>autocomplete</category>
      <category>devops</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Responsive Location Search Component with a React Search Box</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Sat, 14 Nov 2020 22:54:17 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/building-a-responsive-location-search-component-with-a-react-search-box-4p0f</link>
      <guid>https://dev.to/tomtomdevs/building-a-responsive-location-search-component-with-a-react-search-box-4p0f</guid>
      <description>&lt;h4&gt;
  
  
  Introduction: Using React &amp;amp; Mobile-First
&lt;/h4&gt;

&lt;p&gt;Modern web standards allow developers to deliver location-aware features to users based on device GPS or network information. This information could be useful on its own — but, when combined with a mapping service, this information enables many additional interesting features.&lt;/p&gt;

&lt;p&gt;This tutorial will describe how to build a responsive web application with a point of interest (POI) location search feature using the React web framework and the TomTom Search API.&lt;/p&gt;

&lt;p&gt;We’ll use a mobile-first design approach. We can use the Chrome DevTools device toolbar to target different devices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7zhNwxsZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yno20ld6ilwtjg4e9x4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7zhNwxsZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/yno20ld6ilwtjg4e9x4g.png" alt="Alt Text" width="252" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I usually choose an iPhone 5 because this model uses one of the smallest screens. If our design looks good there, it usually scales up well on larger devices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZVPYwU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ad12iv1uuuai2bu1db0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZVPYwU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ad12iv1uuuai2bu1db0.png" alt="Alt Text" width="436" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A demo of the final product is shown below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZVPYwU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ad12iv1uuuai2bu1db0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZVPYwU---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6ad12iv1uuuai2bu1db0.png" alt="Alt Text" width="436" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Why React?
&lt;/h4&gt;

&lt;p&gt;React is a popular JavaScript library for building user interfaces (UIs). It’s distinguished from other UI frameworks by the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Declarative&lt;/strong&gt; — React allows you to describe what your UI should look like instead of how to construct it. This can make React code easier to understand and debug. This is accomplished using a “reactive” system which automatically updates the UI as data changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component-based&lt;/strong&gt; — The basic building block of a React UI is a component. Traditional UI code separates the presentation (HTML) and business logic (JavaScript). React mixes the presentation and business logic in favor of a separation of concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The TomTom location APIs provide easy-to-use services for mapping, geolocation, routing and navigation, and more. This data can benefit a wide variety of applications. We’ll be using the TomTom Search API, which allows us to search a location for nearby POIs including restaurants, retail stores, bars, and so on.&lt;/p&gt;

&lt;p&gt;You can go to &lt;a href="https://developer.tomtom.com/"&gt;https://developer.tomtom.com/&lt;/a&gt; to create an account and obtain an API key. That’s all you will need to follow along.&lt;/p&gt;

&lt;p&gt;We’ll use the popular &lt;a href="https://ghoshnirmalya.github.io/react-search-box/"&gt;react-search-box&lt;/a&gt; component to implement an autocomplete POI search. This will display a collection of changing suggestions as the user types in the search box. The autocomplete suggestions will be populated by the TomTom Search API. This allows the user to query local places and pick from a list of relevant suggestions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Building the App
&lt;/h4&gt;

&lt;p&gt;The goal is to build a React Single Page Application (SPA), so we’ll be using HTML, CSS, and JavaScript as the basic building blocks. The app will also use JSX, React’s syntax extension to JavaScript, to mix HTML templates with JavaScript code.&lt;/p&gt;

&lt;p&gt;Building the app consists of the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaffold a blank application using Create React App&lt;/li&gt;
&lt;li&gt;Obtain, store, and display the user’s GPS coordinates using a Banner component&lt;/li&gt;
&lt;li&gt;Create a PlaceFinder service to query the TomTom Search API&lt;/li&gt;
&lt;li&gt;Configure the react-search-box to use the TomTom suggestions&lt;/li&gt;
&lt;li&gt;Create a Place component to display details of the selected place&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start by using Create React App to scaffold the application. This is an officially-supported Command Line Interface (CLI) tool to create new React applications. You’ll need to install the latest version of Node.js if you don’t have it. Then run the following command in your terminal to scaffold the application in a new folder called poi-app. These commands should work in bash or PowerShell, but you may need to modify them for your terminal of choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app poi-app # Create new react app in new poi-app folder
cd poi-app # Change directory to new app
npm install react-search-box --save # Add react-search-box'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the app using the NPM “start” script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that the default React application is up and running, we can start to make it our own.&lt;/p&gt;

&lt;p&gt;First build the GPS banner. We can obtain the user’s GPS coordinates using the TomTom Geolocation API. This should be done right at the beginning, as our app cannot do anything without the user’s coordinates. &lt;/p&gt;

&lt;p&gt;The componentDidMount() component lifecycle method is a good place for this. It is called immediately after the component is inserted into the DOM. Here’s the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;componentDidMount() {
  navigator.geolocation.getCurrentPosition((e) =&amp;gt; {
    this.setState({ 
      geoLocation: e.coords
    });
  }, async (err) =&amp;gt; {
    this.setState({
      geoError: err
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result and the error are stored in the App component state. Here’s the full component at this point:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class App extends Component {

  constructor(props) {
    super(props);
    this.state = {
      geoLocation: {},
      geoError: null
    };
  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition((e) =&amp;gt; {
      this.setState({ 
        geoLocation: e.coords
      });
    }, async (err) =&amp;gt; {
      this.setState({
        geoError: err
      });
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To display this data, we’ll create a Banner component. If the user grants GPS permission, it will display the user’s GPS coordinates. If permission is denied, it will display the error message to the user. Here is the Banner component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class Banner extends Component {
    render() {
        if (this.props.geoError) {
            return &amp;lt;p className="banner warn"&amp;gt;{this.props.geoError.message}&amp;lt;/p&amp;gt;;
        } else if (this.props.geoLocation.latitude) {
        return &amp;lt;p className="banner success"&amp;gt;
            Lat: &amp;lt;strong&amp;gt;{this.props.geoLocation.latitude.toFixed(4)}&amp;lt;/strong&amp;gt;, 
            Long: &amp;lt;strong&amp;gt;{this.props.geoLocation.longitude.toFixed(4)}&amp;lt;/strong&amp;gt;
        &amp;lt;/p&amp;gt;;
        } else {
            return null
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we will render the Banner component in the App’s render() function, passing in the geoLocation and the geoError as props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;render() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Banner
        geoLocation={this.state.geoLocation}
        geoError={this.state.geoError}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a reactive diagram of the GPS banner feature. Adding diagrams is an important part of building more serious projects, helping you think through steps at a more component-based level. As we go along, we’ll update this diagram to include the different features we continue to add.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--X6nC9TIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oempz4lpg1e7x488yk0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--X6nC9TIE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oempz4lpg1e7x488yk0a.png" alt="Alt Text" width="795" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a demo of the banner behavior when granting GPS permissions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7pl5aEQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oi42datwkh46iaag5106.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7pl5aEQs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/oi42datwkh46iaag5106.gif" alt="Alt Text" width="441" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And when denying GPS permissions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jO99fwpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mhtmv9n58zi0nzdojlq1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jO99fwpG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/mhtmv9n58zi0nzdojlq1.gif" alt="Alt Text" width="880" height="954"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  TomTom Search API
&lt;/h4&gt;

&lt;p&gt;Next we create a &lt;code&gt;PlaceFinder&lt;/code&gt; service to obtain place suggestions using the &lt;a href="https://developer.tomtom.com/search-api/search-api-documentation-search/points-interest-search"&gt;Points of Interest Search endpoint&lt;/a&gt; of the TomTom Search API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class PlaceFinder {
    constructor(apiKey) {
        this.apiKey = apiKey;
    }

    async getNearbyPlaces(query, lat, long, limit = 5, radius = 10000) {
        let baseUrl = 'https://api.tomtom.com/search/2/poiSearch';
        let queryString = `limit=${limit}&amp;amp;lat=${lat}&amp;amp;lon=${long}&amp;amp;radius=${radius}&amp;amp;key=${this.apiKey}`;
        let response = await axios.get(`${baseUrl}/${query}.json?${queryString}`);
        return response.data.results;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API key is passed into the constructor of the class to be used in all subsequent API calls.&lt;/p&gt;

&lt;p&gt;The PlaceFinder service accepts a query which will be the input the user types in. It also accepts the GPS latitude and longitude to narrow POIs down to ones that are nearby. It further accepts optional limit and radius parameters, which are defaulted to 5 and 10000 respectively. The radius is measured in meters.&lt;/p&gt;

&lt;p&gt;The Search API returns details about the POI like the name, website, phone number, address, and GPS coordinates.&lt;/p&gt;

&lt;h4&gt;
  
  
  The React-Search-Box Component
&lt;/h4&gt;

&lt;p&gt;The react-search-box component implements autocomplete functionality for us. All we have to do is feed the query from the search box into the &lt;code&gt;getNearbyPlaces&lt;/code&gt; method and populate the suggestions with the results.&lt;/p&gt;

&lt;p&gt;Here are the relevant parts of the App component with the react-search-box added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async onSearchChange(query) {
  if (query.length &amp;gt; 0) {
    let placeFinder = new PlaceFinder('YOUR_API_KEY');
    let results = (await placeFinder.getNearbyPlaces(query, this.state.geoLocation.latitude, this.state.geoLocation.longitude));
    this.setState({
      searchResults: results
    });
  }
}

render() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Banner
        geoLocation={this.state.geoLocation}
        geoError={this.state.geoError}
      /&amp;gt;

      &amp;lt;ReactSearchBox
        placeholder="Search for nearby places"
        matchedRecords={this.state.searchResults
          .map(result =&amp;gt; ({
            key: result.id,
            name: result.poi.name,
            dist: result.dist,
            value: `${result.poi.name} | ${(result.dist / 1000).toFixed(2)}km `
          }))
          .sort((a, b) =&amp;gt; a.dist - b.dist)
        }
        data={this.state.searchResults
          .map(result =&amp;gt; ({
            key: result.id,
            name: result.poi.name,
            dist: result.dist,
            value: result.poi.name
          }))
          .sort((a, b) =&amp;gt; a.dist - b.dist)
        }
        onSelect={(place) =&amp;gt; console.log(place)}
        autoFocus={true}
        onChange={(query) =&amp;gt; this.onSearchChange(query)}
        fuseConfigs={{
          minMatchCharLength: 0,
          threshold: 1,
          distance: 100000,
          sort: false
        }}
        keys = {['name']}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the updated diagram with the react-search-box added:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U3njfcD7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/peh13rgg85a144owpobk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U3njfcD7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/peh13rgg85a144owpobk.png" alt="Alt Text" width="867" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Displaying Place Details
&lt;/h4&gt;

&lt;p&gt;Finally, we can display more details for a POI when the user selects it from the react-search-box. We add a &lt;code&gt;selectedPlace&lt;/code&gt; property to the state object and set it in the react-search-box’s &lt;code&gt;onSelect()&lt;/code&gt; event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;setPlace(key) {
  let place = this.state.searchResults.find((p) =&amp;gt; p.id === key);
  this.setState({
    selectedPlace: place
  })
}

render() {
  return (
    &amp;lt;div&amp;gt;
      ...
      &amp;lt;ReactSearchBox
        ...
        onSelect={(place) =&amp;gt; this.setPlace(place.key)}
        ...
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we need to display the details of the selectedPlace. For this we add a &lt;code&gt;Place&lt;/code&gt; component that accepts the POI data from the TomTom API as a prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class Place extends Component {
  render() {
    if (this.props.data) {
      return (
        &amp;lt;div className={this.props.className}&amp;gt;
          &amp;lt;h1&amp;gt;{this.props.data.poi.name}&amp;lt;/h1&amp;gt;
          &amp;lt;h3&amp;gt;{this.props.data.poi.classifications[0].code} | {(this.props.data.dist / 1000).toFixed(2)}km away&amp;lt;/h3&amp;gt;
          &amp;lt;p&amp;gt;
            {this.props.data.address.streetNumber 
            +  ' '
            + this.props.data.address.streetName}
            &amp;lt;br/&amp;gt;
            {this.props.data.address.municipality 
            + ', ' + this.props.data.address.countrySubdivision
            + ' ' + this.props.data.address.postalCode}
          &amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
      );
    } else {
      return null;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we add the Place component to the end of the App component’s render function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;Place
  className="place-box"
  data={this.state.selectedPlace}&amp;gt;
&amp;lt;/Place&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the final diagram showing the application with all components.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oTmdO3UI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8lpzz5jx3pghw91qi9r3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oTmdO3UI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8lpzz5jx3pghw91qi9r3.png" alt="Alt Text" width="880" height="577"&gt;&lt;/a&gt;&lt;br&gt;
After a little CSS magic (the stylesheet can be found in the linked repository), here’s what we have.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7UcxkDtC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1u6do01dd75pv28td61d.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7UcxkDtC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/1u6do01dd75pv28td61d.gif" alt="Alt Text" width="441" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Where to Next?
&lt;/h4&gt;

&lt;p&gt;Let’s recap our accomplishments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We took advantage of the GeoLocation API to determine the user’s GPS location.&lt;/li&gt;
&lt;li&gt;We obtained nearby places using TomTom’s Search API.&lt;/li&gt;
&lt;li&gt;We used React to build a simple application leveraging a popular autocomplete search box component and our own custom components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From here we could continue adding functionality depending on our goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use additional APIs to obtain traffic or routing information from the user’s location.&lt;/li&gt;
&lt;li&gt;Use mappings services to render the select POI on a map. &lt;/li&gt;
&lt;li&gt;Integrate with online menus or delivery services to display additional information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, we called the Search API directly here. &lt;a href="https://developer.tomtom.com/maps-sdk-web-js/documentation"&gt;The TomTom Maps SDK for Web&lt;/a&gt; lets you easily add maps to your app and has built in helper functions for accessing TomTom location API services.&lt;/p&gt;

&lt;p&gt;Using location data and thinking spatially allows developers to engage the user in new and exciting ways. The possibilities are endless and you’re off to a good start!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on &lt;a href="https://developer.tomtom.com/blog"&gt;https://developer.tomtom.com/blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mapping</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>October Content Roundup</title>
      <dc:creator>BT</dc:creator>
      <pubDate>Thu, 12 Nov 2020 21:30:05 +0000</pubDate>
      <link>https://dev.to/tomtomdevs/october-content-roundup-107h</link>
      <guid>https://dev.to/tomtomdevs/october-content-roundup-107h</guid>
      <description>&lt;h1&gt;
  
  
  Blogs
&lt;/h1&gt;

&lt;p&gt;Dive deeper into TomTom’s tools and features for fleet management applications. In this month’s blogs, learn about last-mile logistics for developers, fleet tracking, and how TomTom’s API and SDK features developers can be used to build fleet management apps. If you’re more interested in developing a side project, check out our tutorials on building a real-time transit map or displaying TomTom maps with Flutter.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://developer.tomtom.com/blog/build-different/using-tomtom-location-services-develop-fleet-logistics-applications"&gt;Using TomTom Location Services to Develop Fleet Logistics Applications&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;TomTom mapping and routing APIs and the TomTom Maps SDK have many useful features for developers building fleet management and logistics applications. In this article, we'll highlight the API and SDK features you can use to build these apps.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://developer.tomtom.com/blog/build-different/real-time-bart-commute-mapping-part-2-building-web-map-0"&gt;Real-Time Bart Commute Mapping, Part 2: Building a Web Map&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;In a previous article we saw how Bay Area Rapid Transit (BART) supplied transit information to applications through APIs and General Transit Feed Specification Real-Time (GTFS-RT) data to grab station locations and train Estimated Time of Departure (ETD) data and use the TomTom Maps SDK to create a real-time commute map.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://developer.tomtom.com/blog/build-different/displaying-tomtom-maps-flutter"&gt;Displaying TomTom Maps With Flutter&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;In the last few years, Flutter has become one of the most popular cross-platform frameworks in the world. We’ve created a simple map application which uses an open source flutter plugin that implements the JavaScript Leaflet library functionalities and allows users to display a raster map from multiple providers inside the flutter screen.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i-dDAWks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8hmrun22k05fyvjjjvd9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i-dDAWks--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8hmrun22k05fyvjjjvd9.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://dev.tofile:///blog/decoded/last-mile-logistics-developer%E2%80%99s-point-view"&gt;Last-Mile Logistics: A Developer's Point of View&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Last-mile logistics refers to the transfer of a product or person from a hub to its final destination. In this article, we'll examine key aspects of last-mile fleet scenarios and how TomTom location services can help you build last-mile logistics applications.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://developer.tomtom.com/blog/decoded/what-fleet-tracking"&gt;What is Fleet Tracking?&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Knowing where each vehicle is at any given time can assist with fleet scheduling, route optimization, and fuel consumption management. Learn how TomTom helps build fleet management solutions by providing location and routing information to developers through easy-to-use APIs.&lt;/p&gt;
&lt;h1&gt;
  
  
  Youtube Videos
&lt;/h1&gt;
&lt;h4&gt;
  
  
  &lt;a href="https://youtu.be/V52GqpMalvk"&gt;Introduction to TomTom Maps APIs&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;In this video, get an overview of our suite of mapping tools, including map styling, directions, places, traffic, tracking, and our SDKs.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/V52GqpMalvk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Twitch Devisodes
&lt;/h1&gt;

&lt;h4&gt;
  
  
  Devisode 9 - &lt;a href="https://www.twitch.tv/videos/762459720"&gt;EV Routing&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;In this video, Jose and Olivia explore the different Routing API options specifically for Electric Vehicles, how to calculate the Electric Consumption, and how to fetch Charging Stations POIs along the route.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/sKQXS4srvOg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Devisode 10 - &lt;a href="https://www.twitch.tv/videos/776380337"&gt;Introducing the Notifications API&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Using the Notifications API, our dev advocates do a complete walkthrough on how you can easily set up real-time location updates using webhooks - and recap how to customize notifications with the help of Postman, and our geofences creator.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitch.tv/tomtomdevs"&gt;Follow TomTom Developers on Twitch&lt;/a&gt; to make sure you never miss a future livestream!&lt;/p&gt;

&lt;h1&gt;
  
  
  Events
&lt;/h1&gt;

&lt;h4&gt;
  
  
  ESRI SIG France
&lt;/h4&gt;

&lt;p&gt;TomTom returned to ESRI SIG France as a level 2 partner and highlighted our presence with a presentation by Louis Debatte-Monroy, Head of Product Marketing, on “&lt;em&gt;&lt;a href="https://sig2020.esrifrance.fr/programme/5f6b250fe25df4001928a1ab"&gt;Calculating precise journey times, in real time and in the future&lt;/a&gt;&lt;/em&gt;”.&lt;/p&gt;

&lt;h4&gt;
  
  
  IV Dutch-Russian Forum on Logistics
&lt;/h4&gt;

&lt;p&gt;Product Marketing Manager Anna Borbotko gave a talk on predictive technologies for smart logistics.&lt;/p&gt;

&lt;h4&gt;
  
  
  Post &amp;amp; Parcel Live
&lt;/h4&gt;

&lt;p&gt;At &lt;a href="https://www.postandparcel.live/"&gt;Post &amp;amp; Parcel Live&lt;/a&gt;, Fleets &amp;amp; Logistics Product Marketing Manager Julija Babre shared the secrets behind accurate travel time calculation, including best practices, pitfalls and available location technologies in a talk titled, "The Magic Formula Behind On-Time Deliveries”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://download.tomtom.com/open/banners/Fleets-and-Logistics-brochure.pdf"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GvsO3edl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/bfwxy36u1r49abntjqbk.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to connect with us in the &lt;a href="https://devforum.tomtom.com/"&gt;Forum&lt;/a&gt; and share what you’ve been working on, and follow us on &lt;a href="https://twitter.com/TomTomDevs"&gt;Twitter&lt;/a&gt;, &lt;a href="http://twitch.tv/tomtomdevs"&gt;Twitch&lt;/a&gt;, and &lt;a href="https://www.youtube.com/channel/UCL-ZtGd70Khd_9OJACd6rXA/videos"&gt;YouTube&lt;/a&gt; to see what’s coming up next in November.&lt;/p&gt;

&lt;p&gt;Happy mapping!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared on &lt;a href="https://developer.tomtom.com/blog"&gt;https://developer.tomtom.com/blog&lt;/a&gt;. The original author is &lt;a href="https://developer.tomtom.com/blog/author/ruanna-owens"&gt;Ruanna Owens&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mapping</category>
      <category>fleettracking</category>
      <category>webdev</category>
      <category>evrouting</category>
    </item>
  </channel>
</rss>
