天地图卫星影像下载

一、账号注册及Key获取

1.进入天地图官网:天地图API,点击控制台进行账号注册。

2.登录成功后点击控制台,选择应用管理,创建新应用。

配置好你就可以获得对于的Key了,如下图所示

二、地图数据下载GeoJSON

1.打开天地图服务中心下载地图数据天地图 服务中心

2.下载你需要的数据,假设我需要下载两个数据,分别是全国数据和嘉兴市的地图数据。

全国数据的下载,按如下配置好后点击下载数据,等待下载完成即可:

嘉兴市数据的下载,在选择地区选择好省市开始下载即可:

浏览器下载好数据应该如下显示:

三、QGIS软件中添加并显示对应地图数据

1.在 QGIS 中添加天地图服务

  你需要分别添加卫星影像底图和地名注记图层。

(1)在 QGIS 的“浏览器”面板中,找到 XYZ Tiles,右键点击并选择 新建连接...

(2)添加卫星影像底图:在点开新建连接后把Name和URL配置好并点击确定。

卫星影像底图的链接:天地图API

注意:

这里的配置都是两两配对的,比如我用的是影像底图:

http://t0.tianditu.gov.cn/img_w/wmts?tk=您的密钥球面墨卡托投影

那么对应使用的影像注记就是:

http://t0.tianditu.gov.cn/cia_w/wmts?tk=您的密钥球面墨卡托投影

当前给的路径并不是正确的,需要完整的路径应该是:

https://t0.tianditu.gov.cn/img\_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的密钥

https://t0.tianditu.gov.cn/cia\_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的密钥

你只要在对应的“你的密钥”的位置填入你的第一步获得的密钥即可。

接下来,我们回归主体,在下图新建连接里面分别填入(填入的名称Name可以随意):

Name:TDT Satellite

URL:https://t0.tianditu.gov.cn/img\_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=你的密钥

然后就可以点击确定后,双击那个你已经新建的连接,效果如下则说明你成功添加了:

(3)添加影像注记图层(和上述步骤2类似) :在点开新建连接后把Name和URL配置好并点击确定。效果如下:

注意:图层Layers谁在上面优先显示谁,如下图

示例地址:

影像: http://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的密钥
影像注记:http://t0.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=你的密钥

2.在 QGIS 中添加地图数据GeoJSON并下载对应离线的地图数据 :

(1)将之前下载好的地图数据拖入QGIS软件中,效果如下:

(2)使用插件生成地图瓦片包:

1)安装插件:

点击菜单栏 插件 -> 管理并安装插件...

在搜索框中输入 QTiles,找到后点击“安装插件”

2)打开插件: 安装成功后,在工具栏上找到它的图标。

3)配置参数,当前我打算下载中国地图瓦片包,具体配置(全国地图级别ZOOM一般是0-10,市级别的用10-15)如下图:

output的参数可以通过点击右侧的更多三个点的按钮,按如下配置:

配置好后单击run等待其下载完毕。

上****面之前说过,地图数据需要成对下载,刚刚下载了影像底图,现在下对应的影像注记,记住layers的图层需要切换为注记的那个连接,然后依次配置好开始下载:

接下来是嘉兴市的影像底图和对应的对应的影像注记,配置如下:

(3)配置地图config.json:

假设你已经下好了大量的地图数据:

我们需要一个json文件来做映射配置,方便地图服务的部署:

例如我的config.json内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"options": {
"paths": {
"root": "/data",
"mbtiles": "/data"
}
},
"data": {
"chinac_img_w_0_10": {
"mbtiles": "chinac_img_w_0_10.mbtiles"
},
"china_cia_w_0_10": {
"mbtiles": "china_cia_w_0_10.mbtiles"
},
"jiaxin_img_w_10_15": {
"mbtiles": "jiaxin_img_w_10_15.mbtiles"
},
"jiaxin_cia_w_10_15": {
"mbtiles": "jiaxin_cia_w_10_15.mbtiles"
}
}
}

以上完成后还需要用下文的docker来运行地图服务。

3.在 QGIS 中添加地图数据GeoJSON并下载对应离线的地图数据 :

(1)重新拉取 Docker 镜像

首先,你需要从打开Docker Desktop后在命令提示符或powershell重新拉取 maptiler/tileserver-gl 镜像(注意:你需要开启vpn连接外网才可以,否则会连接超时)。打开您的终端(Terminal)并执行以下命令:

1
docker pull maptiler/tileserver-gl一键获取完整项目代码

(2)查找下载好的镜像名称

