带接口api
This commit is contained in:
parent
b48a792744
commit
6402fbb3ef
BIN
src/assets/images/layer.png
Normal file
BIN
src/assets/images/layer.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
@ -8,6 +8,8 @@
|
||||
<OpenLayersZoomControl
|
||||
:map="map"
|
||||
:resetView="resetView"
|
||||
:routeLayerVisible="routeLayerVisible"
|
||||
@layerToggle="toggleRouteLayer"
|
||||
@compass="compass"
|
||||
@zoomIn="zoomIn"
|
||||
@zoomOut="zoomOut"
|
||||
@ -29,7 +31,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { ref, onMounted, onUnmounted, watch } from "vue";
|
||||
import Map from "ol/Map";
|
||||
import View from "ol/View";
|
||||
import TileLayer from "ol/layer/Tile";
|
||||
@ -45,6 +47,18 @@ import OpenLayersMapInfo from "./controls/OpenLayersMapInfo.vue";
|
||||
import OverviewMap from 'ol/control/OverviewMap';
|
||||
import ScaleLine from 'ol/control/ScaleLine';
|
||||
import OpenLayersScaleControl from "./controls/OpenLayersScaleControl.vue";
|
||||
import OSM from 'ol/source/OSM';
|
||||
import VectorLayer from 'ol/layer/Vector';
|
||||
import VectorSource from 'ol/source/Vector';
|
||||
import Feature from 'ol/Feature';
|
||||
import Point from 'ol/geom/Point';
|
||||
import LineString from 'ol/geom/LineString';
|
||||
import Polygon from 'ol/geom/Polygon';
|
||||
import Style from 'ol/style/Style';
|
||||
import Icon from 'ol/style/Icon';
|
||||
import Stroke from 'ol/style/Stroke';
|
||||
import Fill from 'ol/style/Fill';
|
||||
import { fromLonLat } from 'ol/proj';
|
||||
|
||||
// 注册 EPSG:4528 投影
|
||||
proj4.defs(
|
||||
@ -78,6 +92,12 @@ const minZoom = 7; // 最小缩放级别
|
||||
const maxZoom = 15; // 最大缩放级别
|
||||
const initialZoom = 8; // 设置为7.5,在7和8之间
|
||||
|
||||
const routeLayerVisible = ref(false); // 默认不显示路线图层
|
||||
|
||||
function toggleRouteLayer() {
|
||||
routeLayerVisible.value = !routeLayerVisible.value;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 检查是否有保存的默认视图
|
||||
let savedView = null;
|
||||
@ -110,6 +130,19 @@ onMounted(() => {
|
||||
rotation: savedView ? savedView.rotation : rotation, // 使用保存的旋转角度或默认值
|
||||
});
|
||||
|
||||
// 使用OSM底图
|
||||
const baseLayer = new TileLayer({
|
||||
source: new OSM()
|
||||
});
|
||||
|
||||
// 创建矢量图层
|
||||
const vectorSource = new VectorSource();
|
||||
const vectorLayer = new VectorLayer({
|
||||
source: vectorSource,
|
||||
zIndex: 2,
|
||||
visible: routeLayerVisible.value
|
||||
});
|
||||
|
||||
// 创建地图,与.ol3页面完全一致
|
||||
map.value = new Map({
|
||||
target: mapContainer.value,
|
||||
@ -124,18 +157,7 @@ onMounted(() => {
|
||||
constrainResolution: true,
|
||||
}),
|
||||
]),
|
||||
layers: [
|
||||
// 使用TileLayer包裹TileSuperMapRest
|
||||
new TileLayer({
|
||||
source: new TileSuperMapRest({
|
||||
url: "http://10.96.3.10:8090/iserver/services/map-QDJC_DT-GX3/rest/maps/QDJC2DZT",
|
||||
projection: "EPSG:4528",
|
||||
tileGrid: tileGrid,
|
||||
wrapX: false,
|
||||
attributions: "", // 空字符串移除属性信息
|
||||
}),
|
||||
}),
|
||||
],
|
||||
layers: [baseLayer, vectorLayer],
|
||||
view: view,
|
||||
});
|
||||
|
||||
@ -184,7 +206,73 @@ onMounted(() => {
|
||||
}
|
||||
}, 500);
|
||||
|
||||
// 示例:添加一个点
|
||||
const pointFeature = new Feature({
|
||||
geometry: new Point([13394416, 4136655])
|
||||
});
|
||||
pointFeature.setStyle(new Style({
|
||||
image: new Icon({
|
||||
src: 'https://openlayers.org/en/latest/examples/data/icon.png',
|
||||
scale: 0.7
|
||||
})
|
||||
}));
|
||||
vectorSource.addFeature(pointFeature);
|
||||
|
||||
// 示例:添加一条线
|
||||
const lineFeature = new Feature({
|
||||
geometry: new LineString([
|
||||
[13394416, 4136655],
|
||||
[13395000, 4137000]
|
||||
])
|
||||
});
|
||||
lineFeature.setStyle(new Style({
|
||||
stroke: new Stroke({
|
||||
color: 'blue',
|
||||
width: 2
|
||||
})
|
||||
}));
|
||||
vectorSource.addFeature(lineFeature);
|
||||
|
||||
// 示例:添加一个面
|
||||
const polygonFeature = new Feature({
|
||||
geometry: new Polygon([[
|
||||
[13394416, 4136655],
|
||||
[13395000, 4136655],
|
||||
[13395000, 4137000],
|
||||
[13394416, 4137000],
|
||||
[13394416, 4136655]
|
||||
]])
|
||||
});
|
||||
polygonFeature.setStyle(new Style({
|
||||
stroke: new Stroke({ color: 'red', width: 2 }),
|
||||
fill: new Fill({ color: 'rgba(255,0,0,0.2)' })
|
||||
}));
|
||||
vectorSource.addFeature(polygonFeature);
|
||||
|
||||
// --- 随机生成青岛附近的路线 ---
|
||||
function randomLngLat() {
|
||||
const lng = 120.1 + Math.random() * 0.4;
|
||||
const lat = 35.9 + Math.random() * 0.4;
|
||||
return [lng, lat];
|
||||
}
|
||||
// 生成3条路线,每条5~8个点
|
||||
for (let i = 0; i < 3; i++) {
|
||||
const points = [];
|
||||
const count = 5 + Math.floor(Math.random() * 4);
|
||||
for (let j = 0; j < count; j++) {
|
||||
points.push(fromLonLat(randomLngLat()));
|
||||
}
|
||||
const lineFeature = new Feature({
|
||||
geometry: new LineString(points)
|
||||
});
|
||||
lineFeature.setStyle(new Style({
|
||||
stroke: new Stroke({
|
||||
color: ['red', 'blue', 'green'][i % 3],
|
||||
width: 3
|
||||
})
|
||||
}));
|
||||
vectorSource.addFeature(lineFeature);
|
||||
}
|
||||
|
||||
// 确保地图完全加载后再次调整视图
|
||||
setTimeout(() => {
|
||||
@ -211,6 +299,10 @@ onMounted(() => {
|
||||
// 当地图旋转时,不需要额外操作,OpenLayers内部会自动处理拖拽方向
|
||||
// 但我们可以在这里做一些自定义处理,比如更新UI等
|
||||
});
|
||||
|
||||
watch(routeLayerVisible, (val) => {
|
||||
vectorLayer.setVisible(val);
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
@ -39,10 +39,10 @@ function handleMouseMove(event) {
|
||||
// 3. 转换为WGS84
|
||||
try {
|
||||
const [lng, lat] = transform(coordinate, 'EPSG:4528', 'EPSG:4326');
|
||||
console.log('WGS84坐标:', lng, lat);
|
||||
//console.log('WGS84坐标:', lng, lat);
|
||||
wgs84Text.value = `WGS84: 经度=${lng.toFixed(6)}°, 纬度=${lat.toFixed(6)}°`;
|
||||
} catch (error) {
|
||||
console.error('坐标转换失败:', error);
|
||||
// console.error('坐标转换失败:', error);
|
||||
wgs84Text.value = 'WGS84: 转换错误';
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1,7 +1,25 @@
|
||||
<template>
|
||||
<div class="zoom-control">
|
||||
<LayerSwitcher class="layer-switcher" :map="map" @layerChange="onLayerChange" ref="layerSwitcherRef" />
|
||||
|
||||
<el-popover
|
||||
placement="right"
|
||||
width="160"
|
||||
trigger="click"
|
||||
v-model:visible="popoverVisible"
|
||||
popper-class="layer-popover"
|
||||
>
|
||||
<el-checkbox
|
||||
:model-value="props.routeLayerVisible"
|
||||
@change="onLayerToggle"
|
||||
>道路图层</el-checkbox>
|
||||
<template #reference>
|
||||
<div
|
||||
class="layer-toggle"
|
||||
:class="{ active: props.routeLayerVisible }"
|
||||
@click="handleLayerBtnClick"
|
||||
title="图层控制"
|
||||
></div>
|
||||
</template>
|
||||
</el-popover>
|
||||
<div class="compass" @click="onCompass"></div>
|
||||
<div class="zoom-in" @click="onZoomIn"></div>
|
||||
<div class="zoom-out" @click="onZoomOut"></div>
|
||||
@ -10,6 +28,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ElPopover, ElCheckbox } from 'element-plus';
|
||||
// import LayerSwitcher from './LayerSwitcher.vue';
|
||||
|
||||
// 定义props接受地图实例
|
||||
@ -18,6 +37,10 @@ const props = defineProps({
|
||||
resetView: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
routeLayerVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
@ -25,7 +48,9 @@ const props = defineProps({
|
||||
const layerSwitcherRef = ref(null);
|
||||
|
||||
// 向父组件发出事件
|
||||
const emit = defineEmits(['compass', 'zoomIn', 'zoomOut', 'layerChange']);
|
||||
const emit = defineEmits(['compass', 'zoomIn', 'zoomOut', 'layerChange', 'layerToggle']);
|
||||
|
||||
const popoverVisible = ref(false);
|
||||
|
||||
// 指南针/重置视图
|
||||
function onCompass() {
|
||||
@ -57,6 +82,14 @@ function onLayerChange(layerInfo) {
|
||||
emit('layerChange', layerInfo);
|
||||
}
|
||||
|
||||
function onLayerToggle() {
|
||||
emit('layerToggle');
|
||||
}
|
||||
|
||||
function handleLayerBtnClick() {
|
||||
popoverVisible.value = !popoverVisible.value;
|
||||
}
|
||||
|
||||
// 导出方法供外部调用
|
||||
defineExpose({
|
||||
// 设置图层可见性的方法
|
||||
@ -83,6 +116,22 @@ defineExpose({
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.layer-toggle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: url("../../../assets/images/layer.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
z-index: 3000;
|
||||
border-radius: 8px;
|
||||
border: 2px solid transparent;
|
||||
box-sizing: border-box;
|
||||
transition: border 0.2s;
|
||||
}
|
||||
.layer-toggle.active {
|
||||
border: 2px solid #409eff;
|
||||
box-shadow: 0 0 8px #409eff44;
|
||||
}
|
||||
.compass {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
@ -91,15 +140,6 @@ defineExpose({
|
||||
cursor: pointer;
|
||||
z-index: 3000;
|
||||
}
|
||||
.layer-switcher{
|
||||
z-index: 3000;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: url("../../../assets/images/layer.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.zoom-in {
|
||||
background: url("../../../assets/images/zoomOut.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
@ -108,7 +148,6 @@ defineExpose({
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.zoom-out {
|
||||
background: url("../../../assets/images/zoomIn.png") no-repeat;
|
||||
background-size: 100% 100%;
|
||||
@ -120,7 +159,7 @@ defineExpose({
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.zoom-in, .zoom-out, .compass {
|
||||
.zoom-in, .zoom-out, .compass, .layer-toggle {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background-size: 80%;
|
||||
@ -128,4 +167,9 @@ defineExpose({
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.layer-popover {
|
||||
padding: 12px 16px;
|
||||
min-width: 120px;
|
||||
}
|
||||
</style>
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="platform-overview">
|
||||
<div class="platform-overview platform-no-padding">
|
||||
<OpenLayersMap />
|
||||
<CarAlarm />
|
||||
<!-- 右侧展开/收起按钮 -->
|
||||
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, onMounted, onUnmounted } from 'vue';
|
||||
import OpenLayersMap from '../../components/map/OpenLayersMap.vue';
|
||||
import CarAlarm from '../../components/map/info/carClarm.vue';
|
||||
import Eventlist from '../../components/map/info/eventlist.vue';
|
||||
@ -27,17 +27,24 @@ const showEventList = ref(false);
|
||||
function toggleEventList() {
|
||||
showEventList.value = !showEventList.value;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.querySelector('.app-main')?.classList.add('platform-no-padding');
|
||||
});
|
||||
onUnmounted(() => {
|
||||
document.querySelector('.app-main')?.classList.remove('platform-no-padding');
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.platform-overview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height:calc(100vh - 60px);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
z-index:1;
|
||||
}
|
||||
|
||||
/* 右侧展开/收起按钮样式 */
|
||||
@ -51,4 +58,17 @@ function toggleEventList() {
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
/* 只影响本页,精准去除AppMain的左右padding */
|
||||
:deep(.platform-no-padding) .app-main {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.app-main.platform-no-padding {
|
||||
padding-left: 0 !important;
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
|
||||
proxy: {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
'/dev-api': {
|
||||
target: 'http://10.0.0.17:8099',
|
||||
target: 'http://localhost:8099',
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, '')
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user