2

I am using Leaflet javascript library to show some earthquake information. You are able to see few red circles on map. When you click that red circle it will display few details in popup.

I want to show the popup when you click the link from outside of map. This (answer) is useful. But, I want to achieve it without ID? I mean if i have more than 30 markers on map and also I don't have any ID, just class names in my links. How do I trigger popup when I click a link from outside of map?

This (answer) is good. In this answer they mentioned marker 1, marker 2 and marker 3. But, In my case I don't know how many markers will show. Sometimes 5, 50, 100 or may be more than 150. Thats why I have asked this question.

<html>
  <head>
<meta charset="utf-8" />
<title>Leaflet</title>
<link
  rel="stylesheet"
  href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
  integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
  crossorigin=""
/>
<script
  src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
  integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
  crossorigin=""
></script>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  </head>

  <body>
<div id="map" style="width: 400px; height: 400px;"></div>

<script>
  var object = {
    type: "FeatureCollection",
    metadata: {
      generated: 1564051101000,
      url:
        "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2019-07-20&endtime=2019-07-21&minmagnitude=5",
      title: "USGS Earthquakes",
      status: 200,
      api: "1.8.1",
      count: 4
    },
    features: [
      {
        type: "Feature",
        properties: {
          mag: 5.2000000000000002,
          place: "79km ENE of L'Esperance Rock, New Zealand",
          time: 1563662132538,
          updated: 1563663302040,
          tz: -720,
          url: "https://earthquake.usgs.gov/earthquakes/eventpage/us70004pu1",
          detail: "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70004pu1&format=geojson",
          felt: null,
          cdi: null,
          mmi: null,
          alert: null,
          status: "reviewed",
          tsunami: 0,
          sig: 416,
          net: "us",
          code: "70004pu1",
          ids: ",us70004pu1,",
          sources: ",us,",
          types: ",geoserve,origin,phase-data,",
          nst: null,
          dmin: 1.9299999999999999,
          rms: 1.28,
          gap: 70,
          magType: "mww",
          type: "earthquake",
          title: "M 5.2 - 79km ENE of L'Esperance Rock, New Zealand"
        },
        geometry: { type: "Point", coordinates: [-178.1173, -31.174800000000001, 35] },
        id: "us70004pu1"
      },
      {
        type: "Feature",
        properties: {
          mag: 5.5999999999999996,
          place: "23km NNW of Kandrian, Papua New Guinea",
          time: 1563655424914,
          updated: 1563741959328,
          tz: 600,
          url: "https://earthquake.usgs.gov/earthquakes/eventpage/us70004psn",
          detail: "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70004psn&format=geojson",
          felt: 1,
          cdi: 4.2999999999999998,
          mmi: 4.4779999999999998,
          alert: "green",
          status: "reviewed",
          tsunami: 1,
          sig: 483,
          net: "us",
          code: "70004psn",
          ids: ",us70004psn,",
          sources: ",us,",
          types: ",dyfi,geoserve,losspager,moment-tensor,origin,phase-data,shakemap,",
          nst: null,
          dmin: 3.2029999999999998,
          rms: 0.89000000000000001,
          gap: 28,
          magType: "mww",
          type: "earthquake",
          title: "M 5.6 - 23km NNW of Kandrian, Papua New Guinea"
        },
        geometry: { type: "Point", coordinates: [149.5069, -6.0086000000000004, 59.789999999999999] },
        id: "us70004psn"
      },
      {
        type: "Feature",
        properties: {
          mag: 5.0999999999999996,
          place: "Easter Island region",
          time: 1563647034336,
          updated: 1563892918040,
          tz: -420,
          url: "https://earthquake.usgs.gov/earthquakes/eventpage/us70004pra",
          detail: "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70004pra&format=geojson",
          felt: null,
          cdi: null,
          mmi: null,
          alert: null,
          status: "reviewed",
          tsunami: 0,
          sig: 400,
          net: "us",
          code: "70004pra",
          ids: ",us70004pra,",
          sources: ",us,",
          types: ",geoserve,origin,phase-data,",
          nst: null,
          dmin: 2.7559999999999998,
          rms: 0.71999999999999997,
          gap: 118,
          magType: "mb",
          type: "earthquake",
          title: "M 5.1 - Easter Island region"
        },
        geometry: { type: "Point", coordinates: [-111.38379999999999, -29.3232, 10] },
        id: "us70004pra"
      },
      {
        type: "Feature",
        properties: {
          mag: 5.0999999999999996,
          place: "136km ESE of Pangai, Tonga",
          time: 1563635789233,
          updated: 1563636880040,
          tz: -720,
          url: "https://earthquake.usgs.gov/earthquakes/eventpage/us70004pp5",
          detail: "https://earthquake.usgs.gov/fdsnws/event/1/query?eventid=us70004pp5&format=geojson",
          felt: null,
          cdi: null,
          mmi: null,
          alert: null,
          status: "reviewed",
          tsunami: 0,
          sig: 400,
          net: "us",
          code: "70004pp5",
          ids: ",us70004pp5,",
          sources: ",us,",
          types: ",geoserve,origin,phase-data,",
          nst: null,
          dmin: 3.2749999999999999,
          rms: 1.3100000000000001,
          gap: 116,
          magType: "mww",
          type: "earthquake",
          title: "M 5.1 - 136km ESE of Pangai, Tonga"
        },
        geometry: { type: "Point", coordinates: [-173.15700000000001, -20.294899999999998, 10] },
        id: "us70004pp5"
      }
    ],
    bbox: [-178.1173, -31.1748, 10, 149.5069, -6.0086, 59.79]
  };

  var i = 0;

  document.writeln("<div>");
  for (i = 0; i < object.features.length; i++) {
    var timestamp = object.features[i].properties.time / 1000;
    date = new Date(timestamp * 1000);
    dateString = date.toUTCString();

    var today = date;
    today.setHours(today.getHours() + 4);

    // maps

    document.writeln("<div class='list'>");
    document.writeln("<div>" + object.features[i].properties.mag + " Mag</div>");
    document.writeln("</div>");
  }
  document.writeln("</div>");

  var map = L.map("map").setView([-31.174800000000001, -178.1173], 2);

  // load a tile layer
  L.tileLayer(
    "https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}",
    {
      attribution:
        "Tiles &copy; Esri &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012",
      maxZoom: 18
    }
  ).addTo(map);

  // load GeoJSON from an external file
  $.getJSON(
    "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2019-07-20&endtime=2019-07-21&minmagnitude=5",
    function(data) {
      var geojsonMarkerOptions = {
        opacity: 0.8,
        fillOpacity: 0.6
      };

      // color indication by magnitude
      geoLayer = L.geoJson(data, {
        // popup div content
        onEachFeature: function(feature, layer) {
          // variable1 = L.marker([-31.174800000000001,-178.1173]).bindPopup('The html content').addTo(map);

          var popupText =
            "<b>Magnitude:</b> " +
            feature.properties.mag +
            "<br><b>Location:</b> " +
            feature.properties.place;

          layer.bindPopup(popupText, {
            closeButton: true,
            offset: L.point(0, -20)
          });
          layer.on("click", function() {
            layer.openPopup();
          });
        },

        style: function(feature) {
          var mag = feature.properties.mag;
          if (mag >= 4.0) {
            return { color: "red" };
          } else if (mag >= 3.0) {
            return { color: "orange" };
          } else if (mag >= 2.0) {
            return { color: "yellow" };
          } else {
            return { color: "black" };
          }
        },

        // add GeoJSON layer to the map once the file is loaded
        pointToLayer: function(feature, latlng) {
          return L.circleMarker(latlng, geojsonMarkerOptions);
        }
      }).addTo(map);
    }
  );
