Use searchMarkersManager to Add Custom Markers to a Map
Tags: javascript, tutorial, webdev, maps
Published: 2020-08-21 22:43:32

The TomTom Maps SDK for Web provides great default search results on a map display. But if you want to have more manual control over which markers are displayed and what they look like, use searchMarkersManager.

Maps and markers, markers and maps. They're the basic building blocks of so many location-based apps. The TomTom Maps SDK for Web provides great default search results on a map display. But if you want to have more manual control over which markers are displayed and what they look like, use the searchMarkersManagerJavaScript snippet provided with the Maps SDK for Web samples. You can see it in action in the [geocoding and search functional example](https://developer.tomtom.com/maps-sdk-web-js/functional-examples#examples,code,search.html).

In this article we'll explain what customizations you can make to marker displays and walk through an example using searchMarkersManager, a helpful class that exists in the [TomTom Maps SDK Examples code download package](https://developer.tomtom.com/maps-sdk-web-js/downloads).

The examples not only show what’s possible with the Maps SDK — they also contain lots of useful code that you can repurpose in your own project. Specifically, the searchMarkersManager function available from the /assets/js/search-markers/search-markers-manager.js file makes it easy to draw, organize, and style large numbers of search markers as a unit.

Everything in this tutorial can be accomplished using the default SDK functionality, such as styling or controlling the display of the markers and adding entry locations for each element on the map. If you’re interested, there are [other tutorials](https://developer.tomtom.com/maps-sdk-web-js/tutorials-use-cases/map-marker-tutorial) that demonstrate these capabilities.

searchMarkersManager is an optional JavaScript snippet that provides convenience wrappers for adding markers to a map (creating new layers if needed), customizing rendered markers, providing CSS for custom marker and popup styles, and fetching and displaying entry points for map locations.

Think of it as a “cheat code” for working effectively with markers. It handles the low-level marker manipulation and lets you think about the bigger picture. For example, rather than manually going through an array of markers and both drawing and adding styling to each one individually, you can just pass the array and styles to searchMarkersManager and it will take care of the details. It simplifies tasks you'd otherwise have to compose separately as simple method calls with options.

In this article we’ll cover:

* Displaying multiple markers with the searchMarkersManager function.
* Querying locations with the Category Search service.
* Using code samples from the TomTom Maps SDK for Web in your own projects.

We’re going to use the TomTom Maps SDK for Web, for which you’ll need an API key. If you don’t already have one, you can register on the [TomTom Developer Portal](https://developer.tomtom.com/). We’ll be accessing the SDK by loading it directly into the browser from the CDN when the page loads. This is the recommended approach, as it guarantees you’re using the most up-to-date version.

When it’s time to get the example code, you can [download the files from Github](https://github.com/tomtom-international/maps-sdk-for-web-examples) or the download page on TomTom's [website](https://developer.tomtom.com/maps-sdk-web-js/downloads). The download includes search-markers-manager.js, as noted earlier, as well as the source code and CSS for all of the other functional examples on the TomTom developer site.

Because this code lives in a repository, and isn’t part of the SDK, it needs to be included as part of the source deployment of your app. 

##Starting with a Blank Map

Before starting with search markers, you’ll need to create a blank vector map. If you need a refresher, TomTom has a [tutorial explaining how to create a blank map](https://developer.tomtom.com/maps-sdk-web-js/tutorials-basic/display-vector-map).

You should see a very zoomed-out map of Earth.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l7igdbxxrczxqnl0dao2.png)

Now we need to add a few dependencies to help us get the list of coffee shops and display them properly. To do so, we’ll add two new code blocks to our example:

```javascript
<!DOCTYPE html>

<html class="use-all-space">

  <head>

      <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

      <meta charset="UTF-8" />

      <title>LA Coffee Map</title>

      <meta

      name="viewport"

      content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"

      />

      <!-- Replace version in the URL with desired library version -->

      <!-- NEW CODE BLOCK 1-->    

      <link rel="stylesheet" type="text/css" href="assets/css/index.css" />

      <link

      rel="stylesheet"

      type="text/css"

      href="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/<version>/maps/maps.css"

      />

      <link

      rel="stylesheet"

      type="text/css"

      href="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/<version>/maps/css-styles/poi.css"

      />

      <!-- END NEW CODE BLOCK 1 -->

      <style>

      #map {

      width: 100vw;

      height: 100vh;

      }

      </style>

  </head>

  <body>

      <div id="map" class="map"></div>

      <!-- Replace version in the URL with desired library version -->

      <!-- NEW CODE BLOCK 2 -->

      <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/<version>/maps/maps-web.min.js"></script>

      <script src="https://api.tomtom.com/maps-sdk-for-web/cdn/5.x/<version>/services/services-web.min.js"></script>

      <script

      data-showable

      type="text/javascript"

      src="assets/js/search-marker.js"

      ></script>

      <script

      data-showable

      type="text/javascript"

      src="assets/js/search-markers-manager.js"

      ></script>

      <!-- END NEW CODE BLOCK 2 -->

      <script>

      var center = [-118.45202, 34.02873];

      tt.setProductInfo("LA Coffee Map", "1.0");

      var map = tt.map({

      key: "<your-api-key>",

      container: "map",

      style: "tomtom://vector/1/basic-main",

      center: center,

      });

      </script>

  </body>

</html>
```

Notice that we're loading assets from two different locations. Some are from the TomTom CDN source, while the others come from the local /assets directory. Those local files are copied from existing examples on TomTom's [website](https://developer.tomtom.com/maps-sdk-web-js/downloads), though, as mentioned previously, you can also get them from [Github](https://github.com/tomtom-international/maps-sdk-for-web-examples).

Your project should have the following structure:

```javascript
marker-tutorial

  /index.html

    /assets

      /css

        index.css

      /js

        search-marker.js

        search-markers-manager.js
```

You may be curious about the purposes of these files:

* index.css holds pre-made formatting that will be applied to the location marker icons.
* search-marker.js addresses the display and functionality of individual location marker objects.
* search-markers-manager.js is used to create and display marker objects in bulk.

For those curious about other pieces of prewritten code you can integrate into your projects, the [Maps SDK example projects](https://developer.tomtom.com/maps-sdk-web-js/functional-examples) have lots of helpful information. Whether you’re looking for specific features or just want some inspiration, the example projects show which files they use and are easy to play around with via the CodePen link. The complete source code is also available on [GitHub](https://github.com/tomtom-international/maps-sdk-for-web-examples).

Note that this is just prewritten code. It's extremely helpful, but there's nothing magical about it. You can use it, modify it, delete it, or commit it directly to your project.

Before moving on, open your browser's Developer Console and refresh the page. If there are any issues about importing the new files, you'll see the errors show up in the Console tab.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3kb40fpjy7e2gny7yg1o.png)

##Going for Coffee

Our coffee map currently has no coffee, which is a problem. Let's solve this by using TomTom Category Search to look up coffee shops within a 10km radius of our starting location (which is actually the location of another coffee shop in West LA):

Once we have the results, we can draw them on the map and set the proper level of zoom to show the results.

```javascript
<script>

  var center = [-118.45202, 34.02873];

  tt.setProductInfo("LA Coffee Map", "1.0");

  var map = tt.map({

    key: "<your-api-key>",

    container: "map",

    style: "tomtom://vector/1/basic-main",

    center: center,

  });

  var searchMarkersManager = new SearchMarkersManager(map);

  tt.services

    .categorySearch({

      key: "<your-api-key>",

      query: "coffee shop",

      center: center,

      radius: 10000,

      limit: 50,

    })

    .go()

    .then((response) => searchMarkersManager.draw(response.results))

    .then(() => map.fitBounds(searchMarkersManager.getMarkersBounds(), 

      { padding: 50 }));

</script>
```

To reiterate what this code accomplishes:

1. Uses .categorySearch() to find coffee shops in the right geographic area.
2. Creates a searchMarkersManager object that draws a list of results onto our map.
3. Zooms in on our search area by calling map.fitBounds() and passing in the marker bounds we get from searchMarkersManager.getMarkersBounds().

When you refresh the map page, you should see a map of West LA with an assortment of coffee shops.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eljrxi04n1z66lhc15n1.png)

##Customizing Your Results

searchMarketManager offers several options for customizing the results:

* _markerClassName_ is a string that lets you declare a class that will be added to all of the marker objects. You can use this class for styling with CSS or JavaScript events.
* _popupClassName_ is a string that lets you add a class to all popup elements that get created.
* _entryPoints_ is boolean that indicates whether location entry points will be included in results.
* _reverseGeocodeService_ expects a function that will receive a geocode and return the address for a location's entry point. This is particularly helpful for large locations, such as office buildings or airports.

Let's use markerClassName and popupClassName to add styles to the location markers. We'll change the opacity of the markers when they're hovered over to more clearly show what marker we're about to click. Additionally, we'll make the popup text display in italics.

```javascript
var searchMarkersManager = new SearchMarkersManager(map, {

  markerClassName: "marker-style",

  popupClassName: "popup-style",

});
```

And here's the CSS to style them.

```javascript
<style>

  #map {

    width: 100vw;

    height: 100vh;

  }

  .marker-style {

    opacity: 0.5;

  }

  .marker-style:hover {

    opacity: 0.8;

  }

  .popup-style {

      font-style: italic;

  }

</style>
```

Here’s the new version of the map. Try hovering over the different markers to see the styling changes.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fraiiq5px3fqtef4zzlp.png)

##Modifying the Library Code

Because searchMarkersManager supports adding classes to both marker and popup elements, we already have a lot of control over the style of our map icons. But since we’re using code that we’ve copied into our project, and thus completely control, we can customize functionality even more by modifying the example code.

For example, we can modify the search-marker.js file so it only includes information that’s relevant to our goal, which is finding coffee shops. More specifically, let’s update search-marker.js so it won't include the distance or coordinates of each coffeeshop, as they aren’t relevant right now.

Open search-marker.js, find the .createPopupContent() function, and delete or comment out the lines that create the divs named pop-up-result-distance and pop-up-result-position.

```javascript
// if (this.poiData.distance) {

//   this.createDivWithContent('pop-up-result-distance',

//     this.convertDistance(this.poiData.distance), popupContentElem);

// }

// var longitude = this.poiData.position.lon ? 

//                 this.poiData.position.lon : 

//                 this.poiData.position.lng;

// this.createDivWithContent('pop-up-result-position', 

//   this.poiData.position.lat + ', ' + longitude, popupContentElem);
```

If these changes don't show up when you refresh the page, your browser may be caching the JavaScript. Try hitting CMD + shift + r to refresh the cache.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/plt9cfy9x8i7u59jiq7o.png)

##Summary

And there you have it! In this tutorial, you learned how to:

* Use the searchMarkersManager function to draw multiple markers on the map at once.
* Enhance your own projects with code from the publicly available TomTom Maps SDK examples.
* Search for categories of locations with the Category Search service.
* Find great coffee in Los Angeles.

To see more ways you can use searchMarkersManager, as well as other code examples, make sure to visit the [Maps SDK Examples page](https://developer.tomtom.com/maps-sdk-web-js/functional-examples#examples,map,search.html). You can customize the example and run it in your browser by clicking the CodePen tab.

You can find all of the code from tutorial on Github: https://github.com/jhtimmins/tomtom-markers-tutorial

Thanks for reading, and happy mapping!

_This article originally appeared on https://developer.tomtom.com. The original author is James Timmins._