HT for Web作为逻辑拓扑图形组件自身没有GIS功能,但可以与各种GIS引擎即其客户端组件进行融合,各取所长实现逻辑拓扑和物理拓扑的无缝融合,本章将具体介绍HT for Web与开发免费的OpenLayers地图结合应用的关键技术点,该文介绍的结合的原理,其实还可推广到与ArcGIS、百度地图以及GoogleMap等众多GIS地图引擎融合的解决方案。
以上抓图为本文介绍的例子最终运行效果,接下来我们一步步来实现,首选显示地图信息需要有城市经纬度数据,搜索了下感谢此篇博客提供的数据。这么大量的数据我采用的是《HT图形组件设计之道(四)》中介绍的getRawText函数方式,有了数据之后剩下就是呈现的问题了,我们需要将HT的GraphView组件与OpenLayers的map地图组件叠加在一起,也就是OpenLayers的tile地图图片在下方,GraphView的组件在上方,由于GraphView默认是透明的,因此非图元部分用户可穿透看到地图内容。找到合适的组件插入位置是头疼的事情,ArcGIS、百度地图包括GoogleMap几乎每个不同的GIS组件都需要尝试一番才能找到合适的插入位置,其他GIS引擎组件的整合以后章节再介绍,本文我们关注的OpenLayers的插入方式为map.viewPortDiv.appendChild(graphView.getView())。
HT和OpenLayers组件叠加在一起之后,剩下就是拓扑里面图元的摆放位置与经纬度结合的问题,常规网络拓扑图中存储在ht.Node图元的position是逻辑位置,和经纬度没有任何关系,因此在GIS应用中我们需要根据图元的经纬度信息换算出position的屏幕逻辑坐标信息,如果你知道投影算法也可以自己提供函数处理,但所有GIS组件都提供了类似的API函数供调用,当然这部分也没有标准化,不同的GIS组件需要调用的API都有差异,但基本原理是一致的,对于OpenLayers我们通过map.getPixelFromLonLat(data.lonLat)可以将经纬度信息转换成屏幕像素逻辑坐标,也就是ht.Node需要的position坐标信息。
细心的同学会想到转换是双向的,有可能用户需要拖动图元节点改变其经纬度信息,这时候我们就需要另外一个方向函数,即根据屏幕逻辑坐标转换成当前坐标对应的经纬度,在OpenLayers中我们通过map.getLonLatFromPixel(new OpenLayers.Pixel(x, y));可以搞定。
显示搞定后剩下就是交互的问题了,HT自己有套交互体系,OpenLayers也需要地图漫游和缩放的交互,两者如何结合呢?如果能保留住两者的功能那就最好了,答案时肯定的,我们只需要添加mousedown或touchstart事件监听,如果graphView.getDataAt(e)选中了图元我们就通过e.stopPropagation();停止事件的传播,这样map地图就不会响应,这时候HT接管了交互,如果没有选中图元则map接管地图操作的交互。
以上交互设计似乎很完美了,结果运行时发现了几处折腾了我很久才找到解决方案的坑:
- 设置map.events.fallThrough = true;否则map不会将事件透传到HT的GraphView组件
- graphView.getView().style.zIndex = 999; 需要指定一定的zIndex否则会被遮挡
- graphView.getView().className = ‘olScrollable’; 否则滚轮不会响应地图缩放
- 设置ht.Default.baseZIndex: 1000 否则ToolTip会被遮挡
为了让这个例子用户体验更友好,我还用心折腾了些技术点供参考:
- 采用开源免费的http://llllll.li/randomColor/随机颜色类库,该类库还有很多非常棒的颜色获取函数,我只是简单的为每个省份显示不一样的颜色
- 重载了isVisible、isNoteVisible和isLabelVisible仅在缩放达到一定级别才显示更详细的内容,否则缩小时所有城市信息都显示完全无法查看,多少也能提高显示性能
以下为最终效果的抓图、视频和源代码:http://i.youku.com/u/UMTQxNDQ2NjQ0MA==
function init(){ graphView = new ht.graph.GraphView(); var view = graphView.getView(); map = new OpenLayers.Map("map"); var ol_wms = new OpenLayers.Layer.WMS( "OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: "basic"} ); map.addLayers([ol_wms]); map.addControl(new OpenLayers.Control.LayerSwitcher()); map.zoomToMaxExtent(); map.events.fallThrough = true; map.zoomToProxy = map.zoomTo; map.zoomTo = function (zoom,xy){ view.style.opacity = 0; map.zoomToProxy(zoom, xy); console.log(zoom); }; map.events.register("movestart", this, function() { }); map.events.register("move", this, function() { }); map.events.register("moveend", this, function() { view.style.opacity = 1; reset(); }); graphView.getView().className = 'olScrollable'; graphView.setScrollBarVisible(false); graphView.setAutoScrollZone(-1); graphView.handleScroll = function(){}; graphView.handlePinch = function(){}; graphView.mi(function(e){ if(e.kind === 'endMove'){ graphView.sm().each(function(data){ if(data instanceof ht.Node){ var position = data.getPosition(), x = position.x + graphView.tx(), y = position.y + graphView.ty(); data.lonLat = map.getLonLatFromPixel(new OpenLayers.Pixel(x, y)); } }); } }); graphView.enableToolTip(); graphView.getToolTip = function(event){ var data = this.getDataAt(event); if(data){ return '城市:' + data.s('note') + ' 经度:' + data.lonLat.lon + ' 维度:' + data.lonLat.lat; } return null; }; graphView.isVisible = function(data){ return map.zoom > 1 || this.isSelected(data); }; graphView.isNoteVisible = function(data){ return map.zoom > 6 || this.isSelected(data); }; graphView.getLabel = function(data){ return '经度:' + data.lonLat.lon + '\n维度:' + data.lonLat.lat; }; graphView.isLabelVisible = function(data){ return map.zoom > 7 || this.isSelected(data); }; view.addEventListener("ontouchend" in document ? 'touchstart' : 'mousedown', function(e){ var data = graphView.getDataAt(e); if(data || e.metaKey || e.ctrlKey){ e.stopPropagation(); } }, false); view.style.position = 'absolute'; view.style.top = '0'; view.style.left = '0'; view.style.right = '0'; view.style.bottom = '0'; view.style.zIndex = 999; map.viewPortDiv.appendChild(view); var color = randomColor(); lines = china.split('\n'); for(var i=0; i<lines.length; i++) { line = lines[i].trim(); if(line.indexOf('【') === 0){ //province = line.substring(1, line.length-1); color = randomColor(); }else{ var ss = line.split(' '); if(ss.length === 3){ createNode(parseFloat(ss[1].substr(3)), parseFloat(ss[2].substr(3)), ss[0].substr(3), color); } } } } function reset(){ graphView.tx(0); graphView.ty(0); graphView.dm().each(function(data){ if(data.lonLat){ data.setPosition(map.getPixelFromLonLat(data.lonLat)); } }); graphView.validate(); } function createNode(lon, lat, name, color){ var node = new ht.Node(); node.s({ 'shape': 'circle', 'shape.background': color, 'note': name, 'label.background': 'rgba(255, 255, 0, 0.5)', 'select.type': 'circle' }); node.setSize(10, 10); var lonLat = new OpenLayers.LonLat(lon, lat); lonLat.transform('EPSG:4326', map.getProjectionObject()); node.setPosition(map.getPixelFromLonLat(lonLat)); node.lonLat = lonLat; graphView.dm().add(node); return node; }
相关推荐
这个项目,"二三维离线地图演示系统 V1.0(for OpenLayers3)",是一个专门针对OpenLayers 3框架设计的示例系统,它展示了如何利用OpenLayers 3实现在Web端进行二三维地图的离线展示和操作。 OpenLayers 3是一个...
在OpenLayers中调用百度地图是一项常见的需求,特别是在构建Web GIS应用时,用户可能希望结合OpenLayers的强大功能和百度地图的丰富数据。OpenLayers是一个开源JavaScript库,用于创建交互式的地图应用,而百度地图...
如题,基于开源的gis框架(openlayers)设计的js组件,支持异步加载,可扩展。同时也提供了webgis操作的相关案例和代码,无论是学习还是工作需要均可满足。纯前端框架,下载后无需配置,可直接运行。
在IT行业中,前端开发是构建Web应用程序的关键部分,而OpenLayers是一个流行的JavaScript库,用于创建交互式的、基于Web的地图应用。本实例将详细介绍如何利用OpenLayers加载离线地图,并通过mui将其打包成移动应用...
OpenLayers 是一个强大的开源JavaScript库,用于在Web浏览器中创建交互式地图应用。它支持多种数据源,包括瓦片地图,使得开发者可以轻松地将地理信息集成到网站中。本教程将详细介绍如何使用OpenLayers加载瓦片地图...
OpenLayers 是一个强大的开源JavaScript库,用于在网页上创建交互式的地图应用。它支持多种地图服务,包括WMS、WMTS等,并且能够处理不同类型的地理数据,如瓦片地图、矢量数据等。本DEMO展示了如何利用OpenLayers...
1) 部署到tomcat6的webapps下面。 2) 将world.mbtiles放到D:/gisdata/mbtiles/目录下。 3) 在浏览器输入:(世界地图,图层0-7) http://localhost:8080/MbTileService/local_tiles.html
OpenLayers 是一个强大的开源JavaScript库,用于在网页上创建交互式的地图应用。它支持多种地图服务,包括全球知名的地图服务提供商——天地图。天地图是中国官方的地理信息公共服务平台,提供丰富的地形图、卫星...
OpenLayers2是一个开源JavaScript库,专门用于在Web浏览器中创建交互式地图应用。这个库支持多种地图服务,包括WMS、WFS等,使得开发者能够方便地集成来自不同地图服务提供商的数据。"OpenLayers2多地图联动"这个...
OpenLayers 是一个强大的开源JavaScript库,用于在网页上展示地理空间信息。它支持多种地图服务,包括WMS、WMTS等,同时也非常...同时,这也是对OpenLayers API的一个基础实践,为进一步开发复杂的GIS应用打下基础。
4. **Web开发技术**:讲解如何结合HTML、CSS和JavaScript等Web技术创建交互式的Web地图,特别是使用JavaScript库如OpenLayers或Leaflet进行地图操作和功能实现。 5. **数据获取与管理**:介绍地理数据的来源和格式...
通过这个压缩包中的示例,学习者可以了解到如何在OpenLayers 5中整合第三方地图服务,如百度地图,这对于那些希望在自己的Web应用中集成地图功能的开发者来说非常有用。同时,这个示例也是一个很好的起点,可以...
在OpenLayers 3及以上版本中,地图右键功能的实现是一项关键操作,它允许用户与地图交互并执行特定任务,如获取地图上的坐标、测量距离、添加标记等。本篇文章将详细探讨如何在OpenLayers中自定义地图右键菜单,以...
在GIS(地理信息系统)开发中,OpenLayers是一个广泛使用的开源JavaScript库,用于在网页上创建交互式的地图应用。它允许开发者轻松地将地理数据与Web服务集成,提供丰富的地图功能,如缩放、平移、图层管理和标注...
以上只是Vue+OpenLayers+GeoServer整合的一部分核心知识点,实际项目中还可能涉及到地图缩放级别管理、地图图层的动态加载、地理编码、投影转换、以及与其他GIS服务的集成等多种技术。通过深入学习和实践,开发者...
《OpenLayers 3 + GeoServer 实现地图交互详解》 在现代GIS(地理信息系统)应用中,地图交互功能是至关重要的。本篇文章将详细介绍如何利用OpenLayers 3和GeoServer来构建一个具备地图框选、点击街道选中要素以及...
在"Web Gis_webgis_GIS地图开发Js_gis_webgis地图来源_web地图可视化_"这个主题中,我们将探讨如何使用JavaScript来开发Web GIS应用,实现地图的显示、地点查找和地图可视化。 首先,JavaScript(简称Js)是Web开发...
OpenLayers 是一个强大的开源JavaScript库,专用于在Web上创建交互式地图应用。它支持多种地图服务,包括WMS、WMTS等,并且能够轻松地集成地理信息系统(GIS)功能。OpenLayers 5是该库的一个较新版本,带来了许多...
基于openlayers实现如下功能: 1、实现图片地图,图片地图比例尺 2、绘制点的路径 3、绘制多边形,定位不规则多边形中心点,显示名称 4、多边形编辑 5、地图全屏,地图截图 6、点是否在区域中判定 7、暂停,播放,...
该方案在OpenLayers的基础上进行二次开发,采用HTML+CSS+JavaScript的开发技术组合,在完成常用GIS图形功能的基础上,实现了图形系统可同时在Web和移动终端上进行图形信息浏览的功能,并且通过采用图形数据驱动方式使得...