</script>
  </body>
</html>
Karuppiah RK
  • 3,894
  • 9
  • 40
  • 80
  • I am not sure why you are using leaflet 0.7.x. I edited the example to be reproducible by changing the leaflet version to the latest. – kboul Jul 31 '19 at 08:37
  • @kboul I am not aware about the latest version. Thanks.. – Karuppiah RK Jul 31 '19 at 08:38
  • 1
    Why you don't want to use id coming form the API? It is the best way to keep a reference to each feature in order to open the popup outside of the map. You could store the each circle marker in an associative array like `myArray['id'] = L.marker(...).addTo(map)` and then call `myArray['id'].openPopup();` – kboul Jul 31 '19 at 09:04
  • According to https://earthquake.usgs.gov/data/comcat/data-eventterms.php#code , the `code` property is guaranteed to be unique, and thus can be use as the unique feature ID. – IvanSanchez Jul 31 '19 at 09:16
  • @kboul I feel its quite complex to handle ID if I have more than 150 markers on map.. – Karuppiah RK Jul 31 '19 at 09:33
  • @kboul Thanks for your comment. I have tried and got the output result. I have posted it an answer. But, mag colors red, orange, yellow, black didn't work.. – Karuppiah RK Jul 31 '19 at 11:26

1 Answers1

3

Here is an example of a possible solution using es6:

create for instance a div which will hold the anchor tags to be added dynamically:

<div id="anchors"></div>

Now in the js file:

  let markersArray = {}; // create the associative array
  let magsArray = {}; // here hold the ids that correspond to the mags


  // load GeoJSON from an external file
  $.getJSON("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2019-07-20&endtime=2019-07-21&minmagnitude=5", data => {

    // color indication by magnitude
    L.geoJson(data, {

      // add GeoJSON layer to the map once the file is loaded
      pointToLayer: function(feature, latlng) {
        const mag = feature.properties.mag;
        const geojsonMarkerOptions = {
          opacity: 0.8,
          fillOpacity: 0.6,
          // here define the style using ternary operators for circles
          color: mag >= 4.0 ? 'red' : mag >= 3.0 ? 'orange' : mag >= 2.0 ? 'yellow' : 'black'
        };

        // here store the circle markers in the array
        markersArray[feature.id] = L.circleMarker(latlng, geojsonMarkerOptions)
               .addTo(map)
               .bindPopup(
              `<b>Magnitude:</b> " ${feature.properties.mag} 
               <br><b>Location:</b>  ${feature.properties.place}`, {
          closeButton: true,
          offset: L.point(0, -20)
        });

        // here record the mags
        magsArray[feature.id] = feature.properties.mag;

        return L.circleMarker(latlng, geojsonMarkerOptions);
      },
    })

    // add dynamically anchor tags
    let markup = '';
    for (let i in markersArray) {
      markup += `<a href="#" onclick="markersArray['${i}'].openPopup()"><b>${magsArray[i]} Mag</b></a><br/>`;
    }
    document.getElementById('anchors').innerHTML = markup;
  });

Last but not least I do not see the reason of fetching the data using the API and both have it also as a constant variable in your file.

Demo

kboul
  • 13,836
  • 5
  • 42
  • 53