| | |
| | | <!-- 地图 --> |
| | | <template> |
| | | <!-- 地图容器 --> |
| | | <view id="map" class="map" style="width: 100%; height: 80vh"></view> |
| | | <view class="page-container theme-dark"> |
| | | <view id="map" class="map" :prop="setSelectMapLayerKey" :location="location" :change:prop="leaflet.initLayer" |
| | | :change:location="leaflet.setView"></view> |
| | | |
| | | <view class="layer-btn" @click="show = true"> |
| | | <up-icon customPrefix="xyicon" name="tuceng" size="24" color="#000"></up-icon> |
| | | </view> |
| | | |
| | | <view class="location-btn" @click="setMapLocation"> |
| | | <up-icon customPrefix="xyicon" name="dingwei" size="24" color="#000"></up-icon> |
| | | </view> |
| | | |
| | | <u-input placeholder="搜索" border="surround" v-model="value" @change="change" color="#fff"> |
| | | <template #prefix> |
| | | <view class="search-left-box"> |
| | | <u-icon color="#fff" name="arrow-left"></u-icon> 地址 |
| | | </view> |
| | | </template> |
| | | |
| | | <template #suffix> |
| | | <view class="search-right-box"> |
| | | <u-icon color="#fff" name="scan"></u-icon> |
| | | </view> |
| | | </template> |
| | | </u-input> |
| | | |
| | | <up-popup v-model:show="show"> |
| | | <view class="popup-container"> |
| | | <view class="header"> |
| | | <view class="title">图层</view> |
| | | <view class="close" @click="show = false"> |
| | | <u-icon color="#000" name="close"></u-icon> |
| | | </view> |
| | | </view> |
| | | <view class="content"> |
| | | <view class="layer-box" :class="{on: setSelectMapLayerKey === item.key}" v-for="(item, ind) in layers" |
| | | :key="ind" @click="setMapLayer(item)"> |
| | | <view class="image"> |
| | | <up-image :src="item.src" width="100%" height="100%"></up-image> |
| | | </view> |
| | | <view class="label">{{item.name}}</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </up-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | onShow(() => { |
| | | // #ifdef APP-PLUS |
| | | import { |
| | | useMapStore |
| | | } from "@/store/index.js" |
| | | |
| | | // plus.screen.lockOrientation("landscape-primary"); |
| | | // #endif |
| | | }); |
| | | const mapStore = useMapStore() |
| | | |
| | | onHide(() => { |
| | | // #ifdef APP-PLUS |
| | | // plus.screen.lockOrientation("portrait-primary"); |
| | | // #endif |
| | | }); |
| | | const layers = [{ |
| | | src: "/static/images/sl.png", |
| | | name: '标准地图', |
| | | key: 1, |
| | | }, |
| | | { |
| | | src: "/static/images/yx.png", |
| | | name: '卫星地图', |
| | | key: 2, |
| | | } |
| | | ] |
| | | |
| | | const show = ref(false) |
| | | |
| | | const value = ref('') |
| | | |
| | | const change = () => { |
| | | |
| | | } |
| | | |
| | | const setSelectMapLayerKey = computed(() => mapStore.getSelectMapLayerKey) |
| | | const setMapLayer = (item) => { |
| | | mapStore.setSelectMapLayerKey(item.key) |
| | | } |
| | | |
| | | const location = ref('') |
| | | const setMapLocation = () => { |
| | | // 获取定位信息 |
| | | uni.getLocation({ |
| | | type: 'wgs84', // 返回的经纬度是 WGS84 坐标系(适合地图定位) |
| | | isHighAccuracy: true, |
| | | success: function(res) { |
| | | location.value = res |
| | | }, |
| | | fail: function(err) { |
| | | console.log('定位失败:', err); |
| | | } |
| | | }); |
| | | |
| | | } |
| | | |
| | | |
| | | onShow(() => { |
| | | // #ifdef APP-PLUS |
| | | |
| | | // plus.screen.lockOrientation("landscape-primary"); |
| | | // #endif |
| | | }); |
| | | |
| | | onHide(() => { |
| | | // #ifdef APP-PLUS |
| | | // plus.screen.lockOrientation("portrait-primary"); |
| | | // #endif |
| | | }); |
| | | </script> |
| | | |
| | | <script module="leaflet" lang="renderjs"> |
| | | import L from 'leaflet' |
| | | import { |
| | | onBeforeUnmount, |
| | | onMounted |
| | | } from 'vue'; |
| | | import L from 'leaflet' |
| | | |
| | | export default { |
| | | mounted() { |
| | | var basemapLayer0 = L.tileLayer( |
| | | 'http://t1.tianditu.com/vec_c/wmts?layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer1 = L.tileLayer( |
| | | 'http://t1.tianditu.com/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer2 = L.tileLayer( |
| | | 'http://t1.tianditu.com/img_c/wmts?layer=img&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer3 = L.tileLayer( |
| | | 'http://t1.tianditu.com/cia_c/wmts?layer=cia&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemap0 = L.layerGroup([basemapLayer0, basemapLayer1]); |
| | | var basemap1 = L.layerGroup([basemapLayer2, basemapLayer3]); |
| | | var basemapLayer0 = L.tileLayer( |
| | | 'http://t1.tianditu.com/vec_c/wmts?layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer1 = L.tileLayer( |
| | | 'http://t1.tianditu.com/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer2 = L.tileLayer( |
| | | 'http://t1.tianditu.com/img_c/wmts?layer=img&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemapLayer3 = L.tileLayer( |
| | | 'http://t1.tianditu.com/cia_c/wmts?layer=cia&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=e110584a27d506da2740edca951683f4', { |
| | | maxZoom: 18, |
| | | minZoom: 1, |
| | | tileSize: 256, |
| | | zoomOffset: 1 |
| | | }); |
| | | var basemap0 = L.layerGroup([basemapLayer0, basemapLayer1]); |
| | | var basemap1 = L.layerGroup([basemapLayer2, basemapLayer3]); |
| | | |
| | | let map = L.map('map', { |
| | | preferCanvas: true, |
| | | crs: L.CRS.EPSG4326, |
| | | layers: [basemap1], |
| | | zoomControl: false, |
| | | attributionControl: false, |
| | | doubleClickZoom: false, |
| | | editable: true //绘制控件 |
| | | }).setView([25.992338, 114.823254], 13); |
| | | let map = null |
| | | |
| | | const layers = [{ |
| | | src: "/static/images/sl.png", |
| | | name: '标准地图', |
| | | key: 1, |
| | | map: basemap0 |
| | | }, |
| | | { |
| | | src: "/static/images/yx.png", |
| | | name: '卫星地图', |
| | | key: 2, |
| | | map: basemap1 |
| | | } |
| | | ] |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | setSelectMapLayerKey: 1 |
| | | } |
| | | }, |
| | | |
| | | computed: { |
| | | |
| | | }, |
| | | |
| | | mounted() { |
| | | this.initMap() |
| | | }, |
| | | |
| | | methods: { |
| | | initMap() { |
| | | if (map) return |
| | | |
| | | map = L.map('map', { |
| | | preferCanvas: true, |
| | | crs: L.CRS.EPSG4326, |
| | | zoomControl: false, |
| | | attributionControl: false, |
| | | doubleClickZoom: false, |
| | | editable: true //绘制控件 |
| | | }).setView([25.992338, 114.823254], 13); |
| | | }, |
| | | |
| | | initLayer(value) { |
| | | |
| | | this.initMap() |
| | | |
| | | this.$nextTick(() => { |
| | | map.removeLayer(layers.find(i => i.key === this.setSelectMapLayerKey).map); |
| | | |
| | | map.addLayer(layers.find(i => i.key === value).map); |
| | | |
| | | this.setSelectMapLayerKey = value |
| | | }) |
| | | }, |
| | | |
| | | setView(res) { |
| | | if (!res) return |
| | | |
| | | this.initMap() |
| | | |
| | | this.$nextTick(() => { |
| | | map.setView([res.latitude, res.longitude], 16, { |
| | | animate: false // 使用动画过渡 |
| | | }); |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | /* Leaflet 默认容器要有高度 */ |
| | | .map { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | <style lang="scss" scoped> |
| | | .page-container { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | |
| | | .u-input { |
| | | position: absolute; |
| | | left: 16rpx; |
| | | bottom: 16rpx; |
| | | width: calc(100% - 32rpx); |
| | | height: 64rpx; |
| | | z-index: 999; |
| | | box-sizing: border-box; |
| | | background: rgba(0, 0, 0, .4); |
| | | |
| | | .search-left-box { |
| | | display: flex; |
| | | align-items: center; |
| | | color: $u-main-color; |
| | | } |
| | | |
| | | .search-right-box { |
| | | color: $u-main-color; |
| | | } |
| | | } |
| | | |
| | | .location-btn, |
| | | .layer-btn { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | position: absolute; |
| | | right: 16rpx; |
| | | width: 64rpx; |
| | | height: 64rpx; |
| | | background: #fff; |
| | | z-index: 999; |
| | | border-radius: 8rpx; |
| | | } |
| | | |
| | | .layer-btn { |
| | | bottom: 176rpx; |
| | | } |
| | | |
| | | .location-btn { |
| | | bottom: 96rpx; |
| | | } |
| | | } |
| | | |
| | | /* Leaflet 默认容器要有高度 */ |
| | | .map { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .popup-container { |
| | | padding: 20rpx; |
| | | background: #D3D3D3; |
| | | border-radius: 32rpx 32rpx 0 0; |
| | | |
| | | .header { |
| | | padding: 0 20rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | height: 56rpx; |
| | | } |
| | | |
| | | .content { |
| | | padding: 20rpx; |
| | | display: flex; |
| | | background: #fff; |
| | | border-radius: 32rpx; |
| | | |
| | | .layer-box { |
| | | margin-left: 16rpx; |
| | | width: calc(100% / 3); |
| | | |
| | | &:first-child { |
| | | margin-left: 0; |
| | | } |
| | | |
| | | &.on { |
| | | .image { |
| | | border: 1px solid #0055ff; |
| | | } |
| | | |
| | | .label { |
| | | color: #0055ff; |
| | | } |
| | | } |
| | | |
| | | .image { |
| | | width: 100%; |
| | | height: 96rpx; |
| | | border-radius: 16rpx; |
| | | overflow: hidden; |
| | | box-sizing: border-box; |
| | | border: 1px solid transparent; |
| | | } |
| | | |
| | | .label { |
| | | line-height: 48rpx; |
| | | text-align: center; |
| | | font-size: 16rpx; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |