【发布时间】:2021-10-12 08:34:51
【问题描述】:
我正在尝试创建一个可以设置标记固定和可拖动方向的地图。
示例: 所以让我们假设我创建了一条带有标记 A 到标记 B 的路线,这些标记应该是固定的,但显示路线的蓝线应该是可拖动的。
这可能吗?
我已经尝试将标记选项设置为可拖动:false,但它不起作用,请帮助
提前致谢:)
【问题讨论】:
我正在尝试创建一个可以设置标记固定和可拖动方向的地图。
示例: 所以让我们假设我创建了一条带有标记 A 到标记 B 的路线,这些标记应该是固定的,但显示路线的蓝线应该是可拖动的。
这可能吗?
我已经尝试将标记选项设置为可拖动:false,但它不起作用,请帮助
提前致谢:)
【问题讨论】:
这完全可以通过 Google Maps api 实现。 DirectionsRenderer 服务有许多您可以设置的属性 - 其中一个符合您的要求,那就是 draggable
需要设置此属性的是DirectionsRenderer,而不是标记,用您自己的话来说"should be fixed"
例如,DirectionsRenderer 的配置可能是这样的:
let oRender=new google.maps.DirectionsRenderer({
map:map,
panel:document.getElementById('directions'),
draggable:true,
suppressMarkers:true
});
一个演示,它只允许地图上任意一点上的两个标记,并在它们之间创建可拖动的方向。
<!doctype html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Google Maps: Directions Service with draggable route and fixed markers</title>
<style>
body{
padding:0;
margin:0;
display:flex;
flex-direction:row;
flex-wrap;nowrap;
}
#map{
width:80%;
height:100vh;
margin:0;
}
#dir{
width:20%;
height:100vh;
margin:0;
background:whitesmoke!important;
border-right:1px solid black
}
h1{text-align:center;}
</style>
<script>
function initMap(){
let markers=[];
let distance=0;
const options = {
zoom: 12,
center:new google.maps.LatLng( 56.56185, -3.58496 ),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
const map = new google.maps.Map( document.getElementById('map'), options );
const oDir=new google.maps.DirectionsService();
/*
The DirectionsRenderer options has the `draggable`
property set `true` so that the rendered route may
be dragged to form a new route which will be calculated
automatically.
*/
const oRender=new google.maps.DirectionsRenderer({
map:map,
panel:document.getElementById('dir'),
draggable:true,
suppressMarkers:true
});
/*
base options for the DirectionsService
to use. This will be amended later with
the specifics for the route between the
two markers.
*/
const oReqOptions={
provideRouteAlternatives:true,
optimizeWaypoints:true,
avoidFerries:true,
avoidHighways:false,
avoidTolls:false
};
const addMarker=function( latlng ){
let a=arguments;
let args={
position:latlng,
map:map
};
if( typeof( a[1] )=='object' && Object.keys( a[1] ).length > 0 ){
args=Object.assign( args, a[1] );
}
let marker=new google.maps.Marker( args );
return marker;
};
const clickhandler=function(e){
/*
Allow only 2 markers
*/
if( markers.length == 2 ){
markers[0].setMap( null );
markers.splice(0,1);
}
// add the new marker
markers.push( addMarker( e.latLng,{ draggable:false } ) );
// if there are exactly 2 markers - calculate the route between them
if( markers.length==2 ){
let route={
start:markers[0].getPosition(),
finish:markers[1].getPosition()
};
const calculate=()=>new Promise(( resolve, reject )=>{
// amend the route options
let oReq=Object.assign(
oReqOptions,
{
origin:route.start,
destination:route.finish,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}
);
oDir.route( oReq, ( response, status )=>{
if( status === google.maps.DirectionsStatus.OK ){
oRender.setDirections( response );
/*
the distance calculations are not needed for
your purposes but I left them here anyway.
You could just resolve the promise with `true`
and modify the promise chain below when you call
the `calculate` function.
*/
let res=response.routes[0];
for( let k=0; k < res.legs.length; k++ ) {
distance+=Number( res.legs[k].distance.value );
}
resolve( distance )
}
reject( status )
});
});
calculate()
.then(res=>console.log( 'Distance: %dm',res ) )
.catch(err=>console.warn(err))
}
};
google.maps.event.addListener( map, 'click', clickhandler );
}
</script>
<script async defer src='//maps.googleapis.com/maps/api/js?key=KEY&callback=initMap'></script>
</head>
<body>
<div id='dir'><h1>Directions</h1></div>
<div id='map'></div>
</body>
</html>
【讨论】: