gpt4 book ai didi

javascript - 如何在谷歌地图上画圆时知道半径

转载 作者:可可西里 更新时间:2023-11-01 02:05:44 30 4
gpt4 key购买 nike

我有什么:

根据 Google 的建议,我们使用了 MVC 对象和事件 DistanceWidgetRadiusWidget 来显示半径,同时重新调整圆的大小,这对于现有的圆(由 DistanceWidget 绘制的圆圈)。

Fiddle Demo

我需要什么:

我需要在绘制新圆时显示圆的半径。 DistanceWidgetRadiusWidget 事件仅用于现有圆(由 DistanceWidget 绘制的圆)而不用于新圆(用户使用 DrawingManager 工具绘制的圆) ).

是否可以显示用于创建新圈子的 DistanceWidget?

Fiddle

最佳答案

确实是一个很好的挑战。正如@DaveAlperovich 评论的那样,您不能使用 DrawingManager 来检索这条信息;绘图时,您无权访问圆圈;您必须等待 DrawingManager 触发 circlecomplete 事件才能获取对此圆的引用。

尽管如此,如果您不能拥有真正的经理,就假装吧。请参阅下面的代码段和说明。

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>

第 1 步:创建自定义控件

文件中某处或作为外部库:

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);
};

第 2 步:添加一些糖

这些是我们可能会用到的功能;从你的 JsFiddle 中得到了很大的启发 :)

在需要时恢复一致状态的重置方法:

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) ; }
};

还有,远程计算机:

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 控件很简单;让我们看一下 circle 控件。

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);
});
};
};

第四步:绑定(bind)控件

现在一切正常,让我们在构造函数的初始版本中添加一些监听器,以便每个控件在单击时都有相应的 Action 。

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();
});
};

第 5 步:使用它!

假设您的 map 已正确初始化。

在你的 map 初始化函数中:

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);
});
});

享受吧,希望对你有帮助。

关于javascript - 如何在谷歌地图上画圆时知道半径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30368231/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com