? 公司用到了google maps,定位各个酒店在地图中位置。今天做一个简单的总结,关键是记下不同于Demo级别的在地图上加上几个经纬度图标完事的几个细节的处理。
??? 值得注意的需求是地图级别的设置,既要在可见区域包含所有的point,又要将地图缩进在最佳视觉状态(用直白的语言描述,地图可见范围内包含所有酒店的位置图标,并且可见地图区域的放大级别是最合适的)。
? 开始的时候并没有深入去看google map api,后来才发现
getBoundsZoomLevel(bounds) | Number | Returns the zoom level at which the given rectangular region fits in the map view. The zoom level is computed for the currently selected map type. If no map type is selected yet, the first on the list of map types is used. |
就可以满足这个需求。
?
?显示各酒店在地图中位置,由于酒店数据过多采用分页显示,每页显示10个,所以地图上每次最多只会有10个图标标注各酒店位置。
实现整个功能的逻辑是:
1.创建地图,实例化GMap2。如果仅实现上面的功能,用一个自定义类来实现的话,那么这个map所需的属性有:
mapDiv, (map的contener,一般是一个Div)
map,
bounds,
mapOverlays
?
那么这个类可以这么定义:
UI.Map = Class.create({ initialize: function(mapid) { this.mapDiv = $(mapid); this.map = null; this.bounds = null; this.mapOverlays = new Array(); }, addPoint: function(item) { var latLon = new GLatLng(item.lat, item.lon); var overlay = this._createMarker(latLon, this.map); this.map.addOverlay(overlay); this.mapOverlays.push(overlay); this.bounds.extend(latLon); if(this.mapOverlays.length > 1) { this.map.setZoom(this.map.getBoundsZoomLevel(this.bounds)); this.map.setCenter(this.bounds.getCenter()); } else { this.map.setCenter(latLon); } }, clear: function(p) { if(this.map == null) { this.show(); } this.map.closeInfoWindow(); this.mapOverlays.each(function(item) { this.map.removeOverlay(item); }.bind(this)); this.mapOverlays = new Array(); this.bounds = new GLatLngBounds(); this.map.setZoom(12); }, show: function() { if (GBrowserIsCompatible()) { this.map = new GMap2(this.mapDiv); this.map.setCenter(new GLatLng(0, 0), 12); this.map.addControl(new GSmallZoomControl3D()); this.map.addControl(new GMapTypeControl()); this.map.enableContinuousZoom(); } }});
?
?
?
?
2.设置地图中心点(一定要在实例化GMap2后立刻设置一个中心点才可以用,否则地图会很怪异,呵,应该说显示的类似是世界地图蓝色海洋远观图)
3、设置地图的经纬度边界矩形。要用到GLatLngBounds.? google map api reference上面这么描述这个类:
A GLatLngBounds
instance represents a rectangle in geographical coordinates, including one that crosses the 180 degrees meridian.
?
GLatLngBounds(sw?, ne?) | Constructs a rectangle from the points at its south-west and north-east corners. |
4.向地图添加酒店的位置图标,也就是在各酒店的经纬度处创建一个图标。当然,从我们的数据库里可以拿到酒店的经纬度。关键就在这添加各酒店的经纬度的时候,除了将酒店的经纬度加上外,还需要做两件事:一、要重新设置map的中心点,map的中心点获取的方法是GLatLngBounds实例的getCenter()方法。二、要将地图可见区域扩充,用GLatLngBounds实例的extend方法。
extend(latlng) | none | Enlarges this rectangle such that it contains the given point. In longitude direction, it is enlarged in the smaller of the two possible ways. If both are equal, it is enlarged at the eastern boundary. |
?
将酒店所在的经纬度处创建图标则是:
var latLon = new GLatLng(o.lat, o.lon); var overlay =this.createMarker(latLon, letter,describe,mapurl,Map.map); Map.map.addOverlay(overlay);
?
createMarker方法也贴出来:
createMarker:function(point, letter,desc,urlName,map){ var baseIcon = new GIcon(); baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png"; baseIcon.iconSize = new GSize(20, 34); baseIcon.shadowSize = new GSize(37, 34); baseIcon.iconAnchor = new GPoint(9, 34); baseIcon.infoWindowAnchor = new GPoint(9, 2); baseIcon.infoShadowAnchor = new GPoint(18, 25); var icon=new GIcon(baseIcon); icon.image="/images/en/markers/markers"+letter+".png"; var marker = new GMarker(point, icon); GEvent.addListener(marker, "mouseover", function() { // marker.openInfoWindowHtml(desc); marker.openExtInfoWindow( map, "custom_info_window_red", desc, {beakOffset: 3} ); }); return marker; },
?
?map效果图: