PROJECT_RULES.md 23 KB

AcidMap 项目开发规范 (PROJECT RULES)

0. 规则文件维护指导 (RULES MAINTENANCE GUIDE)

0.1 规则更新原则

重要提示: 当项目发生以下变化时,开发人员和AI助手必须同步更新本规则文件:

0.1.1 必须更新的情况

  1. 新功能模块集成 - 添加新的业务功能、API端点或服务组件
  2. 架构变更 - 修改目录结构、分层架构或技术栈
  3. 开发规范变更 - 修改编码规范、注释风格或命名约定
  4. 部署环境变更 - 更新依赖包、数据库版本或服务器配置
  5. API接口变更 - 新增、修改或删除API路由和响应格式

0.1.2 更新流程

  1. 识别变更影响 - 确定变更影响的规范章节
  2. 更新相关章节 - 修改对应的规范内容和示例
  3. 验证一致性 - 确保规范与实际代码实现一致
  4. 文档同步 - 同时更新相关的集成文档和使用指南

0.1.3 AI助手责任

  • 在进行功能开发或架构调整时,主动识别需要更新的规范内容
  • 确保新增功能的开发遵循现有规范,或合理扩展规范
  • 提醒维护相关文档的同步更新

1. 项目概述

1.1 项目基本信息

  • 项目名称: AcidMap (地图数据处理与预测分析系统)
  • 技术栈: FastAPI + PostgreSQL + PostGIS + PyTorch
  • 主要功能: 栅格和矢量地理数据的处理、存储、管理和Cd预测分析
  • 开发语言: Python 3.8+
  • 架构模式: 分层架构 (API层 -> Service层 -> Model层)

1.2 核心业务域

  • 栅格数据处理 (Raster Data Processing)
  • 矢量数据处理 (Vector Data Processing)
  • 空间数据查询和分析
  • GIS数据导入导出
  • Cd预测模型分析 (Cd Prediction Analysis)
    • 作物Cd含量预测
    • 有效态Cd含量预测
    • 预测结果可视化

2. 项目架构

2.1 目录结构规范

AcidMap/
├── app/                    # 应用核心代码
│   ├── api/               # API路由层
│   │   ├── raster.py      # 栅格数据接口
│   │   ├── vector.py      # 矢量数据接口
│   │   └── cd_prediction.py # Cd预测模型接口
│   ├── services/          # 业务逻辑层
│   │   ├── raster_service.py
│   │   ├── vector_service.py
│   │   └── cd_prediction_service.py # Cd预测业务服务
│   ├── models/            # 数据模型层
│   │   ├── base.py        # 基础模型
│   │   ├── orm_models.py  # ORM模型
│   │   ├── raster.py      # 栅格数据模型
│   │   ├── vector.py      # 矢量数据模型
│   │   ├── county.py      # 县域数据模型
│   │   └── farmland.py    # 农田样点数据模型
│   ├── utils/             # 工具函数
│   │   ├── file_validators.py
│   │   └── cd_prediction_wrapper.py # Cd预测系统包装器
│   ├── config/            # 配置管理
│   │   ├── __init__.py
│   │   └── cd_prediction_config.py # Cd预测配置管理
│   ├── static/            # 静态文件
│   │   └── cd_predictions/ # Cd预测输出文件
│   │       ├── figures/    # 地图和直方图
│   │       ├── raster/     # 栅格文件
│   │       ├── reports/    # 报告文件
│   │       └── data/       # 数据文件
│   ├── logs/              # 日志文件
│   ├── scripts/           # 脚本文件
│   ├── database.py        # 数据库配置
│   └── main.py           # FastAPI应用入口
├── Cd_Prediction_Integrated_System/ # Cd预测系统
│   ├── models/            # 预测模型
│   │   ├── crop_cd_model/
│   │   └── effective_cd_model/
│   ├── analysis/          # 数据分析模块
│   ├── utils/             # 工具函数
│   ├── data/              # 数据文件
│   ├── output/            # 输出文件
│   ├── main.py           # 主执行脚本
│   └── config.py         # 配置文件
├── data/                  # 数据文件
│   └── counties.geojson   # 县域地理数据
├── migrations/            # 数据库迁移文件
├── scripts/               # 项目脚本
├── ssl/                   # SSL证书文件
├── config.env            # 环境配置
├── environment.yml       # Conda环境依赖
├── soilgd.sql           # 数据库备份文件
├── db_migrate.py        # 数据库迁移脚本
├── reset_db.py          # 数据库重置脚本
├── test_cd_integration.py # Cd集成测试脚本
├── INTEGRATION_GUIDE.md  # 集成使用指南
├── CD_INTEGRATION_SUMMARY.md # 集成总结文档
└── main.py              # 应用启动入口

