0

I have multiple JSON overlay files - Area 1 through 5.

//AREA 1//        
  map.data.loadGeoJson('https://api.myjson.com/bins/myw18');
//AREA 2//  
  map.data.loadGeoJson('https://api.myjson.com/bins/nkbn0');
//AREA 3//  
  map.data.loadGeoJson('https://api.myjson.com/bins/cwnws');
//AREA 4//  
  map.data.loadGeoJson('https://api.myjson.com/bins/106pnw');
//AREA 5//  
  map.data.loadGeoJson('https://api.myjson.com/bins/7lwmk');

I want to be able to control the visibility of the overlays using the radio button menu.

Also I want for each of the overlays to preserve the map.data functionality (set style property, infoWindow, etc)

enter image description here

I've tried setting each overlay as a variable and adding an if else statement to toggle the visibility but it is not working.

I am assuming that instead of one variable an array has to handle var area1 through var area5 and that array has to be equal to map.data

Below is the code where the JSON has the functionality that I want, but I am unable to turn on/off the overlays.

// This example adds a search box to a map, using the Google Place Autocomplete
// feature. People can enter geographical searches. The search box will return a
// pick list containing a mix of places and predicted search terms.

// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">


function initAutocomplete() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 5,
    center: {
      lat: 52.656963,
      lng: -112.506664
    },
    gestureHandling: 'greedy',
    mapTypeControl: false
  });


  var area1 = new google.maps.Data();
  var area2 = new google.maps.Data();
  var area3 = new google.maps.Data();
  var area4 = new google.maps.Data();
  var area5 = new google.maps.Data();


  //AREA 1//		  
  map.data.loadGeoJson('https://api.myjson.com/bins/myw18');
  //AREA 2//	
  map.data.loadGeoJson('https://api.myjson.com/bins/nkbn0');
  //AREA 3//	
  map.data.loadGeoJson('https://api.myjson.com/bins/cwnws');
  //AREA 4//	
  map.data.loadGeoJson('https://api.myjson.com/bins/106pnw');
  //AREA 5//	
  map.data.loadGeoJson('https://api.myjson.com/bins/7lwmk');

  setArea();

  function setArea() {
    area1.setMap(document.getElementById('area1').checked ? map : null);
    area2.setMap(document.getElementById('area2').checked ? map : null);
    area3.setMap(document.getElementById('area3').checked ? map : null);
    area4.setMap(document.getElementById('area4').checked ? map : null);
    area5.setMap(document.getElementById('area5').checked ? map : null);
  }

  google.maps.event.addDomListener(document.getElementById('area1'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area2'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area3'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area4'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area5'), 'click', setArea);



  map.data.setStyle(function(feature) {
    return {
      fillColor: feature.getProperty('COLOR'),
      strokeWeight: 1,
      strokeColor: 'black',
      fillOpacity: 0.4,
      strokeOpacity: 0.7,
      zIndex: 0
    };
  });

  // Infowindow
  var infoWindow = new google.maps.InfoWindow({
    zIndex: 2
  });
  map.data.addListener('click', function(event) {

    map.data.revertStyle();
    map.data.overrideStyle(event.feature, {
      strokeWeight: 2,
      strokeColor: 'black',
      zIndex: 1
    });

    var CDNAME = event.feature.getProperty('CDNAME');
    var COLOR = event.feature.getProperty('COLOR');

    infoWindow.setPosition(event.latLng);
    infoWindow.setOptions({
      pixelOffset: {
        width: 0,
        height: -3
      }
    });

    infoWindow.setContent(
      "CDNAME: <b>" + CDNAME + "</b><br />" +
      "COLOR: <b>" + COLOR + "</b>"
    );
    infoWindow.open(map);

  });

  map.data.addListener('clickout', function(event) {

    map.data.revertStyle();
    infoWindow.close();
  });

  map.data.addListener('mouseover', function(event) {

    map.data.revertStyle();
    map.data.overrideStyle(event.feature, {
      strokeWeight: 2,
      strokeColor: 'black',
      zIndex: 1
    });
  });



  // Create the search box and link it to the UI element.
  var input = document.getElementById('pac-input');
  var searchBox = new google.maps.places.SearchBox(input);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);

  // Bias the SearchBox results towards current map's viewport.
  map.addListener('bounds_changed', function() {
    searchBox.setBounds(map.getBounds());
  });

  var markers = [];
  // Listen for the event fired when the user selects a prediction and retrieve
  // more details for that place.
  searchBox.addListener('places_changed', function() {
    var places = searchBox.getPlaces();

    if (places.length == 0) {
      return;
    }

    // Clear out the old markers.
    markers.forEach(function(marker) {
      marker.setMap(null);
    });
    markers = [];

    // For each place, get the icon, name and location.
    var bounds = new google.maps.LatLngBounds();
    places.forEach(function(place) {
      if (!place.geometry) {
        console.log("Returned place contains no geometry");
        return;
      }
      var icon = {
        url: 'https://www.adsforcarts.com/wp-content/uploads/2017/09/map-marker2.png',
        size: new google.maps.Size(50, 75),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(25, 75)
      };

      // Create a marker for each place.
      markers.push(new google.maps.Marker({
        map: map,
        icon: icon,
        title: place.name,
        position: place.geometry.location,
        animation: google.maps.Animation.DROP
      }));

      if (place.geometry.viewport) {
        // Only geocodes have viewport.
        bounds.union(place.geometry.viewport);
      } else {
        bounds.extend(place.geometry.location);
      }
    });
    map.fitBounds(bounds);
  });
}
/* Always set the map height explicitly to define the size of the div
		   * element that contains the map. */

