从零搭建离线地图服务:Nginx + Cesium/Leaflet 实战指南

背景与目的

在内网或离线环境下,互联网地图服务无法使用。本文介绍如何通过 Nginx 部署离线地图瓦片服务,并支持 Cesium 和 Leaflet 两种前端地图引擎加载,实现从本地开发到生产环境的无缝迁移。

开发与部署流程

采用"本地先行、无缝迁移"策略:

  1. 本地部署 :Nginx 配置瓦片服务,前端通过 localhost:8001 访问调试
  2. 调试验证 :确认层级切换、坐标偏移等问题解决
  3. 生产部署 :将配置和瓦片复制到服务器,仅修改前端 URL 地址

核心优势 :代码逻辑完全不变,仅需更换服务地址。

一、Nginx 部署离线地图服务

1.1 准备工作

Nginx安装包 瓦片数据 瓦片数据目录示例:

1.2 Nginx 配置

编辑 Nginx 配置文件 conf/nginx.conf,添加以下服务配置:

javascript 复制代码
server {
    listen       8001;
    server_name  localhost;
    location ^~/ {
        root  D:\地图数据\瓦片\tiles;
    }
    
    # CORS 跨域配置(必须添加)
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
    
    # 默认 Content-Type
    default_type application/json;
}

配置说明:

配置项 说明
listen 8001 服务监听端口,可根据需要修改
root 瓦片文件根目录的绝对路径

1.3 启动与验证

启动 Nginx 双击 nginx.exe

验证服务 浏览器访问测试 URL:http://localhost:8010/12/3261/1693.png

如果显示地图瓦片图片,说明服务部署成功。

二、cesium 加载离线瓦片

安装依赖 npm安装

javascript 复制代码
npm install cesium

yarn安装

javascript 复制代码
yarn add cesium

初始化地图并添加瓦片底图 初始化cesium地图

javascript 复制代码
<template>
  <!-- 创建地图容器 -->
  <div id="cesiumContainer" ref="cesiumContainer" style="width: 100%; height: 100%;">
  </div>
</template>
<script setup >
import { ref, onMounted } from 'vue';
import * as Cesium from 'cesium';
const cesiumContainer = ref(null);
const mapViewer = ref(null);
// 初始化地图
const initMap = () => {
  const viewer = new Cesium.Viewer(cesiumContainer.value, {
    animation: false, //是否显示动画控件
    homeButton: false, //是否显示home键
    geocoder: false, //是否显示地名查找控件如果设置为true,则无法查询
    timeline: false, //是否显示时间线控件
    fullscreenButton: false, //是否全屏显示
    scene3DOnly: true, //如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
    shouldAnimate: true,
    infoBox: false, //是否显示点击要素之后显示的信息
    sceneModePicker: false, //是否显示投影方式控件 三维/二维
    navigationInstructionsInitiallyVisible: false,
    navigationHelpButton: false, //是否显示帮助信息控件
    selectionIndicator: false, //是否显示指示器组件
    baseLayerPicker: false, // 禁用底图切换控件
  });
  mapViewer.value = viewer;
  mapViewer.value.camera.flyTo({
    duration: 0,
    destination: Cesium.Cartesian3.fromDegrees(106.55, 29.56, 20000),
  });

  // 添加瓦片底图
  addMapBaseLayer()
};
onMounted(()=>{
  initMap()
})
</script >

添加瓦片方式

javascript 复制代码
// 添加瓦片底图
const addMapBaseLayer = () => {
  const viewer = mapViewer.value;
  if (!viewer) {
    return;
  }
  // 创建UrlTemplateImageryProvider
  const imageryProvider = new Cesium.UrlTemplateImageryProvider({
    url: 'http://localhost:8001/{z}/{x}/{y}.png',
    maximumLevel: 16, // 最大级别,根据你的瓦片数据调整
    minimumLevel: 0, // 最小级别,根据你的瓦片数据调整
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
  });
  // 添加ImageryProvider到Viewer中
  viewer.imageryLayers.addImageryProvider(imageryProvider);
};

三、leaflet 加载离线瓦片

安装依赖

npm 安装

javascript 复制代码
npm install leaflet

yarn 安装

javascript 复制代码
yarn add leaflet

leaflet加载瓦片

javascript 复制代码
<template>
  <!-- 创建地图容器 -->
  <div id="leafletContainer" style="width: 100%; height: 100%;">
  </div>
</template>
<script setup >
import { ref,toRaw, nextTick, onMounted } from 'vue';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
const map = ref(null);
const initMap = () => {
  map.value = L.map('leafletContainer', {
    crs: L.CRS.EPSG3857,
    center: [29.55, 106.52],
    zoom: 12,
    zoomControl: false,
    attributionControl: false,
  });
  // 添加瓦片底图
  L.tileLayer('http://localhost:8001/{z}/{x}/{y}.png', {
    maxZoom: 16,
  }).addTo(toRaw(map.value));
};
onMounted(()=>{
  nextTick(()=>{
    initMap();
  })
})
</script >

CRS 参数说明

crs 用于指定地图使用的坐标参考系, 必须与瓦片数据的坐标系保持一致 ,否则地图会出现位置偏移。

配置值 说明
L.CRS.EPSG3857 Web 墨卡托投影,谷歌地图、高德地图使用
L.CRS.EPSG4326 WGS 84 地理坐标系,经纬度直接投影,天地图使用

效果如下

相关推荐
AlienZHOU4 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc7 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师8 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen9 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒9 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow10 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林81810 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang8007810 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明10 小时前
第 6 章 组件进阶
前端·vue.js
江华森10 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端