1
docker images一键获取完整项目代码

你会看到一个列表,类似这样:

(3)运行容器

现在,你的离线镜像已经成功加载并准备就绪,通过以下命令启动你的地图服务:

把在我本地的地图项目启动起来:将容器的8080端口映射到主机的8083端口:

1
docker run --rm -it -p 8083:8080 -v "C:\Users\dddsg\Desktop\mymapTiles":/data maptiler/tileserver-gl:latest一键获取完整项目代码

C:\Users\dddsg\Desktop\mymapTiles是你下载好的瓦片包:

注意:在测试过程中我遇到bug,我执行结果如下:

1
C:\Users\dddsg>docker run --rm -it -p 8083:8080 -v "C:/Users/dddsg/Desktop/公安项目/地图服务相关/mymapTiles":/data maptiler/tileserver-gl:latestWARNING: The requested image's platform (linux/arm64) does not match the detected host platform (linux/amd64/v3) and no specific platform was requestedStarting tileserver-gl v5.3.1Using specified config file from config.jsonStarting serverListening at http://[::]:8080/SQLITE_READONLY: attempt to write a readonly database一键获取完整项目代码

报错说我的文件夹是只读无法写入,应该是在桌面创建文件夹导致的,你需要把里面的文件移到一个新的你自己创建的文件夹,例如我之后执行:

docker run –rm -it -p 8083:8080 -v “C:/Users/dddsg/Desktop/公安项目/地图服务相关/mymap”:/data maptiler/tileserver-gl:latest

其中C:/Users/dddsg/Desktop/公安项目/地图服务相关/mymap 就是我自己新建的项目,执行后

在浏览器中的地址栏写入:

1
http://localhost:8083/一键获取完整项目代码

这是我们映射的端口,效果图如下:

这说明我们本地的项目成功跑起来了,恭喜你完成到这一步,接下来在vscode部署实现地图的展示。

备注

注意事项

  1. 使用插件下载瓦片之前,一定要先将不相关图层都隐藏掉(取消勾选),否则QGIS中显示的是什么效果,下载下来就是什么效果(比如如果加载了全国的geojson数据,那么下载的切片也会有这个矢量数据,这是不对的)。
  2. 下载文字标注切片时,要配置额外的参数。需要Parameters中的Background transparency数据设置为0,否则默认为255,是不透明的,会遮挡我们的真实影像。下载影像瓦片时则将该项设置为255

切片发布

1
npx http-server ./tiles -p 8000

需要有 node 环境,当然使用其他方式也可。

测试调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
<!doctype html>
<html lang="en">

<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/openlayers/8.1.0/ol.min.css" type="text/css">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
.map {
height: 100%;
width: 100%;
}
.zoom-control {
position: absolute;
top: 15px;
right: 15px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
padding: 16px;
border-radius: 12px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1);
z-index: 1000;
min-width: 280px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
border: 1px solid rgba(0, 0, 0, 0.08);
}
.zoom-control .control-group {
margin-bottom: 12px;
}
.zoom-control .control-group:last-child {
margin-bottom: 0;
}
.zoom-control label {
display: block;
font-size: 13px;
font-weight: 600;
color: #333;
margin-bottom: 8px;
letter-spacing: 0.3px;
}
.zoom-control .input-group {
display: flex;
align-items: center;
gap: 8px;
}
.zoom-control input[type="number"] {
flex: 1;
padding: 8px 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
transition: all 0.2s ease;
background: white;
color: #333;
}
.zoom-control input[type="number"]:focus {
outline: none;
border-color: #4a90e2;
box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
}
.zoom-control button {
padding: 8px 16px;
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
color: white;
border: none;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
white-space: nowrap;
box-shadow: 0 2px 4px rgba(74, 144, 226, 0.3);
}
.zoom-control button:hover {
background: linear-gradient(135deg, #357abd 0%, #2a5f8f 100%);
box-shadow: 0 4px 8px rgba(74, 144, 226, 0.4);
transform: translateY(-1px);
}
.zoom-control button:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(74, 144, 226, 0.3);
}
.zoom-control .slider-group {
display: flex;
align-items: center;
gap: 10px;
}
.zoom-control input[type="range"] {
flex: 1;
height: 6px;
border-radius: 3px;
background: #e0e0e0;
outline: none;
-webkit-appearance: none;
cursor: pointer;
}
.zoom-control input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
cursor: pointer;
box-shadow: 0 2px 6px rgba(74, 144, 226, 0.4);
transition: all 0.2s ease;
}
.zoom-control input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.1);
box-shadow: 0 3px 8px rgba(74, 144, 226, 0.5);
}
.zoom-control input[type="range"]::-moz-range-thumb {
width: 18px;
height: 18px;
border-radius: 50%;
background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%);
cursor: pointer;
border: none;
box-shadow: 0 2px 6px rgba(74, 144, 226, 0.4);
transition: all 0.2s ease;
}
.zoom-control input[type="range"]::-moz-range-thumb:hover {
transform: scale(1.1);
box-shadow: 0 3px 8px rgba(74, 144, 226, 0.5);
}
.zoom-control input[type="range"]::-moz-range-track {
height: 6px;
border-radius: 3px;
background: #e0e0e0;
}
.zoom-control #zoom-display {
min-width: 45px;
padding: 6px 10px;
background: #f5f5f5;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
color: #4a90e2;
text-align: center;
font-variant-numeric: tabular-nums;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/openlayers/8.1.0/dist/ol.js"></script>
<title>OpenLayers example</title>
</head>

