开心人生

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

导航

Google Maps API详解--02

第一种GMarker构造函数参数如表4-10所示。

表4-10 GMarker构造函数参数

参    数

是 否 必 要

值 类 型

定    义

point

GPoint

GPoint点位,屏幕像素坐标

icon

可选

Icon

图标的风格

isInert

可选

Bool

是否为插入(Insert)方式

第二种代码为:

var markerObj = new GMarker(

     point: GLatLng,

Option: GMarkerOptions);

第二种GMarker构造函数参数如表4-11所示。

表4-11 GMarker构造函数参数

参    数

是 否 必 要

值 类 型

定    义

point

GLatLng

GLatLng点位,地理经纬度坐标

Option

可选

GMarkerOptions

标记的选项

JavaScript脚本代码示例如下:

……

var markobj = new GMarker(new GLatLng(31.7,131.2),{draggable: true});

……

2)GMarker方法

① openInfoWindow(content,options)

打开信息窗口,content代表信息窗口内容,可用DOM元素封装后填入;options表示GInfoWindowOptions选项。

在通常情况下,openInfoWindow比较常用,下面给出一个完整的网页调用的例子,并给出执行的结果。JavaScript脚本代码如下:

<!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=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 map;

     function setupMap()

     {

          map = new GMap2(document.getElementById("map1"));

          map.addControl(new GLargeMapControl());

          map.setCenter(new GLatLng(31.7,131.2), 10);

          //创建GMarker对象

          var markobj = new GMarker(new GLatLng(31.7,131.2),{draggable: true});

          //在监听器的回调函数中,打开一个地标的信息窗口,在信息窗口中填写HTML语言

          GEvent.addListener(markobj, "click", function() {

                  markobj.openInfoWindowHtml( '地标名:' +

                  markobj.getTitle() + '<br />' +

                    '纬度/经度: ' + markobj.getPoint().lat() +

                    ', ' + markobj.getPoint().lng());

                });

        map.addOverlay(markobj);

     }

    </script>

</head>

<body onload="javascript:setupMap();" >

    <div id="map1" style="width: 400px; height: 300px"></div>

   </body>

</html>

这个例子首先创建了一个可拖动的地标,并且添加了一个监听事件,监听地图的单击事件,利用HTML语言在气泡内部建立了分割为两行的信息。

在地图显示出来之后,地图中央会出现一个地标,然后单击地标,会出现一个气泡提示框,如图4-38所示。

图4-38 提示框

② openInfoWindowHtml(content, options)

打开信息窗口,content代表信息窗口内容,可用HTML元素封装后填入;options表示GInfoWindowOptions选项。

③ oenInfoWindowTabs(tabArray, options)

打开标签信息窗口,tabArray表示信息窗口内容是标签数组由DOM元素构成的;options表示GInfoWindowOptions选项。

④ openInfoWindowTabsHtml(tabArray, options)

打开标签信息窗口,tabArray表示信息窗口内容是标签数组由HTML元素构成的; options表示GInfoWindowOptions选项。

⑤ showMapBlowup(options)

打开一个信息窗口,窗口中包含该点周围的视场图片, options表示GInfoWindowOptions选项。

以下是JavaScript代码片段:

……

     var map;

     function setupMap()

     {

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

          GEvent.addListener(markobj, "click", function() {

               //弹出一个包括视场周围图片的气泡提示框

                  markobj.showMapBlowup();

                });

        map.addOverlay(markobj);

     }

……

总之这个功能介于放大镜和鹰眼之间,既可以局部放大,也可以在Blowup窗体内部自行浏览。其实这是在窗体气泡内部又“嵌入”了一个Gmap对象。

执行代码之后,效果如图4-39所示。

图4-39 缩略图

⑥ getIcon()

返回标记的图标(该图标是通过构造函数设置的),返回值类型为GIcon。

⑦ getPoint()

返回标记的点位地理坐标(该点位是通过构造函数设置的),返回值类型为GLatLng。

注意

此方法并不是返回一个GPoint类型对象,它和getLatLng一样,都是返回经纬度值。详情请参见getLatLng()方法的描述。

⑧ setPoint(point)

设置标记的点位,是地理坐标。

⑨ enableDragging()

设置标记可拖动、可锚定,此设置的前提是GMarkerOptions.draggable的值为true。

⑩ disableDragging()

设置标记不可拖动、不可锚定。

draggable()

判断标记是否可以被拖动或锚定,返回值为布尔型。如果GMarkerOptions.draggable = true则返回true,否则返回false。

draggingEnabled()

如果标记可以被当前用户拖动或锚定,则返回true,否则返回false。

setImage(url)

通过输入的图片地址,设置标记的图标式样。

hide()

隐藏当前的地标。

show()

显示当前的地标。

isHidden()

判断当前的地标是否隐藏了。如果隐藏了返回true,没有隐藏返回false。

3)GMarker事件

作为Google Maps中的明星,地标同样有着与GMap对象同等的事件触发机制。不过Gmarker的默认事件比GMap要少9个,基本为鼠标触发的事件类型。

鼠标相关的事件有9个,分别是单击、移动鼠标和拖动类事件,具体如下所述。

l Click:当标记被单击的时候触发该事件。

JavaScript脚本代码如下:

     //定义一个地标

     var markobj = new GMarker(new GLatLng(31.7,131.2),{draggable: true});

     //当地标被单击的时候触发“click”事件

     GEvent.addListener(markobj, "click", function() {

               map.zoomIn();

            });

……

l Dblclick:当标记被双击的时候触发该事件。
l Mousedown:当标记上的鼠标被按下的时候触发此事件。
l Mouseup:当标记上的鼠标弹起的时候触发此事件。
l Mouseover:当鼠标经过标记图标的区域上时触发此事件。
l Mouseout:当鼠标滑出标记图标的区域外时触发此事件。
l Dragstart:当标记将要被拖动的那一瞬间触发此事件。
l Drag:当标记被拖动的时候触发此事件。
l Dragend:当标记停止拖动的时候触发此事件。

与信息窗口相关的事件有以下4个。

l Infowindowopen:当信息窗口打开并从标记上覆盖过去的时候触发此事件。
l Infowindowbeforeclose:当信息窗口关闭并从标记上覆盖过去之前触发此事件。
l Infowindowclose:当信息窗口关闭并从标记上覆盖过去的时候触发此事件。
l Remove:当去除(清除)信息窗口的时候触发此事件。

Visibilitychanged为可视状态的事件。当地标状态设置为可视化的时候触发此事件。如果可视,则返回isVisible。

以上的事件代码都比较简单,可以参考类似前面Click事件的实例代码,或参考4.3.4中对事件的参数中提供的例子代码,在此不再赘述。

2.地标选项类GMarkerOptions

1)概述

这个类型没有构造函数,但是据Google Maps API官网称GMarkerOptions可以被JavaScript脚本实例化,而JavaScript脚本中通常采用create方法来实例化对象,例如:

     GMarkerOptions.create();

2)属性

实例化完成之后,可以访问GMarkerOptions的10个可选属性。在创建GMarker对象的时候,无须这样创建GMarkerOptions对象,直接指定属性即可。例如下面将介绍的icon属性的实例代码。

l icon:图标。如未指定,则使用默认的 G_DEFAULT_ICON。

icon属性类型为GIcon(后文会详细介绍)类型。下面这个完整的例子代码在Tomcat中运行良好:

<!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">

//创建地图并初始化

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

         //创建GIcon对象myicon

         var myicon = new GIcon();

         //定义myicon对象的图标

         myicon.image = "http://localhost:8080/gm/pics/1.jpg";

         myicon.iconSize = new GSize(20, 20);

         myicon.iconAnchor = new GPoint(8, 10);

         myicon.infoWindowAnchor = new GPoint(5, 1);

        //通过图标对象创建GMarker对象

         var markerobj = new GMarker(new GLatLng(32.5500, -118.5032),{icon:myicon, dragCrossMove : true});

        map.addOverlay(markerobj);

      }

    }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 300px; height: 200px"></div>

</body>

</html>

在上面的代码中,首先创建地图对象map,然后创建GIcon图标对象。在创建的过程中指定了图标的图像和大小及锚点位置等属性。正如前面讲述的GMarkerOption没有构造函数一样,直接罗列其属性即可,在此罗列了icon属性和dragCrossMove属性。

地标对象markerobj最后被地图加载,如图4-40所示。

图4-40 加载地标图标

l dragCrossMove:地标是否可以在拖动时保持在十字标下面。此选项的默认值为 false。

注意

作者对目前版本的dragCrossMove功能尚存有疑惑。

l title:它的作用与 HTML 元素中的 title 属性一样,都是作为文本标记元素之用。当鼠标移动到地标图标上的时候,文字即显现。其代码如下所示:

     ……

        var markerobj = new GMarker(new GLatLng(32.5500, -118.5032),

{icon:myicon,dragCrossMove:true,title:"test"});

      ……

执行后的效果如图4-41所示。

图4-41 地标的title

l clickable:地标是否为激活状态,如果为激活状态则可以单击。此选项的默认值为 true。

如果该地标是未被激活状态,那对所有的事件都不响应,而且占用客户端资源较少。在实际应用中,切换该属性可设置如下内容。

l bouncy:地标拖动完后是否会上下弹跳。此选项的默认值为 false。
l bounceGravity:地标拖动完后上下弹跳的加速度。此选项的默认值为 1。
l autoPan:将地标拖到图框边缘时自动平移地图。在地标是可被拖动的状态下,该选项的默认值为 true。
l hide:表示初始状态下是否显示地标图标。在默认情况下该值为 false,在后文中会阐述GMarker其实也是通过GOverLay接口实现的。诸如此类的情况还很多,例如GPolyline、GinfoWindow。这些都显示在Google Maps叠加层之中,所以如果要显示叠加层,就必须调用GMarker.show方法来实现。
l zIndexProcess:更改地图上地标的z-Index 顺序,默认顺序是从南方开始标记的。当地标的信息窗口打开时也调用该函数。
l draggable:是否可拖动标记,该选项的默认值为 false。Google官方网站上指出可拖动的地标比可单击的地标占用更多的资源。

当地标被设置为“可拖动”的时候,必然同时也是“可单击”的。

3.地标操作类GMarkerManager

元素类型:类(Class)。

GMarkerManager类可以管理地图上的地标。标记管理器操作的范围包括当前地图的可见区域与不可见区域(也就是地图视场以外的区域)。

虽然从2.50版本开始,Google就不推荐用户使用GMarkerManager了,转而向开源的MarkerManger来操作地标。

1)GMarkerManager构造函数

GMarkerManager构造函数如下:

var newMarkerManager = new GMarkerManager(

     map: GMap2,

     opts: Options);

GMarkerManager构造函数参数如表4-12所示。

表4-12 GMarkerManager构造函数参数

参    数

是 否 必 要

值 类 型

定    义

map

GMap2

作为参数传入的地图对象

opts

可选

Options

选项

2)GMarkerManager方法

可以同时往地标管理器中添加一个或者多个地标,Google Maps也提供了这种方法:addMarker,不同的是参数不一样。

① addMarkers(markerList,minZoom,maxZoom)

往地标管理器中添加多个地标(注意区别于addMarker方法),并同时定义地标显示的最大、最小缩放级别,只有当前地图的缩放级别在minZoom和maxZoom之间的时候,地标才可以正常显示在地图上。

注意

调用该方法之后,需要再调用下面的refresh()方法刷新地图。

② addMarker(singleMarker,minZoom,maxZoom)

