Преглед изворни кода

更新.gitignore以排除meanTemp.tif.aux.xml文件;删除LICENSE文件和requirements.txt文件;添加conda环境导出工具脚本;移动Cd通量移除和Cd预测集成测试脚本至demo文件夹

drggboy пре 1 недеља
родитељ
комит
de0dd1e818

+ 1 - 0
.gitignore

@@ -12,3 +12,4 @@ myenv/
 .idea/
 .vscode/
 *.log
+Cd_Prediction_Integrated_System/output/raster/meanTemp.tif.aux.xml

+ 0 - 10
Cd_Prediction_Integrated_System/requirements.txt

@@ -1,10 +0,0 @@
-# Cd预测集成系统依赖包
-numpy>=1.21.0
-pandas>=1.3.0
-torch>=1.9.0
-scikit-learn>=1.0.0
-geopandas>=0.10.0
-rasterio>=1.2.0
-matplotlib>=3.4.0
-seaborn>=0.11.0
-shapely>=1.7.0

+ 0 - 8
LICENSE

@@ -1,8 +0,0 @@
-MIT License
-Copyright (c) <year> <copyright holders>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 33 - 42
PROJECT_RULES.md

@@ -362,38 +362,6 @@ sqlacodegen postgresql://postgres:123456789Qq@localhost/soilgd --tables table1,t
 - `python db_migrate.py history` - 显示迁移历史
 - `python db_migrate.py stamp head` - 标记数据库版本
 
-**数据库备份与恢复**:
-
-### 备份操作
-```bash
-# 自定义格式(推荐,文件小,支持选择性恢复)
-pg_dump -U postgres -Fc soilgd > soilgd.dump
-
-# SQL文本格式(兼容性好,可读性强)
-pg_dump -U postgres soilgd > soilgd.sql
-```
-
-### 导入操作
-```bash
-# 导入自定义格式备份
-createdb -U postgres soilgd
-pg_restore -U postgres -d soilgd soilgd.dump
-
-# 导入SQL文本格式备份
-createdb -U postgres soilgd
-psql -U postgres -d soilgd -f soilgd.sql
-```
-
-### 快速参考
-| 导出格式 | 导出命令 | 导入命令 |
-|---------|---------|---------|
-| 自定义格式 | `pg_dump -Fc` | `pg_restore` |
-| SQL文本 | `pg_dump` | `psql` |
-
-### 注意事项
-- 格式必须匹配:`pg_dump -Fc` 导出 → `pg_restore` 导入
-
-
 #### 5.2.4 数据导入脚本开发规范
 
 ##### 5.2.4.1 脚本开发原则
@@ -589,16 +557,39 @@ class FarmlandDataImporter:
 
 ### 6.1 开发环境要求
 - Python 3.8+
-- PostgreSQL 12+ (with PostGIS)
-- **Cd预测系统依赖**:
-  - PyTorch >= 1.9.0
-  - scikit-learn >= 1.0.0
-  - geopandas >= 0.10.0
-  - rasterio >= 1.2.0
-  - matplotlib >= 3.4.0
-  - seaborn >= 0.11.0
-  - fiona (地理数据I/O)
-  - pyogrio (高性能地理数据I/O)
+
+### 数据库备份与恢复:
+
+#### 备份操作
+```bash
+# 自定义格式(推荐,文件小,支持选择性恢复)
+pg_dump -U postgres -Fc soilgd > soilgd.dump
+
+# SQL文本格式(兼容性好,可读性强)
+pg_dump -U postgres soilgd > soilgd.sql
+```
+
+#### 导入操作
+```bash
+# 导入自定义格式备份
+createdb -U postgres soilgd
+pg_restore -U postgres -d soilgd soilgd.dump
+
+# 导入SQL文本格式备份
+createdb -U postgres soilgd
+psql -U postgres -d soilgd -f soilgd.sql
+```
+
+#### 快速参考
+| 导出格式 | 导出命令 | 导入命令 |
+|---------|---------|---------|
+| 自定义格式 | `pg_dump -Fc` | `pg_restore` |
+| SQL文本 | `pg_dump` | `psql` |
+
+#### 注意事项
+- 格式必须匹配:`pg_dump -Fc` 导出 → `pg_restore` 导入
+
+
 
 ### 6.2 环境配置文件
 - `config.env`: 数据库连接配置

+ 33 - 40
README.md

