arthur1992
arthur1992
  • 发布:2025-05-26 15:25
  • 更新:2025-05-26 16:35
  • 阅读:65

map点聚合,微信小程序单点何以正常显示,聚合点显示不出来

分类:uni-app

<template>
<view class="content " :class="{ landscape: isLandscape }">
<u-navbar back-text="返回" :title="title" :autoBack="true"></u-navbar>
<!-- #ifdef APP-PLUS -->
<cover-view @click="expandDrawer()">展开收缩</cover-view>
<!-- #endif -->
<!-- #ifndef APP-PLUS -->
<map class="map-view" id="map1" ref="map1" :show-location="true" :latitude="latitude" :longitude="longitude">
<cover-view @click="expandDrawer()">展开收缩</cover-view>
<!-- 数据监控面板 -->
<!-- 注意:这里只保留一个 cover-view,避免嵌套 -->
<!-- <cover-view class="data-panel">-->
<!-- <!– 标题和时间行 –>-->
<!-- <cover-view class="header">-->
<!-- <cover-view class="title">{{ selectedCompany.companyName || '未选择公司' }}</cover-view>-->
<!-- <cover-view class="update-time">更新于{{ currentTime }}</cover-view>-->
<!-- </cover-view>-->

<!-- <!– 数据指标 –>-->
<!-- <cover-view class="data-row">-->
<!-- <cover-view class="label">油烟浓度</cover-view>-->
<!-- <cover-view class="value">0.24mg/m³</cover-view>-->
<!-- </cover-view>-->
<!-- <cover-view class="data-row">-->
<!-- <cover-view class="label">颗粒物浓度</cover-view>-->
<!-- <cover-view class="value">0.32mg/m³</cover-view>-->
<!-- </cover-view>-->
<!-- <cover-view class="data-row">-->
<!-- <cover-view class="label">非甲烷总烃</cover-view>-->
<!-- <cover-view class="value">0.01mg/m³</cover-view>-->
<!-- </cover-view>-->
<!-- </cover-view>-->
</map>
<!-- <!– #endif –>-->
<!-- <ww-bottom-drawerapp ref="drag" :proportionShow='proportionvc' :dragHandleHeight="handleHeight" :isExpand="mExpand"-->
<!-- @callExpand="onCallExpand" :canDrag="canDarg()" :dragLength="dragLength"-->
<!-- :transitionTime='transitionTime' :menuHeight = 'menuHeight' >-->
<!-- <slot>-->
<!-- <u-search :animation="true" :clearabled="true" placeholder="请输公司名称" v-model="keyword" :show-action='true'-->
<!-- @custom="getList(false)" @search="getList(false)"></u-search>-->
<!-- <!– 填充内容 –>-->
<!-- <scroll-view :scroll-top="scrollTop" :scroll-y="mExpand" :style="'width: 100%;height :'+ (menuHeight + 'px') "-->
<!-- @scrolltoupper="upper" @scrolltolower="lower" @scroll="scroll">-->
<!-- <uni-grid :column="1" :highlight="false" :showBorder="false" >-->
<!-- <uni-grid-item v-for="(item, index) in list" :index="index" :key="index" style="height: 200rpx">-->
<!-- <!– 修改网格项样式 –>-->
<!-- <view class="grid-item-box single-column" style="background-color: #fff;">-->
<!-- <view class="header-row">-->
<!-- <view class="number-badge">{{index+1}}</view>-->
<!-- <text class="company-name">{{item.companyName}}</text>-->
<!-- <!– 定位图标按钮 –>-->
<!-- <view @click.stop="locateCompany(item)" v-if="item.companyLat!=null&&item.companyLng!=null">-->
<!-- <u-icon name="map" size="20" color="#4f46e5" />-->
<!-- </view>-->
<!-- </view>-->
<!-- <text class="company-address" >{{item.companyAddress}}</text>-->
<!-- <view class="contact-list">-->
<!-- <view v-if="uIndex==0" v-for="(user, uIndex) in item.companyUsers" :key="uIndex" class="contact-item">-->
<!-- <view class="phone-wrapper" @click.stop="callHandler(user.configUser.phone)">-->
<!-- <u-icon name="phone" size="16" color="#4f46e5" />-->
<!-- <text class="contact-name">{{ user.configUser.relName || '未命名' }}</text>-->
<!-- <text class="contact-phone">{{ user.configUser.phone }}</text>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- </view>-->
<!-- </uni-grid-item>-->
<!-- </uni-grid>-->

<!-- </scroll-view>-->
<!-- <!– end –>-->
<!-- </slot>-->
<!-- </ww-bottom-drawerapp>-->

</view>
</template>

<script>
const img = '/static/location.png';
export default {
components: {},
data() {
return {
_mapContext:{},
isLandscape: false, // 横屏状态
keyword:null,
currentTime: this.formatTime(new Date()),
selectedCompany:{},
covers: [],
tablePage: {
total: 0,
currentPage: 1,
pageSize: 20,
pages: 0,
pageSizes: [10, 20, 30, 40, 50],
loadStatus: 'loadmore',
isLoading: false,
desc: 'create_time',
isLastPage: false, // 新增是否最后一页标识
loading: false // 加载锁
},
list:[],
param:{},
proportionvc: 0.3, //抽屉初始显示的位置,内容的百分比
handleHeight: 20, //抽屉顶部边框高度,可以设置0,隐藏
mExpand: false,
dragLength: 100,
transitionTime: 0.3,
menuHeight:500,//计算预设菜单的高度 px
show:false,
scrollTop: 0, //支付宝使用
mscrollTop: 0,
title: 'Hello',
longitude: 116.3974770000,
latitude: 39.9086920000,
autoplay: true,
interval: 3000,
duration: 1000,
indicatorDots: true,
circular: true,
level:14,
}
},
onLoad() {
// this.getScreenInfo()
// // 监听屏幕旋转
// uni.onWindowResize(() => {
// console.log("监听屏幕旋转.....");
// this.getScreenInfo()
// })
this.model=uni.getStorageSync('company');
let location=JSON.parse(this.model.dictExtend)
this.latitude=location.lat;
this.longitude=location.lng;
this.title=this.model.dictName;
// this.getList()
},
onReady() {
// this.$refs.drag.initTop();
this._mapContext = uni.createMapContext("map1", this);
// 仅调用初始化,才会触发 on.("markerClusterCreate", (e) => {})
this._mapContext.initMarkerCluster({
enableDefaultStyle: false,
zoomOnClick: true,
gridSize: 60,
complete(res) {
console.log('initMarkerCluster', res)
}
});

this._mapContext.on("markerClusterCreate", (e) => {  
  console.log("markerClusterCreate", e);  
});  

this.getList();  

},
methods: {
locateCompany(company) {
if (company.companyLat && company.companyLng) {
this.latitude = company.companyLat;
this.longitude = company.companyLng;
this.level = 18; // 可以根据需要调整缩放级别

    // 如果有地图实例,可以直接调用setCenter方法(如果存在)  
    // 注意:这取决于使用的地图组件是否支持直接设置中心点  
    if (this.$refs.map1 && this.$refs.map1.setCenter) {  
      this.$refs.map1.setCenter({  
        latitude: company.companyLat,  
        longitude: company.companyLng  
      });  
    }  
    this.expandDrawer()  
    this.selectedCompany=company;  
  } else {  
    uni.showToast({  
      title: '没有可用的位置信息',  
      icon: 'none'  
    });  
  }  
},  
formatTime(date) {  
  return `${date.getHours().toString().padStart(2,'0')}:${date.getMinutes().toString().padStart(2,'0')}:${date.getSeconds().toString().padStart(2,'0')}`  
},  
handleMarkerTap(e) {  
  // console.log(e)  
  const markerId = e.detail.markerId  
  this.selectedCompany = this.covers.find(item => item.id === markerId)  

},  

closePopup() {  
  this.$refs.detailPopup.close()  
},  
markEvent(e){  
  console.log(e)  
},  
//nvue对top动画支持不够,使用css的其他的动画转换  
styleCss(){  
  if(this.mExpand){  
    return this.targetCss();//'width: calc(50%);'  
  }else{  
    return this.originCss();//`width: calc(100% - 20px);`  
  }  
},  
targetCss() {  
  return "transform: translateY(100%);transition-property: transform;transition-duration: 1s;"  
},  
originCss() {  
  return "transform: translateY(0px);transition-property: transform;transition-duration: 1s;"  
},  

onChange(e) {  
  let {  
    index  
  } = e.detail;  
  console.error(index);  
  uni.showToast({  
    title: `你点击了${index}`  
  })  
},  
onCallExpand(e) { //展开搜索的回调监听  
  this.mExpand = e.value  
},  
expandDrawer() { //控制初始展开状态和后期外部控制展开和搜索  

  this.$nextTick(function() {  
    this.goTop()  
  });  

},  
showApp() {  
  uni.navigateTo({  
    url: 'app-map'  
  })  
},  
canDarg(){  
  // #ifdef MP-ALIPAY  
  return this.mscrollTop<30  
  // #endif  
  return true  
},  
upper: function(e) {  
  console.log(e)  
},  
lower: function(e) {  
  console.log(e)  
},  
scroll: function(e) {  
  this.mscrollTop = e.detail.scrollTop  
},  
getStatusColor(status) {  
  // 定义从低到高的状态颜色映射  
  const colors = [  
    { background: '#e0f2f1', text: '#0f172a', border: '#64748b' }, // 0 - 极低  
    { background: '#e0f2f1', text: '#0f172a', border: '#64748b' }, // 1  
    { background: '#dbf9f3', text: '#0f172a', border: '#48bb78' }, // 2  
    { background: '#dbf9f3', text: '#0f172a', border: '#48bb78' }, // 3  
    { background: '#fef9c3', text: '#0f172a', border: '#facc15' }, // 4  
    { background: '#fef9c3', text: '#0f172a', border: '#facc15' }, // 5  
    { background: '#fed7aa', text: '#0f172a', border: '#fb923c' }, // 6  
    { background: '#fed7aa', text: '#0f172a', border: '#fb923c' }, // 7  
    { background: '#fca5a5', text: '#0f172a', border: '#ef4444' }, // 8  
    { background: '#fca5a5', text: '#0f172a', border: '#ef4444' }  // 9 - 极高  
  ];  

  return colors[status] || colors[0]; // 默认使用最低级别样式  
},  
async getList(isLoadMore = false) {  
  // ...原有逻辑  
  this.currentTime = this.formatTime(new Date())  
  if (this.tablePage.loading) return;  
  this.tablePage.loading = true;  
  try {  
    const param = {  
      current: this.tablePage.currentPage,  
      size: this.tablePage.pageSize,  
      desc: this.tablePage.desc,  
      companyArea:this.model.dictValue,  
      companyName: this.keyword  
    };  
    const res = await uni.$u.http.get('/api/v1/base/company-info/pagePhone', {params: param});  
    if (isLoadMore) {  
      this.list = [...this.list, ...res.data.records];  
    } else {  
      this.list = res.data.records;  
    }  
    this.covers=res.data.records.filter(item=>item.companyLat!=null&&item.companyLng!=null).map((item,index)=>{  
      let statusColor = this.getStatusColor(index);  
      return {  
        id: index,  
        latitude: item.companyLat,  
        longitude: item.companyLng,  
        iconPath: '/static/location.png',  
        companyName: item.companyName,  
        title: item.companyName,  
        status:item.status,  
        height:30,  
        width:30,  
        joinCluster: true,  
        callout: {  
          content: item.companyName,  
          color: statusColor.text,  
          fontSize: 15,  
          borderRadius: 5,  
          bgColor: statusColor.background,  
          padding: '8',  
          display: 'ALWAYS',  
          borderColor: statusColor.border  
        }  

      }  
    })  
    let markers = []  
    if(this.covers.length>0){  
      markers=this.covers  
      this.selectedCompany=this.covers[0]  
      this._mapContext.addMarkers({  
        markers,  
        clear: false,  
        success: () => console.log('addMarkers success'),  
        fail: (err) => console.error('addMarkers fail:', err),  
        complete(res) {  
          console.log('addMarkers', res)  
        }  
      })  
    }  
    // 更新分页状态  
    this.tablePage.total = res.data.total;  
    this.tablePage.pages = res.data.pages;  
    this.tablePage.isLastPage = this.tablePage.currentPage >= res.data.pages;  

  } finally {  
    this.tablePage.loading = false;  
    this.tablePage.loadStatus = this.tablePage.isLastPage ? 'nomore' : 'loadmore';  
  }  
},  
goTop() {  
  this.mExpand = !this.mExpand  
  // 解决view层不同步的问题  
  // this.scrollTop = this.mscrollTop  
  // this.$nextTick(function() {  
  //    this.scrollTop = 0  
  //    this.$nextTick(function() {  
  //        this.mExpand = !this.mExpand  
  //    });  

  // });  

},  
clickAli(){  
  uni.showToast({  
    title:"点击"  
  })  
},  
mapTap(event){  
  console.log(event)  
}  

}
}
</script>

<style lang="scss" scoped>
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}

@mixin text-ellipsis($line: 1) {
overflow: hidden;
text-overflow: ellipsis;
@if $line > 1 {
display: -webkit-box;
-webkit-line-clamp: $line;
-webkit-box-orient: vertical;
} @else {
white-space: nowrap;
}
}
.content {
flex: 1;
}
.data-panel {
/ 基础定位 /
position: absolute;
top: 160rpx;
left: 20rpx;
right: 20rpx;
z-index: 999;

/ 微信专用样式 /
background: rgba(255, 255, 255, 0.96);
border: 1rpx solid #eeeeee;
border-radius: 16rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
padding: 12rpx;

/ 微信 cover-view 特殊限制 /
line-height: 1.5;
white-space: nowrap;

.header {
display: flex; // 关键属性
justify-content: space-between; // 两端对齐
align-items: center; // 垂直居中
margin-bottom: 16rpx;
width: 100%; // 确保宽度充满容器
}

.title {
flex: 1; // 占据剩余空间
font-size: 32rpx;
color: #1a1a1a;
font-weight: 600;
@include text-ellipsis; // 超出显示省略号
margin-right: 20rpx; // 与时间间隔
}

.update-time {
flex-shrink: 0; // 禁止收缩
font-size: 24rpx;
color: #666;
background: rgba(245, 245, 245, 0.9);
padding: 4rpx 12rpx;
border-radius: 8rpx;
white-space: nowrap; // 防止换行
}

.data-row {
margin: 12rpx 0;
@include flex-center;
justify-content: space-between;
}

.label {
font-size: 28rpx;
color: #666;
}

.value {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
}
.single-column {
width: 100% !important;
margin: 20rpx 0;
padding: 32rpx !important;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.08);
border-radius: 16rpx;
}