往地标管理器中添加一个地标,并同时定义地标显示的最大、最小缩放级别,只有当前地图的缩放级别在minZoom和maxZoom之间的时候,地标才可以正常显示在地图上。

③ refresh()

刷新地图上的地标,只有执行了refresh()方法之后,地标管理器中添加好的地标才能显示在地图上。

④ getMarkerCount(zoomLevel)

返回在小于等于给定的缩放级别zoomLevel下地图上的地标数目。

3)代码实例

GMarkerManager的代码实例如下:

<!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">

          function setupMap() {

          //创建Gmap对象

          if (GBrowserIsCompatible()) {

              map = new GMap2(document.getElementById("map1"));

              map.addControl(new GLargeMapControl());

              map.setCenter(new GLatLng(43.92, -71.385), 15);

              //自动定时器,执行setupMarkers方法

              window.setTimeout(setupMarkers, 1);

          }

          }

           //创建GMarker对象,并在地图上加载

          function setupMarkers () {

          mgn = new GMarkerManager(map);

          var newMarker1 = new GMarker(new GLatLng(43.92,-71.385));

          var newMarker2 = new GMarker(new GLatLng(43.921,-71.3851));

          var newMarker3 = new GMarker(new GLatLng(43.922,-71.3851));

             //向地标管理器中添加地标,并且定义地图缩放级别

          mgn.addMarker(newMarker1, 15);

          mgn.addMarker(newMarker2, 15);

          mgn.addMarker(newMarker3, 15);

            //通过refresh显示出来

          mgn.refresh();

          }

    </script>

</head>

<body onload="javascript:setupMap();" >

    <div id="map1" style="width: 500px; height: 300px"></div>

</body>

</html>

4)代码分析

函数setupMap()首先定义了一个地图对象,然后把中心点定位在(43.92, -71.385)这个位置,并定义了缩放级别为15,一秒钟之后调用函数setupMarkers()。setupMarkers()定义了一个地标管理器对象mgn,创建了3个地标newMarker1、newMarker2、newMarker3,通过调用addMarker方法,加入地标管理器中,最后刷新地图,将地标加入到地图上。

代码执行后的效果如图4-42所示。

4.GMarkerManagerOptions

GMarkerManagerOptions与GMarkerOptions类型一样,可以被JavaScript实例化为对象,但是本身并没有构造函数。

元素类型:类(Class)。

这个类是GMarkerManager构造函数中的选项,一共包括3个选项。

1)属性

属性介绍如下。

l borderPadding:表示填充地标管理器操作的当前地图视场以外的区域。即虽然看不到但是仍然下载到本地填充,如图4-43所示。

borderPadding

地图可视区域

图4-43 可视区域

l maxZoom:地标管理器可操作的当前地图最大缩放值。默认值是地图最大缩放值。
l trackMarkers:确定地标管理器是否要跟随地标(Marker)的移动,默认值是false。这个选项和setPoint()方法的使用是关联的,如果设置为true就可以使用setPoint()方法来改变标记的位置。

2)代码实例

GMarkerManager Options的代码实例如下:

……

    <script type="text/javascript">

      function load() {

      var mydiv;

      var map;

      if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map"));

        map.setCenter(new GLatLng(43.92, -71.385), 7);

        map.addControl(new GLargeMapControl());

          ……

             //在图4-43中由于地图缩放级别被定义为10,故而看起来像一个点,实际有3个点

             mgn = new GMarkerManager(map,{maxZoom:10});

          var newMarker1 = new GMarker(new GLatLng(43.92,-71.385));

          var newMarker2 = new GMarker(new GLatLng(43.921,-71.3851));

          var newMarker3 = new GMarker(new GLatLng(43.922,-71.3851));

             //加载地标的时候,定义了3个不同的缩放级别,在不同的级别下,地标对象显示个数也不同

          mgn.addMarker(newMarker1,8,15);

          mgn.addMarker(newMarker2,7,13);

          mgn.addMarker(newMarker3,7,11);

          mgn.refresh();

          ……

      }

    }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 300px; height: 300px"></div>

</body>

3)代码分析

代码中采用了GMarkerManager的构造函数来创建新的GMarkerManager对象mgn,并且设定了mgn的可操控最大缩放级别为10。mgn调用了addMarker方法添加地标,那么之后必须要调用refresh方法,将叠加层上的地标图标都刷新一次显示出来,如图4-44所示。

图4-44 地标管理器

4.3.9 构建几何图形

Google Maps 将API分成了六大类,其中布局类(Overlay Classes)中主要包括了信息窗口类型、图标类型、折线类型、多边形类型、地标类型等,而GIcon、GPolyline、GPolygon在此单独作为“点”、“线”、“面”几何图形讲述。

注意

这里的“点”类型既不是GPoint也不是GLatLng,因为它们都只是表示单纯的点位位置,而非一个点状图形。

1.线状图形GPolyline类型

该类是在地图上绘制折线的,绘制的时候要用到VML语法,例如像points这样的标识。不过这样的多义线语法不仅可以在IE上显示,也可以在其他网页浏览器上正常显示,如FireFox。

相对于2.5x版本来说,最新版本的GPolyline构造函数增加了一个GPolylineOptions类型的参数,在下面的构造函数中名称为option,该类型不存在构造函数,与前一节提及的GMarkerOptions一样,可以被JavaScript实例化。

1)构造函数与大地线的概念

构造函数如下:

GPolyline(points, color, weight, opacity, option)

GPolyline构造函数参数如表4-13所示。

表4-13 GPolyline构造函数参数

参    数

是 否 必 要

值 类 型

定    义

points

GLatLng 数组

顶点集合

color

可选

String

颜色

weight

可选

Int

宽度

opacity

可选

0~1的小数

透明度

option

可选

GPolylineOptions

选项

GPolylineOptions类型介绍如下。

l clickable:折线是否可单击。可单击就意味着可以响应click事件,用户可以对其进行鼠标单击操作。默认为true(可单击状态)。
l geodesic:这个选项是用来修正地球椭球曲率的(对于Google Maps,不应该用“椭球”一词,关于地图投影会在后文中详细解释),设置为true的时候表示将折线的每一边纠正为沿地球表面两点间最近距离的曲线线段(即测量学上的所谓在参考椭球上的“大地线”又称之为“测地线”),通过图4-45与图4-46的对比可以发现区别。左边的图为geodesic属性设置为false时的样子,折线的边是未受地球曲率影响的笔直的线段;而右边的图为geodesic属性设置为true时的样子,折线的边明显是受地球曲率影响的弯曲的线段。

                  

             图4-45 未纠正之前的直线                     图4-46 纠正后的曲线

以上图片对应的代码片段如下:

……

    <script type="text/javascript">

      function load() {

      var mydiv;

      var map;

        //创建并初始化地图对象

      if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map"));

        map.setCenter(new GLatLng(52.93, -76.389), 2);

        map.addControl(new GLargeMapControl());

        //通过数组创建线段的脚点

        var ArrayPolyPoints = new Array();

        ArrayPolyPoints[0] = new GLatLng(33.92, -51.385);

        ArrayPolyPoints[1] = new GLatLng(52.93, -76.389);

        ArrayPolyPoints[2] = new GLatLng(75.94, -89.395);

        var mypoly = new GPolyline(ArrayPolyPoints,'#000066',3,5,

{geodesic:true});

        map.addOverlay(mypoly);

          }

     }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 300px; height: 300px"></div>

</body>

……

以上的代码中geodesic属性设置为true。

2)构造工厂方法

构造工厂方法如下:

var encodedPolyline = new GPolyline.fromEncoded({

       color: color,

       weight: weight,

       points: encodedPoints,

       levels: encodedLevels,

       zoomFactor: zoomFactor,

       numLevels: numLevels});

工厂方法参数如表4-14所示。

表4-14 工厂方法参数

参    数

是 否 必 要

值 类 型

定    义

color

可选

String

颜色

weight

可选

Int

宽度

opacity

可选

Int

透明度

(续表)

参    数

是 否 必 要

值 类 型

定    义

points

GLatLng 数组

顶点集合

zoomFactor

Int

两个缩放级别之间的放大倍率跨度

levels

Int

缩放级别字符串

numLevels

Int

缩放级别数值

3)GPolyLine方法

GPolyLine方法介绍如下。

l getVertexCount():取得PolyLine的顶点数目,返回值为数值型。
l getVertex(index):取得PolyLine中某个顶点的点位,返回值为GLatLng型。

4)GPolyLine事件

把PolyLine从地图上删除时触发Remove事件,如调用GMap2.removeOverlay()或者GMap2.clearOverlays()方法时就触发此事件。

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">

      function load() {

      var mydiv;

      var map;

      if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map"));

        map.setCenter(new GLatLng(43.92, -71.385), 8);

        map.addControl(new GLargeMapControl());

        //创建Polyline脚点数组

        var ArrayPolyPoints = new Array();

        ArrayPolyPoints[0] = new GLatLng(43.92, -71.385);

        ArrayPolyPoints[1] = new GLatLng(43.93, -71.389);

        ArrayPolyPoints[2] = new GLatLng(43.94, -71.395);

        //创建PolyLine对象,并定义颜色、透明度、粗细

        var mypoly = new GPolyline(ArrayPolyPoints,#E5ECF9,1,1,{geodesic:true});

         map.addOverlay(mypoly);

     }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 300px; height: 300px"></div>

</body>

</html>

代码运行后的效果请参见前面的图4-45和图4-46。

这里的geodesic属性设置为true,应该是对应于图4-45的。GPolyLine的构造函数的第一个参数是GLatLng的对象数组,可以使用JavaScript的动态数组来建立。例如在本例中,GLatLng的对象数组名称为ArrayPolyPoints。ArrayPolyPoints一共被赋值了3个元素,即3个GLatLng对象。为了便于查看出直线弯曲的效果,代码中的经纬度特地选择了跨度距离比较远的3个坐标。

一般来说,小范围之内(例如10平方公里)无须考虑地区曲率的影响,在大区域面积的情况下才需要考虑。

2.多边形GPolygon类型

多边形的绘制与折线类似,需要通过GLatLng对象数组来指定多边形的脚点。同样,在新版的API中,GPolygon构造函数比老版的多了一个GPolygonOptions类型的选项option。

元素类型:类(Class)。

该类定义了Google Maps地图的多边形,用户可以定义为面块或者线框。

1)GPolygon构造函数

GPolygon构造函数如下:

var newPolygon = new Gpolygon(

     points : points,

     strokeColor : strokeColor,

     strokeWeight : strokeWeight,

     strokeOpacity : strokeOpacity,

     fillColor : fillColor,

     fillOpacity : fillOpacity,

     option : GpolygonOptions)

Gpolygon构造函数参数如表4-15所示。

表4-15 Gpolygon构造函数参数

参    数

是 否 必 要

值 类 型

定    义

points

GlatLng 数组

顶点集合

strokeColor

可选

String

边线颜色

strokeWeight

可选

Int

边线宽度

(续表)

参    数

是 否 必 要

值 类 型

定   义

strokeOpacity

可选

0~1之间的小数

边线透明度

fillColor

可选

String

填充色

fillOpacity

可选

0~1之间的小数

填充透明度

option

可选

GPolygonOptions

选项

参数中的GPolygonOptions类型没有构造函数。与前面的GPolylineOptions类型一样,使用时直接罗列即可,同时也可以被JavaScript脚本实例化。其只有一个clickable属性:该属性表示折线是否可单击。可单击就意味着可以响应click事件,用户可以对其进行鼠标单击操作。默认为true(可单击状态)。

2)构造工厂方法

构造工厂方法如下:

var encodedPolygon = new GPolygon.fromEncoded(

     polylines : polylines,

     fill : fill,

     color : color,

     opacity : opacity,

     outline : outline)

构造工厂参数如表4-16所示。

表4-16 构造工厂参数

参    数

是 否 必 要

值 类 型

定    义

polylines

GLatLng 数组

顶点坐标

fill

可选

bool

是否填充

color

可选

string

填充色

opacity

可选

int

填充透明度

outline

可选

bool

是否需要边框

3)代码实例

GPolygon的代码实例如下:

<html xmlns:v="urn:schemas-microsoft-com:vml">

<head>

      <style>

        v\:* { behavior: url(#default#VML); }

      </style>

    <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= …… "

            type="text/javascript"></script>

        <script type="text/javascript">

         var map = null;

         //创建Polygon

        function createPolygon()

{

     var pt1 = new GLatLng(32.0248, 118.7523);

     var pt2 = new GLatLng(32.0350, 118.7540);

     var pt3 = new GLatLng(32.0355, 118.7540);

     var pt4 = new GLatLng(32.0360, 118.7612);

     var pt5 = new GLatLng(32.0370, 118.7689);

//通过数组来定义Polygon的脚点

     var ArrPt = new Array();

     ArrPt[0] = pt1;

     ArrPt[1] = pt2;

     ArrPt[2] = pt3;

     ArrPt[3] = pt4;

     ArrPt[4] = pt5;

     ArrPt[5] = pt1;

     var newPolygon = new GPolygon(ArrPt,"#ccff66",2,0.5,"#ff0033",0.5);

//在地图上添加Polygon对象

     map.addOverlay(newPolygon);

}

       function load() {

         if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map1"));

        map.setCenter(new GLatLng(32.0348, 118.7523), 14);

      }

    }

    </script>

</head>

<body onload="load()" onunload="GUnload()">

<div id="map1" style="width: 500px; height: 300px"></div>

<input id="polylinebtn" value="cretePolygon" type="button" nclick="javascript:create Polygon();"></input>

</body>

</html>

4)代码分析

本例子是通过HTML + JavaScript + VML结合完成的。该例子主要实现了在地图上绘制一个区域的功能。JavaScript函数createPolygon()中调用了GPolygon的构造函数,将事先定义好的点成功绘制在地图上,如图4-47所示。

图4-47 面状图形

5)GPolygon方法

GPolygon方法如下。

l getVertexCount():取得Polygon的顶点数目,返回数值类型。
l getVertex(index):根据输入索引,取得某个顶点,返回GLatLng类型。

JavaScript脚本代码如下:

function createPolygon()

{

     var pt1 = new GLatLng(32.0248, 118.7523);

     var pt2 = new GLatLng(32.0350, 118.7540);

     var pt3 = new GLatLng(32.0355, 118.7540);

     var pt4 = new GLatLng(32.0360, 118.7612);

     var pt5 = new GLatLng(32.0370, 118.7689);

     var ArrPt = new Array();

     ArrPt[0] = pt1;

     ArrPt[1] = pt2;

     ArrPt[2] = pt3;

     ArrPt[3] = pt4;

     ArrPt[4] = pt5;

     ArrPt[5] = pt1;

     var newPolygon = new GPolygon(ArrPt,"#ccff66",2,0.5,"#ff0033",0.5);

     map.addOverlay(newPolygon);

     var Parea = newPolygon.getArea();

     alert(Parea);

}

l getArea():取得Polygon所围的面积(Google Maps会根据投影自己计算),返回数值类型。
l getBounds():取得Polygon的边界,返回GLatLngBounds类型。

6)GPolygon事件

把Polygon从地图上删除时触发Remove事件,如调用GMap2.removeOverlay()或者GMap2.clearOverlays()方法时就触发此事件。

3.点状图标GIcon类型

GIcon表示地表上的点状地标(GMarker)的图标,Google有默认图标G_DEFAULT_ ICONA。

元素类型:类(Class)。

1)GIcon构造函数

GIcon构造函数如下:

var newGIcon = new GIcon(

     copy:copy,

     image:image);

GIcon构造函数参数如表4-17所示。

表4-17 GIcon构造函数参数

参    数

是 否 必 要

值 类 型

定    义

copy

可选

GIcon

是否克隆另一个图标的属性

image

可选

image

是否填充

2)GIcon常量

G_DEFAULT_ICON:地标使用的默认图标。

3)GIcon属性

GIcon属性介绍如下。

l image:图标的图片URL地址,赋值类型为String。
l shadow:图标的阴影图片URL地址,赋值类型为String。
l iconSize:图标的大小,赋值类型为GSize。
l shadowSize:图标阴影的大小,赋值类型为GSize。
l iconAnchor:图标锚定的位置,定义了图标左上角的坐标,屏幕坐标。赋值类型为GPoint。
l infoWindowAnchor:图标的信息窗口的锚定位置,定义了窗口左上角的坐标,屏幕坐标。赋值类型为GPoint。
l printImage:定义印刷品地图上的图标符号的URL地址,赋值类型为String。

4)代码实例

GIcon的代码实例如下:

……

    <script type="text/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);

          }

          }

         

          function AddIconMarker()

          {

               var icon = new GIcon();

               icon.image = "http:// ……/mm_20_red.png";

               icon.shadow = "http:// ……/mm_20_shadow.png";

               icon.iconSize = new GSize(12, 20);

               icon.shadowSize = new GSize(22, 20);

                icon.iconAnchor = new GPoint(8, 10);

               icon.infoWindowAnchor = new GPoint(5, 1);

               map.addOverlay(new GMarker(map.getCenter(), icon));

          }

         

    </script>

</head>

<body onload="javascript:setupMap();" >

    <div id="map1" style="width: 500px; height: 300px"></div>

    <input id="btn" type="button" value="添加标记" onClick="javascript:AddIconMarker ();"

   </body>

</html>

5)代码分析

对于地图而言,首先定义了一个GIcon对象,然后设置这个GIcon对象的属性,定义了诸如图标的图像、阴影、尺寸等具体图片的URL和数值,再由map.addOverlay方法调用,在地图中心点处生成。单击地图下方的【添加标记】按钮后将图标对象加载到地图上,执行后的效果如图4-48所示。

4.3.10 部分Google地图上的覆盖类型

前面小节中提及的几何图形和信息窗口与本节中要讲解的类型都是Goverlay接口的实现类。为了在功能上进行区分,特此另立一小节讲解。

1.GGroundOverlay类型

元素类型:类(Class)。

GGroundOverlay创建了一个覆盖在地图上的方形图像。

1)GGroundOverlay构造函数

GGroundOverlay构造函数如下:

var newGroundoverlay = new GGroundOverlay(

     imageUrl: String

     bounds: GLatLngBounds);

GGroundOverlay构造函数参数如表4-18所示。

表4-18 GGroundOverlay构造函数参数

参    数

是 否 必 要

值 类 型

定    义

imageUrl

String

图片URL地址

bounds

GLatLngBounds

是否填充

2)代码实例

GGroundOverlay的代码实例如下:

……

    <script type="text/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);

          }

          }

          function AddGroundOverlay()

          {

               var bounds = map.getBounds();

               var southWest = bounds.getSouthWest();

               var northEast = bounds.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 gOverly = new

GGroundOverlay("http://127.0.0.1:4466/3Gtime.PNG",rectBounds);

               map.addOverlay(gOverly);

          }

         

    </script>

</head>

<body onload="javascript:setupMap();" >

    <div id="map1" style="width: 500px; height: 300px"></div>

    <input id="btn" type="button" value="添加标记" onClick="javascript: AddGround Overlay ();"

……

3)代码分析

在上述的例子中,GGroundOverlay通过指定的一个PNG图片和长宽分别取值1/4长度的一个范围生成一个实例对象,最终通过map.addOverlay加载。该范围首先通过map.getBounds取得地图的范围,进行简单的数学运算,得到了1/4比例的长度,用以确定新的GGroundOverlay对象的范围。

GGroundOverlay生成的是一个覆盖在地图上的方形图片区域,是和地图上对应的地理位置绑定的。与点状地标和线状地标不同的是,GGroundOverlay对象是随着Google Maps地图一起缩放的。

上述代码执行后的效果如图4-49所示。

图4-49与图4-50对比后可以看出,GGroundOverlay对象是随着Google Maps地图一起缩放的。

           

              图4-49 加载和缩放                         图4-50 放大后的效果

4)GGroundOverlay方法

GGroundOverlay方法介绍如下。

l hide():隐藏覆盖层。
l isHidden():判断覆盖层是否被隐藏(不可见)了。如果不可见,返回true,反之返回false。
l show():显示覆盖层。
l supportsHide():这个方法比较有意思,总是返回true值。

2.GScreenOverlay类型

这个类型与上面讲述的GGroundOverlay方法都是在地图窗口中添加叠加图层,有所不同的是,前者的叠加图层覆盖在“地图上”,而GScreenOverlay是覆盖在屏幕上的。这就意味着无论怎么缩放和平移地图,叠加图层都不会动,仍然保持在地图窗口里。

1)GScreenOverlay构造函数

GScreenOVerlay构造函数如下:

var GScreenOverlayObj = new GScreenOverlay(

imgUrl:String,

screenXY:GScreenPoint,

overlayXY:GScreenPoint,

overlaySize:GScreenSize);

GScreenOverlay构造函数参数如表4-19所示。

表4-19 GScreenOverlay构造函数参数

参    数

是 否 必 要

值 类 型

定    义

imgUrl

String

图片URL地址

screenXY

GScreenPoint

相对于屏幕原点位置

overlayXY

GScreenPoint

相对于screenXY坐标叠加图片的相对位置

overlaySize

GScreenSize

叠加图片大小

2)代码实例

GScreenOverlay的代码实例如下:

……

    <script type="text/javascript">

      var map;

      function load() {

      var mydiv;

      if (GBrowserIsCompatible()) {

             map = new GMap2(document.getElementById("map"));

             map.setCenter(new GLatLng(25.020551,121.525849), 12);

             map.addControl(new GLargeMapControl());

          }

     }

     function AddGroundOverlay()

     {

     //加载本机服务器上的1.jpg图片,相对屏幕原点位移为0,图片相对screenXY坐标原点位移为0

     var s_xy = new GScreenPoint(0,0);

     var o_xy = new GScreenPoint(0,0);

     var s_size = new GScreenSize(200,160)

     var gOverly = new GScreenOverlay("http://127.0.0.1:8080/gm/1.JPG",

s_xy , o_xy , s_size);

          map.addOverlay(gOverly);

     }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 260px; height: 200px"></div>

     <input type="button" onclick="javascript:AddGroundOverlay();"

……

3)代码分析

上面的代码片断中,s_xy表示当前坐标系相对于屏幕坐标系原点位移上下都为0,o_xy表示当前图片中的锚点(图片左下角)相对于s_xy的坐标系原点的位移上下都为0。加载本机的一幅图片后,从地图窗口左下角开始覆盖,无论地图如何缩放和移动,这幅图片始终保持不动、不缩放,这就是与上面GGroundOverlay的主要区别,如图4-51所示。

图4-51 屏幕叠加图片

4)GScreenOverlay方法

GScreenOverlay方法介绍如下。

l hide():隐藏叠加层。
l isHidden():判断叠加层是否被隐藏(不可见)了。如果不可见返回true,反之返回false。
l show():显示叠加层。
l supportsHide():这个方法比较有意思,总是返回true值。

3.GtrafficOverlay类型

元素类型:类(Class)。