@@ -6,7 +6,7 @@
 
 - 支持栅格数据的导入和导出
 - 支持矢量数据的导入和导出
-- **单元分类功能**: 基于空间插值算法的土壤环境质量分类
+- 基于空间插值算法的土壤环境质量分类
 - 使用 PostgreSQL + PostGIS 存储空间数据
 - 提供 RESTful API 接口
 - 支持空间数据查询和分析
@@ -43,19 +43,42 @@ scripts/
 └── ...
 ```
 
-## 安装依赖
+## 环境安装
+
+### conda环境导出工具
+
+项目提供了专门的环境导出脚本,用于管理和分享环境配置:
 
-1. 确保已安装 Python 3.8+
-2. 安装 PostgreSQL 数据库并启用 PostGIS 扩展
-3. 安装项目依赖:
 ```bash
-pip install -r requirements.txt
+# 导出当前环境(包含conda显式安装包和pip包)
+python scripts/demos/conda_env_export_tool.py -e GeoSys -o environment.yml
+
+# 查看帮助
+python scripts/demos/conda_env_export_tool.py --help
 ```
 
+**功能特点:**
+- ✅ 只导出显式安装的包(不包含依赖包)
+- ✅ 合并 conda 和 pip 安装的包
+- ✅ 自动备份现有文件
+
+### 使用 Conda 环境
+
+1. **安装 Anaconda/Miniconda**
+   - 下载并安装 [Anaconda](https://www.anaconda.com/products/distribution) 或 [Miniconda](https://docs.conda.io/en/latest/miniconda.html)
+
+2. **创建项目环境**
+   ```bash
+   # 使用项目提供的环境文件
+   conda env create -f enviroment.yml
+   
+   # 激活环境
+   conda activate GeoSys
+   ```
+
 ## 配置
 
-1. 复制 `.env.example` 文件为 `.env`
-2. 修改 `.env` 文件中的数据库连接信息:
+1. 修改 `config.env` 文件中的数据库连接信息:
 ```
 DB_HOST=localhost
 DB_PORT=5432
