ASCII 文件与 TIFF 文件互转(Python 实现)(2023/03/09)

该文章介绍了如何使用Python的rasterio和GDAL库在ASCII与TIFF文件之间进行转换。提供了两个函数,ascii_to_tiff()和tiff_to_ascii(),分别用于将ASCII栅格数据转换为地理TIFF和反之。转换过程中考虑了坐标系统和元数据的差异,并给出了在Linux和Windows环境下的安装依赖库的指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ASCII 文件与 TIFF 文件互转(Python 实现)

1. 环境

1.1 Linux

$ pip3 install --index-url https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com rioxarray

1.2 Windows

  1. Archived: Python Extension Packages for Windows - Christoph Gohlke (uci.edu)库中下载对应 python 版本的 GDAL 与 Rasterio 离线包,以 python3.10 为例:
    1. https://download.lfd.uci.edu/pythonlibs/archived/GDAL-3.4.3-cp310-cp310-win_amd64.whl
    2. https://download.lfd.uci.edu/pythonlibs/archived/rasterio-1.2.10-cp310-cp310-win_amd64.whl
  2. 安装
$ pip3 install GDAL-3.4.3-cp310-cp310-win_amd64.whl

$ pip3 install rasterio-1.2.10-cp310-cp310-win_amd64.whl

$ pip3 install --index-url https://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com rioxarray

2. 代码

#!/usr/bin/python3
# -*- encoding: utf-8 -*-
"""
@File    :   gis_util.py
@Desc    :   GIS 文件格式转换工具
@Version :   v1.0
@Time    :   2023/02/23
@Author  :   xiaoQQya
@Contact :   xiaoQQya@126.com
"""
import numpy as np
import rioxarray
import xarray as xr


def ascii_to_tiff(asc_path: str, tif_path: str, tif_attrs: dict = {}) -> None:
    """ASCII 文件转 TIFF 文件

    :param asc_path: ASCII 文件路径, 例如: ./test.asc
    :type asc_path: str
    :param tif_path: TIFF 文件输出路径, 例如: ./test.tif
    :type tif_path: str
    :param tif_attrs: TIFF 文件属性, 例如: {"unit": "m"}, defaults to {}
    :type tif_attrs: dict, optional
    """
    # 获取 ASCII 文件前 6 行属性值
    attrs: dict = {}
    with open(asc_path, "r") as file:
        for _ in range(6):
            line: str = file.readline().strip().split(" ")
            attrs[line[0].lower()] = eval(line[-1])
    if "xllcenter" not in attrs.keys():
        attrs["xllcenter"] = attrs["xllcorner"] + 0.5 * attrs["cellsize"]
        attrs["yllcenter"] = attrs["yllcorner"] + 0.5 * attrs["cellsize"]

    # 计算每个点经纬度坐标
    longitudes = [attrs["xllcenter"] + i * attrs["cellsize"] for i in range(attrs["ncols"])]
    latitudes = [attrs["yllcenter"] + i * attrs["cellsize"] for i in range(attrs["nrows"])]
    latitudes.reverse()

    # 读取 ASCII 文件矩阵数值
    data = np.loadtxt(asc_path, skiprows=6)
    data[data == attrs["nodata_value"]] = np.nan
    da = xr.DataArray(data, coords=[latitudes, longitudes], dims=["y", "x"])
    # 设置 TIFF 文件属性值
    tif_attrs["NODATA_VALUE"] = attrs["nodata_value"]
    da.attrs = tif_attrs
    # 设置 TIFF 文件参考系信息
    rioxarray.raster_array.RasterArray(da)
    da.rio.write_crs("epsg:4326", inplace=True)
    da.rio.to_raster(tif_path)


def tiff_to_ascii(tif_path: str, asc_path: str) -> None:
    """TIFF 文件转 ASCII 文件

    :param tif_path: TIFF 文件路径, 例如: ./test.tif
    :type tif_path: str
    :param asc_path: ASCII 输出文件路径, 例如: ./test.asc
    :type asc_path: str
    """
    # 读取 TIFF 文件
    tif = rioxarray.open_rasterio(tif_path)
    shape = tif.rio.shape
    transform = tif.rio.transform()

    # 获取 ASCII 文件前 6 行属性
    attrs: dict = {}
    attrs["ncols"] = shape[1]
    attrs["nrows"] = shape[0]
    attrs["xllcorner"] = transform[2]
    attrs["yllcorner"] = transform[5] + shape[0] * transform[4]
    attrs["cellsize"] = transform[0]
    attrs["nodata_value"] = tif.rio.nodata if tif.rio.nodata else -9999

    # 获取数据
    data = tif.values[0]
    data[np.isnan(data)] = attrs["nodata_value"]

    # 写入文件
    with open(asc_path, "w") as file:
        for key, value in attrs.items():
            file.write(f"{key.upper():14}{value}\n")
        np.savetxt(fname=file, X=data, fmt="%.2f")


if __name__ == "__main__":
    ascii_to_tiff("./ascs/dem.asc", "./tifs/dem.tif", {"UNIT": "m"})
    tiff_to_ascii("./tifs/dem.tif", "./ascs/dem2.asc")

注意:ASCII 文件与 TIFF 文件除了存在格式差异,还存在元空间表达方式的差异。ASCII 文件坐标值在像元的左下角,而 TIFF 文件坐标值在像元的左上角,因此在格式转换时需要注意坐标转换问题。

参考资料:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值