天地图私有化部署笔记
整体思路:先下载离线瓦片地图,然后通过地图服务软件部署在本地服务器上,通过域名或IP地址进行访问和使用。
天地图瓦片地图下载
找了网上很多资料,发现天地图的瓦片地图下载主要分为两种方式:
其中第一种是通过地图软件下载,比如QGIS 下载一个天地图的插件,即可很方便地加载出天地图了,然后将加载出来的天地图导出即可,或者通过瓦片地图下载插件进行下载。
这种方式很方便,但是对于不熟悉这一块内容的人来说,加载出来的地图不确定是否符合要求【比如坐标系、投影方式等参数】,本人期间也踩了不少坑:在网上大致搜了一下之后,发现QGIS是一个开源的地图处理软件,便尝试通过QGIS来处理地图,经过一番折腾之后(安装QGIS,申请天地图API,查看调用URL,安装QGIS中处理天地图的插件[TianDiTu Tool]、导入相关参数[密钥]),发现确实可以加载出天地图,但是发现QGIS加载出来的天地图的默认坐标系是WGS84 EPSG:3857,这与需要的CGCS2000 EPSG:4490的坐标系完全不一样。即使URL中指定CGCS2000坐标系,加载出来的也是WGS84坐标系的地图。
虽然在网上查询相关资料都说WGS84坐标系与CGCS2000坐标系差别不大,误差只有厘米级,但是对于实现厘米级精度的定位的需求来说,WGS84坐标系是无法满足的。且QGIS中图层的CRS属性和QGIS界面右下角的CRS傻傻分不清,也不知道这两者有何关系,总之,对于新手想通过QGIS来下载瓦片地图来说,网上的相关资料要么模棱两可,要么本身也解释不清楚,再加上软件迭代的问题,对新手很不友好。【要是有大佬出一个详细的教程就好了,可以少走很多弯路】于是便放弃这个方式。
第二种方式则是通过脚本代码下载。最简单的就是通过python脚本来下载瓦片地图,只需要知道瓦片地图的URL,即可灵活将瓦片地图下载至本地。然后再通过MapServer等地图服务软件或库将瓦片地图部署在本地服务器上。
以下是下载瓦片地图的记录:
1.天地图API密钥申请
天地图官方网址:https://www.tianditu.gov.cn/
先注册账号:
注册账号之后登录:
按照指引申请成为天地图开发者:
进入控制台,创建新应用:
按照提示填写相关信息:
由于我是要通过脚本代码下载瓦片地图,所以应用类型选择了服务端,浏览器端的密钥无法响应脚本,不过两个都可以分别创建一个,浏览器端的密钥可以很直观方便地查看需要下载的瓦片地图切片是否正确。得到API密钥之后就可以进行调用了。
2.天地图瓦片地图调用URL
可以参考以下链接中的内容:
http://lbs.tianditu.gov.cn/server/MapService.html
地图瓦片获取中的示例,可以修改img_w、LAYER、TILEMATRIXSET等参数来查看不同的地图图层,比如需要查看经纬度投影的矢量底图,则URL如下:
http://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=您的密钥
其中TILEMATRIX是瓦片地图的缩放级别,TILEROW是瓦片地图的行号,TILECOL是瓦片地图的列号。
在浏览器输入以下URL:
https://t0.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX=1&TILEROW=0&TILECOL=1&tk=密钥
到这一步之后,如果需要限定范围来下载瓦片地图,就需要实现通过经纬度反向计算出瓦片地图的行列号;如果不需要限定范围,则可全部下载。
3.经纬度反算瓦片地图行列号
计算原理可参考下面链接:
http://t.csdnimg.cn/IH21I
python脚本如下:
import requests
import os
import math
import random
from enum import Enum, auto
# 经纬度转换瓦片行列数
class datum_id(Enum):
WGS84 = auto()
CGCS2000 = auto()
def get_tile_num(lat,lng,zoom,datum_id:datum_id): #不同的坐标系瓦片排列方式不同
if datum_id == datum_id.CGCS2000:
row = math.floor((90-lat)*2**zoom/360)
col = math.floor((lng+180)*2**zoom/360)
elif datum_id == datum_id.WGS84:
row = math.floor((1-(math.log(math.tan(lat*math.pi/180)+1/math.cos(lat*math.pi/180))/math.pi))*2**(zoom-1))
col = math.floor(((lng+180)/360)*2**zoom)
return col,row
# 下载瓦片
def download_tile(url,zoom,col,row,file_root_path,tk):
# 格式化url
tile_url = url.format(num=random.randint(0, 7), x=col, y=row, z=zoom, tk=tk)
try:
r = requests.get(tile_url)
r.raise_for_status() #如果状态码不是200,将抛出异常
tile_filename = f"{zoom}\{row}\{col}.png"
tile_filepath = os.path.join(file_root_path,tile_filename)
if not os.path.exists(tile_filepath):
os.makedirs(tile_filepath)
# 以二进制写入
with open(tile_filepath,"wb") as f:
f.write(r.content)
except requests.exceptions.HTTPError as http_err:
print(f"HTTP错误: {http_err}")
except requests.exceptions.RequestException as req_err:
print(f"请求错误: {req_err}")
except Exception as e:
print(f"未知错误: {e}")
4.批量下载:
CGCS2000:
纵横比为2:1 每一级的瓦片数量为2^(2n-1)
行数: 2^(n-1)
列数:2^n
矢量底图:vec_c
矢量注记:cva_c
全球境界:ibo_c
python 脚本:
zoom = 9
# 瓦片地图经纬度范围
left_bottom = {'lat':75.51231554958804,'lng':112.91909196472896}
right_top = {'lat':75.51231554958804,'lng':113.00977648647161}
tk_web = "web_key"
tk_server = "server_key"
tk = tk_server
url = "https://t{num}.tianditu.gov.cn/cva_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TileCol={x}&TileRow={y}&TileMatrix={z}&tk={tk}"
file_root_path = "C:\\Tiles\\mark"
def d_function(url,tk,left_bottom,right_top,zoom,file_root_path):
# for z in range(zoom):
right_top_col,right_top_row = get_tile_num(right_top['lat'],right_top['lng'],zoom)
left_bottom_col,left_bottom_row = get_tile_num(left_bottom['lat'],left_bottom['lng'],zoom)
# 按行下载
for row in range(right_top_row,left_bottom_row+1):
for col in range(left_bottom_col,right_top_col+1):
download_tile(url,10,col,row,file_root_path,tk)
d_function(url,tk,left_bottom,right_top,zoom,file_root_path)
也可以通过以下链接,直接下载,这个很方便:
https://zhnny.github.io/online-map-download/
文章链接为:https://www.cnblogs.com/jiujiubashiyi/p/18167871
5.QGIS打开下载的本地瓦片地图
6.将地图作为http服务部署
如果通过QGIS Server来做为服务器软件,则需要先在服务器上安装QGIS和QGIS Server
QGIS Server安装可以参考下面的链接:
https://www.cnblogs.com/unlockth/p/14767649.html
并配置好HTTP服务。
剩下的可以参照官方指导文档,链接如下:
https://www.osgeo.cn/qgis-tutorial/server-usage.html#google_vignette
a.打开工程属性:
b.在QGIS Server选项中的服务功能栏,点开启用服务功能:
c.WMS栏的配置如下:
d.WMTS栏配置如下,图层名称可以修改:
e.由于下载的地图都是图片形式,所以WFS/OAPIP栏没有图层,WCS配置如下:
配置好之后点击Apply即可
f.保存工程文件到qgis server/apps/qgis-ltr/bin目录下,即QGIS Server中的qgis_mapserv.fcgi.exe文件同目录下,需保证下图中标记的三个文件处于同一目录下。demo.qgz即项目工程文件。
g.在本地访问:
http://localhost:2120/qgis-ltr/qgis_mapserv.fcgi.exe?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&MAP=path/to/your/demo.qgz&LAYERS=TianDiTu&CRS=EPSG:4326&WIDTH=4000&HEIGHT=2000&BBOX=-90,-180,90,180
开放端口后,其他用户也可通过服务器的IP地址或者域名访问: