Jquery Leaflet Marker Layer Cluster Support with layers generated from unique json values- Leaflet.FeatureGroup.SubGroup

三世轮回 提交于 2020-01-06 08:16:59

问题


EDIT 3: I was able to get it working. I was making it harder than it actually was!

https://jsfiddle.net/crashvector/xczj76om/13/


EDIT 2: Here is a link to a working fiddle of what I currently have. This has the seperate layers, but doesn't have the clustering function I am trying to implement.

https://jsfiddle.net/xczj76om/12/


EDIT: I have updated my JS with a version that maps a cluster layer, and three individual layers based on the Classification listed in the JSON.

My desire is to implement:

https://ghybs.github.io/Leaflet.FeatureGroup.SubGroup/examples/subGroup-markercluster-controlLayers-realworld.388.html

in order to get rid of the extra cluster layer and cluster the three individual layers together.

I am unsure of how to change this section to accomodate the plugin above.

//define clustering layer 
var markerClusters = L.markerClusterGroup({});  



for ( var i = 0; i < markers.length; ++i ) {
    var popup = '<br/><b>Sample Name:</b> '+ markers[i]["Sample Name"] +
              '<br/><b>Location Description:</b> ' + markers[i]["Location Description"] +
              '<br/><b>Date Taken:</b> ' + markers[i]["Date"] +
              '<br/><b>Classification:</b> ' + markers[i]["Classification"]

    //define markers    
    var m = L.marker( [markers[i].Lattitude, markers[i].Longitude], {icon: icons[markers[i]["Classification"]]})
                  .bindPopup( popup );
    category = markers[i]["Classification"];

    // Initialize the category array if not already set.
    if (typeof categories[category] === "undefined") {
    categories[category] = L.layerGroup().addTo(map);
    layersControl.addOverlay(categories[category], category);
    }
    categories[category].addLayer(m);



markerClusters.addLayer( m );
}

map.addLayer( markerClusters );

I previously asked a question here:

Jquery Leaflet marker layer control for dynamic custom icons with clustering plugin

Which pointed me to this plugin:

Using several Marker Cluster Groups displays overlapping Clusters

And also this thread:

Cluster multiple Layers with markercluster


HTML

    <!DOCTYPE html>
<html>
  <head>
    <title>Sample Locations</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>

    <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.css" />
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/leaflet.markercluster@1.4.1/dist/MarkerCluster.Default.css" />

    <script charset="utf8" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
    integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
    crossorigin=""></script>

    <script type='text/javascript' src='https://unpkg.com/leaflet.markercluster@1.4.1/dist/leaflet.markercluster.js'></script>

 <!-- Load Esri Leaflet from CDN -->
    <script src="https://unpkg.com/esri-leaflet@2.2.4/dist/esri-leaflet.js"
    integrity="sha512-tyPum7h2h36X52O2gz+Pe8z/3l+Y9S1yEUscbVs5r5aEY5dFmP1WWRY/WLLElnFHa+k1JBQZSCDGwEAnm2IxAQ=="
    crossorigin=""></script>
    <!-- Leaflet.FeatureGroup.SubGroup assets -->
<script src="https://unpkg.com/leaflet.featuregroup.subgroup@1.0.2/dist/leaflet.featuregroup.subgroup.js"></script>

<body>
  <style>
    body{
        margin:0;
        padding:0;
        }

    #map{ 
        position: absolute;
        top:0;
        bottom:0;
        right:0;
        left:0;
        }

    #basemaps-wrapper{
        position: absolute;
        bottom: 10px;
        left: 10px;
        z-index: 400;
        background: white;
        padding: 10px;
    }

    #basemaps{
        margin-bottom: 5px;
    }
</style>

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

<div id="basemaps-wrapper" class="leaflet-bar">
  <select name="basemaps" id="basemaps" onChange="changeBasemap(basemaps)">
    <option value="Topographic">Topographic</option>
    <option value="Streets">Streets</option>
    <option value="NationalGeographic">National Geographic</option>
    <option value="Oceans">Oceans</option>
    <option value="Imagery">Imagery</option>
    <option value="ImageryClarity" selected>Imagery (Clarity)</option>
    <option value="ImageryFirefly">Imagery (Firefly)</option>
    <option value="Gray">Gray</option>
    <option value="DarkGray">Dark Gray</option>
    <option value="ShadedRelief">Shaded Relief</option>
    <option value="Physical">Physical</option>
  </select>
</div>
  </head>


    <script type='text/javascript' src='JS/maptest2.js'></script>
  </body>
</html>

Jquery

    // Define site URL
var myURL = jQuery( 'script[src$="JS/maptest2.js"]' ).attr( 'src' ).replace( 'JS/maptest2.js', '' );

//define icon image locations
var Sourceiconurl =  myURL + 'images/source.png',
    Blankiconurl =  myURL + 'images/background.png',
    Unknowniconurl =  myURL + 'images/unknown.png', 
    Backgroundiconurl =  myURL + 'images/background.png';

//initialize variable   
var markers;

//pull data from json
jQuery.ajax({                              
url: myURL +  "map_json.php",
type: "JSON",
async: false,
success: function(data){
       markers = jQuery.parseJSON(data);
       jQuery(markers).each(function( index, element ) {     

       });
} 
}); 

//initialize map
var map = L.map( 'map', {
  center: [39.8333333, -98.585522],
  minZoom: 1,
  zoom: 4
});

