成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

入門Leaflet之小Demo

Eminjannn / 990人閱讀

入門 Leaflet 之小 Demo

寫在前面 ---- WebGIS 開發(fā)基礎(chǔ)之 Leaflet

GIS 基本概念:GIS、Map、Layer、Feature、Geometry、Symbol、Data(Point、Polyline、Polygon)、Renderer、Scale、Project、Coordinates;

GIS 開發(fā)概述:架構(gòu)模式、常用平臺(tái)和 SDK、二維三維

使用 Leaflet 開發(fā)常用功能

地圖加載(底圖類型、切換):

地圖操作(縮放、平移、定位/書簽、動(dòng)畫):

圖層管理(加載、移除、調(diào)整順序):

要素標(biāo)繪(點(diǎn)/聚簇、線、面,符號(hào)化/靜態(tài)動(dòng)態(tài)):

屬性標(biāo)注(字段可選、樣式定制):

專題地圖(點(diǎn)、線、面,渲染):

查詢定位(屬性查詢、空間查詢/周邊搜索/緩沖區(qū)/面查點(diǎn)線面/點(diǎn)線查面、圖屬互查、綜合查詢):

信息窗口(入口、Popup、定制):

坐標(biāo)轉(zhuǎn)換(地理與投影、不同地理坐標(biāo)系):

空間運(yùn)算(長度面積測(cè)量、點(diǎn)取坐標(biāo)、緩沖區(qū)、相交包含關(guān)系):

動(dòng)態(tài)監(jiān)控(固定點(diǎn)狀態(tài)切換、車輛監(jiān)控):

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 的一個(gè)扁平化風(fēng)格 web 開發(fā)框架。

leaflet an open-source JavaScript library for mobile-friendly interactive maps.Leaflet 是一個(gè)為建設(shè)交互性好適用于移動(dòng)設(shè)備地圖,而開發(fā)的現(xiàn)代的、開源的 JavaScript 庫。

Esri Leaflet A lightweight set of tools for using ArcGIS services with Leaflet.一個(gè)輕量級(jí)的工具,基于 leaflet 利用 ArcGIS 服務(wù)。

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

庫引用






地圖加載與切換

const map = L.map("mapDiv", {
        crs: L.CRS.EPSG3857, //要使用的坐標(biāo)參考系統(tǒng),默認(rèn)的坐標(biāo)參考系,互聯(lián)網(wǎng)地圖主流坐標(biāo)系
        // crs: L.CRS.EPSG4326, //WGS 84坐標(biāo)系,GPS默認(rèn)坐標(biāo)系
        zoomControl: true,
        // minZoom: 1,
        attributionControl: true,
    }).setView([30.6268660000, 104.1528940000], 18);//定位在成都北緯N30°37′45.58″ 東經(jīng)E104°09′1.44″
    let Baselayer = L.tileLayer(urlTemplate.mapbox_Image, {
       maxZoom: 17, //最大視圖
        minZoom: 2, //最小視圖
        attribution: "[email protected]  ©  {
    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 定位到當(dāng)前位置 Demo 1.1

庫引用 如上 Demo 1



判斷瀏覽器是否支持

    let map;
    let Baselayer;
    // 使用H5 API定位 定位在當(dāng)前位置
    if (navigator.geolocation) {
        console.log("/* 地理位置服務(wù)可用 */")
        navigator.geolocation.getCurrentPosition(h5ApiSuccess, h5ApiError);
    } else {
        console.log("/* 地理位置服務(wù)不可用 */")
        mapInit([30.374558, 104.09144]);//指定一個(gè)數(shù)據(jù) 定位在成都北緯N30°37′45.58″ 東經(jīng)E104°09′1.44″
    }

定位成功或失敗

    const h5ApiSuccess = (position) => {
        let latitude = position.coords.latitude; //緯度
        let longitude = position.coords.longitude; //經(jīng)度
        console.log("你的經(jīng)度緯度分別為" + longitude + "," + latitude + "。")
        return mapInit([latitude, longitude]);
    };

    const h5ApiError = () => {
        console.log("/* 地理位置請(qǐng)求失敗 */")
        mapInit([30.374558, 104.09144]);//指定一個(gè)數(shù)據(jù) 定位在成都北緯N30°37′45.58″ 東經(jīng)E104°09′1.44″
    };

成功后初始化底圖

    const mapInit = (LatLng) => {
        map = L.map("mapDiv", {
            crs: L.CRS.EPSG3857, //要使用的坐標(biāo)參考系統(tǒng),默認(rèn)的坐標(biāo)參考系
            // crs: L.CRS.EPSG4326, //國內(nèi)的坐標(biāo)參考系
            zoomControl: true,
            // minZoom: 1,
            attributionControl: true,
        }).setView(LatLng, 18);//定位在當(dāng)前位置
        Baselayer = L.tileLayer(urlTemplate.mapbox_Image, {
            maxZoom: 17, //最大視圖
            minZoom: 2, //最小視圖
            attribution: "[email protected]  © 

更多了解 geolocation 對(duì)象,可參考MDN Web 文檔

更多了解使用 marker 高亮顯示,可參考leaflet.marker.highlight插件

基于 Demo 1 利用 leaflet 封裝好的 H5 定位 API,定位到當(dāng)前位置 Demo

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

庫引用 如上 Demo 1

設(shè)置地圖縮放到指定圖層

map.setZoom(10, {
  // animate: false
})  //設(shè)置地圖縮放到

圖層往里進(jìn)一個(gè)圖層,放大

map.zoomIn() //圖層往里進(jìn)一個(gè)圖層,放大
//map.zoomOut()  //圖層往里出一個(gè)圖層,縮小

地圖平移至中心點(diǎn)

map.panTo([37.91082, 128.73583], {
    animate: true
}) //地圖平移,默認(rèn)就是true,將地圖平移到給定的中心。如果新的中心點(diǎn)在屏幕內(nèi)與現(xiàn)有的中心點(diǎn)不同則產(chǎn)生平移動(dòng)作。

地圖飛到中心點(diǎn)

map.flyTo([36.52, 120.31]); // 點(diǎn)到點(diǎn)的拋物線動(dòng)畫,平移加縮放動(dòng)畫
注意:盡量避免 setZoom()等地圖縮放方法與 flyTo、flyToBounds 一起合用,因?yàn)檫@兩類地圖操作方法都有各自的縮放值,造成動(dòng)畫不流暢、不能定位到目的點(diǎn)。

地圖飛到邊界的合適的位置

map.flyToBounds(polygon.getBounds());   //getBounds(獲取邊界):返回地圖視圖的經(jīng)緯度邊界。
    //飛到這個(gè)多變形區(qū)域上面,自動(dòng)判斷區(qū)域塊的大小,合適縮放圖層,將地圖視圖盡可能大地設(shè)定在給定的地理邊界內(nèi)。

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);  //地圖上繪制一個(gè)多形

地圖定位到邊界的合適的位置

map.fitBounds(polygon.getBounds());  //getBounds(獲取邊界):返回地圖視圖的經(jīng)緯度邊界。
  //平移到一個(gè)區(qū)域上面,自動(dòng)判斷區(qū)域塊的大小,合適縮放圖層

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);  //地圖上繪制一個(gè)多邊形
PART 3: 圖層管理(加載、移除、調(diào)整順序): Demo 3

庫引用






 

使用 esri-leaflet 插件加載 ArcGIS 底圖服務(wù)

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請(qǐng)求。
    }).addTo(oMap)); //加載第一個(gè)底圖

    oLayer.push(L.esri.tiledMapLayer({
        url: urlTemplate.SYS_CQMap_IMG_LABEL_MAPSERVER_PATH,
        maxZoom: 17,
        minZoom: 0,
        useCors: false,
    }).addTo(oMap));  //加載第二個(gè)底圖

切換底圖(移除及加載)

const setLayer = (layerUrls, maxZoom) => {
        for (let i = 0; i < oLayer.length; i++) {
            oMap.removeLayer(oLayer[i]) //將圖層在地圖上移除
        }
        oLayer = [] //制空數(shù)組
        layerUrls.map((item) => {
            oLayer.push(L.esri.tiledMapLayer({
                url: item,
                useCors: false,
                maxZoom: maxZoom, // 設(shè)置最大放大圖層值
            }).addTo(oMap));
        })
    }
