我目前正在使用Google Maps API在地图上绘制点。我正在寻找实现点之间“菱形”效果的最佳方法(参见图片)。 本质上,锭剂的厚度将动态确定。
我看到的唯一方法是在我的点的末端绘制2个圆,并在它们之间创建一个没有边界的矩形。我不喜欢这个主意,因为它实际上是在我的地图上为每条线添加3个多边形,这意味着我必须为每条线(每个多边形上一个)添加3个单击事件以显示所需的数据单击时显示。
有没有更好的方法来实现这一目标?
答案 0 :(得分:1)
只需创建2条折线...
function initialize() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 3,
center: {lat: 20, lng: 0},
mapTypeId: 'terrain'
});
var flightPlanCoordinates = [
{lat: 20, lng: -20},
{lat: 20, lng: 20}
];
new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: .3,
strokeWeight: 20,
map: map
});
new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 1,
map: map
});
}
initialize();
#map-canvas {
height: 200px;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
编辑:
您在评论中提到,您需要将笔触固定在距中心线一定距离的位置。
我仍然可以使用该技术,因为您可以基于纬度和缩放级别来计算地图像素的大小(以米为单位),并且笔触的尺寸也以像素为单位,因此您应该能够在每次放大/缩小时重新计算笔划。由于笔划宽度必须是整数,所以不会100%精确,但是应该可以。
如果在相同的纬度上不同的折线点或多或少都应该起作用,因为具有墨卡托投影的地图分辨率取决于纬度。因此,例如,如果您有一条从-70到+70纬度的大折线,它将不会一直很精确。
这是可用于计算1个地图像素大小的公式。您需要用折线中心点替换map.getCenter().lat()
。
// Calculate the width of 1 map pixel in meters
let scale = 156543.03392 * Math.cos(map.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());
不幸的是,这种方法存在问题。尽管未公开,但折线描边宽度不能大于32px 。
var map;
var polyBounds;
var polyStroke;
var polyWidth = 50; // Width in meters
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 12,
center: {
lat: 20,
lng: 0
},
mapTypeId: 'terrain'
});
var flightPlanCoordinates = [{
lat: 20,
lng: -0.5
},
{
lat: 20,
lng: 0.5
}
];
polyStroke = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: .3,
strokeWeight: 0,
map: map
});
new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 1,
map: map
});
polyBounds = new google.maps.LatLngBounds();
for (var i = 0; i < flightPlanCoordinates.length; i++) {
polyBounds.extend(flightPlanCoordinates[i]);
}
google.maps.event.addListenerOnce(map, 'idle', setStroke);
google.maps.event.addListener(map, 'zoom_changed', setStroke);
}
function setStroke() {
// Calculate the width of 1 map pixel in meters
let scale = 156543.03392 * Math.cos(polyBounds.getCenter().lat() * Math.PI / 180) / Math.pow(2, map.getZoom());
polyStroke.setOptions({
strokeWeight: Math.ceil(polyWidth / scale)
});
}
initialize();
#map-canvas {
height: 200px;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
因此,除非您发现这些值适合您的用例,否则这将不是可行的解决方案...
您在评论(How to draw a polygon around a polyline in JavaScript?)中指出的解决方案仍然可能是您的最佳选择。
答案 1 :(得分:0)
我实际上发现了一种使用Google Maps API来实现此目的的简便得多的方法。 内置函数可基于起点获取点的方位角... 因此,我创建了一个函数,该函数接受直线的起点和终点,然后根据标题在这些起点和终点周围创建点-然后使用这些点创建多边形。
var pointCount = 12;
function setLozengePath(startPoint, endPoint) {
var sp = google.maps.geometry.spherical;
var heading = sp.computeHeading(startPoint, endPoint);
var points = [];
for (var i = 0; i <= pointCount; ++i) {
points.push(sp.computeOffset(endPoint, radius, heading + 90 - i * 15));
}
for (var i = 0; i <= pointCount; ++i) {
points.push(sp.computeOffset(startPoint, radius, heading - 90 - i * 15));
}
return points;
}