<body>
<div id="map" class="map"></div>
<div class="zoom-control">
<div class="control-group">
<label>Zoom级别</label>
<div class="input-group">
<input type="number" id="zoom-input" step="0.1" value="12" min="0" max="20">
<button onclick="setZoom()">设置</button>
</div>
</div>
<div class="control-group">
<label>缩放滑块</label>
<div class="slider-group">
<input type="range" id="zoom-slider" step="0.1" value="12" min="0" max="20" oninput="updateZoomFromSlider(this.value)">
<span id="zoom-display">12.0</span>
</div>
</div>
</div>
</body>
<script type="text/javascript">
let key = `你的api key`

// _w表示球面墨卡托投影,_c表示经纬度投影
// 如img_w:影像底图球面墨卡托投影,img_c:影像底图经纬度投影

var img_w = new ol.layer.Tile({
title: "影像图",
source: new ol.source.XYZ({
// url: "http://t{0-7}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + key + "",
url: 'http://localhost:8000/china_tdt_img_w/{z}/{x}/{y}.png'
}),
});
var cia_w = new ol.layer.Tile({
title: "影像图文字标注",
source: new ol.source.XYZ({
// url: "http://t{0-7}.tianditu.gov.cn/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=" + key + "",
url: "http://localhost:8000/china_tdt_cia_w/{z}/{x}/{y}.png"
}),
});


let view = new ol.View({
center: ol.proj.fromLonLat([111.32034, 38.27778]),
zoom: 12,
// minZoom: 12,
// maxZoom: 18.5,
})

var map = new ol.Map({
target: 'map',
// logo: false, // 隐藏右下角的logo
layers: [img_w, cia_w],
view: view,

// 加载控件到地图容器中
// controls: ol.control.defaults({
// zoom: false, // 隐藏缩放按钮
// rotate: false, // 隐藏方向按钮
// attribution: false // 隐藏右下角logo
// })
});

// 监听zoom变化并打印
view.on('change:resolution', function() {
var zoom = view.getZoom();
console.log('当前Zoom级别:', zoom);
// 更新显示
document.getElementById('zoom-display').textContent = zoom.toFixed(1);
document.getElementById('zoom-input').value = zoom.toFixed(1);
document.getElementById('zoom-slider').value = zoom.toFixed(1);

// 当zoom级别超过11级时,清空地图上的旧数据
if (zoom > 11) {
// 清空影像图层数据
img_w.getSource().clear();
// 清空标注图层数据
cia_w.getSource().clear();
}
});

// 设置zoom级别
function setZoom() {
var zoomValue = parseFloat(document.getElementById('zoom-input').value);
if (!isNaN(zoomValue) && zoomValue >= 0 && zoomValue <= 20) {
view.setZoom(zoomValue);
console.log('设置Zoom级别为:', zoomValue);
}
}

// 从滑块更新zoom
function updateZoomFromSlider(value) {
var zoomValue = parseFloat(value);
view.setZoom(zoomValue);
document.getElementById('zoom-display').textContent = zoomValue.toFixed(1);
document.getElementById('zoom-input').value = zoomValue.toFixed(1);
console.log('Zoom级别已更新为:', zoomValue);
}

// 输入框回车键支持
document.getElementById('zoom-input').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
setZoom();
}
});

// 初始化时打印一次
console.log('初始Zoom级别:', view.getZoom());
</script>

</html>

天地图卫星影像下载
https://silengzi.github.io/cube-fluid-blod/2025/11/11/天地图卫星影像下载/
作者
silengzi
发布于
2025年11月11日
许可协议