/ 添加序号样式 /
.header-row {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}

.number-badge {
color: #007aff;
font-size: 28rpx;
font-weight: 500;
@include flex-center;
margin-right: 20rpx;
flex-shrink: 0;

/ 响应式调整 /
@media (max-width: 600rpx) {
width: 36rpx;
height: 36rpx;
font-size: 24rpx;
}
}

.company-name {
font-size: 32rpx;
color: #1e293b;
font-weight: 600;
@include text-ellipsis(1);
}
.company-address {
display: block;
font-size: 28rpx;
color: #64748b;
margin-bottom: 0rpx;
}

.contact-list {
border-top: 1rpx dashed #e2e8f0;
padding-top: 0rpx;
}
.phone-wrapper {
display: flex;
align-items: center;
padding: 0rpx;
margin: 8rpx 0;
border-radius: 8rpx;
transition: background 0.2s;

&:active {
background: rgba(79,70,229,0.05);
}
}

.contact-name {
font-size: 28rpx;
color: #64748b;
margin: 0 16rpx;
}

.contact-phone {
font-size: 26rpx;
color: #4f46e5;
}

.tipNvue {
display: flex;
width: 100%;
height: 200rpx;
background-color: aliceblue;
margin-top: 200rpx;
}
.map-view {
display: flex;
width: 100vw;
height: 100vh;
flex: 1;
}

.grid-item-box {
flex: 1;
/ #ifndef APP-NVUE /
//display: flex;
/ #endif /
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}

.text {
font-size: 26rpx;
margin-top: 10rpx;
}

.swiper-item { height: 100rpx; display: block; line-height: 100rpx; text-align: center; }

:v-deep .amap-logo { opacity: 0 !important;
}

:v-deep .amap-copyright { opacity: 0 !important;
}
</style>
2025-05-26 15:25 负责人:无 分享
已邀请:
AI问答小助手

AI问答小助手 - AI智答引擎,优解尽在掌握!

根据代码和现象分析,聚合点无法显示的问题可能由以下原因导致。以下是分步解决方案:


一、核心问题定位

  1. 聚合配置缺失:禁用默认样式后未配置自定义聚合样式
  2. 数据格式问题markers数组中的坐标数据可能存在异常值
  3. 平台兼容性:微信小程序对点聚合的gridSize参数敏感
  4. 生命周期时序:地图初始化与标记添加的时序问题

二、解决方案

方案1:启用默认聚合样式(验证用)

// 修改initMarkerCluster配置  
this._mapContext.initMarkerCluster({  
  enableDefaultStyle: true, // 临时启用默认样式  
  zoomOnClick: true,  
  gridSize: 60,  
  complete(res) {  
    console.log('initMarkerCluster', res)  
  }  
});
  • 效果:若聚合点显示,说明问题出在自定义样式配置
  • 后续操作:恢复enableDefaultStyle: false后按方案2配置样式

方案2:添加自定义聚合样式