2.2 分层架构说明

  1. API层 (app/api/): 处理HTTP请求,参数验证,调用Service层
  2. Service层 (app/services/): 业务逻辑处理,数据转换,调用Model层
  3. Model层 (app/models/): 数据模型定义,数据库操作
  4. Utils层 (app/utils/): 通用工具函数,验证器等
  5. Config层 (app/config/): 配置管理,环境设置

3. 开发规范

3.1 代码规范

3.1.1 注释规范

必须使用JSDoc风格注释:

def process_raster_data(file_path: str, options: dict) -> dict:
    """
    处理栅格数据文件
    
    @param {str} file_path - 栅格文件路径
    @param {dict} options - 处理选项配置
    @returns {dict} 处理结果,包含状态和数据信息
    @throws {ValueError} 当文件路径无效时抛出
    @example
    >>> result = process_raster_data('/path/to/file.tif', {'format': 'GeoTIFF'})
    >>> print(result['status'])
    """
    pass

3.1.2 命名规范

  • 文件名: 使用下划线分隔 (snake_case)
  • 类名: 使用帕斯卡命名 (PascalCase)
  • 函数名: 使用下划线分隔 (snake_case)
  • 变量名: 使用下划线分隔 (snake_case)
  • 常量名: 全大写下划线分隔 (UPPER_SNAKE_CASE)

3.1.3 导入规范

# 标准库导入
import os
import logging
from typing import List, Dict, Optional

# 第三方库导入
from fastapi import FastAPI, HTTPException
from sqlalchemy import create_engine
from geoalchemy2 import Geometry

# 本地模块导入
from .models import Base
from .services import RasterService

3.2 API设计规范

