文档章节

使用Leaflet创建地图拓扑图

nosand
 nosand
发布于 2014/07/27 23:04
字数 858
阅读 10189
收藏 37

之前我们采用过 Openlayers+Qunee的方案,实现地图拓扑图,鉴于Openlayers是一个古老项目,略显臃肿,对于现代的前端地图应用,显得笨重,在客户的介绍下,我们找到了leaflet - 基于HTML5的轻量地图客户端方案,结合Qunee使用,以及第三方插件,实现更加轻快的地图拓扑图应用 Leaflet介绍 leaflet是一个开源软件,作者在乌克兰,在移动设备上的有良好的体验,比较新和现代的地图客户端,类库压缩后只有33k,非常小巧,这一点让qunee都相形见绌,先看一个leaflet的入门示例

官方示例

首先引入leaflet相关js和css

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>



然后构建地图,并添加openStreetMap

// create a map in the "map" div, set the view to a given place and zoom
var map = L.map('map').setView([51.505, -0.09], 13);

// add an OpenStreetMap tile layer
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

// add a marker in the given location, attach some popup content to it and open the popup
L.marker([51.5, -0.09]).addTo(map)
    .bindPopup('A pretty CSS3 popup. 
 Easily customizable.')
    .openPopup();

运行效果如下: 

hello leaflet

结合Qunee拓扑图

Leaflet地图上可以添加点线面基本图形,如果需要展示更复杂的图形或者链接关系,显得力不足,可以结合Qunee组件使用,下面我们让地图和拓扑图叠加起来,在地图上显示拓扑元素,并整合两者的交互

图层叠加

在地图的DIV容器中添加一个孩子div,作为拓扑图的画布,并设置相应的css,然后调用超类的构造函数,取消默认的双击和滚轮操作,已被后面地图与拓扑图的交互同步
var MapGraph = function (map) {
    var container = map._container;
    var canvas = document.createElement("div");
    canvas.style.width = "100%";
    canvas.style.height = "100%";

    container.appendChild(canvas);

    Q.doSuperConstructor(this, MapGraph, [canvas]);
    this.enableWheelZoom = false;
    this.enableDoubleClickToOverview = false;
    this.originAtCenter = false;
    this.setMap(map);
    ...
}

关联地图

下面实现拓扑图与地图的绑定,在#setMap(map)函数中,监听了地图的zoomstart和zoomend事件,根据经纬度动态的调整图元的屏幕位置,同样在节点被拖动后,也需要设置新的经纬度
MapGraph.prototype = {
    map: null,
    mapShowing: true,
    enableInertia: false,
    createNodeByLonLat: function (name, lon, lat) {
        var l = this.toLonLat(lon, lat);
        var p = this.getPixelFromLonLat(l);
        var node = graph.createNode(name, p.x, p.y);
        node.lonLat = l;
        return node;
    },
    toLonLat: function (lon, lat) {
        return new L.latLng(lat, lon);
    },
    getPixelFromLonLat: function (lonLat) {
        return this.map.latLngToContainerPoint(lonLat, this.map._zoom);
    },
    getLonLatFromPixel: function (x, y) {
        return this.map.containerPointToLatLng([x, y]);
    },
    setMap: function (map) {
        this.map = map;

        this.map.on("zoomstart", this.hideGraph, this);
        this.map.on("zoomend", this.updateNodes, this);

        this.html.ondblclick = createEventFunction(this, function (evt) {
            if (this.getElementByMouseEvent(evt)) {
                Q.stopEvent(evt);
            }
        });
        this.interactionDispatcher.addListener(function (evt) {
            if (evt.kind == Q.InteractionEvent.ELEMENT_MOVE_END) {
                var datas = evt.datas;
                Q.forEach(datas, function (data) {
                    var pixel = this.toCanvas(data.location.x, data.location.y);
                    data.lonLat = this.getLonLatFromPixel(pixel.x, pixel.y);
                }, this);
            }
        }, this)
    },
    hideGraph: function(){
        this.html.style.visibility = "hidden";
    },
    showGraph: function(){
        this.html.style.visibility = "";
    },
    translate: function (tx, ty) {
        Q.doSuper(this, MapGraph, "translate", arguments);
        this.map.panBy([-tx, -ty], {animate: false});
    },
    resetVisibility: function () {
        this.forEach(function (e) {
            if (e.invalidateVisibility) {
                e.invalidateVisibility(true);
            }
        });
    },
    updateNodes: function () {
        this.translateTo(0, 0, 1, true);
        this.resetVisibility();
        this.forEach(function (d) {
            if (d instanceof Q.Node) {
                var l = d.lonLat;
                var p = this.getPixelFromLonLat(l);
                d.location = p;
            }
        }, this);
        this.showGraph();
    }
}

Q.extend(MapGraph, Q.Graph);
此外还可以通过可见过滤器实现,不同比例尺显示不同的节点

运行效果

在线示例: http://demo.qunee.com/map/mapByLeafLet.html 

leaflet + qunee

© 著作权归作者所有

nosand
粉丝 78
博文 40
码字总数 33601
作品 0
徐汇
私信 提问
加载中

评论(1)

何sr
何sr
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);这个求解释
Vue CLI and Leaflet (8)量测

