動態

詳情 返回 返回

leaflet框選範圍下載地圖離線瓦片:以高德地圖為例(附源碼下載) - 動態 詳情

demo源碼運行環境以及配置

  • 運行環境:依賴Node安裝環境,demo本地Node版本:14.19.1。
  • 運行工具:vscode或者其他工具。
  • 配置方式:下載demo源碼,vscode打開,然後順序執行以下命令:
    (1)下載demo環境依賴包命令:npm i
    (2)啓動Node後端接口命令:node nodeServer.js
    (3)打包demo命令: npm run build
    (4)直接打開index.html頁面即可瀏覽

示例效果



  • 前端核心源碼
import L from "leaflet";
import "@geoman-io/leaflet-geoman-free";
import "leaflet.vectorgrid"; //引用矢量瓦片插件
let TileLnglatTransform = require("tile-lnglat-transform"); //  用於經緯度轉換為瓦片座標
let x1, y1, x2, y2;
// 根據地圖平台使用轉換類
let TileLnglatTransformGaode = TileLnglatTransform.TileLnglatTransformGaode;
let tileALL = []; // 保存所有層級瓦片座標等信息
const httpRequest = "http://localhost:8888";
const api = `${httpRequest}/api/downloadMap`;
initMap();
function initMap() {
  const map = L.map("map", {
    attributionControl: false,
  }).setView([23.56, 113.23], 14);
  L.tileLayer(
     "http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
     { subdomains: ["1", "2", "3", "4"], crossOrigin: true }
  ).addTo(map);
  map.pm.addControls({
    position: "topleft",
    drawMarker: false,
    drawCircleMarker: false,
    drawPolyline: false,
    drawRectangle: true,
    drawPolygon: false,
    drawCircle: false,
    drawText: false,
    editMode: false,
    dragMode: false,
    cutPolygon: false,
    removalMode: true,
    rotateMode: false,
  });
  map.pm.setLang("zh");
  map.on("pm:create", (e) => {
    // console.log(e);
    // 左下角
    const southWest = e.layer._bounds._southWest;
    // 右上角
    const northEast = e.layer._bounds._northEast;
    (x1 = southWest.lng), (y1 = northEast.lat); // 起始點座標(左上角)
    (x2 = northEast.lng), (y2 = southWest.lat); // 終點座標(右下角)
    tileALL = [];
    const minzoom = Number($("#minZoom").val());
    const maxzoom = Number($("#maxZoom").val());
    for (let i = minzoom; i <= maxzoom; i++) {
      tileALL[i] = {};
      let p1 = TileLnglatTransformGaode.lnglatToTile(x1, y1, i);
      let p2 = TileLnglatTransformGaode.lnglatToTile(x2, y2, i);
      tileALL[i].t = i; // 層級
      tileALL[i].x = [p1.tileX, p2.tileX]; // 瓦片橫座標範圍(左至右)
      // tileALL[i].y = [p2.tileY, p1.tileY]; // 瓦片縱座標範圍(下至上)
      tileALL[i].y = [p1.tileY, p2.tileY]; // 瓦片縱座標範圍(下至上)
    }
    // console.log("tileALL:",tileALL);
  });
  $("#downloadMap_Btn").click(function () {
    if (tileALL.length === 0) return;
    const minzoom = Number($("#minZoom").val());
    const maxzoom = Number($("#maxZoom").val());
    $.ajax({
      type: "POST",
      url: api,
      data: {
        tileALL: tileALL,
        minzoom: minzoom,
        maxzoom: maxzoom,
      },
      success: function (res) {
        console.log("res", res);
      },
      error: function (e) {
        console.error("請求接口失敗:", e);
      },
    });
  });
}

  • 後端核心源碼
// 1.引入框架
// node項目採用 common.js,不能採用 import 引入,只能用 require 方式
const express = require("express");
let request = require("request"); // 用於請求瓦片地圖
let bagpipe = require("bagpipe"); //  用於異步請求數量控制
// 引入fs文件讀寫模塊
const fs = require("fs");
const os = require("os");
const cors = require("cors");

let bag = new bagpipe(100, { timeout: 2000 }); //限制請求數,此處為100,可根據網絡情況修改
let mapPath = "./tiles"; // 瓦片目錄


// 服務端口
const port = 8888;
// 2.創建應用
const app = express();
app.use(express.urlencoded());
// 3.創建路由規則
// get請求
// 下載範圍內離線地圖瓦片接口
app.post("/api/downloadMap", (req, response) => {
  downloadMap(req, response);
});
//放開所有跨域
app.use(cors());
// 4.監聽端口啓動服務
app.listen(port, () => {
  console.log("server is running at: http://localhost:" + port);
  console.log("server start on: http://" + getIPv4() + ":" + port);
});
……

下載源碼:GIS之家的學習交流圈

user avatar fkxxgis 頭像
點贊 1 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.