123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- <template>
- <div ref="containerRef" class="map-container">
- <div
- ref="mapRef"
- id="YztMap"
- class="map-container"
- :style="{
- width: width,
- height: height,
- transform: 'scale(' + inverseScale.inverseScaleX + ', ' + inverseScale.inverseScaleY + ')',
- transformOrigin: '0 0'
- }"
- ></div>
- <!-- 右下工具 -->
- <div v-show="mapState.showScale" class="zoom-text">{{ mapState.zoom }}级</div>
- <div class="right-tool">
- <!-- 快捷缩放 -->
- <QuickZoom v-model:zoom="mapState.zoom" @change-step="setMapZoom" />
- <div class="flex" style="margin-top: 5px; justify-content: center">
- <div class="mask-btn" @click="handleShowMask">{{ showMask ? '显' : '隐' }}</div>
- <!-- <div class="model-btn" @click="switchThreeDimensional">{{ mapState.isThreeDimensional ? '3D' : '2D' }}</div>-->
- <div class="ruler-icon" style="margin-left: 5px" @click="changeScaleControl"></div>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import 'ol/ol.css';
- import mmJson from '@/assets/json/mm.json';
- import { olMap } from '@/utils/olMap/olMap';
- import { PointType } from '@/api/globalMap/type';
- import { ScaleLine } from 'ol/control';
- interface Props {
- activeMap: string;
- pointType: PointType[];
- showMask: boolean;
- }
- const containerScale = inject('containerScale');
- const props = withDefaults(defineProps<Props>(), {});
- const emits = defineEmits(['update:drawing', 'update:showMask', 'selectGraphics']);
- const mapRef = ref(null);
- const mapState = reactive({
- center: [110.925175, 21.978955],
- zoom: 8.5,
- minZoom: 6,
- maxZoom: 16,
- isThreeDimensional: false,
- // 是否显示比例尺
- showScale: true
- });
- const containerRef = ref();
- const width = ref('100%');
- const height = ref('100%');
- let yztMap, map;
- // 监听是否开启绘制
- watch(
- () => props.drawing,
- (value) => {
- if (value) {
- map.drawGraphics(props.graphicsType);
- } else {
- map.closeDraw();
- }
- }
- );
- const mapList = reactive({
- satellite2: ['YZT1715739306532', 'YZT1695608158269'],
- satellite3: ['YZT1708679726700', 'YZT1695608158269'],
- imageMap: ['YZT1640925052482', 'YZT1695608158269'],
- imageMap2: ['YZT1640925052482', 'YZT1695608158269']
- });
- // 监听地图类型变化
- watch(
- () => props.activeMap,
- () => {
- if (!map) return;
- map.replaceLayers(mapList[props.activeMap]);
- }
- );
- watch(
- () => props.showMask,
- () => {
- if (props.showMask) {
- map.createVecByJson(mmJson, '茂名市');
- } else {
- map.removeMask();
- }
- }
- );
- let scaleLine;
- const init = () => {
- map = new olMap({
- dom: mapRef.value,
- id: mapList[props.activeMap],
- center: mapState.center,
- zoom: mapState.zoom,
- minZoom: mapState.minZoom,
- maxZoom: mapState.maxZoom,
- drawTool: {
- use: true,
- color: props.color,
- drawType: props.drawType,
- graphicsType: props.graphicsType,
- // 绘制完成事件
- onDrawCompleted: (data, overlaysData, obj) => {
- emits('selectGraphics', data, overlaysData.length.toString());
- // 点击空间分析
- obj.on('click', function () {
- // 没在编辑时
- if (!props.drawing) {
- emits('selectGraphics', data);
- }
- });
- }
- },
- // 加载完成事件
- onLoadCompleted: (yMap) => {
- yztMap = yMap;
- // initMouseTool(map);
- scaleLine = new ScaleLine();
- yztMap.addControl(scaleLine);
- yztMap.getView().on('change:resolution', () => {
- mapState.zoom = yztMap.getView().getZoom().toFixed(2);
- });
- if (props.showMask) {
- map.createVecByJson(mmJson, '茂名市');
- }
- handleResize();
- }
- });
- };
- const addMarker = (points) => {
- map.addMarker(points);
- };
- // 设置地图层级
- const setMapZoom = (value) => {
- if (!yztMap) return;
- const view = yztMap.getView();
- if (value === 1) {
- view.setCenter([110.925175, 21.678955]);
- view.setZoom(7.9);
- } else if (value === 2) {
- view.setCenter([110.925175, 21.6789558]);
- view.setZoom(9.21);
- } else if (value === 3) {
- view.setCenter([110.925175, 21.678955]);
- view.setZoom(11.38);
- } else if (value === 4) {
- view.setCenter([110.925175, 21.678955]);
- view.setZoom(12.83);
- }
- };
- // 切换2D、3D
- const switchThreeDimensional = () => {
- const view = yztMap.map.getView();
- mapState.isThreeDimensional = !mapState.isThreeDimensional;
- const pitch = mapState.isThreeDimensional ? 45 : 0;
- view.setPitch(pitch);
- };
- // 切换比例尺
- const changeScaleControl = () => {
- mapState.showScale = !mapState.showScale;
- if (mapState.showScale) {
- yztMap.addControl(scaleLine);
- } else {
- yztMap.removeControl(scaleLine);
- }
- };
- const clearMarker = () => {
- map.clearMarker();
- };
- const handleShowMask = () => {
- emits('update:showMask', !props.showMask);
- };
- defineExpose({ addMarker, clearMarker });
- let inverseScale = ref({
- inverseScaleX: 1,
- inverseScaleY: 1
- });
- const handleResize = () => {
- inverseScale.value.inverseScaleX = 1 / containerScale().scaleX;
- inverseScale.value.inverseScaleY = 1 / containerScale().scaleY;
- const containerWidth = containerRef.value.clientWidth * containerScale().scaleX;
- const containerHeight = containerRef.value.clientHeight * containerScale().scaleY;
- width.value = containerWidth + 'px';
- height.value = containerHeight + 'px';
- yztMap.updateSize();
- };
- // 加载事件
- onMounted(() => {
- init();
- window.addEventListener('resize', handleResize);
- });
- // 卸载事件
- onUnmounted(() => {
- window.removeEventListener('resize', handleResize);
- });
- </script>
- <style scoped>
- .map-container {
- width: 100%;
- height: 100%;
- position: relative;
- .zoom-text {
- position: absolute;
- bottom: 120px;
- right: 170px;
- color: #eaf3fc;
- font-size: 25.73px;
- }
- .right-tool {
- position: absolute;
- bottom: 160px;
- right: 175px;
- z-index: 2;
- }
- .mask-btn {
- background-color: #04327c;
- font-size: 25.73px;
- border: 1px solid #91cfff;
- color: #eaf3fc;
- cursor: pointer;
- padding: 3px 3px;
- border-radius: 5px;
- //margin-right: 5px;
- cursor: pointer;
- }
- .model-btn {
- background-color: #04327c;
- font-size: 25.73px;
- font-family: 'SourceHanSansCN';
- border: 1px solid #91cfff;
- color: #eaf3fc;
- cursor: pointer;
- padding: 3px 3px;
- border-radius: 5px;
- }
- .ruler-icon {
- width: 42px;
- height: 42px;
- background: url('@/assets/images/map/ruler.png') no-repeat;
- background-size: 100% 100%;
- cursor: pointer;
- }
- :deep(.ol-scale-line) {
- left: unset;
- bottom: 16px;
- right: 48px;
- background-color: transparent;
- }
- :deep(.ol-scale-line-inner) {
- color: #ffffff;
- border: 1px solid #fff;
- border-top: none;
- }
- }
- </style>
|