当前位置: 首页 > 知识库问答 >
问题:

GoogleMapReact标记聚类问题

丁韬
2023-03-14

嗨,我正在制作一个反应网站,理想情况下应该包括标记的聚类。

我使用了两种不同的技术,都能有效地显示在地图上,还有一种甚至是集群,但我希望我能将这些技术结合起来。

原因是这两种技术略有不同,使用有效集群的技术不会让我映射出组件,而是必须返回一个google标记。

这是我使用的第一种技术。

import React, { Component, useState } from "react";
import GoogleMapReact from "google-map-react";

import TravelAlert from "./TravelAlerts/TravelAlerts";
import IntelAlert from "./IntelAlerts/IntelAlerts";

import "./GoogleMap.css";

//class component
export class GoogleMap extends Component {
  constructor(props) {
    super(props);
  }
  componentDidMount() {}
  static defaultProps = {
    center: {
      lat: 59.955413,
      lng: 30.337844,
    },
    zoom: 11,
  };

  render() {
    return (
      <>
        <GoogleMapReact
          style={{ height: "100vh", width: "100%", zIndex: -1 }}
          bootstrapURLKeys={{
            key: "AIzaSyAfpKoor5CLGg-HbDwdKHq9mGij2JA-YzE",
          }}
          defaultCenter={this.props.center}
          defaultZoom={this.props.zoom}
        >
//Simply .mapping a bunch of props (if done this way component just needs a lat and a lng prop for each component )
          {this.props.travelAlerts.map((ta) => (
            <TravelAlert
              lat={ta.latitude}
              lng={ta.longitude}
              title={ta.title}
              description={ta.description}
              notes={ta.notes}
              riskId={ta.riskId}
              startDate={ta.startDate}
              endDate={ta.endDate}
            />
          ))}

          {this.props.intelAlerts.map((ta) => (
            <IntelAlert
              lat={ta.latitude}
              lng={ta.longitude}
              title={ta.title}
              description={ta.description}
              notes={ta.notes}
              riskId={ta.riskId}
              startDate={ta.startDate}
              endDate={ta.endDate}
            />
          ))}
        </GoogleMapReact>
      </>
    );
  }
}

export default GoogleMap;

我真的很喜欢这种技术,因为它只是允许您将任何组件映射到屏幕的lat和lng。然而,使用这种技术,我无法得到这些标记的聚类工作。

这是第二种技术,但这不允许我绘制任何自定义标记,这意味着我必须在地图加载之前绘制地图的标记。这不是首选,因为我无法映射自己的自定义标记。

import React, { Component } from "react";
import GoogleMapReact from "google-map-react";
import intelAlert from "../../../components/Map/MapContainer/GoogleMap/IntelAlerts/IntelAlerts";
// import MarkerClusterer from "@google/markerclusterer";

export default class GoogleMapContainer extends Component {
  componentDidMount() {
    const script = document.createElement("script");
    script.src =
      "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js";
    script.async = true;
    document.body.appendChild(script);
  }

  setGoogleMapRef(map, maps) {
    this.googleMapRef = map;
    this.googleRef = maps;
    
    let markers =
      this.props.intelAlerts &&
      this.props.intelAlerts.map((location) => {
        var loc = { lat: location.latitude, lng: location.longitude };
        return new this.googleRef.Marker({ position: loc });
      });
    let markerCluster = new MarkerClusterer(map, markers, {
      imagePath:
        "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m",
      gridSize: 10,
      minimumClusterSize: 2,
    });
  }

  static defaultProps = {
    center: {
      lat: 59.95,
      lng: 30.33,
    },
    zoom: 11,
  };

  render() {
    if (this.props.intelAlerts.length) {
      return (
        <GoogleMapReact
          style={{ height: "100vh", width: "100%", zIndex: -1 }}
          bootstrapURLKeys={{ key: "AIzaSyAfpKoor5CLGg-HbDwdKHq9mGij2JA-YzE" }}
          yesIWantToUseGoogleMapApiInternals
          onGoogleApiLoaded={({ map, maps }) => this.setGoogleMapRef(map, maps)}
          defaultCenter={{ lat: -31.56391, lng: 147.154312 }}
          defaultZoom={15}
          options={{ streetViewControl: true }}
        />
      );
    } else {
      return <></>;
    }
  }
}

是否有一种方法仍然能够映射出我自己的自定义标记并包括标记聚类。

任何帮助或指导都意味着分配,因为关于这个问题的文档很少。

我正在使用谷歌地图反应npm包。

编辑我已经做了类似于此的角。在Angular中,您可以简单地做到这一点。

<div ng-if="showTravellers" >
      <agm-marker-cluster    [minimumClusterSize]= "minClusterSize"> 

          <agm-marker *ngFor="let m of intelligenceAlerts;let i = index;" [visible]="showIntelligence"  [latitude]="m.latitude" [longitude]="m.longitude" [iconUrl]= 'getTheIcon(m.riskId)'  >
            <agm-snazzy-info-window [maxWidth]="600" maxHeight="200px" [closeWhenOthersOpen]="true" backgroundColor="getTheColor(m.colour);">
                <ng-template>
                    <mat-form-field appearance="standard">
                        <mat-card> <h3><b>{{m.colour}}</b> </h3></mat-card>
                  <mat-card> <h3><b>{{m.title}}</b> </h3></mat-card>
                  <mat-card> <p>{{m.notes}} </p></mat-card>
                   <button>Description</button> <button>Start Date</button><button>End Date</button><button>Notes</button>
                 </mat-form-field>
                </ng-template>
               </agm-snazzy-info-window> 
         </agm-marker>
    </agm-marker-cluster>
    </div>

reactjs中是否有一个等价物?

共有1个答案

尚嘉庆
2023-03-14

您只需动态加载Maps JS API,而无需依赖第三方库/包。这样,你就可以简单地按照他们的官方文件进行操作。对于本例,我按照以下两个步骤对地图标记进行聚类,并添加自定义标记:

  • https://developers.google.com/maps/documentation/javascript/marker-clustering
  • https://developers.google.com/maps/documentation/javascript/custom-markers

以下是我制作的Stackblitz示例,供您参考:https://stackblitz.com/edit/react-map-cluster-64766101

一个pp.js

import React, { Component } from "react";
import { render } from "react-dom";
import Map from "./components/map";
import "./style.css";

class App extends Component {
  render() {
    return (
      <Map
        id="myMap"
        html" target="_blank">options={{
          center: { lat: -28.024, lng: 140.887 },
          zoom: 3
        }}
      />
    );
  }
}

export default App;

map.js

import React, { Component } from "react";
import { render } from "react-dom";

const locations = [
  { lat: -31.56391, lng: 147.154312 },
  { lat: -33.718234, lng: 150.363181 },
  { lat: -33.727111, lng: 150.371124 },
  { lat: -33.848588, lng: 151.209834 },
  { lat: -33.851702, lng: 151.216968 },
  { lat: -34.671264, lng: 150.863657 },
  { lat: -35.304724, lng: 148.662905 },
  { lat: -36.817685, lng: 175.699196 },
  { lat: -36.828611, lng: 175.790222 },
  { lat: -37.75, lng: 145.116667 },
  { lat: -37.759859, lng: 145.128708 },
  { lat: -37.765015, lng: 145.133858 },
  { lat: -37.770104, lng: 145.143299 },
  { lat: -37.7737, lng: 145.145187 },
  { lat: -37.774785, lng: 145.137978 },
  { lat: -37.819616, lng: 144.968119 },
  { lat: -38.330766, lng: 144.695692 },
  { lat: -39.927193, lng: 175.053218 },
  { lat: -41.330162, lng: 174.865694 },
  { lat: -42.734358, lng: 147.439506 },
  { lat: -42.734358, lng: 147.501315 },
  { lat: -42.735258, lng: 147.438 },
  { lat: -43.999792, lng: 170.463352 }
];