这个类的作用是在地图上添加一个交通层,该层可以动态地显示交通路况信息。

1)GTrafficOverlay构造函数

GTraffic Overlay构造函数如下:

var newTrafOverlay = new GTrafficOverlay();

2)GTrafficOverlay方法

GTrafficOverlay方法介绍如下。

l hide():隐藏该层。
l show():显示该层。

3)GTrafficOverlay事件

Changed:如果视场中有交通路况的数据发生了变动,比如交通数据更新或者拖动、缩放了地图,都会引起这个事件的触发。

4.GStreetviewOverlay类型

显示道路图像数据,作用是在地图上添加一个道路层。

图4-52与图4-53对比后可以看出,未加载与已加载了道路之后,两幅地图的变化。

        

             图4-52 未加载道路层                          图4-53 已加载道路层

1)GStreetviewOverlay构造函数

GStreetview Overlay构造函数如下:

var GstreetviewOverlayObj= new GStreetviewOverlay ();

2)GStreetviewOverlay事件

Changed(isInMapView :boolean):如果视场中有道路图像数据发生了变动就会引起这个事件的触发。参数isInMapView表示当前的地图图框视场中是否包含街道图像数据。

4.3.11 Google Maps与XML

Google旗下的两款主打产品Gmail和Google Maps都使用了AJAX技术,AJAX就是异步JavaScript和XML技术的整合。在使用Google Maps时,页面无须刷新即可连续加载新的地图数据。而AJAX的基础在于XMLHttpRequest对象,XMLHttpRequest对象与服务器的交互无须等待页面表单form的提交,从而无须刷新整个页面数据,给予用户全新的Web程序使用体验。

Google Maps API提供了一种与浏览器无关的建立XMLHttpRequest对象的工厂方法——GXmlHttp。

1.GXmlHttp

这是一个名称空间(NameSpace),可以创建一个XMLhttp对象。

1)GXmlHttp静态函数create()

var request = GXmlHttp.create();

创建一个XmlHttpRequest对象。

2)代码实例

GXmlHttp的代码实例如下:

<!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://maps.google.com/maps?file=api&amp;v=2&amp;key= …… "

            type="text/javascript"></script>

    <script type="text/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);

          }

          }

         

          function gxmlfun()

          {

               //创建XMLhttp对象

               var request = GXmlHttp.create();

               //request对象获取Tablenew.xml文件

               request.open("GET", "Tablenew.xml", true);

               request.onreadystatechange = function() {

                    if (request.readyState == 4) {

                         var xmlDoc = request.responseXML;

                         var PerPos = xmlDoc.documentElement.childNodes;

                         //取得XML文件中lng和lat的节点值

                         for (var i = 0; i < PerPos.length; i++) {

                         var lng = PerPos[i].getElementsByTagName("lng")[0].text;

                         var lat = PerPos[i].getElementsByTagName("lat")[0].text;

                         var latlngObj = new GLatLng(lat,lng);

                         map.addOverlay(new GMarker(latlngObj));

                         }

                    }

               }

               request.send(null);

          }

    </script>

</head>

<body onload="javascript:setupMap();" >

<div id="map1" style="width: 500px; height: 300px"></div>

<input id="btn" type="button" value="添加标记" onClick="javascript:gxmlfun();">

   </body>

</html>

Tablenew.xml的XML文件内容如下(这些XML文件可以通过第三方工具软件,诸如Office Access或者免费的Postgresql的插件生成,也可以用笔记本直接按照XML语法规范编写):

<?xml version="1.0" encoding="UTF-8"?>

<dataroot>

     <Table>

          <id>1</id>

          <lng>-71.385</lng>

          <lat>43.92</lat>

          <MarkId>1</MarkId>

     </Table>

     <Table>

          <id>2</id>

          <lng>-71.386</lng>

          <lat>43.921</lat>

          <MarkId>2</MarkId>

     </Table>

     <Table>

          <id>3</id>

          <lng>-71.387</lng>

          <lat>43.922</lat>

          <MarkId>3</MarkId>

     </Table>

     <Table>

          <id>4</id>

          <lng>-71.388</lng>

          <lat>43.923</lat>

          <MarkId>4</MarkId>

     </Table>

</dataroot>

3)代码分析

在本例网页里的JavaScript脚本代理中,实现了一个极为简单的XMLhttp利用。通过gxmlfun函数实现了一个XMLhttp对象,通常情况下XMLhttp对象是进行XML数据交换的选择,在此例中通过request.open语句,载入了XML格式的数据,只是例中这个XML文件是在本地的,但这个XML文件也可以在Internet的其他地方,只要给出URL并可以被访问即可。

在名为Tablenew.xml的XML中,用两个子标签<lng>、<lat>分别表示经度和纬度。脚本中的PerPos变量得到的是一个数组,然后通过循环访问,分别利用经纬度生成地标,载入到地图中。

在Google Maps的地图上执行后的效果如图4-54所示。

图4-54 绘制

2.通过GXml类来处理XML

元素类型:名称空间(NameSpace)。

用户通过GXml可以针对XML文档进行操作,如解析或者取得节点的值。GXml提供了两个针对XML的静态函数。

1)parse(xmltext)

解析以参数形式传入的XML文档,解析后,用户可以通过其他编程语言获取XML文档的节点信息,而无须自己编程解析。

GXml.parse提供了DOM的方式解析,以内存中的树形方式解析展现,解析后成为一个“对象”,用户可以动态地访问该XML对象的每个节点。

使用DOM解析的方式的优点是非常简单、快速,但不是很灵活,需要一次性把整个XML文档解析。而且如果XML文档本身文件比较大,并且包含了比较复杂的结构,那么GXml解析出的内存树会非常占资源。

2)value(xmlnode)

返回一个以DOM解析方式的xml节点的文本。

3.格式类型GXslt

元素类型:类(Class)。

XSLT即为XSL Transformation。通过GXslt类,用户可以转换XML成为其他文档格式,如HTML文档。该类提供了两种方法。

(1)create(DOMXslt):输入DOM形式的XSLT程序段,返回一个GXslt类实例。

(2)transformToHtml(xmlTxt,htmlEle):提供XML的转换,把输入的xmlTxt文档转换成HTML格式的形式,显示在网页上,htmlEle是转换后存放结果的HTML元素。

4.管理托管XML文件的GgeoXml类型

元素类型:类(Class)。

该类通过XML文件向地图上加载地理要素或者图形。这里的XML文件包括KML文件,为远程托管类型的文件。如同前面讲解的GPolygon等类型一样,也是实现GOverlay接口。

1)GGeoXml构造函数

GGeoXml构造函数如下:

var newGeoXml = new GGeoXml(

     XmlDocURL:String,

     fun_callback:Function);

GGeoXml构造函数参数如表4-20所示。

表4-20 GGeoXml构造函数参数

参    数

是 否 必 要

值 类 型

定    义

XmlDocURL

String

XML文档的地址

fun_callback

可选

Function

回调函数

2)GGeoXml方法

GGeoXml方法介绍如下。

l getTileLayerOverlay() :获取瓦片层,如果成功,返回值为GTileLayerOverlay对象,否则返回null。
l getDefaultCenter() :返回地图当前的默认中心点经纬度坐标,返回值为GLatLng对象。
l getDefaultSpan() :返回当前地图视场的跨度。这个跨度是以经纬度来表示的,而非用“米”来表示。
l getDefaultBounds() :返回当前地图视场的范围,返回值为GLatLngBounds对象。
l gotoDefaultViewport(map) :将地图视场定位到XML图形的范围内。
l hasLoaded() :返回布尔值。如果XML文件加载完毕,则返回true,否则返回false。
l  loadedCorrectly():返回布尔值。如果成功调用XML文件,则返回true,否则返回false。

该类除了可以加载KML文件外,还可以加载一般的普通图像文件(图像文件以XML的方式存储),如图4-55所示的“Hello World”的图片。

以下为存储图片信息的XML文档:

<?xml version="1.0" encoding="UTF-8"?>

<dataroot>

<pic>

<id>2</id>

<pic>

/9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoH

BwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQME

……

……

OdrRXB/8FDvj58MfHX7Hnj/Q/DfxG8JeIdauv7P+z6bpWuWtzczbdQtnbZGkhZsK

rMcDgKT0FFfo3C8JU8FNTVvee/pE5qzvI//Z

</pic>

</pic>

</dataroot>

4.3.12 GLog

元素类型:名称空间(NameSpace)。

用户通过GLog可以记录日志,从而更好地调试程序。

GLog的静态方法如下。

l write(msgTxt,txtColor):往日志窗口写入消息,msgTxt是将要写入的消息文档,txtColor是文字的颜色。
l writeUrl(urlStr):把输入的URL地址当做字符串写入日志窗口。
l writeHtml(htmlTxt):把HTML文本写入日志窗口执行显示。

例如下面的JavaScript代码:

function load() {

……

GLog.writeHtml("<b>Html Text</b><br/> line1<br/>line2");

……

}

变量窗口是自动弹出的,以上代码执行后的效果如图4-56所示。

图4-56 变量窗口

4.3.13 GDownloadUrl

元素类型:函数(Function)。

该方法是Google Maps提供的获取XML数据的一种方法,本函数无须XMLHttpRequest的readystate检查。

GDownloadUrl函数如下:

GDownloadUrl(url,onLoadFunction)

JavaScript的脚本代码如下:

……

var map;

function setupMap() {

if (GBrowserIsCompatible()) {

    map = new GMap2(document.getElementById("map1"));

    map.addControl(new GLargeMapControl());

    map.setCenter(new GLatLng(31.7,131.2), 10);

}

GDownloadUrl("googleTest.xml", function(data, responseCode) {

var xml = GXml.parse(data);

var bridges = xml.documentElement.getElementsByTagName("googleTest");

for (var i = 0; i < bridges.length; i++) {

    var name = bridges[i].getAttribute("id");

    var latitude = parseFloat(bridges.item(i).childNodes[2].text);

    var longitude = parseFloat(bridges.item(i).childNodes[1].text);

    //var marker = createBridgeMarker(i, name, latitude, longitude)

    var GLatlngObj = new GLatLng(latitude,longitude);

    map.addOverlay(new GMarker(GLatlngObj));

}

});

}

GDownloadUrl函数的第一个参数是xml的地址全称,显然googleTest.xml文件在同一个根目录下。第二个参数是个回调函数,读取xml中的变量值,并且为每对经纬度值增加一个对应的地标点到地图上。

名为“googleTest.xml”的XML文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<dataroot>

     <googleTest>

          <id>109</id>

          <lng>128.2</lng>

          <lat>29.6</lat>

     </googleTest>

     <googleTest>

          <id>110</id>

          <lng>128.8</lng>

          <lat>30.2</lat>

     </googleTest>

     <googleTest>

          <id>111</id>

          <lng>131.2</lng>

          <lat>31.7</lat>

     </googleTest>

     <googleTest>

          <id>112</id>

          <lng>132.3</lng>

          <lat>32.4</lat>

     </googleTest>

     <googleTest>

          <id>113</id>

          <lng>133</lng>

          <lat>32.9</lat>

     </googleTest>

     <googleTest>

          <id>114</id>

          <lng>133.8</lng>

          <lat>33.2</lat>

     </googleTest>

     <googleTest>

          <id>115</id>

          <lng>134.9</lng>

          <lat>33.4</lat>

     </googleTest>

     <googleTest>

          <id>116</id>

          <lng>136.2</lng>

          <lat>33.7</lat>

     </googleTest>

</dataroot>

如图4-57所示为KML点。

图4-57 KML点

