Листовка пользовательских координат на изображении

1

У меня есть изображение размером 8576x8576px, и я хочу, чтобы координаты совпадали с 1:1. Также я хочу, чтобы координаты 0,0 были в центре изображения (теперь центр -128,128). И я тоже хочу показать координаты. Я хочу поместить кнопку locate для пользовательских координат вставки, а затем найти их на карте. Что-то вроде этого: http://xero-hurtworld.com/map_steam.php (Я использую то же изображение, но больше). Размер плитки я сделал 268px.

Мой код:

https://jsfiddle.net/ze62dte0/

<!DOCTYPE html>
<html>
  <head>
    <title>Map</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.css" />
    <!--[if lte IE 8]>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.ie.css" />
    <![endif]-->
    <script src="http://cdn.leafletjs.com/leaflet-0.6.4/leaflet.js" charset="utf-8"></script>
    <script>
      function init() {
        var mapMinZoom = 0;
        var mapMaxZoom = 3;
        var map = L.map('map', {
          maxZoom: mapMaxZoom,
          minZoom: mapMinZoom,
          crs: L.CRS.Simple
        }).setView([0, 0], mapMaxZoom);



    window.latLngToPixels = function(latlng){
    return window.map.project([latlng.lat,latlng.lng], window.map.getMaxZoom());
    };
    window.pixelsToLatLng = function(x,y){
    return window.map.unproject([x,y], window.map.getMaxZoom());
    };

        var mapBounds = new L.LatLngBounds(
            map.unproject([0, 8576], mapMaxZoom),
            map.unproject([8576, 0], mapMaxZoom));

        map.fitBounds(mapBounds);
        L.tileLayer('{z}/{x}/{y}.jpg', {
          minZoom: mapMinZoom, maxZoom: mapMaxZoom,
          bounds: mapBounds,
          noWrap: true,
          tms: false
        }).addTo(map);

        L.marker([0, 0]).addTo(map).bindPopup("Zero");

        L.marker([-128, 128]).addTo(map).bindPopup("center");

        var popup = L.popup();

        <!-- Click pop-up>
        var popup = L.popup();

        function onMapClick(e) {
            popup
            .setLatLng(e.latlng)
            .setContent("You clicked in " + e.latlng.toString ())
            .openOn(map);
        }

        map.on('click', onMapClick);

      }
    </script>
    <style>
      html, body, #map { width:100%; height:100%; margin:0; padding:0; }
    </style>
  </head>
  <body onload="init()">
    <div id="map"></div>
  </body>
</html>
Теги:
leaflet
dictionary

1 ответ

5
Лучший ответ

Если я правильно понимаю, вы хотите, чтобы CRS, подобный L.CRS.Simple, помещал tile 0/0/0 (размер плитки 268px, который равен 8576/2⁵), чтобы:

  • Позиция [0, 0] находится в центре этой плитки.
  • Весь мир (т.е. целая плитка 0/0/0) переходит из положения [-8576/2, -8576/2] в [8576/2, 8576/2].

Вам просто нужно отрегулировать L.CRS.Simple с соответствующим преобразованием, чтобы учитывать этот масштаб 1/2⁵ = 1/32 (вместо 1) и смещение 8576 * 1/32/2 = 268/2 = 134 (вместо 0,5).

L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
  transformation: new L.Transformation(1 / 32, 134, -1 / 32, 134)
});

var map = L.map('map', {
  maxZoom: mapMaxZoom,
  minZoom: mapMinZoom,
  crs: L.CRS.MySimple
}).setView([0, 0], mapMaxZoom);

Демо: http://plnkr.co/edit/5SQqp7SP4nf8muPM5iso?p=preview (я использовал Plunker вместо jsfiddle, потому что вы предоставили полный код страницы с HTML, тогда как jsfiddle ожидает, что вы разделите ваши HTML, CSS и JavaScript кодируются в отдельные блоки).

Что касается отображения координат и кнопки "Найти", было бы довольно легко реализовать, чтобы он был похож на пример, который вы упомянули. Не стесняйтесь открывать новые вопросы, если вам нужна помощь.

В приведенном выше примере я использовал Leaflet.Coordinates plugin, чтобы быстро реализовать обе функции (см. элемент управления в нижнем левом углу карты; вам нужно приступить к перемещению мыши на карте для отображения координат, нажмите на этот элемент управления, чтобы открыть режим издания).


EDIT:

Что касается плагина Leaflet.Coordinates, он переносит отображаемую координату долготы, чтобы оставаться в пределах [-180; 180] градусов.

В вашем случае, когда координаты не являются градусами, точка отсчета не имеет значения.

Я думаю, что это причина расхождения координат между всплывающим окном и элементом управления.

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

// Patch first to avoid longitude wrapping.
L.Control.Coordinates.include({
  _update: function(evt) {
    var pos = evt.latlng,
      opts = this.options;
    if (pos) {
      //pos = pos.wrap(); // Remove that instruction.
      this._currentPos = pos;
      this._inputY.value = L.NumberFormatter.round(pos.lat, opts.decimals, opts.decimalSeperator);
      this._inputX.value = L.NumberFormatter.round(pos.lng, opts.decimals, opts.decimalSeperator);
      this._label.innerHTML = this._createCoordinateLabel(pos);
    }
  }
});

Обновлено демо: http://plnkr.co/edit/M3Ru0xqn6AxAaSb4kIJU?p=preview

  • 0
    Спасибо вам большое! Это сработало! Именно так, как я хочу!
  • 0
    Добро пожаловать, спасибо за отзыв. Можете ли вы рассмотреть вопрос об отзыве и принятии этого ответа? Это система переполнения стека, чтобы поблагодарить людей, хотя, конечно, хороший комментарий также высоко ценится! :-)
Показать ещё 15 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню