基於HTML5的在線地圖 - 加載TopoJSON數據

Qunee for HTML5有許多地圖的示例,包括地鐵圖,基於SVG數據的地圖,結合leaflet的地圖等,每一個示例都是單獨的實現,代碼也各有不一樣,因而咱們想,是否能將這些方案統一塊兒來,實現一種地圖解決方案呢?因而咱們開始整合,從世界地圖到國內各市縣的地圖,再到各類地鐵圖,都用HTML5技術呈現出來,而在地圖之上還有咱們的拓撲圖,等值分析圖,地鐵線路分析等等,本文咱們將介紹如何使用Qunee加載標準地圖數據,實現從世界地圖到國內省市地圖的呈現 php

標準地圖數據

首先遇到的是地圖數據的問題,咱們選擇支持兩種數據格式:GeoJSON和TopoJSON,前者是地理數據的標準格式,各類GIS軟件都支持,後者是D3.js用到的一種數據格式,能有效壓縮數據文件,Qunee建議使用TopoJSON數據格式 html

地圖數據

Qunee地圖示例

下面以一個hello world示例介紹MapChart的使用 jquery

<!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>

運行界面

hello qunee map

地圖投影算法

地球是個球體,球面轉換到平面鋪開總會存在誤差,咱們看一幅沒有投影的世界地圖,格陵蘭島看上去比印度大不少,而實際上格陵蘭島的面積只有印度的2/3,因此對於維度較高的地區地圖投影是很必要的,因此對於單獨的中國地圖顯示咱們建議使用winkel3投影,而對於世界地圖能夠不用投影 算法

使用winkel3投影的中國地圖
hello qunee map with winkel3 projection 投影

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

世界地圖 winkel3投影

從世界到國內省地圖示例

地圖數據能夠疊加,下面的示例加載了三個地圖數據文件:世界地圖、省界,分別設置不一樣的zIndex和樣式(填充色,字體大小等),實現從世界地圖一直放大到省的效果,其中部分地塊的名稱作了位置調整: json

代碼示例

<!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 canvas

運行效果 世界地圖 by qunee

點擊地塊縮放效果

地圖縮放

高性能地圖

Qunee for HTML5圖形組件使用HTML5技術,具備良好的性能,地圖方面也是如此,對於Qunee正式商業版本,支持從世界地圖到縣市級別的地圖數據,下面的視頻演示了多幅地圖數據的疊加效果:世界地圖、省界、地市、縣界,此外在地圖之上還加入了上萬的拓撲節點連線數據,操做依舊能保持流暢,並能將地圖導出上億像素的大圖 app

相關文章
相關標籤/搜索