4.3.14 Google地图的路径和指向

使用Web地图,经常用到的一个功能就是道路的指向与查询。终端用户输入目的地与出发地,然后提交给WMS服务器,服务器通过geocoding(地址分析)过程将目的地与出发地的经纬度位置计算出来,再通过查询途径的路径或者计算最优路径来形成最终查询结果。简而言之这就是所谓的道路指向功能。

Google Maps Mobile最新版本已经提供了道路查询和指向的功能。通过该功能,直接可以将终端用户查询出来的道路,以及指向信息通过手机展现在Google Maps Mobile上,加之目前3G无线应用已经普遍开花,道路查询和指向功能大有替代传统移动电话服务商的彩信平台路径查询之势。

Google Maps API一共有4个有关路径与指向的类型,分别是GDirections、Gdirections Options、GRoute、GStep,下面将逐一介绍。

1.方向类型GDirections

元素类型:类(Class)。

这个类创建一个方向对象,用于保存方向信息并且在地图上展现出来。展现的方式分为两种——图形式和文字式。

1)GDirections构造函数

GDirections构造函数如下:

var newDirections = new GDirections(

     map:GMap2,

     DivPanel: DIV);

构造函数参数如表4-21所示。

表4-21 GDirections构造函数参数

参    数

是 否 必 要

值 类 型

定    义

map

可选

GMap2

地图对象,方向以图形方式展现

DivPanel

可选

Div

Div对象,方向信息通过文字展现

2)GDirections方法

① load(query,queryOptions)

发送一个方向请求,返回方向信息。默认的方式下,返回一个Polyline折线,如果构造函数中声明了DivPanel,则返回文本形式的方向值。query是字符串,格式形如:“地点_1 to 地点_2”。

代码执行后的效果如图4-58所示。

图4-58 路径

在上图中,在GDirections构造的时候就指定了显示方向路径的文本容器,因此Google Maps在执行查询之后,会自动将查询结果以文字描述的方式显示出来。

注意

这个查询是异步的。

② loadFromWaypoints(waypoints, queryOpts?)

通过中途点查询“地址指向”(Direction)。waypoints为中途点,可以是文本地址信息也可以是GLatLng点。

③ clear()

清除所有的“地址指向”信息。

④ getStatus()

返回“地址指向”请求的状态。

⑤ getBounds()

如果“地址指向”查询成功,则返回这次查询结果的范围,返回值类型是GLatLngBounds;如果查询不成功,则返回null。

JavaScript脚本代码如下(这个例子是表明如何得到地址边界的4个边经纬度的):

……

function Directionbound()

{

    var boundObj = new GBounds();

    boundObj = GDirectionObj.getBounds();

    if (boundObj !== null)

    {

       //地址边界的4个边经纬度

var minXX = boundObj.minX;

        var maxXX = boundObj.maxX;

        var minYY = boundObj.minY;

        var maxYY = boundObj.maxY;

        alert(minXX + ',' +maxXX + ',' + minYY + ',' + maxYY );

    }

}

⑥ getNumRoutes()

返回“地址指向”查询的结果路径数目。如果不能成功查询则返回-1。

这个方法返回的不是中途点的数目,而是完整路径的数目,与getNumGeocodes方法相区别,请在开发的时候注意。

⑦ getRoute(index)

返回查询得到的指向路径结果中的某一条,但是此处的序号却是从0开始的,这与Google Maps API中的其他元素不同,要特别要注意。关于路径的详细描述,请参看下面的GRoute。

⑧ getNumGeocodes()

得到“地址指向”查询结果中的Geocode对象的数目,即中途点(Waypoints)的数目。如果查询不成功,则返回0。

⑨ getGeocode(index)

按照给定的序号,得到“地址指向”查询结果中的某个中途点(Waypoints)。

⑩ getCopyrightsHtml()

返回查询结果的Copyright信息,以HTML文本的方式返回。

JavaScript脚本代码如下:

function Directionbound()

{

ss = new GDirections(map, directionsPanel);

……

    alert(ss.getCopyrightsHtml());

}

代码执行后的效果如图4-59所示。

图4-59 查询信息

   getSummaryHtml()

返回包含“地址指向”查询的时间和距离的HTML文档。

   getDistance()

取得“地址指向”查询结果的路径总长度。返回的结果为一个包含长度值和HTML文本的对象,如图4-60所示。

这个对象中包括“meters”和“html”两个对象属性。“meter”属性表示路程的长度值,“html”属性表示对象所包含的HTML文本。

   getDuration()

取得“地址指向”查询请求的总时间。返回的结果为一个包含表示时间值和HTML文本的对象,如图4-61所示。

       

              图4-60 路径长度                                  图4-61 耗时

这个对象中包括“seconds”和“html”两个对象属性。“seconds”属性表示路程的时间值,以“秒”为单位;“html”属性表示对象所包含的HTML文本。

   getPolyline()

取得表示指向路径的折线。当查询结果被加载之后,返回GPolyline对象,否则返回null。

JavaScript脚本代码如下:

var gdirObj ;

……

function Directionbound()

{

    var tmpLine = gdirObj.getPolyline();

    var tmpDis = gdirObj.getDistance();

    alert(tmpLine.getLength());

}

对比图4-62和图4-63会发现两图中的长度数值并不一致。这个现象很有趣,估计是Google Maps地图上的折线的计算数值与路径长度数据的出处不同。路径长度可能更加准确一些,或许是人为录入的,而并非是计算出来的,当然这个答案只有Google自己知道。

         

                  图4-62 代码长度                                图4-63 数据长度

   getMarker(index)

取得表示路径上中途点的地标,按地标的序号返回某个地标。当查询结果被加载之后,返回GMarker对象,否则返回null。

2.GDirectionsOptions类型

GDirectionsOptions类型介绍如下。

l locale:表示地址请求结果的方位,值是字符串型。
l getPolyline:表示是否取地址指向请求的Polyline对象,设置为true为取,否则不取。
l getSteps:表示是否取地址指向请求的一段段文字信息,设置为true为取,否则不取。
l preserveViewport:表示是否取地址指向请求的视点窗口,设置为true为取,否则不取。

3.GRoute路线信息类型

元素类型:类(Class)。

该类是GDirections对象保存方向的路线信息所创建的。GRoute类没有构造函数,用户可以直接调用。

GRoute方法介绍如下。

l getNumSteps():返回路径中的段数。

其代码如下:

     function GetRounte()

     {

          var tmpRoute = gdirObj.getRoute(0);

          alert(tmpRoute.getNumSteps());

     }

如图4-64所示,所谓段数,指的是Google Maps给出的整个路径共有几节。本例子中为24节。

图4-64 路径

l getStep(index):取得路径中的某一段。这个方法返回的是一个对象,该对象类型为GStep。关于GStep的详细描述请参看后面的段落。

JavaScript脚本代码如下:

function GetRouteStep()

{

            var tmpRoute = gdirObj.getRoute(0);

            var tmpDisObj = tmpRoute.getStep(1).getDistance();

            alert(tmpDisObj.meters);

}

l getStartGeocode():返回路径的开始点的Geocode对象。

JavaScript脚本代码如下:

function GetRouteGeocode()

{

        var tmpRoute = gdirObj.getRoute(0);

        var tmpGeocodeObj = tmpRoute.getStartGeocode();

        //返回开始点的参数信息

     var tmpGeocodeMore = tmpGeocodeObj.AddressDetails;

     //返回开始点的国家名称

        var CountryNameStr = tmpGeocodeMore.Country.CountryNameCode;

        //返回开始点的地名

     var LocalName = tmpGeocodeMore.Country.AdministrativeArea.Locality.Locality Name;

            alert(LocalName + ' ,' + CountryNameStr);

}

代码执行后的效果如图4-65所示。

图4-65 路径返回

l getEndGeocode():返回路径的结束点的Geocode对象。关于Geocode对象的详细解释,请参见后面的段落。

JavaScript脚本代码请参见上面的getStartGeocode方法。

l getEndLatLng():返回查询路径的最后一个点的点位信息,返回值为GLatLng类型。
l getSummaryHtml():返回包含路径全长和时间的HTML片段。
l getDistance():返回路径全长,返回值为一个对象。
l getDuration():返回路径的总时间,返回值为一个对象。

4.表示某段路径的GStep类型

元素类型:类(Class)。

GStep查询路径返回后的Route的某一段。由于没有构造函数,所以无法直接创建该类对象,只有在路径查询的时候由GDirections 对象创建。

GStep方法介绍如下。

l getLatLng():取得本Step段的第一个点的点位坐标。
l getPolylineIndex():取得本Step段PolyLine线段的序号。
l getDescriptionHtml():取得本Step段的描述字符串。
l getDistance():取得本Step段的长度。
l getDuration():取得本Step段的耗时时长。

4.3.15 在地图上做广告

Google AdSense是著名的广告服务。通过Google提供的JavaScript脚本及Google的网页机器人,Google服务器将受到广告展示请求并且分析将要展示广告的页面,最终决定如何添加,以及添加的广告的内容。用户通过Google AdSense可以很方便地动态展示Google广告,并且可以提供终端用户网络搜索等服务。

在Google Maps中自然少不了大名鼎鼎的AdSense的踪迹,API提供了在地图中展现广告的方法,这种将地理空间信息与广告信息关联起来的方法比在传统的网页上做广告要巧妙。

1.广告管理类型GAdsManager

元素类型:类(Class)。

该类是在AdSense中抓取广告,并在地图上以地标(GMarker)的形式显示广告画面的。默认的情况下,广告是不显示的。

1)GAdsManager构造函数

GAdsManager构造函数如下:

var newADMgn = new GAdsManager(

     map: GMap2,

     publisherId: String,

     ADmgnOpts: Options);

GAdsManager构造函数参数如表4-22所示。

表4-22 GAdsManager构造函数参数

参    数

是 否 必 要

值 类 型

定    义

map

GMap2

GMap2实例对象

publisherId

String

发行者名称

ADmgnOpts

可选

Options

广告(AD)管理器选项

2)GAdsManager方法

GAdsManager方法介绍如下。

l enable():能够显示广告。在默认情况下,在地图中创建GadsManager对象后,还需要用该方法来激活GAdsManager对象。
l disable():不能显示广告。

2.GAdsManagerOptions类型

这个类型是GAdsManager构造函数的参数类型。

GAdsManagerOptions方法介绍如下。

l maxAdsOnMap:显示的最大广告数。
l channel:AdSense通道数目。
l minZoomLevel:要显示广告的最大缩放级别。默认的级别是6。

4.3.16 在Google上创建自己的地图类型

如同传统的第三方GIS方案一样,用户可以在购买GIS系统软件之后使用自己的地图数据,过去在类似于Google Maps这样的由软件公司和地图供应商提供地图服务(Map Service)的情况下,终端用户是无法用网页上的地图图框来显示自己的地图数据的。如果想要实现这种需求,一般需要满足以下任一个条件。

l 通过协议将GIS服务软件公司的地图服务器端软件安装在用户自己的企业服务器上。
l 通过GIS服务软件公司提供的API,将自己的地图数据嵌入到网页图框中。

Google Maps 提供了API,帮助用户实现这样的目标。

要在Google Maps中使用自己的地图数据,需要深刻理解地图的投影(Projection)、瓦片图层(Tile Layer)、地图类型(GMaptype)等重要概念,还需要有一定的地理学常识,下面逐一介绍。

1.定义地图种类的GMapType类型

元素类型:类(Class)。

GMapType地图类型,在GMaps的构造函数中使用。

GmapOptions类用于自定义地图类型。例如,用户自有的地图图像数据或者从第三方地图供应商那里得到的图像数据,需要通过Goolge Maps/Maps Mobile显示出来的特殊应用。此时用户自己的地图只要能满足Google对地图类型的定义,就可以将此地图作为新增的地图类型GMapType来使用。

目前最新版(3.0版)的Google Maps API定义了18种地图类型,这18种地图类型可以在Google Maps API的英文网站上查询到,中文网站上还是没更新前的2.9x版的16种,这18种地图类型如表4-23所示。

表4-23 地图类型

类型名称

功能描述

G_NORMAL_MAP

(默认)着色底图地图

(续表)

类型名称

功能描述

G_SATELLITE_MAP

显示卫星图像

G_HYBRID_MAP

覆盖主要街道层在卫星图像上的叠加地图

G_PHYSICAL_MAP

具有地理特征(如地形和植被)的地图。默认不显示(自2.94版开始)

G_MAPMAKER_NORMAL_MAP

通过MapMaker制作的普通着色地图

G_MAPMAKER_HYBRID_MAP

通过MapMaker制作的叠加地图

G_MOON_ELEVATION_MAP

显示月球表面具有彩色编码的高低阴影地形图。默认不显示(自2.95版开始)

G_MOON_VISIBLE_MAP

围绕月球轨道摄制的照片。默认不显示(自2.95版开始)

G_MARS_ELEVATION_MAP

显示火星表面具有彩色编码的高低阴影地形图。默认不显示(自2.95版开始)

G_MARS_VISIBLE_MAP

围绕火星轨道摄制的照片。默认不显示(自2.95版开始)

G_MARS_INFRARED_MAP

显示火星表面红外影像图,较热的地区以亮色显示,较冷的地区以暗色显示。 默认不显示(自2.95版开始)

G_SKY_VISIBLE_MAP

天体图。默认不显示(自2.95版开始)

G_SATELLITE_三维_MAP

Google Earth Plug插件。通过这个插件,用户可以把Google Earth插入到自己的网页中,成为一个地图类型。

如果之前用户没有安装过Google Earth Plug插件,当第一次运行的时候,浏览器会提示用户下载并安装。可以用GMap2.getEarthInstance()检查是否安装有GE插件,该插件实际就是Google Earth被封装后的组件,支持Google Earth API

G_DEFAULT_MAP_TYPES

前面3种地图类型组合数组(G_NORMAL_MAP、G_SATELLITE_MAP 和 G_HYBRID_MAP)

G_MOON_MAP_TYPES

前面两种月球类型组合数组(G_MOON_ELEVATION_MAP 和 G_MOON_VISIBLE _MAP)

G_MARS_MAP_TYPES

前面3种火星地图类型组合数组(G_MARS_ELEVATION_MAP、G_MARS_VISIBLE_ MAP 和 G_MARS_INFRARED_MAP)

G_SKY_MAP_TYPES

前面定义的天空地图类型数组 (G_SKY_VISIBLE_MAP)

G_MAPMAKER_MAP_TYPES

Google支持用户可以通过MapMaker来自行创建、修改、补充地图,这种服务目前针对3种地图类型,分别为G_MAPMAKER_NORMAL_MAP、G_SATELLITE_MAP和G_MAPMAKER_HYBRID_MAP类型

如果需要使用GMap2.addMapType()的方法来添加新的地图类型,如新加一个地图类型,则第一步应该从创建新地图类型GmapType对象开始。

1)新建一个地图类型对象

GMapType构造函数如下:

var newMapType = new GMapType(

     layerList: Array of GTileLayer,

     projection: GProjection,

     name: String,

     params: Options);

GMapType构造函数参数如表4-24所示。

4-24 GMapType构造函数参数

参    数

是 否 必 要

值 类 型

定    义

layerList

Array of GTileLayer

GTileLayer对象实例

projection

GProjection

GProjection对象实例

name

String

该Gmaptype的名称

params

可选

Options

选项参数

构造一个新地图类型对象需要注意前3个参数。第一个参数为GtileLayer的对象数组;一般通过脚本或者服务器端程序生成;第二个参数是投影Gprojection的对象,一般情况下用户可以采用Google地图的默认投影;第三个参数是需要用户去定义的新地图类型的名称,该名称在后面的代码中可以重新被定义,例如下面的例子:

……

var tmpMaptype = new GMapType([tmplay],

                      G_SATELLITE_MAP.getProjection(),

                      'test',

                      {errorMessage:'picture can not be loaded'});

……

function test()

{

          //在此定义新地图类型的其他属性,下文有详细讲解

}

……

构造函数的第一个和第二个参数的定义与使用,在后面的小节中会详细阐述。

2)GMapType方法

① getBoundsZoomLevel(bounds, viewSize)

根据输入的范围和视场大小返回地图缩放的级别。返回值类型为正整数型。

此处的bounds参数为GLatLngBounds类型值,需定义4个脚点坐标值,如下面的JavaScript的例子:

……//参照上文代码

function test()

    {

          var bounds = map.getBounds();

          var southWest = bounds.getSouthWest();

          var northEast = bounds.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 a = tmpMaptype.getBoundsZoomLevel(rectBounds,200);

            alert(a);

    }

     ……

② getCopyrights(bounds, zoomLevel)

根据输入的范围和缩放级别,返回地图数据的Copyrights信息。返回值类型为字符型数组。

③ getErrorMessage()

当地图瓦片不显示的时候,返回错误信息。返回值类型为字符串型。

JavaScript脚本代码实例如下:

……

tmpMaptype = new GMapType([tmplay],

          G_SATELLITE_MAP.getProjection(),

          'test',

          {errorMessage:'picture can not be loaded'});

……

alert(tmpMaptype.getErrorMessage());

……

上面的代码中定义了错误出现的字符串信息,当不能创建地图类型对象的时候报错。对比下图的提示信息,代码执行后的效果如图4-66所示。

图4-66 错误信息

④ getLinkColor()

根据超链接放置的位置,计算当前地图区域的颜色,确定目前超链接最好用什么样的颜色覆盖在地图上最醒目。

JavaScript脚本代码实例如下:

     ……

       alert(tmpMaptype.getLinkColor());

⑤ getMaximumResolution(latlng)

返回包含某个点位的当前地图类型最大缩放级别。

⑥ getMinimumResolution(latlng)

返回包含某个点位的当前地图类型最小缩放级别。

⑦ getName(opt_short)

取得GMapTypeControl定义的地图类型的名称,即地图切换按钮上的地图名称。

⑧ getProjection()

取得当前地图类型的投影。

⑨ getSpanZoomLevel(center,span,viewSize)

通过中心点位、视场大小及对应的级别跨度,取得当前地图类型的对应跨度的缩放级别。

⑩ getTextColor()

根据文本放置的位置,计算当前地图区域的颜色,确定目前文本最好用什么样的颜色覆盖在地图上最醒目。

getTileLayers()

表示获得瓦片数组。

getTileSize()

表示获得瓦片的尺寸。

getUrlArg()

返回一个URL参数,该参数用于传递给地图以确定当前应该使用某种地图的类型。

GMapType的使用,网上有许多例子,主要需要解决的地方是瓦片图的排列编码和投影问题,以下是JavaScript脚本编写的简单小例子:

……

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

         tmpMaptype.getCopyright = function(a,b,c)

         {

            return "tmpMaptype";

         }

          //将地图类型加入到当前的Google Msps地图中

         map.addMapType(tmpMaptype);

         map.addControl(new GMapTypeControl());

        

         var targetSource = map.addMapType;

     }

3)地图类型常量

地图类型常量如下:

G_NORMAL_MAP

① 普通矢量底图的地图,就是通常所见的彩色绘制的地图,这种地图的底图在服务器端通常以矢量文件的格式存在,而传到客户端的都是合成转换过后的图片,如图4-67所示。

图4-67 彩色图

地图因为是手绘的,所以会有各种颜色的配色,而且这种配色基本是根据地图绘图学的配色标准绘制的,所以都比较正式和醒目。

注意

上图中的【Map】按钮为“矢量底图的地图”,【Satellite】按钮为“卫星底图的地图”,【Hybrid】按钮为“矢量图、卫星图叠加图”,【test】按钮为自定义的例子地图类型,下同。

② G_SATELLITE_MAP

卫星底图的地图,就是通常见到的航测照片,如图4-68所示。

③ G_HYBRID_MAP

这种地图Google Maps做了处理,将矢量图、卫星图叠加成图。就是利用卫星图片作为底图,而将某些地图突出显示,从而形成某种专题地图。如图4-69所示,在卫星底图上绘制了公路的彩色线条,用以突出显示。

       

               图4-68 卫星图                                  图4-69 混合图

④ G_DEFAULT_MAP_TYPES

返回以上3种地图类型的数组。

2.地图类型的参数类型GMapTypeOptions

该类是GMaptype构造函数中的选项参数类型。

GMapTypeOptions的属性如下。

l alt:设置GMapType的备选文档,通过GMapType.getAlt()可以得到,返回值类型为String,默认值为空字符串。
l errorMessage:设置GMapType错误信息。通过GMapType.getErrorMessage()可以得到,返回值类型为String类型,默认值为空字符。
l linkColor:设置超链接文本的颜色,通过GMapType.getLinkColor()可以得到,返回值类型为String类型,默认值是#7777cc。
l maxResolution:表示当前图中的最大缩放级别,设置该GMapType最大缩放级别,通过GMapType.getMaximumResolution()可以得到,值类型为Number数值型。
l minResolution:表示当前图中的最小缩放级别。设置该GMapType最小缩放级别,通过GMapType.getMinimumResolution()可以得到,值类型为Number数值型。
l shortName:表示GMapType名称,通过GMapType.getName(true)可以得到,值类型为String类型。
l textColor:设置文本颜色,通过GMapType.getTextColor()可以得到,值类型为String类型,默认值为black。
l tileSize:设置该GMapType中瓦片图的尺寸,通过GMapType.getTileSize()可以得到,值类型为Number类型,默认值为256。
l urlArg:设置该GMapType的主题,通过GMapType.getUrlArg()可以得到,值类型为String类型,默认为空字符串。

3.瓦片图层GTileLayer类型

元素类型:接口(Interface)。

瓦片层指用户可以使用这个接口实现在Google Maps的框架内显示自己的地图。

1)GTileLayer构造函数

GTileLayer构造函数如下:

var TileLyrObj = new GTileLayer(

     copyrights: Array of GCopyright,

     minZoomLevel: Int,

     maxZoomLevel: Int);

GTileLayer构造函数参数如表4-25所示。

表4-25 GTileLayer构造函数参数

参    数

是 否 必 要

值 类 型

定    义

copyrights

Array of GCopyright

GCopyright对象的数组

minZoomLevel

Int

显示Copyright信息的最小缩放级别

maxZoomLevel

Int

显示Copyright信息的最大缩放级别

2)GTileLayer方法

GTileLayer方法介绍如下。

l minResolution():返回当前地图类型的最小缩放值。
l maxResolution():返回当前地图类型的最大缩放值。
l getTileUrl(tile, zoom):取得某一个缩放级别下面瓦片图的URL地址。这是个抽象函数,tile在这指有坐标值的瓦片点位,并非是瓦片本身,通过该函数可以将自己的地图“插入”到Google Maps中。但插入自己的地图需要一些条件,如瓦片图的大小尺寸、比例、缩放级别和Google Maps的对应关系,而且需要自己编写对应的瓦片编排逻辑代码。
l isPng():主要是为了判断瓦片是否可以透明化,默认是GIF格式。如果图片是PNG格式返回true,不是PNG格式则返回false。
l getOpacity():获得瓦片图的透明度,如果返回1.0就是完全透明的,0.0则是不透明的。

