学习教程|中国香港地区CORS网数据下载教程

中国香港地区CORS网数据下载教程

香港特别行政区测绘处的大地测量组主要负责建立和维护一个覆盖全港的高精度测量控制网。此外,该小组还负责管理和维护本地的卫星定位参考系统——香港卫星定位参考站网(SatRef)。

为了获取GNSS原始数据,用户可以选择两种方式下载:网页下载和FTP服务器下载。

  • 网页下载:对初学者而言,这是最为简便的方式。然而,网页每次下载的RINEX压缩数据文件大小上限为50MB,仅适用于下载少量数据。
  • FTP服务器下载:相比之下,FTP方式没有下载大小限制,适合需要批量下载多个站点、多天数据的用户。通过配合Python脚本,可以高效实现自动化下载。

接下来将详细介绍这两种下载方式,并提供相应的Python脚本示例,以帮助用户实现多站点、多日期的GNSS数据批量下载。


一、网页下载方式

用户可通过以下步骤,从测绘处大地测量组提供的网页界面下载GNSS原始数据:

1.访问下载页面

打开香港卫星定位参考站网的RINEX数据下载页面(https://www.geodetic.gov.hk/sc/rinex/downv.aspx)

2.选择参考站点

系统提供共23个可选站点,包括香港地区的20个参考站以及澳门地区的3个参考站。用户可根据实际需求选择一个或多个站点进行数据下载。

3.选择数据格式

根据所需的数据类型,选择相应的RINEX格式(如RINEX 2.x或3.x)。

4.选择时间范围

设定所需的观测时间段。请注意,时间为协调世界时(UTC),即香港时间(HKT)减去8小时(UTC = HKT – 8)。

5.提交并下载

完成以上选择后,点击“提交”按钮。页面将生成下载链接,用户确认后即可开始下载所选数据文件。


二、通过FTP连接工具下载

使用FTP工具进行数据下载适合需要批量获取大体量数据的用户。本方法以常用的FTP客户端 FileZilla 为例进行说明。

  1. 安装FTP客户端

用户可选择安装 FileZilla、LeapFTP 等支持 FTPS 协议的FTP客户端。以下操作基于 FileZilla 进行演示。

  1. 配置FTP连接

打开 FileZilla 客户端,在界面上方的快速连接栏中输入以下信息:

然后点击 “快速连接”按钮。

⚠️注意:该FTP服务器使用 FTPS(FTP over SSL) 加密方式,首次连接时可能会弹出安全证书提示,用户可选择“始终信任”并继续连接。

  1. 下载数据

连接成功后,在右侧远程服务器目录中浏览所需数据。根据测站编号、日期及所需RINEX格式(如 2.11 或 3.03)导航至相应文件夹,右键点击目标文件或文件夹,选择 “下载” 即可将数据保存至本地。


三、使用 Python 脚本进行批量下载

使用 Python 编写脚本可实现从香港卫星定位参考站(SatRef)FTP服务器的自动化、多站点、多日期GNSS数据下载。该方法适用于大规模数据采集需求,具备重连、重试、超时控制等稳健机制。

1. 安装 Python 环境与相关依赖库

建议使用 Anaconda 创建独立虚拟环境进行开发,以避免污染系统自带的 Python base 环境。后续将提供 Anaconda 虚拟环境配置教程。

配置好环境后,在终端或控制台中执行以下命令安装所需库:

pip install ftplib ssl threading

2. 导入依赖库

import os
import ftplib
import ssl
import gzip
import shutil
import time
from threading import Thread

各模块功能简述:

  • os:文件路径与操作系统交互
  • ftplib:Python 的 FTP 客户端库
  • ssl:用于构建安全连接的 SSL/TLS 支持
  • gzip:处理 .gz 格式压缩文件
  • shutil:高级文件操作(复制、移动等)
  • time:添加延时,实现重试机制
  • threading:多线程控制下载超时

3. 配置基本参数

year = 2024                     # 数据年份
start_doy = 1                   # 起始年积日(Day of Year)
end_doy = 366                   # 结束年积日(闰年为366)

local_base_dir = os.path.abspath(r"../data/rinex")  # 本地存储路径

station_list = [
    "hkcl", "hkfn", "hkkt", "hklm", "hklt", "hkmw", "hknp", "hkoh",
    "hkpc", "hkqt", "hksc", "hksl", "hkss", "hkst", "hktk", "hkws",
    "kyc1", "t430"
]

host = 'rinex.geodetic.gov.hk'
port = 990

说明:

  • year:指定要下载的数据年份
  • start_doy 和 end_doy:定义下载的年积日范围(1–366)
  • local_base_dir:下载文件的本地存储目录
  • station_list:要下载的测站代码
  • host 与 port:FTP 服务器地址与端口号(990 为 FTPS 专用端口)

4. 自定义支持 TLS1.2 的 FTP 类

class ImplicitFTP_TLS(ftplib.FTP_TLS):
    """支持 TLS 1.2 的 FTP 客户端"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._sock = None
        self.context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)

    @property
    def sock(self):
        return self._sock

    @sock.setter
    def sock(self, value):
        if value is not None and not isinstance(value, ssl.SSLSocket):
            value = self.context.wrap_socket(value)
        self._sock = value

说明:

  • 强制使用 TLS 1.2 协议,确保与 FTP 服务端的加密兼容性
  • 自动包装 socket 以实现 SSL 安全连接

5. FTP连接函数(带自动重连)

def connect_with_retry(host, port):
    """连接FTP服务器,失败时自动重试"""
    while True:
        try:
            ftp = ImplicitFTP_TLS()
            ftp.connect(host=host, port=port)
            ftp.login()
            ftp.prot_p()  # 启用数据通道保护
            print("FTP连接成功")
            return ftp
        except Exception as e:
            print(f"连接失败: {e},正在重试...")
            time.sleep(5)

6. 带超时机制的文件下载函数

def download_with_timeout(ftp, remote_file_path, local_file_path, timeout=300):
    """下载文件,加入超时控制机制"""
    def download():
        try:
            with open(local_file_path, 'wb') as local_file:
                ftp.retrbinary(f'RETR {remote_file_path}', local_file.write)
            print(f"下载成功: {remote_file_path}")
        except Exception as e:
            print(f"下载失败: {remote_file_path} - {e}")

    download_thread = Thread(target=download)
    download_thread.start()
    download_thread.join(timeout=timeout)

    if download_thread.is_alive():
        print(f"下载超时终止: {remote_file_path}")
        return False
    return True

7. 安全列出远程目录内容

def safe_nlst(ftp, remote_dir, retries=3):
    """安全列出远程目录,支持重试"""
    for attempt in range(retries):
        try:
            ftp.cwd(remote_dir)
            file_list = ftp.nlst()
            print(f"目录读取成功: {remote_dir}")
            return file_list
        except Exception as e:
            print(f"访问失败: {remote_dir} - {e},重试中 ({attempt + 1}/{retries})")
            if attempt < retries - 1:
                ftp = connect_with_retry(host, port)
            else:
                print(f"目录最终访问失败,跳过: {remote_dir}")
                return []

8. 下载与处理函数(带重试机制)

def download_and_process_file(ftp, remote_file_path, local_file_path, local_doy_dir, retries=3, timeout=300):
    """下载并处理文件,支持重试与超时控制"""
    file_name = os.path.basename(remote_file_path)
    if file_exists(local_doy_dir, file_name):
        print(f"文件已存在,跳过: {file_name}")
        return

    for attempt in range(retries):
        try:
            success = download_with_timeout(ftp, remote_file_path, local_file_path, timeout)
            if not success:
                raise TimeoutError(f"超时: {remote_file_path}")
            rename_and_extract(local_file_path, local_doy_dir)
            return
        except TimeoutError as e:
            print(f"重试中 ({attempt + 1}/{retries}) - {e}")
        except Exception as e:
            print(f"处理失败: {remote_file_path} - {e},重试中 ({attempt + 1}/{retries})")

        ftp = connect_with_retry(host, port)

    print(f"文件最终下载失败: {remote_file_path}")

9. 使用说明

  • 请根据实际需求修改脚本开头的参数(年份、年积日范围、测站列表等)
  • 执行脚本文件(例如命名为 download_hk_rinex.py)
  • 脚本将自动创建本地目录结构,下载并处理目标文件
  • 支持断点续传,若中途中断,再次运行会自动跳过已完成部分

下载地址

关注GNSS空间环境智能感知课题微信公众号,发送“香港CORS”,获取下载地址。

欢迎关注我们,我们会不定期分享最新研究成果与数据!