county.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from sqlalchemy import Column, Integer, String, Text, Index, JSON
  2. from sqlalchemy.dialects.postgresql import JSONB
  3. from geoalchemy2 import Geometry
  4. <<<<<<< HEAD
  5. from app.models.orm_models import Base
  6. =======
  7. from app.database import Base
  8. from shapely.geometry import shape, MultiPolygon, Polygon
  9. >>>>>>> 70db4c2c4e190ff614ee0479a8bc3b38ebf02816
  10. import json
  11. class County(Base):
  12. """县级行政区划地理数据表"""
  13. __tablename__ = "counties"
  14. # 字段映射字典
  15. FIELD_MAPPING = {
  16. '县名': 'name',
  17. '县代码': 'code',
  18. '市名': 'city_name',
  19. '市代码': 'city_code',
  20. '省名': 'province_name',
  21. '省代码': 'province_code'
  22. }
  23. # 反向映射字典
  24. REVERSE_FIELD_MAPPING = {v: k for k, v in FIELD_MAPPING.items()}
  25. id = Column(Integer, primary_key=True, index=True)
  26. name = Column(String(100), nullable=False, comment="县名")
  27. code = Column(Integer, comment="县代码")
  28. city_name = Column(String(100), comment="市名")
  29. city_code = Column(Integer, comment="市代码")
  30. province_name = Column(String(100), comment="省名")
  31. province_code = Column(Integer, comment="省代码")
  32. # 使用PostGIS的几何类型来存储多边形数据
  33. geometry = Column(Geometry('MULTIPOLYGON', srid=4326), nullable=False, comment="县级行政区划的几何数据")
  34. # 存储完整的GeoJSON数据
  35. geojson = Column(JSON, nullable=False, comment="完整的GeoJSON数据")
  36. # 显式定义索引
  37. __table_args__ = (
  38. Index('idx_counties_name', 'name'),
  39. Index('idx_counties_code', 'code'),
  40. #Index('idx_counties_geometry', 'geometry', postgresql_using='gist'),
  41. )
  42. @classmethod
  43. def from_geojson_feature(cls, feature):
  44. """从GeoJSON Feature创建County实例
  45. Args:
  46. feature: GeoJSON Feature对象
  47. Returns:
  48. County: 新创建的County实例
  49. """
  50. properties = feature['properties']
  51. # 转换中文字段名为英文
  52. mapped_properties = {
  53. cls.FIELD_MAPPING.get(k, k): v
  54. for k, v in properties.items()
  55. }
  56. # 将GeoJSON geometry转换为EWKT格式(SRID=4326)
  57. geometry = feature['geometry']
  58. geom = shape(geometry)
  59. # 统一为 MultiPolygon 以匹配列类型
  60. if isinstance(geom, Polygon):
  61. geom = MultiPolygon([geom])
  62. wkt = f"SRID=4326;{geom.wkt}"
  63. # 创建实例
  64. county = cls(
  65. **mapped_properties,
  66. geometry=wkt,
  67. geojson=feature
  68. )
  69. return county
  70. def to_geojson_feature(self):
  71. """将County实例转换为GeoJSON Feature
  72. Returns:
  73. dict: GeoJSON Feature对象
  74. """
  75. properties = {}
  76. # 转换英文字段名为中文
  77. for eng_field, cn_field in self.REVERSE_FIELD_MAPPING.items():
  78. if hasattr(self, eng_field):
  79. properties[cn_field] = getattr(self, eng_field)
  80. return {
  81. 'type': 'Feature',
  82. 'properties': properties,
  83. 'geometry': self.geometry
  84. }