4.地图投影GProjection类型

“所谓地图投影,简略地说就是将椭球面各元素(包括坐标、方向和长度)按一定的数学法则投影到平面上”(摘录自孔祥元、梅是义《控制测量学》)。此处,投影平面就是指计算机屏幕上的地图窗口。从椭球面上的大地坐标投影到投影面的对应关系,有专门的数学解析公式,在此不深入探讨,读者可以自行参阅相关资料。

Google Maps采用的是基于WGS84参考椭球的球形墨卡托Spherical Mercator投影(EPSG:900913或者EPSG:3857),将地球视为一个球体,而非通常WGS84椭球体。

元素类型为接口(Interface)。通过这个接口,可以定义地图的投影。

1)GProjection地图类型方法

GProjection地图类型方法如下。

l fromLatLngToPixel(latlng,zoom):地图的地理经纬度坐标转换成屏幕像素坐标,返回值为GPoint点。
l fromPixelToLatLng(pixel, zoom, unbounded) :屏幕像素坐标转换成地图的地理经纬度坐标,返回值为GLatLng。
l tileCheckRange(tile, zoom, tilesize) :检查在当前的地图类型下,瓦片的序号是否在有效的范围内,该范围是地图类型对象GMaptype在构建的时候确定的,只有在当前的序号范围内的瓦片才能被正常显示。
l getWrapWidth(zoom):获取地图循环显示的宽度,如在低缩放级别下,Google Maps的地图是“循环”的,也就是在X轴的方向上循环。在默认的情况下,通常返回“Infinity”,表示无限大。

地图循环显示如图4-70所示。

循环

图4-70 地图循环显示

2)代码实例

关于地图投影的一个代码实例如下:

<!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 map;

     //创建并初始化地图对象

      function load() {

      var mydiv;

      if (GBrowserIsCompatible()) {

        map = new GMap2(document.getElementById("map"));

        map.setCenter(new GLatLng(52.93, -76.389), 6);

        map.addControl(new GLargeMapControl());

          }

     }

    

    //从自定义投影获得屏幕点的经纬度

     function getPointFromLatLng()

     {

          var myProjection = new GProjection();

          //重定义fromLatLngToPixel方法

          myProjection.fromLatLngToPixel = function(latLng,zoomIndex)

          {

               var GeoVar_x = 1.00406024095420839*map.getCenter().lat();

               var GeoVar_y = 1.00080019032010225*map.getCenter().lng();

               var tmp = map.getCurrentMapType().getProjection().fromLatLngToPixel(

new GLatLng(GeoVar_x,GeoVar_y),zoomIndex);

               return new GPoint(tmp.x,tmp.y);

             }

            var xy= myProjection.fromLatLngToPixel(map.getCenter(),6);

          alert(xy.x + ',' + xy.y);

     }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 300px; height: 230px"></div>

     <input id="clickbtn" type="button" value="得到投影后的中心点" onclick="getPoint FromLatLng();">

</body>

</html>

3)代码分析

这段代码是关于得到投影中心点的代码。按钮【得到投影后的中心点】的单击事件为getPointFromLatLng函数,代码中该函数首先取得了地图的中心点经纬度,通过当前地图的投影换算出中心点经纬度的屏幕坐标。代码中定义了两个坐标变形量,x坐标变形量为1.00406024095420839,y坐标变形量为1.00080019032010225,最后把变形量与真实坐标数值相乘,得出变形后的屏幕坐标值:(4713,5326),如图4-71所示。

图4-71 投影后的中心点

本例中,当前默认地图投影下的中心点经纬度对应点的屏幕坐标为(4715,5342)。

5.墨卡托投影GMercatorProjection类型

元素类型:类(Class)。

上一个问题提到了Google Maps采用的是基于WGS84参考椭球的球形墨卡托Spherical Mercator投影(EPSG:900913或者EPSG:3857),将地球视为一个球体,而非通常WGS84椭球体。

通过这个类可以很快创建一个墨卡托投影对象。墨卡托投影是等角圆柱投影的一种,是荷兰的地理学家Mercator于1569年创立的。这个投影假设有一个同轴的圆柱体切割于地球,对地球进行等角度投影,将圆柱展开成平面后,得到的地图是经纬线平直并且相互垂直的。在任何一点上任何方向的长度比均相等,没有角度变形,而面积变形显著,纬度越高变形愈大。墨卡托投影主要用于航海图和航空图。

1)GMercatorProjection构造函数

GMercatorProjection构造函数如下:

var MercatorProjectionObj = new GMercatorProjection(

     zoomlevel: Int);

2)GMercatorProjection地图类型方法

GMercatorProjection地图类型方法介绍如下。

l fromLatLngToPixel(latlng, zoom):地图的地理经纬度坐标转换成屏幕像素坐标,返回值为GPoint点。
l fromPixelToLatLng(pixel, zoom, unbounded):屏幕像素坐标转换成地图的地理经纬度坐标,返回值为GLatLng。
l tileCheckRange(tile, zoom, tilesize):检查在当前的地图类型下,瓦片的序号是否在适合的范围内。该范围是由地图类型确定的,只有在当前的序号范围内的瓦片才能被正常显示。
l getWrapWidth(zoom):与GProjection中的方法返回结果不同的是,在墨卡托投影上,经度方向不同。

6.自己的版权信息GCopyright类型

GCopyright包含了用户自定义的地图类型的copyright信息。对应于构造函数内部的bounds参数,该参数为GLatLngBounds类型,指定了在bounds包含范围的内部,地图数据的copyright信息是由用户自己定义的。

1)GCopyright构造函数

GCopyright构造函数如下:

var CopyrightObj = new GCopyright(

     id: String,

     bounds: GLatLngBounds,

     minZoom: Int,

     text: String);

GCopyright构造函数参数如表4-26所示。

表4-26 GCopyright构造函数参数

参    数

是 否 必 要

值 类 型

定    义

id

GLatLng 数组

顶点集合

bounds

可选

String

边线颜色

minZoom

可选

Int

边线宽度

Text

可选

0~1之间的小数

边线透明度

2)GCopyright属性

GCopyright属性如表4-27所示。

表4-27 GCopyright属性

属    性

类    型

定    义

id

Int

copyright对象的ID号

bounds

GLatLngBounds

显示copyright信息的区域

minZoom

Int

该copyright信息显示的最小缩放级别

text

String

copyright信息的显示文本

7.GCopyrightCollection

元素类型:类(Class)。

该类用于在用户自己的地图上显示copyright信息。特别是在Google Maps的框架内显示第三方地图数据的时候,此时需要使用GCopyrightCollection来声明copyright的信息。

1)GCopyrightCollection方法

GCopyrightCollection方法如下。

l addCopyright(copyright):往GCopyrightCollection对象中添加一个GCopyRight对象。
l getCopyrights(bounds, zoom):根据给定的边框范围和缩放级别,返回Copyright字符串。
l getCopyrightNotice(bounds, zoom):根据给定的边框范围和缩放级别,返回包括前缀在内的copyright信息。

2)GCopyrightCollection事件

newcopyright:当往Copyright序列中添加一个copyright对象的时候,触发此事件。

4.3.17 地址解析

1.Geocode对象

GPS的功能主要是获得某个地点的经纬度。但是如果只知道经纬度,也无法知道该经纬度的地点实际所在的区域名称、街道名称等信息。另一方面,在一个城市中如果只知道一条街道的地址名称,普通用户是无法轻易地从一张旅游图中知道经纬度信息的,此时就需要一种能够将地址信息和经纬度对应联系起来的技术,这种技术就是Geocode。

Geocode即地理编码,有很多种实现的方法,不同的地理信息系统、地理服务公司有不同的解决方案,例如ArcGIS、Google Maps都有各自的实现方式。在使用Google Maps的时候,用户只需要输入想要查询的地址,即可定位到所在位置的地图,这一过程就是Geocode在起作用。

Google Maps API中,在前2.5X版本中没有提供Geocode操作类型,但是开发者在实际运用过程中常会涉及到Geocode对象,通过第三方的开发工具中提供的对象查看器可以看到如图4-72所示的Geocode对象的结构图。

图4-72 树状结构

2.Geocode类型

最新一版的API中提供了3个有关Geocode的类型,分别是GClientGeocoder类、GGeocodeCache类、GFactualGeocodeCache类,同时也可以通过HTTP请求来连接Google地理服务器,以解析多个地址编码。

1)GClientGeocoder类

用于在客户端获取用户输入的地址,然后连接Google服务器的地址解析服务。同时GClientGeocode还可以在客户端建立地址解析缓存,这样就无须对相同的解析请求重复连接服务器了。

① GClientGeocoder构造函数

GClientGeocoder构造函数如下:

var newClientGeocoder = new GClientGeocoder(

     GeocoderCache:GeocoderCache);

GClientGeocoder构造函数参数如表4-28所示。

表4-28 GClientGeocoder构造函数参数

参    数

是 否 必 要

值 类 型

定    义

GeocoderCache

cache

Geocoder自己的缓存

② GClientGeocoder方法

GClientGeocoder方法介绍如下。

(1)getLatLng(addresstxt:String, callback:function)

连接服务器对客户端传递的地址进行解析,如果解析成功则利用返回值来调用callback回调函数。callback回调函数可以传递一个null值的Gpoint类型参数,例如:

<!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 map;

        //初始化地图

      function load() {

      var mydiv;

      if (GBrowserIsCompatible()) {

          map = new GMap2(document.getElementById("map"));

          //首先可以看到整个北美洲的概貌(如图4-73所示)

          map.setCenter(new GLatLng(52.93, -76.389), 2);

          map.addControl(new GLargeMapControl());

             }

          }

          function showAddress()

          {

          var myaddress = document.getElementById("txt").value;

          var geocoder = new GClientGeocoder();

          //利用返回值调用回调函数

          geocoder.getLatLng(myaddress,function(point){

               if (!point) {

                alert("无法解析:" + myaddress);

              } else {

               //如果找到地址对应的经纬度,则以此点为中心点,放大到13级(如图4-74所示)

                  map.setCenter(point, 13);

                  var mymarker = new GMarker(point);

                  map.addOverlay(mymarker);

                  marker.openInfoWindowHtml(myaddress);

              }

           });

          }

    </script>

</head>

<body onload="load()" >

     <div id="map" style="width: 260px; height: 200px"></div>

     <input id="btn_click" type="button" value="解析地址" onclick="javascript:show Address();">

     <input id="txt" type="text">

</body>

</html>

这段代码来源于Google官方中文网站。这个例子很有用,在日常网站建设项目中经常遇到,不管是显性的给用户提供地址分析的服务,还是非显性的只提供网站所有者显示自己所在的位置。

代码中的txt为地址输入框,btn_click为解析地址的按钮。调用showAddress函数,其中回调函数有一个function参数,传递的point起初为null值,在解析了地址之后,返回值会填充point。最后通过setCenter将地图缩放移动到返回值经纬度坐标处,再加上一个红色地标,如图4-73和图4-74所示。请对比下面这两幅图的前后在缩放级别和地标图表上的不同。

            

           图4-73 几乎包含整个北美                    图4-74 放大级别调整到13级后

(2)getLocations(LatLngObj:GLatLng, callback:function)

相对上面的getLatLng方法,这个方法是通过经纬度逆向取得地址的方法的,如果成功则利用返回的地址调用回调函数。

