当我尝试更改地图视图时 OpenLayers 出错
Error in OpenLayers when I try to change the map view
我正在尝试开始使用 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 & 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>
因此,我在文本框中键入地址或城市或其他任何内容,然后单击提交按钮 - 搜索位置的地图上会出现一个红点,但地图并未以该位置为中心;相反,我得到了我之前描述的错误。可能出了什么问题?
编辑:将 view.center 行替换为:
view.animate({
center: ol.proj.fromLonLat([msg[0].lon, msg[0].lat]),
duration: 2000});
这让它做了 一些事情 - 但它位于海洋中央!
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});
根据 OpenLayers 文档,view.center
应该在地图上调用 view.setCenter()
with a longitude and latitude (need to make sure they are numbers and not strings, using parseFloat
). I added a centerMap()
function to your ajax done
function, that will center the screen using the View
classes ability to 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 & 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>
我正在尝试开始使用 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 & 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>
因此,我在文本框中键入地址或城市或其他任何内容,然后单击提交按钮 - 搜索位置的地图上会出现一个红点,但地图并未以该位置为中心;相反,我得到了我之前描述的错误。可能出了什么问题?
编辑:将 view.center 行替换为:
view.animate({
center: ol.proj.fromLonLat([msg[0].lon, msg[0].lat]),
duration: 2000});
这让它做了 一些事情 - 但它位于海洋中央!
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});
根据 OpenLayers 文档,view.center
应该在地图上调用 view.setCenter()
with a longitude and latitude (need to make sure they are numbers and not strings, using parseFloat
). I added a centerMap()
function to your ajax done
function, that will center the screen using the View
classes ability to 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 & 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>