You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将经纬度下载的谷歌地图.TIF图像转换为GeoTIFF以保留空间信息

Absolutely! You can absolutely convert your downloaded map image into a GeoTIFF with spatial reference information retained. The core idea is to add geographic metadata (like projection, coordinate bounds) to the regular image file, since PIL (which you're using now) doesn't handle geospatial data natively. Here's a step-by-step solution using rasterio—a Python library designed for working with geospatial raster data:

Step 1: Install Required Libraries

First, install rasterio and numpy (we'll use numpy to convert PIL images to arrays for rasterio):

pip install rasterio numpy

Step 2: Fix Redundant Tile Downloads (Optional but Important)

Looking at your generateTiles method, you're downloading each tile twice and pasting it twice—this is redundant and wastes bandwidth/time. Let's clean that up first:

def generateTiles(self, **kwargs):
    start_x = kwargs.get('start_x', None)
    start_y = kwargs.get('start_y', None)
    tile_width = kwargs.get('tile_width', 5)
    tile_height = kwargs.get('tile_height', 5)
    if start_x == None or start_y == None:
        start_x, start_y = self.getXY()
    width, height = 256 * tile_width, 256 * tile_height
    map_img = Image.new('RGB', (width, height))
    for x in range(0, tile_width):
        for y in range(0, tile_height):
            url = f'https://mt0.google.com/vt?lyrs={self._layer}&x={start_x + x}&y={start_y + y}&z={self._zoom}'
            current_tile = f'{x}-{y}'
            urllib.request.urlretrieve(url, current_tile)
            im = Image.open(current_tile)
            map_img.paste(im, (x * 256, y * 256))
            os.remove(current_tile)
    return map_img

Step 3: Add Geospatial Metadata & Save as GeoTIFF

Next, modify your script to calculate the Web Mercator (EPSG:3857) bounds of your image (Google Maps uses this projection) and write the GeoTIFF using rasterio.

First, add these imports at the top of your script:

import rasterio
import numpy as np

Then update the main function's save logic:

def main():
    # Replace with your actual lat/lon values
    lat = 40.7128
    lon = -74.0060
    gmd = ImagesDownloader(lat, lon, 15, layer='s')
    print("瓦片坐标为{}".format(gmd.getXY()))
    try:
        # 获取高分辨率图像
        img = gmd.generateTiles(tile_width=5, tile_height=5)  # Explicitly set tile dimensions here
    except IOError:
        print("无法生成图像 - 请尝试调整缩放级别并检查坐标")
    else:
        # Convert PIL Image to numpy array
        img_array = np.array(img)
        # Calculate geospatial parameters (Web Mercator EPSG:3857)
        zoom = gmd._zoom
        start_x, start_y = gmd.getXY()
        tile_width = 5
        tile_height = 5
        
        # Web Mercator projection bounds
        mercator_extent = 20037508.34 * 2  # Total width/height of Web Mercator in meters
        tile_size_meters = mercator_extent / (2 ** zoom)
        pixel_size_meters = tile_size_meters / 256  # Size of each pixel in meters
        
        # Top-left corner coordinates (Web Mercator)
        top_left_x = -20037508.34 + start_x * tile_size_meters
        top_left_y = 20037508.34 - start_y * tile_size_meters
        
        # Create affine transform for the image
        transform = rasterio.transform.from_origin(
            top_left_x, top_left_y, pixel_size_meters, pixel_size_meters
        )
        
        # Write the GeoTIFF file
        with rasterio.open(
            "high_resolution_geotiff.tif",
            "w",
            driver="GTiff",
            height=img_array.shape[0],
            width=img_array.shape[1],
            count=3,  # 3 bands for RGB
            dtype=img_array.dtype,
            crs="EPSG:3857",
            transform=transform,
        ) as dst:
            # Transpose array from (H, W, 3) to (3, H, W) as required by rasterio
            dst.write(img_array.transpose(2, 0, 1))
        
        print("GeoTIFF地图已成功生成")

How This Works

  • Coordinate Conversion: We calculate the exact Web Mercator bounds of your tiled image using the tile coordinates (start_x, start_y) and zoom level.
  • Affine Transform: This defines how pixel coordinates map to real-world geographic coordinates.
  • Rasterio Writing: Rasterio handles embedding the CRS (EPSG:3857) and transform into the TIFF file, making it a valid GeoTIFF that GIS tools (like QGIS, ArcGIS) can recognize and display in the correct location.

Alternative: Using GDAL

If you prefer using GDAL (the underlying library rasterio uses), you could use gdal.Translate or build the dataset manually, but rasterio provides a much cleaner Pythonic API for this use case.

内容的提问来源于stack exchange,提问作者Skarl001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 22:17:44