Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

点击MarkerCluster聚合点获取的数组长度与实际不符 #340

Open
AkimotoAkira77 opened this issue Nov 24, 2023 · 2 comments
Open

Comments

@AkimotoAkira77
Copy link

AkimotoAkira77 commented Nov 24, 2023

// @ts-nocheck
import React, { useEffect, useState, useRef, useCallback } from "react";
import { getAllPoints } from "@/api";
import { Map, APILoader, Marker, Geolocation } from "@uiw/react-amap";
import myIcon from "@/assets/image/myIcon.png";

interface lnglat {
  longitude: number;
  latitude: number;
}

const MyPage: React.FC<any> = () => {
  const [point, setPoint] = useState<lnglat>({
    longitude: 121.49203,
    latitude: 31.24149,
  }); // 地图中心点
  const [points, setPoints] = useState<any[]>([]);

  const [map, setMap] = useState<any>(null);

  useEffect(() => {
    getPointsData();
  }, []);

  const getPointsData = async () => {
    try {
      const { code, msg, data } = await getAllPoints();
      if (code === 200) {
        setPoints(data);
      }
    } catch (e) {
      console.log("获取点位失败");
    }
  };

  const handleMarker = (markerData: any) => {};

  return (
    <div>
      <div>
        <APILoader
          akey="myKey"
          plugins={[
            "AMap.MarkerClusterer",
            "AMap.AutoComplete",
            "AMap.PlaceSearch",
          ]}
        >
          <Map
            zoom={19}
            zooms={[3, 19]}
            center={[point.longitude, point.latitude]}
            ref={(instance) => {
              if (instance && instance.map && !map) {
                setMap(instance.map);
              }
            }}
            onClick={(e) => {
              console.log(e);
            }}
          >
            <MarkerCluster points={points} handleMarker={handleMarker} />
          </Map>
        </APILoader>
      </div>
    </div>
  );
};

export default MyPage;

let cluster: any;

const MarkerCluster = (props: any) => {
  // eslint-disable-next-line react/prop-types
  const { AMap: AMap, map, container, points, handleMarker } = props;
  const gridSize = 60;

  useEffect(() => {
    if (!!points && points.length > 0) {
      addCluster();
    }
    return () => {
      if (cluster) {
        cluster.setMap(null);
      }
      cluster = null;
    };
  }, [points, cluster]);

  const _renderMarker = function (context: any) {
    // console.log("context", context?.data);
    // const content =
    //   '<div style="background-color: hsla(180, 100%, 50%, 0.3); height: 18px; width: 18px; border: 1px solid hsl(180, 100%, 40%); border-radius: 12px; box-shadow: hsl(180, 100%, 50%) 0px 0px 3px;"></div>';
    // context.marker.setContent(content);
    const offset = new AMap.Pixel(-11, -22);
    // const anchor = new AMap.Anchor(6,6)
    const icon = new AMap.Icon({
      imageSize: new AMap.Size(22, 22),
      image: myIcon,
    });
    context.marker.setIcon(icon);
    // context.marker.setAnchor([6,6])
    context.marker.setOffset(offset);
    // context.marker.on("click", e => {
    //   console.log("click", e, e.target.getExtData());
    // });
  };
  const sts = [
    {
      url: "https://webapi.amap.com/theme/v1.3/m1.png",
      size: new AMap.Size(53, 53),
      offset: new AMap.Pixel(-26, -26),
    },
    {
      url: "https://webapi.amap.com/theme/v1.3/m2.png",
      size: new AMap.Size(56, 56),
      offset: new AMap.Pixel(-28, -28),
    },
    {
      url: "https://webapi.amap.com/theme/v1.3/m3.png",
      size: new AMap.Size(66, 66),
      offset: new AMap.Pixel(-33, -33),
    },
    {
      url: "https://webapi.amap.com/theme/v1.3/m4.png",
      size: new AMap.Size(78, 78),
      offset: new AMap.Pixel(-39, -39),
    },
    {
      url: "https://webapi.amap.com/theme/v1.3/m5.png",
      size: new AMap.Size(90, 90),
      offset: new AMap.Pixel(-45, -45),
    },
  ];
  const addCluster = () => {
    if (!!cluster || points.length < 1) {
      cluster.setMap(null);
    } else if (points.length > 0) {
      cluster = new AMap.MarkerCluster(map, points, {
        styles: sts,
        gridSize: 60,
        minClusterSize: 10,
        // renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式
        renderMarker: _renderMarker,
      });
      cluster.on("click", (e: any) => {
        console.log("聚合data", e?.clusterData);
        if (e?.clusterData?.length === 1) {
          // 处理单点业务逻辑
          const markerData = e?.clusterData[0];
          handleMarker(markerData);
        } else {
          // 两个点以上
        }
      });
    }
  };
  return <div></div>;
};

6a0ddf7f96e4b678a90b2e35d032468

我这边使用官方的MarkerCluster插件,可以显示聚合类,然后就是有个需求就是点2-10的聚合点时展示一个弹框列表,我这边打印e?.clusterData,发现数组长度有时会比显示的聚合数量少,甚至五千多的聚合点点出来length只有二十几个,请问可能是啥问题

@jaywcjlove
Copy link
Member

@AkimotoAkira77 我看到你使用的是原生 api, 这极有可能是你的 key 限制,看一下官方文档,最快捷的方式是,提工单问客服

@edk24
Copy link

edk24 commented Apr 18, 2024

更新一下解决办法,我问题和楼主一样。提工单问了

  1. AMap.MarkerCluster 别用 AMap.MarkerClusterer
  2. 应该取 clusterData[n]['_amapMarker'].originData

给出我的代码;

let ambulancePoints: AmbulancePoint[] = [];
clusterData.forEach((item) => {
  ambulancePoints = ambulancePoints.concat(item['_amapMarker'].originData[0])
})

originData 是原始数据,这东西在文档上也没有写 实属有点坑啊

不知道为什么 originData 也是个二维数组,我看了都只有一个成员, 就取了 0

来个大佬解释一下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants