日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

入门Leaflet之小Demo

發布時間:2025/7/14 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 入门Leaflet之小Demo 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

入門 Leaflet 之小 Demo


寫在前面 ---- WebGIS 開發基礎之 Leaflet

  • GIS 基本概念:GIS、Map、Layer、Feature、Geometry、Symbol、Data(Point、Polyline、Polygon)、Renderer、Scale、Project、Coordinates;
  • GIS 開發概述:架構模式、常用平臺和 SDK、二維三維
  • 使用 Leaflet 開發常用功能
    • 地圖加載(底圖類型、切換):
    • 地圖操作(縮放、平移、定位/書簽、動畫):
    • 圖層管理(加載、移除、調整順序):
    • 要素標繪(點/聚簇、線、面,符號化/靜態動態):
    • 屬性標注(字段可選、樣式定制):
    • 專題地圖(點、線、面,渲染):
    • 查詢定位(屬性查詢、空間查詢/周邊搜索/緩沖區/面查點線面/點線查面、圖屬互查、綜合查詢):
    • 信息窗口(入口、Popup、定制):
    • 坐標轉換(地理與投影、不同地理坐標系):
    • 空間運算(長度面積測量、點取坐標、緩沖區、相交包含關系):
    • 動態監控(固定點狀態切換、車輛監控):
  • Leaflet API

  • Demo 用到的庫

    • Flat-UI?Flat UI is based on Bootstrap, a comfortable, responsive, and functional framework that simplifies the development of websites.Flat-UI 是基于 Bootstrap 的一個扁平化風格 web 開發框架。
    • leaflet?an open-source JavaScript library for mobile-friendly interactive maps.Leaflet 是一個為建設交互性好適用于移動設備地圖,而開發的現代的、開源的 JavaScript 庫。
    • Esri Leaflet?A lightweight set of tools for using ArcGIS services with Leaflet.一個輕量級的工具,基于 leaflet 利用 ArcGIS 服務。

    PART 1: 地圖加載(底圖類型、切換)?Demo 1

    • 庫引用
    <link rel="stylesheet" type="text/css" href="./lib/Flat-UI-master/dist/css/vendor/bootstrap/css/bootstrap.min.css" /> <link rel="stylesheet" href="./lib/Flat-UI-master/dist/css/flat-ui.min.css"> <link rel="stylesheet" href="./lib/leaflet/leaflet.css"> <script src="./lib/Flat-UI-master/dist/js/vendor/jquery.min.js"></script> <script src="./lib/Flat-UI-master/dist/js/flat-ui.js"></script> <script src="./lib/leaflet/leaflet.js"></script> <script src="./js/urlTemplate.js"></script>
    • 地圖加載與切換
    const map = L.map("mapDiv", {crs: L.CRS.EPSG3857, //要使用的坐標參考系統,默認的坐標參考系,互聯網地圖主流坐標系 // crs: L.CRS.EPSG4326, //WGS 84坐標系,GPS默認坐標系 zoomControl: true, // minZoom: 1, attributionControl: true, }).setView([30.6268660000, 104.1528940000], 18);//定位在成都北緯N30°37′45.58″ 東經E104°09′1.44″ let Baselayer = L.tileLayer(urlTemplate.mapbox_Image, { maxZoom: 17, //最大視圖 minZoom: 2, //最小視圖 attribution: 'liuvigongzuoshi@foxmail.com &copy; <a href="https://github.com/liuvigongzuoshi/WebGIS-for-learnning/tree/master/Leaflet_Demo">WebGIS-for-learnning</a>' }).addTo(map); const setLayer = (ele) => { map.removeLayer(Baselayer) if (ele == "mapbox_Image") { Baselayer = L.tileLayer(urlTemplate.mapbox_Image, { maxZoom: 17, minZoom: 2 }).addTo(map); } else if (ele == "mapbox_Vector") { Baselayer = L.tileLayer(urlTemplate.mapbox_Vector, { maxZoom: 17, // minZoom: 2 }).addTo(map); console.log(Baselayer) } }

    基于 Demo 1 利用 H5 Geolocation API 定位到當前位置?Demo 1.1

    • 庫引用 如上 Demo 1
    <!-- marker高亮顯示庫引用 --> <link rel="stylesheet" href="./lib/leaflet.marker.highlight/leaflet.marker.highlight.css"> <script src="./lib/leaflet.marker.highlight/leaflet.marker.highlight.js"></script>
    • 判斷瀏覽器是否支持
    let map;let Baselayer;// 使用H5 API定位 定位在當前位置if (navigator.geolocation) { console.log('/* 地理位置服務可用 */') navigator.geolocation.getCurrentPosition(h5ApiSuccess, h5ApiError); } else { console.log('/* 地理位置服務不可用 */') mapInit([30.374558, 104.09144]);//指定一個數據 定位在成都北緯N30°37′45.58″ 東經E104°09′1.44″ }
    • 定位成功或失敗
    const h5ApiSuccess = (position) => {let latitude = position.coords.latitude; //緯度 let longitude = position.coords.longitude; //經度 console.log('你的經度緯度分別為' + longitude + ',' + latitude + '。') return mapInit([latitude, longitude]); }; const h5ApiError = () => { console.log('/* 地理位置請求失敗 */') mapInit([30.374558, 104.09144]);//指定一個數據 定位在成都北緯N30°37′45.58″ 東經E104°09′1.44″ };
    • 成功后初始化底圖
    const mapInit = (LatLng) => {map = L.map("mapDiv", { crs: L.CRS.EPSG3857, //要使用的坐標參考系統,默認的坐標參考系 // crs: L.CRS.EPSG4326, //國內的坐標參考系 zoomControl: true, // minZoom: 1, attributionControl: true, }).setView(LatLng, 18);//定位在當前位置 Baselayer = L.tileLayer(urlTemplate.mapbox_Image, { maxZoom: 17, //最大視圖 minZoom: 2, //最小視圖 attribution: 'liuvigongzuoshi@foxmail.com &copy; <a href="https://github.com/liuvigongzuoshi/WebGIS-for-learnning/tree/master/Leaflet_Demo">WebGIS-for-learnning</a>' }).addTo(map); L.marker(LatLng, { highlight: "permanent" //永久高亮顯示 }).addTo(map); }
    • 更多了解 geolocation 對象,可參考MDN Web 文檔
    • 更多了解使用 marker 高亮顯示,可參考leaflet.marker.highlight插件
    • 基于 Demo 1 利用 leaflet 封裝好的 H5 定位 API,定位到當前位置?Demo

    PART 2: 地圖操作(縮放、平移、定位/書簽、動畫)?Demo 2

    • 庫引用 如上 Demo 1
    • 設置地圖縮放到指定圖層
    map.setZoom(10, {// animate: false }) //設置地圖縮放到
    • 圖層往里進一個圖層,放大
    map.zoomIn() //圖層往里進一個圖層,放大 //map.zoomOut() //圖層往里出一個圖層,縮小
    • 地圖平移至中心點
    map.panTo([37.91082, 128.73583], {animate: true }) //地圖平移,默認就是true,將地圖平移到給定的中心。如果新的中心點在屏幕內與現有的中心點不同則產生平移動作。
    • 地圖飛到中心點
    map.flyTo([36.52,?120.31]);?// 點到點的拋物線動畫,平移加縮放動畫 注意:盡量避免 setZoom()等地圖縮放方法與 flyTo、flyToBounds 一起合用,因為這兩類地圖操作方法都有各自的縮放值,造成動畫不流暢、不能定位到目的點。
    • 地圖飛到邊界的合適的位置
    map.flyToBounds(polygon.getBounds()); //getBounds(獲取邊界):返回地圖視圖的經緯度邊界。//飛到這個多變形區域上面,自動判斷區域塊的大小,合適縮放圖層,將地圖視圖盡可能大地設定在給定的地理邊界內。let polygon = L.polygon([[37, -109.05], [41, -109.03], [41, -102.05], [37, -102.04]], [40.774, -74.125], { color: 'green', fillColor: '#f03', fillOpacity: 0.5 }).addTo(map); //地圖上繪制一個多形
    • 地圖定位到邊界的合適的位置
    map.fitBounds(polygon.getBounds()); //getBounds(獲取邊界):返回地圖視圖的經緯度邊界。//平移到一個區域上面,自動判斷區域塊的大小,合適縮放圖層let polygon = L.polygon([[37, -109.05], [41, -109.03], [41, -102.05], [37, -102.04]], [40.774, -74.125], { color: 'green', fillColor: '#f03', fillOpacity: 0.5 }).addTo(map); //地圖上繪制一個多邊形

    PART 3: 圖層管理(加載、移除、調整順序):?Demo 3

    • 庫引用
    <link rel="stylesheet" type="text/css" href="./lib/Flat-UI-master/dist/css/vendor/bootstrap/css/bootstrap.min.css" /> <link rel="stylesheet" href="./lib/Flat-UI-master/dist/css/flat-ui.min.css"> <link rel="stylesheet" href="./lib/leaflet/leaflet.css"> <script src="./lib/Flat-UI-master/dist/js/vendor/jquery.min.js"></script> <script src="./lib/Flat-UI-master/dist/js/flat-ui.js"></script> <script src="./lib/leaflet/leaflet.js"></script> <script src="./lib/esri-leaflet-v2.1.2/dist/esri-leaflet.js"></script> <!-- esri-leafleat插件 --> <script src="./js/urlTemplate.js"></script>
    • 使用 esri-leaflet 插件加載 ArcGIS 底圖服務
    let oMap = null;let oLayer = [];oMap = L.map('mapDiv', { crs: L.CRS.EPSG4326, zoomControl: false, minZoom: 7, attributionControl: false }).setView([29.59, 106.59], 12); //定位在重慶 oLayer.push(L.esri.tiledMapLayer({ url: urlTemplate.SYS_CQMap_IMG_MAPSERVER_PATH, maxZoom: 17, minZoom: 0, useCors: false, //是否瀏覽器在跨域的情況下使用GET請求。 }).addTo(oMap)); //加載第一個底圖 oLayer.push(L.esri.tiledMapLayer({ url: urlTemplate.SYS_CQMap_IMG_LABEL_MAPSERVER_PATH, maxZoom: 17, minZoom: 0, useCors: false, }).addTo(oMap)); //加載第二個底圖
    • 切換底圖(移除及加載)
    const setLayer = (layerUrls, maxZoom) => {for (let i = 0; i < oLayer.length; i++) { oMap.removeLayer(oLayer[i]) //將圖層在地圖上移除 } oLayer = [] //制空數組 layerUrls.map((item) => { oLayer.push(L.esri.tiledMapLayer({ url: item, useCors: false, maxZoom: maxZoom, // 設置最大放大圖層值 }).addTo(oMap)); }) } 不同的底圖可能圖層數不一樣,就可能造成瀏覽器去請求不存在的圖層,以及給用戶展示出空白區域的不好體驗,所以切換圖層時候應注意設置最大及最小縮放值。

    PART 4: 要素標繪(點、線、面,符號化/靜態動態)?Demo 4

    • 庫引用 如上 Demo 1
    • 畫一個圓
    // 畫一個circle const circle = L.circle([36.52, 120.31], { color: 'green', //描邊色 fillColor: '#f03', //填充色 fillOpacity: 0.5, //透明度 radius: 10000 //半徑,單位米 }).addTo(map); // 綁定一個提示標簽 circle.bindTooltip('我是個圓');
    • Maker 及自定義 Maker
    // 做一個maker const marker = L.marker([36.52, 120.31]).addTo(map); // 綁定一個提示標簽 marker.bindTooltip('這是個Marker', { direction: 'left' }).openTooltip(); //自定義一個maker const greenIcon = L.icon({ iconUrl: './icon/logo.png', iconSize: [300, 79], // size of the icon popupAnchor: [0, -10] // point from which the popup should open relative to the iconAnchor }); const oMarker = L.marker([36.52, 124.31], { icon: greenIcon }).addTo(map); // 綁定一個提示標簽 oMarker.bindTooltip('這是個自定義Marker', { direction: 'left', offset: [-150, 0] });
    • 畫一根線
    //畫一根線 const polyline = L.polyline([[45.51, -122.68], [37.77, -122.43], [34.04, -118.2]], { color: 'red' }).addTo(map); // 飛到這個線的位置 // map.fitBounds(polyline.getBounds());
    • 畫一個多邊形
    // 畫一個polygon const polygon = L.polygon([[[37, -109.05], [41, -109.03], [41, -102.05], [37, -102.04]], // outer ring [[37.29, -108.58], [40.71, -108.58], [40.71, -102.50], [37.29, -102.50]] // hole ], { color: 'green', fillColor: '#f03', fillOpacity: 0.5 }).addTo(map); // 綁定一個提示標簽 polygon.bindTooltip('this is 個多邊形'); // 飛到這個多邊形的位置 // map.fitBounds(polygon.getBounds());

    PART 5: 信息窗口(入口、Popup、定制)?Demo 5

    • 庫引用 如上 Demo 1
    • 畫一個 circle 并綁定一個 Popup
    // 畫一個circle const circle = L.circle([36.92, 121.31], { color: 'green', //描邊色 fillColor: '#f03', //填充色 fillOpacity: 0.5, //透明度 radius: 10000 //半徑,單位米 }).addTo(map); // 綁定一個彈窗 circle.bindPopup('我是個圓');
    • 定位一個 marker,綁定一個自定義 Popup
    // 定位一個maker const marker = L.marker([36.52, 120.31]).addTo(map); //maker上自定義一個popup const html = '<p>Hello world!<br />This is a nice popup.</p>'; const popup = marker.bindPopup(html, { maxHeight: 250, maxWidth: 490, className: 'content', offset: [0, 0] }).on('popupopen', function (params) { console.log(params) });
    • 實現動態改變 Popup 的內容
    const mypop = L.popup();map.on('click', function (e) { mypop.setLatLng(e.latlng) .setContent('你臨幸了這個點:<br>' + e.latlng.toString()) .openOn(map); });

    PART 6: geojson 數據繪制邊界(坐標轉換、渲染)?Demo 6

    • 庫引用 如上 Demo 1
    • 獲得 geojson 并處理數據
    // 請求geojson并處理數據 const population = () => { $.get("./js/geojson.json", function (response) { const poplData = response.data const PolygonsCenter = response.geopoint drawPolygons(poplData, PolygonsCenter) }); } 模擬后臺返回的數據geojson
    • 繪制邊界并添加圖例
    let oPolygon_VilPop = [];const legend = L.control({position: 'bottomright' }); const drawPolygons = (poplData, PolygonsCenter) => { for (const i in poplData) { poplData[i].geoJson = JSON.parse(poplData[i].geoJson) oPolygon_VilPop[i] = L.geoJSON(poplData[i].geoJson, { style: function () { return { color: 'white', fillColor: getBgColor(poplData[i].population), //獲取邊界的填充色 fillOpacity: 0.6, weight: 3, dashArray: '10' }; } }).bindTooltip(poplData[i].villageName + '<br><br>人口' + poplData[i].population + '人', { direction: 'top' }).on({ mouseover: highlight, //鼠標移動上去高亮 mouseout: resetHighlight, //鼠標移出恢復原樣式 click: zoomTo //點擊最大化 }).addTo(oMap); } // 添加圖例 legend.onAdd = legendHtml; legend.addTo(oMap); // 定位到該界限的中心位置 oMap.flyToBounds(PolygonsCenter); } // 添加圖例 legend.onAdd = legendHtml; legend.addTo(oMap); // 定位到該界限的中心位置 oMap.flyToBounds(PolygonsCenter); }
    • 返回邊界的填充色及圖列的樣式
    const getBgColor = (d) => {return d > 400 ? '#800026' : d > 300 ? '#BD0026' : d > 200 ? '#FC4E2A' : d > 100 ? '#FD8D3C' : d > 50 ? '#FED976' : '#FFEDA0'; } const legendHtml = (map) => { let div = L.DomUtil.create('div', 'legend locateVP_legend'), grades = [0, 50, 100, 200, 400], labels = [], from, to; for (let i = 0; i < grades.length; i++) { from = grades[i]; to = grades[i + 1]; labels.push( '<i style="background:' + getBgColor(from + 1) + '"></i> ' + from + (to ? ' &sim; ' + to + '人' : '以上')); } div.innerHTML = labels.join('<br>'); return div; };
    • 鼠標移動上去的事件、鼠標移出的事件、發生點擊的事件
    const highlight = (e) => {let layer = e.target; layer.setStyle({ weight: 6, color: '#fff', fillOpacity: 0.9, dashArray: '0' }) } const resetHighlight = (e) => { let layer = e.target; layer.setStyle({ color: 'white', weight: 3, fillOpacity: 0.6, dashArray: '10' }) } const zoomTo = (e) => { oMap.fitBounds(e.target.getBounds()); }

    寫在后面

    國內常用地圖服務資源加載插件

    Leaflet.ChineseTmsProviders?Provider for Chinese Tms Service
    • Leaflet 調用國內各種地圖的功能十分復雜,幸好有 leaflet.ChineseTmsProviders 這個插件,這四種地圖直接就可以加載進來,十分方便。
    • 使用方法很簡單可點擊上面鏈接去 GitHub 看使用說明,或拉這個 demo下來來瞧一瞧代碼。

    優化 marker 相關的插件

    • 提供了豐富多彩的圖標?Leaflet.awesome-markers, See the?demo map點擊預覽
    • 強大的集聚插件?Leaflet.markercluster, See the?demo map
    • 優化的 label?Leaflet.label, See the?demo map
    • 優化重疊在一起的 markers?OverlappingMarkerSpiderfier-Leaflet, See the?demo map
    • 優化在邊框上顯示不在當前視野中的 marker?Leaflet.EdgeMarker, See the?demo map

    模塊化開發的加載包注意的問題

    • 引 leaflet 包的時候不要忘記引用包里的 css?import 'leaflet/dist/leaflet.css';

    關于 Leaflet 和 esri-leaflet 一起使用 L.esri.TiledMapLayer 加載 ArcGIS 服務切片底圖時,控制臺打印報錯?Uncaught ReferenceError: proj4 is not defined

    • 查看了下源碼?if (!proj4) { warn('L.esri.TiledMapLayer is using a non-mercator spatial reference. Support may be available through Proj4Leaflet http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html');}?問題就出在這里,esri-leaflet 里的一個插件 proj4leaflet 依賴proj4,所以需要手動引入 proj4 這個包。
    • 這個 GitHub 上面的提問及回答?Github esri-leaflet Issues
    • 如果你是模塊化開發,需要再npm i proj4?然后再引入進來好了?import * as proj4 from 'proj4'; window['proj4'] = proj4;
    • 如果你是常規開發,直接添加一個 script 標簽引用 CDN 資源上托管的Proj4js就是了?<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4-src.js"></script>

    Leaflet 學習資料整理

    • Leaflet-Develop-Guide ??-開發文檔及常用插件小結

    參考

    • GIS 制圖樂園 esri-leaflet 入門教程(1)-leaflet 介紹
    • Awesome GIS(GIS Tech Stack 技術棧)
    • 麻辣 GIS Leaflet 學習筆記

    轉載于:https://www.cnblogs.com/Jeely/p/11132288.html

    總結

    以上是生活随笔為你收集整理的入门Leaflet之小Demo的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。