Как наложить точечный объект на полигональный объект

Как я могу получить точечный объект вместо полигонального? Я накладываю многоугольник поверх точечного объекта или маркера, однако у меня также есть всплывающая подсказка (всплывающее окно), которая срабатывает при наведении курсора на объекты, но отображается только всплывающее окно многоугольника, даже когда я нахожусь над точкой / маркером. Я уверен, что точка/маркер находится над/поверх многоугольника, потому что я установил непрозрачность 1,0, и точка/маркер все еще видна.

Итак, когда точка находится поверх многоугольника, как я могу запустить всплывающее окно на функции точки/маркера? Или это потенциальный дефект?

Я заменил событие наведения на событие «щелчок» в функции точки/маркера, и всплывающее окно работает, как и ожидалось, но это нежелательное поведение.

ТИА! Рик...


person Rick    schedule 08.04.2020    source источник
comment
С тех пор я узнал, что это ожидаемое поведение, когда функции перекрываются. Это связано с тем, что событие не запускается повторно при нахождении над точкой из-за того, что карта все еще видит курсор как находящийся над полигоном... по сути, курсор никогда не покидал полигональный слой. Существует очень крошечная область точки, в которой, если я наведу курсор в нужное место, появится всплывающее окно точки, но если я немного сдвинусь, всплывающее окно многоугольника появится снова. Ну что ж...   -  person Rick    schedule 08.04.2020


Ответы (1)


Я провел кучу экспериментов, и именно порядок добавления событий имеет значение, а не порядок слоев в данном случае. Если вы не добавляете события на карту, а не в отдельные слои, используется порядок рендеринга.

Я собрал небольшое тестовое приложение для проверки всех различных сценариев:

var map, datasource, output, polygonLayer, pointLayer, isSwapped = false;

function GetMap() {
  output = document.getElementById('output');

  //Initialize a map instance.
  map = new atlas.Map('myMap', {
    center: [-122.1255, 47.6305],
    zoom: 17,
    view: 'Auto',

    //Add your Azure Maps subscription key to the map SDK. Get an Azure Maps key at https://azure.com/maps
    authOptions: {
      authType: 'subscriptionKey',
      subscriptionKey: subscriptionKey
    }
  });

  //Wait until the map resources are ready.
  map.events.add('ready', function() {

    //Create a data source and add it to the map.
    datasource = new atlas.source.DataSource();
    map.sources.add(datasource);

    //Add polygon to data source.
    datasource.add(new atlas.data.Polygon(
      [
        [
          [-122.126, 47.63096],
          [-122.12602, 47.62997],
          [-122.12537, 47.62994],
          [-122.12534, 47.63094],
          [-122.12600, 47.63096]
        ]
      ]
    ));

    //Add point data
    datasource.add(new atlas.data.Point([-122.1255, 47.6305]));

    polygonLayer = new atlas.layer.PolygonLayer(datasource, null, {
      fillColor: 'red'
    });


    pointLayer = new atlas.layer.SymbolLayer(datasource, null, {
      filter: ['==', ['geometry-type'], 'Point']
    });

    map.layers.add([polygonLayer, pointLayer]);

    map.events.add('mousemove', layerHovered);
  });
}

function layerHovered(e) {
  var msg = [];

  if (e.shapes && e.shapes.length > 0) {
    msg.push(e.shapes.length, ' shapes hovered.<ul>');

    e.shapes.forEach(s => {
      if (s instanceof atlas.Shape) {
        msg.push('<li>Shape: ', s.getType(), '</li>');
      } else {
        msg.push('<li>Feature: ', s.geometry.type, ' (', s.source, ' -> ', s.sourceLayer, ')</li>');
      }
    });

    msg.push('</ul>');
  }

  output.innerHTML = msg.join('');
}

function swapLayerOrder() {
  map.layers.remove([pointLayer, polygonLayer]);

  if (isSwapped) {

    map.layers.add([polygonLayer, pointLayer]);
  } else {
    map.layers.add([pointLayer, polygonLayer]);
  }

  isSwapped = !isSwapped;
}

