Google Maps API详解--01
4.3 Google Maps API详解
新版Google Maps API在功能上分为六大类:
l 核心类(Core Class)。
l 基础类(Base Classes)。
l 事件类(Event Classes)。
l 控制类(Control Classes)。
l 布局类(Overlay Classes)。
l 服务类(Service Classes)。
遗憾的是Google官方英文版网站上已经给出了明确的分类,而中文版官网上并没有更新。
Google Maps API中最核心的部分莫过于核心类GMap2了,它是所有其他元素的核心和基础,其他的元素都是围绕GMap2展开的。本章首先介绍如何创建GMap对象,在此之前,需要确认用户的浏览器是否支持GMap,Google Maps API提供了一种验证的方法——GBrowserIsCompatible()。
4.3.1 验证浏览器是否支持GMap2对象
验证的方法是GBrowserIsCompatible,元素类型为“函数(Function)”。
用返回的布尔值来判断网页浏览器是否符合运行Google Maps的要求。如果返回真,则代表这个浏览器可以查看Google Maps;如果返回否,则不行。
GBrowserIsCompatible函数:var isBwComp = GBrowserIsCompatible()
JavaScript脚本代码如下:
……
if (GBrowserIsCompatible())
{
map = new GMap2(document.getElementById("map1"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(31.7,131.2), 10);
}
一般进行地图创建的时候,首先要判断浏览器是否支持Google Maps的运行。
4.3.2 地图的分层GMapPane类型
GMapPane枚举项定义了地图上不同业务功能的图层系统,每个枚举项代表一个图层。
GMapPane枚举项的介绍如下:
l G_MAP_FLOAT_PANE。
Ø 定义:信息窗口层。
Ø 位置:地图的最上方。
l G_MAP_FLOAT_SHADOW_PANE。
Ø 定义:地图阴影层。
Ø 位置:在标记层之上,标记鼠标事件层之下。
l G_MAP_MAP_PANE。
Ø 定义:这一层包含了Google Maps所绘制的线条。
Ø 位置:倒数第二层,在地图层之上。
l G_MAP_MARKER_MOUSE_TARGET_PANE。
Ø 定义:这一层用于响应鼠标事件,本身的属性是透明的。
Ø 位置:在地图阴影层之上。
l G_MAP_MARKER_PANE。
Ø 定义:包含标记层。
Ø 位置:在标记阴影层之上。
l G_MAP_MARKER_SHADOW_PANE。
Ø 定义:标记阴影层。
Ø 位置:在标记层之下。
这些图层的位置关系如图4-5所示。
图4-5 Google Maps分层
4.3.3 核心类GMap2
1.页面上的HTML代码
作为Google Maps API的核心内容,GMap2实例是所有Google Maps应用的重点对象,GMap2对象贯穿了整个应用项目的全部,无论是编程过程还是调试过程。
有的应用在网页打开时就自动“静态”创建GMap2对象,有的需要通过脚本“动态”创建,或者通过AJAX的方式创建。但无论怎样创建,都必须了解如何才能得到一个稳定、可调试的GMap2对象。
一般采用JavaScript脚本创建,代码如下:
map = new GMap2(document.getElementById("map1"));
GMap2类的元素类型为“类(Class)”,通过该类创建一个地图实例。
2.创建一个GMap对象
创建GMap对象首先需要在网页上有一个容器元素作为创建基础,而通常情况下,这个容器元素是个Div元素,例如:
<div id="map1" style="width: 300px; height: 200px"></div>
有了这个名为“map1”的Div容器对象之后,下一步可以创建GMap对象了,GMap2的构造函数结构如下:
var newMapobj = new GMap2(
container: DOM_Div,
opts: Options);
构造函数参数如表4-2所示。
表4-2 GMap2构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
container |
是 |
DOM_Div |
DOM元素,是个Div |
opts |
可选 |
Options |
构造函数选项 |
用JavaScript脚本创建GMap2的代码如下:
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
……
}
第一行出现的GBrowserIsCompatible()在GMap2介绍之前的4.3.1节中就讲解过——作为验证浏览器是否支持Google Maps运行之用。“map1”已经在页面的HTML代码中定义过了,是一个Div对象。
第三行的setCenter设置了地图的中心,一般情况下是必须的。GMap对象只有设置地图中心之后,才会被标识为已加载。采用isLoaded方法返回true;否则返回false,详情请参见本节后文第6点中对“GMap2地图状态方法”的讲解。
当GMap对象“map”被创建好之后,就可以使用“map.”这种形式来调用GMap2的各种方法了。
GMap2构造函数中的最后一个参数为GmapOptions类型,这个类型包含以下4个属性。
l size:设置地图容器的大小。值类型为GSize类型。
l mapTypes:设置GMapType数组,默认情况下,Google Maps地图类型为G_DEFAULT_ MAP_TYPES。
l draggableCursor:当地图设置为可以拖动时,地图上显示拖动图标。值类型为String类型。
l draggingCursor:当地图移动时,地图上显示的拖动图标。
下面是一段完整的建立GMap对象的代码,包括HTML和JavaScript脚本:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps Sample</title>
<script src="http://ditu.google.com/maps?file=api&v=2&key=abcdefgh "
type="text/javascript"></script>
<script type="text/javascript">
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(32.5500, 118.5032), 14);
}
}
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>
这是一段非常简单的GMap2类的代码,目的是创建一个Google Maps地图窗口。该窗口在HTML页面的名称为“map”,长度为500像素点、宽度为300像素点,并且将中心点定位在东经118.5032°、北纬32.5500°的位置。
3.GMap2方法
GMap2方法有以下几种。
l enableDragging():设置地图可以被拖动。
l disableDragging():禁止地图被拖动。
l draggingEnabled():返回地图是否能够被拖动的布尔值。如果能够拖动,返回“真”;否则返回“假”。
l enableInfoWindow():设置地图信息窗口可以弹出。
l disableInfoWindow():禁止地图信息窗口弹出。
l infoWindowEnabled():返回地图信息窗口是否能够被弹出的布尔值。如果能够弹出,返回“真”;否则返回“假”。这个方法通常作为检验之用。
l enableDoubleClickZoom():设置可以双击缩放地图,左键双击为放大,右键双击为缩小(默认)。
JavaScript脚本实例如下:
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(43.92, -71.385), 10);
map.enableDoubleClickZoom();
}
}
l disableDoubleClickZoom():禁止双击缩放地图,Google Earth 默认为禁止双击缩放。例子代码请参看上面的enableDoubleClickZoom()的脚本实例。
l doubleClickZoomEnabled():返回地图是否可以双击缩放的布尔值。如果能够双击缩放,返回“真”;否则返回“假”。例子代码如下:
……
if (map.doubleClickZoomEnabled())
{
alert('可以双击');
}
l enableContinuousZoom():设置地图可以连续平滑地缩放。
l disableContinuousZoom():禁止地图连续平滑地缩放。
l continuousZoomEnabled():返回地图是否可以连续平滑地缩放的布尔值。如果能够连续平滑地缩放,返回“真”;否则返回“假”。
l enableScrollWheelZoom():设置地图可以由鼠标滚轮控制缩放。
为了便于用户操作,通常把双击缩放和鼠标滚轮缩放都开放。这不失为一个好方法,例如下面的JavaScript代码:
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(43.92, -71.385), 10);
map.enableDoubleClickZoom();
map.enableScrollWheelZoom();
}
}
l disableScrollSheelZoom():禁止由鼠标滚轮控制地图缩放。
l scrollWheelZoomEnabled():返回地图缩放是否可以由鼠标滚轮控制。如果能够由鼠标滚轮控制缩放,返回“真”;否则返回“假”。
4.GMap2控件方法
这里所谓的“控件”就是指在Google Maps上显示,可以控制地图的一些按钮和拖动条,例如比例尺拖动条、方向按钮等。
GMap2的控件方法一共有3个,分别是添加控件(addControl)、删除控件(removeControl)和获得地图容器(网页上的DOM元素,原本对象构建函数的参数)的名称getContainer。
1)addControl(control, position):按照给定的位置(Position)添加一个控件
所有的这些Google Maps控件都继承自Gcontrol类,并实现Gcontrol接口,Google Maps提供了8种控件,分别是:缩放平移按钮控件GSmallMapControl()、缩放平移按钮及滑块控件GLargeMapControl()、缩放按钮控件GSmallZoomControl()、地图比例尺控件Gscale Control()、地图类型控件GMapTypeControl()、下拉菜单式地图类型控件GmenuMap TypeControl()、嵌套的地图类型控件GHierarchicalMapTypeControl()、鹰眼控件GOverviewMapControl()。关于地图控件请参见后面Gcontrol小节的讲解。
下面这段addControl代码反映了其使用方法:
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(new GLargeMapControl());
map.addControl(new GScaleControl());
map.setCenter(new GLatLng(43.92, -71.385), 10);
}
}
如上面的JavaScript代码,在地图上添加一个比例尺控件和一个包括方向键和缩放条的“大”控件,所谓“大”控件如图4-6所示。
注意 |
添加“大”控件的时候,如果地图的高度设置太小,“大”控件往往容易超出地图边框。根据以往的常规经验,一般地图的高度至少设置为280px(像素)以上,才能将“大”控件完全包含在地图框以内,否则会出现如图4-6所示的情况。 |
图4-6 控件
2)removeControl(control):删除一个控件
这里传入的是控件对象本身。
3)getContainer():取得地图的容器
一般而言,地图的容器就是在网页上的GMap2对象得以创建的DOM元素Div。在本章代码中,所有的地图容器都是Div,名称为“map1”。下面这段代码恰好可以说明:
……
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
//创建的基础容器是名为map1的Div元素
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var a = map.getContainer();
alert(a.id);
}
}
……
<body>
<div id="map1" style="width: 300px; height: 200px"></div>
</body>
以上的代码中构造函数采用的父容器为名为“map1”的Div的DOM元素,执行后对照图4-7和GMap构造代码,getContainer函数获得了GMap对象——map的名称是“map1”。
图4-7 父容器
5.GMap2地图类型方法
所谓地图类型(GmapType)就是指不同种类的地图。例如地球卫星图像地图、着色底图地图、月球表面阴影地图、火星表面阴影地图等。这些不同类型的地图都具有投影,例如墨卡托投影。在后面的GmapType小节中会重点讲述。
GMap2地图类型方法一共有5种,分别是获取地图类型数组方法getMapTypes、设置地图类型方法setMapType、得到当前地图类型方法getCurrentMapType、新增地图类型方法addMapType、删除地图类型方法removeMapType。下面分别对这5种方法进行介绍。
1)getMapTypes()
getMapTypes()为返回一个地图类型的数组,反映了当前地图的所有地图类型。参见下面的JavaScript实例代码:
var map;
function setupMap()
{
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var a = map.getMapTypes();
var mname = '';
for (var i=0;i<a.length-1;i++)
{
//a是当前地图类型MapType的数组,通过getName方法获得地图类型名称
mname = a[i].getName() + ',' + mname;
}
alert(mname);
}
}
如图4-8所示,地图中有两个地图类型,一个名为“Satellite”,另一个名为“Map”,而弹出的提示框中也明确显示了。
图4-8 地图类型
2)getCurrentMapType()
getCurrentMapType()为得到当前的地图类型。注意得到的是地图类型GMapType对象,而不是对象名称。
JavaScript脚本实例代码如下:
……
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
//得到当前的地图类型
var a = map.getCurrentMapType();
var mname = a.getName();
alert(mname);
}
}
如图4-9所示,上面的代码很简单,当前地图的类型名为“Map”。
图4-9 地图类型
3)setMapType(type)
setMapType(type)为设置地图的类型。
注意 |
这些地图类型必须是已知的地图类型,包括Google Maps API最新版中的18种地图类型,还包括用户自定义的类型,但必须在此函数前定义。下同。 |
4)addMapType(type)
addMapType(type)为往当前地图上添加一个地图类型。注意点同上。
以下是一个完整的HTML页面代码,包括JavaScript脚本:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="content-script-type" content="text/javascript" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<title>Google Maps JavaScript API</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefgh"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
var map = null;
var tmpMaptype = null;
var s=""
function startup()
{
//创建一个地图
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(39.56457,-74.56456), 13);
var myImgURL = function(a, b){
s = 'http://127.0.0.1/test/tilt.png'; //指明了瓦片图的位置
return s;
};
var tmplay = new GTileLayer(new GCopyrightCollection(''),1,10);
tmplay.getTileUrl = myImgURL;
//创建新的地图类型
tmpMaptype = new GMapType([tmplay],
G_SATELLITE_MAP.getProjection(),
'test',
{errorMessage:'picture can not be loaded'});
//设置新地图类型的copyright信息
tmpMaptype.getCopyright = function(a,b,c)
{
return "tmpMaptype";
}
map.addMapType(tmpMaptype);
map.addControl(new GMapTypeControl());
//添加地图类型
var targetSource = map.addMapType;
}
//]]>
</script>
</head>
<body onload="startup();">
<div id="map" style="width:360px;height:170px"></div>
<div id="msg"></div>
</body>
</html>
代码中新增了名为“test”的地图类型,并且地图类型的copyright的显示文字为“tmpMaptype”,而test类型的瓦片图被设置为http://127.0.0.1/test/tilt.png的一张图。仅仅对这一张图片进行瓦片式的拼图,形成完整的一幅地图,如图4-10所示。
注意 |
在现实的应用中,瓦片图需要正常地编排,编排方式要和Google Maps保持一致,而这里只是个示例,所以仅仅是一张图片。 |
图4-10 瓦片
如图4-11所示,地图的右上角有4个地图类型按钮,分别表示着色地图(Map)、卫星地图(Satellite)、叠加地图(Hybrid)和自定义的地图类型(test)。
可以看出新的地图类型为“test”,单击【test】地图类型按钮,地图加载本地图形,拼接成相同图形的瓦片层(因为只有一张来自http://127.0.0.1/test/tilt.png的图片而已),如图4-12所示。
|




图4-11 地图类型控件 图4-12 加载瓦片图类型
5)removeMapType(type)
removeMapType(type)为从当前地图上删除一个地图类型。
JavaScript脚本实例代码如下:
……
var tmpMaptype = null;
//创建一个新的地图类型“test”
tmpMaptype = new GMapType([tmplay],
G_SATELLITE_MAP.getProjection(),
'test',
{errorMessage:'picture can not be loaded'});
……
function removeMap()
{
map.removeMapType(tmpMaptype);
}
对比图4-13和图4-14,【RemoveTest】按钮的作用是去除名为“test”的地图类型。
单击【Remove】按钮后,图4-14中地图的右上角已经去除了【test】地图类型按钮。
图4-13 加载类型 图4-14 删除类型
6.GMap2地图状态方法
Google Map API提供了获取地图当前缩放比例、地图中心点坐标、地图边框脚点经纬度等状态地图的方法,也提供了获取地图对象本身状态的方法。例如地图对象在屏幕上的大小(单位为像素),判断地图对象是否加载等方法。
下面逐一讲解。
1)isLoaded()
在创建GMap2对象的时候曾经讲解过,当地图创建并定义了中心点之后,才被认为已经加载返回true,否则返回false。
JavaScript脚本实例代码如下:
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
var L1 = map.isLoaded(); //此时地图还没有定义中心点,所以返回false
map.setCenter(new GLatLng(43.92, -71.385), 14);
var L2 = map.isLoaded(); //此时返回true
alert(L1 + ','+ L2);
}
}
请读者注意对比JavaScript代码中的前后位置与返回结果之间的关系。如图4-15所示,第一个“false”是没有设置地图中心点的时候返回的值,第二个“true”则是设置了地图中心点之后返回的值,表示GMap对象已经被加载了。
图4-15 地图状态
2)getCenter()
getCenter()为得到地图的中心点位,返回GLatLng类型的值。
这里的中心点位置不一定是setCenter()设置的位置,如果地图已经被用户移动了,则表示当前地图框中心点对应的实际地点的地理坐标。
JavaScript脚本实例代码如下:
……
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var mc = map.getCenter();
var mclat = mc.lat();
var mclng = mc.lng();
alert('( '+ mclat + ' , '+ mclng + ' )');
}
}
上述代码执行后的效果如图4-16所示。
注意 |
图4-16中的返回值与setCenter()设置的中心点位置经纬度坐标一样,因为是在地图没有被用户移动或缩放的情况下执行的代码。 |
图4-16 地图中心点
3)getBounds()
getBounds()为得到地图视场的地理坐标方框,返回值为GlatLngBounds对象。
JavaScript脚本实例代码如下:
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var mc = map.getBounds();
var mlat = mc.getCenter().lat();
var mlng = mc.getCenter().lng();
alert(mlat + ' , ' + mlng);
}
}
上述代码执行后的效果如图4-17所示。
图4-17 地图边界经纬度
说明 |
getBounds()的返回值是GlatLngBounds对象,表示一个矩形框,这个矩形框表示在实地抽象出的一个方框,而并非屏幕上的地图对象所在的Div边缘。 |
第7、8两行是获取这个边框的中心点位置,效果如图4-17所示。
4)getBoundsZoomLevel(bounds)
getBoundsZoomLevel(bounds)为取得给定范围的地图的缩放级别,返回值为整数。
例如下面的JavaScript脚本代码:
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var mc = map.getBounds();
var southWest = mc.getSouthWest();
var northEast = mc.getNorthEast();
var lngDelta = (northEast.lng() - southWest.lng()) / 4;
var latDelta = (northEast.lat() - southWest.lat()) / 4;
//设置一个地图方框,给出地图的范围
var rectBounds = new GLatLngBounds(
new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
//获取该范围内的缩放级别
var mbl = getBoundsZoomLevel(rectBounds);
alert(mbl);
}
}
上面的代码中首先设置了地图的中心点,然后通过getBounds()获取了当前地图的范围边框,计算出东西两侧的经度差值、南北的纬度差值,再将差值四等分之后,赋值给了lngDelta和latDelta,然后创建了一个新的地图范围边框“rectBounds”。这个新边框比当前地图边框大了1/4圈。最后通过getBoundsZoomLevel()将新边框指定给当前地图,算出当前地图的缩放比例mbl。
注意 |
因为地球的参考椭球的表面是曲面而非平面,所以在实际应用中经纬度的差值与平面距离的差值并不一样。特别是在大范围的区域,用上述方法将地图方位放大1/4圈是不可取的,在此代码中的方法只是做示意之用。 |
5)getSize()
getSize()为返回当前地图的视场尺寸,单位为像素(pixel)。
6)getZoom()
getZoom()为返回当前地图的缩放级别值。
例如下面的JavaScript脚本代码:
……
var map;
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(43.92, -71.385), 14);
var mz = map.getZoom();
alert(mz);
}
}
上述代码很简单,执行后的效果如图4-18所示。
7.GMap2改变地图状态
了解了地图状态之后,还需要进一步了解Google Maps是如何改变地图状态的。GMap2拥有10个改变地图对象状态的方法,下面分别讲解。
l checkResize():当地图容器尺寸发生变化后要调用此方法。
l panBy(distance):根据输入的移动距离移动到另一位置(该距离为屏幕像素单位的距离)。在下面讲述的panTo方法中,该方法与panBy的区别在于参数和运行方式。panTo是给定了一个GlatLng对象的经纬度,而panBy的参数是Gsize对象,依距离平移,Gsize对象中指定了经纬度坐标的差值。
Gsize对象的详细描述请参看后文。
l panDirection(dx, dy):以地图视场宽度的一半为距离移动。+1是向右下移动,-1是向左上移动,如图4-19所示。
图4-19 地图移动方向
例如下面的JavaScript脚本例子:
var map;
……
function setupMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.setCenter(new GLatLng(39.92, -74.385), 10);
}
}
function movemap()
{
map.panDirection(1,-1);
}
以上的例子是向右上方移动的。
l panTo(center):改变地图中心点到另一个位置。panTo的参数是GlatLng对象,不能直接使用经纬度。panTo与setCenter的最大区别就是比setCenter少一个缩放级别参数。panTo相当于无缩放的平移,setCenter相当于同时可缩放、可平移。另外,setCenter有panTo没有的初始化GMap对象的功能。
例如下面的JavaScript脚本例子:
……
function movemap()
{
var nc= new GLatLng(40.21, -74.315);
map.panTo(nc);
}
l returnToSavedPosition():重新调用由savePosition()存储的位置数据。
l savePosition():将地图的位置和当前的缩放级别保存下来,以后可以使用returnTo SavedPosition()重新调用。
l setCenter(center,zoom?,type?):根据输入的中心经纬度、缩放级别、地图类型设置地图的视场中心点。需要注意的是,该方法必须在地图创建好之后的下一步调用,如果调用其他方法则报错。
l setZoom(level):设置地图的缩放级别。
l zoomIn():放大一个缩放步长。每次缩放的一个步长即将缩放级别增减1,zoomIn与下面的zoomOut方法一样。
l zoomOut():缩小一个缩放步长。缩小一个级别,同上。
8.GMap2图层方法
GMap2对象提供了4种图层操作的方法,分别是新增、删除、清除所有图层和返回地图的Pane对象(创建基础Div对象),下面分别介绍。
l addOverlay(overlay):添加一个图层,该图层不一定是某种特定的Google Maps定义好的图层,只要是GOverLay类型的元素都可以,触发addOverlay事件。
l clearOverlays():清除所有图层,触发clearOverlays事件。
l getPane(pane):返回地图上的长方形区域Div对象,这种Div对象可以通过GOver- lay .initialize()创建。
l removeOverlay(overlay):去除一个图层,触发removeOverlay事件。
9.GMap2信息窗口方法
Google Maps吸引用户的地方,除了精准的卫星影像图之外,还有就是地标。地标的信息一般需要通过信息窗口来展示,这些信息窗口不但能够显示文字,还能够显示HTML元素,以网页的形式展现文字、图片等数据。另外信息窗口还可以为GMap对象提供9种操作信息窗口的方法。
这9种方法中,所有的options参数都是GinfoWindowOptions类对象,该类前一版本的API提供了7个属性,而当前的版本又增加了3个属性,一共10个属性。有关GinfoWindow Options类的详细介绍,请参见本章后面的内容。
下面逐一讲解这9种信息窗口方法。
l openInfoWindow(point,node,options):在给定的点位(Point)打开信息窗口。用户可以往信息窗口中添加某些DOM元素,比如:
map.openInfoWindow(map.getCenter(),document.createTextNode("Hello world~"));
l openInfoWindowHtml(point,html,options):在给定的点位(Point)打开信息窗口。用户可以往信息窗口中添加某些HTML元素,比如:
map.openInfoWindowHtml (map.getCenter(),"Text Html one</b>Text Html two</b>");
l openInfoWindowTabs(point,tabArray,options):在给定的点位(Point)打开标签信息窗口。用户可以往信息窗口中添加某些DOM元素。
l openInfoWindowTabsHtml(point,tabs,options):在给定的点位(Point)打开标签信息窗口。用户可以往信息窗口中添加某些HTML元素。Options是GInfoWindowOptions选项。
l showMapBlowup(point,options):在给定的点位(Point)打开一个信息窗口,窗口中包含该点周围的视场图片。类似于鹰眼功能,不过信息窗口中的图形与当前的地图位置,以及缩放比例相同,而没有鹰眼那样的全幅地图。而且信息窗口中的地图类型为两种,分别是着色底图地图【Map】按钮和卫星图像地图【Sat】按钮。
JavaScript脚本如下:
GEvent.addListener(markobj, "mouseover", function() {
markobj.showMapBlowup(new GLatLng(32.5500,-118.5032));
});
执行的效果如图4-20所示。
图4-20 给定点位周围的视场
l updateInfoWindow(tabs,update):更新信息窗口。
l updateCurrentTab(modifier,update):更新当前的标签窗口。
l closeInfoWindow():关闭信息窗口。
l getInfoWindow():取得信息窗口对象,如果地图上没有信息窗口,则调用该方法时会创建一个新信息窗口,但不会显示出来。
因为这9种方法的调用都一样,在此给出关于调用openInfoWindowHtml()方法的源代码,读者可以此类推:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps Sample</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=true_or_false&key=abcdefg" type="text/javascript"></script>
<script type="text/javascript">
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(32.5500, -118.5032), 14);
map.addControl(new GLargeMapControl());
}
var markobj = new GMarker(new GLatLng(32.5500,-118.5032),{draggable: true});
GEvent.addListener(markobj, "mouseover", function() {
markobj.openInfoWindowHtml("Hello world~ ");
});
map.addOverlay(markobj);
}
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>
上面的代码设置了一个监听(Google Maps事件监听器,后文中会详细讲述),设置为当鼠标移动到地标点之上时触发,地标Gmarker对象“markobj”调用了openInfoWindowHtml()方法,显示一段文字:“Hello world~”,执行后的效果如图4-21所示。
图4-21 “Hello world”信息窗口
在前面提及的诸如openInfoWindowHtml()、openInfoWindowTabs()等方法中需要用到的参数选项,其中的参数类型就是GInfoWindowOptions类型,该参数定义了信息窗口的状态,这个类型没有构造函数。
GInfoWindowOptions方法介绍如下。
l selectedTab:根据输入值确定选择的信息标签框,序号是从0开始的。
l maxWidth:定义了信息窗口的宽度,单位是像素值。
l noCloseOnClick:定义了在地图上单击一下之后是否关闭信息窗口。默认值是false,表示关闭;如果设置为true,表示当在地图其他地方单击的时候不关闭信息窗口。
l onOpenFn:定义了一个回调函数入口,当打开信息窗口并且其中内容都出现之后,调用该函数。
l onCloseFn:定义了一个回调函数入口,当信息窗口关闭之后调用该函数。
l zoomLevel:设置了信息窗口中放大地图的缩放比例,用于设置showMapBlowup()方法。
l mapType:设置了信息窗口中放大地图的类型,用于设置showMapBlowup()方法。
l maxContent:信息窗口最大化时显示的内容,可以是HTML DOM元素。
l maxTitle:信息窗口最大化时显示的标题内容,可以是纯文本信息,也可以是HTML DOM元素。
l pixelOffset:这个方法的返回值是GSize类型(该类型在本章4.3.6节会有详细的讲解),该方法表示信息窗口移动的距离,单位是像素。
4.3.4 GControl
Gcontrol用来定义地图上的控件,如切换卫星图片、矢量底图地图的按钮,再如地图上控制方向和缩放级别的拖动条等,这些都是GControl对象。
Google Maps在上一版的Gcontrol中提供了6种不同的控件,最新版的API中提供了8种控件,分别介绍如下。
1.var newGontrol = new GSmallMapControl();
这是创建一个简单的包括方向键和缩放按钮的GControl控件。
GSmallMapControl代码实例如下。
<script type="text/javascript">
//创建简单控件对象
var newGontrol = new GSmallMapControl();
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(39.92, 116.385), 15);
//加载简单控件对象
map.addControl(newGontrol);
}
}
</script>
代码执行后,创建的GSmallMapControl效果如图4-22所示。
图4-22 小控件
2.var newGontrol = new GLargeMapControl();
这是创建一个完整的方向键和缩放拖动条的GControl控件。
类似于上面的代码,GLargeMapControl的代码实例如下:
……
<script type="text/javascript">
//创建完整控件对象
var newGontrol = new GLargeMapControl();
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(39.92, 116.385), 15);
//加载完整控件对象到地图
map.addControl(newGontrol);
}
}
</script>
……
代码执行后,创建的GLargeMapControl的效果如图4-23所示。
图4-23 大控件
3.var newGontrol = new GSmallZoomControl();
这是创建一个只包含缩放按钮的GControl控件。
具体代码请参照以上两个构造函数的代码段落,只需把构造对象的那行代码换成目前的构造函数即可。代码执行后的效果如图4-24所示。
4.var newGontrol = new GScaleControl();
这是一个创建地图比例尺的控件。
具体代码请参照以上构造函数的代码段落,只需把构造对象的那行代码换成目前的构造函数即可。
代码执行后的效果如图4-25所示。
图4-24 小按钮 图4-25 比例尺
5.var newGontrol = new GMapTypeControl();
这是一个创建可切换地图的控件。
具体代码请参照以上构造函数的代码段落,只需把构造对象的那行代码换成目前的构造函数即可。
代码执行后的效果如图4-26所示。
图4-26 地图类型
6.var newGontrol = new GOverviewMapControl();
这是一个创建地图的鹰眼图(一种可以大致反映当前地图窗口观察范围的缩略图)的控件。
具体代码请参照以上构造函数的代码段落,只需把构造对象的那行代码换成目前的构造函数即可。
代码执行后的效果如图4-27所示。
图4-27 鹰眼
7.var newGontrol = new GMenuMapTypeControl ();
创建一种下拉式地图图层控件新一版本的Google Maps API支持“图层”的概念,不过所有的图层需要具备相同的投影,可参见(8)中的介绍。默认下拉选项有3种,分别是着色底图地图、卫星影像地图和合成叠加地图,如图4-28所示。
图4-28 下拉图层控件
8.var newControl = new GhierarchicalMapTypeControl();
创建下拉复选框式的图层列表。与上面(7)中介绍的GmenuMapTypeControl方法类似,都是创建自选的图层列表。新一版本的Google Maps API支持“图层”的概念,不过所有的图层需要具备相同的投影。
在使用该方法时需注意,之前的GMap2构造函数中,需要将所有的子图层包括进去,如下面的代码:
map = new GMap2(document.getElementById("map"),
{mapTypes:[G_MARS_ELEVATION_MAP,G_PHYSICAL_MAP,G_SATELLITE_MAP]});
最终的效果如图4-29所示。
图4-29 下拉复选框式的图层列表
4.3.5 确定点位的基本类型
有几个类型是构建GMap地图对象、设置和操作要素、地标对象的基础。例如GLatLng、GPoint等。读者应该在掌握了这些API类型之后,再去了解其他的类型,这是一个比较正常的学习顺序。
1.地理经纬度坐标GLatLng类型
GLatLng定义了点的地理位置,反映经纬度坐标值。请注意区别于GPoint(有关GPoint请参见本节的第2个问题),通过字面理解GLatLng指代的是地理经纬度。
1)GLatLng构造函数
GlatLng构造函数如下:
var newLatLng = new GLatLng(
lat: Float,
lng: Float,
unbounded: Bool);
GLatLng构造函数参数如表4-3所示。
表4-3 GLatLng构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
lat |
是 |
Float |
纬度 |
lng |
是 |
Float |
经度 |
unbounded |
可选 |
Bool |
是否有边界 |
2)GLatLng方法
GLatLng方法介绍如下。
l lat():返回纬度,数值在-90~+90之间,浮点型。
l lng():返回经度,数值在-180~+180之间,浮点型。
l latRadians():以弧度的形式返回纬度值,数值在-π/2~+π/2之间,浮点型。
l lngRadians():以弧度的形式返回经度值,数值在-π~+π之间,浮点型。
l distanceFrom(otherLatlng):返回从一个点到另一个点的长度,以“米”为单位。
l toUrlValue():以URL加参数的形式返回,为字符串的形式,该URL可以被Google Maps执行定位。
l toUrlValue(precision):类似于toUrlValue()方法,并且用户可以自定义精度(Precision)。以URL加参数的形式返回,为字符串的形式。
3)GLatLng属性
GLatLng属性介绍如下。
l X:经度,浮点型。
l Y:纬度,浮点型。
4)GLatLng代码实例
GLatLng的代码实例如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/ xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google JavaScript API</title>
<script src="http://ditu.google.com/maps?file=api&v=2&key= …… "
type="text/javascript"></script>
<script type="text/javascript">
var newGontrol = new GSmallMapControl();
var map = null;
//创建并初始化地图
function load() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(newGontrol);
//设置地图中心的方法中采用了GLatLng类型来创建经纬度对象
map.setCenter(new GLatLng(40.72, -74.00), 15);
}
}
function MovetoMap()
{
var i = 0.001;
var lng = 40.72 + i;
var lat = -74.00 + i;
window.setInterval(function() {
lng = lng + i;
lat = lat + i;
//移动地图的panto方法中也采用了GLatLng类型来创建经纬度对象
map.panTo(new GLatLng(lat,lng), 15);
}, 2000);
}
</script
</head>
<body onload="load()" onunload="GUnload()">
<div id="map1" style="width: 500px; height: 300px"></div>
<input id ="btn" type="button" value="开始移动" onClick="javascript:MovetoMap();" />
</body>
</html>
5)代码分析
本例子实现了一个自动移动地图的例子。当地图打开之后,每隔2秒地图就会向固定的方向自动移动,如此反复循环,这个例子很有用,例如在GIS项目应用中有一个车辆在地图上行进,当车辆进行到地图图框边缘时,一般无需用户去拖动地图,而是地图自行沿着车辆前景的方向拓展并移动,保持车辆始终在地图的视野范围内。
函数load()定义了一个GMap2对象实例,并且确定了地图加载后的中心点坐标;MovetoMap()函数定义了自动移动的逻辑,每次调用map.panTo自动移动到一个新的位置,就创建一个GLatLng对象,代表一个点位。
如上述对于GLatLng的定义,它是经纬度的点位。区别于GPoint,新建GLatLng对象的格式如上面的实例数据,应该为GLatLng(40.72纬度, -74.00经度)。
2.屏幕坐标的GPoint类型
上一个问题提到了GLatLng,指代的是地理坐标点位,而涉及屏幕坐标点位就要采用GPoint类型来描述。在初期的2.X版本之前,GPoint和GPolygon一样都表示地理上的某一个位置点,但是随着Google Maps功能的增多,人们发现应该区分地理点和屏幕点的不同,于是就出现了用来专门表示地理坐标经纬度信息的GLatLng类型,而GPoint则演变成了专门表示屏幕上点位的类型,所以GPoint的出现要早于GLatLng。
其元素类型为类(Class)。
点位的屏幕坐标,请注意区别于GLatLng在GPoint的坐标中,X的起点在最左端,Y的起点在最上端,如图4-30所示。
|
|

