首先声明感谢http://google-maps-utility-library-v3.googlecode.com/svn/tags/keydragzoom/1.0/docs/examples.html的作者,我参考他的keydragzoom,修改了他的源码完成了我的dragzoomcontrol。
先介绍一下DragZoomControl,简单的很就是在第三版的Google Map中,添加一个按钮,点击“DragZoom”按钮后进行框选操作,框选完成后可以跟后台进行Ajax交互,这里的例子是将框选的southwest和northeast传给后台再传到前台。(有点无聊
)。
然后就是贴上代码:
dragzoomcontrol.js:
(function () {
/**
* Converts 'thin', 'medium', and 'thick' to pixel widths
* in an MSIE environment. Not called for other browsers
* because getComputedStyle() returns pixel widths automatically.
* @param {String} widthValue
*/
var toPixels = function (widthValue) {
var px;
switch (widthValue) {
case 'thin':
px = "2px";
break;
case 'medium':
px = "4px";
break;
case 'thick':
px = "6px";
break;
default:
px = widthValue;
}
return px;
};
/**
* Get the widths of the borders of an HTML element.
*
* @param {Object} h HTML element
* @return {Object} widths object (top, bottom left, right)
*/
var getBorderWidths = function (h) {
var computedStyle;
var bw = {};
if (document.defaultView && document.defaultView.getComputedStyle) {
computedStyle = h.ownerDocument.defaultView.getComputedStyle(h, "");
if (computedStyle) {
// The computed styles are always in pixel units (good!)
bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0;
bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0;
bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0;
return bw;
}
} else if (document.documentElement.currentStyle) { // MSIE
if (h.currentStyle) {
// The current styles may not be in pixel units so try to convert (bad!)
bw.top = parseInt(toPixels(h.currentStyle.borderTopWidth), 10) || 0;
bw.bottom = parseInt(toPixels(h.currentStyle.borderBottomWidth), 10) || 0;
bw.left = parseInt(toPixels(h.currentStyle.borderLeftWidth), 10) || 0;
bw.right = parseInt(toPixels(h.currentStyle.borderRightWidth), 10) || 0;
return bw;
}
}
// Shouldn't get this far for any modern browser
bw.top = parseInt(h.style["border-top-width"], 10) || 0;
bw.bottom = parseInt(h.style["border-bottom-width"], 10) || 0;
bw.left = parseInt(h.style["border-left-width"], 10) || 0;
bw.right = parseInt(h.style["border-right-width"], 10) || 0;
return bw;
};
/**
* Get the position of the mouse relative to the document.
* @param {Object} e Mouse event
* @return {Object} left & top position
*/
var getMousePosition = function (e) {
var posX = 0, posY = 0;
e = e || window.event;
if (typeof e.pageX !== "undefined") {
posX = e.pageX;
posY = e.pageY;
} else if (typeof e.clientX !== "undefined") {
posX = e.clientX +
(typeof document.documentElement.scrollLeft !== "undefined" ? document.documentElement.scrollLeft : document.body.scrollLeft);
posY = e.clientY +
(typeof document.documentElement.scrollTop !== "undefined" ? document.documentElement.scrollTop : document.body.scrollTop);
}
return {
left: posX,
top: posY
};
};
/**
* Get the position of an HTML element relative to the document.
* @param {Object} h HTML element
* @return {Object} left & top position
*/
var getElementPosition = function (h) {
var posX = h.offsetLeft;
var posY = h.offsetTop;
var parent = h.offsetParent;
// Add offsets for all ancestors in the hierarchy
while (parent !== null) {
// Adjust for scrolling elements which may affect the map position.
if (parent !== document.body && parent !== document.documentElement) {
posX -= parent.scrollLeft;
posY -= parent.scrollTop;
}
posX += parent.offsetLeft;
posY += parent.offsetTop;
parent = parent.offsetParent;
}
return {
left: posX,
top: posY
};
};
/**
* Set the properties of an object to those from another object.
* @param {Object} obj target object
* @param {Object} vals source object
*/
var setVals = function (obj, vals) {
if (obj && vals) {
for (var x in vals) {
if (vals.hasOwnProperty(x)) {
obj[x] = vals[x];
}
}
}
return obj;
};
/**
* Set the opacity. If op is not passed in, this function just performs an MSIE fix.
* @param {Node} div
* @param {Number} op (0-1)
*/
var setOpacity = function (div, op) {
if (typeof op !== 'undefined') {
div.style.opacity = op;
}
if (typeof div.style.opacity !== 'undefined') {
div.style.filter = "alpha(opacity=" + (div.style.opacity * 100) + ")";
}
};
function DragZoom(map, opt_zoomOpts) {
var ov = new google.maps.OverlayView();
var me = this;
ov.onAdd = function () {
me.init_(map, opt_zoomOpts);
};
ov.draw = function () {
};
ov.onRemove = function () {
};
ov.setMap(map);
this.prjov_ = ov;
}
/**
* Init the tool.
*/
DragZoom.prototype.init_ = function (map, opt_zoomOpts) {
// Set CSS styles for the DIV containing the control
this.controlDiv_=opt_zoomOpts.controlDiv;
this.controlDiv_.style.paddingTop = '5px';
// Set CSS for the control border
var controlUI = document.createElement('DIV');
controlUI.style.backgroundColor = '#FFFFFF';
controlUI.style.borderColor = '#717B87';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '1px';
controlUI.style.boxShadow = '1px 2px 4px #888888';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to Active the map DragZoom';
this.controlDiv_.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('DIV');
controlText.style.fontFamily = 'Arial,sans-serif';
controlText.style.fontSize = '12px';
controlText.style.paddingBottom = '1px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.style.paddingTop = '1px';
controlText.innerHTML = 'DragZoom';
controlUI.appendChild(controlText);
this.map_ = map;
opt_zoomOpts = opt_zoomOpts || {};
this.borderWidths_ = getBorderWidths(this.map_.getDiv());//Container());
this.paneDiv_ = document.createElement("div");
this.paneDiv_.onselectstart = function () {
return false;
};
// default style
setVals(this.paneDiv_.style, {
backgroundColor: 'white',
opacity: 0.0,
cursor: 'crosshair'
});
// allow overwrite
setVals(this.paneDiv_.style, opt_zoomOpts.paneStyle);
// stuff that cannot be overwritten
setVals(this.paneDiv_.style, {
position: 'absolute',
overflow: 'hidden',
zIndex: 10001,
display: 'none'
});
setOpacity(this.paneDiv_);
// An IE fix: if the background is transparent, it cannot capture mousedown events
if (this.paneDiv_.style.backgroundColor === 'transparent') {
this.paneDiv_.style.backgroundColor = 'white';
setOpacity(this.paneDiv_, 0);
}
this.map_.getDiv().appendChild(this.paneDiv_);//Container()
this.boxDiv_ = document.createElement('div');
setVals(this.boxDiv_.style, {
border: 'thin solid #FF0000'
});
setVals(this.boxDiv_.style, opt_zoomOpts.boxStyle);
setVals(this.boxDiv_.style, {
position: 'absolute',
display: 'none'
});
setOpacity(this.boxDiv_);
this.map_.getDiv().appendChild(this.boxDiv_);
this.boxBorderWidths_ = getBorderWidths(this.boxDiv_);
var me = this;
this.controlUIDownListener_ = google.maps.event.addDomListener(controlUI, 'click', function() {
me.onControlUIClick_();
});
this.mouseDownListener_ = google.maps.event.addDomListener(this.paneDiv_, 'mousedown', function (e) {
me.onMouseDown_(e);
});
this.mouseDownListenerDocument_ = google.maps.event.addDomListener(document, 'mousedown', function (e) {
me.onMouseDownDocument_(e);
});
this.mouseMoveListener_ = google.maps.event.addDomListener(document, 'mousemove', function (e) {
me.onMouseMove_(e);
});
this.mouseUpListener_ = google.maps.event.addDomListener(document, 'mouseup', function (e) {
me.onMouseUp_(e);
});
this.controlUIDown_ = false;
this.dragging_ = false;
this.startPt_ = null;
this.endPt_ = null;
this.boxMaxX_ = null;
this.boxMaxY_ = null;
this.mousePosn_ = null;
this.mapPosn_ = getElementPosition(this.map_.getDiv());
this.mouseDown_ = false;
};
/**
* Checks if the mouse is on top of the map. The position is captured
* in onMouseMove_.
* @return true if mouse is on top of the map div.
*/
DragZoom.prototype.isMouseOnMap_ = function () {
var mousePos = this.mousePosn_;
if (mousePos) {
var mapPos = this.mapPosn_;
var mapDiv = this.map_.getDiv();
return mousePos.left > mapPos.left && mousePos.left < mapPos.left + mapDiv.offsetWidth &&
mousePos.top > mapPos.top && mousePos.top < mapPos.top + mapDiv.offsetHeight;
} else {
// if user never moved mouse
return false;
}
};
/**
* Show or hide the overlay pane, depending on whether the mouse is over the map.
*/
DragZoom.prototype.setPaneVisibility_ = function () {
if (this.map_ && this.controlUIDown_ && this.isMouseOnMap_()) {
//alert("setPaneVisibility_");
var mapDiv = this.map_.getDiv();
this.paneDiv_.style.left = 0 + 'px';
this.paneDiv_.style.top = 0 + 'px';
this.paneDiv_.style.width = mapDiv.offsetWidth - (this.borderWidths_.left + this.borderWidths_.right) + 'px';
this.paneDiv_.style.height = mapDiv.offsetHeight - (this.borderWidths_.top + this.borderWidths_.bottom) + 'px';
this.paneDiv_.style.display = 'block';
this.boxMaxX_ = parseInt(this.paneDiv_.style.width, 10) - (this.boxBorderWidths_.left + this.boxBorderWidths_.right);
this.boxMaxY_ = parseInt(this.paneDiv_.style.height, 10) - (this.boxBorderWidths_.top + this.boxBorderWidths_.bottom);
} else {
this.paneDiv_.style.display = 'none';
}
};
DragZoom.prototype.onControlUIClick_ = function () {
if (this.map_ && !this.controlUIDown_) {
//alert("onControlUIDown_");
this.controlUIDown_ = true;
this.controlDiv_.childNodes.item(0).style.backgroundColor = '#E8E8E8';
this.controlDiv_.childNodes.item(0).childNodes.item(0).style.fontWeight = 'bold';
this.setPaneVisibility_();
/**
* This event is fired when the ControlUI button is pressed.
* @name DragZoom#activate
* @event
*/
google.maps.event.trigger(me, 'activate');
}else {
alert("onControlUIUp_");
this.controlUIDown_ = false;
this.dragging_ = false;
this.controlDiv_.childNodes.item(0).style.backgroundColor = '#FFFFFF';
this.controlDiv_.childNodes.item(0).childNodes.item(0).style.fontWeight = 'normal';
this.boxDiv_.style.display = 'none';
this.paneDiv_.style.display = "none";
/**
* This event is fired while the user release the controlUI
* @name DragZoom#deactivate
* @event
*/
google.maps.event.trigger(this, 'deactivate');
}
};
/**
* Get the <code>google.maps.Point</code> of the mouse position.
* @param {Object} e
* @return {google.maps.Point} point
* @private
*/
DragZoom.prototype.getMousePoint_ = function (e) {
var mousePosn = getMousePosition(e);
var p = new google.maps.Point();
p.x = mousePosn.left - this.mapPosn_.left - this.borderWidths_.left;
p.y = mousePosn.top - this.mapPosn_.top - this.borderWidths_.top;
p.x = Math.min(p.x, this.boxMaxX_);
p.y = Math.min(p.y, this.boxMaxY_);
p.x = Math.max(p.x, 0);
p.y = Math.max(p.y, 0);
return p;
};
/**
* Handle mouse down.
* @param {Event} e
*/
DragZoom.prototype.onMouseDown_ = function (e) {
if (this.map_ && this.controlUIDown_) {
this.mapPosn_ = getElementPosition(this.map_.getDiv());
this.dragging_ = true;
this.startPt_ = this.endPt_ = this.getMousePoint_(e);
var prj = this.prjov_.getProjection();
var latlng = prj.fromDivPixelToLatLng(this.startPt_);
/**
* This event is fired when the drag operation begins.
* @name DragZoom#dragstart
* @param {GLatLng} startLatLng
* @event
*/
google.maps.event.trigger(this, 'dragstart', latlng);
}
};
/**
* Handle mouse down at the document level.
* @param {Event} e
*/
DragZoom.prototype.onMouseDownDocument_ = function (e) {
this.mouseDown_ = true;
};
/**
* Handle mouse move.
* @param {Event} e
*/
DragZoom.prototype.onMouseMove_ = function (e) {
this.mousePosn_ = getMousePosition(e);
if (this.dragging_) {
this.endPt_ = this.getMousePoint_(e);
var left = Math.min(this.startPt_.x, this.endPt_.x);
var top = Math.min(this.startPt_.y, this.endPt_.y);
var width = Math.abs(this.startPt_.x - this.endPt_.x);
var height = Math.abs(this.startPt_.y - this.endPt_.y);
this.boxDiv_.style.left = left + 'px';
this.boxDiv_.style.top = top + 'px';
this.boxDiv_.style.width = width + 'px';
this.boxDiv_.style.height = height + 'px';
this.boxDiv_.style.display = 'block';
/**
* This event is repeatedly fired while the user drags the box. The southwest and northeast
* point are passed as parameters of type <code>google.maps.Point</code> (for performance reasons),
* relative to the map container. Note: the event listener is responsible
* for converting Pixel to LatLng, if necessary.
* @name DragZoom#drag
* @param {google.maps.Point} southwestPixel
* @param {google.maps.Point} northeastPixel
* @event
*/
google.maps.event.trigger(this, 'drag', new google.maps.Point(left, top + height), new google.maps.Point(left + width, top));
} else if (!this.mouseDown_) {
this.setPaneVisibility_();
}
};
/**
* Handle mouse up.
* @param {Event} e
*/
DragZoom.prototype.onMouseUp_ = function (e) {
this.mouseDown_ = false;
if (this.dragging_) {
var left = Math.min(this.startPt_.x, this.endPt_.x);
var top = Math.min(this.startPt_.y, this.endPt_.y);
var width = Math.abs(this.startPt_.x - this.endPt_.x);
var height = Math.abs(this.startPt_.y - this.endPt_.y);
var prj = this.prjov_.getProjection();
// 2009-05-29: since V3 does not have fromContainerPixel,
var containerPos = getElementPosition(this.map_.getDiv());
var mapPanePos = getElementPosition(this.prjov_.getPanes().mapPane);
left = left + (containerPos.left - mapPanePos.left);
top = top + (containerPos.top - mapPanePos.top);
var sw = prj.fromDivPixelToLatLng(new google.maps.Point(left, top + height));
var ne = prj.fromDivPixelToLatLng(new google.maps.Point(left + width, top));
var bnds = new google.maps.LatLngBounds(sw, ne);
this.map_.fitBounds(bnds);
this.controlUIDown_ = false;
this.dragging_ = false;
this.controlDiv_.childNodes.item(0).style.backgroundColor = '#FFFFFF';
this.controlDiv_.childNodes.item(0).childNodes.item(0).style.fontWeight = 'normal';
this.boxDiv_.style.display = 'none';
/**
* This event is fired when the drag operation ends.
* Note that the event is not fired if the hot key is released before the drag operation ends.
* @name DragZoom#dragend
* @param {GLatLngBounds} newBounds
* @event
*/
google.maps.event.trigger(this, 'dragend', bnds);
}
};
/**
* @name google.maps.Map
* @class These are new methods added to the Google Maps API's
* <a href = 'http://code.google.com/apis/maps/documentation/v3/reference.html#Map'>Map</a>
* class.
*/
/**
* Enable drag zoom. The user can zoom to an area of interest by holding down the hot key
* <code>(shift | ctrl | alt )</code> while dragging a box around the area.
* @param {KeyDragZoomOptions} opt_zoomOpts
*/
google.maps.Map.prototype.enableKeyDragZoom = function (opt_zoomOpts) {
this.dragZoom_ = new DragZoom(this, opt_zoomOpts);
};
/**
* Disable drag zoom.
*/
google.maps.Map.prototype.disableKeyDragZoom = function () {
var d = this.dragZoom_;
if (d) {
alert("disableKeyDragZoom");
google.maps.event.removeListener(d.mouseDownListener_);
google.maps.event.removeListener(d.mouseDownListenerDocument_);
google.maps.event.removeListener(d.mouseMoveListener_);
google.maps.event.removeListener(d.mouseUpListener_);
google.maps.event.removeListener(d.controlUIDownListener_);
google.maps.event.removeListener(d.controlUIUpListener_);
this.getDiv().removeChild(d.boxDiv_);
this.getDiv().removeChild(d.paneDiv_);
this.dragZoom_ = null;
}
};
/**
* Returns true if the drag zoom feature has been enabled.
* @return {Boolean}
*/
google.maps.Map.prototype.keyDragZoomEnabled = function () {
return this.dragZoom_ !== null;
};
/**
* Returns the DragZoom object which is created when <code>google.maps.Map.enableKeyDragZoom</code> is called.
* With this object you can use <code>google.maps.event.addListener</code> to attach event listeners
* for the 'activate', 'deactivate', 'dragstart', 'drag', and 'dragend' events.
* @return {DragZoom}
*/
google.maps.Map.prototype.getDragZoomObject = function () {
return this.dragZoom_;
};
})();
index.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<style>
#map {
width: 700px;
height: 400px;
}
</style>
<script type="text/javascript" src="js/jquery-1.7.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="js/dragzoomcontrol.js"></script>
<script type="text/javascript">
var map;
var markersArray = [];
var center = new google.maps.LatLng(30.67, 104.06);
function init() {
var myOptions = {
zoom: 13,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
// Create the DIV to hold the control and
// call the DragZoomControl() constructor passing in this DIV.
var dragZoomControlDiv = document.createElement('DIV');
dragZoomControlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(dragZoomControlDiv);
map.enableKeyDragZoom({
controlDiv: dragZoomControlDiv,
boxStyle: {
opacity: 0.7
},
paneStyle: {
backgroundColor: "gray",
opacity: 0.1
}
});
var dz = map.getDragZoomObject();
google.maps.event.addListener(dz, 'activate', function() {
log('DragZoom Activated');
});
google.maps.event.addListener(dz, 'dragstart', function(latlng) {
log('DragZoom Started: ' + latlng);
});
google.maps.event.addListener(dz, 'drag', function(start, end) {
//log('DragZoom Dragging...' + start + end);
});
google.maps.event.addListener(dz, 'dragend', function(bnds) {
log('DragZoom DragEnd :' + bnds);
$.ajax({
url: 'AjaxMap',
type: 'post',
dataType: 'json',
data: {
swlat: bnds.getSouthWest().lat(),
swlng: bnds.getSouthWest().lng(),
nelat: bnds.getNorthEast().lat(),
nelng: bnds.getNorthEast().lng()
},
success: function(jsonMsg){
//var json = [eval('(' +jsonMsg +')')];
var json=jsonMsg;
var sw = new google.maps.LatLng(json.swlat, json.swlng);
var ne = new google.maps.LatLng(json.nelat, json.nelng);
deleteOverlays();
addMarker(sw);
addMarker(ne);
}
});
});
google.maps.event.addListener(dz, 'deactivate', function() {
log('DragZoom Deactivated');
});
}
function addMarker(location) {
marker = new google.maps.Marker({
position: location,
map: map,
title: "Hello World"
});
markersArray.push(marker);
}
function deleteOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
}
function log(msg){
$("#msg").html($("#msg").html()+"<br/>"+msg);
//document.getElementById('msg').innerHTML +="<br/>"+msg;
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
<br/>
<div id="msg"></div>
</body>
</html>
后台的servlet:
package com.wujay;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONObject;
public class AjaxMap extends HttpServlet {
public AjaxMap() {
super();
}
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=gbk");
PrintWriter out=response.getWriter();
String swlat=request.getParameter("swlat");
String swlng=request.getParameter("swlng");
String nelat=request.getParameter("nelat");
String nelng=request.getParameter("nelng");
JSONObject obj=new JSONObject();
obj.put("swlat",swlat);
obj.put("swlng",swlng);
obj.put("nelat",nelat);
obj.put("nelng",nelng);
out.print(obj);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
public void init() throws ServletException {
// Put your code here
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>AjaxMap</servlet-name>
<servlet-class>com.wujay.AjaxMap</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AjaxMap</servlet-name>
<url-pattern>/AjaxMap</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
我把MyEclipse工程作为附件有需要的可以看看。
The End

介绍了一款用于Google Maps的自定义插件DragZoomControl,该插件允许用户通过拖拽选择区域来实现地图的缩放功能,并与后台进行Ajax交互获取选区的坐标。

被折叠的 条评论
为什么被折叠?



