# How to add layers to a map in OpenSearch Dashboard 1.2.0

**URL:** <https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654>\
**Category:** OpenDistro\
**Tags:** troubleshoot, configure\
**Created:** [February 16, 2022, 9:08pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654 "2022-02-16T21:08:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 16, 2022, 9:08pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/1 "2022-02-16T21:08:01Z")

</div>

Kibana Dashboards allows me to have layers on a map where the user can hide or show the layer depending on what they want to see.

I am struggling to understand how to do this with OpenSearch Dashboards 1.2.0. I can create a map, but there seems to be no mechanism for adding a layer that the user can hide or show while they are using our dashboard.

Does this feature exist? If so, how do I do it?

Thanks.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 17, 2022, 8:31am UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/2 "2022-02-17T08:31:24Z")

</div>

Hello,  
The maps module as known in Kibana does not (yet) exist in OSD.  
However, you can probably use the [transform plugin](https://github.com/lguillaud/osd_transform_vis) with the help of the JS library leaflet/openstreetmap but it requires a bit of development.  
However, I have also provided samples to use leaflet and layers in leaflet (see sample\_vizs directory).  
The plugin is also available from the [Community page](https://opensearch.org/community_projects/).  
Hope it helps.  
Lionel

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 17, 2022, 2:02pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/3 "2022-02-17T14:02:26Z")

</div>

Thank you Lionel.

I tried to install the transform plugin inside the docker container running opensearch dashboards and am getting an error:  
_Plugin installation was unsuccessful due to error “Plugin transformVis [1.1.0] is incompatible with OpenSearch Dashboards [1.2.0]”_

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 17, 2022, 2:40pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/4 "2022-02-17T14:40:11Z")

</div>

Hello,  
Which release did you get ?  
If using 1.2, the command line to install the plugin is $KIBANA\_HOME/bin/opensearch-dashboards-plugin install [https://github.com/lguillaud/osd\_transform\_vis/releases/download/1.2.0/transformVis-1.2.0.zip](https://github.com/lguillaud/osd_transform_vis/releases/download/1.2.0/transformVis-1.2.0.zip).  
Please let me know.  
Lionel

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 17, 2022, 3:10pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/5 "2022-02-17T15:10:37Z")

</div>

Thanks Lionel. I was able to install 1.2.0, and it shows up in the list of installed plugins:  
[alertingDashboards@1.2.0.0](mailto:alertingDashboards@1.2.0.0)  
[anomalyDetectionDashboards@1.2.0.0](mailto:anomalyDetectionDashboards@1.2.0.0)  
[ganttChartDashboards@1.2.0.0](mailto:ganttChartDashboards@1.2.0.0)  
[indexManagementDashboards@1.2.0.0](mailto:indexManagementDashboards@1.2.0.0)  
[observabilityDashboards@1.2.0.0](mailto:observabilityDashboards@1.2.0.0)  
[queryWorkbenchDashboards@1.2.0.0](mailto:queryWorkbenchDashboards@1.2.0.0)  
[reportsDashboards@1.2.0.0](mailto:reportsDashboards@1.2.0.0)  
transformVis@1.2.0

But when I try to create a new visualization I don’t see transform.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/mauve_hedgehog/original/2X/2/202dbec23717dc0b11f7623e213d497bfd1bba9d.png)

I must have done something wrong. Thanks for the clues, I’ll keep plugging along.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 17, 2022, 3:14pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/6 "2022-02-17T15:14:43Z")

</div>

Hello,  
Did you add the specific configuration lines into the `opensearch_dashboards.yml` file ?  
See related section in README file: [GitHub - lguillaud/osd\_transform\_vis: OpenSearch-Dashboards plugin to create custom visualisations](https://github.com/lguillaud/osd_transform_vis#server-side).

Extract from my Dockerfile:

```nohighlight
...
ARG VERSION
...
# Transform viz settings
RUN echo "csp.strict: false" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo "csp.warnLegacyBrowsers: false" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo "csp.rules:" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"script-src 'unsafe-eval' 'unsafe-inline' 'self' https://www.gstatic.com/ https://d3js.org/ https://cdn.jsdelivr.net/ https://cdnjs.cloudflare.com/ https://cdn.datatables.net/ 'self'\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"worker-src blob: *\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"child-src data: * blob: *\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

# transform_viz
RUN /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin install https://github.com/lguillaud/osd_transform_vis/releases/download/$VERSION/transformVis-$VERSION.zip
...

```

Lionel

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 17, 2022, 3:33pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/7 "2022-02-17T15:33:51Z")

