我正在使用针对meteor的leaflet.js包,我在初始渲染时将地图默认设置为当前位置时遇到问题。 setView方法适用于硬数字,但它不像我的变量。我对js很新,所以错误很明显。这就是我所拥有的:
Template.map.rendered = function() {
L.Icon.Default.imagePath = 'packages/bevanhunt_leaflet/images';
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
console.log('--- Your Position: ---');
console.log('Lat: ' + position.coords.latitude);
latit = position.coords.latitude;
console.log('Long: ' + position.coords.longitude);
longit = position.coords.longitude;
console.log('---------------------');
var abc = L.marker([position.coords.latitude, position.coords.longitude]).addTo(map);
}
)}
map = L.map('map', {
doubleClickZoom: false
}).setView([latit, longit], 13);
我不断得到的错误是
Uncaught TypeError: Cannot read property 'addLayer' of undefined
L.Marker.L.Class.extend.addTo @ leaflet-src.js:3511
(anonymous function) @ client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:28
当我在console.log(latit)或console.log(longit)时,它返回数字,以及" undefined"在它之后。提前感谢任何可以提供帮助的人!
编辑:
初始渲染时的确切控制台输出:
Exception from Tracker afterFlush function:
debug.js:41 ReferenceError: latit is not defined
at Template.map.rendered (client.js? ea76789cca0ff64d5985320ec2127d5de1fb802f:36)
at template.js:116
at Function.Template._withTemplateInstanceFunc (template.js:437)
at fireCallbacks (template.js:112)
at null.<anonymous> (template.js:205)
at view.js:104
at Object.Blaze._withCurrentView (view.js:523)
at view.js:103
at Object.Tracker._runFlush (tracker.js:468)
at onGlobalMessage (setimmediate.js:102)
client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:22 --- Your Position: ---
client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:23 Lat: 41.0525926
client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:25 Long: -73.5398427
client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:27 ---------------------
leaflet-src.js:3511 Uncaught TypeError: Cannot read property 'addLayer' of undefinedL.Marker.L.Class.extend.addTo @ leaflet-src.js:3511(anonymous function) @ client.js?ea76789cca0ff64d5985320ec2127d5de1fb802f:28
编辑2: 我想保持这个简单,但这里完全是我的js:
var map;
var latit;
var longit;
// on startup run resizing event
Meteor.startup(function() {
$(window).resize(function() {
$('#map').css('height', window.innerHeight - 82 - 45);
});
$(window).resize(); // trigger resize event
});
// create marker collection
var Markers = new Meteor.Collection('markers');
Meteor.subscribe('markers');
Template.map.rendered = function() {
L.Icon.Default.imagePath = 'packages/bevanhunt_leaflet/images';
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
console.log('--- Your Position: ---');
console.log('Lat: ' + position.coords.latitude);
latit = position.coords.latitude;
console.log('Long: ' + position.coords.longitude);
longit = position.coords.longitude;
console.log('---------------------');
var abc = L.marker([position.coords.latitude, position.coords.longitude]).addTo(map);
}
)}
map = L.map('map', {
doubleClickZoom: false
}).setView([latit, longit], 13); //Error is somewhere before here!!
L.tileLayer.provider('Thunderforest.Outdoors').addTo(map);
map.on('dblclick', function(event) {
Markers.insert({latlng: event.latlng});
});
//add markers
var query = Markers.find();
query.observe({
added: function (document) {
var marker = L.marker(document.latlng).addTo(map)
.on('click', function(event) {
map.removeLayer(marker);
Markers.remove({_id: document._id});
});
},
//remove markers
removed: function (oldDocument) {
layers = map._layers;
var key, val;
for (key in layers) {
val = layers[key];
if (val._latlng) {
if (val._latlng.lat === oldDocument.latlng.lat && val._latlng.lng === oldDocument.latlng.lng) {
map.removeLayer(val);
}
}
}
}
});
};
答案 0 :(得分:8)
谢谢@sosdoc,初始化这些变量确实有帮助,并且在项目的长期内帮助我。但是为了简单地在我当前的位置渲染地图,我找到了一个更简单的答案! leaflet内置了一个locate方法。而不是传递'未初始化'的latit和longit vars,我这样做了:
map = L.map('map', {doubleClickZoom: false}).locate({setView: true, maxZoom: 16});
将地图设置为您的位置。 maxzoom只是可以缩放和更改的次数的变量。
答案 1 :(得分:2)
从完整代码中您可以看到错误在这里
map = L.map('map', {
doubleClickZoom: false
}).setView([latit, longit], 13);
因为latit
和longit
没有设置(在JS中,在你给它们任何值之前它们是未定义的)。
您可能会感到困惑,因为此代码在您定义的任何回调之前执行:在此脚本终止后执行Template.map.rendered
。
对此的解决方案是为这些参数设置初始值
var latit = 0;
var longit = 0;
您的地图最初将位于非洲西部。
然后,当执行map.rendered
时,您需要将地图重新定位到更新的latit和longit变量(更新它们不会更新地图)。
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
latit = position.coords.latitude;
longit = position.coords.longitude;
// this is just a marker placed in that position
var abc = L.marker([position.coords.latitude, position.coords.longitude]).addTo(map);
// move the map to have the location in its center
map.panTo(new L.LatLng(latit, longit));
}
如果您愿意,您还可以将标记的位置传递给panTo()
函数:
map.panTo(abc.getLatLng());
最后,请记住,每当您将function()
传递给其他某个函数时,稍后会执行该函数以响应某些事件,这将在JavaScript中广泛完成。
答案 2 :(得分:0)
navigator.geolocation.getCurrentPosition(function(location) {
var latlng = new L.LatLng(location.coords.latitude, location.coords.longitude);
alert(latlng);
var mymap = L.map('mapid').setView(latlng, 13)
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://mapbox.com">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: 'pk.eyJ1IjoiYmJyb29rMTU0IiwiYSI6ImNpcXN3dnJrdDAwMGNmd250bjhvZXpnbWsifQ.Nf9Zkfchos577IanoKMoYQ'
}).addTo(mymap);
var marker = L.marker(latlng).addTo(mymap);
});
#mapid {
height: 500px;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v0.min.js"></script>
<link rel="stylesheet" href="https://npmcdn.com/leaflet@1.0.0-rc.2/dist/leaflet.css" />
<script src="https://npmcdn.com/leaflet@1.0.0-rc.2/dist/leaflet.js"></script>
<div id="mapid"></div>
//更多的传单教程可以参考