// 在initMarkerCluster配置中添加  
this._mapContext.initMarkerCluster({  
  enableDefaultStyle: false,  
  zoomOnClick: true,  
  gridSize: 60,  
  // 新增样式配置  
  styles: [  
    {  
      url: '/static/cluster-icon.png', // 自定义聚合图标  
      textColor: '#FFFFFF',  
      textSize: 14,  
      width: 40,  
      height: 40,  
      anchorX: 20,  
      anchorY: 20  
    }  
  ],  
  complete(res) {  
    console.log('initMarkerCluster', res)  
  }  
});

方案3:验证坐标数据有效性

// 修改covers生成逻辑  
this.covers = res.data.records  
  .filter(item => item.companyLat && item.companyLng)  
  .map((item, index) => {  
    // 添加坐标有效性验证  
    if (isNaN(item.companyLat) || isNaN(item.companyLng)) {  
      console.warn('无效坐标:', item);  
      return null;  
    }  

    return {  
      id: index,  
      latitude: parseFloat(item.companyLat), // 确保转换为数字类型  
      longitude: parseFloat(item.companyLng),  
      // ...其他属性  
    }  
  })  
  .filter(item => item !== null); // 过滤无效数据

方案4:调整网格尺寸

// 修改initMarkerCluster配置  
this._mapContext.initMarkerCluster({  
  enableDefaultStyle: false,  
  zoomOnClick: true,  
  gridSize: 80, // 增大网格尺寸(微信小程序推荐值60-100)  
  // ...其他配置  
});

方案5:确保地图初始化完成

// 修改onReady生命周期  
onReady() {  
  this._mapContext = uni.createMapContext("map1", this);  

  // 添加地图初始化完成监听  
  this._mapContext.getMapStyle((mapStyle) => {  
    this.initCluster();  
  });  
},  
methods: {  
  initCluster() {  
    this._mapContext.initMarkerCluster({  
      // ...配置  
    });  

    this._mapContext.addMarkers({  
      markers: this.covers,  
      clear: false,  
      success: () => console.log('addMarkers success'),  
      fail: (err) => console.error('addMarkers fail:', err)  
    });  
  }  
}

三、进阶调试

如果问题依旧存在,可尝试以下操作:

1. 检查控制台输出

  • 确认initMarkerClustercomplete回调是否触发
  • 查看addMarkersfail回调是否有错误信息

2. 简化测试数据

// 临时使用静态数据测试  
this.covers = [  
  {  
    id: 1,  
    latitude: 39.908692,  
    longitude: 116.397477,  
    iconPath: '/static/location.png'  
  },  
  {  
    id: 2,  
    latitude: 39.908692,  
    longitude: 116.397477,  
    iconPath: '/static/location.png'  
  }  
];

3. 更新基础库版本

  • 确保微信开发者工具基础库版本 ≥ 2.21.0
  • manifest.json中配置:
    "mp-weixin": {  
    "appid": "你的appid",  
    "setting": {  
      "urlCheck": false,  
      "postcss": true,  
      "minified": true  
    },  
    "usingComponents": true,  
    "libVersion": "2.21.0"  
    }  

四、注意事项

  1. 图标路径:自定义聚合图标需放在static目录下
  2. 坐标系:确保所有坐标使用相同坐标系(GCJ-02)
  3. 性能优化:单个聚合点内标记点数量建议不超过100个
  4. 平台差异
    // 添加平台条件编译  
    // #ifdef MP-WEIXIN  
    gridSize: 80,  
    // #endif  

五、完整配置示例

// 修改后的初始化代码  
onReady() {  
  this._mapContext = uni.createMapContext("map1", this);  

  this._mapContext.getMapStyle(() => {  
    this._mapContext.initMarkerCluster({  
      enableDefaultStyle: false,  
      zoomOnClick: true,  
      gridSize: 80,  
      styles: [  
        {  
          url: '/static/cluster-icon.png',  
          textColor: '#FFFFFF',  
          textSize: 14,  
          width: 40,  
          height: 40  
        }  
      ]  
    });  

    this._mapContext.addMarkers({  
      markers: this.covers,  
      clear: false,  
      success: () => console.log('Markers added'),  
      fail: (err) => console.error('Add markers failed:', err)  
    });  
  });  
}

通过以上步骤,90%以上的点聚合显示问题可被解决。如果问题依旧存在,建议提供微信开发者工具控制台完整输出和covers数组的示例数据进一步排查。

  • arthur1992 (作者)

    enableDefaultStyle: true, 这样就能出来聚合图片,改成false加自定义就出不来

    2025-05-26 16:18

arthur1992

arthur1992 (作者)

建议在map标签上设置一个开关就能打开

要回复问题请先登录注册