开心人生

用今天的努力----实现我所向往的明天

导航

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&amp;v=2&amp;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&amp;v=2&amp;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 缩放级别上述代码很简单,执行后的效果如图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&amp;v=2&amp;sensor=true_or_false&amp;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&amp;v=2&amp;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所示。

0

X

图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&amp;v=2&amp;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个属性,分别是左上角和右下角的XY笛卡儿坐标值,如图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&amp;v=2&amp;sensor=true_or_false&amp;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&amp;v=2&amp;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&amp;v=2&amp;sensor=true_ or_false&amp;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&amp;v=2&amp;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);

posted on 2010-07-20 21:24  hai  阅读(2063)  评论(0)    收藏  举报