Google Maps несколько оверлеев JSON с одной и той же функцией SetStyle - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть несколько оверлейных файлов JSON - от 1 до 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');

Я хочу иметь возможность контролировать видимость наложений с помощью меню переключателей.

Также я хочу, чтобы для каждого из оверлеев сохранялась функциональность map.data (установить свойство стиля, информационное окно и т. Д.)

enter image description here

Я пытался установить каждое наложение как переменную и добавить оператор if else для переключения видимости, но он не работает.

Я предполагаю, что вместо одной переменной массив должен обрабатывать var area1 - var area5 , и этот массив должен быть равен map.data

Ниже приведен код, в котором JSON обладает необходимой мне функциональностью, но я не могу включить / выключить оверлеи.

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

Когда карта загружается, я хочу, чтобы была видна только Area1, так как этот параметр радио установлен по умолчанию.

Я хочу, чтобы область 1 имела цвет, и когда я нажимаю на нее, открывается информационное окно

Когда я выбираю другое радио, например Area4, я хочу, чтобы Area1 становился невидимым, а Area4 становился видимым, а также имел ту же функциональность, что и Area1.

1 Ответ

1 голос
/ 16 апреля 2019

Один из вариантов - создание именованных функций для стилизации и обработки событий щелчка и мыши.Присвойте их всем слоям данных

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

подтверждение концепции скрипта

screenshot of map with styling and infowindow

фрагмент кода:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...