一、功能分析 地图的量测功能,是地理信息系统中的常用功能。主要量测地图上的距离,面积,或者线要素的长度,面要素周长和面积。 这篇文章将介绍第一个基于 leaflet.js 实现地图量测插件 le...

蓝波丶坎迪
07/16
0
0
基于HTML5的在线地图 - 加载TopoJSON数据

Qunee for HTML5有许多地图的示例,包括地铁图,基于SVG数据的地图,结合leaflet的地图等,每个示例都是单独的实现,代码也各有不同,于是我们想,是否能将这些方案统一起来,实现一种地图解...

nosand
2015/03/29
2.4K
2
Vue-CLI and Leaflet (5): 点 绘制

(一) Vue-CLI and Leaflet:起步 - 在 Vue-CLI 中使用 Leaflet (二) Vue-CLI and Leaflet:地图基本操作(放大,缩小,平移,定位等) (三) Vue-CLI and Leaflet: 添加 marker, polyli...

蓝波丶坎迪
06/23
0
0
Mapbox Studio 常见问题

之前借助leaflet +qunee实现了地图拓扑图,同样使用leaflet的有个更专业的地图应用:Mapbox,可以定制出简单、专业、漂亮的地图,在传统地图服务商(Google,Nokia, Apple ...)之外,有了更...

nosand
2014/12/01
10.2K
0
整合 Ext JS 和第三方类库

介绍 ExtJS提供了许多高度可定制化内置组件。如果它不在框架(framework)里面,你可以很容易的扩展这些类,或者浏览Sencha市场(Sencha Market)寻找你可能需要的任何东西。那些都在大部分的...

crazymus
2013/07/02
6.4K
2

没有更多内容

加载失败,请刷新页面

加载更多

一次看懂 Https 证书认证

TLS > 传输层安全性协定 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为网际网路通信,提供安全及数据完整性保障。 如图,TLS...

极客收藏夹
37分钟前
4
0
https证书买哪家好?有哪些供应商

在选购https证书前除了要了解类型外,还需要了解https证书供应商,毕竟不同的供应商,提供的产品质量与服务也是有差异的。今天小编就为大家讲讲https证书供应商方面的内容,希望各位会喜欢。...

安信证书
39分钟前
5
0
Zuul 配置

概述:zuul底层是基于servlet,是由一系列的filter链构成。 1、路由配置 a、单例serverId映射 zuul: routes: client-a: path: /client/** serviceId: client-a 意思是...

java框架开发者
56分钟前
3
0
zk中FinalRequestProcessor解析

是处理器最后一个环节 FinalRequestProcessor implements RequestProcessor 处理器链最后一个环节处理事务和非事务请求最后一个环节 构造器 public FinalRequestProcessor(ZooKeeperServer z...

writeademo
57分钟前
4
0
Axios 详解

首先祝广大程序猿们节日快乐! 一、axios简介 基于promise,用于浏览器和node.js的http客户端 二、特点 支持浏览器和 node.js 支持 promise 能拦截请求和响应 能转换请求和响应数据 能取消请求...

张兴华ZHero
58分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部