添加图例功能,修改地图
@ -23,9 +23,11 @@
|
||||
"default-passive-events": "^2.0.0",
|
||||
"echarts": "^5.2.2",
|
||||
"element-plus": "^2.2.27",
|
||||
"esri-leaflet": "^3.0.19",
|
||||
"js-base64": "^3.7.5",
|
||||
"js-cookie": "^3.0.1",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"leaflet": "^1.9.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
|
||||
23
frontend/src/assets/legend/map-dxsdzYijian.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>map-dxsdzYijian</title>
|
||||
<defs>
|
||||
<path d="M10,0 C15.5228475,0 20,4.4771525 20,10 C20,15.5228475 15.5228475,20 10,20 C4.4771525,20 0,15.5228475 0,10 C0,4.4771525 4.4771525,0 10,0 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<g id="1-首页" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="1.1-首页-水电开发-全国" transform="translate(-158.000000, -812.000000)">
|
||||
<g id="图例备份-4" transform="translate(16.000000, 737.000000)">
|
||||
<g id="编组-9" transform="translate(142.000000, 74.000000)">
|
||||
<g id="map-shuikudaxing-yijian" transform="translate(0.000000, 1.000000)">
|
||||
<g id="路径" fill-rule="nonzero">
|
||||
<use fill="#499934" xlink:href="#path-1"></use>
|
||||
<use fill="#71B603" xlink:href="#path-1"></use>
|
||||
<use fill="#78C300" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<path d="M10,1.66666667 C14.6023729,1.66666667 18.3333333,5.39762709 18.3333333,10 L18.3333333,10 L1.66666667,10 L1.67048694,9.74522729 C1.80514922,5.26072284 5.48285621,1.66666667 10,1.66666667 Z" id="形状结合" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
7
frontend/src/assets/map/ddd1.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="37" height="37" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-374 -236)">
|
||||
<path d="M376.5 255C376.5 245.335 384.111 237.5 393.5 237.5 402.889 237.5 410.5 245.335 410.5 255 410.5 264.665 402.889 272.5 393.5 272.5 384.111 272.5 376.5 264.665 376.5 255Z" stroke="#00B0F0" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/>
|
||||
<path d="M379.5 255.5 406.5 255.5 405.462 260.488C403.409 265.196 398.602 268.5 393 268.5 387.398 268.5 382.591 265.196 380.538 260.488Z" stroke="#00B0F0" stroke-width="1.33333" stroke-miterlimit="8" fill="#5DA6DF" fill-rule="evenodd"/>
|
||||
<path d="M406.5 255.5 379.5 255.5 380.538 250.128C382.591 245.058 387.398 241.5 393 241.5 398.602 241.5 403.409 245.058 405.462 250.128Z" stroke="#00B0F0" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 925 B |
7
frontend/src/assets/map/ddd2.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="37" height="37" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-374 -236)">
|
||||
<path d="M376.5 255C376.5 245.335 384.111 237.5 393.5 237.5 402.889 237.5 410.5 245.335 410.5 255 410.5 264.665 402.889 272.5 393.5 272.5 384.111 272.5 376.5 264.665 376.5 255Z" stroke="#E1AB4F" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/>
|
||||
<path d="M379.5 255.5 406.5 255.5 405.462 260.488C403.409 265.196 398.602 268.5 393 268.5 387.398 268.5 382.591 265.196 380.538 260.488Z" stroke="#E1AB4F" stroke-width="1.33333" stroke-miterlimit="8" fill="#E1AB4F" fill-rule="evenodd"/>
|
||||
<path d="M406.5 255.5 379.5 255.5 380.538 250.128C382.591 245.058 387.398 241.5 393 241.5 398.602 241.5 403.409 245.058 405.462 250.128Z" stroke="#E1AB4F" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 925 B |
7
frontend/src/assets/map/ddd3.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="37" height="37" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-374 -236)">
|
||||
<path d="M376.5 255C376.5 245.335 384.111 237.5 393.5 237.5 402.889 237.5 410.5 245.335 410.5 255 410.5 264.665 402.889 272.5 393.5 272.5 384.111 272.5 376.5 264.665 376.5 255Z" stroke="#0FC55B" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/>
|
||||
<path d="M379.5 255.5 406.5 255.5 405.462 260.488C403.409 265.196 398.602 268.5 393 268.5 387.398 268.5 382.591 265.196 380.538 260.488Z" stroke="#0FC55B" stroke-width="1.33333" stroke-miterlimit="8" fill="#0FC55B" fill-rule="evenodd"/>
|
||||
<path d="M406.5 255.5 379.5 255.5 380.538 250.128C382.591 245.058 387.398 241.5 393 241.5 398.602 241.5 403.409 245.058 405.462 250.128Z" stroke="#0FC55B" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 925 B |
7
frontend/src/assets/map/ddd4.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg width="37" height="37" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-374 -236)">
|
||||
<path d="M376.5 255C376.5 245.335 384.111 237.5 393.5 237.5 402.889 237.5 410.5 245.335 410.5 255 410.5 264.665 402.889 272.5 393.5 272.5 384.111 272.5 376.5 264.665 376.5 255Z" stroke="#91938E" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/>
|
||||
<path d="M379.5 255.5 406.5 255.5 405.462 260.488C403.409 265.196 398.602 268.5 393 268.5 387.398 268.5 382.591 265.196 380.538 260.488Z" stroke="#91938E" stroke-width="1.33333" stroke-miterlimit="8" fill="#91938E" fill-rule="evenodd"/>
|
||||
<path d="M406.5 255.5 379.5 255.5 380.538 250.128C382.591 245.058 387.398 241.5 393 241.5 398.602 241.5 403.409 245.058 405.462 250.128Z" stroke="#91938E" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 925 B |
6
frontend/src/assets/map/dzwj.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-194 -511)">
|
||||
<path d="M195.5 526.5 223.5 526.5 222.423 531.488C220.294 536.196 215.31 539.5 209.5 539.5 203.69 539.5 198.706 536.196 196.577 531.488Z" stroke="#91938E" stroke-width="1.33333" stroke-miterlimit="8" fill="#91938E" fill-rule="evenodd"/>
|
||||
<path d="M223.5 526.5 195.5 526.5 196.577 521.128C198.706 516.058 203.69 512.5 209.5 512.5 215.31 512.5 220.294 516.058 222.423 521.128Z" stroke="#91938E" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
6
frontend/src/assets/map/dzyj.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-194 -511)">
|
||||
<path d="M195.5 526.5 223.5 526.5 222.423 531.488C220.294 536.196 215.31 539.5 209.5 539.5 203.69 539.5 198.706 536.196 196.577 531.488Z" stroke="#00B0F0" stroke-width="1.33333" stroke-miterlimit="8" fill="#5DA6DF" fill-rule="evenodd"/>
|
||||
<path d="M223.5 526.5 195.5 526.5 196.577 521.128C198.706 516.058 203.69 512.5 209.5 512.5 215.31 512.5 220.294 516.058 222.423 521.128Z" stroke="#00B0F0" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
6
frontend/src/assets/map/dzyjwjr.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-194 -511)">
|
||||
<path d="M195.5 526.5 223.5 526.5 222.423 531.488C220.294 536.196 215.31 539.5 209.5 539.5 203.69 539.5 198.706 536.196 196.577 531.488Z" stroke="#E1AB4F" stroke-width="1.33333" stroke-miterlimit="8" fill="#E1AB4F" fill-rule="evenodd"/>
|
||||
<path d="M223.5 526.5 195.5 526.5 196.577 521.128C198.706 516.058 203.69 512.5 209.5 512.5 215.31 512.5 220.294 516.058 222.423 521.128Z" stroke="#E1AB4F" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
6
frontend/src/assets/map/dzzj.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg width="30" height="30" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden">
|
||||
<g transform="translate(-194 -511)">
|
||||
<path d="M195.5 526.5 223.5 526.5 222.423 531.488C220.294 536.196 215.31 539.5 209.5 539.5 203.69 539.5 198.706 536.196 196.577 531.488Z" stroke="#0FC55B" stroke-width="1.33333" stroke-miterlimit="8" fill="#0FC55B" fill-rule="evenodd"/>
|
||||
<path d="M223.5 526.5 195.5 526.5 196.577 521.128C198.706 516.058 203.69 512.5 209.5 512.5 215.31 512.5 220.294 516.058 222.423 521.128Z" stroke="#0FC55B" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 647 B |
@ -24,10 +24,19 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
import MapLegend from "@/components/mapLegend/index.vue";
|
||||
import MapFilter from "@/components/mapFilter/index.vue";
|
||||
import MapController from "@/components/mapController/index.vue";
|
||||
import BaseLayerSwitcher from "@/components/baseLayerSwitcher/index.vue";
|
||||
import BaseLayerSwitcher from "@/components/BaseLayerSwitcher/index.vue";
|
||||
|
||||
import { MapClass } from './map.class'
|
||||
onMounted(() => {
|
||||
const mapClass = MapClass.getInstance()
|
||||
// const globalData = GlobalData.getInstance()
|
||||
//@ts-ignore
|
||||
window.mapClass = mapClass
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -40,7 +49,7 @@ import BaseLayerSwitcher from "@/components/baseLayerSwitcher/index.vue";
|
||||
#mapContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
background-color: red;
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
}
|
||||
</style>
|
||||
|
||||
115
frontend/src/components/gis/event-emitter.ts
Normal file
@ -0,0 +1,115 @@
|
||||
type EventCallback = (...args: any[]) => void;
|
||||
|
||||
export class EventEmitter {
|
||||
private events: Map<string, EventCallback[]> = new Map();
|
||||
|
||||
on(event: string, callback: EventCallback): this {
|
||||
if (!this.events.has(event)) {
|
||||
this.events.set(event, []);
|
||||
}
|
||||
this.events.get(event)!.push(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
off(event: string, callback?: EventCallback): this {
|
||||
if (!this.events.has(event)) return this;
|
||||
|
||||
if (callback) {
|
||||
const callbacks = this.events.get(event)!;
|
||||
const index = callbacks.indexOf(callback);
|
||||
if (index > -1) {
|
||||
callbacks.splice(index, 1);
|
||||
}
|
||||
} else {
|
||||
this.events.delete(event);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
emit(event: string, ...args: any[]): this {
|
||||
if (this.events.has(event)) {
|
||||
this.events.get(event)!.forEach(callback => {
|
||||
try {
|
||||
callback(...args);
|
||||
} catch (error) {
|
||||
console.error(`Event ${event} handler error:`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
once(event: string, callback: EventCallback): this {
|
||||
const onceCallback: EventCallback = (...args: any[]) => {
|
||||
callback(...args);
|
||||
this.off(event, onceCallback);
|
||||
};
|
||||
return this.on(event, onceCallback);
|
||||
}
|
||||
|
||||
removeAllListeners(): this {
|
||||
this.events.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
listenerCount(event: string): number {
|
||||
return this.events.get(event)?.length || 0;
|
||||
}
|
||||
}type EventCallback = (...args: any[]) => void;
|
||||
|
||||
export class EventEmitter {
|
||||
private events: Map<string, EventCallback[]> = new Map();
|
||||
|
||||
on(event: string, callback: EventCallback): this {
|
||||
if (!this.events.has(event)) {
|
||||
this.events.set(event, []);
|
||||
}
|
||||
this.events.get(event)!.push(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
off(event: string, callback?: EventCallback): this {
|
||||
if (!this.events.has(event)) return this;
|
||||
|
||||
if (callback) {
|
||||
const callbacks = this.events.get(event)!;
|
||||
const index = callbacks.indexOf(callback);
|
||||
if (index > -1) {
|
||||
callbacks.splice(index, 1);
|
||||
}
|
||||
} else {
|
||||
this.events.delete(event);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
emit(event: string, ...args: any[]): this {
|
||||
if (this.events.has(event)) {
|
||||
this.events.get(event)!.forEach(callback => {
|
||||
try {
|
||||
callback(...args);
|
||||
} catch (error) {
|
||||
console.error(`Event ${event} handler error:`, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
once(event: string, callback: EventCallback): this {
|
||||
const onceCallback: EventCallback = (...args: any[]) => {
|
||||
callback(...args);
|
||||
this.off(event, onceCallback);
|
||||
};
|
||||
return this.on(event, onceCallback);
|
||||
}
|
||||
|
||||
removeAllListeners(): this {
|
||||
this.events.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
listenerCount(event: string): number {
|
||||
return this.events.get(event)?.length || 0;
|
||||
}
|
||||
}
|
||||
29
frontend/src/components/gis/map.class.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import type { layer, MapInterface } from "./map.d";
|
||||
import { MapLeaflet } from "./map.leaflet";
|
||||
|
||||
interface MapClassInterface extends MapInterface {
|
||||
layers: Map<string, layer>;
|
||||
view: any;
|
||||
}
|
||||
|
||||
export const mapServerBaseUrl = localStorage.getItem("gisurl") || "http://210.72.227.199:18084/";
|
||||
|
||||
export class MapClass implements MapClassInterface {
|
||||
layers: Map<string, layer>;
|
||||
view: any;
|
||||
private static instance: MapClass;
|
||||
private service: MapInterface;
|
||||
|
||||
static getInstance(): MapClass {
|
||||
if (!this.instance) {
|
||||
this.instance = new MapClass();
|
||||
}
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.layers = new Map();
|
||||
this.view = null;
|
||||
this.service = new MapLeaflet();
|
||||
}
|
||||
}
|
||||
232
frontend/src/components/gis/map.d.ts
vendored
Normal file
@ -0,0 +1,232 @@
|
||||
export type layerType =
|
||||
| "markers"
|
||||
| "tiledMap"
|
||||
| "tiledMapQuery"
|
||||
| "geoJson"
|
||||
| "arcgisFeature"
|
||||
| "dynamicMapLayer"
|
||||
| "arcgisMap"
|
||||
| "label";
|
||||
export type layerOption = {
|
||||
opacity?: number;
|
||||
data?: Array<any>;
|
||||
zIndex?: number;
|
||||
clickEvent?: Function;
|
||||
hoverEvent?: Function;
|
||||
legendImages?: Array<any> | null | undefined;
|
||||
geoJsonLegend?: Array<any> | null | undefined;
|
||||
tiledMapType?: undefined | "superMap";
|
||||
};
|
||||
|
||||
export interface layer {
|
||||
id: string;
|
||||
key: string;
|
||||
_layer?: any;
|
||||
type?: layerType;
|
||||
url?: string;
|
||||
urlThd?: string;
|
||||
label?: string;
|
||||
thumbnail?: string;
|
||||
visible?: boolean;
|
||||
option?: layerOption;
|
||||
tempobj?: any;
|
||||
opacity?: any;
|
||||
}
|
||||
|
||||
export interface MapInterface {
|
||||
getRainColor: any;
|
||||
getRainColor1: any;
|
||||
removeContentmarkers: any;
|
||||
removeGanliumarkers: any;
|
||||
addarcgisLayerWithNotLine: any
|
||||
/**
|
||||
* 地图初始化
|
||||
* @param container DOM容器
|
||||
* @return any 地图视图
|
||||
*/
|
||||
init(container: React.ReactNode, rectangle?: any, center?: any): Promise<any>;
|
||||
|
||||
/**
|
||||
*添加 图层
|
||||
*/
|
||||
addLayer(layer: layer): any;
|
||||
|
||||
/**
|
||||
* 添加canvasMarker
|
||||
*/
|
||||
addCanvasMarker(
|
||||
data: Array<any>,
|
||||
legend?: Array<any>,
|
||||
option?: { skipRemoveHtml?: boolean },
|
||||
flag?: any
|
||||
): any;
|
||||
|
||||
invalidateSize(): void;
|
||||
|
||||
getRain(data: any): void;
|
||||
/**
|
||||
* 添加地图缩放监听事件
|
||||
*/
|
||||
addZoomEvent(func: Function, type?: string): void;
|
||||
|
||||
/**
|
||||
* 添加鼠标移动事件
|
||||
* @param func 事件
|
||||
*/
|
||||
addMouseMoveEvent(func: Function): void;
|
||||
|
||||
/**
|
||||
* 添加鼠标点击事件
|
||||
* @param func 事件
|
||||
*/
|
||||
addMouseClickEvent(func: Function): void;
|
||||
|
||||
/**
|
||||
* 定位
|
||||
* @param data
|
||||
*/
|
||||
fitBounds(data: any): void;
|
||||
|
||||
/**
|
||||
* 获取所有的图层
|
||||
*/
|
||||
getLayers(): Map<string, layer> | null;
|
||||
|
||||
/**
|
||||
* 获取地图缩放级别
|
||||
*/
|
||||
getMapZoom(): number;
|
||||
|
||||
/**
|
||||
* 放大
|
||||
*/
|
||||
zoomEnlarge(): number;
|
||||
|
||||
/**
|
||||
* 缩小
|
||||
*/
|
||||
zoomNarrow(): number;
|
||||
|
||||
/**
|
||||
* 获取当前地图视图的比例尺或者缩放级别
|
||||
*/
|
||||
getMapZoomOrScale(): { scale?: number; zoom?: number };
|
||||
|
||||
/**
|
||||
* 显示图层
|
||||
* @param layers
|
||||
*/
|
||||
showLayer(id: string): void;
|
||||
|
||||
/**
|
||||
* 隐藏图层
|
||||
* @param layers
|
||||
*/
|
||||
hideLayer(id: string): void;
|
||||
|
||||
/**
|
||||
* 设置地图位置
|
||||
* @param position
|
||||
*/
|
||||
setCenter(position: { lat: number; lng: number }, zoom?: any): void;
|
||||
|
||||
/**
|
||||
* 移除所有图层
|
||||
*/
|
||||
removeAllLayer(): void;
|
||||
|
||||
/**
|
||||
* 移除所有站点标签
|
||||
*/
|
||||
removeAllLabel(): void;
|
||||
|
||||
/**
|
||||
* 移除图层
|
||||
* @param layer
|
||||
*/
|
||||
removeLayer(layer: layer): void;
|
||||
|
||||
/**
|
||||
* 重新渲染图层数据
|
||||
*/
|
||||
reRenderLayer(
|
||||
key: string,
|
||||
options?: { opacity?: number; data: Array<any>; zIndex?: number }
|
||||
): Promise<any>;
|
||||
|
||||
/**
|
||||
* 移除鼠标移动事件监听
|
||||
*/
|
||||
removeMouseMoveEvent(): void;
|
||||
|
||||
/**
|
||||
* 移除监听事件
|
||||
*/
|
||||
removeEvent(type: string, func: Function): void;
|
||||
|
||||
/**
|
||||
* 移除要素图层
|
||||
*/
|
||||
removeFeatureLayer(): void;
|
||||
|
||||
/**
|
||||
* 移除水系图层
|
||||
*/
|
||||
removedataSource(item: any): void;
|
||||
|
||||
/**
|
||||
* 移除鼠标点击事件监听
|
||||
*/
|
||||
removeMouseClickEvent(): void;
|
||||
|
||||
/**
|
||||
* 缩放
|
||||
* out 放大
|
||||
* in 缩小
|
||||
*/
|
||||
zoomToggle(type: "out" | "in"): void;
|
||||
|
||||
/**
|
||||
* 增加arcgis图层
|
||||
*/
|
||||
addarcgisLayer(item: any, data?: any): void;
|
||||
|
||||
/**
|
||||
* 增加图层label
|
||||
*/
|
||||
addmapLabel(item: any, data: any, zoom: any): void;
|
||||
addmapLine(item: any, data: any): void;
|
||||
|
||||
/**
|
||||
* 删除arcgis图层
|
||||
*/
|
||||
removearcgisLayer(): void;
|
||||
|
||||
/**
|
||||
* 删除图层label
|
||||
*/
|
||||
removearcgisLabel(): void;
|
||||
|
||||
removeLayermarkers(): void;
|
||||
|
||||
removeRainLayer(): void;
|
||||
|
||||
removeGroupLayer(): void;
|
||||
|
||||
removeMapLayer(): void;
|
||||
|
||||
/**
|
||||
* 测距
|
||||
*/
|
||||
handelstartDrawLine(): void;
|
||||
|
||||
/**
|
||||
* 测面积
|
||||
*/
|
||||
handelstartDrawPolygon(): void;
|
||||
|
||||
/**
|
||||
* 清除
|
||||
*/
|
||||
handelclearLayer(): void;
|
||||
}
|
||||
373
frontend/src/components/gis/map.leaflet.ts
Normal file
@ -0,0 +1,373 @@
|
||||
import { layer, MapInterface } from "./map";
|
||||
import * as L from "leaflet";
|
||||
import * as esriLeaflet from "esri-leaflet";
|
||||
import { mapServerBaseUrl } from "./map.class";
|
||||
// @ts-ignore
|
||||
import axios from "axios";
|
||||
// import "@/components/thematicMap/leaflet/leaflet.inflatable-markers-group.js"
|
||||
|
||||
const tiledMapGroup = L.layerGroup();
|
||||
const chartMapGroup = L.layerGroup();
|
||||
const overlayGroup = L.layerGroup();
|
||||
const CENTER_positionCN: any = [37.072654, 86.171125]; // [26.072654, 107.171125]; //中心纬经度 中国
|
||||
|
||||
let boundCavansLayer: any = null;
|
||||
let ganliulist:any = []
|
||||
export class MapLeaflet implements MapInterface {
|
||||
map: any = null;
|
||||
htmlMakerLayer: any = [];
|
||||
minimumZoom = 7;
|
||||
|
||||
temperatureMapObj: any = [];
|
||||
|
||||
addLayer(layer: any): any {
|
||||
// The WMTS URL
|
||||
console.warn(layer)
|
||||
switch (layer.type) {
|
||||
case "tiledMap":
|
||||
if (layer.url) {
|
||||
let setzIndex = 1;
|
||||
if (layer.zIndex && layer.zIndex != "" && layer.zIndex != "0") {
|
||||
setzIndex = Number(layer.zIndex);
|
||||
}
|
||||
if (layer.title !== '干流河流') {
|
||||
layer._layer = esriLeaflet
|
||||
.dynamicMapLayer({
|
||||
url: layer.url,
|
||||
opacity: layer.opacity,
|
||||
zIndex: 999999999999
|
||||
})
|
||||
?.addTo(this.map)
|
||||
.bringToBack()
|
||||
} else {
|
||||
axios.get('http://210.72.227.199:18084/geoserver/cite/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=cite:glhl_epsg4326&maxFeatures=50&outputFormat=application%2Fjson')
|
||||
.then((res) => {
|
||||
res.data?.features.map((item: any, index: number) => {
|
||||
const a = L.geoJSON(item, {
|
||||
style: {
|
||||
},
|
||||
}).addTo(this.map);
|
||||
ganliulist.push(a)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
return layer;
|
||||
break
|
||||
case "geoserver-wmts":
|
||||
if (layer.url) {
|
||||
if (layer.title == "地图瓦片图层") {
|
||||
console.log('地图瓦片')
|
||||
//增加遮罩
|
||||
axios.get('/zfile/qgcbuji/overlayLand3.json')
|
||||
.then((res) => {
|
||||
var landLayer = L.geoJson(res.data, {
|
||||
style: {
|
||||
opacity: 0,
|
||||
//填充透明度
|
||||
fillOpacity: 1,
|
||||
//填充颜色
|
||||
fillColor: '#ececec'
|
||||
}
|
||||
})?.addTo(overlayGroup).bringToBack();
|
||||
})
|
||||
axios.get('/zfile/qgcbuji/overlayOcean.json')
|
||||
.then((res) => {
|
||||
var oceanLayer = L.geoJson(res.data, {
|
||||
style: {
|
||||
opacity: 0,
|
||||
//填充透明度
|
||||
fillOpacity: 1,
|
||||
//填充颜色
|
||||
fillColor: '#8eccf1'
|
||||
}
|
||||
})?.addTo(overlayGroup).bringToFront();
|
||||
})
|
||||
overlayGroup?.addTo(this.map);
|
||||
}
|
||||
var optionobj = JSON.parse(layer.options);
|
||||
if (optionobj) {
|
||||
var ignLayer = L.tileLayer
|
||||
.wmts(layer.url, {
|
||||
tileMatrixSet: optionobj.tileMatrixSet, //"EPSG:3857_qgc_arcgistiles_l13_google",
|
||||
tileSize: 256, //切片大小
|
||||
maxZoom: 13,
|
||||
noWrap: true,
|
||||
opacity: 1.01,
|
||||
minZoom: 4,
|
||||
layer: optionobj.layer, //"qgc_arcgistiles_l13_google",
|
||||
})
|
||||
.addTo(this.map)
|
||||
.bringToBack();
|
||||
layer._layer = ignLayer;
|
||||
layer._layer.layerGroup = overlayGroup;
|
||||
}
|
||||
}
|
||||
return layer;
|
||||
case "arcgisMap":
|
||||
if (layer.url) {
|
||||
if (this.map) {
|
||||
const mapLayer = esriLeaflet
|
||||
.tiledMapLayer({
|
||||
url: layer.url,
|
||||
format: "image/png",
|
||||
maxNativeZoom: 17,
|
||||
})
|
||||
.addTo(this.map)
|
||||
.bringToBack();
|
||||
layer._layer = mapLayer;
|
||||
}
|
||||
}
|
||||
return layer;
|
||||
case "tiledMapQuery":
|
||||
if (layer.url && layer.id) {
|
||||
if (layer.title == "岛屿") {
|
||||
layer.layers = "cite:nhqddt_epsg3857";
|
||||
}
|
||||
layer._layer = L.tileLayer
|
||||
.wms(layer.url, {
|
||||
id: layer.id,
|
||||
format: "image/png",
|
||||
transparent: true,
|
||||
zIndex: 9999,
|
||||
layers: layer.layers,
|
||||
// maxZoom:10,
|
||||
})
|
||||
.addTo(this.map);
|
||||
// .bringToBack();
|
||||
return layer;
|
||||
}
|
||||
return layer;
|
||||
case "label":
|
||||
if (layer.url) {
|
||||
const tileLayer: any = L.tileLayer(layer.url, {
|
||||
subdomains: ["0", "1", "2", "3", "4", "5", "6", "7"],
|
||||
crossOrigin: "anonymous",
|
||||
});
|
||||
const boundary = (providerName: any) => {
|
||||
// return BoundaryCanvas(tileLayer, {});
|
||||
};
|
||||
let boundaryLayers;
|
||||
if (layer.title == "行政标注") {
|
||||
boundaryLayers = boundary(tileLayer._leaflet_id)
|
||||
.addTo(this.map)
|
||||
.bringToBack()
|
||||
.setZIndex(10);
|
||||
} else {
|
||||
boundaryLayers = boundary(tileLayer._leaflet_id).addTo(this.map);
|
||||
}
|
||||
tileLayer.boundLayer = boundaryLayers;
|
||||
layer._layer = boundaryLayers;
|
||||
return layer;
|
||||
}
|
||||
break;
|
||||
|
||||
case "markers":
|
||||
this.getRain(layer);
|
||||
break;
|
||||
default: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用于消除瓦片之间的缝隙(leaflet加载wmts在非整数缩放时瓦片间会有缝隙)
|
||||
*/
|
||||
inittiles() {
|
||||
var originalInitTile = L.GridLayer.prototype._initTile;
|
||||
L.GridLayer.include({
|
||||
_initTile: function (tile: any) {
|
||||
originalInitTile.call(this, tile);
|
||||
|
||||
var tileSize = this.getTileSize();
|
||||
|
||||
tile.style.width = tileSize.x + 2 + "px";
|
||||
tile.style.height = tileSize.y + 2 + "px";
|
||||
},
|
||||
});
|
||||
}
|
||||
init(container: React.ReactNode, rectangle?: any): Promise<any> {
|
||||
try {
|
||||
console.log("init初始化container", container);
|
||||
this.inittiles();
|
||||
// var corner1 = L.latLng(0.712, -10.227),
|
||||
// corner2 = L.latLng(70.774, 204.125),
|
||||
|
||||
// var corner1 = L.latLng(-50.712, -10.227),
|
||||
// corner2 = L.latLng(100.774, 204.125),
|
||||
// var corner1 = L.latLng(20.712, 50.227),
|
||||
// corner2 = L.latLng(51.774, 160.125),
|
||||
var corner1 = L.latLng(20.712, 0),
|
||||
corner2 = L.latLng(51.774, 179.125),
|
||||
bounds = L.latLngBounds(corner1, corner2);
|
||||
const map = L.map(container as any, {
|
||||
preferCanvas: true,
|
||||
minZoom: 4.4,
|
||||
center: CENTER_positionCN,
|
||||
zoom: 4.4,
|
||||
maxZoom: 18,
|
||||
zoomControl: false,
|
||||
maxBounds: bounds,
|
||||
zoomSnap: 0,
|
||||
crs: L.CRS.EPSG3857,
|
||||
});
|
||||
this.map = map;
|
||||
|
||||
//遮罩
|
||||
var pNW = { lat: 85.0, lng: -90.0 };
|
||||
var pNE = { lat: 85.0, lng: 270.0 };
|
||||
var pSE = { lat: -45.0, lng: 270.0 };
|
||||
var pSW = { lat: -45.0, lng: -90.0 };
|
||||
var pArray = [];
|
||||
pArray.push(pNW);
|
||||
pArray.push(pSW);
|
||||
pArray.push(pSE);
|
||||
pArray.push(pNE);
|
||||
pArray.push(pNW);
|
||||
|
||||
let mapURL =
|
||||
mapServerBaseUrl + "arcgis/rest/services/zh_boundary/MapServer/0/query";
|
||||
esriLeaflet
|
||||
.query({
|
||||
url: mapURL,
|
||||
})
|
||||
// .where(mapWhere)
|
||||
.run((error: any, result: any, response: any) => {
|
||||
if (response) {
|
||||
// let test = arcgisToGeoJSON(response);
|
||||
// let chinaList = test.features[0].geometry.coordinates;
|
||||
// var boundsCounty = [
|
||||
// [0.0, -20.0],
|
||||
// [276.0, -20.0],
|
||||
// [276.0, 75.0],
|
||||
// [0.0, 75.0],
|
||||
// [0.0, -20.0],
|
||||
// ];
|
||||
// console.log("chinaList", chinaList);
|
||||
|
||||
// var geojsonRelt: any = {
|
||||
// type: "Feature",
|
||||
// properties: {},
|
||||
// geometry: {
|
||||
// type: "MultiPolygon",
|
||||
// coordinates: [[boundsCounty, ...chinaList]],
|
||||
// },
|
||||
// };
|
||||
|
||||
// var chinaCavansLayer = L.geoJSON(geojsonRelt, {
|
||||
// style: {
|
||||
// color: "#8EA5BA",
|
||||
// weight: 1,
|
||||
// fillColor: "#ffffff",
|
||||
// fillOpacity: 1,
|
||||
// },
|
||||
// });
|
||||
//chinaCavansLayer.addTo(this.map).bringToBack().setZIndex(0);
|
||||
}
|
||||
});
|
||||
|
||||
let params = {
|
||||
startTime: "2022-01-01 00:00:00",
|
||||
};
|
||||
|
||||
|
||||
L.control
|
||||
.scale({ maxWidth: 150, metric: true, imperial: false })
|
||||
.addTo(this.map);
|
||||
this.map.on("zoomend", (e: any) => {
|
||||
var scale = document.getElementsByClassName(
|
||||
"leaflet-control-scale-line"
|
||||
)[0].innerHTML;
|
||||
var num = parseInt(scale);
|
||||
|
||||
if (scale.includes("km")) {
|
||||
console.log("比例尺:1:" + num * 1000 + "m");
|
||||
} else {
|
||||
console.log("比例尺1:" + num + "m");
|
||||
}
|
||||
console.log("scale", scale);
|
||||
|
||||
console.log("当前缩放级别", e.target.getZoom());
|
||||
});
|
||||
console.log("rectangle", rectangle);
|
||||
if (rectangle) {
|
||||
if (rectangle[0] && rectangle[0][0] == 90) {
|
||||
//this.map.setView([43.719771, 126.687641,], 9);
|
||||
} else {
|
||||
map.fitBounds(rectangle);
|
||||
}
|
||||
}
|
||||
return Promise.resolve(map);
|
||||
} catch (e) {
|
||||
console.log("测试", e);
|
||||
return Promise.reject({});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
removeLayer(layer: layer | any): void {
|
||||
switch (layer.type) {
|
||||
case "geoJson":
|
||||
break;
|
||||
default:
|
||||
if (layer._layer) {
|
||||
if (layer._layer.layerGroup) {
|
||||
layer._layer.layerGroup.clearLayers();
|
||||
}
|
||||
this.map?.off("zoom", layer._layer.func);
|
||||
this.map && this.map.removeLayer(layer._layer);
|
||||
} else if (layer) {
|
||||
if (layer.layerGroup) {
|
||||
layer.layerGroup.clearLayers();
|
||||
}
|
||||
this.map?.off("zoom", layer.func);
|
||||
this.map && this.map.removeLayer(layer);
|
||||
let mapvalue = tiledMapGroup.getLayers();
|
||||
|
||||
for (let i = 0; i < mapvalue.length; i++) {
|
||||
if (mapvalue[i].options.id == layer.id) {
|
||||
tiledMapGroup.removeLayer(mapvalue[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
addboundCavansLayer = (list: any, bgStyle?: any) => {
|
||||
if (boundCavansLayer && this.map.hasLayer(boundCavansLayer)) {
|
||||
this.map.removeLayer(boundCavansLayer);
|
||||
}
|
||||
var boundsCounty = [
|
||||
[0.0, -20.0],
|
||||
[176.0, -20.0],
|
||||
[176.0, 75.0],
|
||||
[0.0, 75.0],
|
||||
[0.0, -20.0],
|
||||
];
|
||||
var geojsonRelt: any = {
|
||||
type: "Feature",
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: "MultiPolygon",
|
||||
coordinates: [[boundsCounty, ...list]],
|
||||
},
|
||||
};
|
||||
var boundCavansLayerRelt = L.geoJSON(
|
||||
geojsonRelt,
|
||||
bgStyle
|
||||
? { ...bgStyle }
|
||||
: {
|
||||
color: "transparent",
|
||||
fillColor: "#0a2b4b",
|
||||
fillOpacity: 0.9,
|
||||
}
|
||||
);
|
||||
boundCavansLayer = boundCavansLayerRelt;
|
||||
console.warn(boundCavansLayerRelt.addTo)
|
||||
boundCavansLayerRelt.addTo(this.map).bringToFront().setZIndex(99999999999);
|
||||
};
|
||||
|
||||
}
|
||||
@ -1,8 +1,14 @@
|
||||
<template>
|
||||
<a-tooltip placement="leftBottom" trigger="click" color="transparent" :overlayInnerStyle="{boxShadow: 'none'}">
|
||||
<a-tooltip
|
||||
placement="leftBottom"
|
||||
trigger="click"
|
||||
color="transparent"
|
||||
:overlayInnerStyle="{ boxShadow: 'none' }"
|
||||
>
|
||||
<template #title>
|
||||
<div class="layers-tree">
|
||||
<div class="layers-tree-title">图层管理</div>
|
||||
|
||||
<div class="layers-tree-content">
|
||||
<a-Tree
|
||||
checkable
|
||||
@ -19,74 +25,73 @@
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
const onCheck = () => {
|
||||
console.log("点击了测量工具");
|
||||
};
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import { useMapStore } from "@/store/modules/map";
|
||||
import { useRoute } from "vue-router";
|
||||
let route = useRoute();
|
||||
const mapStore: any = useMapStore();
|
||||
// 图层数据
|
||||
const layerConfigs = computed(() => mapStore.layerData);
|
||||
|
||||
// 选中的图层
|
||||
const checkedKeys = ref([]);
|
||||
const layerConfigs = ref([
|
||||
{
|
||||
title: "图层1",
|
||||
key: "layer1",
|
||||
children: [
|
||||
{
|
||||
title: "子图层1",
|
||||
key: "sublayer1",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "图层2",
|
||||
key: "layer2",
|
||||
},
|
||||
{
|
||||
title: "图层3",
|
||||
key: "layer3",
|
||||
},
|
||||
{
|
||||
title: "图层4",
|
||||
key: "layer4",
|
||||
},
|
||||
{
|
||||
title: "图层5",
|
||||
key: "layer5",
|
||||
},
|
||||
{
|
||||
title: "图层6",
|
||||
key: "layer6",
|
||||
},
|
||||
{
|
||||
title: "图层7",
|
||||
key: "layer7",
|
||||
},
|
||||
{
|
||||
title: "图层8",
|
||||
key: "layer8",
|
||||
},
|
||||
{
|
||||
title: "图层9",
|
||||
key: "layer9",
|
||||
},
|
||||
{
|
||||
title: "图层10",
|
||||
key: "layer10",
|
||||
},
|
||||
{
|
||||
title: "图层11",
|
||||
key: "layer11",
|
||||
},
|
||||
{
|
||||
title: "图层12",
|
||||
key: "layer12",
|
||||
},
|
||||
{
|
||||
title: "图层13",
|
||||
key: "layer13",
|
||||
},
|
||||
]);
|
||||
const onSelect = (selectedKeys: any) => {
|
||||
console.log(selectedKeys);
|
||||
const onCheck = (v: any, e: any) => {
|
||||
// 环保设施和环保设施在建数据获取,两者只能同时存在勾选一项
|
||||
const fData = layerConfigs.value?.filter((e: any) => e.key === "facilities")?.[0];
|
||||
const fbData = layerConfigs.value?.filter((e: any) => e.key === "facilities_built")?.[0];
|
||||
const facilities_built_data =
|
||||
(fbData && [fbData.key, ...fbData?.children?.map((e: any) => e.key)]) || [];
|
||||
const facilities_data =
|
||||
(fData && [fData.key, ...fData?.children?.map((e: any) => e.key)]) || [];
|
||||
|
||||
let checkKeys = v;
|
||||
|
||||
if (e?.node.key === "rare_fish_point") {
|
||||
checkKeys = v?.filter((item: any) => item !== "fish_along_point");
|
||||
} else if (e?.node.key === "fish_along_point") {
|
||||
checkKeys = v?.filter((item: any) => item !== "rare_fish_point");
|
||||
}
|
||||
if (e.checked) {
|
||||
if (e?.node.key === "stinfo_video_point" || e?.node.key == "stinfo") {
|
||||
checkKeys = v?.filter((item: any) => item !== "stinfo_ai_video_point");
|
||||
} else if (e?.node.key === "stinfo_ai_video_point") {
|
||||
checkKeys = v?.filter(
|
||||
(item: any) => item !== "stinfo_video_point" && item !== "stinfo"
|
||||
);
|
||||
}
|
||||
console.log(checkKeys, "res111");
|
||||
|
||||
if (
|
||||
checkKeys.some((e: any) => facilities_data.includes(e)) &&
|
||||
checkKeys.some((e: any) => facilities_built_data.includes(e))
|
||||
) {
|
||||
if (
|
||||
facilities_built_data.some((e: any) =>
|
||||
e.includes(checkKeys[checkKeys.length - 1])
|
||||
)
|
||||
) {
|
||||
checkKeys = checkKeys.filter((e: any) => !facilities_data.includes(e));
|
||||
} else if (
|
||||
facilities_data.some((e: any) => e.includes(checkKeys[checkKeys.length - 1]))
|
||||
) {
|
||||
checkKeys = checkKeys.filter((e: any) => !facilities_built_data.includes(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
checkedKeys.value = checkKeys;
|
||||
mapStore.updateLayerData(checkKeys);
|
||||
};
|
||||
const getCheckedKeys = () => {
|
||||
const name = route.path.split("/")[2];
|
||||
if (name === "shuiDianKaiFaZhuangKuang") {
|
||||
checkedKeys.value = ["customBaseLayer", "eng", "eng_point"];
|
||||
}
|
||||
mapStore.updateLayerData(checkedKeys.value);
|
||||
};
|
||||
onMounted(() => {
|
||||
getCheckedKeys();
|
||||
// router.push({ name: 'map' })
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.map-item {
|
||||
|
||||
46
frontend/src/components/mapLegend/LegendItem.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<!-- LegendItem.vue -->
|
||||
<template>
|
||||
<div
|
||||
class="legendItem"
|
||||
:class="{ gray: item.checked == 0, disabled: item.canBeChecked == 0 }"
|
||||
>
|
||||
<div class="legendIcon" :class="{ smallIcon: item.layerCode == 'eng_point' }">
|
||||
<img :src="getIconPath(item.icon)" alt="" />
|
||||
</div>
|
||||
<div class="legendIconTitle">
|
||||
<span v-html="item.name" style="white-space: pre-wrap"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getIconPath } from '@/utils/index';
|
||||
defineProps<{ item: any }>();
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.legendItem {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
padding: 4px 0;
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.legendIcon {
|
||||
width: 25px !important;
|
||||
height: 25px !important;
|
||||
// background-color: red;
|
||||
text-align: center;
|
||||
}
|
||||
.smallIcon {
|
||||
width: 22px !important;
|
||||
height: 22px !important;
|
||||
}
|
||||
.legendIconTitle {
|
||||
cursor: pointer;
|
||||
flex: 1 1;
|
||||
}
|
||||
&:hover {
|
||||
color: #2f6b98;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -8,20 +8,27 @@
|
||||
</div>
|
||||
|
||||
<div class="legendContent" v-show="isOpen">
|
||||
<a-spin :spinning="data === 0">
|
||||
<div class="legendGroup" v-for="i in data">
|
||||
<div class="groupTitle">工程</div>
|
||||
<a-spin :spinning="legendData.length === 0">
|
||||
<div class="legendGroup" v-for="i in legendData">
|
||||
<div class="groupTitle">{{ i.name }} {{ i.layerCode }}</div>
|
||||
<div class="groupContent">
|
||||
<div class="legendItem" v-for="j in 10" :key="j">
|
||||
<div class="legendIcon smallIcon"></div>
|
||||
<div class="legendIconTitle">
|
||||
大型水电站-已建
|
||||
<!-- <span
|
||||
><br />
|
||||
2.、装机容量(万kW)
|
||||
</span> -->
|
||||
<template v-for="j in i.childrenList" :key="j.name">
|
||||
<LegendItem v-if="j.layerCode" :item="j" @click="legendItemClick(j)" />
|
||||
<div
|
||||
v-else-if="j.childrenList && j.childrenList.length > 0"
|
||||
class="legendGroup"
|
||||
>
|
||||
<div class="groupTitle">{{ j.name }}</div>
|
||||
<div class="groupContent">
|
||||
<LegendItem
|
||||
v-for="item in j.childrenList"
|
||||
:key="item.layerCode"
|
||||
:item="item"
|
||||
@click="legendItemClick(item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
@ -29,13 +36,50 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from "vue";
|
||||
const data = ref(0);
|
||||
import { onMounted, ref, computed, watch } from "vue";
|
||||
import { useMapStore } from "@/store/modules/map";
|
||||
import LegendItem from "@/components/mapLegend/LegendItem.vue";
|
||||
const mapStore: any = useMapStore();
|
||||
// 图层数据
|
||||
const legendData = ref(mapStore.legendDataSelected);
|
||||
const legendItemClick = (item: any) => {
|
||||
if (item.canBeChecked == 0) {
|
||||
return;
|
||||
}
|
||||
item.checked = item.checked == 0 ? 1 : 0;
|
||||
};
|
||||
watch(
|
||||
() => mapStore.legendDataSelected,
|
||||
(newValue) => {
|
||||
// layerConfigs.value = newValue;
|
||||
console.log(newValue);
|
||||
legendData.value = newValue;
|
||||
// for (let i = 0; i < newValue.length; i++) {
|
||||
// console.log(mapStore.layerData[i]);
|
||||
// if (newValue[i].key != "-") {
|
||||
// if (newValue[i].checked == 1) {
|
||||
// if (newValue[i].children?.length > 0) {
|
||||
// legendData.value.push(newValue[i]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
data.value = 10;
|
||||
}, 1000);
|
||||
console.log(data.value);
|
||||
// for (let i = 0; i < mapStore.layerData.length; i++) {
|
||||
// console.log(mapStore.layerData[i]);
|
||||
// if (mapStore.layerData[i].key != "-") {
|
||||
// if (mapStore.layerData[i].checked == 1) {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// console.log(layerConfigs.value)
|
||||
// setTimeout(() => {
|
||||
// data.value = 10;
|
||||
// }, 1000);
|
||||
// console.log(data.value);
|
||||
});
|
||||
const isOpen = ref(true);
|
||||
</script>
|
||||
@ -69,10 +113,6 @@ const isOpen = ref(true);
|
||||
overflow-x: scroll;
|
||||
overflow-y: scroll;
|
||||
border-top: 1px solid #eeeeee;
|
||||
overflow-y: hidden;
|
||||
// &::-webkit-scrollbar {
|
||||
// width: 0;
|
||||
// }
|
||||
.legendGroup {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
@ -91,22 +131,8 @@ const isOpen = ref(true);
|
||||
filter: grayscale(100%);
|
||||
color: #00000073;
|
||||
}
|
||||
.legendItem {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
padding: 4px 0;
|
||||
min-height: 30px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.legendIcon {
|
||||
width: 22px !important;
|
||||
height: 22px !important;
|
||||
background-color: red;
|
||||
}
|
||||
.legendIconTitle {
|
||||
cursor: pointer;
|
||||
flex: 1 1;
|
||||
}
|
||||
.disabled {
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,23 +3,36 @@
|
||||
<div>
|
||||
<SidePanelItem title="基本情况介绍" :shrink="true">
|
||||
<p v-if="title_text" class="basic_body1">{{ title_text }}</p>
|
||||
<div v-else class="zanwushujv"> <a-empty /></div>
|
||||
<div v-else class="zanwushujv"><a-empty /></div>
|
||||
</SidePanelItem>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
import SidePanelItem from "@/components/SidePanelItem/index.vue";
|
||||
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
// 定义组件名(便于调试和递归)
|
||||
defineOptions({
|
||||
name: 'jidiInfoMod'
|
||||
name: "jidiInfoMod",
|
||||
});
|
||||
const title_text = ref('我国水能资源丰富,主要集中在金沙江、长江上游、雅砻江、黄河上游、大渡河、南盘江-红水河、乌江和西南诸河等流域,总技术可开发量约3.81亿kW,占全国技术可开发量的55.5%。截至2023年年底,雅砻江、金沙江、大渡河、乌江、长江上游、南盘江-红水河等流域已建和在建比例超80%,水能资源开发程度较高,剩余待开发水利资源主要集中在西南诸河,发展潜力巨大。')
|
||||
const title_text = ref(
|
||||
"我国水能资源丰富,主要集中在金沙江、长江上游、雅砻江、黄河上游、大渡河、南盘江-红水河、乌江和西南诸河等流域,总技术可开发量约3.81亿kW,占全国技术可开发量的55.5%。截至2023年年底,雅砻江、金沙江、大渡河、乌江、长江上游、南盘江-红水河等流域已建和在建比例超80%,水能资源开发程度较高,剩余待开发水利资源主要集中在西南诸河,发展潜力巨大。"
|
||||
);
|
||||
watch(
|
||||
() => JidiSelectEventStore.selectedItem,
|
||||
(newVal) => {
|
||||
console.log(newVal);
|
||||
if (newVal.name == '当前全部') {
|
||||
}
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
// 页面加载时执行的逻辑
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
onMounted(() => {});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@ -3,12 +3,11 @@ import { ref } from "vue";
|
||||
import { useJidiSelectEventStore } from "@/store/modules/jidiSelectEvent";
|
||||
const loading = ref(false);
|
||||
const isOpen = ref(true);
|
||||
const jidiData = useJidiSelectEventStore().jidiData;
|
||||
const JidiSelectEventStore = useJidiSelectEventStore();
|
||||
|
||||
const jidiDataNum = ref(9);
|
||||
const selectedItem: any = ref(1);
|
||||
const itemClick = (id: any) => {
|
||||
selectedItem.value = id;
|
||||
const itemClick = (index: any) => {
|
||||
useJidiSelectEventStore().updataJidiData(index);
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -17,7 +16,7 @@ const itemClick = (id: any) => {
|
||||
<a-spin :spinning="loading">
|
||||
<div
|
||||
class="qgc-dropdown-select"
|
||||
@mouseenter="jidiDataNum = jidiData.length"
|
||||
@mouseenter="jidiDataNum = JidiSelectEventStore.jidiData.length"
|
||||
@mouseleave="jidiDataNum = 9"
|
||||
>
|
||||
<div class="title" @click="isOpen = !isOpen">
|
||||
@ -29,9 +28,9 @@ const itemClick = (id: any) => {
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="item"
|
||||
v-for="i in jidiData.slice(0, jidiDataNum)"
|
||||
:class="{ selected: selectedItem === i.id }"
|
||||
@click="itemClick(i.id)"
|
||||
v-for="(i, index) in JidiSelectEventStore.jidiData.slice(0, jidiDataNum)"
|
||||
:class="{ selected: i.selected }"
|
||||
@click="itemClick(index)"
|
||||
>
|
||||
<i class="icon iconfont icon-hydroPower"></i>
|
||||
<span style="margin-left: 10px">{{ i.name }}</span>
|
||||
|
||||
@ -5,51 +5,72 @@ export const useJidiSelectEventStore = defineStore('jidiSelectEvent', () => {
|
||||
const jidiData = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: "当前全部",
|
||||
name: '当前全部',
|
||||
selected: true
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "水电基地2",
|
||||
name: '水电基地2',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "水电基地3",
|
||||
name: '水电基地3',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "水电基地4",
|
||||
name: '水电基地4',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "水电基地5",
|
||||
name: '水电基地5',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "水电基地6",
|
||||
name: '水电基地6',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "水电基地7",
|
||||
name: '水电基地7',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "水电基地8",
|
||||
name: '水电基地8',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "水电基地9",
|
||||
name: '水电基地9',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "水电基地10",
|
||||
name: '水电基地10',
|
||||
selected: false
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: "水电基地11",
|
||||
},
|
||||
]);
|
||||
name: '水电基地11',
|
||||
selected: false
|
||||
}
|
||||
]);
|
||||
const selectedItem = ref(jidiData.value[0]);
|
||||
const updataJidiData = (index: any) => {
|
||||
selectedItem.value = jidiData.value[index];
|
||||
jidiData.value.forEach((item: any) => {
|
||||
item.selected = false;
|
||||
});
|
||||
jidiData.value[index].selected = true;
|
||||
};
|
||||
|
||||
return {
|
||||
jidiData
|
||||
jidiData,
|
||||
selectedItem,
|
||||
updataJidiData
|
||||
};
|
||||
});
|
||||
5259
frontend/src/store/modules/map.ts
Normal file
@ -27,6 +27,22 @@ body::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background-color: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 4px;
|
||||
background: #bbb;
|
||||
-webkit-box-shadow: inset 0 0 6px #ddd;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
// main-container global css
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
@ -64,13 +80,13 @@ svg {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.moduleContent{
|
||||
.moduleContent {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.leftContent {
|
||||
width: 188px;
|
||||
@ -79,4 +95,3 @@ svg {
|
||||
height: 98%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
@ -95,3 +95,19 @@ export function downloadFile(obj :any, name :any, suffix :any) {
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
const modules = import.meta.glob('@/assets/legend/*.svg', { eager: true });
|
||||
// 图例图标映射
|
||||
export const iconMap: Record<string, string> = {};
|
||||
Object.entries(modules).forEach(([path, module]) => {
|
||||
const fileName = path.match(/\/([^/]+)\.svg$/)?.[1];
|
||||
console.log(fileName)
|
||||
if (fileName) {
|
||||
iconMap[fileName] = (module as any).default;
|
||||
}
|
||||
});
|
||||
// 获取图标路径
|
||||
export const getIconPath = (icon: string): string => {
|
||||
console.log(iconMap[icon] )
|
||||
return iconMap[icon] || '';
|
||||
};
|
||||
@ -33,8 +33,8 @@ service.interceptors.request.use(
|
||||
service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
const { status, msg } = response;
|
||||
console.log(msg)
|
||||
console.log(response);
|
||||
// console.log(msg)
|
||||
// console.log(response);
|
||||
if (status === 200) {
|
||||
if (response.data.code == 401) {
|
||||
message.error(response.data.msg||'请求失败');
|
||||
|
||||