应业务需求变更,需要在内网使用地图并实现打点等功能,由于无法直接使用外网天地图资源,基于项目现有代码做调整。需要将天地图瓦片资源下载到内网服务器,并且将天地图JavaScript API指向到内网服务器,实现在内网使用天地图相关功能。此文章仅作为前端开发、调试过程记录。
1.下载对应天地图api等资源文件并引入
- api.js文件下载地址:api.tianditu.gov.cn/api?v=4.0&t…您的密钥 (密钥通过天地图官网开发资源中注册、申请获得)
- tianditu4.0.css文件下载地址:api.tianditu.gov.cn/v4.0/css/ti…
- components.js文件下载地址:api.tianditu.gov.cn/v4.0/compon…
将以上三个文件放置在项目对应的public文件夹下,并对api文件内容做相应的修改:
- 定义天地图瓦片资源地址
// 为了方便本地开发、调试,前期自行搭建瓦片资源服务(文章后续有记录瓦片下载及服务搭建)。
window.TMAP_URL = 'http://localhost:3000/tiles' // 此处地址暂时使用本地服务地址,后续修改为内网资源服务地址
- 格式化后约57行处,修改瓦片数据请求路径
R: T.Protocol.value + "api.tianditu." + T.Domain + "/apiserver/ajaxproxy?proxyReqUrl=",
r: function () {
return window.TMAP_URL + '/vec_c/'
},
T: function () {
return window.TMAP_URL + '/cva_c/'
},
t: function () {
return window.TMAP_URL + '/vec_w/'
},
Y: function () {
return window.TMAP_URL + '/cva_w/'
},
U: function () {
return window.TMAP_URL + '/img_c/'
},
u: function () {
return window.TMAP_URL + '/cia_c/'
},
I: function () {
return window.TMAP_URL + '/img_w/'
},
i: function () {
return window.TMAP_URL + '/cia_w/'
},
O: function () {
return window.TMAP_URL + '/ter_c/'
},
o: function () {
return window.TMAP_URL + '/cta_c/'
},
P: function () {
return window.TMAP_URL + '/ter_w/'
},
p: function () {
return window.TMAP_URL + '/cta_w/'
},
A: ["./components.js"], // 指向本地文件
a: ["./tianditu4.0.css"],
TMAP_DEFAULT_MAPTYPES: [],
- 修改请求瓦片入参格式(根据与后端协商后修改,此处为了前端本地调试方便简化写法)
// 格式化后约3165行
T.Map.M({
LW: function (t) {
var i = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
i.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.t() + t.x + "/" + t.y + "/" + t.z
: T.w.r() + t.x + "/" + t.y + "/" + t.z
}
var n = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
; (n.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.Y() + t.x + "/" + t.y + "/" + t.z
: T.w.T() + t.x + "/" + t.y + "/" + t.z
}),
(TMAP_NORMAL_MAP = new T.MapType([i, n], "TMAP_NORMAL_MAP", { a: 1 }))
var e = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
e.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.I() + t.x + "/" + t.y + "/" + t.z
: T.w.U() + t.x + "/" + t.y + "/" + t.z
}
var o = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
; (o.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.i() + t.x + "/" + t.y + "/" + t.z
: T.w.u() + t.x + "/" + t.y + "/" + t.z
}),
(TMAP_SATELLITE_MAP = new T.MapType([e], "TMAP_SATELLITE_MAP")),
(TMAP_HYBRID_MAP = new T.MapType([e, o], "TMAP_HYBRID_MAP"))
var s = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
s.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.P() + t.x + "/" + t.y + "/" + t.z
: T.w.O() + t.x + "/" + t.y + "/" + t.z
}
var r = new T.TileLayer("", { minZoom: 1, maxZoom: 18 })
; (r.getTileUrl = function (t) {
return 0 == T.gq.EW
? T.w.p() + t.x + "/" + t.y + "/" + t.z
: T.w.o() + t.x + "/" + t.y + "/" + t.z
}),
(TMAP_TERRAIN_MAP = new T.MapType([s], "TMAP_TERRAIN_MAP")),
(TMAP_TERRAIN_HYBRID_MAP = new T.MapType([s, r], "TMAP_TERRAIN_HYBRID_MAP"))
},
}),
修改前后对比:
在index.html文件中引入
<script src="<%= BASE_URL %>api.js" type="text/javascript"></script>
2.下载天地图瓦片数据
为了方便前端开发、调试,使用地图瓦片下载工具下载部分瓦片数据作为示例。本次使用QGIS软件进行瓦片数据下载,QGIS软件打开天地图地图数据需要下载插件并配置。
- 安装TianDiTu Tools插件
- 配置插件 - 点击设置,在设置弹窗内添加已申请的天地图key
- 选择需要下载的图层
-
打开工具箱,选择“生成XYZ瓦片(目录)”
依次设置需要下载的范围及缩放级别,并选择需要输出的指定文件夹,点击运行等待下载完成。
天地图接口请求的地图瓦片和标注瓦片是不同接口,重复步骤3、4依次下载:cia_w 影像地图标注、cva_w 矢量地图标注、img_w 影像地图、vec_w 矢量地图
3. 基于Express框架搭建服务器并访问瓦片数据
- 安装Express框架
npm init -y # 初始化项目
npm install express --save # 安装Express
- 创建Express服务
const express = require("express")
const app = express()
const path = require("path")
const PORT = 3000
// 设置静态文件目录
// 假设瓦片数据存储在项目的`tiles`目录下
app.use("/tiles", express.static("tiles"))
// 假设瓦片存储在'tiles'目录下,目录结构为'tiles/{n}/{z}/{x}/{y}'
// 接口参数同api.js中配置
app.get("/tiles/:n/:z/:x/:y", (req, res) => {
const n = req.params.n // 图层类型
const z = req.params.z // 行
const x = req.params.x // 列-图片名称
const y = req.params.y // 缩放等级
// 构造瓦片文件的完整路径
const tilePath = path.join(__dirname, "tiles", n, y, z, `${x}.png`)
// 检查文件是否存在
app.use(express.static("tiles"))
res.sendFile(tilePath, (err) => {
if (err) {
if (err.code === "ENOENT") {
// 如果文件不存在,返回404
res.status(404).send(tilePath + " not found")
} else {
// 其他错误
res.status(500).send("服务器内部错误")
}
}
})
})
// 启动服务器
app.listen(PORT, () => {
console.log(`服务器正在监听端口 ${PORT}`)
})
- 将瓦片数据放入项目tiles文件夹下,运行服务器并访问瓦片数据
node server.js
http://localhost:3000/tiles/img_w/1/1/1.png // 访问示例
4. 前端渲染地图并实现打点功能
<template>
<div
id="mapDiv"
style="
height: 800px;
width: 800px;
border: 1px solid black;
border-radius: 10px;
user-select: none;
"
/>
</template>
<script>
export default {
name: "largedatascreen",
data() {
return {
map: null,
autoStationData: [
{
id: 1,
number: "001",
name: "xxxxxxxxxx",
city: "xx",
lng: "81.2293213147951",
lat: "40.5482562913776",
stationType: "xx",
stationLevel: "xx",
creatime: "2022-09-21",
},
{
id: 2,
number: "002",
name: "yyyyyyyyyyyyyyy",
city: "yy",
lng: "86.0602017389291",
lat: "44.2363615256064",
stationType: "yy",
stationLevel: "yy",
creatime: "2023-09-06",
},
{
id: 3,
number: "003",
name: "zzzzzzzzzzzzzzzzzzz",
city: "zz",
lng: "79.0345031681691",
lat: "39.8619961949699",
stationType: "zz",
stationLevel: "zz",
creatime: "2022-07-21",
},
],
};
},
mounted() {
this.initMap();
},
methods: {
// 初始化地图
initMap() {
this.map = new T.Map("mapDiv", {
center: new T.LngLat(87.6168, 43.8256), // 地图中心点
minZoom: 1, // 最小缩放级别
maxZoom: 6, // 最大缩放级别
zoom: 5, // 初始缩放级别
});
this.map.setMapType(TMAP_HYBRID_MAP);
this.autoStationData.map((i) => {
this.onLoad(i);
});
},
onLoad(obj) {
let position = new T.LngLat(obj.lng, obj.lat);
let icon = new T.Icon({
iconUrl: require("@/assets/bigScreen/auto.svg"), //请求图标图片的URL
iconSize: new T.Point(30, 30), //图标可视区域的大小。
iconAnchor: new T.Point(30, 30), //图标的定位锚点
});
let marker = new T.Marker(position, {
icon: icon,
});
this.map.addOverLay(marker);
let infoWin = new T.InfoWindow();
let sContent = `
<div style="margin-top:5px;font-size:1.1rem;">
详情:<br/>
名称:${obj.name}<br/>
经度:${obj.lng}<br/>
纬度:${obj.lat}<br/>
类型:${obj.stationType}<br/>
级别:${obj.stationLevel}<br/>
时间:${obj.creatime}<br/>
</div>
`;
infoWin.setContent(sContent);
marker.addEventListener("click", (e) => {
infoWin.setOffset(new T.Point(-15, 10));
infoWin.setLngLat(e.lnglat);
marker.openInfoWindow(infoWin);
});
},
},
};
</script>
效果图:
地图服务代码及瓦片数据网盘地址:pan.baidu.com/s/1NgHM73VE…
瓦片数据层级只下载到6级,只做调试使用,数据层级没有那么高。