leaflet與angularJS的使用之畫線、矩形及自定義iCON

需求:在angularJS的頁面中使用OSM添加相應的元素,畫線,畫圈,畫矩形以及網格。
效果:廢話不多說,先看效果。如果不是你需要的效果,那麼就不要再往下翻浪費時間了。
示例地圖
詳細描述:
talk is cheap, show me code

<html ng-app="myApp">
<head>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.12/angular-material.min.css">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
          integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
          crossorigin=""/>

    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
            integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
            crossorigin=""></script>
    <style>
        #mapid {
            height: 100%;
            width: 100%;

        }
        .my-div-icon{
            font-size:25px;
            background:#6495ED;
            width:120px;
            height: 30px;
            color:white;
        }
    </style>
</head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>My AngularJS App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="../app.css">
    <link href="../lib/angular-material/angular-material.css" rel="stylesheet">
</head>

<body ng-cloak ng-controller="myController">

<div id="mapid" >
</div>
<div id="my-div-icon" class="my-div-icon" ng-if="false">

</div>
<div>
    <button ng-click="ff()">hello</button>
</div>
<div ng-if="response[0].failedGrids.length > 0">
    <h1>{{response[0].failedGrids}}</h1>
</div>
<script>
</script>


<script src="https://cdn.bootcss.com/angular.js/1.7.8/angular.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.7.8/angular-animate.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.7.8/angular-aria.js"></script>
<script src="https://cdn.bootcss.com/angular-material/1.1.17/angular-material.js"></script>src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="../app.js"></script>
<script src="../view12-map/view12.js"></script>

</body>
</html>

JS

'use strict';
var myApp = angular.module('myApp', ['ngMaterial', 'ngAria', 'ngMessages']);
myApp.controller('myController', function ($scope, $compile,$timeout) {
    $scope.user = "UU";
    $scope.response = [{
        "locationId": "location1",
        "topLat": 31.828153,
        "bottomLat": 30.828153,
        "leftLon": 120.466008,
        "rightLon": 122.066008,
        "grids": [{
            "gridId": 1,
            "locationId": "location1",
            "topLat": 31.828153,
            "bottomLat": 31.228153,
            "leftLon": 120.466008,
            "rightLon": 121.0008,
            "status": "success"
        }, {
            "gridId": 2,
            "locationId": "location1",
            "topLat":31.828153,
            "bottomLat": 31.228153,
            "leftLon": 121.0008,
            "rightLon":121.606,
            "status": "success"
        }, {
            "gridId": 3,
            "locationId": "location1",
            "topLat": 31.828153,
            "bottomLat": 31.228153,
            "leftLon": 121.0008,
            "rightLon": 122.066008,
            "status": "success"
        }, {
            "gridId": 4,
            "locationId": "location1",
            "topLat": 31.228153,
            "bottomLat": 30.828153,
            "leftLon": 120.466008,
            "rightLon": 121.206,
            "status": "success"
        }, {
            "gridId": 5,
            "locationId": "location1",
            "topLat": 31.228153,
            "bottomLat": 30.828153,
            "leftLon": 121.206,
            "rightLon": 122.066008,
            "status": "failed"
        }],
        "failedGrids": [7,9]
    }];

	$timeout(function(){
		    var myMap = L.map('mapid').setView([$scope.response[0].topLat,$scope.response[0].leftLon], 11);
		    $scope.myMap = myMap;
    L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        maxZoom: 18,
        id: 'mapbox/streets-v11',
        tileSize: 512,
        zoomOffset: -1,
        accessToken: '自己申請的accessTocken'
    }).addTo(myMap);
	},400);
    
    $scope.ff = function () {
        var myIcon;
        angular.forEach($scope.response, function (res) {

            var grids = res.grids;
            angular.forEach(grids, function (g) {
                if (g.status == "success"){
                    var l2 = L.polyline([
                        [g.topLat,g.leftLon],
                        [g.topLat, g.rightLon],
                        [g.bottomLat, g.rightLon],
                        [g.bottomLat, g.leftLon],
                        [g.topLat,g.leftLon]
                    ],{color:'#3840CF', weight: 1}).addTo($scope.myMap);
                }else if (g.status == "failed"){
                var ll = L.polygon([
                        [g.topLat,g.leftLon],
                        [g.topLat, g.rightLon],
                        [g.bottomLat, g.rightLon],
                        [g.bottomLat, g.leftLon],
                        [g.topLat,g.leftLon]
                    ],{color:'#3840CF', weight: 1,fillColor:'#5b8cd6',fillOpacity:0.6,}).addTo($scope.myMap);
                }
            });
            console.log(res.locationId);
            var line = L.polyline([
                [res.topLat,res.leftLon],
                [res.topLat, res.rightLon],
                [res.bottomLat,res.rightLon],
                [res.bottomLat, res.leftLon],
                [res.topLat,res.leftLon]
            ],{color:'#3840CF',fillColor:'#3840CF', weight:3}).addTo($scope.myMap);
            myMap.fitBounds(line.getBounds());
             myIcon = L.divIcon({
                html: res.locationId,
                className: 'my-div-icon',
                iconSize:{width: 20, height: 40},
            });
            var marker = L.marker([res.topLat, res.leftLon], {icon: myIcon,title: "Localtion Name: " + res.locationId + "\n Last Synchronization Status: " + res.status + "\n Failed Grids: [" + res.failedGrids.join(',') + "]"}).addTo($scope.myMap);

            var circle = L.circle([31, 120.4], {
                color: 'red',
                fillColor: '#f03',
                fillOpacity: 0.5,
                radius: 5000
            }).addTo($scope.myMap);
        });
    };
});

##注意:
如果在加載地圖的時候,不是使用$timeout()方法的話,會很容易造成地圖只顯示在屏幕左上角的一點點部分,如圖:
在這裏插入圖片描述
這是由於在放置地圖的div在沒有渲染完成就已經開始加載地圖了,而加載地圖又是根據所在的div的中心點爲地圖的中心點,然後加載地圖。由於此時的div未加載完成,因此其中心點是(0,0)的地方,也就是屏幕左上角,所以地圖是殘缺的,像鋸齒一樣的形狀。
解決這個問題有三個方法:

  • 1、按F12進入調試,此時地圖會自動調整。
    在這裏插入圖片描述
  • 2、調用map.invalidateSize(true)方法。
    當div的大小發生變化時,每次都調用一下該方法。
$scope.show = function() {
	myMap.invalidateSize(true);
}
  • 3、使用$timeout()方法
    這個正是上面例子中使用的方法,在400ms之後再加載地圖,此時的div已經加載完成了,就不會出現地圖缺失的問題了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章