class Map extends Component {
  constructor(props) {
    super(props);
    this.state = {
      map: ""
    };
  }

  onScriptLoad() {
    this.state.map = new window.google.maps.Map(
      document.getElementById(this.props.id),
      this.props.options
    );
    this.addMarker();
  }

  componentDidMount() {
    if (!window.google) {
      var s = document.createElement("script");
      s.type = "text/javascript";
      s.src = `https://maps.google.com/maps/api/js?key=YOUR_API_KEY`;
      var x = document.getElementsByTagName("script")[0];
      x.parentNode.insertBefore(s, x);

      var s2 = document.createElement("script");
      s2.type = "text/javascript";
      s2.src = `https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js`;
      var x2 = document.getElementsByTagName("script")[0];
      x2.parentNode.insertBefore(s2, x2);

      s.addEventListener("load", e => {
        this.onScriptLoad();
      });
    } else {
      this.onScriptLoad();
    }
  }
  // Add some markers to the map.
  addMarker() {
    const markers = locations.map((location, i) => {
      return new google.maps.Marker({
        position: location,
        icon:
          "https://developers.google.com/maps/documentation/javascript/examples/full/images/info-i_maps.png",
        map: this.state.map
      });
    });
    // Add a marker clusterer to manage the markers.
    new MarkerClusterer(this.state.map, markers, {
      imagePath:
        "https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m"
    });
  }

  render() {
    return <div className="map" id={this.props.id} />;
  }
}

export default Map;

注意:用实际的API密钥替换API密钥占位符

 类似资料:
  • 根据科罗拉多州罗斯国家森林区域树木类型的观测数据covtype.csv,实现树木类型识别任务 聚类之后,发现可视化的图不是自己想要的,我想要的是每个颜色都有自己的区域,但是运行结果不如意 到底要聚类还是分类啊

  • 文件范围的元数据 reST 有字段列表”field lists” 的概念; 字段序列如下: :fieldname: Field content 文件开端的字段列表会被文档工具解释为文档源信息,通常记录了作者,出版日期等元数据. 在Sphinx中, 在所有标记前面的字段列表将作为文档元数据放在Sphinx 环境中,不显示在输出文档中; 在文档标题后的字段列表仍然是文档源信息的一部分显示在输出文档中.

  • 对于层次聚类法,我们不需要预先指定分类的数量,这个算方法会将每条数据都当作是一个分类,每次迭代的时候合并距离最近的两个分类,直到剩下一个分类为止。 因此聚类的结果是:顶层有一个大分类,这个分类下有两个子分类,每个子分类下又有两个子分类,依此类推,层次聚类也因此得命。 在合并的时候我们会计算两个分类之间的距离,可以采用不同的方法。如下图中的A、B、C三个分类,我们应该将哪两个分类合并起来呢? 单链聚

  • 我正在编写一个利用时间的Web应用程序,所以我决定使用Joda库,更具体地说是Joda Time-JSP tags Version 1.1.1(可以在这里找到->www.Joda.org/joda-time-jsptags/) 我的代码是正确的,就站点解释的 <%PageContext.SetAttribute(“now”,new org.joda.time.dateTime());%> foll

  •   聚类是一种无监督学习问题,它的目标就是基于相似度将相似的子集聚合在一起。聚类经常用于探索性研究或者作为分层有监督流程的一部分。 spark.mllib包中支持下面的模型。 k-means算法 GMM(高斯混合模型) PIC(快速迭代聚类) LDA(隐式狄利克雷分布) 二分k-means算法 流式k-means算法

  • 内容: 层次聚类法 编写层次聚类算法 k-means聚类算法 安然事件 前几章我们学习了如何构建分类系统,使用的是已经标记好类别的数据集进行训练: 训练完成后我们就可以用来预测了:这个人看起来像是篮球运动员,那个人可能是练体操的;这个人三年内不会患有糖尿病。 可以看到,分类器在训练阶段就已经知道各个类别的名称了。那如果我们不知道呢?如何构建一个能够自动对数据进行分组的系统?比如有1000人,每人有