侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

基于HTML5的在线地图 - 加载TopoJSON数据

2023-12-15 星期五 / 0 评论 / 0 点赞 / 38 阅读 / 7356 字

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

Qunee for HTML5有许多地图的示例,包括地铁图,基于SVG数据的地图,结合leaflet的地图等,每个示例都是单独的实现,代码也各有不同,于是我们想,是否能将这些方案统一起来,实现一种地图解决方案呢?于是我们开始整合,从世界地图到国内各市县的地图,再到各种地铁图,都用HTML5技术呈现出来,而在地图之上还有我们的拓扑图,等值分析图,地铁线路分析等等,本文我们将介绍如何使用Qunee加载标准地图数据,实现从世界地图到国内省市地图的呈现

标准地图数据

首先遇到的是地图数据的问题,我们选择支持两种数据格式:GeoJSON和TopoJSON,前者是地理数据的标准格式,各种GIS软件都支持,后者是D3.js用到的一种数据格式,能有效压缩数据文件,Qunee建议使用TopoJSON数据格式

Qunee地图示例

下面以一个hello world示例介绍MapChart的使用

<!DOCTYPE html><html><head>    <title>地图浏览</title>    <meta charset="utf-8"></head><body><div style="height: 600px;" id="canvas"/><!--加载Qunne和Map相关扩展类库--><!--Qunee图形组件 --><script src="http://demo.qunee.com/lib/qunee-min.js?v=1.8.1"></script><!--MapChart组件 --><script src="http://map.qunee.com/src/MapChart.js"></script><!--TopoJSON数据支持 --><script src="http://map.qunee.com/src/topojson.js"></script><script>    var map = new Q.MapChart('canvas');    map.loadTopoJSON('data/shengjie.json', {        zIndex: -10, onfinish: function (map) {            map.zoomToOverview();            map.createMapNode('hello map', 105, 35);        }    });</script></body></html>

运行界面

地图投影算法

地球是个球体,球面转换到平面铺开总会存在偏差,我们看一幅没有投影的世界地图,格陵兰岛看上去比印度大很多,而实际上格陵兰岛的面积只有印度的2/3,所以对于维度较高的地区地图投影是很必要的,所以对于单独的中国地图显示我们建议使用winkel3投影,而对于世界地图可以不用投影

使用winkel3投影的中国地图

使用winkel3投影的世界地图效果

从世界到国内省地图示例

地图数据可以叠加,下面的示例加载了三个地图数据文件:世界地图、省界,分别设置不同的zIndex和样式(填充色,字体大小等),实现从世界地图一直放大到省的效果,其中部分地块的名称做了位置调整:

代码示例

<!DOCTYPE html><html><head>    <title>世界地图 by Qunee</title>    <meta charset="utf-8"></head><body class="layout" style="margin: 0px;"><div data-options="region:'center'" id="canvas"/><script src="http://demo.qunee.com/lib/qunee-min.js?v=1.8.1"></script><!--<script src="qunee-min.js?v=1"></script>--><!-- build:js js.js --><script src="../bower_components/jquery/dist/jquery.js"></script><script src="../bower_components/layout.border/src/layout.border.js"></script><script src="src/MapChart.js"></script><script src="src/topojson.js"></script><!-- endbuild --><script>    var colors = ["#D5E7C4", "#CDE6FF", "#EFDEE6", "#FFF8CC"];    var stateColors = ['#2898E0', '#4BB9FF', '#2EADFF'];    var index = 0;    var map = new Q.MapChart('canvas');    map.onclick = function (evt) {        var currentElement = evt.getData();        if (currentElement && map.selectionModel.isSelected(currentElement)) {            this.centerElement(currentElement);        }    }    map.loadTopoJSON('data/world.json', {        zIndex: -10, callback: function (area) {            area.setStyle(Q.Styles.SHAPE_FILL_COLOR, colors[index++ % colors.length]);            if (area.name == 'China' || area.name == 'Taiwan') {                area.name = null;                area.setStyle(Q.Styles.SHAPE_STROKE, 12);                area.setStyle(Q.Styles.SHAPE_STROKE_STYLE, Q.toColor(0x77555555));                area.zIndex = -9.5;            }        }, onfinish: function (map) {            map.zoomToOverview();            var shanghai = map.createMapNode(null, 121.48, 31.23);            shanghai.image = Q.Shapes.getShape(Q.Consts.SHAPE_CIRCLE, -10, -10, 20, 20);            shanghai.setStyle(Q.Styles.SHAPE_FILL_COLOR, Q.toColor(0xEEFF0000));            shanghai.setStyle(Q.Styles.SHAPE_STROKE_STYLE, Q.toColor(0xEE00FFFF));            shanghai.setStyle(Q.Styles.SHAPE_STROKE, 3);            map.loadTopoJSON('data/shengjie.json', {                zIndex: -9,                callback: function (element) {                    if (element.name == '甘肃') {                        element.setStyle(Q.Styles.LABEL_OFFSET_X, 50);                    } else if (element.name == '河北') {                        element.setStyle(Q.Styles.LABEL_OFFSET_X, -30);                    } else if (element.name == '内蒙古') {                        element.setStyle(Q.Styles.LABEL_OFFSET_Y, 50);                    } else if (element.name == '广东') {                        element.setStyle(Q.Styles.LABEL_OFFSET_Y, -30);                    } else if (element.name == '香港') {                        element.setStyle(Q.Styles.LABEL_OFFSET_X, 15);                    } else if (element.name == '澳门') {                        element.setStyle(Q.Styles.LABEL_OFFSET_X, -15);                    }                    element.setStyle(Q.Styles.SHAPE_FILL_COLOR, stateColors[index++ % stateColors.length]);                    element.setStyle(Q.Styles.SHAPE_STROKE_STYLE, '#EEE');                    element.setStyle(Q.Styles.SHAPE_STROKE, 1);                }            })        }    });</script></body></html>

在线演示

在线演示地址:map.qunee.com

运行效果

点击地块缩放效果

高性能地图

Qunee for HTML5图形组件使用HTML5技术,具有良好的性能,地图方面也是如此,对于Qunee正式商业版本,支持从世界地图到县市级别的地图数据,下面的视频演示了多幅地图数据的叠加效果:世界地图、省界、地市、县界,此外在地图之上还加入了上万的拓扑节点连线数据,操作依旧能保持流畅,并能将地图导出上亿像素的大图

广告 广告

评论区