#map {
  height: 100%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#description {
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
}

#infowindow-content .title {
  font-weight: bold;
}

#infowindow-content {
  display: none;
}

#map #infowindow-content {
  display: inline;
}

.pac-card {
  margin: 10px 10px 0 0;
  border-radius: 2px 0 0 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  outline: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  background-color: #fff;
  font-family: Roboto;
}

#pac-container {
  padding-bottom: 12px;
  margin-right: 12px;
}

.pac-controls {
  display: inline-block;
  padding: 5px 11px;
}

#search {
  position: absolute;
}

#pac-input {
  width: 400px;
  margin: 10px;
  padding: 0 11px 0 13px;
  height: 40px;
  background-color: #fff;
  font-family: Roboto;
  font-size: 17px;
  font-weight: 300;
  text-overflow: ellipsis;
  width: 320px;
  height: 40px;
  border-width: 2px;
  border: white;
  box-shadow: none;
  border-radius: 2px;
  box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
  font-family: Roboto, Arial, sans-serif;
  font-weight: 400;
  color: gray;
}

#pac-input:focus {
  border-color: #4d90fe;
  color: black;
}

#title {
  color: #fff;
  background-color: #4d90fe;
  font-size: 25px;
  font-weight: 500;
  padding: 6px 12px;
}

#target {
  width: 345px;
}
<div id="search">
  <input id="pac-input" class="controls" type="search" placeholder="Search Any Address">
</div>
<form class="form">
  <div class="switch-field">
    <input type="radio" id="area1" name="switch-two" checked/>
    <label for="area1">Area 1</label>

    <input type="radio" id="area2" name="switch-two" />
    <label for="area2">Area 2</label>

    <input type="radio" id="area3" name="switch-two" />
    <label for="area3">Area 3</label>

    <input type="radio" id="area4" name="switch-two" />
    <label for="area4">Area 4</label>

    <input type="radio" id="area5" name="switch-two" />
    <label for="area5">Area 5</label>
  </div>
</form>
<div id="map"></div>

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initAutocomplete" async defer></script>

When the map loads I want only the Area1 to be visible since that radio option is checked by default.

I want Area 1 to have the color and when I click on it for an infoWindow to open up

When I choose another radio, Area4 for example, I want Area1 to become invisible and Area4 to become visible and also have the same functionality as Area1.

  • Shouldn't map.data.loadGeoJson be like area1.loadGeoJson? – StackSlave Apr 16 at 0:28
  • Correct! but the you'd have to add logic for areas 2-5. Too much code that way – Discover Apr 16 at 16:33
1

One option is to create named functions for styling and handling click and mouse over events. Assign those to all of the data layers

function createArea(url) { // create an "area" from its URL and assign all the event listeners
  var area = new google.maps.Data();
  area.loadGeoJson(url);
  area.setStyle(styleFunc);
  area.addListener('click', clickFunc);
  area.addListener('mouseover', mouseFunc);
  return area;
}