与getLatLng的功能所不同的是,getLocations能够获得一个完整的包括错误信息的结果,而不仅仅是GLatLng点位值。所以getLocations能够对解释失败的GGeoStatusCode代码编写相应的处理过程。

该方法的调用过程与前面的getLatLng方法类似,将下列函数加入getLatLng示例代码的页面中即可:

          function getAddress(overlay, latlng)

          {

          //var myaddress = document.getElementById("txtlatlng").value;

          var geocoder = new GClientGeocoder();

          if (latlng != null) {

              address = latlng;

              geocoder.getLocations(latlng, function(response){

                 var place = response.Placemark[0];

                 alert(place.address );

              });

          }

          }

鼠标移动到中国台湾省台北市的某个位置,单击后返回“100台湾台北市中正區水源快速道路”字样,这就是图中鼠标所在位置的地址,如图4-75所示。

图4-75 反向获得地址

以下代码为另外一个getLocations的典型例子:

var map;

     function setupMap()

     {

          if (GBrowserIsCompatible())

          {

               map = new GMap2(document.getElementById("map1"));

               map.addControl(new GLargeMapControl());

               map.setCenter(new GLatLng(31.7,131.2), 10);

          }

          var address = "1 Walker Street, New York";

          geocoder = new GClientGeocoder();

          geocoder.getLocations(address, addMarkFun);

     }

     function addMarkFun()

     {

          ……

     }

在上面的代码中,首先创建地图,然后定义了一个名为“1 Walker Street, New York”的地址(需要注意的是并非所有的地址Google Maps都可以解析,需要找一个Google Maps可以解析的)。接着代码创建了地理编码解析的客户端对象geocoder,最终解析之。

通常情况下解析好地理信息之后,我们可以加标一个点,来显示地址解析后的空间位置,所以函数addMarkFun是一个根据解析好的经纬度位置,加地标点的回调函数。

代码执行后的效果如图4-76所示。

图4-76 解析后的位置

(3)getCache()

返回当前的地址解析缓存。关于地址解析缓存,请参见下一个问题GgeocodeCache类型,下同。

(4)setCache(cacheObj:GGeocodeCache)

设置当前的地址解析缓存,也可以设置为null,表示禁止客户端使用缓存。

(5)getViewport()

将Geocode地址解析的视点改变到bounds描述的范围。请参考下列代码:

function MapSetViewClick()

{

     var bounds = map.getBounds();

        var southWest = bounds.getSouthWest();

        var northEast = bounds.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));

        //将视场切换到地址缓存中reecBounds定义的范围

        geocoder.setViewport(rectBounds);

}

(6)setBaseCountryCode(countryCode:string)

设置Geocoder默认的国家代码,使得搜索区域具有针对性。Google Maps官方提示这个国家代码的格式规则需要符合ISO 3166-1国际标准。

说明

ISO 3166-1是关于国家代码的一个标准,于1974年首次颁布,目前最新的标准是ISO 3166-3代码集。读者可以在ISO的官方网站上查看关于ISO 3166的最新技术标准文档:

http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=24591

关于国家代码,可以登录http://en.wikipedia.org/wiki/CcTLD参考,在本书的附录A中也给出了中英文对照的CcTLD国家代码与国名对应表。

(7)getBaseCountryCode()

得到国家/地区代码,若没有有效的代码,则返回null。

(8)reset()

重置地址解析。在GGeocodeCache类构建对象之时被调用。

2)GGeocodeCache类

该类是地址解析的缓存类型。在GClientGeocoder类型的讲解中,提及了有关地址解析缓存的概念,有了GGeocodeCache无须每次在解析地址的时候都连接服务器一次,本地浏览器首先检查地址解析缓存中当前查询点的缓存地图,如果有,则直接在缓存中获取。

GGeocodeCache类有一个构造函数和5个方法。

① GGeocodeCache构造函数

GGeocodeCache构造函数如下:

          var GgeocodeCacheObj = new GgeocodeCache();

② GGeocodeCache方法

GGeocodeCache方法介绍如下。

l get(address:string):在缓存中取得address对应的解析回答(reply),如果没有回答,则返回null值。
l isCachable(GeoCodingreply): 如果当前地址解析过后的信息可以被缓存,返回true,否则返回false。返回类型为布尔型。
l put(address,GeoCodingreply):将当前的地址和解析过后的返回信息都保存在缓存里,和get(address)是对应关系。
l reset():重置客户端的Geocode缓存,创建GGeocodeCache类之后将随即调用GGeocodeCache.reset()方法。
l toCanonical(address:string) :将参数address变成规范的地址。Google 地图中规范的模式如下。

Ø 字母全部小写。

Ø 空格替代逗号。

Ø 一个空格替代多个空格。

3)GFactualGeocodeCache类

元素类型:类(Class)。

Geocode缓存类,用于缓存地址解析后对应的地图信息,与GGeocodeCache类似。不同的是,GFactualGeocodeCache保存的是那些短期内不会发生变化的解析信息。

① GFactualGeocodeCache构造函数

GFactualGeocodeCache构造函数如下:

var newFactualGeocodeCache = new GFactualGeocodeCache ();

② GFactualGeocodeCache方法

isCachable(GeoCodingreply):判断该地址解析的信息是否可以被缓存。

这个方法与GGeocodeCache类中的isCachable方法的区别是:GfactualGeocode Cache.is Cachable对被缓存的解析信息要求更为严格,需要解析信息后地图的Geocoder返回的状态值为G_GEO_SUCCESS;而GGeocodeCache.isCachable只要解析信息不为null就可以了。

③ GGeoStatusCode

元素类型:枚举(Enumerate)。

GGeoStatusCode为Google Maps的Geocoder当前状态值。

枚举项名称与数字的对应关系如表4-29所示。

表4-29 状态类型号码

枚 举 项 名 称

数    字

枚 举 项 名 称

数    字

G_GEO_SUCCESS

200

G_GEO_UNKNOWN_ADDRESS

602

G_GEO_BAD_REQUEST

400

G_GEO_UNAVAILABLE_ADDRESS

603

G_GEO_SERVER_ERROR

500

G_GEO_UNKNOWN_DIRECTIONS

604

G_GEO_MISSING_QUERY

601

G_GEO_BAD_KEY

610

G_GEO_MISSING_ADDRESS

601

G_GEO_TOO_MANY_QUERIES

620

枚举项解释如下。

l G_GEO_SUCCESS:标志着没有错误发生,Google Maps官方的解释还提及了地址成功地被Geocode解析。
l G_GEO_BAD_REQUEST:方向请求没能被成功解析。
l G_GEO_SERVER_ERROR:方向请求或者地址请求没有被成功解析执行。
l G_GEO_MISSING_QUERY:方向请求或者地址请求丢失,没有被响应。
l G_GEO_MISSING_ADDRESS:解释同上。
l G_GEO_UNKNOWN_ADDRESS:对地址进行Geocode解释的时候,没有发现对应的地理位置坐标。
l G_GEO_UNAVAILABLE_ADDRESS:地址编码格式不合法。
l G_GEO_UNKNOWN_DIRECTIONS:方向编码格式不合法。
l G_GEO_BAD_KEY:Google Maps所对应的Key不正确。
l G_GEO_TOO_MANY_QUERIES:访问请求,超过了Key所对应的访问量。

④ GGeoAddressAccuracy

元素类型:枚举(Enumerate)。

GGeoAddressAccuracy反映了地址的精确程度,枚举值和定义解释如表4-30所示。

表4-30 枚兴值和定义解释

枚 举 值

定    义

0

无法解析的地址

1

能达到国家范围这一级别的精度

2

能达到省(州)范围级别的精度

3

能达到市、县范围级别的精度

4

能达到乡、镇范围级别的精度

5

能达到邮政编码一级的精度,对应中国就是区范围一级的精度

6

能达到街道范围一级的精度

7

能达到街、巷一级的精度

8

能达到对应具体地址的精度

9

能达到建筑物级别的精度

4.3.18 通过API操作网页页面元素

通过Google Maps API提供的GDraggableObject类型,用户可以操作页面DOM元素。例如Div,可以拖动它。这是个非常明智且有效的方法,在项目研发中能解决很多诸如鼠标拖动某个图标之类的需求。

1.GDraggableObject构造函数

GDraggableObject构造函数如下:

var newDragObj = new GDraggableObject(

     DOMEle: DOM,

     opts:opts);

GDraggableObject构造函数参数如表4-31所示。

表4-31 GDraggableObject 构造函数参数

参    数

是 否 必 要

值 类 型

定    义

DOMEle

DOM元素

HTML网页上的DOM元素

opts

可选

<选项>

几种选项,具体见下表

opts是GDraggableObjectOptions类型,该类型的详细属性选项请参见表4-32。

表4-32 GDraggableObjectOptions属性表

参    数

类    型

定    义

container

DOM元素

存放可拖动对象的DOM容器

delayDrag

Boolean

延迟拖动,直到鼠标离开按下的地方才开始拖动执行。默认为false

draggableCursor

String

对象成为可以被拖动状态时显示的光标

draggingCursor

String

拖动时显示的光标

left

Number

对象的左边距

top

Number

对象的上边距

2.GDraggableObject静态方法

GDraggableObject静态方法如下。

l setDraggableCursor(string):设置鼠标移动到后面创建的可拖动对象上方时的光标。
l setDraggingCursor(string):设置鼠标移动到后面创建的对象时的光标。

3.GDraggableObject方法

GDraggableObject方法如下。

l setDraggableCursor(string):设置鼠标移动到可拖动对象上方时的光标。
l setDraggingCursor(string):设置拖动对象时的光标。

4.代码实例

GDraggableObject的代码实例如下:

<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>

    var objIcon = 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), 10);

      }

    }

     //创建可拖动对象,并且设置相关的鼠标状态

    function ButDragable_onclick() {

        var mm = document.getElementById("rect");

        var dragdom = new GDraggableObject(mm);

        dragdom.setDraggableCursor('hand');

        dragdom.setDraggingCursor('move');

    }

    </script>

</head>

<body onload="load();">

<table>

    <tr>

         <td>

              <div id="map" style="width: 500px; height: 300px"></div>

         </td>

    </tr>

  <tr>

         <td>

              <div id="rect" style="width: 70px; height: 70px; background-color:Green; "></div>

         </td>

    </tr>

</table>

      <input id="ButDragable" type="button" value="开始拖动" onclick="return ButDragable _onclick()" />

</body>

</html>

5.代码分析

首先基于名为“map”的div创建地图对象,并且定义了地图工具和地图中心点位置。

页面文档中定义了名为“rect”的方块,背景色为了区别于地图,用了实心绿色。JavaScript脚本函数ButDragable_onclick实现了创建可拖动对象“dragdom”,并且定义了鼠标在移到“dragdom”上时变成hand型图标,在移动的过程中变成move型图标。

代码执行后的效果如图4-77所示,这幅图表现了正在拖动过程中的样子。

图4-77 移动的方块

6.GDraggableObject事件

GDraggableObject事件如下。

l mousedown:当在要移动的DOM元素上鼠标按下时触发此事件。
l mouseup:当在要移动的DOM元素上鼠标弹起时触发此事件。
l click:当在要移动的DOM元素单击的时候触发此事件。
l dragstart:当DOM元素刚刚开始被移动的时候触发此事件。
l drag:当DOM元素在移动过程中触发此事件,该事件在移动过程中不断循环地被触发。
l Dragend:当移动DOM元素结束的时候触发此事件。

posted on 2010-07-20 23:19  hai  阅读(2229)  评论(0)    收藏  举报