不同的底圖可能圖層數(shù)不一樣,就可能造成瀏覽器去請(qǐng)求不存在的圖層,以及給用戶展示出空白區(qū)域的不好體驗(yàn),所以切換圖層時(shí)候應(yīng)注意設(shè)置最大及最小縮放值。
PART 4: 要素標(biāo)繪(點(diǎn)、線、面,符號(hào)化/靜態(tài)動(dòng)態(tài)) Demo 4

庫引用 如上 Demo 1

畫一個(gè)圓

// 畫一個(gè)circle
const circle = L.circle([36.52, 120.31], {
  color: "green", //描邊色
  fillColor: "#f03",  //填充色
  fillOpacity: 0.5, //透明度
  radius: 10000 //半徑,單位米
}).addTo(map);
// 綁定一個(gè)提示標(biāo)簽
circle.bindTooltip("我是個(gè)圓");

Maker 及自定義 Maker

// 做一個(gè)maker
const marker = L.marker([36.52, 120.31]).addTo(map);
// 綁定一個(gè)提示標(biāo)簽
marker.bindTooltip("這是個(gè)Marker", { direction: "left" }).openTooltip();


//自定義一個(gè)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);
// 綁定一個(gè)提示標(biāo)簽
oMarker.bindTooltip("這是個(gè)自定義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);
// 飛到這個(gè)線的位置
// map.fitBounds(polyline.getBounds());

畫一個(gè)多邊形

// 畫一個(gè)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);
// 綁定一個(gè)提示標(biāo)簽
polygon.bindTooltip("this is 個(gè)多邊形");
// 飛到這個(gè)多邊形的位置
// map.fitBounds(polygon.getBounds());
PART 5: 信息窗口(入口、Popup、定制) Demo 5

庫引用 如上 Demo 1

畫一個(gè) circle 并綁定一個(gè) Popup

// 畫一個(gè)circle
const circle = L.circle([36.92, 121.31], {
 color: "green", //描邊色
 fillColor: "#f03",  //填充色
 fillOpacity: 0.5, //透明度
 radius: 10000 //半徑,單位米
}).addTo(map);

// 綁定一個(gè)彈窗
circle.bindPopup("我是個(gè)圓");

定位一個(gè) marker,綁定一個(gè)自定義 Popup

// 定位一個(gè)maker
const marker = L.marker([36.52, 120.31]).addTo(map);

//maker上自定義一個(gè)popup
const html = "

Hello world!
This is a nice popup.

"; const popup = marker.bindPopup(html, { maxHeight: 250, maxWidth: 490, className: "content", offset: [0, 0] }).on("popupopen", function (params) { console.log(params) });

實(shí)現(xiàn)動(dòng)態(tài)改變 Popup 的內(nèi)容

const mypop = L.popup();

map.on("click", function (e) {
  mypop.setLatLng(e.latlng)
    .setContent("你臨幸了這個(gè)點(diǎn):
" + e.latlng.toString()) .openOn(map); });
PART 6: geojson 數(shù)據(jù)繪制邊界(坐標(biāo)轉(zhuǎn)換、渲染) Demo 6

庫引用 如上 Demo 1

獲得 geojson 并處理數(shù)據(jù)

// 請(qǐng)求geojson并處理數(shù)據(jù)
const population = () => {
    $.get("./js/geojson.json", function (response) {
        const poplData = response.data
        const PolygonsCenter = response.geopoint
        drawPolygons(poplData, PolygonsCenter)
    });
}
模擬后臺(tái)返回的數(shù)據(jù)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 + "

人口" + poplData[i].population + "人", { direction: "top" }).on({ mouseover: highlight, //鼠標(biāo)移動(dòng)上去高亮 mouseout: resetHighlight, //鼠標(biāo)移出恢復(fù)原樣式 click: zoomTo //點(diǎn)擊最大化 }).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(
            " " +
            from + (to ? " ∼ " + to + "人" : "以上"));
    }
    div.innerHTML = labels.join("
"); return div; };

鼠標(biāo)移動(dòng)上去的事件、鼠標(biāo)移出的事件、發(fā)生點(diǎn)擊的事件

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());
}
寫在后面 國內(nèi)常用地圖服務(wù)資源加載插件
Leaflet.ChineseTmsProviders Provider for Chinese Tms Service

Leaflet 調(diào)用國內(nèi)各種地圖的功能十分復(fù)雜,幸好有 leaflet.ChineseTmsProviders 這個(gè)插件,這四種地圖直接就可以加載進(jìn)來,十分方便。

使用方法很簡單可點(diǎn)擊上面鏈接去 GitHub 看使用說明,或拉這個(gè) demo下來來瞧一瞧代碼。

優(yōu)化 marker 相關(guān)的插件

提供了豐富多彩的圖標(biāo) Leaflet.awesome-markers, See the demo map

強(qiáng)大的集聚插件 Leaflet.markercluster, See the demo map

優(yōu)化的 label Leaflet.label, See the demo map

優(yōu)化重疊在一起的 markers OverlappingMarkerSpiderfier-Leaflet, See the demo map

優(yōu)化在邊框上顯示不在當(dāng)前視野中的 marker Leaflet.EdgeMarker, See the demo map

模塊化開發(fā)的加載包注意的問題

引 leaflet 包的時(shí)候不要忘記引用包里的 css import "leaflet/dist/leaflet.css";

關(guān)于 Leaflet 和 esri-leaflet 一起使用 L.esri.TiledMapLayer 加載 ArcGIS 服務(wù)切片底圖時(shí),控制臺(tái)打印報(bào)錯(cuò) 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 里的一個(gè)插件 proj4leaflet 依賴proj4,所以需要手動(dòng)引入 proj4 這個(gè)包。

這個(gè) GitHub 上面的提問及回答 Github esri-leaflet Issues

如果你是模塊化開發(fā),需要再npm i proj4 然后再引入進(jìn)來好了 import * as proj4 from "proj4"; window["proj4"] = proj4;

如果你是常規(guī)開發(fā),直接添加一個(gè) script 標(biāo)簽引用 CDN 資源上托管的Proj4js就是了

Leaflet 學(xué)習(xí)資料整理

Leaflet-Develop-Guide

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93420.html

相關(guān)文章

  • leaflet 入門視頻

    摘要:優(yōu)酷騰訊控件優(yōu)酷騰訊控件優(yōu)酷騰訊控件優(yōu)酷騰訊控件屬性優(yōu)酷騰訊屬性設(shè)置優(yōu)酷騰訊設(shè)置和事件優(yōu)酷騰訊更多內(nèi)容,請(qǐng)關(guān)注公眾號(hào)二維碼 hello world 優(yōu)酷 騰訊 leaflet 控件 zoom優(yōu)酷 騰訊 leaflet 控件 scale優(yōu)酷 騰訊 leaflet 控件 layers優(yōu)酷 騰訊 leaflet 控件 屬性優(yōu)酷 騰訊 leaflet UILayer m...

    silvertheo 評(píng)論0 收藏0
  • leaflet 入門視頻

    摘要:優(yōu)酷騰訊控件優(yōu)酷騰訊控件優(yōu)酷騰訊控件優(yōu)酷騰訊控件屬性優(yōu)酷騰訊屬性設(shè)置優(yōu)酷騰訊設(shè)置和事件優(yōu)酷騰訊更多內(nèi)容,請(qǐng)關(guān)注公眾號(hào)二維碼 hello world 優(yōu)酷 騰訊 leaflet 控件 zoom優(yōu)酷 騰訊 leaflet 控件 scale優(yōu)酷 騰訊 leaflet 控件 layers優(yōu)酷 騰訊 leaflet 控件 屬性優(yōu)酷 騰訊 leaflet UILayer m...

    Noodles 評(píng)論0 收藏0
  • 發(fā)個(gè)微信小程序的demo

    摘要:是存放小程序頁面的文件夾。相當(dāng)于,每個(gè)文件對(duì)應(yīng)一個(gè)和文件,命名必須相同。最后附上源碼下載地址微信小程序之小閱讀 引言:微信小程序的發(fā)布已經(jīng)有一周了,網(wǎng)上到處都炸開了鍋,身為一個(gè)前端小菜鳥,覺得是時(shí)候提升一下格了, 于是乎,趕緊補(bǔ)一個(gè)小小的demo(微信小程序之小閱讀),望勿噴! 進(jìn)入項(xiàng)目 showImg(https://segmentfault.com/img/bVDGkm?w=6...

    lieeps 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<