如何在Google地图上绘制圆圈时了解半径 [英] How to know radius while drawing a circle on Google Maps
问题描述
我有什么:
根据Google的建议,我们使用了MVC对象和 DistanceWidget
&
RadiusWidget
显示半径,同时调整对现有圆圈(由DistanceWidget绘制的圆圈)正常工作的圆的大小。
我需要: 我需要显示画一个新的圈子圈。事件 是否可以显示DistanceWidget来创建新的圈子? 的确是一个很好的挑战。正如@DaveAlperovich所评论的那样,你不能使用 不过,如果您不能拥有真正的管理员,那就假装它。 文件中的某处或作为外部库: 这是我们可能使用的功能; ) 重置方法可在需要时恢复一致状态: 而且,远程计算机:
DistanceWidget
& RadiusWidget
仅用于现有圆圈(由 DistanceWidget
绘制的圆圈)不适用于新圆圈(用户使用DrawingManager绘制的圆圈工具)。
DrawingManager
来检索这条信息;在绘图时,您无法访问该圈子;您必须等待 DrawingManager
触发 circlecomplete
事件才能获得对此圆圈的引用。
查看下面的代码段和描述。
var FakeDrawer = function(controlDiv,map){var self = this; / *初始化,一些样式... * / self._map = map; self.initControls(controlDiv); / *设置click事件侦听器:drawingmode为圆形控件* / google.maps.event.addDomListener(self._controls.circle,'click',function(){/ *确保一致性* / self.reset(); / *绑定绘图模式* / self._map.setOptions({draggableCursor:crosshair}); self._drawListener = self._map.addListener('mousedown',self.drawingMode(self));}); / *只需重置停止控件的东西* / google.maps.event.addDomListener(self._controls.stop,'click',function(){self.reset();});}; FakeDrawer.prototype.drawingMode =函数(self){return function(center){/ *让我们在绘制过程中冻结地图* / self._map.setOptions({draggable:false}); / *创建一个将被手动缩放的新圆圈* / var circle = new google.maps.Circle({fillColor:'#000',fillOpacity:0.3,strokeWeight:2,clickable:false,editable:false,map:self ._map,radius:1,center:center.latLng,zIndex:1}); / *更新每个鼠标移动的半径* / var onMouseMove = self._map.addListener('mousemove',function(border){var radius = 1000 * self.distanceBetweenPoints(center.latLng,border.latLng); circle.setRadius (radius); / *以下是该特性,绘制时知道半径* / google.maps.event.trigger(self,'drawing_radius_changed',circle);}); / *用户已完成绘图* / google.maps.event.addListenerOnce(self._map,'mouseup',function(){/ *移除所有侦听器,因为它们不再是必需的* / google.maps.event.removeListener (onMouseMove); circle.setEditable(true); / *恢复一些选项以保持一致的行为* / self.reset(); / *通知侦听器与最后一个圆圈* / google.maps.event.trigger(self,' circlecomplete',circle);}); };}; FakeDrawer.prototype.reset = function(){var self = this; self._map.setOptions({draggableCursor:,draggable:true}); / *删除任何应用的侦听器* / if(self._drawListener){google.maps.event.removeListener(self._drawListener); }}; / *创建视图和关联的css * / FakeDrawer.prototype.initControls = function(controlDiv){var self = this;函数createControlUI(title,image){var controlUI = document.createElement('div'); controlUI.style.backgroundColor ='#fff'; controlUI.style.border ='1px solid rgba(0,0,0,.15)'; controlUI.style.boxShadow ='1 4px -1px rgba(0,0,0,.3)'; controlUI.style.marginTop ='10px'; controlUI.style.textAlign ='center'; controlUI.style.width ='25px'; controlUI.style.height ='25px'; controlUI.style.display ='inline-block'; controlUI.title = title; if(image ==circle){controlUI.style.borderLeft =none; } var controlImgWrapper = document.createElement('div'); controlImgWrapper.style.width ='16px'; controlImgWrapper.style.height ='16px'; controlImgWrapper.style.overflow ='隐藏'; controlImgWrapper.style.display ='inline-block'; controlImgWrapper.style.marginTop ='4px'; controlUI.appendChild(controlImgWrapper); var imageOffset = {circle:0,openhand:-9 * 16} [image]; var controlImg = document.createElement('img'); controlImg.src ='https://maps.gstatic.com/mapfiles/drawing.png'; controlImg.style.marginTop = imageOffset +px; controlImgWrapper.appendChild(controlImg); var focusBackground = function(){controlUI.style.backgroundColor ='#eee'; }; var unfocusBackground = function(){controlUI.style.backgroundColor =#fff; }; controlImg.addEventListener('mouseenter',focusBackground); controlImg.addEventListener('mouseout',unfocusBackground); controlUI.addEventListener('mouseenter',focusBackground); controlUI.addEventListener('mouseout',unfocusBackground);返回controlUI; } self._controls = {circle:createControlUI(绘制一个圆圈,circle),停止:createControlUI(停止绘制,openhand),}; controlDiv.appendChild(self._controls.stop); controlDiv.appendChild(self._controls.circle);}; FakeDrawer.prototype.distanceBetweenPoints = function(p1,p2){if(!p1 ||!p2){return 0; } var R = 6371; var dLat =(p2.lat() - p1.lat())* Math.PI / 180; var dLon =(p2.lng() - p1.lng())* Math.PI / 180; Math.sin(dLat / 2)* Math.sin(dLat / 2)+ Math.cos(p1.lat()* Math.PI / 180)* Math.cos(p2.lat()* Math。 PI / 180)* Math.sin(dLon / 2)* Math.sin(dLon / 2); var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1 - a)); var d = R * c; return d;};函数InitializeMap(){var latlng = new google.maps.LatLng(29.760193,-95.36939); var myOptions = {zoom:12,center:latlng,zoomControl:true,mapTypeId:google.maps.MapTypeId.ROADMAP,disableDefaultUI:true}; var map = new google.maps.Map(document.getElementById(map),myOptions); / *添加自定义控件* / var fakeDrawerDiv = document.createElement('div'); var fakeDrawer = new FakeDrawer(fakeDrawerDiv,map); fakeDrawerDiv.index = 1; map.controls [google.maps.ControlPosition.TOP_CENTER] .push(fakeDrawerDiv); var updateInfo = function(circle){document.getElementById(info)。innerHTML =Radius:+ circle.getRadius(); }; google.maps.event.addListener(fakeDrawer,'drawing_radius_changed',updateInfo); google.maps.event.addListener(fakeDrawer'circlecomplete',function(circle){google.maps.event.addListener(circle,'radius_changed',function(){updateInfo(circle);});});} google .maps.event.addDomListener(window,'load',InitializeMap);
html,body {height:100%; margin:0px; padding:0px} #map {height:80%; width:100%;}
< script src = https://maps.googleapis.com/maps/api/js?v=3&libraries=drawing&ext=.js\"></script><div id =地图>< / div> ;< div id =info>< / div>
第1步:创建自定义控件
var FakeDrawer = function(controlDiv,map){
var self = this;
/ *初始化,一些样式... * /
self._map = map;
self.initControls(controlDiv);
};
FakeDrawer.prototype.initControls(controlDiv){
var self = this;
function createControlUI(title,image){
var controlUI = document.createElement('div');
/ * ...查看片段的细节..只是一些样式* /
return controlUI;
self._controls = {
circle:createControlUI(绘制圆,圆),
stop:createControlUI(停止绘制, openhand),
};
controlDiv.appendChild(self._controls.stop);
controlDiv.appendChild(self._controls.circle);
};
步骤2:添加一些糖分
FakeDrawer.prototype.reset = function(){
var self = this;
self._map.setOptions({
draggableCursor:,
draggable:true
});
$ b $ / *移除所有应用的监听器* /
if(self._drawListener){google.maps.event.removeListener(self._drawListener); }
};
FakeDrawer.prototype.distanceBetweenPoints = function(p1,p2){
if(!p1 ||!p2){
return 0;
}
var R = 6371;
var dLat =(p2.lat() - p1.lat())* Math.PI / 180;
var dLon =(p2.lng() - p1.lng())* Math.PI / 180;
var a = Math.sin(dLat / 2)* Math.sin(dLat / 2)+ Math.cos(p1.lat()* Math.PI / 180)* Math.cos(p2.lat )* Math.PI / 180)* Math.sin(dLon / 2)* Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1 - a));
var d = R * c;
return d;
};
第3步:创建您自己的绘图模式
<现在我们有了一些控制,我们必须定义它们的行为。 stop 控制很简单,让我们看看
圈
控制。
FakeDrawer.prototype。 drawingMode = function(self){
return function(center){
/ *让我们在绘制过程中冻结地图* /
self._map.setOptions({draggable:false});
/ *创建一个新的圈子,手动缩放* /
var circle = new google.maps.Circle({
fillColor:'#000',
fillOpacity:0.3,
strokeWeight:2,
clickable:false,
editable:false,
map:self._map,
radius:1,
center:center.latLng,
zIndex:1
});
$ b $ *更新每个鼠标移动的半径* /
var onMouseMove = self._map.addListener('mousemove',function(border){
var radius = 1000 * self.distanceBetweenPoints(center.latLng,border.latLng);
circle.setRadius(radius);
/ *以下是该功能,绘制时知道半径* /
google.maps.event.trigger(self,'drawing_radius_changed',circle);
});
$ b $ * / *用户已完成绘图* /
google.maps.event.addListenerOnce(self._map,'mouseup',function(){
/ *全部删除因为它们不再需要* /
google.maps.event.removeListener(onMouseMove);
circle.setEditable(true);
/ *还原一些选项保持一致的行为* /
self.reset();
/ *通知监听器与最终圈* /
google.maps.event.trigger(self ,'circlecplete',圈);
});
};
};
步骤4:绑定控制
现在确保一切正常,让我们在构造函数的初始版本中添加一些监听器,以便每个控件在单击时都有相应的操作。
var FakeDrawer = function(controlDiv,map){
var self = this;
/ *初始化,一些样式... * /
self._map = map;
self.initControls(controlDiv);
$ b $ *设置点击事件侦听器:drawingmode * /
google.maps.event.addDomListener(self._controls.circle,'click',function(){
/ *确保一致性* /
self.reset();
/ *仅绘图模式* /
self._map.setOptions({draggableCursor:crosshair});
self._drawListener = self._map.addListener('mousedown',self.drawingMode(self));
});
google.maps.event.addDomListener(self._controls.stop,'click',function(){
self.reset();
});
};
步骤5:使用它!
假设您的地图已正确初始化。
在您的map init函数中:
var fakeDrawerDiv = document。的createElement( 'DIV');
var fakeDrawer = new FakeDrawer(fakeDrawerDiv,map);
fakeDrawerDiv.index = 1;
map.controls [google.maps.ControlPosition.TOP_CENTER] .push(fakeDrawerDiv);
$ b $ var updateInfo = function(circle){
document.getElementById(info)。innerHTML =Radius:+ circle.getRadius();
};
google.maps.event.addListener(fakeDrawer,'drawing_radius_changed',updateInfo);
google.maps.event.addListener(fakeDrawer'circlecomplete',function(circle){
google.maps.event.addListener(circle,'radius_changed',function(){
updateInfo (圈);
});
});
享受,希望它会有所帮助。
What I have :
As per Google suggestion we have used MVC object and the events DistanceWidget
& RadiusWidget
to display the radius while re-sizing the circle which is working fine for existing circle (circle drawn by DistanceWidget).
What I need :
I need to show the radius of the circle while drawing a new circle. The event DistanceWidget
& RadiusWidget
are used only for existing circle (circle drawn by DistanceWidget
) not for new circle (user drawn circle by using DrawingManager tool).
Is it possible to show DistanceWidget for creating new circle?
a nice challenge indeed. As @DaveAlperovich has commented, you can't use the DrawingManager
to retrieve this piece of information; While drawing, you don't have any access to the circle; You have to wait for the DrawingManager
to trigger the circlecomplete
event to get a reference to this circle.
Nevertheless, if you can't have a real manager, just fake it. See the snippet and the description right below.
var FakeDrawer = function(controlDiv, map) {
var self = this;
/* Initialization, some styling ... */
self._map = map;
self.initControls(controlDiv);
/* Setup the click event listener: drawingmode for the circle control */
google.maps.event.addDomListener(self._controls.circle, 'click', function() {
/* Ensure consistency */
self.reset();
/* Bind the drawing mode */
self._map.setOptions({
draggableCursor: "crosshair"
});
self._drawListener = self._map.addListener('mousedown', self.drawingMode(self));
});
/* Just reset things for the stop controls */
google.maps.event.addDomListener(self._controls.stop, 'click', function() {
self.reset();
});
};
FakeDrawer.prototype.drawingMode = function(self) {
return function(center) {
/* Let's freeze the map during drawing */
self._map.setOptions({
draggable: false
});
/* Create a new circle which will be manually scaled */
var circle = new google.maps.Circle({
fillColor: '#000',
fillOpacity: 0.3,
strokeWeight: 2,
clickable: false,
editable: false,
map: self._map,
radius: 1,
center: center.latLng,
zIndex: 1
});
/* Update the radius on each mouse move */
var onMouseMove = self._map.addListener('mousemove', function(border) {
var radius = 1000 * self.distanceBetweenPoints(center.latLng, border.latLng);
circle.setRadius(radius);
/* Here is the feature, know the radius while drawing */
google.maps.event.trigger(self, 'drawing_radius_changed', circle);
});
/* The user has finished its drawing */
google.maps.event.addListenerOnce(self._map, 'mouseup', function() {
/* Remove all listeners as they are no more required */
google.maps.event.removeListener(onMouseMove);
circle.setEditable(true);
/* Restore some options to keep a consistent behavior */
self.reset();
/* Notify listener with the final circle */
google.maps.event.trigger(self, 'circlecomplete', circle);
});
};
};
FakeDrawer.prototype.reset = function() {
var self = this;
self._map.setOptions({
draggableCursor: "",
draggable: "true"
});
/* Remove any applied listener */
if (self._drawListener) {
google.maps.event.removeListener(self._drawListener);
}
};
/* Create views and associated css */
FakeDrawer.prototype.initControls = function(controlDiv) {
var self = this;
function createControlUI(title, image) {
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '1px solid rgba(0, 0, 0, .15)';
controlUI.style.boxShadow = '1 4px -1px rgba(0, 0, 0, .3)';
controlUI.style.marginTop = '10px';
controlUI.style.textAlign = 'center';
controlUI.style.width = '25px';
controlUI.style.height = '25px';
controlUI.style.display = 'inline-block';
controlUI.title = title;
if (image == "circle") {
controlUI.style.borderLeft = "none";
}
var controlImgWrapper = document.createElement('div');
controlImgWrapper.style.width = '16px';
controlImgWrapper.style.height = '16px';
controlImgWrapper.style.overflow = 'hidden';
controlImgWrapper.style.display = 'inline-block';
controlImgWrapper.style.marginTop = '4px';
controlUI.appendChild(controlImgWrapper);
var imageOffset = {
"circle": 0,
"openhand": -9 * 16
}[image];
var controlImg = document.createElement('img');
controlImg.src = 'https://maps.gstatic.com/mapfiles/drawing.png';
controlImg.style.marginTop = imageOffset + "px";
controlImgWrapper.appendChild(controlImg);
var focusBackground = function() {
controlUI.style.backgroundColor = '#eee';
};
var unfocusBackground = function() {
controlUI.style.backgroundColor = "#fff";
};
controlImg.addEventListener('mouseenter', focusBackground);
controlImg.addEventListener('mouseout', unfocusBackground);
controlUI.addEventListener('mouseenter', focusBackground);
controlUI.addEventListener('mouseout', unfocusBackground);
return controlUI;
}
self._controls = {
circle: createControlUI("Draw a circle", "circle"),
stop: createControlUI("Stop drawing", "openhand"),
};
controlDiv.appendChild(self._controls.stop);
controlDiv.appendChild(self._controls.circle);
};
FakeDrawer.prototype.distanceBetweenPoints = function(p1, p2) {
if (!p1 || !p2) {
return 0;
}
var R = 6371;
var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
function InitializeMap() {
var latlng = new google.maps.LatLng(29.760193, -95.36939);
var myOptions = {
zoom: 12,
center: latlng,
zoomControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
/* Add a custom control */
var fakeDrawerDiv = document.createElement('div');
var fakeDrawer = new FakeDrawer(fakeDrawerDiv, map);
fakeDrawerDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(fakeDrawerDiv);
var updateInfo = function(circle) {
document.getElementById("info").innerHTML = "Radius: " + circle.getRadius();
};
google.maps.event.addListener(fakeDrawer, 'drawing_radius_changed', updateInfo);
google.maps.event.addListener(fakeDrawer, 'circlecomplete', function(circle) {
google.maps.event.addListener(circle, 'radius_changed', function() {
updateInfo(circle);
});
});
}
google.maps.event.addDomListener(window, 'load', InitializeMap);
html,
body {
height: 100%;
margin: 0px;
padding: 0px
}
#map {
height: 80%;
width: 100%;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=drawing&ext=.js"></script>
<div id="map"></div>
<div id="info"></div>
Step 1: Create a custom control
Somewhere in the file or as an external library:
var FakeDrawer = function (controlDiv, map) {
var self = this;
/* Initialization, some styling ... */
self._map = map;
self.initControls(controlDiv);
};
FakeDrawer.prototype.initControls(controlDiv) {
var self = this;
function createControlUI (title, image) {
var controlUI = document.createElement('div');
/* ... See the snippet for details .. just some styling */
return controlUI;
}
self._controls = {
circle: createControlUI("Draw a circle", "circle"),
stop: createControlUI("Stop drawing", "openhand"),
};
controlDiv.appendChild(self._controls.stop);
controlDiv.appendChild(self._controls.circle);
};
Step 2: Add some sugars
This are functions that we may use; Highly inspired from your JsFiddle :)
A reset method to recover a consistent state when needed:
FakeDrawer.prototype.reset = function () {
var self = this;
self._map.setOptions({
draggableCursor: "",
draggable: "true"
});
/* Remove any applied listener */
if (self._drawListener) { google.maps.event.removeListener(self._drawListener) ; }
};
And, a distance computer:
FakeDrawer.prototype.distanceBetweenPoints = function (p1, p2) {
if (!p1 || !p2) {
return 0;
}
var R = 6371;
var dLat = (p2.lat() - p1.lat()) * Math.PI / 180;
var dLon = (p2.lng() - p1.lng()) * Math.PI / 180;
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
};
Step 3: Create your own drawing mode
Now that we have some controls, we have to define their behavior. The stop
control is straightforward; Let's have a look to the circle
control.
FakeDrawer.prototype.drawingMode = function (self) {
return function (center) {
/* Let's freeze the map during drawing */
self._map.setOptions({draggable: false});
/* Create a new circle which will be manually scaled */
var circle = new google.maps.Circle({
fillColor: '#000',
fillOpacity: 0.3,
strokeWeight: 2,
clickable: false,
editable: false,
map: self._map,
radius: 1,
center: center.latLng,
zIndex: 1
});
/* Update the radius on each mouse move */
var onMouseMove = self._map.addListener('mousemove', function (border) {
var radius = 1000 * self.distanceBetweenPoints(center.latLng, border.latLng);
circle.setRadius(radius);
/* Here is the feature, know the radius while drawing */
google.maps.event.trigger(self, 'drawing_radius_changed', circle);
});
/* The user has finished its drawing */
google.maps.event.addListenerOnce(self._map, 'mouseup', function () {
/* Remove all listeners as they are no more required */
google.maps.event.removeListener(onMouseMove);
circle.setEditable(true);
/* Restore some options to keep a consistent behavior */
self.reset();
/* Notify listener with the final circle */
google.maps.event.trigger(self, 'circlecomplete', circle);
});
};
};
Step 4: Bind controls
Now that everything is okay, let's add some listeners to the initial version of the constructor so that each control has a corresponding action when clicked.
var FakeDrawer = function (controlDiv, map) {
var self = this;
/* Initialization, some styling ... */
self._map = map;
self.initControls(controlDiv);
/* Setup the click event listeners: drawingmode */
google.maps.event.addDomListener(self._controls.circle, 'click', function() {
/* Ensure consistency */
self.reset();
/* Only drawingmode */
self._map.setOptions({draggableCursor: "crosshair"});
self._drawListener = self._map.addListener('mousedown', self.drawingMode(self));
});
google.maps.event.addDomListener(self._controls.stop, 'click', function () {
self.reset();
});
};
Step 5: Use it!
Assuming that your map has been initialized correctly.
Inside your map init function:
var fakeDrawerDiv = document.createElement('div');
var fakeDrawer = new FakeDrawer(fakeDrawerDiv, map);
fakeDrawerDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(fakeDrawerDiv);
var updateInfo = function (circle) {
document.getElementById("info").innerHTML = "Radius: " + circle.getRadius();
};
google.maps.event.addListener(fakeDrawer, 'drawing_radius_changed', updateInfo);
google.maps.event.addListener(fakeDrawer, 'circlecomplete', function (circle) {
google.maps.event.addListener(circle, 'radius_changed', function () {
updateInfo(circle);
});
});
Enjoy, hope it will help.
这篇关于如何在Google地图上绘制圆圈时了解半径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!