SuperMap自定义ScaleBar控件(转)
在SuperMap IS.NET 2008(5.3.0及以上版本)的控件中有一个名为ScaleBarControl的控件,功能是与地图控件(MapControl)联动,实现地图按预定比例尺缩放。不过使用后,发现有几个诟病(也许是偶水平较低):
- ScaleBar的小滑块(slider)很难通过控件的属性设置,让放大、缩小后的位置与背景的尺度条相匹配。
- ScaleBar按钮图片和配饰的位置都比较难控制,特别是会受页面其他CSS影响。
- 如果应用涉及多幅地图,必须在MapControl中逐个设置每幅地图的比例尺级别。
所以...... 咱们动手来自己打造一个Custom ScaleBar,哈哈~~ 先上张最终成果图:
呵呵,有点感觉吧。是不是比ScaleBar更强大啊!废话少说,一起来看看实现方式思路:
- 用DIV和Table在页面中构建ScaleBar
- 采用AjaxScripts方式,用javaScript完成ScaleBar功能,并适当做些封装
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml" >
- <head>
- <title>ScaleBar Demo</title>
- <script type="text/javascript" src="scripts/SuperMap.IS.Include.js"></script>
- <script type="text/javascript" src="scripts/Page.js"></script>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- </head>
- <!-- maybe we should put 'OnPageLoad' in jQuery $(document).ready() function -->
- <body onload="OnPageLoad('底图')" onunload="OnPageUnload()">
- <!-- MapControl -->
- <div id="myMap" style="width:744px; height:516px; overflow:hidden; margin:0;
- padding:0; position:absolute; left:137px; top:153px; border:solid 1px gray">
- </div>
- <!-- Scalebar slider -->
- <div id="mapSlider" style="position: absolute; width: 14px; height: 8px; z-index: 2; left: 170px; top: 245px">
- <img src="images/slider.png" style="width: 14px; height: 8px; border: 0px;" alt="" />
- </div>
- <!-- Scalebar button -->
- <div id="layer1" style="position: absolute; width: 54px; height: 225px; z-index: 1;
- left: 150px; top: 146px;">
- <table width="54" cellspacing="0" cellpadding="0" border="0" id="table1" style="position:relative; top:13px;">
- <tbody>
- <tr height="18">
- <td></td>
- <td width="18" colspan="3">
- <img style="width: 18px; height: 18px; border: 0px;" onclick="OnClickPan(4)" src="images/north.png" />
- </td>
- <td></td>
- </tr>
- <tr height="18">
- <td width="18" align="right">
- <img style="width: 18px; height: 18px; border: 0px;" onclick="OnClickPan(2)" src="images/west.png" />
- </td>
- <td width="18" align="center">
- <img style="width: 18px; height: 18px; border: 0px;" onclick="ViewEntire()" src="images/middle.png" />
- </td>
- <td width="18" align="left">
- <img style="width: 18px; height: 18px; border: 0px;" onclick="OnClickPan(1)" src="images/east.png" />
- </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <img height="18" width="18" border="0" style="" onclick="OnClickPan(3)" src="images/south.png" />
- </td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td>
- <img height="18" width="18" border="0" style="" onclick="OnClickZoomIn()" src="images/zoom-plus.png" />
- </td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td align="center">
- <img height="77" width="16" border="0" src="images/scalebar.gif" />
- </td>
- <td></td>
- </tr>
- <tr>
- <td></td>
- <td>
- <img height="18" width="18" border="0" style="" onclick="OnClickZoomOut()" src="images/zoom-minus.png" />
- </td>
- <td></td>
- </tr>
- </tbody>
- </table>
- </div>
- <div id="info">
- debug info</div>
- </body>
- </html>
Table的样式写法不是很好,没用css进行控制,大家有空改改吧。接着看对应的功能按钮实现:
- // 预设比例尺级别
- var ZoomLevels = 4;
- // scalebar slider.png距离scalebar.gif底部的像素距离
- var SliderStartAt = 298; //pixelTop value
- var SliderStepMove = 16; //pixel
- var map = null;
- var currentMapName="";
- //装载地图
- function OnPageLoad(mapName){
- if(map==null)
- {
- var params = new Object();
- params.mapHandler = "http://192.168.19.211/Web/"; //input your mapHandler
- params.mapName = mapName;
- currentMapName = mapName;
- params.mapScales = [1/6278912,1/3139456,1/1569728,1/784864];
- params.imageFormat = "gif";
- params.x = -1082645.1410411300;
- params.y = 2522135.1399492200;
- params.zoomLevel = 1;
- params.fixedView = false;
- params.buffer = 256; // 预先进行下载的视图范围。
- map = new SuperMap.IS.MapControl($("myMap"), params);
- map.Init();
- map.AttachEvent("onendzoom", RefreshSlider);
- //map.AttachEvent("onchangeview", UpdateInfo); for debug
- }
- else
- {
- map.Destroy();
- map = null;
- var params = new Object();
- params.mapHandler = "http://192.168.19.211/Web/";
- params.mapName = mapName;
- currentMapName = mapName;
- params.mapScales = [1/6278912,1/3139456,1/1569728,1/784864];
- params.imageFormat = "gif";
- params.x = -1082645.1410411300;
- params.y = 2522135.1399492200;
- params.zoomLevel = 1;
- params.fixedView = false;
- params.buffer = 256; // 预先进行下载的视图范围。
- map = new SuperMap.IS.MapControl($("myMap"), params);
- map.Init();
- map.AttachEvent("onendzoom", RefreshSlider); //绑定OnEndZoom事件,在缩放完毕后调用RefreshSlider方法
- }
- }
- //卸载地图
- function OnPageUnload()
- {
- map.Destroy();
- map = null;
- }
- //[ScaleBar Function]
- //Scalebar Event Handler
- function RefreshSlider(eventArg)
- {
- var zoomLevel = eventArg.param.zoomLevel;
- MoveSlider(zoomLevel);
- }
- // "+" Button to ZoomIn
- function OnClickZoomIn()
- {
- var mapLevel = map.GetZoomLevel();
- if(mapLevel < ZoomLevels + 1) // your map max level
- {
- mapLevel += 1;
- map.SetZoomLevel(mapLevel);
- MoveSlider(mapLevel);
- }
- }
- // "-" Button to ZoomOut
- function OnClickZoomOut()
- {
- var mapLevel = map.GetZoomLevel();
- if(mapLevel > 1)
- {
- mapLevel -= 1;
- map.SetZoomLevel(mapLevel);
- MoveSlider(mapLevel);
- }
- }
- //Move Slider when ZoomLevel change
- function MoveSlider(zoomlevel)
- {
- var mapSlider = document.getElementById("mapSlider");
- mapSlider.style.pixelTop = SliderStartAt - SliderStepMove * ( zoomlevel - 1 );
- }
- // East,West,South,North Pan Button
- function OnClickPan(tag)
- {
- var x = map.GetMapCenterX();
- var y = map.GetMapCenterY();
- switch(tag)
- {
- case 1://east
- x += 100000;
- map.PanToMapCoord(x, y);
- break;
- case 2://west
- x -= 100000;
- map.PanToMapCoord(x, y);
- break;
- case 3://south
- y -= 100000;
- map.PanToMapCoord(x, y);
- break;
- case 4://north
- y += 100000;
- map.PanToMapCoord(x, y);
- break;
- }
- }
- // View Entire Map
- function ViewEntire() {
- map.SetCenterAndZoom(-1187645.110411300,2372135.1399492200,0.00000016) // x, y, zoomlevel= 1/6278912 = 0.00000016
- }
- // Debug Info
- function UpdateInfo(eventArg)
- {
- var info = $("info");
- if (!info) { return false; }
- if(eventArg.param == null){
- info.innerHTML = '<font color="red">error: ' + eventArg.error + '</font>';
- return false;
- }
- info.innerHTML = 'mapName = ' + eventArg.param.mapName
- + ', zoomLevel=' + eventArg.param.zoomLevel
- + ', mapCenter = ' + eventArg.param.mapCenter.ToString()
- + ', pixelCenter = ' + eventArg.param.pixelCenter.ToString();
- }
代码中都尽量补充了一些注释,应该比较容易看懂。是不是很容易就搞定Custom ScaleBar啦,呵呵。也别高兴太早,剩下的还有几个问题待和大家一起解决和思考:
- ScaleBar的脚本是否应该从page.js中抽离,单独放入SuperMap.IS.CustomScaleBar.js中啊?方便继续完善。(大家可下载源代码,对比SuperMap.IS.CustomScaleControl.js研究下。)
- 在firefox中运行仍有问题,估计是CSS样式问题。
- 还可以进一步将内部方法、属性包裹起来吗? 如果保留下来,以后开发用起来更方便呢?
好啦,先写到这里,欢迎大家多留言讨论。源文件请在此处下载!