</div>

Any useful information from the OSD logs ?

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 17, 2022, 4:02pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/8 "2022-02-17T16:02:14Z")

</div>

Thanks for all the help.

I was just running the base image from docker hub. I have to create a local image with all these settings. Once I do that I’ll respond either way.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 17, 2022, 5:53pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/9 "2022-02-17T17:53:10Z")

</div>

Hello,  
In order to help you, please find below:

- Docker file for OS: Dockerfile-os
- Docker file for OSD: Dockerfile-osd
- docker-compose file: docker-compose-opensearch.yml

**Dockerfile-os**

```nohighlight
FROM opensearchproject/opensearch:latest

ENV discovery.type=single-node
ENV bootstrap.memory_lock=true
ENV cluster.name=elasticsearch
ENV ES_JAVA_OPTIONS="-Xms1g -Xmx1g"

USER opensearch

# Add log
RUN mkdir -p /usr/share/opensearch/logs
RUN echo "" >> /usr/share/opensearch/config/opensearch.yml

# expose port number
EXPOSE 9200

# Optional conf
RUN echo "http.cors.enabled : true" >>/usr/share/opensearch/config/opensearch.yml
RUN echo "http.cors.allow-origin: \"*\"" >>/usr/share/opensearch/config/opensearch.yml
RUN echo "http.cors.allow-methods : OPTIONS, HEAD, GET, POST, PUT, DELETE" >>/usr/share/opensearch/config/opensearch.yml
RUN echo "http.cors.allow-headers: \"kbn-version, Origin, X-Requested-With, Content-Type, Accept, Engaged-Auth-Token, Authorization\"" >>/usr/share/opensearch/config/opensearch.yml

USER opensearch

```

**Dockerfile-osd**

```nohighlight
FROM opensearchproject/opensearch-dashboards

EXPOSE 5601

# install required packages to install Kibana & custom plugins
USER root
RUN yum -y update
RUN yum -y install wget

# add opensearch-dashboards logs
RUN mkdir -p /usr/share/opensearch-dashboards/logs
RUN touch /usr/share/opensearch-dashboards/logs/opensearch_dashboards.log
RUN chown -R opensearch-dashboards: /usr/share/opensearch-dashboards/logs
RUN chmod 777 /usr/share/opensearch-dashboards/logs/opensearch_dashboards.log
RUN echo "logging.dest: /usr/share/opensearch-dashboards/logs/opensearch_dashboards.log" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

USER opensearch-dashboards
# install opensearch-dashboards plugins
RUN echo "" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

# Transform viz settings
RUN echo "csp.strict: false" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo "csp.warnLegacyBrowsers: false" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo "csp.rules:" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"script-src 'unsafe-eval' 'unsafe-inline' 'self' https://www.gstatic.com/ https://d3js.org/ https://cdn.jsdelivr.net/ https://cdnjs.cloudflare.com/ https://cdn.datatables.net/ 'self'\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"worker-src blob: *\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml
RUN echo " - \"child-src data: * blob: *\"" >> /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

# transform_viz
RUN /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin install https://github.com/lguillaud/osd_transform_vis/releases/download/1.2.0/transformVis-1.2.0.zip

# Change network opensearch-dashboards settings
RUN sed -i "s?opensearch.hosts: \[https://localhost:9200\]?opensearch.hosts: \[\"https://opensearch-1.2.4:9200\"\]?" /usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

USER 0
RUN chmod 777 /usr/share/opensearch-dashboards/*

USER opensearch-dashboards

```

**docker-compose-opensearch.yml**

```nohighlight
version: '3'
services:
  opensearch:
    image: os:latest
    container_name: "opensearch-1.2.4"
    environment:
      - discovery.type=single-node
      - cluster.name=opensearch
      - node.name=opensearch
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    ports:
      - "9200:9200"
  opensearch-dashboards:
    image: osd:latest
    container_name: "opensearch-dashboards-1.2.0"
    ports:
      - "5601:5601"

```

Then run the following commands:

```nohighlight
docker build -t os -f Dockerfile-os .
docker build -t osd -f Dockerfile-osd .
docker-compose -f docker-compose-opensearch.yml up

```

Finally, open `localhost:5601` (user and password are admin/Admin).

Hope it helps.  
Lionel

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 17, 2022, 6:35pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/10 "2022-02-17T18:35:01Z")

