openlayers关于clusters介绍

效果展示

初始化地图

Javascript 复制代码
<template>
  <div id="map" class="map"></div>
</template>

<script>
import Map from "ol/Map.js";
import View from "ol/View.js";
import { centerPoint } from "@/utils/showPage.js";
import { gaodeMapLayer } from "@/utils/MapLayer.js";
import { clusters, clusterCircleStyle, clusterCircles } from "@/utils/cluster";
import { createEmpty, extend, getHeight, getWidth } from "ol/extent.js";
export default {
  name: "cluster",
  data() {
    return {
      map: null
    };
  },
  mounted() {
    const map = new Map({
      layers: [gaodeMapLayer, clusters, clusterCircles],
      target: "map",
      view: new View({
        center: centerPoint,
        zoom: 11,
        minZoom: 2,
        maxZoom: 30,
        projection: "EPSG:4326",
        rotation: 0,
      }),
    });
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 900px;
}
</style>

图层详解

  • 公共方法和样式

    Javascript 复制代码
     function gasPointType() {
       let customPoint = config.CUSTOM_POINT.val,
         GAS_POINT_TYPE = config.GAS_POINT_TYPE.children;
       GAS_POINT_TYPE.forEach((item) => {
         item.type = item.val.typeId.value;
       });
       return [
         ...GAS_POINT_TYPE,
         { type: customPoint.typeId.value, val: customPoint },
       ];
     }
     function getICon(properties) {
       let typeId = properties.typeId || "1",
         allPoint = gasPointType();
       return allPoint.find((i) => i.type == typeId).val;
     }
     function clusterMemberStyle(clusterMember) {
       let properties = clusterMember.getProperties();
       let item = getICon(properties);
       return new Style({
         geometry: clusterMember.getGeometry(),
         image: new Icon({
           rotation: 0,
           src: item.iconUrl.value,
           anchorXUnits: "fraction",
           imgSize: [item.width.value, item.height.value],
         }),
       });
     }
     function generatePointsCircle(count, clusterCenter, resolution) {
       const circumference =
         circleDistanceMultiplier * circleFootSeparation * (2 + count);
       let legLength = circumference / (Math.PI * 2); 
       const angleStep = (Math.PI * 2) / count;
       const res = [];
       let angle;
       legLength = Math.max(legLength, 35) * resolution;
       for (let i = 0; i < count; ++i) {
    
         angle = circleStartAngle + i * angleStep;
         res.push([
           clusterCenter[0] + legLength * Math.cos(angle),
           clusterCenter[1] + legLength * Math.sin(angle),
         ]);
       }
    
       return res;
     }
  • clusters图层

    Javascript 复制代码
      const vectorSource = new VectorSource({
        features: new GeoJSON().readFeatures({
          type: devList.type,
          features: _devList,
        }),
      });
    
      const clusterSource = new Cluster({
        distance: 35,
        source: vectorSource,
      });
      }
      function clusterStyle(feature) {
        const size = feature.get("features").length;
        if (size > 1) {
          return [
            new Style({
              image: outerCircle,
            }),
            new Style({
              image: innerCircle,
              text: new Text({
                text: size.toString(),
                fill: textFill,
                stroke: textStroke,
              }),
            }),
          ];
        }
        const originalFeature = feature.get("features")[0];
        return clusterMemberStyle(originalFeature);
      }
    
      const clusters = new VectorLayer({
        source: clusterSource,
        style: clusterStyle,
      });
  • clusterCircles图层

    Javascript 复制代码
       const clusterCircles = new VectorLayer({
         source: clusterSource,
         style: clusterCircleStyle,
       });
    
       function clusterCircleStyle(
         cluster,
         resolution,
         clickFeature,
         clickResolution
       ) {
         if (cluster !== clickFeature || resolution !== clickResolution) {
           return null;
         }
         const clusterMembers = cluster.get("features");
         const centerCoordinates = cluster.getGeometry().getCoordinates();
         return generatePointsCircle(
           clusterMembers.length,
           cluster.getGeometry().getCoordinates(),
           resolution
         ).reduce((styles, coordinates, i) => {
           const point = new Point(coordinates);
           const line = new LineString([centerCoordinates, coordinates]);
           styles.unshift(
             new Style({
               geometry: line,
               stroke: convexHullStroke,
             })
           );
           styles.push(
             clusterMemberStyle(
               new Feature({
                 ...clusterMembers[i].getProperties(),
                 geometry: point,
               })
             )
           );
           return styles;
         }, []);
       }

地图pointermove和click

Javascript 复制代码
  map.on("pointermove", (event) => {
      clusters.getFeatures(event.pixel).then((features) => {
        map.getTargetElement().style.cursor =
          features[0] && features[0].get("features").length > 1
            ? "pointer"
            : "";
      });
    });

    map.on("click", (event) => {
      clusters.getFeatures(event.pixel).then((features) => {
        if (features.length > 0) {
          const clusterMembers = features[0].get("features");
          if (clusterMembers.length > 1) {
            // Calculate the extent of the cluster members.
            const extent = createEmpty();
            clusterMembers.forEach((feature) =>
              extend(extent, feature.getGeometry().getExtent())
            );
            const view = map.getView();
            const resolution = map.getView().getResolution();
            if (
              view.getZoom() === view.getMaxZoom() ||
              (getWidth(extent) < resolution && getHeight(extent) < resolution)
            ) {
              // Show an expanded view of the cluster members.
              let clickFeature = features[0];
              let clickResolution = resolution;
              clusterCircles.setStyle((cluster, resolution) => {
                clusterCircleStyle(
                  cluster,
                  resolution,
                  clickFeature,
                  clickResolution
                );
              });
            } else {
              // Zoom to the extent of the cluster members.
              view.fit(extent, { duration: 500, padding: [50, 50, 50, 50] });
            }
          }
        }
      });
    });
相关推荐
outstanding木槿6 分钟前
浅拷贝 与 深拷贝
前端·javascript
SamHou06 分钟前
手把手 Flexbox——从零开始的奶奶级 Web 开发教程3
前端·css·web
粥里有勺糖1 小时前
视野修炼第123期 | 你在用Node几?
前端·javascript·github
水花花花花花1 小时前
蓝桥杯国赛前一晚知识点准备(十六届python)
前端·javascript·python
1977835462 小时前
Python 实现 web 请求与响应
前端
赫本的猫2 小时前
JavaScript对象:深入理解创建、构造与类型
前端·javascript
计算机学长2 小时前
中华传统文化网页纯前端期末大作业3页|HTML+CSS+JS|新手必备
前端·源码
Aniugel2 小时前
项目经验与分析
前端
赫本的猫2 小时前
JavaScript原型与原型链:深入浅出指南
前端·javascript
小华同学ai2 小时前
6.2k tar 热门项目,揭秘:一篇 Markdown 如何秒生成 PPT、书籍、文章
前端·后端·github