<template> <div class="mapDrawTool"> <div id="mapboxDrawContainer"> <div id="nf-address-search-input" v-if="inputShow"> <el-input clearable id="pickerInput" placeholder="请输入位置名称" v-model="inputText" :prefix-icon="Search" style="width: 300px" @input="inputGetAddress()" /> </div> <div class="addressOption" v-if="addressListIsShow"> <div class="addressOptionItem" v-for="item in addressList" @click="clickAddress(item)"> {{ item.formatted_address }} </div> </div> </div> </div> </template> <script> import bus from '@/bus'; import axios from 'axios'; import request from '@/utils/request'; import kaifengWaterLabel1 from '@/assets/geojson/kaifeng/kaifengWaterLabel1.json'; import kaifengWater from '@/assets/geojson/kaifeng/kaifengWater.json'; import WaterAnalysis_icon from '@/assets/images/gisMap/in.png'; import { nextTick } from 'vue'; export default { components: {}, props: { initJson: { type: String, default: () => '/static/libs/mapbox/style/floodOneMap.json', }, isNeedInput: { type: Boolean, default: true, }, isCanClick: { type: Boolean, default: true, }, previousPoint: { type: String, default: '', }, previousPointName: { type: String, default: '', }, }, setup(props, event) { const allData = reactive({ inputText: '', addressList: [], addressListIsShow: false, pointGeometry: '', inputShow: true, }); let map = null; let config = null; const initeMap = async () => { config = (await axios.get(props.initJson)).data; let { sprites, l7 } = config.params; window.mapBoxSelectPositionMap = new mapboxL7.Scene({ id: 'mapboxDrawContainer', map: new mapboxL7.Mapbox({ style: config.params.init.style, center: config.params.init.center, zoom: config.params.init.zoom, }), }); mapBoxSelectPositionMap.map.load = false; map = mapBoxSelectPositionMap.map; map.ogcLayers = []; mapBoxSelectPositionMap.unLoadLayers = []; (sprites || []).forEach(url => { map.style._loadSprite(url.includes('http') ? url : window.location.href.split('#')[0] + url); }); ((l7 || []).images || []).forEach(item => mapBoxSelectPositionMap.addImage(item.name, item.url.includes('http') ? item.url : window.location.href.split('#')[0] + item.url) ); setTimeout(() => { map.on('load', async () => { const mouseLocation = new mapboxL7.MouseLocation({ transform: position => { return [position[0].toFixed(6), position[1].toFixed(6)]; }, }); mapBoxSelectPositionMap.addControl(mouseLocation); !!!map.getSource('kaifengWater') && map.addSource('kaifengWater', { type: 'geojson', data: kaifengWater }); !!!map.getLayer('kaifengWater') && map.addLayer({ id: 'kaifengWater', type: 'fill', source: 'kaifengWater', paint: { 'fill-color': '#0c3b7a', }, }); addWaterLabel(); props.loadCallback && props.loadCallback(); if (props.previousPoint && props.previousPointName) { let drewPoint = turf.featureCollection([turf.point(props.previousPoint.split(',').map(Number))]); drewPoint.features[0].properties.name = props.previousPointName; addPointToMap(drewPoint); map.easeTo({ center: props.previousPoint.split(',').map(Number), zoom: 14, }); } else { let timeout = setTimeout(() => { let { pitch, center } = config.params.init; pitch && mapBoxSelectPositionMap.map.setPitch(pitch); center && mapBoxSelectPositionMap.map.setCenter(center); clearTimeout(timeout); }, 1000); } mapBoxSelectPositionMap.map.load = true; }); }, 200); if (props.isCanClick) { map.on('click', e => { let drewPoint = turf.featureCollection([turf.point([e.lngLat.lng, e.lngLat.lat])]); allData.pointGeometry = e.lngLat.lng + ',' + e.lngLat.lat; getAddressByLngLat(...NewFiberMap.CoordTransform.wgs84togcj02(e.lngLat.lng, e.lngLat.lat)).then(res => { allData.inputText = res.formatted_address; bus.emit('getDrawPoint', [allData.pointGeometry, res.formatted_address]); drewPoint.features[0].properties.name = res.formatted_address; addPointToMap(drewPoint); }); }); } }; //添加河流标注 const addWaterLabel = () => { !!!map.getSource('kaifengWaterLabel1') && map.addSource('kaifengWaterLabel1', { type: 'geojson', data: kaifengWaterLabel1 }); !!!map.getLayer('kaifengWaterLabel1') && map.addLayer({ id: 'kaifengWaterLabel1', type: 'symbol', source: 'kaifengWaterLabel1', layout: { 'text-field': ['get', 'name'], 'text-font': ['KlokanTech Noto Sans Regular'], 'text-transform': 'uppercase', }, paint: { 'text-halo-color': 'rgba(0,0,0,1)', 'text-color': 'rgba(0,167,210,1)', 'icon-opacity': 1, 'text-halo-width': 1, }, }); !!!map.getSource('kaifengWaterLabel2') && map.addSource('kaifengWaterLabel2', { type: 'geojson', data: kaifengWater }); !!!map.getLayer('kaifengWaterLabel2') && map.addLayer({ id: 'kaifengWaterLabel2', type: 'symbol', source: 'kaifengWaterLabel2', layout: { 'symbol-placement': 'line', 'text-field': ['get', 'name'], 'text-font': ['KlokanTech Noto Sans Regular'], 'text-letter-spacing': 0.1, 'text-rotation-alignment': 'map', 'text-size': { base: 1.4, stops: [ [10, 16], [20, 22], ], }, 'text-transform': 'uppercase', }, paint: { 'text-halo-color': 'rgba(0,0,0,1)', 'text-color': 'rgba(0,167,210,1)', 'icon-opacity': 1, 'text-halo-width': 1, }, }); }; //根据经纬度获取地名 const getAddressByLngLat = async (lng, lat) => { let data = await request({ url: `/amap/v3/geocode/regeo`, method: 'GET', params: { location: `${lng},${lat}`, key: '5f806b4c107901cd999af4c4931a8882', radius: 1000, extensions: 'all', output: 'json', }, }); if (data.info === 'OK') return data.regeocode; }; //输入框获取地址 const inputGetAddress = async () => { if (allData.inputText === '') { allData.addressListIsShow = false; } let data = await request({ url: `/amap/v3/geocode/geo`, method: 'GET', params: { address: allData.inputText, city: 'kaifeng', key: '5f806b4c107901cd999af4c4931a8882', radius: 1000, output: 'json', }, }); if (data.info === 'OK') { allData.addressListIsShow = true; allData.addressList = data.geocodes; } }; //搜索地址点击 const clickAddress = value => { if (!!value.location) { let lonlat = value.location.split(',').map(Number); let lonlat_84 = NewFiberMap.CoordTransform.gcj02towgs84(lonlat[0], lonlat[1]); let drewPoint = turf.featureCollection([turf.point(lonlat_84)]); allData.pointGeometry = lonlat_84[0] + ',' + lonlat_84[1]; bus.emit('getDrawPoint', [allData.pointGeometry, value.formatted_address]); drewPoint.features[0].properties.name = value.formatted_address; addPointToMap(drewPoint); map.easeTo({ center: lonlat_84, zoom: 15, }); allData.inputText = value.formatted_address; allData.addressListIsShow = false; } }; //渲染点位 const addPointToMap = geojson => { if (!map.getLayer('drewPoint')) { map.loadImage(WaterAnalysis_icon, function (error, image) { if (error) throw error; map.addImage('drewPoint_icon', image); map.addSource('drewPoint', { type: 'geojson', data: geojson, }); map.addLayer({ id: 'drewPoint', type: 'symbol', source: 'drewPoint', layout: { 'text-field': ['get', 'name'], 'text-font': ['KlokanTech Noto Sans Regular'], 'text-offset': [0, -3], 'icon-image': 'drewPoint_icon', // 你的自定义图标名称 'icon-size': 0.2, // 图标大小 'icon-anchor': 'center', // 图标锚点位置 }, paint: { 'text-color': 'rgba(18, 150, 219,1)', 'text-halo-color': 'rgba(213, 242, 247,1)', 'text-halo-width': 2, }, }); }); } else { map.getSource('drewPoint').setData(geojson); } }; onMounted(() => { initeMap(); nextTick(() => { allData.inputShow = props.isNeedInput; }); console.log(props.previousPoint, props.previousPointName); }); onBeforeUnmount(() => { mapBoxSelectPositionMap.destroy(); mapBoxSelectPositionMap = null; }); return { ...toRefs(allData), initeMap, inputGetAddress, clickAddress, }; }, }; </script> <style lang="scss"> .mapDrawTool { width: 100%; height: 100%; position: absolute; left: 0px; top: 0px; z-index: 10; background: lavender; #mapboxDrawContainer { width: 100%; height: 100%; position: absolute; } .l7-control-mouse-location { background: none; } .l7-control-mouse-location { color: #ffffff; } #nf-address-search-input { position: absolute; top: 20px; display: flex; justify-content: flex-start; align-items: center; z-index: 100; background: rgba(255, 255, 255, 1); margin-left: 20px; } .addressOption { position: absolute; top: 53px; z-index: 100; background: rgba(255, 255, 255, 1); margin-left: 20px; height: 200px; width: 300px; background: rgba(0, 69, 101, 1); .addressOptionItem { font-size: 14px; font-family: PingFang SC; color: rgba(255, 255, 255, 1); margin-left: 10px; margin-top: 5px; cursor: pointer; &:hover { background: #08596a; } } } } </style>