测试使用Python GDAL 下载Mapbox瓦片地图及拼接

20 篇文章 7 订阅

测试使用 Python GDAL 下载 Mapbox 瓦片地图及拼接

本教程将展示如何以编程方式从网络地图(通常称为瓦片地图)瓦片服务器下载地图图像,对其进行地理参考(设置坐标系)并将其保存为GeoTIFF。

Code

import lib

#!/usr/bin/env python
# coding: utf-8
import urllib.request
import os
from math import log, tan, radians, cos, pi,floor,degrees,atan, sinh
from osgeo import gdal
import glob

设置环境变量


temp_dir = os.path.join(os.getcwd(), 'temp')
output_dir = os.path.join(os.getcwd(), 'output')
os.environ['GDAL_DATA'] = '/home/wblong/Anaconda3/share/gdal'
os.environ['PROJ_LIB'] = '/home/wblong/Anaconda3/share/proj'

瓦片XYZ与经纬度换算

def sec(x):
    return(1/cos(x))
    
def latlon_to_xyz(lat, lon, z):
    tile_count = pow(2, z)
    x = (lon + 180) / 360
    y = (1 - log(tan(radians(lat)) + sec(radians(lat))) / pi) / 2
    return(tile_count*x, tile_count*y)

def bbox_to_xyz(lon_min, lon_max, lat_min, lat_max, z):
    x_min, y_max = latlon_to_xyz(lat_min, lon_min, z)
    x_max, y_min = latlon_to_xyz(lat_max, lon_max, z)
    return(floor(x_min), floor(x_max),
           floor(y_min), floor(y_max))

def mercatorToLat(mercatorY):
    return(degrees(atan(sinh(mercatorY))))

def x_to_lat_edges(x, z):
    tile_count = pow(2, z)
    unit = 360 / tile_count
    lon1 = -180 + x * unit
    lon2 = lon1 + unit
    return(lon1, lon2)

def x_to_lon_edges(x, z):
    tile_count = pow(2, z)
    unit = 360 / tile_count
    lon1 = -180 + x * unit
    lon2 = lon1 + unit
    return (lon1, lon2)

def y_to_lat_edges(y, z):
    tile_count = pow(2, z)
    unit = 1 / tile_count
    relative_y1 = y * unit
    relative_y2 = relative_y1 + unit
    lat1 = mercatorToLat(pi * (1 - 2 * relative_y1))
    lat2 = mercatorToLat(pi * (1 - 2 * relative_y2))
    return(lat1, lat2)

# 根据瓦片{X,Y,Z}计算经纬度范围

def tile_edges(x, y, z):
    lat1, lat2 = y_to_lat_edges(y, z)
    lon1, lon2 = x_to_lon_edges(x, z)
    return[lon1, lat1, lon2, lat2]


瓦片下载、设置空间参考及合并

# 对瓦片png添加空间参考EPSG:4326
def georeference_raster_tile(x, y, z, path):
    bounds = tile_edges(x, y, z)
    filename, extension = os.path.splitext(path)
    gdal.Translate(filename + '.tif',
                   path,
                   outputSRS='EPSG:4326',
                   outputBounds=bounds)
#地图瓦片合并拼接
def merge_tiles(input_pattern, output_path):
    vrt_path = temp_dir + "/tiles.vrt"
    gdal.BuildVRT(vrt_path, glob.glob(input_pattern))
    gdal.Translate(output_path, vrt_path)
# 瓦片下载
def download_tile(x, y, z, tile_server):
    url = tile_server.replace(
        "{x}", str(x)).replace(
        "{y}", str(y)).replace(
        "{z}", str(z))
    path = f'{temp_dir}/{x}_{y}_{z}.png'
    urllib.request.urlretrieve(url, path)
    return(path)
    

测试下载Mapbox瓦片

tile_server = "https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.png?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxx"

zoom = 16

lon_min = 21.49147
lon_max = 21.5
lat_min = 65.31016
lat_max = 65.31688

x_min, x_max, y_min, y_max = bbox_to_xyz(
    lon_min, lon_max, lat_min, lat_max, zoom)

for x in range(x_min, x_max + 1):
    for y in range(y_min, y_max + 1):
        print(f"{x},{y}")
        png_path = download_tile(x, y, zoom, tile_server)
        georeference_raster_tile(x, y, zoom, png_path)

print("Download complete")
print("Merging tiles")
merge_tiles(temp_dir + '/*.tif', output_dir + '/merged.tif')
print("Merge complete")

在这里插入图片描述
在这里插入图片描述合并后
在这里插入图片描述

使用python_GDAL测试地图瓦片下载及拼接测试

参考

  1. https://dev.to/jimutt/generate-merged-geotiff-imagery-from-web-maps-xyz-tile-servers-with-python-4d13
  2. https://blog.csdn.net/mrbaolong/article/details/137610742?spm=1001.2014.3001.5502
  3. https://blog.csdn.net/mrbaolong/article/details/137479780?spm=1001.2014.3001.5502
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python GDAL图像拼接是指将多张地理信息系统(GIS)图像文件合并为一张更大的地图。这个过程涉及到将多个地图投影成同一个坐标系、大小和像素分辨率。首先需要用GDAL库读取原始图像文件,然后将它们转换为统一格式,并实行坐标系统的转换,使它们都以同样的方式进行渲染。接着需要确定最终拼接后图像的大小和分辨率,并使用GDAL库核实这些参数。最后,将各个图像拼接在一起,生成一个全新的大图。这个过程可以使用GDAL库的“gdal_merge.py”模块或者“Dataset.ReadAsArray()”方法来执行。合并完成后,还可以使用Python脚本对图像进行进一步的剪裁、裁剪或图像矢量化。 总的来说,Python GDAL图像拼接是一项复杂的工作,需要深入理解GDAL库的功能和图像处理技术。如果你想进行GIS图像的拼接和处理,这个库会是一个非常有用的资源。它可以让你快速有效地合并、处理大量的地图数据,并生成一张完整的高清地图。 ### 回答2: Python是一种非常方便的编程语言,用于处理数据和图像非常方便,为了实现图像的拼接功能,Gdal库是一个非常好的选择。Gdal是c++编写的一种开放源代码的软件库,主要用于在读写常见的栅格空间数据格式的文件。通过Gdal库,我们可以方便地读取,处理和操作图像,可以实现图像拼接等各种功能。 以下是用Python GDAL库实现图像拼接的一般步骤: 1. 打开要拼接的两个或更多图像文件。我们可以使用gdal_open函数来打开图像文件。 2. 确定合成图像的大小和位置。在图像处理过程中,必须指定新图像的大小和位置以进行合成。 3. 确定输入图像(或“成像区域”)的范围。在合成图像时,必须选择每个输入图像的范围。我们可以使用gdal_translate函数执行此操作。 4. 映射输入图像,以便它们适合于合成图像的大小和位置。这可以通过gdal_warp函数来执行。 5. 对图像执行任何必要的处理。例如,周边均衡化、亮度、色调等。一般在这个步骤中,还需要进行颜色匹配。 6. 合成图像。使用gdal_merge函数将已映射,并经过处理后的图像合成。 7. 保存输出图像。使用gdal_translate函数或其他类似函数输出新文件。 在Python使用gdal库,我们还可以使用numpy库来处理图像数据,matplotlib库来显示图像,以及图像处理方面的其它Python库。Python GDAL库的使用需要有一定的基础,同时掌握相关的图像处理技术和方法,在实际应用中,需要对图像的处理逻辑进行合理的规划和设计。 ### 回答3: Python GDAL是一个处理地理空间数据的强大工具,可以帮助我们实现图像拼接。图像拼接是将多个图像合并成一个大型图像的处理过程,用于制作地图和卫星图像。 图像拼接的基本原理是确定每个图像的边界,将它们按照一定的规则排列在一起,并保持彼此之间的连续性。常用的技术是通过遮罩过滤掉图像背景的没有用部分,然后进行重叠和透明度混合等操作。 下面的步骤将指导您如何使用Python GDAL完成图像拼接: 1. 导入必要的库 使用Python GDAL时,需要导入一些必要的库,如numpy、gdal和osgeo,以便能够处理地理空间数据。 ```python import numpy as np from osgeo import gdal from osgeo import osr ``` 2. 读取图像 使用GDAL打开多个图像,利用numpy将其转换为数组,再根据需要对其进行处理。 ```python ds = gdal.Open('image1.tif') image1 = np.array(ds.GetRasterBand(1).ReadAsArray()) ds = gdal.Open('image2.tif') image2 = np.array(ds.GetRasterBand(1).ReadAsArray()) ``` 3. 确定图像边界 对于每一个图像,使用GDAL获取其边界和投影信息,然后将其转换为我们需要的坐标系统。在这里,我们使用欧气射投影(Mercator projection)。 ```python geo_transform = ds.GetGeoTransform() proj = ds.GetProjection() #获取左上角和右下角的坐标 ul = (geo_transform[0], geo_transform[3]) lr = (geo_transform[0] + geo_transform[1] * ds.RasterXSize, geo_transform[3] + geo_transform[5] * ds.RasterYSize) #将边界转换为Mercator projection src_srs = osr.SpatialReference() src_srs.ImportFromWkt(proj) tgt_srs = src_srs.CloneGeogCS() coord_trans = osr.CoordinateTransformation(src_srs, tgt_srs) ul_lon, ul_lat, _ = coord_trans.TransformPoint(ul[0], ul[1]) lr_lon, lr_lat, _ = coord_trans.TransformPoint(lr[0], lr[1]) ``` 4. 缩放和重采样 将较小的图像缩放到与较大的图像相同的大小,同时使用重采样功能来确保图像缩放后的质量。 ```python #将image2缩放到image1的大小 resampled_image2 = np.zeros_like(image1) gdal.ReprojectImage(ds, gdal.Open('image1.tif'), proj, proj, gdal.GRA_NearestNeighbour, callback = gdal.TermProgress_nocb) resampled_image2 = np.array(ds.GetRasterBand(1).ReadAsArray()) ``` 5. 重叠和混合 计算每幅图像的重叠区域以及透明度,然后将它们混合在一起。我们可以使用numpy的where()函数生成一个遮罩来实现这个操作。 ```python #获取图像重叠区域 overlap = (ul_lon < lr_lon) and (ul_lat > lr_lat) if overlap: #转换投影并计算图像重叠区域和透明度 left, bottom, right, top = (ul_lon, lr_lat, lr_lon, ul_lat) overlapped_image1 = image1[(image1_lon < right) & (image1_lon > left)] overlapped_resampled_image2 = resampled_image2[(resampled_image2_lon > left) & (resampled_image2_lon < right)] blend_alpha = np.zeros_like(image1) blend_alpha[(image1_lat < top)&(image1_lat > bottom)&(resampled_image2_lat < top)&(resampled_image2_lat > bottom)] = 1.0 #将图像进行混合,alpha是透明度 blended_image = np.where(blend_alpha == 1.0, resampled_image2, image1) alpha = np.where(blended_image == resampled_image2, blend_alpha, 1.0 - blend_alpha) else: blended_image = image1 ``` 6. 输出结果 当完成图像拼接时,可以使用GDAL将其保存为一个新的tif文件,以供以后使用。 ```python driver = gdal.GetDriverByName('GTiff') outdata = driver.Create('merged_image.tif', len(image1_lon), len(image1_lat), 1, gdal.GDT_Float32) outdata.SetProjection(src_srs.ExportToWkt()) outdata.SetGeoTransform(geo_transform) outdata.GetRasterBand(1).WriteArray(blended_image) outdata = None ``` 通过以上步骤,我们就可以使用Python GDAL实现图像拼接。这是一个非常实用的技术,尤其对于GIS和遥感数据的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值