| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- <template>
- <div class="light-map" :class="{ 'full': full }">
- <map
- id="prevMap"
- map-id="prevMap"
- class="light-map-map"
- :enable-poi="false"
- :scale="12"
- :longitude="AppCofig.defaultLonLat[0]"
- :latitude="AppCofig.defaultLonLat[1]"
- @markertap="onMarkerTap"
-
- />
- <SimpleDropDownPicker
- class="light-map-region-picker"
- :modelValue="selectedRegion"
- @update:modelValue="onSelectedRegion"
- :columns="regionLoader.content.value"
- />
- <Button
- :innerStyle="{
- position: 'absolute',
- bottom: '20rpx',
- right: '20rpx',
- zIndex: 100,
- backgroundColor: '#ffffff',
- }"
- icon="navigation"
- @click="getCurrentLonlat"
- >定位</Button>
- </div>
- </template>
- <script setup lang="ts">
- import { getCurrentInstance, onMounted, ref, watch } from 'vue';
- import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
- import { geoJsonToWechatMapShapes } from '@/common/utils/geoJsonToWechatMap';
- import LightVillageApi, { VillageListItem } from '@/api/light/LightVillageApi';
- import MapApi from '@/api/map/MapApi';
- import AppCofig from '@/common/config/AppCofig';
- import type { MapMarker, MapPolygon, MapPolyline } from '@/types/Map';
- import SimpleDropDownPicker from '@/common/components/SimpleDropDownPicker.vue';
- import Button from '@/components/basic/Button.vue';
- import { navTo } from '@/components/utils/PageAction';
- import CommonContent from '@/api/CommonContent';
- import { waitTimeOut } from '@imengyu/imengyu-utils';
- const instance = getCurrentInstance();
- const mapCtx = uni.createMapContext('prevMap', instance);
- const selectedRegion = ref<number>();
- const nextNeedAutoFocus = ref(false);
- const currentAddress = ref<string>('');
- const currentLonlat = ref<{ longitude: number, latitude: number }>({
- longitude: AppCofig.defaultLonLat[0],
- latitude: AppCofig.defaultLonLat[1],
- });
- const villageData = new Map<number, VillageListItem>();
- const emit = defineEmits(['getedCurrentLonlat','update:isLightMode']);
- const props = defineProps<{
- startLonlat?: { longitude: number, latitude: number } | undefined;
- isLightMode?: boolean;
- full?: boolean;
- }>();
- const regionLoader = useSimpleDataLoader(async () => {
- return (await CommonContent.getCategoryChildList(5)).map(p => ({
- id: p.id,
- name: p.title,
- }));
- }, false);
- const mapLoader = useSimpleDataLoader<MapMarker[]>(async () => {
- mapCtx.removeMarkers({
- markerIds: Array.from(villageData.keys()),
- })
- villageData.clear();
- await waitTimeOut(200);
- const res = (await LightVillageApi.getVillageList(undefined, selectedRegion.value, undefined, 1, 100)).map((p, i) => {
- villageData.set(p.id, p);
- const maker : MapMarker = {
- id: p.id ?? i,
- title: p.villageName,
- longitude: Number(p.longitude),
- latitude: Number(p.latitude),
- width: 30,
- height: 30,
- iconPath: '',
- joinCluster: true,
- callout: {
- display: 'ALWAYS',
- content: p.villageName,
- color: '#000000',
- fontSize: 12,
- padding: 5,
- bgColor: '#ffffff',
- borderRadius: 5,
- },
- }
- if (p.isLight) {
- if (p.lightValue >= 1) {
- maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light3.png`;
- } else if (p.lightValue >= 0.5) {
- maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light2.png`;
- } else if (p.lightValue >= 0.25) {
- maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light1.png`;
- } else {
- maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/Light1.png`;
- }
- const size = Math.floor(35 +(p.lightValue) * 10);
- maker.width = size;
- maker.height = size;
-
- } else {
- maker.width = 35;
- maker.height = 35;
- maker.iconPath = `https://mncdn.wenlvti.net/app_static/xiangyuan/images/map/LightUnLight.png`;
- }
- return maker as MapMarker;
- });
- mapCtx.addMarkers({
- clear: true,
- markers: res,
- })
- if (nextNeedAutoFocus.value) {
- setTimeout(() => {
- mapCtx.includePoints({
- points: res.map(p => {
- if (!p.longitude || !p.latitude) {
- p.longitude = AppCofig.defaultLonLat[0];
- p.latitude = AppCofig.defaultLonLat[1];
- }
- return {
- latitude: p.latitude,
- longitude: p.longitude,
- }
- }),
- padding: [20, 20, 20, 20],
- });
- }, 200);
- }
- return res;
- }, false, false, true);
- function onMarkerTap(e: any) {
- if (props.isLightMode) {
- emit('update:isLightMode', false);
- navTo('/pages/home/light/submit', {
- villageId: e.markerId,
- });
- return;
- }
- const village = villageData.get(e.markerId);
- if (village) {
- uni.setStorageSync('VillageTemp', JSON.stringify(village));
- setTimeout(() => {
- navTo('/pages/home/light/details', { id: village.id });
- }, 200);
- }
- }
- function onSelectedRegion(regionId: number) {
- selectedRegion.value = regionId;
- nextNeedAutoFocus.value = true;
- mapLoader.loadData(undefined, true);
- }
- function setCurrentRegion(regionName: string) {
- selectedRegion.value = regionLoader.content.value?.find(p => p.name == regionName)?.id || undefined;
- mapLoader.loadData(undefined, true);
- }
- function getCurrentLonlat() {
- uni.getLocation({
- type: 'wgs84',
- success: async (res) => {
- currentLonlat.value = {
- longitude: res.longitude,
- latitude: res.latitude,
- };
- const address = await MapApi.regeo(res.latitude, res.longitude);
- currentAddress.value = address.district;
- setCurrentRegion(address.district);
- emit('getedCurrentLonlat', currentLonlat.value);
- mapCtx.moveToLocation({
- latitude: currentLonlat.value.latitude,
- longitude: currentLonlat.value.longitude,
- });
- },
- });
- }
- onMounted(async () => {
- mapCtx.initMarkerCluster({
- enableDefaultStyle: false,
- zoomOnClick: true,
- gridSize: 40,
- });
- mapCtx.on('markerClusterCreate', (e: { clusters: any[] }) => {
- const customClusters = e.clusters.map((cluster) => {
- const { center, clusterId, markerIds } = cluster;
- return {
- ...center,
- width: 0,
- height: 0,
- clusterId,
- label: {
- content: markerIds.length.toString(), // 聚合点的数量
- fontSize: 16,
- color: '#fff',
- width: 30,
- height: 30,
- bgColor: '#8bb346', // 背景颜色
- borderRadius: 25,
- textAlign: 'center',
- anchorX: -10,
- anchorY: -35,
- },
- };
- });
- mapCtx.addMarkers({
- markers: customClusters,
- clear: false,
- });
- });
- if (props.startLonlat) {
- currentLonlat.value = props.startLonlat;
- mapCtx.moveToLocation({
- latitude: currentLonlat.value.latitude,
- longitude: currentLonlat.value.longitude,
- });
- }
- await regionLoader.loadData(undefined, true);
- if (!props.startLonlat) {
- const res = await LightVillageApi.getIpAddress();
- currentLonlat.value = {
- longitude: Number(res.point.x),
- latitude: Number(res.point.y),
- };
- await waitTimeOut(100);
- currentAddress.value = res.address_detail.district;
- setCurrentRegion(res.address_detail.district);
- emit('getedCurrentLonlat', currentLonlat.value);
- mapCtx.moveToLocation({
- latitude: currentLonlat.value.latitude,
- longitude: currentLonlat.value.longitude,
- });
- } else {
- const address = await MapApi.regeo(currentLonlat.value.latitude, currentLonlat.value.longitude);
- currentAddress.value = address.district;
- setCurrentRegion(address.district);
- }
- });
- </script>
- <style lang="scss">
- .light-map {
- position: relative;
- width: 100%;
- height: 600rpx;
- border-radius: 30rpx;
- overflow: hidden;
- &.full {
- height: 100vh;
- border-radius: 0;
- .light-map-map {
- height: 100vh;
- }
- }
- .light-map-map {
- width: 100%;
- height: 600rpx;
- }
- .light-map-region-picker {
- position: absolute;
- bottom: 20rpx;
- left: 50%;
- transform: translateX(-50%);
- z-index: 100;
- }
- .light-map-address {
- position: absolute;
- bottom: 20rpx;
- right: 20rpx;
- z-index: 100;
- }
- }
- </style>
|