function changeEvents(elm) {
  map.events.remove('mousemove', layerHovered);
  map.events.remove('mousemove', pointLayer, layerHovered);
  map.events.remove('mousemove', polygonLayer, layerHovered);

  switch (elm.value) {
    case 'map':
      map.events.add('mousemove', layerHovered);
      break;
    case 'ps':
      map.events.add('mousemove', [polygonLayer, pointLayer], layerHovered);
      break;
    case 'sp':
      map.events.add('mousemove', [pointLayer, polygonLayer], layerHovered);
      break;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <title></title>

  <meta charset="utf-8" />

  <!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
  <link rel="stylesheet" href="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.css" type="text/css" />
  <script src="https://atlas.microsoft.com/sdk/javascript/mapcontrol/2/atlas.min.js"></script>  
</head>

<body onload="GetMap()">
      <div id="myMap" style="position:relative;width:100%;height:600px;"></div>

	<div style="position:absolute;top: 10px;left:10px;background-color:white;padding:10px;">
	
		<input type="button" onclick="swapLayerOrder()" value="Swap layer order"/>
		
		<br/><br/>
		
		Attach event to:<br/>
		<input type="radio" name="gender" value="map" checked="checked" onclick="changeEvents(this)"/> map<br/>
		<input type="radio" name="gender" value="ps" onclick="changeEvents(this)"/> polygon layer then symbol layer<br/>
		<input type="radio" name="gender" value="sp" onclick="changeEvents(this)"/> symbol layer then polygon layer<br/>
		
		<br/>
		
		<div id="output"></div>
	
	</div>
    <script>var subscriptionKey = atob('dFRrMUpWRWFlTnZEa3h4bnhIbTljWWFDdnFsT3ExdS1mWFR2eVhuMlhrQQ==')</script>
</body>

</html>

person rbrundritt    schedule 09.04.2020
comment
Хорошо, мне удалось принять ваш вклад и изменить порядок событий на слоях, и теперь я получаю хорошие результаты. Однако возникает проблема, если точечный объект является маркером. Я добавляю пульсирующий маркер, чтобы представить датчик IoT, отправляющий сигнал. У меня есть всплывающее окно, и слой и событие добавляются после многоугольника и точечного объекта, который представляет объект (точка при уменьшении масштаба; многоугольник при увеличении), но маркер включен на всех уровнях масштабирования. Если я не выключу многоугольник, я не смогу вывести маркер на всплывающую информацию. Хотел бы добавить точки, а затем стилизовать их как маркер пульсирующего типа. Спасибо еще раз! - person Rick; 13.04.2020
comment
Маркеры и всплывающие окна используют традиционные элементы DOM. Они всегда отображаются поверх других элементов карты, поскольку их невозможно отобразить на холсте WebGL. Не уверен, что понимаю вашу проблему. Я бы подумал, что маркер даже будет запущен первым, поскольку мышь ударит по нему первой, но, возможно, карта улавливает событие и запускает события в зависимости от порядка их добавления. В зависимости от того, насколько велик ваш набор данных, можно создать эффект пульсации, используя пузырьковый слой со слоем символов. - person rbrundritt; 14.04.2020
comment
Спасибо еще раз! Я хотел бы увидеть, как будут созданы пузырьковый слой и символьный слой, мой набор данных невелик. Во всех примерах я нахожу следующие комментарии к созданию события: Откройте всплывающее окно при перемещении мыши или касании на слое формы/символа. Mousemove используется, когда наведение мыши срабатывает только тогда, когда мышь изначально проходит по фигуре/символу. Если две формы и/или символы перекрываются, перемещение мыши от одной к другой не вызовет событие для новой формы/символа, поскольку мышь по-прежнему считается над исходным слоем. Опять же, кажется, что это относится только к символу маркера... точки и многоугольники не проблема - person Rick; 14.04.2020
comment
Я собрал образец и обнаружил, что он работает и с большими наборами данных (пробовал до 100 000 точек). Образец можно найти здесь: azuremapscodesamples.azurewebsites.net / - person rbrundritt; 14.04.2020
comment
Спасибо большое... Просто СУПЕР! - person Rick; 14.04.2020