新增多个图层;更新图层图标;修复SCADA设备列表状态功能

This commit is contained in:
JIANG
2025-10-30 11:57:06 +08:00
parent b3d9c7a97a
commit 265ecdc795
9 changed files with 125 additions and 37 deletions

View File

@@ -18,7 +18,7 @@ import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile";
import MVT from "ol/format/MVT";
import { FlatStyleLike } from "ol/style/flat";
import { toLonLat } from "ol/proj";
import { along, bearing, lineString, length } from "@turf/turf";
import { along, bearing, lineString, length, toMercator } from "@turf/turf";
import { Deck } from "@deck.gl/core";
import { TextLayer } from "@deck.gl/layers";
import { TripsLayer } from "@deck.gl/geo-layers";
@@ -26,7 +26,9 @@ import { CollisionFilterExtension } from "@deck.gl/extensions";
import VectorSource from "ol/source/Vector";
import GeoJson from "ol/format/GeoJSON";
import VectorLayer from "ol/layer/Vector";
import { Style, Icon } from "ol/style";
import { Icon, Style } from "ol/style.js";
import { FeatureLike } from "ol/Feature";
import { Point } from "ol/geom";
interface MapComponentProps {
children?: React.ReactNode;
@@ -189,6 +191,52 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
}),
});
};
// 定义 reservoirs 图层的样式函数,使用固定图标
const reservoirsStyle = () => {
const reserviorIcon = "/icons/reservior.svg";
return new Style({
image: new Icon({
src: reserviorIcon,
scale: 0.1, // 根据需要调整图标大小
anchor: [0.5, 0.5], // 图标锚点居中
}),
});
};
// 定义 valves 图层的样式函数,使用固定图标
const valvesStyle = function (feature: FeatureLike) {
const styles = [];
const valveIcon = "/icons/valve.svg";
const geometry = feature.getGeometry();
const lineCoords =
geometry?.getType() === "LineString"
? (geometry as any).getCoordinates()
: null;
if (geometry) {
const lineCoordsWGS84 = lineCoords.map((coord: []) => {
const [lon, lat] = toLonLat(coord);
return [lon, lat];
});
// 计算中点
const lineStringFeature = lineString(lineCoordsWGS84);
const lineLength = length(lineStringFeature);
const midPoint = along(lineStringFeature, lineLength / 2).geometry
.coordinates;
// 在中点添加 icon 样式
const midPointMercator = toMercator(midPoint);
styles.push(
new Style({
geometry: new Point(midPointMercator),
image: new Icon({
src: valveIcon,
scale: 0.12,
anchor: [0.5, 0.5],
}),
})
);
}
return styles;
};
// 矢量瓦片数据源和图层
const junctionSource = new VectorTileSource({
url: `${mapUrl}/gwc/service/tms/1.0.0/TJWater:geo_junctions_mat@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL
@@ -204,6 +252,14 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_scada&outputFormat=application/json`,
format: new GeoJson(),
});
const reservoirsSource = new VectorSource({
url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_reservoirs&outputFormat=application/json`,
format: new GeoJson(),
});
const valvesSource = new VectorSource({
url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_valves&outputFormat=application/json`,
format: new GeoJson(),
});
// WebGL 渲染优化显示
const junctionLayer = new WebGLVectorTileLayer({
source: junctionSource as any, // 使用 WebGL 渲染
@@ -212,7 +268,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
maxZoom: 24,
minZoom: 12,
properties: {
name: "节点图层", // 设置图层名称
name: "节点", // 设置图层名称
value: "junctions",
type: "point",
properties: [
@@ -232,7 +288,7 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
maxZoom: 24,
minZoom: 12,
properties: {
name: "管道图层", // 设置图层名称
name: "管道", // 设置图层名称
value: "pipes",
type: "linestring",
properties: [
@@ -263,6 +319,32 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
properties: [],
},
});
const reservoirsLayer = new VectorLayer({
source: reservoirsSource,
style: reservoirsStyle,
extent: extent, // 设置图层范围
maxZoom: 24,
minZoom: 12,
properties: {
name: "水库", // 设置图层名称
value: "reservoirs",
type: "point",
properties: [],
},
});
const valvesLayer = new VectorLayer({
source: valvesSource,
style: valvesStyle,
extent: extent, // 设置图层范围
maxZoom: 24,
minZoom: 12,
properties: {
name: "阀门", // 设置图层名称
value: "valves",
type: "linestring",
properties: [],
},
});
useEffect(() => {
if (!mapRef.current) return;
// 缓存 junction、pipe 数据,提供给 deck.gl 显示标签使用
@@ -396,10 +478,17 @@ const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
const map = new OlMap({
target: mapRef.current,
view: new View({
maxZoom: 24,
projection: "EPSG:3857",
}),
// 图层依面、线、点、标注次序添加
layers: [pipeLayer, junctionLayer, scadaLayer],
layers: [
pipeLayer,
junctionLayer,
valvesLayer,
scadaLayer,
reservoirsLayer,
],
controls: [],
});
setMap(map);