我想构建一个显示用户当前位置的页面。 我想构建的功能是用户可以选择地图上的任何位置,脚本将计算他的位置和点击位置之间的距离。
取得的成果:网站显示位置,用户可以点击放置第二个标记。
问题:第一个标记应出现在用户当前位置。
已有的代码: JSfiddle
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Distance between two markers</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v2.4.0/mapbox.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
pre.ui-distance {
position:absolute;
bottom:10px;
left:10px;
padding:5px 10px;
background:rgba(0,0,0,0.5);
color:#fff;
font-size:11px;
line-height:18px;
border-radius:3px;
}
.ui-button {
background:#3887BE;
color:#FFF;
display:block;
position:absolute;
top:50%;left:50%;
width:160px;
margin:-20px 0 0 -80px;
z-index:100;
text-align:center;
padding:10px;
border:1px solid rgba(0,0,0,0.4);
border-radius:3px;
}
.ui-button:hover {
background:#3074a4;
color:#fff;
}
</style>
<div id='map'></div>
<div class='ui-button'>
<a href='#' id='geolocate' >Find me</a>
<pre id='distance' class='ui-distance'>Click to place a marker</pre>
<script>
L.mapbox.accessToken = 'pk.eyJ1IjoiYWJ6YWwiLCJhIjoiY2llempiaW9oMWJvdXNnbTAxZnY4NTNvOSJ9.I0bW1wxrOYS2MPZD0FrTtA';
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38.9, -77], 12);
// Start with a fixed marker.
var fixedMarker = L.marker(new L.LatLng(38.9131775, -77.032544), {
icon: L.mapbox.marker.icon({
'marker-color': 'ff8888'
})
}).bindPopup('Mapbox DC').addTo(map);
// Store the fixedMarker coordinates in a variable.
var fc = fixedMarker.getLatLng();
// Create a featureLayer that will hold a marker and linestring.
var featureLayer = L.mapbox.featureLayer().addTo(map);
// When a user clicks on the map we want to
// create a new L.featureGroup that will contain a
// marker placed where the user selected the map and
// a linestring that draws itself between the fixedMarkers
// coordinates and the newly placed marker.
map.on('click', function(ev) {
// ev.latlng gives us the coordinates of
// the spot clicked on the map.
var c = ev.latlng;
var geojson = [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [c.lng, c.lat]
},
"properties": {
"marker-color": "#ff8888"
}
}, {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[fc.lng, fc.lat],
[c.lng, c.lat]
]
},
"properties": {
"stroke": "#000",
"stroke-opacity": 0.5,
"stroke-width": 4
}
}
];
featureLayer.setGeoJSON(geojson);
// Finally, print the distance between these two points
// on the screen using distanceTo().
var container = document.getElementById('distance');
container.innerHTML = (fc.distanceTo(c)).toFixed(0) + 'm';
});
var geolocate = document.getElementById('geolocate');
if (!navigator.geolocation) {
geolocate.innerHTML = 'Geolocation is not available';
} else {
geolocate.onclick = function (e) {
e.preventDefault();
e.stopPropagation();
map.locate();
};
}
// Once we've got a position, zoom and center the map
// on it, and add a single marker.
map.on('locationfound', function(e) {
map.fitBounds(e.bounds);
myLayer.setGeoJSON({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [e.latlng.lng, e.latlng.lat]
},
properties: {
'title': 'Here I am!',
'marker-color': '#ff8888',
'marker-symbol': 'star'
}
});
// And hide the geolocation button
geolocate.parentNode.removeChild(geolocate);
});
// If the user chooses not to allow their location
// to be shared, display an error message.
map.on('locationerror', function() {
geolocate.innerHTML = 'Position could not be found';
});
</script>
</body>
</html>
答案 0 :(得分:1)
抱歉,它有点乱,不完全是我认为你想要的,但可以根据需要改变工作(我创建了第二个featureLayer,以便表示找到的用户位置的原始标记保留在map - 这样一个人必须点击两次才能测量两个距离,但至少用户可以选择起点,而找到&#34;起点可能不是用户的确切位置。)I摆脱了它开始的fixedMarker因为我们不需要它。 The JSFiddle
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38.9, -77], 12);
// Create a featureLayer that will hold a marker and linestring.
var featureLayer = L.mapbox.featureLayer().addTo(map);
var secondFeatureLayer = L.mapbox.featureLayer().addTo(map);
// 1. Let's create a counter so that we can record the separate clicks
var counter = 0;
// 2. Let's use some variables outside the function scope
var c,
c2,
prevClick;
map.on('click', function(ev) {
// 3. Check if we've yet to click once
if (counter < 1) {
// 4. assign current click coordinates to prevClick for later use
prevClick = ev.latlng;
// ev.latlng gives us the coordinates of
// the spot clicked on the map.
c = ev.latlng;
counter++;
} else {
c = prevClick;
counter = 0;
}
c2 = ev.latlng;
var geojson = [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [c.lng, c.lat]
},
"properties": {
"marker-color": "#ff8888"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [c2.lng, c2.lat]
},
"properties": {
"marker-color": "#ff8888"
}
},{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[c.lng, c.lat],
[c2.lng, c2.lat]
]
},
"properties": {
"stroke": "#000",
"stroke-opacity": 0.5,
"stroke-width": 4
}
}
];
secondFeatureLayer.setGeoJSON(geojson);
// Finally, print the distance between these two points
// on the screen using distanceTo().
var container = document.getElementById('distance');
container.innerHTML = (c2.distanceTo(c)).toFixed(0) + 'm';
});
var geolocate = document.getElementById('geolocate');
if (!navigator.geolocation) {
geolocate.innerHTML = 'Geolocation is not available';
} else {
geolocate.onclick = function (e) {
e.preventDefault();
e.stopPropagation();
map.locate();
};
}
// Once we've got a position, zoom and center the map
// on it, and add a single marker.
map.on('locationfound', function(e) {
map.fitBounds(e.bounds);
featureLayer.setGeoJSON({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [e.latlng.lng, e.latlng.lat]
},
properties: {
'title': 'Here I am!',
'marker-color': '#ff8888',
'marker-symbol': 'star'
}
});
// And hide the geolocation button
geolocate.parentNode.removeChild(geolocate);
});
// If the user chooses not to allow their location
// to be shared, display an error message.
map.on('locationerror', function() {
geolocate.innerHTML = 'Position could not be found';
});