如何基于Google Maps缩放级别调整叠加层图片尺寸
如何让叠加层精准对应Google静态地图上的农田地块
你当前的代码仅将叠加层居中放置,要让它覆盖目标农田地块,核心是把农田地块的经纬度坐标转换为静态地图上的像素位置,而非简单居中。以下是具体实现方案:
1. 准备地块地理边界数据
首先需要获取叠加层对应的农田地块的经纬度范围,比如地块的左上角、右下角经纬度(格式参考示例中的plot_bounds)。
2. 经纬度转地图像素坐标实现
通过墨卡托投影公式,将地理坐标转换为静态地图上的像素位置,修改后的完整代码如下:
import requests from PIL import Image import io import math API_KEY = '***' # 地图中心经纬度(格式:[经度, 纬度]) plot_center = [75.49927187059548, 26.613400716542262] # 农田地块边界经纬度:[左上角经度, 左上角纬度, 右下角经度, 右下角纬度] # 请替换为你实际的地块边界坐标 plot_bounds = [75.4985, 26.6138, 75.4999, 26.6130] zoom = 18 image_size = "640x480" image_width, image_height = map(int, image_size.split('x')) def latlon_to_mercator(lat, lon): """将经纬度转换为墨卡托投影坐标(单位:米)""" R = 6378137 # 地球半径 x = lon * R * math.pi / 180 y = math.log(math.tan((90 + lat) * math.pi / 360)) * R return x, y # 下载Google静态卫星地图 url = f"https://maps.googleapis.com/maps/api/staticmap?center={plot_center[1]},{plot_center[0]}&zoom={zoom}&size={image_size}&key={API_KEY}&maptype=satellite" response = requests.get(url) google_image = Image.open(io.BytesIO(response.content)) # 下载叠加层图片 response = requests.get("https://storage.googleapis.com/kawa-public/4ed05009-8a61-4eb9-8b17-faa8d0d65ae3/kvi/kvi-s2-2023-07-03T15-01-25.838Z.png") overlay_image = Image.open(io.BytesIO(response.content)) # 计算地图中心的墨卡托坐标 center_lat, center_lon = plot_center[1], plot_center[0] center_x, center_y = latlon_to_mercator(center_lat, center_lon) # 计算当前zoom级别下,单张256x256瓦片覆盖的墨卡托范围 tile_size = 2 * math.pi * 6378137 / (2 ** zoom) # 计算整张地图图片的墨卡托范围 map_width_m = tile_size * (image_width / 256) map_height_m = tile_size * (image_height / 256) # 地图左上角的墨卡托坐标 map_left_x = center_x - map_width_m / 2 map_top_y = center_y + map_height_m / 2 # 地块左上角的墨卡托坐标 plot_left_lon, plot_top_lat = plot_bounds[0], plot_bounds[1] plot_left_x, plot_top_y = latlon_to_mercator(plot_top_lat, plot_left_lon) # 计算叠加层在地图上的左上角像素位置 overlay_x = int((plot_left_x - map_left_x) * (image_width / map_width_m)) overlay_y = int((map_top_y - plot_top_y) * (image_height / map_height_m)) # 合成最终图片 output_image = Image.new("RGBA", google_image.size) output_image.paste(google_image, (0, 0)) output_image.paste(overlay_image, (overlay_x, overlay_y), mask=overlay_image) output_image.save("output_image.png")
额外调整(可选)
如果叠加层的尺寸与地块在地图上的像素尺寸不匹配,可通过resize方法缩放叠加层:
# 计算地块在地图上的像素宽度和高度 plot_right_lon, plot_bottom_lat = plot_bounds[2], plot_bounds[3] plot_right_x, plot_bottom_y = latlon_to_mercator(plot_bottom_lat, plot_right_lon) target_width = int((plot_right_x - plot_left_x) * (image_width / map_width_m)) target_height = int((plot_top_y - plot_bottom_y) * (image_height / map_height_m)) # 缩放叠加层 overlay_image = overlay_image.resize((target_width, target_height), Image.Resampling.LANCZOS)
内容的提问来源于stack exchange,提问作者Anurag-Sharma
相关产品推荐
相关产品推荐

