Google Maps Api: невозможно щелкнуть по кликабельному многоугольнику позади слоя данных

Привет, я использую API Google Maps (JavaScript) для создания интерактивной карты мира. Все шло очень хорошо, пока я не столкнулся с этой проблемой. Я использую полигоны, чтобы показать контур страны. Эти полигоны запускают модальную информацию, показывающую информацию о стране при нажатии. Это работало, пока я не начал использовать "Уровень данных: данные о землетрясениях". Вместо данных о землетрясениях я использую информацию о продажах компании, в которой я работаю. Таким образом, если большая часть наших клиентов из Нидерландов, то слой данных, назначенный Нидерландам, будет очень большим. Проблема в том, что из-за слоев данных страны больше не кликабельны. Я не могу нажать "через" слой данных. Есть ли вероятность, что я могу вызвать событие позади слоя данных?

Этот код отображает слои данных:

map.data.loadGeoJson('./data/test.json');

map.data.setStyle(function(feature) {
  var percentage = parseFloat(feature.getProperty('percentage'));
  return ({
    icon: {
      path: google.maps.SymbolPath.CIRCLE,
      scale: percentage,
      fillColor: '#00ff00',
      fillOpacity: 0.35,
      strokeWeight: 0
    }
  })

});

map.data.addListener('mouseover', function(event) {
  map.data.overrideStyle(event.feature, {
    title: 'Hello, World!'
  });
});

map.data.addListener('mouseout', function(event) {
  map.data.revertStyle();
});

function eqfeed_callback(data) {
  map.data.addGeoJson(data);
}

Этот код отображает полигоны:

function drawMap(data) {

  var rows = data['rows'];
  for (var i in rows) {
    if (rows[i][0] != 'Antarctica') {


      var newCoordinates = [];
      var geometries = rows[i][1]['geometries'];

      if (geometries) {
        for (var j in geometries) {
          newCoordinates.push(constructNewCoordinates(geometries[j]));
        }
      } else {
        newCoordinates = constructNewCoordinates(rows[i][1]['geometry']);
      }
      var country = new google.maps.Polygon({
        paths: newCoordinates,
        strokeColor: 'transparent',
        strokeOpacity: 1,
        strokeWeight: 0.3,
        fillColor: '#cd0000',
        fillOpacity: 0,
        name: rows[i][0]

      });
      google.maps.event.addListener(country, 'mouseover', function() {
        this.setOptions({
          fillOpacity: 0.3
        });
      });
      google.maps.event.addListener(country, 'mouseout', function() {
        this.setOptions({
          fillOpacity: 0
        });
      });
      google.maps.event.addListener(country, 'click', function() {
        var countryName = this.name;
        var code = convert(countryName); // Calls a function that converts the name of the country to its official ISO 3166-1 alpha-2 code.
        var modal = document.querySelector('.modal');
        var instance = M.Modal.init(modal);
        instance.open();

      });


      country.setMap(map);
    }
  }

Если прочитать в документации, что изменение zIndex не будет работать, потому что "Маркеры всегда отображаются перед строками и полигонами".

Есть ли способ нажать на многоугольник позади слоя данных?

РЕДАКТИРОВАТЬ Я попытался дать многоугольнику более высокий zIndex, и я сделал слой данных не кликабельным

map.data.loadGeoJson('./data/test.json');

map.data.setStyle(function(feature) {
  var percentage = parseFloat(feature.getProperty('percentage'));

  return ({
    icon: {
      path: google.maps.SymbolPath.CIRCLE,
      scale: percentage,
      fillColor: '#00ff00',
      fillOpacity: 0.35,
      strokeWeight: 0,
      clickAble: false,
      zIndex: 50


    }
  })

});

function eqfeed_callback(data) {
  map.data.addGeoJson(data);
}


function drawMap(data) {

  var rows = data['rows'];
  for (var i in rows) {
    if (rows[i][0] != 'Antarctica') {


      var newCoordinates = [];
      var geometries = rows[i][1]['geometries'];

      if (geometries) {
        for (var j in geometries) {
          newCoordinates.push(constructNewCoordinates(geometries[j]));
        }
      } else {
        newCoordinates = constructNewCoordinates(rows[i][1]['geometry']);
      }
      var country = new google.maps.Polygon({
        paths: newCoordinates,
        strokeColor: 'transparent',
        strokeOpacity: 1,
        strokeWeight: 0.3,
        fillColor: '#cd0000',
        fillOpacity: 0,
        name: rows[i][0],
        zIndex: 100

      });
      google.maps.event.addListener(country, 'mouseover', function() {
        this.setOptions({
          fillOpacity: 0.3
        });
      });
      google.maps.event.addListener(country, 'mouseout', function() {
        this.setOptions({
          fillOpacity: 0
        });
      });
      google.maps.event.addListener(country, 'click', function() {
        var countryName = this.name;
        var code = convert(countryName); // Calls a function that converts the name of the country to its official ISO 3166-1 alpha-2 code.
        var modal = document.querySelector('.modal');
        var instance = M.Modal.init(modal);
        instance.open();

      });


      country.setMap(map);
    }
  }
  //console.log(map);
  //test(map)
}

РЕДАКТИРОВАТЬ Очевидно, что слой данных не проблема, но значок был. Вот почему это не сработало, когда я сделал это:

     map.data.setStyle(function(feature) {
        var percentage = parseFloat(feature.getProperty('percentage'));

        return ({
            icon: {
                path: google.maps.SymbolPath.CIRCLE,
                scale: percentage,
                fillColor: '#00ff00',
                fillOpacity: 0.35,
                strokeWeight: 0,
                clickable: false
            }

        })

    });

Правильный способ сделать это это:

    map.data.setStyle(function(feature) {
        var percentage = parseFloat(feature.getProperty('percentage'));

        return ({
            icon: {
                path: google.maps.SymbolPath.CIRCLE,
                scale: percentage,
                fillColor: '#00ff00',
                fillOpacity: 0.35,
                strokeWeight: 0
            },
            clickable: false
        })

    });

1 ответ

Решение

У вас есть 2 варианта:

  1. Установить zIndex ваших полигонов на большее число, чем слой данных. Ваши полигоны будут кликабельными, но, очевидно, будут отображаться над слоем данных, что может быть не тем, что вы хотите.

  2. Установить clickable Свойство слоя данных имеет значение false, чтобы можно было щелкать элементы ниже. Это будет работать, если вам не нужно реагировать на клики на слое данных...

Вариант 2, пример кода:

map.data.setStyle({
    clickable: false
});

Изменить: полный рабочий пример ниже, используя опцию 2. Как вы можете видеть, полигон находится ниже слоя данных, но вы все равно можете щелкнуть по нему.

function initMap() {

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {
      lat: -28,
      lng: 137
    }
  });

  var polygon = new google.maps.Polygon({
    strokeOpacity: 0,
    strokeWeight: 0,
    fillColor: '#00FF00',
    fillOpacity: .6,
    paths: [
      new google.maps.LatLng(-26, 139),
      new google.maps.LatLng(-23, 130),
      new google.maps.LatLng(-35, 130),
      new google.maps.LatLng(-26, 139)
    ],
    map: map
  });

  polygon.addListener('click', function() {

    console.log('clicked on polygon');
  });

  // Load GeoJSON
  map.data.loadGeoJson('https://storage.googleapis.com/mapsdevsite/json/google.json');

 // Set style
  map.data.setStyle({
    fillColor: '#fff',
    fillOpacity: 1,
    clickable: false
  });
}
#map {
  height: 200px;
}
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
<div id="map"></div>

