Compare commits
3 Commits
main
...
b7a25899b2
| Author | SHA1 | Date | |
|---|---|---|---|
| b7a25899b2 | |||
| b4cd0d4e35 | |||
| a267d1fa39 |
@@ -48,16 +48,10 @@ class MapService:
|
||||
template_cache.reset_project_state(project, texts, extent)
|
||||
else:
|
||||
logger.info(f"[首次加载] {os.path.basename(template_path)}")
|
||||
modifier = TemplateModifier(self.config)
|
||||
actual_path = modifier.modify(template_path)
|
||||
template_cache.load_template(actual_path, layout_name=model.get("mapLayout", "A4"))
|
||||
if actual_path != template_path:
|
||||
try:
|
||||
os.remove(actual_path)
|
||||
except OSError:
|
||||
pass
|
||||
# 直接读原始模板,不做文件级修改(避免 ZIP 兼容性问题)
|
||||
project.read(template_path)
|
||||
|
||||
# 更新 PostgreSQL 图层连接(仅首次加载)
|
||||
# 更新图层连接 + GPKG/SRID/表名修正(仅首次加载)
|
||||
if not is_cache_hit:
|
||||
self._update_db_connections(project)
|
||||
|
||||
@@ -94,59 +88,89 @@ class MapService:
|
||||
return model["name"]
|
||||
|
||||
def _update_db_connections(self, project: QgsProject) -> None:
|
||||
"""更新所有 PostgreSQL 图层的数据库连接参数"""
|
||||
"""更新图层连接 + SRID修正 + GPKG静态层替换"""
|
||||
db_config = self.config["db"]
|
||||
override = self.config.get("template_override", {})
|
||||
actual_schema = override.get("actual", {}).get("schema", "qgis")
|
||||
static_config = self.config.get("static_layers", {})
|
||||
static_enabled = static_config.get("enabled", False)
|
||||
gpkg_dir = static_config.get("gpkg_dir", "")
|
||||
static_layers_map = static_config.get("layers", {})
|
||||
|
||||
static_count = 0
|
||||
|
||||
for layer in project.mapLayers().values():
|
||||
if layer.providerType() == "ogr":
|
||||
provider = layer.providerType()
|
||||
|
||||
# GPKG 静态层替换:postgres 表 → 本地 GPKG 文件
|
||||
if provider == "postgres" and static_enabled:
|
||||
uri_str = layer.dataProvider().uri().uri()
|
||||
for name, info in static_layers_map.items():
|
||||
table_key = info["table"]
|
||||
schema, table = table_key.split(".", 1)
|
||||
if f'table="{schema}"."{table}"' in uri_str:
|
||||
gpkg_path = os.path.join(gpkg_dir, info["file"]).replace("\\", "/")
|
||||
layer.setDataSource(gpkg_path, name, "ogr")
|
||||
static_count += 1
|
||||
logger.debug(f"静态图层 {name} → GPKG")
|
||||
break
|
||||
else:
|
||||
# 没匹配到静态层,继续处理为 postgres
|
||||
self._fix_postgres_layer(layer, db_config, actual_schema)
|
||||
continue
|
||||
|
||||
if provider == "ogr":
|
||||
static_count += 1
|
||||
continue
|
||||
|
||||
if layer.providerType() != "postgres":
|
||||
continue
|
||||
|
||||
try:
|
||||
uri = layer.dataProvider().uri()
|
||||
uri.setConnection(
|
||||
db_config["host"],
|
||||
str(db_config["port"]),
|
||||
db_config["database"],
|
||||
db_config["username"],
|
||||
db_config["password"],
|
||||
)
|
||||
# 更新 schema
|
||||
old_uri = uri.uri()
|
||||
if f'table="{actual_schema}".' not in old_uri:
|
||||
for old_schema in SCHEMA_REPLACEMENTS:
|
||||
new_uri = old_uri.replace(
|
||||
f'table="{old_schema}".',
|
||||
f'table="{actual_schema}".',
|
||||
)
|
||||
if new_uri != old_uri:
|
||||
uri = QgsDataSourceUri(new_uri)
|
||||
break
|
||||
|
||||
# 表名映射(模板表名 ≠ 目标库表名)
|
||||
uri_str = uri.uri()
|
||||
for old_name, new_name in TABLE_RENAMES.items():
|
||||
full_old = f'table="{actual_schema}"."{old_name}"'
|
||||
full_new = f'table="{actual_schema}"."{new_name}"'
|
||||
if full_old in uri_str:
|
||||
uri_str = uri_str.replace(full_old, full_new)
|
||||
uri = QgsDataSourceUri(uri_str)
|
||||
|
||||
layer.setDataSource(uri.uri(), layer.name(), "postgres")
|
||||
|
||||
if layer.isValid():
|
||||
fc = layer.featureCount()
|
||||
logger.info(f"图层 {layer.name()} 连接更新成功 ({fc} features)")
|
||||
else:
|
||||
logger.error(f"图层 {layer.name()} 更新后仍无效")
|
||||
except Exception as e:
|
||||
logger.error(f"更新图层 {layer.name()} 连接失败: {e}")
|
||||
if provider == "postgres":
|
||||
self._fix_postgres_layer(layer, db_config, actual_schema)
|
||||
|
||||
if static_count:
|
||||
logger.info(f"静态底图已本地化: {static_count} 个 GPKG 图层跳过远程连接")
|
||||
logger.info(f"静态底图已本地化: {static_count} 个图层")
|
||||
|
||||
@staticmethod
|
||||
def _fix_postgres_layer(layer, db_config, actual_schema):
|
||||
"""修正单个 PostgreSQL 图层的连接参数"""
|
||||
try:
|
||||
uri = layer.dataProvider().uri()
|
||||
uri.setConnection(
|
||||
db_config["host"],
|
||||
str(db_config["port"]),
|
||||
db_config["database"],
|
||||
db_config["username"],
|
||||
db_config["password"],
|
||||
)
|
||||
# Schema 替换
|
||||
uri_str = uri.uri()
|
||||
for old_schema in SCHEMA_REPLACEMENTS:
|
||||
if f'table="{old_schema}".' in uri_str:
|
||||
uri_str = uri_str.replace(
|
||||
f'table="{old_schema}".',
|
||||
f'table="{actual_schema}".',
|
||||
)
|
||||
uri = QgsDataSourceUri(uri_str)
|
||||
break
|
||||
# 表名映射
|
||||
uri_str = uri.uri()
|
||||
for old_name, new_name in TABLE_RENAMES.items():
|
||||
full_old = f'table="{actual_schema}"."{old_name}"'
|
||||
full_new = f'table="{actual_schema}"."{new_name}"'
|
||||
if full_old in uri_str:
|
||||
uri_str = uri_str.replace(full_old, full_new)
|
||||
uri = QgsDataSourceUri(uri_str)
|
||||
# SRID 修正
|
||||
uri_str = uri.uri()
|
||||
if " srid=0 " in uri_str:
|
||||
uri_str = uri_str.replace(" srid=0 ", " srid=4326 ")
|
||||
uri = QgsDataSourceUri(uri_str)
|
||||
|
||||
layer.setDataSource(uri.uri(), layer.name(), "postgres")
|
||||
|
||||
if layer.isValid():
|
||||
fc = layer.featureCount()
|
||||
logger.info(f"图层 {layer.name()} 连接更新成功 ({fc} features)")
|
||||
else:
|
||||
logger.error(f"图层 {layer.name()} 更新后仍无效")
|
||||
except Exception as e:
|
||||
logger.error(f"更新图层 {layer.name()} 连接失败: {e}")
|
||||
@@ -37,7 +37,7 @@ class TemplateCache:
|
||||
# 保存到临时文件
|
||||
tmp_file = tempfile.NamedTemporaryFile(
|
||||
suffix=".qgz", delete=False,
|
||||
dir=os.path.dirname(template_path),
|
||||
dir=tempfile.gettempdir(),
|
||||
)
|
||||
tmp_path = tmp_file.name
|
||||
tmp_file.close()
|
||||
|
||||
@@ -69,7 +69,7 @@ class TemplateModifier:
|
||||
try:
|
||||
tmp = tempfile.NamedTemporaryFile(
|
||||
suffix=".qgz", delete=False,
|
||||
dir=os.path.dirname(template_path),
|
||||
dir=tempfile.gettempdir(),
|
||||
)
|
||||
tmp_path = tmp.name
|
||||
tmp.close()
|
||||
|
||||
Reference in New Issue
Block a user