Google Maps V3中的范围环

时间:2013-07-05 21:43:49

标签: javascript google-maps google-maps-api-3

我有一个很久以前编写过的脚本而不是我已经从V2更新到V3并且我试图从中心LatLng点绘制范围环。这在V2工作,但它在V3中不起作用,我无法弄清楚为什么我知道一些代码已经折旧但不确定它需要替换什么。

//Function to draw circles
function doDrawCircle(circleUnits, center, circleRadius, liColor, liWidth, liOpa, fillColor, fillOpa, opts, radials){
    var bounds = new google.maps.LatLngBounds();
    var circlePoints = Array();
    with (Math) {
        if (circleUnits == 'KM') {
            var d = circleRadius/6378.8;    // radians
        }
        else { //miles
            var d = circleRadius/3963.189;  // radians
        }
        var lat1 = (PI/180)* center.lat(); // radians
        var lng1 = (PI/180)* center.lng(); // radians
        for (var a = 0 ; a < 361 ; a++ ) {
            var tc = (PI/180)*a;
            var y = asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc));
            var dlng = atan2(sin(tc)*sin(d)*cos(lat1),cos(d)-sin(lat1)*sin(y));
            var x = ((lng1-dlng+PI) % (2*PI)) - PI ; // MOD function
            var point = new google.maps.LatLng(parseFloat(y*(180/PI)),parseFloat(x*(180/PI)));
            circlePoints.push(point);
            bounds.extend(point);
            if(a==0){
                var offset = new google.maps.Size(-5,0);                                                   //    Added the offset - mile markers look a bit better
                var label = new ELabel(point, circleRadius, "style1", offset, 40);
                map.addOverlay(label);

            }
            if (((a==0) || (a==45) || (a==90) || (a==135) || (a==180) || (a==225) || (a==270) || (a==315)) && radials) {
            //if (((a==0) || (a==45) || (a==90) || (a==135) || (a==180)) && radials) {
                var pline = new google.maps.Polyline([center,point] , liColor, liWidth, liOpa);
                map.addOverlay(pline);
            }
        }
        var poly = new google.maps.Polygon(circlePoints, liColor, liWidth, liOpa, fillColor, fillOpa, opts);
        map.addOverlay(poly);                           // Add a target circle to the map
        map.setZoom(map.getBoundsZoomLevel(bounds));    // This sets the map bounds to be as big as the target circles, comment out if you don't want it

    }

}

然后我在地图的initialize()函数中有这个。