Я обнаружил, что после установки z-порядка api карт ненадежно отправляет щелчки на полигональный объект в верхнем слое, когда много полигонов.

У меня был один уровень данных регионов, где каждая функция является границей участка. Когда вы нажимаете на один объект, он загружает другой слой данных поверх. Верхний слой состоит из многоугольников внутри области с более высоким z-порядком, представляющих границы названия дома в этой области.

После загрузки домов нажатие на дом должно отправить щелчок на многоугольник дома, а не на регион. Но иногда это не удавалось - особенно если домов много.

Чтобы решить эту проблему, после нажатия на функцию региона я установил, что эта функция неактивна. Тогда щелчки всегда переходят к правильному объекту дома. Вы по-прежнему можете нажимать на другие объекты нижнего слоя, но не на выбранный. Это решение должно работать, если ваши данные и презентация построены по аналогичной схеме.

/* private utility is only called by this.hideOnlyMatchingFeaturesFromLayer() */
  _overrideStyleOnFeature(feature, layer, key, value,  overrideStyle, defaultStyle) {
    if (feature.getProperty(key) === value) {
      if (this.map) {
        layer.overrideStyle(feature, overrideStyle);
      }
    } else {
      if (this.map) {
        layer.overrideStyle(feature, defaultStyle);
      }
    }
  }

  /* Apply an overrideStyle style to features in a data layer that match key==value
   * All non-matching features will have the default style applied.
   * Otherwise all features except the matching feature is hidden!
   * Examples:
   *    overrideStyle = { clickable: false,strokeWeight: 3}
   *    defaultStyle = { clickable: true,strokeWeight: 1}
   */

  overrideStyleOnMatchingFeaturesInLayer(layer, key, value, overrideStyle, defaultStyle) {
    layer.forEach((feature) => {
      if (Array.isArray(feature)) {
        feature.forEach((f) => {
          _overrideStyleOnFeature(f, layer, key, value, overrideStyle, defaultStyle);
        });
      } else {
        _overrideStyleOnFeature(feature, layer, key, value, overrideStyle, defaultStyle);
      }
    });
  }

  /* example usage */
  overrideStyleOnMatchingFeaturesInLayer(
    theRegionsDataLayer,
    'PROP_NAME',
    propValue,
    { clickable: false, strokeWeight: 3},
    { clickable: true, strokeWeight: 1}
);

Другие вопросы по тегам