Search code examples
javascriptjsongoogle-mapsgeojsoninfobox

Remove json marker label


I'm trying to remove marker labels created using the InfoBox.js script. The markers are stored as an external geojson point file which I have hosted in the code below. Each marker has a label based on a json property.

The labels show up fine on load and I have a geojson file that loads up when the zoom_changed > 9 Listener is triggered. When this happens the "main" geojson turns off (visible: false) and the "subpoints" turn on. The problem is that the labels for the "main" geojson do not turn off and vise versa for the "subpoints".

Thus far the following stackexchange posts have not helped: "Google Map API - Removing Markers" and "Google forEach map.data feature - return feature LatLng". There have been dozens of other small things I've tried that have not worked that are too numerous to list. To make things easier, here is a jsfiddle that I created: https://jsfiddle.net/tlavery/9jzh41jr/2/. It doesn't run properly right now but I'm sure that's a quick fix for some pro.

I have also tried this same thing with the markerwithlabels.js library. The same issue occurred and the markerwithlabel was a lot slower than the InfoBox.js option.

Here is my simplified code, excluding other original code that works fine:

<!DOCTYPE html>
<html>
<head>
    <title>Label points</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #map {
            height: 100%;
        }

        .labels {             
             font-family: "Lucida Grande", "Arial", sans-serif;
             font-size: 10px;
             font-weight: bold;
             text-align: center;
             width: 40px;            
             white-space: nowrap;
        }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script src="infobox.js" type="text/javascript"></script>  
    <script>
        var map;

        var mapOptions = {
            center: { lat: 49.5, lng: -126.5 },
            zoom: 8,
            maxZoom: 15,
            minZoom: 7,
            scaleControl: true
        };

        var labelArray = [];

        //initMap initiates all the styles and listeners
        function initMap() {           

            map = new google.maps.Map(document.getElementById('map'), mapOptions);

            var harvestPoints = new google.maps.Data();
            harvestPoints.loadGeoJson('https://api.myjson.com/bins/1d9u6');

            var harvestSubPoints = new google.maps.Data();
            harvestSubPoints.loadGeoJson('https://api.myjson.com/bins/3g2qm');

            var areaIcon = function (feature) {
                labelID = "lb" + feature.getProperty('MGNT_AREA').toString();              
                var LatLong = feature.getGeometry().get();
                var labelID = new InfoBox({
                        content: feature.getProperty('MGNT_AREA'),
                        boxStyle: {
                            textAlign: "center",
                            fontSize: "8pt",
                            width: "50px"
                        },
                        disableAutoPan: true,
                        pixelOffset: new google.maps.Size(-25, -24),
                        position: LatLong,
                        closeBoxURL: "",
                        isHidden: false,
                        enableEventPropagation: true,                        
                });               
                labelID.open(map);
                labelArray.push(labelID);//this does not work for some reason
                //there is a custom icon I use for the real page. I won't bother with it here.
                //return ({ icon: 'labels/num_icon.png' });
            };           


            var vFalse = {
                visible: false
            };            

            var styleFeatures = function (hp, hsp) {                
                harvestPoints.setStyle(hp);                
                harvestSubPoints.setStyle(hsp);
            };

            styleFeatures(areaIcon, vFalse);            

            //global InfoWindow variables to display the detailed status text for the subAreaPoints
            var infowindow = new google.maps.InfoWindow({maxWidth: 300});

            harvestSubPoints.addListener('click', function (event) {              
               infowindow.setPosition(event.latLng);
               //the label and the status details are displayed seperated by a ": "
               infowindow.setContent(event.feature.getProperty('LABEL') +": "+ event.feature.getProperty('Details'));
               infowindow.open(map);
            });          

            map.addListener('zoom_changed', function (event) {              
                currentZoom = map.getZoom();
                console.log("currentZoom = " + currentZoom)                
                if (currentZoom > 9) {                    
                    styleFeatures(vFalse, areaIcon);
                } else if (currentZoom <= 9) {                    
                    styleFeatures(areaIcon, vFalse);                  
                    infowindow.close(map);                                   
                    }
                });       

            harvestSubPoints.setMap(map);           
            harvestPoints.setMap(map);            

        };//close the initMap function
        console.log("initMap() finished");
        google.maps.event.addDomListener(window, 'load', initMap);

    </script>
</head>
<body>
    <!--the map css settings from above set the map to take up 100% of the browser window-->
    <div id="map"></div>
</body>
</html>