function clickFunc(event) { // handle layer clicks
  this.revertStyle();
  this.overrideStyle(event.feature, {
    strokeWeight: 2,
    strokeColor: 'black',
    zIndex: 1
  });

  var CDNAME = event.feature.getProperty('CDNAME');
  var COLOR = event.feature.getProperty('COLOR');

  infoWindow.setPosition(event.latLng);
  infoWindow.setOptions({
    pixelOffset: {
      width: 0,
      height: -3
    }
  });

  infoWindow.setContent(
    "CDNAME: <b>" + CDNAME + "</b><br />" +
    "COLOR: <b>" + COLOR + "</b>"
  );
  infoWindow.open(map);
}

function mouseFunc(event) {  // handle layer mouse over events
  this.revertStyle();
  this.overrideStyle(event.feature, {
    strokeWeight: 2,
    strokeColor: 'black',
    zIndex: 1
  });
}

proof of concept fiddle

screenshot of map with styling and infowindow

code snippet:

function initAutocomplete() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 5,
    center: {
      lat: 52.656963,
      lng: -112.506664
    },
    gestureHandling: 'greedy',
    mapTypeControl: false
  });

  var area1 = createArea('https://api.myjson.com/bins/myw18');
  var area2 = createArea('https://api.myjson.com/bins/nkbn0');
  var area3 = createArea('https://api.myjson.com/bins/cwnws');
  var area4 = createArea('https://api.myjson.com/bins/106pnw');
  var area5 = createArea('https://api.myjson.com/bins/7lwmk');

  function styleFunc(feature) {
    return {
      fillColor: feature.getProperty('COLOR'),
      strokeWeight: 1,
      strokeColor: 'black',
      fillOpacity: 0.4,
      strokeOpacity: 0.7,
      zIndex: 0
    };
  }

  // Infowindow
  var infoWindow = new google.maps.InfoWindow({
    zIndex: 2
  });
  map.addListener('click', function() {
    area1.revertStyle();
    area2.revertStyle();
    area3.revertStyle();
    area4.revertStyle();
    area5.revertStyle();
    infoWindow.close();
  })

  function clickFunc(event) {
    this.revertStyle();
    this.overrideStyle(event.feature, {
      strokeWeight: 2,
      strokeColor: 'black',
      zIndex: 1
    });

    var CDNAME = event.feature.getProperty('CDNAME');
    var COLOR = event.feature.getProperty('COLOR');

    infoWindow.setPosition(event.latLng);
    infoWindow.setOptions({
      pixelOffset: {
        width: 0,
        height: -3
      }
    });

    infoWindow.setContent(
      "CDNAME: <b>" + CDNAME + "</b><br />" +
      "COLOR: <b>" + COLOR + "</b>"
    );
    infoWindow.open(map);
  }


  function mouseFunc(event) {
    this.revertStyle();
    this.overrideStyle(event.feature, {
      strokeWeight: 2,
      strokeColor: 'black',
      zIndex: 1
    });
  }

  function createArea(url) {
    var area = new google.maps.Data();
    area.loadGeoJson(url);
    area.setStyle(styleFunc);
    area.addListener('click', clickFunc);
    area.addListener('mouseover', mouseFunc);
    return area;
  }

  setArea();

  function setArea() {
    infoWindow.close();
    area1.setMap(document.getElementById('area1').checked ? map : null);
    area2.setMap(document.getElementById('area2').checked ? map : null);
    area3.setMap(document.getElementById('area3').checked ? map : null);
    area4.setMap(document.getElementById('area4').checked ? map : null);
    area5.setMap(document.getElementById('area5').checked ? map : null);
  }

  google.maps.event.addDomListener(document.getElementById('area1'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area2'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area3'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area4'), 'click', setArea);
  google.maps.event.addDomListener(document.getElementById('area5'), 'click', setArea);

}
#map {
  height: 90%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<form class="form">
  <div class="switch-field">
    <input type="radio" id="area1" name="switch-two" checked/>
    <label for="area1">Area 1</label>

    <input type="radio" id="area2" name="switch-two" />
    <label for="area2">Area 2</label>

    <input type="radio" id="area3" name="switch-two" />
    <label for="area3">Area 3</label>

    <input type="radio" id="area4" name="switch-two" />
    <label for="area4">Area 4</label>

    <input type="radio" id="area5" name="switch-two" />
    <label for="area5">Area 5</label>
  </div>
</form>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initAutocomplete" async defer></script>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.