Javascript 谷歌地图V3中的范围环

Javascript 谷歌地图V3中的范围环,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,我有一个脚本是很久以前写的,不是我写的,我已经从V2升级到V3,我正在尝试从一个中心点画距离环。这在V2中起作用,但在V3中不起作用,我不明白为什么我知道一些代码被贬低了,但不确定需要替换什么 //Function to draw circles function doDrawCircle(circleUnits, center, circleRadius, liColor, liWidth, liOpa, fillColor, fillOpa, opts, radials){ var

我有一个脚本是很久以前写的,不是我写的,我已经从V2升级到V3,我正在尝试从一个中心点画距离环。这在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

    }

}
这就是它应该看起来的样子。这是从工作的V2地图

链接到完整代码


您需要做的第一件事是在此处获取最新版本的elabel.js for google maps V3:

好消息是,你不需要所有复杂的数学和你在doDrawCircle函数中用到的东西。现在,您可以使用google.maps.Circle以及几何体库,该几何体库必须通过使用“libraries=geometry”参数的google maps脚本标记的url参数包含,因此我们可以通过google.maps.geometry.spheremic.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>

圈子
.style1{
/*用于环上的范围数*/
颜色:#FFF;
字体大小:10px;
文本阴影:2px 2px 2px#000;
字体大小:粗体;
字体系列:verdana、helvetica、arial、无衬线字体;
背景色:黑色;
}
函数初始化(){
变量i、仪表、选项、标签位置、textLength、textXcenter、标签、,
//注意:我在.style1 css规则中声明了实际的字体像素大小
//只是为了帮助可视化我定位标签文本的方式
textPixelSize=10,
//稍后需要将textYcenter和textXcenter反转为负数
textYcenter=(textPixelSize/2)+2,//2px调整“y”位置,近似值
映射选项={
缩放:6,
中心:新google.maps.LatLng(32.8297,-96.6486),
mapTypeId:google.maps.mapTypeId.HYBRID
},
范围=[62124187249316374],//以英里为单位的圆半径
圆圈=[],
标签=[],
map=new google.maps.map(document.getElementById('map_canvas'),mapOptions);
对于(i=0;i
编辑: 这里是修订版,允许通过“范围”按钮切换环的可见性。还删除了所有文本标签定位调整数学,并替换为对不同长度的文本使用样式类(如果需要,可以更轻松地在样式中使用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>

圈子
.style1{
/*用于环上的范围数*/
颜色:#FFF;
字体大小:.6em;
文本阴影:2px 2px 2px#000;
字体大小:粗体;
字体系列:verdana、helvetica、arial、无衬线字体;
背景色:黑色;
边缘顶部:-0.5em;
}
.d2{/*环上的两位数*/
左边距:-1米;
}
.d3{/*环上的三位数字*/
左边距:-1.5em;
}
/*现有.按钮样式规则的直接副本*/
.按钮{
光标:指针;
-webkit用户选择:无;
-moz用户选择:无;
文本对齐:居中;
位置:相对位置;
字体系列:Arial,无衬线;
字体大小:13px;
字体大小:粗体;
盒影:rgba(0,0,0,0.4)0 2px 4px;
-moz盒阴影:rgba(0,0,0,0.4)02px4px;
-webkit盒阴影:rgba(0,0,0,0.4)0 2px 4px;
颜色:#000;
边框:1px实心#717B87;
背景色:#fff;
保证金:5px;
填充:1px6px;
溢出:隐藏;
}
函数LabelCircle(选项){
this.circle=新的google.maps.circle(options.circleOptions);
this.label=新ELabel(options.labelOptions);
this.label.setMap(options.circleOptions.map);
this.isVisible=true;
}
LabelCircle.prototype.setVisible=函数(bool){
var方法=(bool)?'show':'hide';
此.circle.setVisible(bool);
这个.标签[方法]();
this.isVisible=bool;
};
//现有功能的直接副本
功能按钮控制(选项){
var control=document.createElement('DIV');
control.innerHTML=options.name;
control.className='button';
控制指数=1;
//将控件添加到映射中
options.gmap.controls[options.position].push(control);
google.maps.event.addDomListener(控件“单击”,选项.action);
返回控制;
}
函数初始化(){
变量i、仪表、选项、标签位置、文本长度、标签、,
映射选项={
缩放:6,
中心:新google.maps.LatLng(32.8297,-96.6486),
mapTypeId:google.maps.mapTypeId.HYBRID
},
范围=[62124187249316374],//以英里为单位的圆半径
labelCircles=[],
map=new google.maps.map(document.getElementById('map_canvas'),mapOptions);
<!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>