</div>

Wow, thanks for the help Lionel. I was able to get it installed and up and running. I was able to create a map on the dashboard using the samples you provided. I need to figure out the layering next as I want to be able to include points on the graph that can be included or excluded by the user of the dashboard.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 18, 2022, 8:40am UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/11 "2022-02-18T08:40:27Z")

</div>

Hello,  
For adding/removing layers, the leaflet documentation will help you (e.g. [Documentation - Leaflet - a JavaScript library for interactive maps](https://leafletjs.com/reference.html#layergroup)). I think you can add buttons (or event click to the map) to handle adding/removing layers.  
Lionel

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 18, 2022, 2:09pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/12 "2022-02-18T14:09:59Z")

</div>

Thanks for the information Lionel. I think this is outside my skillset. I am not sure that what I am trying to do can be done with OpenSearch Dashboards, which is a real problem. I don’t get why OpenSearch is a step backwards from ES. That question is not directed at you, by the way. You have been very helpful.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 18, 2022, 4:14pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/13 "2022-02-18T16:14:57Z")

</div>

You’re welcome.  
I know this plugin requires Javascript skills but allows great flexibility.  
To give a quick answer to the question that was not directed to me 🙂: basically, OpenSearch is a “step backwards from ES” mainly because some of the pieces in ES are proprietary code (under license) and could not be forked as such into OS.  
However, depending on the community needs, a map module could come to life …

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 18, 2022, 5:22pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/14 "2022-02-18T17:22:31Z")

</div>

Lionel, thank you for the answer to the question I did not direct to you 😀. I completely understand why it is the way it is. My issue/frustration is that I do not know Javascript. Perhaps everyone else that will run into the problem is Javascript proficient and the need for mapping is not great. In looking at your plugin more closely, I see the before\_render and after\_render in the map\_openstreetmap\_custom\_geojson example. I guess my question relates to if these get called to update the map based on some change by the user. Let’s say I put a button on the page to add markers based on a query of an index. What method has to get invoked, after\_render? Sorry for all the questions. Thanks.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 21, 2022, 8:27am UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/15 "2022-02-21T08:27:18Z")

</div>

Hello John,

Before\_render and after\_render hooks are mainly used in the following context:

- before\_render: when you need to manipulate/enrich data that you get from the DSL query part. It ensures that all the data will be ready before rendering the visualization (usually made within the after\_render\_function). For example, you need to add a field that is computed from the data you get from OS.
- after\_render: when you need to make sure the DOM is built before using it. In other words, wait for the template part (HML/CSS) to be completely interpreted by the browser. This is is the recommended way of doing but you could name the function differently.

The way the plugin works. When the viz is loaded from a dashboard:

1. A query is made to OpenSearch (if you are using a query in the DSL part)
2. The template part is built (to render the HTML part)
3. “At the same time”, the Javascript functions are run (again the after\_render function is only triggered when the template is fully loaded).

Each time you change filters/dates, the viz is reloaded and functions are played again.

To answer your questions, what you could do in your case is to add a button and event to handle it in the after\_render function.  
Add the button in the template part:

```nohighlight
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
 <button class='btn btn-primary active' id="myBtn">Change view/map</button>

```

Add the button management in the javascript part (note that you need to get the button location using the getShadowDomLocation function):

```nohighlight
const shadowMyButtonLocation = getShadowDomLocation("#myBtn").vizLocation[0];
$(shadowMyButtonLocation).click(function() {
// insert here what you need to do when you click the button
alert("Hello, I'm here");
});

```

I know this plugin is not the easiest one as it requires skills in JS development.

Hope it helps a little bit anyway.

Lionel

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 21, 2022, 8:57am UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/16 "2022-02-21T08:57:18Z")

</div>

How to remove a layer ?  
In the map\_openstreetmap\_custom\_geojson viz, replace JS part by:

