Ошибка в OpenLayers при попытке изменить вид карты - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь начать делать геокодирование с OpenLayers и Nominatim, но когда я пытаюсь изменить вид карты (скажем, потому что пользователь ввел адрес, и я хочу центрировать карту на нем), я получаю ошибка:

ol-debug.js:6171 Uncaught TypeError: Cannot read property 'getCode' of null
at Object.ol.proj.getTransformFromProjections (ol-debug.js:6171)
at Object.ol.proj.getTransform (ol-debug.js:6155)
at Object.ol.proj.transform (ol-debug.js:6251)
at Object.ol.proj.fromLonLat (ol-debug.js:6063)
at Object.<anonymous> ((index):74)
at c (jquery-3.4.1.min.js:2)
at Object.fireWith [as resolveWith] (jquery-3.4.1.min.js:2)
at l (jquery-3.4.1.min.js:2)
at XMLHttpRequest.<anonymous> (jquery-3.4.1.min.js:2)

Вот мой код (в основном это просто пример кода, который я нашел в Интернете):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>OpenStreetMap &amp; OpenLayers - Marker Example</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
    <script src="https://openlayers.org/en/v4.6.5/build/ol-debug.js" type="text/javascript"></script>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
            integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
            crossorigin="anonymous"></script>

    <script>
        /* OSM & OL example code provided by https://mediarealm.com.au/ */
        var map;
        var mapLat = -33.829357;
        var mapLng = 150.961761;
        var mapDefaultZoom = 10;
        var view = new ol.View({
            center: ol.proj.fromLonLat([mapLng, mapLat]),
            zoom: mapDefaultZoom
        })
        function initialize_map() {
            map = new ol.Map({
                target: "map",
                layers: [
                    new ol.layer.Tile({
                        source: new ol.source.OSM({
                            url: "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
                        })
                    })
                ],
                view: view
            });
        }
        function add_map_point(lat, lng) {
            var vectorLayer = new ol.layer.Vector({
                source: new ol.source.Vector({
                    features: [new ol.Feature({
                        geometry: new ol.geom.Point(ol.proj.transform([parseFloat(lng), parseFloat(lat)], 'EPSG:4326', 'EPSG:3857')),
                    })]
                }),
                style: new ol.style.Style({
                    image: new ol.style.Icon({
                        anchor: [0.5, 0.5],
                        anchorXUnits: "fraction",
                        anchorYUnits: "fraction",
                        src: "https://upload.wikimedia.org/wikipedia/commons/e/ec/RedDot.svg"
                    })
                })
            });
            map.addLayer(vectorLayer);
        }

        function geocode() {
            var address = $("#address").val();

            console.log(address);

            var data = {
                "format": "json",
                "addressdetails": 1,
                "q": address,
                "limit": 1
            };
            $.ajax({
                method: "GET",
                url: "https://nominatim.openstreetmap.org",
                data: data
            })
                .done(function (msg) {
                    console.log(msg);
                    add_map_point(msg[0].lat, msg[0].lon);
                    view.center = ol.proj.fromLonLat(msg[0].lon, msg[0].lat);
                    });
        }
    </script>
</head>
<body onload="initialize_map();">
    <input type="text" id="address" />
    <button type="submit" id="submit" onclick="geocode();">Submit</button>
    <div id="map" style="width: 100vw; height: 100vh;"></div>
</body>
</html>

Поэтому я набираю адрес или город или что-то еще в текстовом поле и нажимаю кнопку отправки - красная точка появляется на карте в месте поиска, но карта не центрируется в этом месте; вместо этого я получаю ошибку, которую я описал ранее. Что может быть не так?

edit: заменил строку view.center на:

view.animate({
    center: ol.proj.fromLonLat([msg[0].lon, msg[0].lat]),
    duration: 2000});

и это заставило его сделать что-то - но оно центрируется посреди океана!

Ответы [ 2 ]

1 голос
/ 24 мая 2019

В соответствии с документацией OpenLayers, view.center должен вызывать view.setCenter() с долготой и широтой (необходимо убедиться, что это числа, а не строки, используя parseFloat).Я добавил функцию centerMap() к вашей функции ajax done, которая будет центрировать экран, используя способность классов View к animate движению на карте, и использует mapDefaultZoom васустановили:

function centerMap(lat, lng) {
  view.animate({
    center: ol.proj.fromLonLat([parseFloat(lng), parseFloat(lat)]),
    duration: 1000,
    zoom: mapDefaultZoom
  });
  console.log("Long: " + lng + " Lat: " + lat);
}

var map;
var mapLat = -33.829357;
var mapLng = 150.961761;
var mapDefaultZoom = 10;
var view = new ol.View({
  center: ol.proj.fromLonLat([mapLng, mapLat]),
  zoom: mapDefaultZoom
});

function initialize_map() {
  map = new ol.Map({
    target: "map",
    layers: [
      new ol.layer.Tile({
        source: new ol.source.OSM({
          url: "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
        })
      })
    ],
    view: view
  });
}

function add_map_point(lat, lng) {
  var vectorLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: [new ol.Feature({
        geometry: new ol.geom.Point(ol.proj.transform([parseFloat(lng), parseFloat(lat)], 'EPSG:4326', 'EPSG:3857')),
      })]
    }),
    style: new ol.style.Style({
      image: new ol.style.Icon({
        anchor: [0.5, 0.5],
        anchorXUnits: "fraction",
        anchorYUnits: "fraction",
        src: "https://upload.wikimedia.org/wikipedia/commons/e/ec/RedDot.svg"
      })
    })
  });
  map.addLayer(vectorLayer);
}

function geocode() {
  var address = $("#address").val();

  console.log(address);

  var data = {
    "format": "json",
    "addressdetails": 1,
    "q": address,
    "limit": 1
  };
  $.ajax({
      method: "GET",
      url: "https://nominatim.openstreetmap.org",
      data: data
    })
    .done(function(msg) {
      console.log(msg);
      add_map_point(msg[0].lat, msg[0].lon);
      //view.center = ol.proj.fromLonLat(msg[0].lon, msg[0].lat);
      centerMap(msg[0].lat, msg[0].lon);
    });
}

function centerMap(lat, lng) {
  view.animate({
    center: ol.proj.fromLonLat([parseFloat(lng), parseFloat(lat)]),
    duration: 1000,
    zoom: mapDefaultZoom
  });
  console.log("Long: " + lng + " Lat: " + lat);
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>OpenStreetMap &amp; OpenLayers - Marker Example</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css">
  <script src="https://openlayers.org/en/v4.6.5/build/ol-debug.js" type="text/javascript"></script>
  <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>

</head>

<body onload="initialize_map();">
  <input type="text" id="address" value="1600 Pennsylvania Ave SE, Washington, DC 20003" />
  <button type="submit" id="submit" onclick="geocode();">Submit</button>
  <div id="map" style="width: 100vw; height: 100vh;"></div>
</body>

</html>
1 голос
/ 24 мая 2019

view.center должно быть view.setCenter()

view.setCenter([ol.proj.fromLonLat(msg[0].lon, msg[0].lat]);

Если значения lon / lat являются строками, их необходимо преобразовать в число с плавающей точкой

view.setCenter([ol.proj.fromLonLat(parseFloat(msg[0].lon), parseFloat(msg[0].lat)]);

Вы также можете попробовать

view.animate({
    center: ol.proj.fromLonLat([parseFloat(msg[0].lon), parseFloat(msg[0].lat)]),
    duration: 2000});
...