如何通过Flask向GeoServer程序化上传.tiff栅格数据(无需GeoServer界面)
程序化通过Flask向GeoServer上传TIFF栅格数据实现方案
核心思路
利用GeoServer提供的REST API完成上传与发布,无需依赖Web界面。Flask作为中间层接收前端上传的TIFF文件,再调用GeoServer的REST接口完成数据上传和图层发布。
前提准备
- 确认GeoServer已启用REST服务(默认启用,可访问
http://<geoserver-host>:8080/geoserver/rest验证)。 - 准备GeoServer管理员账号(默认
admin/geoserver)。 - 提前创建目标工作区(Workspace),或通过代码自动创建。
实现步骤与代码
1. 安装依赖
pip install flask requests
2. Flask完整实现代码
from flask import Flask, request, jsonify import requests from requests.auth import HTTPBasicAuth app = Flask(__name__) # 配置GeoServer参数,替换为你的实际信息 GEOSERVER_CONFIG = { "url": "http://localhost:8080/geoserver", "username": "admin", "password": "geoserver", "workspace": "my_workspace", "coveragestore": "my_geotiff_store", # 存储TIFF的数据存储名称 "store_path": "file:///opt/geoserver/data_dir/data/my_workspace/my_geotiff_store" # 数据存储物理路径,需保证GeoServer有写入权限 } def create_geotiff_store(): """自动创建GeoTIFF类型的数据存储(不存在则创建)""" create_url = f"{GEOSERVER_CONFIG['url']}/rest/workspaces/{GEOSERVER_CONFIG['workspace']}/coveragestores" headers = {"Content-type": "text/xml"} store_xml = f"""<dataStore> <name>{GEOSERVER_CONFIG['coveragestore']}</name> <connectionParameters> <entry key="url">{GEOSERVER_CONFIG['store_path']}</entry> <entry key="create spatial index">true</entry> </connectionParameters> </dataStore>""" try: response = requests.post( create_url, auth=HTTPBasicAuth(GEOSERVER_CONFIG['username'], GEOSERVER_CONFIG['password']), headers=headers, data=store_xml ) # 存储已存在时返回409,属于正常情况 if response.status_code not in [201, 409]: response.raise_for_status() return True except requests.exceptions.RequestException as e: print(f"创建数据存储失败: {str(e)}") return False @app.route('/upload-tiff', methods=['POST']) def upload_and_publish_tiff(): # 检查上传文件合法性 if 'tiff_file' not in request.files: return jsonify({"error": "未上传文件"}), 400 tiff_file = request.files['tiff_file'] if tiff_file.filename == '': return jsonify({"error": "未选择文件"}), 400 if not tiff_file.filename.lower().endswith(('.tiff', '.tif')): return jsonify({"error": "仅支持TIFF格式文件"}), 400 # 确保数据存储存在 if not create_geotiff_store(): return jsonify({"error": "数据存储创建失败"}), 500 # 1. 上传TIFF文件到GeoServer数据存储 upload_url = f"{GEOSERVER_CONFIG['url']}/rest/workspaces/{GEOSERVER_CONFIG['workspace']}/coveragestores/{GEOSERVER_CONFIG['coveragestore']}/file.geotiff" upload_headers = {"Content-type": "image/tiff"} try: upload_response = requests.put( upload_url, auth=HTTPBasicAuth(GEOSERVER_CONFIG['username'], GEOSERVER_CONFIG['password']), headers=upload_headers, data=tiff_file.read() ) upload_response.raise_for_status() except requests.exceptions.RequestException as e: return jsonify({"error": f"文件上传失败: {str(e)}", "status": upload_response.status_code}), 500 # 2. 发布为覆盖层(Coverage) coverage_name = tiff_file.filename.split('.')[0] publish_url = f"{GEOSERVER_CONFIG['url']}/rest/workspaces/{GEOSERVER_CONFIG['workspace']}/coveragestores/{GEOSERVER_CONFIG['coveragestore']}/coverages" publish_headers = {"Content-type": "text/xml"} coverage_xml = f"""<coverage> <name>{coverage_name}</name> <nativeName>{tiff_file.filename}</nativeName> <title>{coverage_name}</title> <srs>EPSG:4326</srs> <!-- 替换为你的TIFF实际坐标系 --> </coverage>""" try: publish_response = requests.post( publish_url, auth=HTTPBasicAuth(GEOSERVER_CONFIG['username'], GEOSERVER_CONFIG['password']), headers=publish_headers, data=coverage_xml ) publish_response.raise_for_status() except requests.exceptions.RequestException as e: return jsonify({"error": f"图层发布失败: {str(e)}", "status": publish_response.status_code}), 500 return jsonify({"message": f"TIFF文件上传并发布成功,图层名称: {coverage_name}"}), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True)
关键注意事项
- 路径权限:确保
store_path指向的目录GeoServer进程有写入权限(Linux下可执行chown -R geoserver:geoserver <目录路径>)。 - 坐标系匹配:代码中
EPSG:4326需替换为TIFF文件实际坐标系,否则可能导致图层无法正常显示。 - 接口测试:用curl或Postman发送测试请求:
curl -X POST -F "tiff_file=@/path/to/your/file.tiff" http://localhost:5000/upload-tiff - 错误扩展:可根据需求添加日志记录、更精细的异常捕获逻辑。
内容的提问来源于stack exchange,提问作者Zarabotok 04
相关产品推荐
相关产品推荐