@@ -102,40 +125,14 @@ uvicorn app.main:app --reload
 python scripts/demos/unit_grouping_demo.py
 ```
 
-3. 运行单元分类集成测试:
-```bash
-python tests/integration/test_unit_grouping.py
-```
 
 4. 访问 API 文档:
 - Swagger UI: http://localhost:8000/docs
 - ReDoc: http://localhost:8000/redoc
 
-## API 接口
-
-### 栅格数据接口 (/api/raster)
-- POST /import: 导入栅格数据
-- GET /export: 导出栅格数据
-- GET /query: 查询栅格数据
-
-### 矢量数据接口 (/api/vector)
-- POST /import: 导入矢量数据
-- GET /export: 导出矢量数据
-- GET /query: 查询矢量数据
-
-### 单元分类接口 (/api/unit-grouping)
-- GET /h_xtfx: 获取所有单元的h_xtfx分类结果
-- GET /statistics: 获取统计信息
-- GET /unit/{unit_id}: 获取特定单元的h_xtfx值
-- GET /points/statistics: 获取点位统计信息
-- GET /database/summary: 获取数据库摘要信息
-- GET /units/batch: 批量获取单元信息
-
-详细说明请参考: [单元分类功能文档](docs/features/unit-grouping/README.md)
-
 ## 开发环境
 
-- Python 3.8+
+- Python 3.8
 - PostgreSQL 12+
 - PostGIS 3.0+
 - FastAPI 0.104.1
@@ -147,8 +144,4 @@ python tests/integration/test_unit_grouping.py
 2. 创建特性分支
 3. 提交更改
 4. 推送到分支
-5. 创建 Pull Request
-
-## 许可证
-
-MIT License 
+5. 创建 Pull Request

+ 37 - 0
enviroment.yml

@@ -0,0 +1,37 @@
+name: GeoSys
+channels:
+  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge
+  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
+  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/
+  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
+dependencies:
+  - python=3.8
+  - psycopg2=2.9.7
+  - uvicorn=0.32.1
+  - fastapi=0.115.4
+  - geoalchemy2=0.17.1
+  - alembic=1.14.0
+  - pandas=2.0.3
+  - openpyxl=3.1.5
+  - shapely=2.0.1
+  - cpuonly=2.0
+  - pytorch==2.3.1
+  - torchaudio=2.3.1
+  - torchvision=0.18.1
+  - scikit-learn==1.3.0
+  - geopandas=0.13.2
+  - seaborn=0.13.2
+  - fiona=1.9.4
+  - pyogrio=0.6.0
+  - pip:
+      - affine==2.4.0
+      - attrs==25.3.0
+      - greenlet==3.1.1
+      - rasterio==1.3.11
+      - snuggs==1.4.7
+      - sqlacodegen==2.3.0.post1
+      - sqlalchemy==1.4.54
+      - typeguard==4.4.0
+      - typing-extensions==4.13.2
+      - zipp==3.20.2
+prefix: D:\Anaconda\envs\GeoSys


+ 244 - 0
scripts/demos/conda_env_export_tool.py

@@ -0,0 +1,244 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+Conda环境导出工具
+
+该脚本结合conda显式安装的包(包含版本信息)和pip显式安装的包,创建一个完整的environment.yml文件。
+
+特性:
+- 📦 导出conda显式安装的包,包含精确的版本信息
+- 🐍 导出pip安装的包,保持完整的版本约束
+- ✨ 自动合并两种包管理器的依赖项
+- 🎯 只包含用户显式安装的包,避免冗余依赖
+
+使用方法:
+python scripts/demos/conda_env_export_tool.py --env-name 环境名 --output environment.yml
+
+python scripts/demos/conda_env_export_tool.py -e base -o environment.yml
+作者: AcidMap项目组
+"""
+
+import argparse
+import subprocess
+import yaml
+import tempfile
+import os
+import json
+import re
+from pathlib import Path
+
+
+def run_command(command):
+    """执行命令并返回输出"""
+    try:
+        result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding='utf-8')
+        if result.returncode != 0:
+            print(f"命令执行失败: {command}")
+            print(f"错误信息: {result.stderr}")
+            return None
+        return result.stdout
+    except Exception as e:
+        print(f"执行命令时出错: {e}")
+        return None
+
+
+def get_conda_explicit_packages(env_name):
+    """获取conda显式安装的包(包含版本信息)"""
+    print(f"正在获取环境 '{env_name}' 的conda显式安装包...")
+    
+    with tempfile.NamedTemporaryFile(mode='w+', suffix='.yml', delete=False) as temp_file:
+        temp_path = temp_file.name
+    
+    try:
+        # 首先获取显式安装的包名(无版本)
+        command = f"conda env export --name {env_name} --from-history --file {temp_path}"
+        output = run_command(command)
+        
+        if output is None:
+            return None
+            
+        # 读取显式安装的包名
+        with open(temp_path, 'r', encoding='utf-8') as f:
+            conda_env = yaml.safe_load(f)
+        
+        # 获取显式安装的包名列表
+        explicit_packages = []
+        if 'dependencies' in conda_env:
+            for dep in conda_env['dependencies']:
+                if isinstance(dep, str):
+                    # 使用更健壮的方法提取包名
+                    # 匹配包名(字母、数字、下划线、连字符、点)直到遇到版本操作符或特殊字符
+                    match = re.match(r'^([a-zA-Z0-9_.-]+)', dep.strip())
+                    if match:
+                        package_name = match.group(1)
+                        explicit_packages.append(package_name)
+                    else:
+                        print(f"警告: 无法解析包名 '{dep}',跳过")
+                        continue
+        
+        # 获取所有已安装包的详细信息
+        command = f"conda list --name {env_name} --json"
+        list_output = run_command(command)
+        
+        if list_output is None:
+            print("警告: 无法获取包的详细信息,将返回无版本的包列表")
+            return conda_env
+        
+        all_packages = json.loads(list_output)
+        
+        # 创建包名到版本的映射
+        package_versions = {}
+        for pkg in all_packages:
+            if pkg.get('channel') != 'pypi':  # 只处理conda包
+                package_versions[pkg['name']] = f"{pkg['name']}={pkg['version']}"
+        
+        # 更新dependencies列表,添加版本信息
+        versioned_dependencies = []
+        for pkg_name in explicit_packages:
+            if pkg_name in package_versions:
+                versioned_dependencies.append(package_versions[pkg_name])
+            else:
+                print(f"警告: 未找到包 '{pkg_name}' 的版本信息,保持原样")
+                versioned_dependencies.append(pkg_name)
+        
+        conda_env['dependencies'] = versioned_dependencies
+        print(f"✅ 成功获取 {len(versioned_dependencies)} 个显式安装的conda包(包含版本信息)")
+        
+        return conda_env
+        
+    finally:
+        # 清理临时文件
+        if os.path.exists(temp_path):
+            os.unlink(temp_path)
+
+
+def get_pip_packages(env_name):
+    """获取pip安装的包"""
+    print(f"正在获取环境 '{env_name}' 的pip安装包...")
+    
+    with tempfile.NamedTemporaryFile(mode='w+', suffix='.yml', delete=False) as temp_file:
+        temp_path = temp_file.name
+    
+    try:
+        # 导出完整环境(包含pip包)
+        command = f"conda env export --name {env_name} --file {temp_path}"
+        output = run_command(command)
+        
+        if output is None:
+            return None
+            
+        # 读取生成的文件
+        with open(temp_path, 'r', encoding='utf-8') as f:
+            full_env = yaml.safe_load(f)
+        
+        # 提取pip包
+        pip_packages = []
+        if 'dependencies' in full_env:
+            for dep in full_env['dependencies']:
+                if isinstance(dep, dict) and 'pip' in dep:
+                    pip_packages = dep['pip']
+                    break
+        
+        return pip_packages
+        
+    finally:
+        # 清理临时文件
+        if os.path.exists(temp_path):
+            os.unlink(temp_path)
+
+
+def create_combined_environment_file(env_name, output_file):
+    """创建结合conda和pip包的环境文件"""
+    
+    # 获取conda显式包
+    conda_env = get_conda_explicit_packages(env_name)
+    if conda_env is None:
+        print("获取conda包失败")
+        return False
+    
+    # 获取pip包
+    pip_packages = get_pip_packages(env_name)
+    if pip_packages is None:
+        print("获取pip包失败")
+        return False
+    
+    # 合并
+    if pip_packages:
+        # 确保dependencies是列表
+        if 'dependencies' not in conda_env:
+            conda_env['dependencies'] = []
+        
+        # 添加pip包
+        conda_env['dependencies'].append({'pip': pip_packages})
+    
+    # 检查文件是否已存在
+    file_exists = os.path.exists(output_file)
+    if file_exists:
+        print(f"⚠️  文件 '{output_file}' 已存在,将被替换")
+    
+    # 写入输出文件
+    try:
+        with open(output_file, 'w', encoding='utf-8') as f:
+            yaml.dump(conda_env, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
+        
+        if file_exists:
+            print(f"✅ 成功替换环境文件: {output_file}")
+        else:
+            print(f"✅ 成功创建环境文件: {output_file}")
+        print(f"📦 Conda显式包数量: {len([dep for dep in conda_env['dependencies'] if isinstance(dep, str)])}")
+        print(f"🐍 Pip包数量: {len(pip_packages) if pip_packages else 0}")
+        
+        return True
+        
+    except Exception as e:
+        print(f"写入文件时出错: {e}")
+        return False
+
+
+def main():
+    """主函数"""
+    parser = argparse.ArgumentParser(
+        description="导出包含conda显式包(含版本)和pip包的环境文件",
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        epilog="""
+示例:
+  python scripts/demos/conda_env_export_tool.py --env-name GeoSys --output my_environment.yml
+  python scripts/demos/conda_env_export_tool.py -e myenv -o environment.yml
+  
+注意: 该工具会自动获取显式安装包的版本信息,确保环境的精确重现。
+        """
+    )
+    
+    parser.add_argument(
+        '--env-name', '-e',
+        required=True,
+        help="conda环境名称"
+    )
+    
+    parser.add_argument(
+        '--output', '-o',
+        default='environment_combined.yml',
+        help="输出文件名 (默认: environment_combined.yml)"
+    )
+    
+    args = parser.parse_args()
+    
+    print(f"🚀 开始导出环境 '{args.env_name}' 到文件 '{args.output}'")
+    print("=" * 50)
+    
+    success = create_combined_environment_file(args.env_name, args.output)
+    
+    if success:
+        print("=" * 50)
+        print("✨ 导出完成!")
+        print(f"\n📝 使用此文件创建新环境:")
+        print(f"   conda env create -f {args.output}")
+    else:
+        print("❌ 导出失败")
+        return 1
+    
+    return 0
+
+
+if __name__ == "__main__":
+    exit(main()) 

+ 0 - 0
test_cd_flux_removal.py → scripts/demos/test_cd_flux_removal.py


+ 0 - 0
test_cd_integration.py → scripts/demos/test_cd_integration.py