//create esri layers and selector
var layer = L.esri.basemapLayer('Imagery').addTo(map);
  var layerLabels = L.esri.basemapLayer('ImageryLabels');
      map.addLayer(layerLabels);

  function setBasemap(basemap) {
    if (layer) {
      map.removeLayer(layer);
    }

    layer = L.esri.basemapLayer(basemap);

    map.addLayer(layer);

    if (layerLabels) {
      map.removeLayer(layerLabels);
    }

    if (basemap === 'ShadedRelief'
     || basemap === 'Oceans'
     || basemap === 'Gray'
     || basemap === 'DarkGray'
     || basemap === 'Terrain'
   ) {
      layerLabels = L.esri.basemapLayer(basemap + 'Labels');
      map.addLayer(layerLabels);
    } else if (basemap.includes('Imagery')) {
      layerLabels = L.esri.basemapLayer('ImageryLabels');
      map.addLayer(layerLabels);
    }
  }

  function changeBasemap(basemaps){
    var basemap = basemaps.value;
    setBasemap(basemap);
  }

//create legend (need to figure out how to format)  
var legend = L.control({position: 'bottomright'});

legend.onAdd = function (map) {

    var div = L.DomUtil.create('div', 'legend'),
        categorynames = ["Source", "Blank/Background", "Unknown"],
        imagefiles = [Sourceiconurl,Blankiconurl,myURL + Unknowniconurl];

    // assign image for each category
    for (var i = 0; i < categorynames.length; i++) {
        div.innerHTML +=
            categorynames[i] + (" <img src="+ imagefiles[i] +" height='50' width='50'>") +'<br>';
    }

    return div;
};

legend.addTo(map);

//define base icon features
 var MapIcon = L.Icon.extend({
    options: {
        iconSize:     [40, 55],
        iconAnchor:   [20, 35],
        popupAnchor:  [2, -10]
    }
}); 

//define custom icons 
var Source = new MapIcon({iconUrl: Sourceiconurl}),
    Blank = new MapIcon({iconUrl: Blankiconurl}),
    Unknown = new MapIcon({iconUrl: Unknowniconurl}), 
    Background = new MapIcon({iconUrl: Backgroundiconurl});

//allows function to read json field and assign to icon url 
var icons = {
    "Source": Source,
    "Blank": Blank,
    "Unknown": Unknown,
    "Background": Background};

var categories = {},
    category;

var layersControl = L.control.layers(null, null).addTo(map);







//define clustering layer 
var markerClusters = L.markerClusterGroup({});  



for ( var i = 0; i < markers.length; ++i ) {
    var popup = '<br/><b>Sample Name:</b> '+ markers[i]["Sample Name"] +
              '<br/><b>Location Description:</b> ' + markers[i]["Location Description"] +
              '<br/><b>Date Taken:</b> ' + markers[i]["Date"] +
              '<br/><b>Classification:</b> ' + markers[i]["Classification"]

    //define markers    
    var m = L.marker( [markers[i].Lattitude, markers[i].Longitude], {icon: icons[markers[i]["Classification"]]})
                  .bindPopup( popup );
    category = markers[i]["Classification"];

    // Initialize the category array if not already set.
    if (typeof categories[category] === "undefined") {
    categories[category] = L.layerGroup().addTo(map);
    layersControl.addOverlay(categories[category], category);
    }
    categories[category].addLayer(m);



markerClusters.addLayer( m );
}

map.addLayer( markerClusters );

JSON

[
  {
    "Sample Name": "7411-2",
    "Date": "2017-09-05",
    "Lattitude": "40.3126",
    "Longitude": "-94.0277",
    "Location Description": "Lake 1",
    "Classification": "Unknown",
    "Empty": "1"
  },
  {
    "Sample Name": "7411-1",
    "Date": "2017-09-05",
    "Lattitude": "40.5999",
    "Longitude": "-93.7661",
    "Location Description": "Lake 2",
    "Classification": "Source",
    "Empty": "1"
  },
  {
    "Sample Name": "7406-3",
    "Date": "2017-07-31",
    "Lattitude": "39.4076",
    "Longitude": "-94.5555",
    "Location Description": "Lake 3",
    "Classification": "Background",
    "Empty": "1"
  },
  {
    "Sample Name": "7406-3",
    "Date": "2017-07-31",
    "Lattitude": "39.4076",
    "Longitude": "-94.5555",
    "Location Description": "Lake 3",
    "Classification": "Background",
    "Empty": "1"
  }
]

ICONS

You can use any 4 .png icon files in place of the ones I have listed.

回答1:


I was able to make all the magic happen with the following block. This creates dynamic layers based on the JSON field and then allows those layers to be clustered together dynamically based on what layers are currently selected.

var categories = {},
  category;

var layersControl = L.control.layers(null, null).addTo(map);
var parentGroup = L.markerClusterGroup().addTo(map);

for ( var i = 0; i < markers.length; ++i ) {
    var popup = '<br/><b>Sample Name:</b> '+ markers[i]["Sample Name"] +
              '<br/><b>Location Description:</b> ' + markers[i]["Location Description"] +
              '<br/><b>Date Taken:</b> ' + markers[i].Date +
              '<br/><b>Classification:</b> ' + markers[i].Classification

    //define markers    
    var m = L.marker( [markers[i].Lattitude, markers[i].Longitude], {icon: icons[markers[i].Classification]})
                  .bindPopup( popup );
    category = markers[i].Classification;

    // Initialize the category array if not already set.
    if (typeof categories[category] === "undefined") {
    categories[category] = L.featureGroup.subGroup(parentGroup,m).addTo(map);
    layersControl.addOverlay(categories[category], category);
    }
    categories[category].addLayer(m);




}


来源:https://stackoverflow.com/questions/56856490/jquery-leaflet-marker-layer-cluster-support-with-layers-generated-from-unique-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!