jQuery Leaflet Marker Layer Cluster Support,具有从唯一的json值生成的图层-Leaflet.FeatureGroup.SubGroup [英] Jquery Leaflet Marker Layer Cluster Support with layers generated from unique json values- Leaflet.FeatureGroup.SubGroup

查看:143
本文介绍了jQuery Leaflet Marker Layer Cluster Support,具有从唯一的json值生成的图层-Leaflet.FeatureGroup.SubGroup的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够使它工作.我让它变得比实际更难了!

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


这是我目前所拥有的工作提琴的链接.它具有单独的层,但是没有我要实现的聚类功能.

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


我已经更新了我的JS,该版本映射了一个集群层,并根据JSON中列出的分类对三个单独的层进行了映射.

我的愿望是实现:

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

为了摆脱多余的群集层并将三个单独的层群集在一起.

我不确定如何更改此部分以适应上面的插件.

//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 );


我以前在这里问过一个问题:

Jquery小叶标记层控件带有集群插件的动态自定义图标

哪个指向我指向此插件:

使用多个标记群集组显示重叠的群集

还有这个线程:

使用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"
  }
]

图标

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

解决方案

通过以下代码,我能够使所有魔术发生.这将基于JSON字段创建动态图层,然后允许根据当前选择的图层将这些图层动态聚在一起.

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);




}

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.

解决方案

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);




}

这篇关于jQuery Leaflet Marker Layer Cluster Support,具有从唯一的json值生成的图层-Leaflet.FeatureGroup.SubGroup的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