Создание пользовательского элемента управления и связывание с элементом HTML - PullRequest
0 голосов
/ 12 марта 2020

Я использую OpenLayers 6. Я пытаюсь создать собственный элемент управления геолокации, который запускается при нажатии. Кнопки HTML, расположенные за пределами карты.

Вот определение кнопки расположения кнопки вне карты:

   <div data-role="footer" data-position="fixed" class="centered-butons">
    <div data-role="controlgroup" id="footerControls" data-type="horizontal" style="text-align: center" data-theme="b">

        <a href="#streetsearchpage" data-role="button" data-mini="true" data-icon="search" data-transition="none">Search</a>
        <a href="#" id="locate" data-role="button" data-mini="true" data-icon="location" data-transition="none">Location</a>
    </div>
   </div>   

А вот как я пытаюсь создать пользовательский элемент управления:

 var LocateControl = /*@__PURE__*/(function (Control) {
    function LocateControl(opt_options) {

        var target = document.querySelector('#locate');

        Control.call(this, {
            //element: element
            target: target
        });

        element.addEventListener('click', this.handleLocateTo.bind(this), false);
    }

    //some logic

    return LocateControl;
}(ol.control.Control));

Я не хочу создавать динамически кнопку и использовать свойство элемента внутри функции вызова, вместо этого я хочу использовать кнопку, которая уже существует (id = "locate").

Итак, я попробовал код выше и получаю эту ошибку:

    Uncaught ReferenceError: element is not defined

Есть ли способ связать пользовательский элемент управления с существующей кнопкой вне карты (в моем случае id = "locate") ?

1 Ответ

0 голосов
/ 12 марта 2020

Я думаю, что ваша ошибка при создании элемента управления по методу call. Вы устанавливаете цель, но в вашем случае вам это не нужно, потому что вы не собираетесь ничего там размещать. Кроме того, у вас может быть ошибка. Если вы не предоставите элемент Node in, он может работать, но вы можете увидеть его в консоли.

Здесь я взял пример пользовательского элемента управления OL и изменил его так он использует внешнюю кнопку.

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
			#a { display: none; }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
    <title>Custom Control</title>
  </head>
  <body>
    <div>Reset Rotation:
      <button id="b">N</button>
    </div>
    <div id="map" class="map"></div>
    <script type="text/javascript">
    var RotateNorthControl = /*@__PURE__*/(function (Control) {
      function RotateNorthControl(opt_options) {
        var options = opt_options || {};
        var button = document.getElementById('b');
        Control.call(this, {
          element: document.createElement('div'),
          target: options.target
        });
        button.addEventListener('click', this.handleRotateNorth.bind(this), false);
      }
      if ( Control ) RotateNorthControl.__proto__ = Control;
      RotateNorthControl.prototype = Object.create( Control && Control.prototype );
      RotateNorthControl.prototype.constructor = RotateNorthControl;
      RotateNorthControl.prototype.handleRotateNorth = function handleRotateNorth () {
        this.getMap().getView().setRotation(0);
      };

      return RotateNorthControl;
    }(ol.control.Control));
    var map = new ol.Map({
      controls: ol.control.defaults().extend([
        new RotateNorthControl()
      ]),
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        })
      ],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 3,
        rotation: 1
      })
    });
    </script>
  </body>
</html>

Обновление

Возможно, реальный ответ на вашу проблему состоит в том, что вам не нужен пользовательский элемент управления в вашем случае. Дело в том, что в принципе вы можете решить свою проблему, связав событие onclick кнопки с какой-то функцией, которая делает то, что вы хотите. Однако, возможно, я не вижу всю картину.

Свойство target позволяет привязать элемент управления к элементу вне элемента управления картой. В то время как свойство элемента является контейнером пользовательского элемента управления.

Поэтому в первом решении я обманул, предоставив им пустые узлы (я признаю, что это, вероятно, не лучшее решение).

Проверьте этот новый пример, который я сделал для вас, со случаями всего этого,

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
			#ovmap { height: 150px; margin-top: 20px;}
    </style>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
    <title>Controls</title>
  </head>
  <body>
    <div class="container">
      <div class="row mt-2">
        <div class="col">
          <h3>Button</h3>
          <button id="b" type="button" class="btn btn-primary"
          onclick="handleRotateNorth()">N</button>
        </div>
        <div class="col">
          <h3>OverviewMap</h3>
          <div id="ovmap"></div>
        </div>
        <div class="col">
          <h3>Scaleline</h3>
          <div id="scale"></div>
        </div>
      </div>
      <div class="row mt-2">
        <div id="map" class="map"></div>
      </div>
    </div>
    <script type="text/javascript">
    var source = new ol.source.OSM();
    var overviewMapControl = new ol.control.OverviewMap({
      layers: [
        new ol.layer.Tile({
          source: source
        })
      ],
      target: document.getElementById('ovmap'),
      collapsed: false
    });
    var scalelineControl = new ol.control.ScaleLine({
      target: document.getElementById('scale')
    });
    var map = new ol.Map({
      controls: ol.control.defaults().extend([
        overviewMapControl,
        scalelineControl
      ]),
      layers: [
        new ol.layer.Tile({
          source: source
        })
      ],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 3,
        rotation: 1
      })
    });
    function handleRotateNorth () {
        map.getView().setRotation(0);
    };
    </script>
  </body>
</html>
...