【发布时间】:2016-09-13 08:47:17
【问题描述】:
下面的代码包含适当的 cmets 以便正确理解。如果问题不清楚,请告诉我
我的要求是获取用户在地图上所做的矩形选择下的所有标记的信息。 (使用控制键+鼠标按下+鼠标移动事件)
我有一个要在谷歌地图中绘制的标记列表。为了稍后对其进行操作,我使用了 API 提供的自定义叠加层。它工作正常。
现在我需要允许用户通过按下 Control 键 + 鼠标来绘制一个矩形选择。当鼠标移动时,会在地图上绘制一个矩形,并检查是否有任何标记位于绘制的矩形下方。这也很好用。
但是,如果我使用鼠标滚动地图,则会错误地计算值并且没有得到结果。即矩形没有正确绘制。
我的分析是鼠标移动事件的PageX和PageY的使用有问题。最初我使用了 clientX 和 clientY,但为了帐户滚动,我使用了 PageX 和 PageY。
这里可能有什么问题?请告诉我。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Proto 1 displaying a list of cameras with custom markers.</title>
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
#rectangle {
position: absolute;
border: 1px solid #c1e0ff;
z-index: 100000;
visibility: hidden;
background-color: #c1e0ff;
opacity: 0.5
}
</style>
</head>
<body>
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBY_Jb6UGbhR1g9cM3uPGStdevUputZh5s"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var map;
/* Need to listen for control key + mouse down + mouse move to draw a rectangle over google map and check for markers below the selection*/
document.addEventListener('keydown', multipleCameraSelection);
function multipleCameraSelection(e) {
if (e.ctrlKey) {
map.setOptions({
draggable: false
});
document.onmousedown = function(event) {
/*get div having ID of rectangle.This is created and added to the overlay image pane of map in the draw() function*/
var rectangleDiv = document.getElementById('rectangle');
/*get the co ordinates where mouse is clicked*/
var initialX = event.pageX;
var initialY = event.pageY;
rectangleDiv.style.left = initialX + 'px';
rectangleDiv.style.top = initialY + 'px';
document.onmousemove = function(event) {
/*on mouse move width and height of rectangle is calculated and set*/
var wid = Math.abs(event.pageX - initialX);
var hei = Math.abs(event.pageY - initialY);
rectangleDiv.style.width = wid + 'px';
rectangleDiv.style.height = hei + 'px';
rectangleDiv.style.visibility = 'visible';
if (event.pageX < initialX && event.pageY >= initialY) {
rectangleDiv.style.left = event.pageX + 'px';
} else if (event.pageY <= initialY && event.pageX >= initialX) {
rectangleDiv.style.top = event.pageY + 'px';
} else if (event.pageY < initialY && event.pageX < initialX) {
rectangleDiv.style.left = event.pageX + 'px';
rectangleDiv.style.top = event.pageY + 'px';
}
}
document.onmouseup = function(event) {
document.onmousedown = null;
document.onmousemove = null;
document.onmouseup = null;
rectangleDiv.style.visibility = 'hidden';
/*get the current left , top value of element*/
var rectPos = getOffsetValues(rectangleDiv);
/*all markers have a name starting with cameraDiv. checking whether they lies between the rectangle drawn*/
$("div[id^='cameraDiv']").each(function(index, value) {
var elemToFind = value;
var elemToFindpos = getOffsetValues(elemToFind);
if ((((rectPos.topValue + rectangleDiv.offsetHeight) > elemToFindpos.topValue) && (rectPos.topValue < elemToFindpos.topValue || rectPos.topValue <= (elemToFindpos.topValue + elemToFind.offsetHeight))) &&
(((rectPos.leftValue + rectangleDiv.offsetWidth) > elemToFindpos.leftValue) && (rectPos.leftValue < elemToFindpos.leftValue || rectPos.leftValue <= (elemToFindpos.leftValue + elemToFind.offsetWidth)))) {
console.log(value);
}
})
map.setOptions({
draggable: true
});
}
}
}
}
function getOffsetValues(elem) {
var left = 0,
top = 0;
while (elem) {
left += elem.offsetLeft;
top += elem.offsetTop;
elem = elem.offsetParent;
}
return {
leftValue: left,
topValue: top
};
}
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {
lat: 8.5241,
lng: 76.9366
}
});
overlay = new CameraLayer(map);
//setMarkers(map);
}
var overlay;
CameraLayer.prototype = new google.maps.OverlayView();
function CameraLayer(map) {
this.map_ = map;
this.div_ = null;
this.setMap(map);
//window.alert('constructor called');
}
CameraLayer.prototype.onAdd = function() {
var panes = this.getPanes();
var div = document.createElement('div');
div.style.position = 'absolute';
div.id = 'myCustomdiv';
this.div_ = div;
panes.overlayImage.appendChild(this.div_);
}
CameraLayer.prototype.draw = function() {
/*when a scroll happens replot the markers in correct pixel coordinates using methods exposed by map api*/
while (this.div_.firstChild)
this.div_.removeChild(this.div_.firstChild);
var msgContainer = document.createDocumentFragment();
for (i = 0; i < camerasToPlace.length; i++) {
var lat = camerasToPlace[i];
var lat1 = lat[1];
var lng1 = lat[2];
var latLng = new google.maps.LatLng({
lat: lat1,
lng: lng1
});
var pixelPosition = this.getProjection().fromLatLngToDivPixel(latLng);
//msgContainer.appendChild()
var div1 = document.createElement('div');
div1.id = 'cameraDiv' + i;
div1.style.position = 'absolute';
var img = document.createElement('img');
img.src = 'camera.png';
img.style.position = 'absolute';
//img.style.width = '100%';
//img.style.height = '100%';
div1.style.left = pixelPosition.x + 'px';
div1.style.top = pixelPosition.y + 'px';
//
div1.style.width = '32px';
div1.style.height = '32px';
div1.appendChild(img);
msgContainer.appendChild(div1)
}
/*creating and appending a div to the overlay image , width and height calculated when the mouse move event happens , style applied above*/
var rectDiv = document.createElement('div');
rectDiv.id = 'rectangle';
rectDiv.style.position = 'absolute';
this.div_.appendChild(rectDiv);
/*container holding marker data to plot in map with left and top values*/
this.div_.appendChild(msgContainer);
}
/* a list holding the latitude and longitude values to be used in draw function to plot in map*/
var camerasToPlace = [
['Camera1 located at TVM', 8.545394, 76.883503],
['Camera2 located at TVM', 8.7379, 76.7163],
['Camera3 located at TVM', 8.8932, 76.6141],
['Camera4 located at TVM', 8.7707, 76.8836],
['Camera5 located at TVM', 8.936906, 76.871831],
['Camera6 located at TVM', 8.485295, 76.916806]
];
google.maps.event.addDomListener(window, 'load', initMap);
</script>
</body>
</html>
【问题讨论】:
-
看起来您正在使用网页选择;为了实现您的目标,我会在地图内使用点击事件。那你就不用担心pageX,pageY(这可能会很棘手)
-
@EmmanuelDelay 你的建议奏效了。谢谢
标签: javascript google-maps google-maps-api-3