我现在需要让它看起来像这样:
Correct map http://www.pcwp.com/images2009/ui-2.gif
我在互联网上寻找解决方案,但无济于事.有任何想法吗?
解决方法
让我们从重新创建地图开始:
<!DOCTYPE html> <html> <head> <Meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Google Maps Cyclones</title> <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script> </head> <body> <div id="map" style="width: 600px; height: 400px"></div> <script type="text/javascript"> var i; var mapOptions = { mapTypeId: google.maps.MapTypeId.TERRAIN,center: new google.maps.LatLng(28.50,-81.50),zoom: 5 }; var map = new google.maps.Map(document.getElementById("map"),mapOptions); var pathPoints = [ new google.maps.LatLng(25.48,-71.26),new google.maps.LatLng(25.38,-73.70),new google.maps.LatLng(25.28,-77.00),new google.maps.LatLng(25.24,-80.11),new google.maps.LatLng(25.94,-82.71),new google.maps.LatLng(27.70,-87.14) ]; pathPoints[0].radius = 80; pathPoints[1].radius = 100; pathPoints[2].radius = 200; pathPoints[3].radius = 300; pathPoints[4].radius = 350; pathPoints[5].radius = 550; new google.maps.Polyline({ path: pathPoints,strokeColor: '#00FF00',strokeOpacity: 1.0,strokeWeight: 3,map: map }); for (i = 0; i < pathPoints.length; i++) { new google.maps.Circle({ center: pathPoints[i],radius: pathPoints[i].radius * 1000,fillColor: '#FF0000',fillOpacity: 0.2,strokeOpacity: 0.5,strokeWeight: 1,map: map }); } </script> </body> </html>
Google Maps Cyclones – Figure 1 http://img186.imageshack.us/img186/1197/mp1h.png
我假设你已经到了这一点,因此上面的例子应该是不言自明的.基本上我们已经定义了6个点,以及6个半径,并且我们已经在地图上渲染了圆圈以及绿色路径.
在我们继续之前,我们需要定义一些方法来计算从一个点到另一个点的距离和方位.我们还需要一种方法,在给定方位时返回目标点,以及从源点移动的距离.幸运的是,Chris Veness于Calculate distance,bearing and more between Latitude/Longitude points为这些方法提供了非常好的JavaScript实现.以下方法已经过调整,可以与Google的google.maps.LatLng一起使用:
Number.prototype.toRad = function() { return this * Math.PI / 180; } Number.prototype.toDeg = function() { return this * 180 / Math.PI; } google.maps.LatLng.prototype.destinationPoint = function(brng,dist) { dist = dist / 6371; brng = brng.toRad(); var lat1 = this.lat().toRad(),lon1 = this.lng().toRad(); var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist) + Math.cos(lat1)*Math.sin(dist)*Math.cos(brng) ); var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist)*Math.cos(lat1),Math.cos(dist)-Math.sin(lat1)*Math.sin(lat2)); if (isNaN(lat2) || isNaN(lon2)) return null; return new google.maps.LatLng(lat2.toDeg(),lon2.toDeg()); } google.maps.LatLng.prototype.bearingTo = function(point) { var lat1 = this.lat().toRad(),lat2 = point.lat().toRad(); var dLon = (point.lng()-this.lng()).toRad(); var y = Math.sin(dLon) * Math.cos(lat2); var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); var brng = Math.atan2(y,x); return ((brng.toDeg()+360) % 360); } google.maps.LatLng.prototype.distanceTo = function(point) { var lat1 = this.lat().toRad(),lon1 = this.lng().toRad(); var lat2 = point.lat().toRad(),lon2 = point.lng().toRad(); var dLat = lat2 - lat1; var dLon = lon2 - lon1; var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon/2) * Math.sin(dLon/2); return 6371 * (2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a))); }
然后我们需要添加另一个循环,该循环将我们之前用于渲染原始圆的for循环内的中间圆渲染.以下是它的实现方式:
var distanceStep = 50; // Render an intermediate circle every 50km. for (i = 0; i < pathPoints.length; i++) { new google.maps.Circle({ center: pathPoints[i],map: map }); if (i < (pathPoints.length - 1)) { distanceToNextPoint = pathPoints[i].distanceTo(pathPoints[i + 1]); bearingToNextPoint = pathPoints[i].bearingTo(pathPoints[i + 1]); radius = pathPoints[i].radius; radiusIncrement = (pathPoints[i + 1].radius - radius) / (distanceToNextPoint / distanceStep); for (j = distanceStep; j < distanceToNextPoint; j += distanceStep,radius += radiusIncrement) { new google.maps.Circle({ center: pathPoints[i].destinationPoint(bearingToNextPoint,j),radius: radius * 1000,strokeWeight: 0,map: map }); } } }
这就是我们得到的:
Google Maps Cyclones – Figure 2 http://img188.imageshack.us/img188/5687/mp2a.png
如果没有原始圆圈周围的黑色笔划,这就是它的样子:
Google Maps Cyclones – Figure 3 http://img181.imageshack.us/img181/2908/mp3t.png
您可能会注意到,主要的挑战是渲染具有一致不透明度的圆圈,即使它们彼此重叠.有几种方法可以实现这一目标,但这可能是另一个问题的主题.
在任何情况下,以下是此示例的完整实现:
<!DOCTYPE html> <html> <head> <Meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Google Maps Cyclones</title> <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script> </head> <body> <div id="map" style="width: 600px; height: 400px"></div> <script type="text/javascript"> Number.prototype.toRad = function() { return this * Math.PI / 180; } Number.prototype.toDeg = function() { return this * 180 / Math.PI; } google.maps.LatLng.prototype.destinationPoint = function(brng,dist) { dist = dist / 6371; brng = brng.toRad(); var lat1 = this.lat().toRad(),lon1 = this.lng().toRad(); var lat2 = Math.asin( Math.sin(lat1)*Math.cos(dist) + Math.cos(lat1)*Math.sin(dist)*Math.cos(brng) ); var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(dist)*Math.cos(lat1),Math.cos(dist)-Math.sin(lat1)*Math.sin(lat2)); if (isNaN(lat2) || isNaN(lon2)) return null; return new google.maps.LatLng(lat2.toDeg(),lon2.toDeg()); } google.maps.LatLng.prototype.bearingTo = function(point) { var lat1 = this.lat().toRad(),lat2 = point.lat().toRad(); var dLon = (point.lng()-this.lng()).toRad(); var y = Math.sin(dLon) * Math.cos(lat2); var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); var brng = Math.atan2(y,x); return ((brng.toDeg()+360) % 360); } google.maps.LatLng.prototype.distanceTo = function(point) { var lat1 = this.lat().toRad(),lon1 = this.lng().toRad(); var lat2 = point.lat().toRad(),lon2 = point.lng().toRad(); var dLat = lat2 - lat1; var dLon = lon2 - lon1; var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon/2) * Math.sin(dLon/2); return 6371 * (2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a))); } var i; var j; var distanceToNextPoint; var bearingToNextPoint; var radius; var radiusIncrement; var distanceStep = 50; // Render an intermediate circle every 50km. var mapOptions = { mapTypeId: google.maps.MapTypeId.TERRAIN,map: map }); if (i < (pathPoints.length - 1)) { distanceToNextPoint = pathPoints[i].distanceTo(pathPoints[i + 1]); bearingToNextPoint = pathPoints[i].bearingTo(pathPoints[i + 1]); radius = pathPoints[i].radius; radiusIncrement = (pathPoints[i + 1].radius - radius) / (distanceToNextPoint / distanceStep); for (j = distanceStep; j < distanceToNextPoint; j += distanceStep,radius += radiusIncrement) { new google.maps.Circle({ center: pathPoints[i].destinationPoint(bearingToNextPoint,map: map }); } } } </script> </body> </html>