// You can add circles, or change other parameters
            // radials should be set to true for the maximum distance if you want radials
            // doDrawCircle(circleUnits, center, circleRadius, lineColor, lineWidth, lineOpacity, fillColor, fillOpacity, opts, radials)
            doDrawCircle('MI',llCenter,  62, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
            doDrawCircle('MI',llCenter, 124, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
            doDrawCircle('MI',llCenter, 187, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
            doDrawCircle('MI',llCenter, 249, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
            doDrawCircle('MI',llCenter, 312, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
            doDrawCircle('MI',llCenter, 374, lcolor, 1, .7, "#FFFF00", 0, { clickable: false }, false);
//          doDrawCircle('MI',llCenter, 374, lcolor, 1, .7, '#00FF00', 0, { clickable: false }, true);   // This would add the radials

这就是它的样子。这是来自工作的V2地图。

V2 EXAMPLE

链接到完整代码

FULL MAP CODE

1 个答案:

答案 0 :(得分:1)

您需要做的第一件事是在谷歌地图V3上获取最新版本的elabel.js:

https://github.com/erunyon/ELabel/blob/master/elabel.js

然后,好消息是你不需要所有那些复杂的数学和你在doDrawCircle函数中发生的事情。您现在可以使用google.maps.Circle以及必须通过google maps脚本标记的url参数包含的几何库,使用'libraries = geometry'参数,这样我们就可以通过google获取文本标签放置位置的起始点.maps.geometry.spherical.computeOffset。然后我在下面的文字放置中加入了一点点推文,看起来更整洁一些。 测试用例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Circles</title>
<style type="text/css">
.style1 {
    /* used for range numbers on rings */
    color: #FFF;
    font-size: 10px;
    text-shadow: 2px 2px 2px #000;
    font-weight: bold;
    font-family: verdana, helvetica, arial, sans-serif;
    background-color:black;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=geometry"></script>
<!-- elabel.js for google maps V3 from here: https://github.com/erunyon/ELabel/blob/master/elabel.js -->
<script src="elabel.js"></script>
<script>

function initialize() {
    var i, meters, options, labelLocation, textLength, textXcenter, label,
         //note I declared the actual font pixel size in .style1 css rule
         //just to help with visualizing the way I'm positioning the label texts
        textPixelSize = 10,
         //will need to invert textYcenter as well as textXcenter to negative numbers later
        textYcenter = (textPixelSize / 2) + 2, //2px tweak for 'y' position, approximation
        mapOptions = {
            zoom: 6,
            center: new google.maps.LatLng(32.8297,-96.6486),
            mapTypeId: google.maps.MapTypeId.HYBRID
        },
        ranges = [62, 124, 187, 249, 312, 374], //circle radii in miles
        circles = [],
        labels = [],
        map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
    for (i = 0; i < ranges.length; i++) {
         //convert miles to meters:
        meters = ranges[i] / 0.00062137;
        options = {
            strokeColor: '#FF0000',
            strokeOpacity: 0.8,
            strokeWeight: 1,
            fillOpacity: 0,
            map: map,
            center: mapOptions.center,
            radius: meters
        };
        circles.push(new google.maps.Circle(options));//ta-da! easy circles in V3
         //labelLocation will be a google.maps.LatLng object
        labelLocation = google.maps.geometry.spherical.computeOffset(mapOptions.center, meters, 0);
        textLength = (''+ranges[i]).length;
        textXcenter = (textLength * textPixelSize) / 2; //approximation
        label = new ELabel({
            latlng: labelLocation,
            label: ranges[i],
            classname: 'style1',
            offset: new google.maps.Size(-textXcenter, -textYcenter),//negative will move left and up
            opacity: 100,
            overlap: true,
            clicktarget: false
        });
        label.setMap(map);
        labels.push(label);
    }
}

google.maps.event.addDomListener(window, 'load', initialize);

</script>
</head>
<body>
<div id="map_canvas" style="width:780px; height:600px; margin:10px auto;"></div>
</body>
</html>

编辑: 这是修订版,允许通过“范围”按钮切换环的可见性。还删除了所有文本标签定位调整数学,并替换为使用不同长度文本的样式类(如果需要,可以更容易地在样式中使用em单位)。添加了LabelCircle构造函数,以便更容易地封装和同时控制圆圈和标签

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Circles</title>
<style type="text/css">
.style1 {
    /*used for range numbers on rings*/
    color: #FFF;
    font-size: .6em;
    text-shadow: 2px 2px 2px #000;
    font-weight: bold;
    font-family: verdana, helvetica, arial, sans-serif;
    background-color:black;
    margin-top: -0.5em;
}
.d2 { /*two-digit numbers on rings*/
    margin-left: -1em;
}
.d3 { /*three-digit numbers on rings*/
    margin-left: -1.5em;
}
/*direct copy of your existing .button style rule*/
.button{
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  text-align: center;
  position: relative;
  font-family: Arial, sans-serif;
  font-size: 13px;
        font-weight:bold;
  box-shadow: rgba(0, 0, 0, 0.4) 0 2px 4px;
  -moz-box-shadow: rgba(0, 0, 0, 0.4) 0 2px 4px;
  -webkit-box-shadow: rgba(0, 0, 0, 0.4) 0 2px 4px;
  color: #000;
  border: 1px solid #717B87;
  background-color: #fff;
  margin: 5px;
  padding: 1px 6px;
  overflow: hidden;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=geometry"></script>
<!-- elabel.js for google maps V3 from here: https://github.com/erunyon/ELabel/blob/master/elabel.js -->
<script src="elabel.js"></script>
<script>

function LabelCircle(options) {
    this.circle = new google.maps.Circle(options.circleOptions);
    this.label = new ELabel(options.labelOptions);
    this.label.setMap(options.circleOptions.map);
    this.isVisible = true;
}

LabelCircle.prototype.setVisible = function (bool) {
    var method = (bool) ? 'show' : 'hide';
    this.circle.setVisible(bool);
    this.label[method]();
    this.isVisible = bool;
};

//a direct copy of your existing function
function buttonControl(options) {
    var control = document.createElement('DIV');
    control.innerHTML = options.name;
    control.className = 'button';
    control.index = 1;
    // Add the control to the map
    options.gmap.controls[options.position].push(control);
    google.maps.event.addDomListener(control, 'click', options.action);
    return control;
}

function initialize() {
    var i, meters, options, labelLocation, textLength, label,
        mapOptions = {
            zoom: 6,
            center: new google.maps.LatLng(32.8297,-96.6486),
            mapTypeId: google.maps.MapTypeId.HYBRID
        },
        ranges = [62, 124, 187, 249, 312, 374], //circle radii in miles
        labelCircles = [],
        map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
    for (i = 0; i < ranges.length; i++) {
         //convert miles to meters:
        meters = ranges[i] / 0.00062137;
         //labelLocation will be a google.maps.LatLng object
        labelLocation = google.maps.geometry.spherical.computeOffset(mapOptions.center, meters, 0);
         //we'll use textLength below to add a class to the label
        textLength = (''+ranges[i]).length;
        options = {
            circleOptions: {
                strokeColor: '#FF0000',
                strokeOpacity: 0.8,
                strokeWeight: 1,
                fillColor: 'transparent',
                fillOpacity: 0,
                map: map,
                center: mapOptions.center,
                radius: meters
            },
            labelOptions: {
                latlng: labelLocation,
                label: ranges[i],
                classname: 'style1 d' + textLength,
                //offset: //no longer needed, using style classes
                opacity: 100,
                overlap: true,
                clicktarget: false
            }
        };
        labelCircles.push(new LabelCircle(options));
    }
    var rangeOptions = {
        gmap: map,
        name: 'Range',
        position: google.maps.ControlPosition.TOP_RIGHT,
        action: function(){
            for (var tmp, i = 0; i < labelCircles.length; i++) {
                tmp = labelCircles[i];
                tmp.setVisible(!tmp.isVisible);
            }
        }
    };
    var rangeButton = buttonControl(rangeOptions);
}

google.maps.event.addDomListener(window, 'load', initialize);

</script>
</head>
<body>
<div id="map_canvas" style="width:780px; height:600px; margin:10px auto;"></div>
</body>
</html>