Solution

  • One option would be to manage the infoboxes separately, have a separate array for each set of markers, add those infoboxes associated with the each layer when the layer is displayed or remove them from the map when hidden:

    // in the global scope
    var labelArray = [];
    var labelArraySub = [];
    
    
    function newLabel(feature) {
        labelID = "lb" + feature.getProperty('MGNT_AREA').toString();
        var LatLong = feature.getGeometry().get();
        var label = new InfoBox({
            content: feature.getProperty('MGNT_AREA'),
            boxStyle: {
                textAlign: "center",
                fontSize: "8pt",
                width: "50px"
            },
            disableAutoPan: true,
            pixelOffset: new google.maps.Size(-25, -24),
            position: LatLong,
            closeBoxURL: "",
            isHidden: false,
            enableEventPropagation: true
        });
        label.open(map);
        return label;
    }
    
    var areaIcon = function (feature) {
        labelArray.push(newLabel(feature)); 
        return ({
            icon: 'http://maps.google.com/mapfiles/ms/micons/blue.png'
        });
    };
    var areaIconS = function (feature) {
        labelArraySub.push(newLabel(feature)); 
        //return ({ icon: 'labels/num_icon.png' });
    };
    
    var styleFeatures = function (hp, hsp) {
        harvestPoints.setStyle(hp);
        harvestSubPoints.setStyle(hsp);
        toggleFeatures(typeof hsp == "function");
    };
    
    function toggleFeatures(sub) {
        for (var i = 0; i < labelArray.length; i++) {
            labelArray[i].setVisible(!sub);
        }
        for (var i = 0; i < labelArraySub.length; i++) {
            labelArraySub[i].setVisible(sub);
        }
    }
    

    proof of concept fiddle

    code snippet:

    var map;
    
    var mapOptions = {
      center: {
        lat: 49.5,
        lng: -126.5
      },
      zoom: 8,
      maxZoom: 15,
      minZoom: 7,
      scaleControl: true
    };
    
    var labelArray = [];
    var labelArraySub = [];
    
    //initMap initiates all the styles and listeners
    function initMap() {
    
        map = new google.maps.Map(document.getElementById('map'), mapOptions);
    
        var harvestPoints = new google.maps.Data();
        harvestPoints.loadGeoJson('https://api.myjson.com/bins/1d9u6');
    
        var harvestSubPoints = new google.maps.Data();
        harvestSubPoints.loadGeoJson('https://api.myjson.com/bins/3g2qm');
    
    
        function newLabel(feature) {
          labelID = "lb" + feature.getProperty('MGNT_AREA').toString();
          var LatLong = feature.getGeometry().get();
          var label = new InfoBox({
            content: feature.getProperty('MGNT_AREA'),
            boxStyle: {
              textAlign: "center",
              fontSize: "8pt",
              width: "50px"
            },
            disableAutoPan: true,
            pixelOffset: new google.maps.Size(-25, -24),
            position: LatLong,
            closeBoxURL: "",
            isHidden: false,
            enableEventPropagation: true
          });
          label.open(map);
          return label;
        }
        var areaIcon = function(feature) {
          labelArray.push(newLabel(feature)); //this does not work for some reason
          //there is a custom icon I use for the real page. I won't bother with it here.
          return ({
            icon: 'http://maps.google.com/mapfiles/ms/micons/blue.png'
          });
        };
        var areaIconS = function(feature) {
          labelArraySub.push(newLabel(feature)); //this does not work for some reason
          //there is a custom icon I use for the real page. I won't bother with it here.
          //return ({ icon: 'labels/num_icon.png' });
        };
    
    
        var vFalse = {
          visible: false
        };
    
        var styleFeatures = function(hp, hsp) {
          harvestPoints.setStyle(hp);
          harvestSubPoints.setStyle(hsp);
          toggleFeatures(typeof hsp == "function");
        };
    
        function toggleFeatures(sub) {
          for (var i = 0; i < labelArray.length; i++) {
            labelArray[i].setVisible(!sub);
          }
          for (var i = 0; i < labelArraySub.length; i++) {
            labelArraySub[i].setVisible(sub);
          }
        }
        styleFeatures(areaIcon, vFalse);
    
        //global InfoWindow variables to display the detailed status text for the subAreaPoints
        var infowindow = new google.maps.InfoWindow({
          maxWidth: 300
        });
    
        harvestSubPoints.addListener('click', function(event) {
          infowindow.setPosition(event.latLng);
          //the label and the status details are displayed seperated by a ": "
          infowindow.setContent(event.feature.getProperty('LABEL') + ": " + event.feature.getProperty('Details'));
          infowindow.open(map);
        });
    
        map.addListener('zoom_changed', function(event) {
          currentZoom = map.getZoom();
          console.log("currentZoom = " + currentZoom);
          if (currentZoom > 9) {
            styleFeatures(vFalse, areaIconS);
          } else if (currentZoom <= 9) {
            styleFeatures(areaIcon, vFalse);
            infowindow.close(map);
          }
        });
    
        harvestSubPoints.setMap(map);
        harvestPoints.setMap(map);
        console.log("initMap() finished");
      } //close the initMap function
    
    google.maps.event.addDomListener(window, 'load', initMap);
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    #map {
      height: 100%;
      width: 100%;
    }
    .labels {
      font-family: "Lucida Grande", "Arial", sans-serif;
      font-size: 10px;
      font-weight: bold;
      text-align: center;
      width: 40px;
      white-space: nowrap;
    }
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script src="https://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
    <title>Label points</title>
    <div id="map"></div>