基于矩形区域的Mapillary街景图像快速获取


前言

之前有小伙伴问想获取多张街景图的元数据,总不能在Mapillary上面自己找图像id号,然后发请求,这种方法太耗时了。所以就有了第二篇Mapillary街景数据获取的博文,旨在解决如何快速获取大量的街景图像这一问题。好在Mapillary提供了获取某个区域内部街景图像id号的接口,只要有id号就能按第一篇博文的方法获取元数据,下面介绍思路。


一、基于矩形边界框坐标获取地图瓦片行列号

根据边界框的WGS84坐标获取14级地图瓦片中与边界框区域相交的瓦片行列号。瓦片层级为何是14级,这是Mapillary官方规定的。此处用到了mercantile库,这是一个有关地图切片的Python库。

代码如下:

import mercantile

# boundingbox,左下角与右上角WGS84坐标--示例坐标为美国佛罗里达州
west, south, east, north = [-80.13423442840576, 25.77376933762778, -80.1264238357544, 25.788608487732198]
tiles = list(mercantile.tiles(west, south, east, north, 14))
print(tiles)

代码运行结果如下图所示:
在这里插入图片描述
可知与矩形区域相交的瓦片有两个,它们的行列号xy、层级z将用来构造请求区域街景id的Url

二、构造Url并请求

本节利用第一部分获取的地图瓦片行列号层级构造url,通过GET请求获取数据,并将数据保存json格式。这部分需使用requests库、vt2geojson库和json库,其中vt2geojson库的作用是将地图矢量切片从远程 URL 或本地系统文件转储到 GeoJSON。

代码如下:

import json
import requests
from vt2geojson.tools import vt_bytes_to_geojson

# Mapillary访问令牌,换成你自己的
access_token = 'MLYARDJsQP6BFV3QPg8VIVjqFRZBjDE08XJjP33pZAkjNppgVJjKJP9BLiawEepZCQ7Pbk10lnvEFTWedTAN2fEXtKIz9HTXXLqJ5qy2NTwaLLIUQHgQKB3CsdjmiZBfgZDZD'

num = 1
# 这里的变量tiles是第一部分中得到的
for tile in tiles:
	# 构造url
	tile_url = 'https://tiles.mapillary.com/maps/vtp/mly1_public/2/{}/{}/{}?access_token={}'.format(tile.z,tile.x,tile.y,access_token)
	# 发GET请求
	response = requests.get(tile_url)
	# response.content是二进制字节
	# vt_bytes_to_geojson() 基于矢量瓦片的字节创建GeoJSON
		# 参数一:瓦片内容,字节类型
		# 参数二:瓦片X坐标,int
		# 参数三:瓦片Y坐标,int
		# 参数四:瓦片Z坐标,int
		# 参数五:瓦片图层的类型
    data = vt_bytes_to_geojson(response.content, tile.x, tile.y, tile.z,layer="image")
    data = json.dumps(data,indent=4)
    # 将数据保存为json格式
	with open(f'{num}.json','w') as f:
    	f.write(data)
	print('保存成功!')
	num = num+1
	

保存的json文件内容如下图所示:
在这里插入图片描述
可以看到,json文件中每个街景图像是用点要素格式保存的,既有空间几何信息也有属性信息,其中属性信息包括街景id号。下面只需for循环遍历id号就能请求元数据了。

把json文件导入mapshaper网站中可视化,效果如下图所示,可以看到街景点在地图上的位置。共有5459个点要素,说明当前14级地图瓦片内部有5459张街景图像。
在这里插入图片描述

三、遍历id获取元数据并下载图像

本节在请求元数据之前还需判断当前id对应的街景位置是否在矩形区域内部,虽然地图瓦片与矩形区域相交,但不能保证整个瓦片都在矩形区域内部,所以判断是必要的。

代码如下:

# 代码与第一第二部分无关
import json
import requests

# 读取第二部分保存的json文件
with open('1.json','r') as f:
    data = json.load(f)

#矩形区域坐标
west, south, east, north = [-80.13423442840576,25.77376933762778,-80.1264238357544,25.788608487732198]

# Mapillary访问令牌,换成你自己的
access_token = 'MLYARDJsQP6BFV3QPg8VIVjqFRZBjDE08XJjP33pZAkjNppgVJjKJP9BLiawEepZCQ7Pbk10lnvEFTWedTAN2fEXtKIz9HTXXLqJ5qy2NTwaLLIUQHgQKB3CsdjmiZBfgZDZD'

# 以前5个点要素为例
for feature in data['features'][:5]:
    # 获取每个点要素的经纬度坐标
    lng = feature['geometry']['coordinates'][0]
    lat = feature['geometry']['coordinates'][1]  
    # 判断要素是否在矩形区域内部
    if lng > west and lng < east and lat > south and lat < north:
        # 请求图像元数据中原图字段
        image_id = feature['properties']['id']
        header = {'Authorization': 'OAuth {}'.format(access_token)}
        url = 'https://graph.mapillary.com/{}?fields=thumb_original_url'.format(image_id)
        r = requests.get(url, headers=header)
        data = r.json()
        # 拿到原图对应的url
        image_url = data['thumb_original_url']

        # 保存图像,因为图像是二进制数据,所以用wb模式
        with open(f'{image_id}.jpg','wb') as f:
            image_data = requests.get(image_url, stream=True).content
            f.write(image_data)
        print('ok')  

下载的街景图如下所示:
在这里插入图片描述


总结

以上内容就是快速获取大量Mapillary街景图像的方法,希望可以帮助到更多的人。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值