```nohighlight
// Leaflet use
// https://nouvelle-techno.fr/articles/pas-a-pas-inserer-une-carte-openstreetmap-sur-votre-site

// Custom geojson
// https://leafletjs.com/examples/geojson/

({
  getShadowDomLocation: function(selector) {
  let vizLocation;
  // output-viz being the top selector used by the Transform plugin
  // Get all the output-viz elements (can have mutliple selector if multiple transfrm vizs in a dashboard)
  // selector parameter value must be unque within the DOM
  const elements = $('.output-vis');
  let shadow;
  for (let elem of elements) {
      shadow = elem.shadowRoot;
      vizLocation = $(shadow).find(selector);
      if (vizLocation.length > 0) {
      // selector found, exiting
        break;
      } else {
        vizLocation = '.notFound';
      }
  } 
  const obj = {
    vizLocation: vizLocation,
    shadowRoot: shadow
    } 
// obj object contains the shadowRoot element and and the location of the selector within the shadowRoot 
  return obj;
},

css: function() {  
  const css_list = [
    "https://use.fontawesome.com/releases/v5.6.3/css/all.css",
    "https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
  ];  
  for (let css_file of css_list) {
    const links = document.head.querySelectorAll("link");

    // Already been injected
    for(let l in links) if(links[l].href == css_file) return;
      const link = document.createElement('link');
      link.rel = "stylesheet";
      link.href = css_file;
      document.head.appendChild(link);
    } 
  },

  before_render: function() {
    // Set geo points
    let locationsForLayer1 = [
      {
  			"id": "1",
  			"name": "Paris",
  			"lat": "48.8566",
  			"lon": "2.3522",
  			"size": "4",
  			"class": "myDivIconPurple"
  		},
  		{
  			"id": "3",
  			"name": "Toulouse",
  			"lat": "43.6045",
  			"lon": "	1.4440",
  			"size": "2",
  			"class": "myDivIconPurple"
  		}, {
  			"id": "4",
  			"name": "Grenoble",
  			"lat": "45.1715",
  			"lon": "5.7224",
  			"size": "3",
  			"class": "myDivIconPurple"
  		}
    ]
    let locationsForLayer2 = [
      {
  			"id": "2",
  			"name": "Nice",
  			"lat": "43.7034",
  			"lon": "	7.2663",
  			"size": "2",
  			"class": "myDivIcon"
  		},
  		{
  			"id": "5",
  			"name": "Bordeaux",
  			"lat": "44.8400",
  			"lon": "-0.5800",
  			"size": "2",
  			"class": "myDivIcon"
  		}
    ]
    
    response = {
      "locationsForLayer1": locationsForLayer1,
      "locationsForLayer2": locationsForLayer2
    }
  },
  
  after_render: function() {
    const meta = this.meta; 
    let locationsForLayer1 = response.locationsForLayer1;
    let locationsForLayer2 = response.locationsForLayer2;

    $.getScript("https://cdn.jsdelivr.net/npm/leaflet@1.7.1/dist/leaflet.js")
    .done(function(script, textStatus) {
      $.getScript("https://cdn.jsdelivr.net/gh/lguillaud/osd_transform_vis@main/geojson/departements.geojson.js")
      .done(function(script, textStatus) {

        // Get geojson into json object
        let myGeoJson = JSON.parse(departements);

        // Create HTML container for map
        // Rebuild each time to avoid multiple maps layers
        let myDiv = meta.getShadowDomLocation("#myDiv").vizLocation; 
        $(myDiv).empty();
        $(myDiv).append('<div id="map"></div>')
        let mapLocation = meta.getShadowDomLocation("#map").vizLocation[0];
  
        // Create map object
        let map=new L.map(mapLocation);
        
        // Add GeoJSON layer to map
        // Set options
        let myStyle = {
          "color": "#ff7800",
          "weight": 3,
          "opacity": 0.15
        };
        L.geoJSON(myGeoJson, { style: myStyle }).addTo(map);
        
        // Maps location
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 
          attribution: 'data © <a href="//osm.org/copyright">OpenStreetMap</a>/ODbL - render <a href="//openstreetmap.fr">OSM France</a>',
          minZoom: 1,
      		maxZoom: 20
      	}).addTo(map); 
  
        // Create markers group
        let markerGroup1 = L.layerGroup();
        let markerGroup2 = L.layerGroup();
        
        // Markers creation layer 1
        let markers = [];  
        for (let location in locationsForLayer1) { 
          // Icon to use
          let myIcon = L.divIcon({
      			html: '<i class="fas fa-circle fa-' + locationsForLayer1[location].size + 'x"></i>',
      			iconSize: [20, 20],
      			className: locationsForLayer1[location].class
      		}); 
  	
  	      // If custom icon
          let marker = L.marker([locationsForLayer1[location].lat, locationsForLayer1[location].lon], { icon: myIcon })
          // Default icon
          //let marker = L.marker([locations[location].lat, locations[location].lon]) 
            .addTo(map)
            .bindPopup(locationsForLayer1[location].name); 
               
          // Add marker to group
          markerGroup1.addLayer(marker);
          // Add marker to list of markers 
  		    markers.push(marker);
        }
    
        // Markers creation layer 2
        markers = [];  
        for (let location in locationsForLayer2) { 
          // Icon to use
          let myIcon = L.divIcon({
      			html: '<i class="fas fa-circle fa-' + locationsForLayer2[location].size + 'x"></i>',
      			iconSize: [20, 20],
      			className: locationsForLayer2[location].class
      		}); 
  	
  	      // If custom icon
          let marker = L.marker([locationsForLayer2[location].lat, locationsForLayer2[location].lon], { icon: myIcon })
          // Default icon
          //let marker = L.marker([locations[location].lat, locations[location].lon]) 
            .addTo(map)
            .bindPopup(locationsForLayer2[location].name); 
               
          // Add marker to group
          markerGroup2.addLayer(marker);
          // Add marker to list of markers 
  		    markers.push(marker);
        }

        // Create marker group for zoom 
        let group = new L.featureGroup(markers);
        // Make all markers visible, using pad to avoid marker being cut 
        map.fitBounds(group.getBounds().pad(0.3));
        map.addLayer(markerGroup1);
        map.addLayer(markerGroup2);
        
        // Manage Button
        const shadowMyButtonLocation = meta.getShadowDomLocation("#myBtn").vizLocation[0];
        $(shadowMyButtonLocation).unbind()
        $(shadowMyButtonLocation).click(function() {
           map.removeLayer(markerGroup2);
        })
      });    
    });    
  }
})

```

