小程序之多个marker展示在可见区域

230 阅读2分钟

  背景:详情内容分为半屏和少半屏,地图可见区域同步变化。在地图总高度不变的前提下,将marker展示在可见区域。  

场景1:只有一个marker或者两个marker的经纬度相同:地图中心点同步移动到这个marker上。

  • 设置地图的缩放级别为16

  • 设置地图中心点偏移至地图可见区域中心

  • 将地图中心点移动到这个marker上

    // h1:折叠时地图可见区域的高度
    // h2:展开时地图可见区域的高度
    // h3:真实地图高度
    // mapExpand:地图折叠或展开状态
      const showMapHeight = mapExpand ? h2 : h1; // 可见区域地图高度
      const offsetY = 0.5 * showMapHeight / h3;
      this.setData({ mapScale: 16 }, () => {
        setTimeout(() => {
          const offset = [0.5, offsetY];
          map.setCenterOffset({
            offset,
            complete: () => {
              map.moveToLocation({ // 设置地图中心点
                longitude: markers[0].longitude,
                latitude: markers[0].latitude,
              });
            },
          });
        }, 400);
      });
    

    场景2:ios下,两个marker的经纬度不同

  • 设置中心点偏移

  • 获取折叠和展开状态下,marker距地图上下左右的padding

  • 通过includePoints将marker展示在可见区域

      // 折叠和展开的地图高度相差33vh,20为标点宽高,多加24作为视觉间距
      const mapPadding = {
        fold: [statusBarHeight + 44, 44, vh2px(33) + 24, 44], // 折叠时,重新设置下padding
        expand: [statusBarHeight + 44, 44, 24, 44],
       }
       const padding = mapExpand ? expandPadding : foldPadding;
       map.setCenterOffset({
          offset,
          complete: () => {
            map.includePoints({
              padding,
              points,
            });
          },
        });
    

    场景3:andriod下,两个marker的经纬度不同

    对于andriod手机,includePoints只能识别padding的第一个值!!!所以,需要新的方案将marker展示在地图可见区域

  • 定义两个地图:map1位页面展示的地图,map2为一个隐藏地图。map2的高度为不同状态下map1可见区域的高度。

  • 通过includePoints将marker展示在map2中

  • 获取map2的缩放级别,将此赋值给map1

  • 获取map2的地图区域信息,结合地图高度信息,计算出map1对应此区域的中心点

  • 将map1的中心点移动到此处

    hiddenMap.includePoints({
          padding,
          points,
          complete: () => {
            hiddenMap.getScale({
              success(res) {
                // Math.random() * 0.001的扰动用于保证scale变动生效: 保持map伸缩状态,手动调整地图缩放比例再重置scale
                const mapScale = res.scale + Math.random() * 1.0e-6;
                that.setData({ mapScale }, () => {
                  hiddenMap.getRegion({
                    success(regionRes) {
                      const p0 = regionRes.northeast || {};
                      const p1 = regionRes.southwest || {};
                      // 计算target
                      const hiddenMapHeight = mapExpand ? h2 : h1;
                      const targetYOffset = 0.5 * h3 - hiddenMapHeight;
                      const target = {
                        longitude: 0.5 * (p0.longitude + p1.longitude),
                        latitude: p1.latitude + (targetYOffset * (p1.latitude - p0.latitude)) / hiddenMapHeight,
                      };
                      map.moveToLocation({
                        ...target,
                      });
                    },
                  });
                });
              },
            });
          },
        });