3.2.1 路由组织

  • 栅格数据: /api/raster/*
  • 矢量数据: /api/vector/*
  • Cd预测分析: /api/cd-prediction/*
  • 使用RESTful设计原则

3.2.2 HTTP状态码

  • 200: 成功
  • 201: 创建成功
  • 400: 客户端错误
  • 404: 资源未找到
  • 500: 服务器错误

3.2.3 响应格式

{
    "success": true,
    "message": "操作成功",
    "data": {...},
    "error": null
}

3.3 数据库规范

3.3.1 数据库配置

  • 数据库: PostgreSQL 12+
  • 空间扩展: PostGIS 3.0+
  • 连接池: SQLAlchemy连接池管理
  • 环境配置: config.env文件

3.3.2 模型定义

  • 继承Base类
  • 使用GeoAlchemy2处理空间数据
  • 添加适当的索引和约束

3.3.3 迁移管理

  • 使用Alembic进行数据库迁移

3.4 可视化规范

3.4.1 分辨率设置

  • 默认DPI: 300 (标准分辨率输出)
  • 高分辨率DPI: 600 (高质量输出)
  • 高分辨率模式: 支持通过high_res=True参数启用600 DPI输出
  • 图像格式: JPG格式,支持bbox_inches='tight'自动裁切

3.4.2 分辨率配置层级

  1. 配置文件级别: config.VISUALIZATION_CONFIG["dpi"] = 300
  2. matplotlib全局设置: plt.rcParams['savefig.dpi'] = 300
  3. 方法参数级别: high_res参数可动态控制输出DPI

3.4.3 可视化方法接口

  • 栅格地图: create_raster_map(high_res=False) - 默认300 DPI标准分辨率输出
  • 直方图: create_histogram(high_res=False) - 默认300 DPI标准分辨率输出
  • 图像尺寸: 可通过figure_sizefigsize参数调整

3.4.4 字体配置

  • 优先使用Windows系统中文字体: Microsoft YaHei, SimHei等
  • 支持跨平台字体回退机制
  • 自动字体缓存重建解决字体问题
  • 保持迁移文件版本控制
  • 提供数据库重置脚本

4. 核心组件说明

4.1 数据库层 (database.py)

# 核心配置项
- SQLALCHEMY_DATABASE_URL: 数据库连接字符串
- SessionLocal: 会话工厂
- get_db(): 依赖注入函数
- execute_sql(): 原生SQL执行

4.2 API路由层

  • 栅格API (api/raster.py): 处理栅格数据的CRUD操作
  • 矢量API (api/vector.py): 处理矢量数据的CRUD操作
  • Cd预测API (api/cd_prediction.py): 处理Cd预测模型的调用和结果获取

4.3 业务服务层

  • RasterService: 栅格数据业务逻辑
  • VectorService: 矢量数据业务逻辑
  • CdPredictionService: Cd预测分析业务逻辑

4.4 数据模型层

  • ORM模型: 数据库表映射
    • RasterData: 栅格数据模型
    • VectorData: 矢量数据模型
    • Counties: 县域地理数据模型
    • FarmlandData: 农田样点空间位置与索引数据模型
  • Pydantic模型: API输入输出验证

4.5 Cd预测系统组件

  • CdPredictionWrapper: Cd预测系统包装器
  • CdPredictionConfig: Cd预测配置管理
  • 作物Cd预测模型: 基于神经网络的作物Cd含量预测
  • 有效态Cd预测模型: 基于神经网络的有效态Cd含量预测

5. 开发流程

5.1 新功能开发流程

  1. 需求分析: 确定功能边界和技术方案
  2. 数据模型设计: 设计相关的数据库表和ORM模型
  3. Service层开发: 实现业务逻辑
  4. API层开发: 实现HTTP接口
  5. 测试: 单元测试和集成测试
  6. 文档更新: 更新API文档和代码注释
  7. 规则文件更新: 更新PROJECT_RULES.md中的相关规范

5.2 数据库变更流程

5.2.1 数据库表格添加标准流程

第一步: 创建/修改 ORM 模型

  1. app/models/ 目录下创建或编辑模型文件
  2. 定义SQLAlchemy ORM模型类,继承Base类
  3. 确保在 app/models/__init__.py 中导入新模型

    # 实际案例: 农田数据模型
    # app/models/farmland.py
    from sqlalchemy import Column, Integer, Float
    from geoalchemy2 import Geometry
    from app.database import Base  # 统一的Base导入
    
    class FarmlandData(Base):
    """
    农田样点空间位置与索引数据模型
        
    @param {int} farmland_id - 区域农业用地矢量点编号(主键)
    @param {int} sample_id - 采样自增的ID(主键+自增)
    @param {float} lon - 经度
    @param {float} lan - 纬度
    @param {float} type - 用地类型:旱地(0)、水田(1)、水浇地(2)
    """
    __tablename__ = 'Farmland_data'
        
    farmland_id = Column('Farmland_ID', Integer, primary_key=True)
    sample_id = Column('Sample_ID', Integer, primary_key=True, autoincrement=True)
    lon = Column('lon', Float, nullable=True)
    lan = Column('lan', Float, nullable=True)
    type = Column('Type', Float, nullable=True)
    geom = Column(Geometry('POINT', srid=4326))
    

第二步: 使用迁移脚本生成迁移文件

# 使用项目自带的迁移脚本
python db_migrate.py create "添加新数据表"

# 或直接使用alembic命令
alembic revision --autogenerate -m "添加新数据表"

第三步: 检查生成的迁移文件

  1. 查看 migrations/versions/ 目录下新生成的迁移文件
  2. 验证迁移内容是否正确
  3. 必要时手动调整迁移脚本

第四步: 执行数据库迁移

# 使用项目迁移脚本
python db_migrate.py upgrade

# 或直接使用alembic命令  
alembic upgrade head

第五步: 验证迁移结果

# 查看当前数据库版本
python db_migrate.py current

# 查看迁移历史
python db_migrate.py history

5.2.2 使用sqlacodegen反向生成模型 (可选)

当需要从现有数据库表生成ORM模型时:

# 反向生成所有表的模型
sqlacodegen postgresql://postgres:123456789Qq@localhost/soilgd > models.py

# 生成特定表的模型
sqlacodegen postgresql://postgres:123456789Qq@localhost/soilgd --tables table1,table2 > specific_models.py

5.2.3 数据库脚本命令参考

db_migrate.py 脚本命令:

  • python db_migrate.py create "描述" - 创建新迁移
  • python db_migrate.py upgrade - 升级到最新版本
  • python db_migrate.py downgrade - 降级到上一版本
  • python db_migrate.py current - 显示当前版本
  • python db_migrate.py history - 显示迁移历史
  • python db_migrate.py stamp head - 标记数据库版本

其他数据库操作:

  • python reset_db.py - 重置数据库
  • psql -U postgres -d soilgd -f soilgd.sql - 从备份文件恢复数据库

5.2.4 数据导入脚本开发规范

5.2.4.1 脚本开发原则
  • 统一模式: 所有导入脚本应遵循统一的结构和错误处理模式
  • 参考现有脚本: 可参考 scripts/import_counties.py (GeoJSON导入) 和 scripts/import_farmland_data.py (Excel导入)
  • 完整日志: 实现详细的操作日志记录
  • 事务安全: 确保数据完整性,支持回滚机制
  • 批量处理: 大数据集使用批量插入优化性能
5.2.4.2 数据导入脚本模板结构
"""
数据导入脚本模板
@description: [描述导入的数据类型和来源]
"""

import os
import sys
import logging
# 添加项目根目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.database import SessionLocal
from app.models.[model_file] import [ModelClass]

# 设置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

class [DataType]Importer:
    """
    [数据类型]导入器
    """
    def __init__(self, file_path: str):
        self.file_path = file_path
    
    def read_data(self):
        """读取数据文件"""
        pass
    
    def validate_data(self, data):
        """验证数据格式和完整性"""
        pass
    
    def import_data(self, data):
        """将数据导入到数据库"""
        db = SessionLocal()
        try:
            # 批量处理逻辑
            # 事务提交
            db.commit()
            logger.info("数据导入完成")
        except Exception as e:
            db.rollback()
            logger.error(f"数据导入失败: {str(e)}")
            raise
        finally:
            db.close()
    
    def run_import(self):
        """执行完整的导入流程"""
        try:
            data = self.read_data()
            validated_data = self.validate_data(data)
            self.import_data(validated_data)
        except Exception as e:
            logger.error(f"导入流程失败: {str(e)}")
            raise

def main():
    file_path = "path/to/data/file"
    importer = [DataType]Importer(file_path)
    importer.run_import()

if __name__ == "__main__":
    main()
5.2.4.3 GeoJSON数据导入参考

参考脚本: scripts/import_counties.py

主要特点:

  • 使用JSON模块读取GeoJSON文件
  • 通过模型类的from_geojson_feature方法处理几何数据
  • 完整的错误处理和日志记录
  • 事务安全保证

    # 核心导入逻辑示例
    def import_counties_from_geojson(file_path: str, db: Session):
    with open(file_path, 'r', encoding='utf-8') as f:
        geojson_data = json.load(f)
        
    for feature in geojson_data['features']:
        try:
            county = County.from_geojson_feature(feature)
            db.add(county)
            logger.info(f"成功导入: {county.name}")
        except Exception as e:
            logger.error(f"导入失败: {str(e)}")
            continue
        
    db.commit()
    
5.2.4.4 Excel数据导入参考

参考脚本: scripts/import_farmland_data.py

主要特点:

  • 使用pandas读取Excel文件和指定sheet
  • 支持数据类型转换和映射(如Type字段映射)
  • 自动生成PostGIS几何对象
  • 批量插入优化(1000条/批次)
  • 数据验证和清洗

    # 核心导入逻辑示例
    class FarmlandDataImporter:
    def __init__(self, excel_path, sheet_name='Farmland'):
        self.excel_path = excel_path
        self.sheet_name = sheet_name
        self.type_mapping = {'旱': 0.0, '水田': 1.0, '水浇地': 2.0}
        
    def read_excel_data(self):
        df = pd.read_excel(self.excel_path, sheet_name=self.sheet_name)
        return df
        
    def validate_data(self, df):
        # 数据类型转换
        df['Type_Numeric'] = df['Type'].map(self.type_mapping)
        return df
        
    def create_geometry(self, lon, lat):
        return WKTElement(f'POINT({lon} {lat})', srid=4326)
        
    def import_data(self, df):
        # 批量导入逻辑
        batch_size = 1000
        for i in range(0, len(df), batch_size):
            batch_objects = []
            # ... 创建批次对象
            db.add_all(batch_objects)
            db.commit()
    
5.2.4.5 数据导入最佳实践
  1. 文件路径检查: 导入前验证数据文件是否存在
  2. 数据预览: 读取数据后显示前几行供确认
  3. 字段映射: 建立清晰的字段映射表(如类型编码转换)
  4. 几何数据处理: 自动生成PostGIS兼容的几何对象
  5. 批量操作: 大数据集分批处理,避免内存溢出
  6. 进度跟踪: 显示导入进度和统计信息
  7. 异常处理: 跳过无效数据行,记录详细错误信息
  8. 结果验证: 导入完成后验证数据库中的记录数量
5.2.4.6 常用数据源类型
  • GeoJSON: 地理空间矢量数据(参考import_counties.py
  • Excel/CSV: 结构化表格数据(参考import_farmland_data.py
  • Shapefile: GIS矢量数据(使用geopandas读取)
  • GeoTIFF: 栅格地理数据(使用rasterio处理)

5.2.5 注意事项

  • 备份数据库后再执行迁移
  • 在开发环境先测试迁移
  • 保持迁移文件的版本控制
  • 迁移失败时及时回滚
  • Base类统一性:所有模型必须使用app.database中的同一个Base实例
    • ❌ 错误:from .base import Base(会创建独立的Base)
    • ✅ 正确:from app.database import Base(使用统一的Base)

5.3 代码提交规范

  • feat: 新功能
  • fix: 修复bug
  • docs: 文档更新
  • refactor: 代码重构
  • test: 测试相关
  • integrate: 系统集成

5.4 Cd预测功能开发流程

  1. 模型验证: 确保Cd预测系统完整性
  2. 包装器开发: 创建系统调用包装器
  3. 服务层集成: 实现异步预测服务
  4. API接口开发: 创建预测和下载接口
  5. 文件管理: 实现输出文件的管理和清理
  6. 集成测试: 运行完整的集成测试脚本

6. 环境配置

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)

6.2 环境配置文件

  • config.env: 数据库连接配置
  • environment.yml: Conda环境依赖

6.3 启动命令

# 开发环境
uvicorn app.main:app --reload

# 生产环境  
uvicorn app.main:app --host 0.0.0.0 --port 8000

# Cd集成测试
python test_cd_integration.py

7. 安全规范

7.1 CORS配置

  • 限制允许的源域名
  • 配置适当的HTTP方法和头部

7.2 数据库安全

  • 使用环境变量管理敏感信息
  • 实施连接池管理
  • SQL注入防护

7.3 文件上传安全

  • 文件类型验证
  • 文件大小限制
  • 恶意文件检测

7.4 Cd预测系统安全

  • 预测任务超时控制 (5分钟)
  • 输出文件访问权限管理
  • 敏感路径信息隐藏
  • 异常信息安全过滤

8. 性能优化

8.1 数据库优化

  • 适当的索引设计
  • 查询优化
  • 连接池配置

8.2 API优化

  • 响应压缩
  • 缓存策略
  • 分页处理

8.3 Cd预测性能优化

  • 异步任务处理 (asyncio)
  • CPU密集型任务线程池执行
  • 预测结果文件缓存
  • 自动文件清理 (最多保留10个)

9. 错误处理

9.1 异常分类

  • 业务异常: 4xx HTTP状态码
  • 系统异常: 5xx HTTP状态码
  • 数据库异常: 专门的错误处理

9.2 日志记录

  • 使用Python logging模块
  • 分级别记录日志
  • 敏感信息脱敏

9.3 Cd预测错误处理

  • 预测系统完整性检查
  • 依赖包缺失检测
  • 预测超时异常处理
  • 文件生成失败回退机制

10. 测试规范

10.1 测试覆盖

  • 单元测试: Service层和Utils层
  • 集成测试: API端点测试
  • 数据库测试: 模型和查询测试

10.2 测试数据

  • 使用测试数据库
  • 测试数据隔离
  • 数据清理策略

10.3 Cd预测测试规范

  • 配置模块测试
  • 包装器功能测试
  • API端点注册验证
  • 文件系统完整性检查

11. 部署规范

11.1 部署环境

  • 支持Docker容器化部署
  • SSL证书配置
  • 环境变量管理

11.2 监控和维护

  • 应用性能监控
  • 错误日志监控
  • 数据库性能监控

11.3 Cd预测部署特殊要求

  • 确保Cd_Prediction_Integrated_System目录完整
  • 验证地理空间库安装 (fiona, pyogrio)
  • 配置预测输出目录权限
  • 监控预测任务执行时间

12. API文档规范

12.1 Cd预测API端点

一键接口 (生成并直接返回图片)

POST /api/cd-prediction/crop-cd/generate-and-get-map
POST /api/cd-prediction/effective-cd/generate-and-get-map
POST /api/cd-prediction/crop-cd/generate-and-get-histogram
POST /api/cd-prediction/effective-cd/generate-and-get-histogram

分步式接口 (先生成后下载)

POST /api/cd-prediction/crop-cd/generate-map
POST /api/cd-prediction/effective-cd/generate-map
GET  /api/cd-prediction/crop-cd/download-map
GET  /api/cd-prediction/effective-cd/download-map
GET  /api/cd-prediction/crop-cd/download-histogram
GET  /api/cd-prediction/effective-cd/download-histogram

12.2 一键接口特点

  • 即时响应: 生成完成后直接返回图片文件
  • 简化操作: 无需分两步操作,一次调用完成
  • 适用场景: 前端直接显示、浏览器预览、快速下载
  • 返回格式: 直接返回FileResponse图片文件

12.3 分步式接口特点

  • 灵活控制: 可以先生成后选择性下载
  • 状态查询: 生成接口返回详细的统计信息
  • 批量操作: 生成一次可多次下载不同格式
  • 返回格式: JSON响应包含文件路径和统计信息

12.4 响应格式规范

一键接口响应

Content-Type: image/jpeg
Content-Disposition: attachment; filename="crop_cd_prediction_map.jpg"
[图片文件二进制数据]

分步式接口响应

{
    "success": true,
    "message": "作物Cd预测地图生成成功",
    "data": {
        "map_path": "string",
        "histogram_path": "string", 
        "raster_path": "string",
        "prediction_stats": {}
    },
    "error": null
}

12.5 文档维护

  • 使用FastAPI自动生成文档 (/docs)
  • 更新API变更日志

总结

本规范文档旨在为AcidMap项目的开发提供统一的标准和指导。所有开发人员和AI助手在进行功能开发、代码维护和系统扩展时,都应严格遵循本规范,以确保代码质量、系统稳定性和开发效率。

重要提醒: 本规范文件应与项目功能同步更新。任何新功能集成、架构调整或开发流程变更都必须及时反映到相应的规范章节中。

遇到规范未覆盖的情况时,应优先考虑:

  1. 代码可读性和可维护性
  2. 系统安全性和稳定性
  3. 性能优化和用户体验
  4. 与现有架构的一致性

最后更新: 2025-06-14 (新增数据库导入脚本开发规范和农田数据模型)