0

我有一个很久以前写的脚本,不是我写的,我已经从 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 示例

链接到完整代码

完整的地图代码

4

1 回答 1

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>
于 2013-07-06T14:12:08.597 回答