1. 程式人生 > >局域網內web地圖的簡單實現

局域網內web地圖的簡單實現

set warning lena 刪掉 fun pop geos files user

首先,我先說一下這次的主要目的。我們的想法是在不連互聯網的局域網中搭起來一個地圖服務,類似於百度地圖的網頁版本,功能最少要有看地圖、放縮、標記、批量標記、實時經緯度坐標。這個東西還是讓我費了一番力氣(首先要搞明白地圖加載過程和常用gis系統的服務調用)。這種系統的工作原理大概如下圖
技術分享圖片

我在此就不去寫文件系統和gis服務的部分了,這一部分的核心就是你先要下載一個可以用、自己滿意的瓦片文件數據,然後使用一些webgis的框架把它做成服務,怕麻煩的話可以考慮geoserver以及一些docker的方案。

那麽我們要做的就是前端這一部分,首先推薦一下leaflet這個框架,非常的清晰明了,按照quickstart走基本沒問題。https://leafletjs.com/

我們將要實現的醜陋的界面如下(渣渣審美,也懶得搞美觀)
技術分享圖片

首頁就是簡單樸素的地圖,可以在下面的地圖裏進行拖拽,縮放,上面的三個按鈕顧名思義,分別是標記一個點,清除掉所有標記點,批量標記。

技術分享圖片

這就是我們標記之後的狀態,藍色氣泡是默認的,你也可以換成你自己的圖。標記既可以按照經緯度去準確標點,也可以鼠標左鍵雙擊標點。

技術分享圖片
按照經緯度準確標點的功能如上圖所示。

那麽下面就是我們開始愉快的看代碼了,完整的項目文件夾在 https://github.com/chuxiuhong/webmap

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>地圖服務</title>
</head>
<body>
<link rel="stylesheet" href="./static/bootstrap.min.css"> //加載bootstrap的css,這些靜態文件都有cdn庫,我在項目內使用的是本地化的,可以到github上看完整的項目文件夾
<script src="./static/jquery.slim.min.js"></script>
<script src="./static/popper.min.js"></script>
<script src="./static/bootstrap.min.js"></script>
<link rel="stylesheet" href="static/leaflet.css"/>   //加載leaflet的css
<script src="static/leaflet.js"></script>            //加載leaflet的js,切記要把js放在css後面加載

<nav class="navbar navbar-inverse">
    <div class="col-md-4">
        <button type="button" class="btn btn-warning" id="mark_button">標記</button>    //三個按鈕
        <button type="button" class="btn btn-warning" id="clear_button">清除標記</button>
        <button type="button" class="btn btn-warning" id="batch_mark">批量標記</button>
    </div>
    <div class="col-md-2">
        <p class="text-center">地圖</p>
    </div>
    <div class="col-md-4">
        <p class="text-right" id="point"></p>
    </div>
</nav>

<style>
    #mapid { height: 1000px; }   //設置地圖的尺寸
</style>
<div id="mapid">
    <script type="text/javascript">
        document.oncontextmenu = function (e) {
            return false;       //禁用掉右鍵,可寫可不寫的部分
        };
        var map = L.map('mapid').setView([30, 100], 4);  //設置地圖初始化時查看的部分及尺度
        L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {maxZoom: 18}).addTo(map);
        //核心語句,加載openstreetmap的瓦片服務,{z}代表level,{x},{y}分別代表行和列,maxzoom很明顯是最大放大級別(先了解下瓦片數據的加載方式即可知曉),加載之後把圖添加到map中
        var marker_group = L.layerGroup().addTo(map); //建立一個標記組,便於我們後面批量的刪除掉這些標記點
        map.on('mousemove', function (e) {
            var latlng_str = e.latlng.toString().split("LatLng")[1]; //移動鼠標的時候觸發事件,在右上角顯示出來我們的經緯度
            $("#point").html(latlng_str)
        });
        map.on('dblclick', function (e) {
            var marker = L.marker(e.latlng).addTo(marker_group);  //雙擊的時候觸發標記,標記鼠標當前的選中點

        });

        $("#clear_button").click(function (e) {
            map.removeLayer(marker_group);//點擊清除標記之後,把標記圖層整個都刪掉
            marker_group = L.layerGroup().addTo(map);//刪掉之後還要建立一個同名的新的圖層,好讓我們可以繼續使用標記功能
        });

        $('#mark_button').click(function (e) {
            var mark_prompt = prompt("先緯度後經度,請用空格分開", "");//按照輸入的經緯度標記點
            var point_latlng = L.latLng(mark_prompt.split(" ")[0], mark_prompt.split(" ")[1]);
            var marker = L.marker(point_latlng).addTo(marker_group);
        });
        $('#batch_mark').click(function (e) {
           $('#file').trigger('click');
        });
        function upload(input) {
            //這裏我們是默認我們的經緯度坐標通過excel中的兩列復制到文本文件中,那麽中間的間隔就是"\t",你也可以改成自己想要的讀取方法
            if (window.FileReader) {
                var file = input.files[0];
                filename = file.name.split(".")[0];
                var reader = new FileReader();
                reader.onload = function() {
                    var str_list = reader.result.split("\n");
                    for (var i =0;i<str_list.length;i++){
                        if(str_list[i].length > 1){
                            a = str_list[i].split("\t")[0];
                            b = str_list[i].split("\t")[1];
                            console.log(a,b);
                            var point_latlng = L.latLng(a, b);
                            console.log("get here");
                            var marker = L.marker(point_latlng).addTo(marker_group);
                        }
                    }
                    console.log(str_list);
                };
                reader.readAsText(file);
            }
        }


    </script>
    <input type="file" id="file" onchange="upload(this)"
           style="filter:alpha(opacity=0);opacity:0;width: 0;height: 0;"/>
</div>
</body>
</html>

局域網內web地圖的簡單實現