图4-30 Google Maps屏幕坐标
1)GPoint构造函数
GPoint构造函数如下:
var newPoint = new GPoint(
x: Float,
y: Float);
GPoint构造函数参数如表4-4所示。
表4-4 GPoint构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
x |
是 |
Float |
X坐标值 |
y |
是 |
Float |
Y坐标值 |
2)GPoint属性
GPoint属性如下。
l x:X坐标值,从最左端起,浮点型。
l y:Y坐标值,从最上端起,浮点型。
3)GPoint方法
GPoint方法如下。
l equals(other):判断和另一个点是否重合,重合返回true,否则返回false,布尔型。
l toString():返回GPoint坐标的字符串。
3)GPoint代码实例
GPoint的代码实例如下:
……
var iconTest = new GIcon();
iconTest.image = 'http://www.test.com/1.png';
iconTest.shadow = 'http://www.test.com/2.png';
iconTest.iconSize = new GSize(10, 20);
iconTest.shadowSize = new GSize(15, 20);
iconTest.iconAnchor = new GPoint(6, 20);
iconTest.infoWindowAnchor = new GPoint(5, 2);
……
以上代码的最后两行定义了GIcon对象iconTest的锚点与弹出的信息窗口锚点在屏幕上的位置。
4.3.6 定义方形区域
在项目应用中,常常会涉及到范围定义,一般为矩形范围的定义或者不规则多边形范围的定义。在ArcGIS等传统的GIS中,提供了多边形范围的定义与操作方法,但Google Maps中的多边形利用getBounds方法得到的仍旧是多边形的最大外围方框,而不是多边形边框坐标,所以方形区域的定义显得尤为重要。
Google Maps API提供了3种定义地图方形区域的类型,分别是定义方形区域大小的GSize类型、在屏幕上定义方形区域范围的GBounds类型和在实地以经纬度定义方形区域范围的GLatLngBounds类型。
1.屏幕上的方形区域GSize
其元素类型为类(Class)。
GSize定义了在地图屏幕区域上的方形区域,X轴方向的坐标差值是width,Y轴方向的坐标差值是height,均为像素值。
panBy方法的参数就是一个GSize类型的对象,这个对象有两个参数——width和height。Google在官网中不推荐用户修改GSize对象中的这两个值。
1)GSize构造函数
GSize构造函数如下:
new newSize = new GSize(
width: Float,
height: Float);
GSize构造函数参数如表4-5所示。
表4-5 GSize构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
width |
是 |
Float |
X轴方向的宽度 |
height |
是 |
Float |
Y轴方向的高度 |
2)GSize属性
width和height分别为X轴方向的差值和Y轴方向的差值。
l width:定义X轴方向的宽度,浮点型。
l height:定义Y轴方向的高度,浮点型。
3)GSize方法
GSize方法介绍如下。
l equals(other):判断和另一个方形区域是否重合,重合返回true;否则返回flase,布尔型。
l toString():返回GPoint坐标的字符串。
4)GSize代码实例
GSize的代码实例如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google JavaScript API </title>
<script src="http://maps.google.com/maps?file=api&v=2&key=abcdefgh"
type="text/javascript"></script>
<script type="text/javascript">
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.setCenter(new GLatLng(40.917, -74.397), 12);
var objIcon = new GIcon();
objIcon.image = "test.png";
objIcon.iconSize =new GSize(200,100);
objIcon.iconAnchor = new GPoint(6, 20);
var point = new GLatLng(40.917, -74.397);
map.addOverlay(new GMarker(point, objIcon));
}
}
function isequals()
{
var point = new GLatLng(40.917, -74.397);
if (objIcon.iconSize.equals(point) == true)
{
alert('yes');
}
else
{
alert('no');
}
}
</script>
</head>
<body onload="load();isequals();" onunload="GUnload()">
<div id="map" style="width: 500px; height: 300px"></div>
</body>
</html>
5)代码分析
本段代码是通过创建GIcon对象来加载图片的,而GIcon对象的大小由GSize决定。
代码中设定好了图片的尺寸:长度200像素、高度100像素。此时Google Maps会忽略原来图片的大小,转而采用设定好的大小展现。图片展现的位置以SetCenter函数定义好的中心点为准,代码执行后的效果如图4-31所示。
图4-31 加载图的大小设置
本例中的图片test.png大小并非长、宽为200像素和100像素,而通过GSize的设定,拉伸了图片的长宽比。
2.GScreenSize类
与GSize类似,通过宽度width与长度height来定义矩形区域的大小。与上一段GSize的区别在于GSize是通过脚点坐标来确定矩形区域的。
GScreenSize的构造函数如下:
var GScreenSizeObj = new GScreenSize(width:int,
height:int,
xunits:String,
yunits:String)
GScreenSize构造函数参数如表4-6所示。
表4-6 GScreenSize构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
width |
是 |
Float |
X轴方向的宽度 |
height |
是 |
Float |
Y轴方向的高度 |
xunits |
否 |
String |
X的单位(相对百分比或者像素) |
yunits |
否 |
String |
Y的单位(相对百分比或者像素) |
GScreenSize的属性与构造函数的参数相同,意义也相同,在此不再赘述。
3.地图上的矩形区域GBounds
GBounds是在地图屏幕上定义的方形区域,单位为像素。请注意区别于GLatLngBounds(地理经纬度单位)。
前一版本的GBounds,Google给出的定义是以像素表示地图上的方形区域,但是在构造函数中,给出的参数类型却是GLatLng型。自从Google Maps API新版本发布之后这个问题已经很明确了——GBounds的参数类型就是GPoint类型的对象数组,不过到目前为止,Google Maps API中还没有以GBounds类型为返回值的函数。
与之相对应的是GLatLngBounds,这个类与GBounds的区别在于GBounds的参数单位是像素,以地图屏幕为参照划定的矩形区域;而GLatLngBounds则是以实地为参考,以经纬度坐标为划定区域的。
1)GBounds构造函数
GBounds构造函数如下:
new newBound = new GBounds (
points: Array of GPoint);
GBounds构造函数参数如表4-7所示。
表4-7 GBounds构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
points |
是 |
Array of GLatLng |
点位的数组 |
采用JavaScript脚本可以创建数组,JavaScript的数组是解析型数组(即如果数组元素为空,则该元素实际是不占用内存的),JavaScript脚本可创建动态数组或者静态数组,创建动态数组的格式如下:
myArray = new Array();
创建静态数组的格式如下:
myArray = new Array([size]);
在Windows中,JavaScript脚本创建的数组下标以0开始,创建好动态数组之后,可以以下列形式赋值:
myArray[index] = x; (index表示下标编号,x表示任意数值)
了解了JavaScript如何创建数组之后,下面的代码则显示了GBounds对象创建的例子:
var pointsArr = new Array();
pointsArr[0]= new GPoint(50,50);
pointsArr[1] = new GPoint(50,150);
pointsArr[2] = new GPoint(150,150);
pointsArr[3] = new GPoint(150,50);
var boundobj = new GBounds(pointsArr);
2)GBounds属性
GBounds一共提供了4个属性,分别是左上角和右下角的X、Y笛卡儿坐标值,如图4-32所示。
图4-32 GBounds笛卡儿坐标系
l minX:方形区域最左边的X值,整型值。
l minY:方形区域最上边的Y值,整型值。
l maxX:方形区域最右边的X值,整型值。
l maxY:方形区域最下边的Y值,整型值。
关于属性的应用代码,请参看下文的“GBounds代码实例”。
3)GBounds方法
GBounds一共包含了8个方法,重叠类的有4个,分别是判断是否重合的equals方法、判断是否包含的containsBounds方法、containsPoint方法,以及延伸方形区域至重合的extend方法;点位类的有4个,分别是返回两个脚点坐标值字符串的toString ()方法、返回两个脚点坐标对象的min()和max()方法、返回中心点坐标值对象的mid方法。
l equals(otherGBoundobj):判断和另一个点是否重合,重合返回true;否则返回false,布尔型。
l toString():返回左上角和右下角坐标,以字符串的形式返回。
l mid():返回方形区域中心点坐标,这里为笛卡儿坐标系的像素坐标。返回值是GPoint。
l min()方法和max():分别返回矩形区域左上角和右下角坐标,这里为笛卡儿坐标系的像素坐标,返回值是GPoint。
l containsBounds(otherGBoundobj):如果包含参数中的另一个GBounds对象,返回true,反之返回false。
l containsPoint(GPointobj):如果包含参数中的一个点对象,返回true,反之返回false。这里“包含”的意思也包括压线,即方形区域的边与该点重叠。
l extend(GPointobj):如果方形区域不包含此点,那么放大该区域直至方形区域的边与该点重合。
4)GBounds代码实例
Gbounds的代码实例如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps Sample</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=true_or_false&key=abcdefg "
type="text/javascript"></script>
<script type="text/javascript">
//创建地图对象并初始化
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(32.5500, -118.5032), 14);
}
//创建GPoint数组,共包括4个子元素
var pointsArr = new Array();
pointsArr[0]= new GPoint(50,50);
pointsArr[1] = new GPoint(50,150);
pointsArr[2] = new GPoint(150,150);
pointsArr[3] = new GPoint(150,50);
//用数组来创建GBounds对象
var boundobj = new GBounds(pointsArr);
alert(boundobj.minX + ','
+ boundobj.maxX + ','
+ boundobj.maxY + ','
+ boundobj.minY );}
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width: 500px; height: 500px"></div>
</body>
</html>
5)代码分析
GBounds的参数points其实是GPoint类型的对象数组,JavaScript采用new Array()建立动态数组,一共4个GPoint对象,代表矩形的4个脚点,创建完毕后调用minX、maxX、maxY、minY属性来获取4个脚点的X/Y值(屏幕笛卡儿坐标)。
执行代码后的效果如图4-33所示。
图4-33 GBounds脚点坐标
4.地图上的方形区域GLatLngBounds
GLatLngBounds定义了一个方形的区域范围,范围的坐标为地理经纬度坐标。
前面提到了GBounds类型,该类型的参数是GPoint类型的对象数组,与屏幕位置和尺寸发生联系。而这里的GLatLngBounds则是以GLatLng为参数的,表示以实地经纬度坐标划定的方形区域。
1)GLatLngBounds构造函数
GLatLngBounds构造函数如下所示:
var newLatLngBounds = new GLatLngBounds(
sw: GLatlng,
ne: GLatlng);
GLatLngBounds构造函数参数如表4-8所示。
表4-8 GLatLngBounds构造函数参数
参 数 |
是 否 必 要 |
值 类 型 |
定 义 |
sw |
是 |
GLatlng |
Southwest的缩写,表示西南角 |
ne |
是 |
GLatlng |
Northeast的缩写,表示东北角 |
参看下列创建对象的JavaScript脚本代码:
……
rectBounds = new GLatLngBounds(
new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
……
2)GLatLngBounds方法
GLatLngBounds的方法比GBounds多了4个,其他的8个方法基本类似,而这4个特有的方法主要与地理性质有关联,分别是返回坐标系原点坐标的toSpan()方法、是否南北方向大到可包围南北极的isFullLat()方法、是否东西方向大到可包围地球一圈的isFullLng()方法,以及是否该方形区域为空的isEmpty ()方法。
l equals(otherLatlngBound):判断是否和另一个区域重合,该重合度有个阈值,小于这个值即认为重合,返回true;否则返回false,布尔值。
l contains(latlng):判读输入的经纬度是否在方形区域范围内。如果包含返回true,否则返回false,布尔值。
l intersects(otherLatLngBound):是否和其他方形区域有相交叠的部分。如果有交叠返回true;否则返回false,布尔值。
l containsBounds(otherLatLngBound):是否包含其他的方形区域。如果包含返回true;否则返回false,布尔值。
l extend(LatLng):根据输入的点位,让方形区域变大,直到包含这个点位为止,无返回值。
l getSouthWest():返回西南角的坐标点位,赋值类型为GLatLng。
l getNorthEast():返回东北角的坐标点位,赋值类型为GLatLng。
l toSpan():返回该GLatLngBounds参照坐标系的原点,返回值类型为GLatLng。
l isFullLat():如果该GLatLngBounds南北方向的范围大到可以包括南北极,则返回true;否则返回false,赋值类型为布尔值。
l isFullLng():如果该GLatLngBounds东西方向的范围大到可以绕地球一周,则返回true;否则返回false,赋值类型为布尔值。
l isEmpty():如果该GLatLngBounds为空,则返回true;否则返回false,赋值类型为布尔值。
l getCenter():返回该GLatLngBounds中心点点位,返回值类型为GLatLng。
3)代码实例
一个完整的GLatLngBounds实例代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312"/>
<title>Google JavaScript API </title>
<script src="http://maps.google.com/maps?file=api&v=2&key= …… "
type="text/javascript"></script>
<script type="text/javascript">
var rectBounds= null;
var map = null;
//建立地图并初始化
function load()
{
if (GBrowserIsCompatible())
{
map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.setCenter(new GLatLng(40.917, -74.397), 12);
var bounds = map.getBounds();
//同时确定地图的边框
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
//计算边框差值的1/4作为delta值
var lngDelta = (northEast.lng() - southWest.lng()) / 4;
var latDelta = (northEast.lat() - southWest.lat()) / 4;
//用delta值创建边框GLatLngBounds对象
rectBounds = new GLatLngBounds(
new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
//创建地图叠加层(关于叠加层详细讲解请参阅本章4.3.10小节)并加载
var gOverly = new GGroundOverlay("test.png",rectBounds);
map.addOverlay(gOverly);
}
}
//得到地图中心点位
function GetCenter()
{
if (rectBounds !== null)
{
var bc = rectBounds.getCenter();
alert(bc.lat() + ',' + bc.lng());
}
}
//判断新建矩形区域与当前地图可视边框是否有交叠
function isInterSect()
{
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngDelta = (northEast.lng() - southWest.lng()) / 8;
var latDelta = (northEast.lat() - southWest.lat()) / 8;
var tmprectBounds = new GLatLngBounds(
new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
if (rectBounds.intersects(tmprectBounds) == true)
{
alert('有交叠');
}
else
{
alert('无交叠');
}
}
//判断新建矩形区域是否为空
function IsEmpty()
{
if (rectBounds.isEmpty() == true)
{
alert('为空');
}
else
{
alert('非空');
}
}
//判断新建矩形区域与当前地图可视边框是否为包含关系
function isContainPt()
{
var pt = new GLatLng(40.917, -74.397);
if (rectBounds.contains(pt) == true)
{
alert('包含');
}
else
{
alert('不包含');
}
}
</script>
</head>
<body onload="load();" onunload="GUnload()">
<table>
<tr>
<td style="height: 145px">
<div id="map" style="width: 200px; height: 140px"></div>
</td>
<td style="height: 145px">
<table>
<tr>
<td style="width: 84px">
<input id="btnInterSect" value="是否交叠" type="button" onclick= "isInterSect();" style="width: 80px" />
</td>
</tr>
<tr>
<td style="width: 84px">
<input id="btnContainPt" value="是否包含点" type="button" onclick= "isContainPt();" style="width: 80px" />
</td>
</tr>
<tr>
<td style="width: 84px">
<input id="Button2" value="是否为空" type="button" onclick= "IsEmpty();" style="width: 80px" />
</td>
</tr>
<tr>
<td style="width: 84px">
<input id="Button1" value="获取中心" type="button" onclick= "GetCenter();" style="width: 80px" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
4)代码分析
上面的代码包含了页面HTML代码与JavaScript脚本,是一个完整的例子。本例一共设置了4个判断按钮:是否交叠按钮采用了intersects方法,是否为空用采用了isEmpty方法,是否包含采用了contains方法,获取中心点位经纬度来用了getCenter方法。
这里的代码很好理解,首先确定地图当前可视范围的地理边框坐标;然后计算delta值,通过加入delta值来新建GLatLngBounds矩形区域;最后逐一判断其与地图可视边框的关系。通过这个代码正好复习创建GLatLngBounds对象及它的方法。在此不多解释,读者可按照源代码自行实验,然后观察执行结果,效果如图4-34所示。
图4-34 交叠关系
4.3.7 Google Maps事件管理
事件(Event)在例如以JavaScript为代表的脚本语言中非常重要,而且Google Maps API官方指定的脚本就是JavaScript。JavaScript脚本语言是一个典型的事件驱动(Event-driven),通过捕获网页DOM元素上用户鼠标和键盘引发一系列动作。
在传统的观念中,C/S程序比B/S程序除了功能多之外,还有一个重要的区别就是程序对用户的动作反馈不同。不管是操作系统还是应用层软件,对事件的响应完善程度都决定了对异步处理的精确,并且决定了是否可以提供完美的用户体验。
Google Maps也提供了很好的事件响应、捕捉、管理的方法,在功能上主要分为事件对象和事件响应两类,下面分别介绍。
1.GEvent名称空间
这个名称空间(Namespace)包含很多注册的事件函数,用户可以将自定义的事件注册为GEvent名称空间,通过GEvent用户可以监视地图事件和自定义的事件。Google Maps一共定义了23个类型的默认事件,如表4-9所示。
表4-9 事件类型
序 号 |
事 件 名 称 |
定 义 |
1 |
addmaptype |
添加地图类型时触发此事件 |
2 |
addoverlay |
添加地图图层时触发此事件 |
3 |
clearoverlays |
清空所有图层时触发此事件 |
4 |
click |
单击时触发此事件 |
5 |
dblclick |
双击时触发此事件 |
6 |
drag |
拖动触发此事件 |
7 |
dragend |
拖动结束触发此事件 |
8 |
dragstart |
拖动开始触发此事件 |
9 |
infowindowbeforeclose |
信息窗口关闭之前触发此事件 |
10 |
infowindowclose |
信息窗口关闭,此事件发生在infowindowbeforeclose之前 |
11 |
infowindowopen |
信息窗口打开触发此事件 |
12 |
load |
地图加载,初始化完毕时触发此事件 |
13 |
maptypechanged |
地图类型改变(例如切换地图类型) |
14 |
mousemove |
地图上鼠标移动时触发此事件 |
15 |
mouseout |
鼠标移动到地图之外时触发此事件 |
16 |
mouseover |
鼠标移动到地图之内时触发此事件 |
17 |
move |
地图移动时触发此事件 |
18 |
moveend |
地图移动结束时触发此事件 |
19 |
movestart |
地图开始移动时触发此事件 |
20 |
removemaptype |
删除地图类型时触发此事件 |
21 |
removeoverlay |
删除地图图层时触发此事件 |
22 |
singlerightclick |
当右键单击时触发该事件 |
23 |
zoomend |
当地图缩放结束后 |
上表中列出了目前GMap2所支持的23种事件,所有的用户自定义事件都需要从以上事件中派生出来,即用户无法让Google Maps事件监听器在默认的情况下对以上这23种事件以外的事件作出响应。
但是对于事件驱动的JavaScript脚本,不能定义自定义事件来驱动GMap对象作出响应,那么很多应用将受限制。如果用户需要定义自己的事件名称,让GMap对象响应的话,Google Maps API提供了一个trigger方法可实现这一需求。
从事件驱动的层面来说,整个Google Maps所有的事件都是通过GEvent..trigger来响应的。
1)GEvent静态函数
这一版本的GEvent包含了11个方法,比前一版多了一个clearNode方法,其他方法均一样。其中addListener、addDomListener、bind、bindDom 4个方法有事件监听类型对象的返回值,其他均没有返回值。
Google Maps中所有的事件触发都通过触发器trigger,这个方法至关重要。
trigger(eventSource,event,.. [args]..)为监听程序触发器,args可作为执行函数的输入参数。
利用trigger,用户可以自定义事件,例如下面的JavaScript代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps Sample</title>
<script src="http://maps.google.com/maps?file=api&v=2&sensor=true_ or_false&key= …… "
type="text/javascript"></script>
<script type="text/javascript">
var mydiv;
var map;
function load()
{
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(32.5500, -118.5032), 14);
map.addControl(new GLargeMapControl());
mydiv = document.getElementById("testevent");
//添加对"testevent"DOM对象的监听
GEvent.addListener(mydiv,"eventTestName",function(){
alert('Event trigger is ok!');
});
}
}
</script>
</head>
<body onload="load()" onunload="GUnload()">
<table>
<tr>
<td>
<div id="map" style="width: 300px; height: 300px"></div>
</td>
<td>
<div id="testevent" style="width: 100px; height:300px;background:#ff0000" onclick="javascript:GEvent.trigger(mydiv,'eventTestName');"></div>
</td>
</tr>
</table>
</body>
</html>
这是一个完整的Google Maps事件代码实例,代码中涉及到绑定(注册)事件、事件触发器、添加事件监听的JavaScript脚本。
首先页面上定义了两个Div对象,id号分别是“map”和“testevent”,并且testevent为红色底色,在testevent的click事件中,触发了一个自定义的事件,事件名称为“eventTestName”。
而JavaScript脚本中通过load函数,创建地图对象之后,向GMap对象添加了一个事件监听器,被监听的对象正是mydiv(testevent在javascript中的名称),被监听事件名称为“eventTestName”。当此事件被触发后,执行弹出“Event trigger is ok!”这样的提示窗口,如图4-35所示。
图4-35 右边红色区域的单击事件
2)GMap2对象有两个添加监听的方法
l addListener(eventSource,event,handler):GEventListenerobj。
添加针对eventSource的事件监听,eventSource是地图要素对象,如GMarker对象等。当事件Event(事件类型请参看前面的事件表格)发生时执行handler(handler为Google API或自定义的函数)。
返回值为一个事件监听类型对象。
这个函数包括下面介绍的addDomListener方法的代码示例,可参看关于trigger的例子代码。
l addDomListener(eventDOMSource,event,handler): GEventListenerobj。
添加针对DOM对象eventDOMSource的事件监听,eventDOMSource是DOM对象,如网页上的Div对象。当事件Event(事件类型请参看前面的事件表格)发生时执行handler(handler为Google API或自定义的函数)。
返回值为一个事件监听类型对象。
3)Google Maps绑定事件的操作方法
l bind(eventSource,event,object,method) :GEventListenerobj。
这个过程相当于注册事件处理函数,用于将事件Event(事件类型请参看前面的事件表格)对象与自定义事件绑定,用以替代原来的处理函数,eventSource是地图要素对象。Object是执行method的对象。
返回值为一个事件监听类型对象。
l bindDom(eventDOMSource,event,object,method) :GEventListenerobj。
这个过程相当于注册事件处理函数,用于将事件Event(事件类型请参看前面的事件表格)对象与自定义事件绑定,用以替代原来的处理函数,eventDOMSource是DOM对象。Object是执行函数method的对象。
返回值为一个事件监听类型对象。
这个方法也很有用,实际项目应用中经常会遇到,具体用法请参看如下代码:
<script type="text/javascript">
function load() {
var mydiv;
var map;
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(32.5500, -118.5032), 14);
map.addControl(new GLargeMapControl());
mydiv = document.getElementById("testevent");
//绑定DOM对象的事件
GEvent.bindDom(mydiv,"click",map,function(){
alert("binddom is ok!");
});
}
}
</script>
……
<div id="testevent" style="width: 100px; height:300px;background:#ff0000" ></div>
……
在上面的代码中,首先页面上定义了两个Div对象,id号分别是“map”和“testevent”,并且testevent为红色底色(JavaScript代码中名称为mydiv)。在脚本代码端GEvent.bindDom方法将mydiv的click事件与GMap对象map绑定在一起,并且设置了事件被触发后,执行弹出“binddom is ok!”的提示窗口,如图4-36所示。
图4-36 绑定DOM对象事件
l removeListener(handle)。
RemoveListener(handle)为删除某个监听执行程序的注册。
4)回调函数
l callback(object, method):通过method的回调。
l callbackArgs(object,method,.. [args]..):通过method的回调,args可作为回调函数的输入参数。
5)清除监听器
l clearInstanceListeners(eventSource):清除对于eventSource所有的事件监听器。
l clearListeners(eventSource, event):清除对于eventSource的event事件的监听。
l clearNode(node):node下面所有的子节点递归调用clearInstanceListeners方法。
6)GEvent事件
l ClearListeners:当清空事件监听的时候触发此事件。
Gevent的代码实例如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google JavaScript API</title>
<script src="http://ditu.google.com/maps?file=api&v=2&key=abcdefg"
type="text/javascript"></script>
<script type="text/javascript">
var newGontrol = new GSmallMapControl();
var map = null;
//创建并初始化地图
function load() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(newGontrol);
map.setCenter(new GLatLng(39.92, 116.385), 15);
//监听单击事件,并且将地图在单击处放大
GEvent.addListener(map, "click", function(){
alert('click');
GEvent.callback(map,map.zoomIn());
});
}
}
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map1" style="width: 500px; height: 300px"></div>
</body>
</html>
在上面的代码中,利用GEvent.addListener的方法,注册了对于map的click事件的监听。运行代码后,单击地图,网页会弹出一个包含“click”的信息框,单击“确定”按钮后地图被放大,如图4-37所示。
图4-37 事件监听
2.事件监听器
GEventListener元素类型:类(Class)。
这个类是由GEvent.. addListener()或者GEvent.addDomListener()执行的时候产生的,本身并没有构造函数,并且这个类也没有方法函数。
JavaScript脚本实例代码如下:
……
function setupMap()
{
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map1"));
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(31.7,131.2), 10);
}
var markobj = new GMarker(new GLatLng(31.7,131.2),{draggable: true});
//添加监听,并且在回调方法中打开信息窗口,显示“Hello world~”
GEvent.addListener(markobj, "mouseover", function() {
markobj.openInfoWindowHtml("Hello world~ ");
});
map.addOverlay(markobj);
}
以上的代码中首先创建了一个GMarker地标对象,然后用addListener方法对地标对象添加mouseover监听。若该事件被触发,则执行openInfoWindowHtml函数,显示“Hello world~”信息框。
关于openInfoWindowHtml方法的详细介绍,请参见下面的介绍。
4.3.8 地标类操作
地标是Google 地图区别于其他Web地图的一个重要方面,Google Maps API中提供了4种类型来定义和操作地标,分别是GMarker类、GmarkerOptions类、GMarkerManager 类、GMarkerManagerOptions 类。
GMarker类型为地标对象的所属类型,包括两个构造函数,其中的参数就是Gmarker Options类型的对象;新版本的API不推荐使用GmarkerManger来操作地标,而推荐用户采用开源的MarkerManager程序。但是这一版本的API仍然保留了GmarkerManger类型,其构造函数中阐述类型为GmarkerManagerOptions类型的对象。
注意 |
MarkerManager程序可以在http://gmaps-utility-library-dev.googlecode.com/ svn/tags/markermanager/中找到。 |
1.地标类GMarker
元素类型:类(Class)。
该类为Google Maps的标记类,使用GMap2.addOverlay()添加到地图上。GMarker在地图上创建之后,单击可以弹出信息窗口。
1)GMarker构造函数
GMarker构造函数在2.50版之前有两个,而之后的API不推荐使用第一种构造方法,因为前者只能创建类型简单的“静态”地标对象,若用户想创建可弹起、可拖动的“动态”地标对象(Google Maps最新版的API中提供了10种不同种类的动态地标,请参见GMarkerOptions问题的讲解),则需要使用后面的第二种构造方法。
这里对第二种构造方法进行深入介绍。
第一种代码为:
var markerObj = new GMarker(
point: GPoint,
icon: Icon,
isInert: Bool);