初始化集成qgis
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
地图缩放策略模块。支持 5 种缩放模式。
|
||||
"""
|
||||
from qgis.core import (
|
||||
QgsPointXY, QgsGeometry, QgsRectangle,
|
||||
QgsCoordinateTransform, QgsCoordinateReferenceSystem,
|
||||
)
|
||||
|
||||
from app.config.paths import get_logger
|
||||
|
||||
logger = get_logger("qgis.zoom")
|
||||
|
||||
ZOOM_RULES = {
|
||||
"11": "pan_to_center",
|
||||
"12": "by_layer",
|
||||
"13": "layer_intersect",
|
||||
"14": "center_distance",
|
||||
"15": "layer_merged",
|
||||
}
|
||||
|
||||
|
||||
class MapZoom:
|
||||
def __init__(self, project, layout, map_item):
|
||||
self.project = project
|
||||
self.layout = layout
|
||||
self.map_item = map_item
|
||||
|
||||
def execute(self, rule: str, data: dict) -> None:
|
||||
"""执行缩放操作"""
|
||||
method_name = ZOOM_RULES.get(rule, "pan_to_center")
|
||||
method = getattr(self, method_name)
|
||||
logger.info(f"缩放: {method_name}, 参数: {data}")
|
||||
method(data)
|
||||
|
||||
def _make_transform(self, source_crs=None) -> QgsCoordinateTransform:
|
||||
qct = QgsCoordinateTransform()
|
||||
qct.setDestinationCrs(self.map_item.crs())
|
||||
qct.setSourceCrs(
|
||||
source_crs if source_crs
|
||||
else QgsCoordinateReferenceSystem("EPSG:4326")
|
||||
)
|
||||
return qct
|
||||
|
||||
def pan_to_center(self, data: dict) -> None:
|
||||
qct = self._make_transform()
|
||||
point = QgsPointXY(float(data["X"]), float(data["Y"]))
|
||||
geom = QgsGeometry.fromWkt(point.asWkt())
|
||||
geom.transform(qct, QgsCoordinateTransform.ForwardTransform)
|
||||
center = geom.asPoint()
|
||||
qr = QgsRectangle.fromCenterAndSize(
|
||||
center, self.map_item.extent().width(), self.map_item.extent().height()
|
||||
)
|
||||
self.map_item.zoomToExtent(qr)
|
||||
|
||||
def center_distance(self, data: dict) -> None:
|
||||
qct = self._make_transform()
|
||||
point = QgsPointXY(float(data["X"]), float(data["Y"]))
|
||||
geom = QgsGeometry.fromWkt(point.asWkt())
|
||||
geom.transform(qct, QgsCoordinateTransform.ForwardTransform)
|
||||
box = geom.buffer(float(data["value"]) / 1000, 100).boundingBox()
|
||||
self.map_item.zoomToExtent(box.buffered(box.width() * 0.1))
|
||||
|
||||
def by_layer(self, data: dict) -> None:
|
||||
layers = self.project.mapLayersByName(data["value"])
|
||||
if not layers:
|
||||
logger.warning(f"图层不存在: {data['value']}")
|
||||
return
|
||||
layer = layers[0]
|
||||
if layer.featureCount() == 0:
|
||||
self.pan_to_center(data)
|
||||
return
|
||||
qct = self._make_transform(layer.crs())
|
||||
geom = QgsGeometry.fromWkt(layer.extent().asWktPolygon())
|
||||
geom.transform(qct, QgsCoordinateTransform.ForwardTransform)
|
||||
box = geom.boundingBox()
|
||||
self.map_item.zoomToExtent(box.buffered(box.width() * 0.1))
|
||||
|
||||
def layer_merged(self, data: dict) -> None:
|
||||
names = data["value"].split(",")
|
||||
combined = None
|
||||
for name in names:
|
||||
layers = self.project.mapLayersByName(name.strip())
|
||||
if not layers:
|
||||
continue
|
||||
layer = layers[0]
|
||||
qct = self._make_transform(layer.crs())
|
||||
geom = QgsGeometry.fromWkt(layer.extent().asWktPolygon())
|
||||
geom.transform(qct, QgsCoordinateTransform.ForwardTransform)
|
||||
box = geom.boundingBox()
|
||||
if combined is None:
|
||||
combined = box
|
||||
else:
|
||||
combined.combineExtentWith(box)
|
||||
if combined:
|
||||
self.map_item.zoomToExtent(combined.buffered(combined.width() * 0.1))
|
||||
|
||||
def layer_intersect(self, data: dict) -> None:
|
||||
names = data["value"].split(",")
|
||||
intersection = None
|
||||
for name in names:
|
||||
layers = self.project.mapLayersByName(name.strip())
|
||||
if not layers:
|
||||
continue
|
||||
layer = layers[0]
|
||||
qct = self._make_transform(layer.crs())
|
||||
layer.selectAll()
|
||||
geom = None
|
||||
for fid in layer.selectedFeatureIds():
|
||||
if geom is None:
|
||||
geom = layer.getGeometry(fid)
|
||||
else:
|
||||
geom = geom.combine(layer.getGeometry(fid))
|
||||
if geom:
|
||||
qgm = QgsGeometry.fromWkt(geom.asWkt())
|
||||
qgm.transform(qct, QgsCoordinateTransform.ForwardTransform)
|
||||
box = qgm.boundingBox()
|
||||
if intersection is None:
|
||||
intersection = box
|
||||
else:
|
||||
intersection = intersection.intersection(box)
|
||||
if intersection:
|
||||
bbox = intersection.boundingBox()
|
||||
self.map_item.zoomToExtent(bbox.buffered(bbox.width() * 0.1))
|
||||
Reference in New Issue
Block a user