http://logfei.blogspot.com/
使用地图API实现自定义叠加层
定制GoogleBar --谷歌地图的本地搜索栏
谷歌地图上的快捷键
说实话,之前我也没有注意过这一点,甚至都没有想过地图可以支持快捷键,一个以拖拽成名的应用,谁又能想到可以用快捷键来控制呢。
有一天无聊的上下翻动地图API的文档,突然发现一个很陌生的类,GKeyboardHandler,没见过!
仔细看了一下,居然是用来使地图支持键盘操作的,更有意思的是,这个类在文档顶部的类名列表中没有出现,不知道是整理文档的疏漏,还是因为这个类太小,小的连一个方法或者参数都没有,只有光秃秃一个类充作构造函数。也可能是这个类所支持的键盘操作有限吧,我把支持的键做了个列表:
键 | 动作 |
方向键 | 向对应的方向连续移动地图,同时按下邻近的两个会向对角移动 |
Home/End | 以3/4的幅度左右平移地图 ,动画效果 |
Page Up/Page Down | 以3/4的幅度上下平移地图,动画效果 |
+ / - | 放大/缩小一个级别的地图 |
只有地图的移动和缩放操作,特意到地图主页上试了试,支持,没有问题,只不过你需要先点击地图,使地图容器处于激活状态。用起来也不错,感觉地图的移动居然比鼠标拖动时还要平滑。
如果需要在你自己的地图上使用,只需要一句话:
new GKeyboardHandler(map);
够简单吧,呵呵,赶紧扔开你的鼠标到右边的地图上试试吧。
在谷歌地图主页上,有可以控制地图缩放的控件、有切换地图类型的控件、有显示缩略图的控件等等,这些控件在地图API里默认也都是提供的,所以,你可以在你的地图上加上这些控件,并且可以根据你的需要随意调整地图控件的位置、改变控件的外观,就像我在右边的地图上把缩放控件移到右上角而不是默认的左上角、并且使用了一个微型化的外观。下面先看看可以在地图上添加哪些控件吧。
地图API中默认控件的种类
1、地图缩放控件
缩放控件是可以控制地图移动和放大级别的,默认有三种:
1) 全功能控件 GLargeMapControl
有方向按钮、恢复按钮、缩放按钮和缩放滑块
2) 微型化控件 GSmallMapControl
把全功能控件去掉恢复按钮和缩放滑块后的控件
3) 微型缩放控件 GSmallZoomControl
只有放大/缩小两个按钮
下面从左到右依次是GLargeMapControl,GSmallMapControl,GSmallZoomControl这三个控件,选用哪一个就看你的空间有多大了。不过,我认为通过GMap2提供的设置项允许用户使用滚轮和双击缩放地图比使用一个大大的缩放控件更方便。
这几天谷歌地图主页刚刚换了新的缩放控件,有点类似于谷歌地球上哪个,不过使用API实现的还没有变,仍然是上面显示的这个样子。
2、地图类型选择控件
地图类型选择控件是用来选定所显示地图的类型的,比如普通地图、卫星地图、地形地图等等,也有三种,唉,突然想起孔乙己:)
1)按钮式标准控件 GMapTypeControl
每种地图类型对应一个按钮,点击不同的按钮切换地图类型,比如
2)菜单式控件 GMenuMapTypeControl
所有的地图类型使用一个下拉菜单来显示,选择菜单中的不同项来切换地图类型,比如
3)阶层式标准控件 GHierarchicalMapTypeControl
类似标准的按钮控件,不过在某些按钮下可以选择在该类型地图下的嵌套内容,比如卫星地图中还可以选择是否使用标签、即是否使用混合类型(Hybrid)的地图,如下:
这个控件目前在中文地图上没有什么作用,因为中文地图还不支持Hybrid类型的地图,也不能在地图上显示Panoramio的图片和Wikipedia的内容。
3、缩略图控件 GOverviewMapControl
在地图上显示一个比现有地图范围更大、但是尺寸要小得多的缩略图,默认位置在右下角,在该控件的右下角有一个箭头,点击可以收放这个控件,需要移动地图时你也可以直接拖动缩略图里的那个蓝框,会比你直接拖动地图要快一些。
4、比例尺控件 GScaleControl
显示当前地图的比例尺,所以上面的数值会随地图的缩放变化,这个控件不是特别引人注目
5、本地搜索控件 GoogleBar
上一篇介绍GMap2设置项的文章里把这个包括了进去,还是放在这里比较合适,是什么我就不多说了,看图
谷歌地图上常用的默认控件基本就这些了,你在我右边的地图里基本都能找到这些控件,想把这些控件加到你的地图上也不难,接着来看。
向地图上添加控件的方法
上面我已经给出了每个控件对应的类名,添加的步骤(以添加右边地图中的微型缩放控件为例):
1、重置控件的位置,如果你使用控件的默认位置,这一步就不需要了。一般情况下也确实不需要,只有在你的地图空间狭小,控件摆布不开的时候才会有,右边的地图就是这种情况。
GSmallMapControl.prototype.getDefaultPosition = function(){
return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 30));
}
注意G_ANCHOR_TOP_RIGHT和new GSize(10, 30)这两个参数,这个其实就决定了右边地图里微型缩放控件的位置,位于右上角(TOP_RIGHT),距地图右边距10px,上边距30px。
2、创建控件对象
var mapControl = new GSmallMapControl();
3、调用map.addControl()方法添加控件
map.addControl(mapControl);
怎么样,还没过瘾?API里提供的默认控件基本就这些了,如果你还想加上你自己设置的控件,比如右边地图上的状态控制,那就看看我之前介绍的 自定义地图控件的方法吧。
到这里为止,通过 指定GMapOptions、 设定地图设置项、添加默认控件,我们可以在不需要添加任何叠加层、信息窗口、事件侦听的情况下,就可以创建一个内容比较丰富的地图了。当然,等我介绍完本地搜索控件的定制方法,我们的地图内容会更丰富。
GMap2可以有哪些设置项
1、可以连续缩放
地图缩放的时候旧图块在新图块加载完成之前不会直接消失,图块的切换比较平滑,在网速较慢的时候这种效果会好一些。地图默认情况下不支持,建议打开这个功能。使用map.enableContinuousZoom() / map.disableContinuousZoom() 方法来切换。另外,需要的时候你可以使用map.continuousZoomEnabled()方法来探测一下地图是否支持连续缩放。
2、支持滚轮缩放
使用鼠标滚轮来实现地图缩放,默认也是不支持的,建议打开。使用map.enableScrollWheelZoom() / map.disableScrollWheelZoom() 方法来切换,使用map.scrollWheelZoomEnabled()方法来探测。
3、支持双击缩放
左键双击放大地图,默认也是不支持,建议打开。使用map.enableDoubleClickZoom() / map.disableDoubleClickZoom()方法切换,使用map.doubleClickZoomEnabled()方法探测。另外,右键双击缩小地图默认是支持的,没有发现地图API中有方法可以改变右键双击的属性。
4、支持地图拖动(默认)
按住左键拖动地图,默认是支持的。使用enableDragging/disableDragging方法切换,使用draggingEnabled() 方法探测。这个估计是个比较老的方法,因为在已经有静态地图API的情况下实在想不出来有什么理由不让地图可以拖动,除非你是想临时的禁止地图可拖动。
5、支持信息窗口(默认)
在需要的时候地图可以弹出一个泡状的东东,在里面显示信息,默认也是支持的。使用enableInfoWindow/disableInfoWindow 方法切换,使用infoWindowEnabled()方法探测。一般情况下,这个属性让它保持默认就好了,如果你只需要在地图上标注并且不允许任何信息窗口的弹出,或者想上一个地图拖动的属性一样,需要临时性的禁止。
6、添加搜索栏
把地图左下角的Logo换成一个带搜索框的控件,这样你就可以在你的地图中直接使用谷歌的数据源来支持用户搜索,定制好的话简直就可以当作一个微型的地图主页来用。这个是中文API中新增的功能,以前的文章中我提到使用GMapOptions中的googleBarOptions属性可以来定制这个控件的。这个在地图上默认是没有添加的,所以,如果你没有使用map.enableGoogleBar()方法来显式的声明加上搜索栏的话,googleBarOptions也是不会起作用的。添加搜索栏反向的禁用操作是map.disableGoogleBar()。
使用GMapOptions定制你的谷歌地图
var map = new GMap2(document.getElementById("mapContainer"));
简单的说,GMapOptions是你在new一个GMap2对象的时候,可以直接使用对象变量的形式作为可选参数传递给GMap2的构造函数,GMapOptions自己没有构造函数(地图API中类构造函数的可选参数多用这种形式来定义),比如:
var options = {size:GSize(400, 300), backgroundColor:"#FF0000"};
var map = new GMap2(document.getElementById("mapContainer"), options);
这里options就是一个GMapOptions,size、backgroundColor就是他的选项。
在GMapOptions中,我们可以定义以下这些属性来指定地图的某些特性:
1)size
默认情况下,你创建的地图大小就是你给定的地图容器的大小,所以,通常情况下,你需要显式的声明你的地图容器的width和height属性,否则,地图是不能正常显示的。但是,有了size这个可选属性后,你就多了一个选择了。你可以在创建地图的时候直接通过size这个属性指定地图的大小,而不需要听命于地图容器了,即使这个地图容器已经显示的定义了width和height的大小。当然,size属性对应的值是一个GSize类型的数据,比如,如果给定options={size:GSize(400, 300)},那么,你所创建的地图大小就是400×300的一个矩形块,而和你指定的容器大小无关,但是地图的左上角和地图容器的左上角还是重合的。
2)mapTypes
创建地图后,默认显示的地图类型是普通地图,如果要加上可以选择的卫星地图、地形地图等等其他类型的地图,可以使用GMap2.setMapType() 方法,但这样往往会罗列一堆的setMapType。GMapOptions提供了mapTypes这个可选项,通过一个数组就可以给地图加上多种支持类型,比如使用{mapTypes:[G_NORMAL_MAP,G_SATELLITE_MAP,G_PHYSICAL_MAP]},你的地图就拥有三种普通、卫星、地形三种类型了。mapTypes数组中的第一项是地图加载的默认类型,所以,如果你想默认加载卫星地图,把G_SATELLITE_MAP 移到数组的第一项就可以了。
3)draggableCursor、draggingCursor
这两个选项是用来定义地图上你的光标类型,我把它们放在一起介绍不等于它们必须一起使用,你可以单独使用任何一个。其中,draggableCursor 是地图可拖拽状态(默认就是可拖拽的)下的光标,draggingCursor是拖拽地图时的光标,对应的值和你在JavaScript里面设置其他的光标时使用的值一样,比如,{draggableCursor:"crosshair",draggingCursor:"move"}。当然,你也可以使用url形式加上你自己的图标,看你发挥了!
4) backgroundColor
在地图图块的图片还没有传送完成之前,地图的显示区域默认会使用灰色填充,这个就是backgroundColor可以发挥作用的地方了,你可以把灰色换成其他任何符合W3C标准的颜色,比如{backgroundColor:"#FF0000"},不过估计没人会喜欢用这种大红做背景的:)。可惜的是这里只能定义color,要是这个选项是background而不是backgroundColor,千方百计想打个Logo的兄弟就真能找着好地方了。
5) googleBarOptions
这个和你在地图上通过GMap2.enableGoogleBar()时有关系,指定你添加GoogleBar时的一些默认属性,在以后说GoogleBar的时候再来专门说吧,定制性还是很强的。
使用谷歌地图API实现自定义控件
使用谷歌地图API定义自定义的控件其实非常简单,看看我在右边地图的右上角添加的半透明的状态监控栏,这就是一个自定义的控件。
闲话少说,先看一段Hello World的代码
function MyControl(){}
MyControl.prototype = new GControl();
MyControl.prototype.initialize = function(map){
this.map = map;
var container = map.getContainer();
var label = document.createElement("div");
container.appendChild(label);
lable.innerHTML = "Hello World";
return label;
}
MyControl.prototype.getDefaultPosition = function(){
return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(50, 10));
}
上面这段代码中,MyControl就是一个自定义的控件了,在需要的时候,和添加其他默认控件一样,使用map.addControl(new MyControl())就可以在地图上添加这个自定义的控件了,只不过这个控件现在也没什么实际用处,就是在你的地图容器的顶部显示一个Hello World的文本,与地图没什么交互。
下面来详细解释一下这段代码:
第一行定义了一个MyControl类;
接下来,把这个类定义为GControl类的子类,就是把MyControl的prototype指定为GControl类的实例/对象;
后面的两个方法initiallize和getDefaultPosition是继承GControl类的时候必须实现的两个方法,API文档里定义GControl是接口类,所以可以把这两个方法认为是抽象方法,就不难理解为什么必须要实现了。需要注意的是,这两个方法我们只负责实现,但是不需要我们去显式的调用,在向地图上添加控件时API类库会自动调用这两个方法。
方法initialize接受一个参数map,就是你创建地图时new出来的GMap2对象。在这个方法中,你使用map.getContainer() 方法取得放置地图的DOM容器,然后,你就可以向这个DOM容器里添加任何你想加入的DOM元素了。在上面的示例中我创建了一个div元素,用来显示 Hello World,但是,你可以在这里加入任何你想添加的DOM元素,并且可以定义它们的行为,也就是说,这里就是你可以自由发挥的天地了,无论你是想显示动态的信息,还是来控制地图,比如右边地图里的状态监控栏。initialize方法最后需要返回你所创建的最外层的DOM元素,这个千万别忘了。
方法getDefaultPosition的作用是定义你的控件在地图容器里的位置,实现起来就更简单了,你可以直接把我这里的代码copy过去,改成你需要定位的地方就可以了。GControlPosition的第一个参数是你的控件的锚点,只能使用G_ANCHOR_TOP_LEFT、 G_ANCHOR_TOP_RIGHT、G_ANCHOR_BOTTOM_LEFT、G_ANCHOR_BOTTOM_RIGHT这四个代表上左、上右、下左、下右这四个角的常量,后一个参数使用GSize来定义你的控件距离地图容器边界的偏移量,第一个参数是横向偏移、第二个参数是纵向偏移。
到这里一个自定义的控件就完成了,没什么复杂的吧?刚才看到论坛里有朋友问怎么能把自己的LOGO和地图左下角Google的LOGO并排放在一起,看了自定义控件,你一定知道怎么做了吧。不过,千万别想用你的LOGO覆盖Google的LOGO哦,基本的版权意识咱们还是应该有的,就像你也希望别人能够尊重你的劳动成果一样