In the template part, replace all by:

```nohighlight
<style>
  #map { height: 600px; }  
  
  .myDivIcon {
    text-align: center; /* Horizontally center the text (icon) */
    line-height: 20px; /* Vertically center the text (icon) */
    color: blue;
  }
    
  .myDivIconPurple {
    text-align: center; /* Horizontally center the text (icon) */
    line-height: 20px; /* Vertically center the text (icon) */
    color: purple;
  }
</style>

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
   integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
   crossorigin=""/>

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">

<div id="myDiv">
</div>

<button class='btn btn-primary active' id="myBtn">Remove blue points</button>

```

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 22, 2022, 6:47pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/17 "2022-02-22T18:47:35Z")

</div>

Hi Lionel. Thank you for all the help. I was able to do what I wanted thanks to your plugin and the running help you have provided over the past several days. Your plugin worked to do exactly as I needed.

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 23, 2022, 1:58pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/18 "2022-02-23T13:58:31Z")

</div>

Hi John,

Glad to hear that.

---

<div class="post-metadata">

**Author:** ![jrcartmell](https://avatars.discourse-cdn.com/v4/letter/j/d78d45/32.png) [@jrcartmell](https://forum.opensearch.org/u/jrcartmell)\
**Post date:** [February 25, 2022, 10:32pm UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/19 "2022-02-25T22:32:15Z")

</div>

Again thanks for all the help Lionel. One followup. If I have an OS Dashboard with two visualizations, one controls where the user can set some of the query parameters and the other a transform map, how can I access those query parameter values in the transform map?

---

<div class="post-metadata">

**Author:** ![lguillaud](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.opensearch.org/lguillaud/32/3133_2.png) [@lguillaud](https://forum.opensearch.org/u/lguillaud)\
**Post date:** [February 28, 2022, 7:59am UTC](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654/20 "2022-02-28T07:59:58Z")

</div>

What kind of visualization is the one that allows the user to set some of the query parameters ?

If this is also a transform viz, the best would be to have a single transform viz with a part in charge of modifying query parameters and the other part in charge of displaying the map. Being in the same viz, you can add event that re-run what needed.

If this is an out-of-the-box viz (pie, …), when you set new filters it should update the data (query) in the transform viz but only in the case you add the following in the query part (see [GitHub - lguillaud/osd\_transform\_vis: OpenSearch-Dashboards plugin to create custom visualisations](https://github.com/lguillaud/osd_transform_vis#query-dsl)):

- “_DASHBOARD\_CONTEXT_”,
- “_TIME\_RANGE_[your\_time\_field\_for\_the\_index\_pattern]”

[Next page](https://forum.opensearch.org/t/how-to-add-layers-to-a-map-in-opensearch-dashboard-1-2-0/8654.md?page=2)
