角度Google地图会获取地图边界内的所有位置

时间:2018-09-24 13:05:21

标签: angular typescript google-maps angular-google-maps

我正在Angular 6项目中使用此框架:

这是我与Angular合作的第一个项目,因此我仍在弄清楚它的工作方式。 我目前的专案状态如下: 我可以加载以特定位置为中心的地图。它还会加载标记并在缩小时将它们聚类。在侧面菜单中,列出了所有标记项,并显示了有关位置的一些信息。我还实现了一些用户交互:将鼠标悬停在侧面菜单中的标记或列表项上会突出显示列表/地图中的相应项。单击标记或列表项时,也会在侧面菜单中显示一些详细信息。到目前为止一切顺利。

现在,我要提取位于地图当前范围内的所有标记,以缩短侧面菜单中的列表。 在组件模板中,我按以下方式使用地图(我提取了使用地图的部分):

[...]

<!-- Map Section -->
<div class="main-data-container content-box">
  <div class="split-view-container" #parentData>
    <app-spinner *ngIf="!allItems"></app-spinner>
    <agm-map [style.height.px]="parentData.offsetHeight"
             [latitude]="mapCenter.lat"
             [longitude]="mapCenter.lon"
             [zoom]="mapZoom"
             #agmMap>
      <agm-marker-cluster [styles]="[companyStyle]">
        <agm-marker
          *ngFor="let companyLocation of companyLocations"
          (markerClick)="clickedMarker(companyLocation)"
          (mouseOver)="hoverOverMarker(companyLocation)"
          (mouseOut)="hoverOutMarker(companyLocation)"
          [latitude]="companyLocation.latitude"
          [longitude]="companyLocation.longitude"
          [iconUrl]="{url: setIcon(companyLocation), scaledSize: {width: 55, height: 82.5}}">
        </agm-marker>
      </agm-marker-cluster>
    </agm-map>
  </div>

  [...]

companyLocations:打字稿文档中的数组,其中包含有关公司多个地点的信息。

#agmMap:通过此操作,我将html元素绑定到打字稿文件中的对象。

现在到我正在苦苦挣扎的打字稿部分:

[...]

@ViewChild('agmMap') agmMap: any;

companyLocations: Array<CompanyLocation>;

filteredCompanyLocations: Array<CompanyLocation>;

[...]

checkMarkersInBounds() {

    // Initialize Filtered Arrays as empty Arrays
    this.filteredCompanyLocations = [];

    // Run through all CompanyLocations
    for(let company of this.companyLocations){

      //write coordinates from companyLocation into LatLng Object 
      let loc: LatLngLiteral = {lat: company.latitude, lng: company.longitude};

      //Check if the Location is in Bounds of the Map
      if (this.agmMap.getBounds().contains(loc)){

        //If it's in Bounds add it to the filtered Array
        this.filteredCompanyLocations.push(company);

      }
    }
  }

[...]

我在.getBounds()上遇到错误:

  

TypeError:this.agmMap.getBounds不是函数。

当尝试用this.agmMap.getBounds().contains(loc)切换this.agmMap._mapsWrapper.getBounds().contains(loc)时,它抛出:

  

TypeError:this.agmMap._mapsWrapper.getBounds(...)。包含的不是函数。

我已经在这里和其他地方尝试了几种解决方案,用于不同但相似的Intent,并使其适应我的应用程序:

我希望有人得到一些提示,甚至是解决方案。从那以后我一直在为此苦苦挣扎。也许我只是盲目地解决了这个问题,而我却忽略了一些必不可少的内容...

2 个答案:

答案 0 :(得分:1)

如果未过滤列表很长,则可能需要添加一个反跳计时器。

  private debounceTimer = null;

  public checkMarkersInBounds(bounds: any): void {
    // debounce timer prevents processing of marker filters until map stops moving for 200ms
    if (this.debounceTimer !== null) {
      clearTimeout(this.debounceTimer);
      this.debounceTimer = null;
    }
    this.debounceTimer = setTimeout(() => {
      this.companyFilter = [];
      for (const companyof this.companyLocations) {
        if (bounds.contains({ lat: company.lat, lng: company.long })) {

          //Put the item in an Array which can be shown in the List

        }
      }

    }, 200);
  }

答案 1 :(得分:0)

我找到了解决此问题的方法。 在模板中,将事件输出添加到地图的(boundsChange)输出中。这会返回地图的边界,并且在边界发生变化时(显然)也会触发该事件:

[...]
<agm-map
        [style.height.px]="parentData.offsetHeight"
        [latitude]="mapCenter.lat"
        [longitude]="mapCenter.lon"
        [zoom]="mapZoom"
        (boundsChange)="checkMarkersInBounds($event)">
[...]

在TS文件中,我实现了checkMarkersInBounds(bounds)方法,如下所示:

checkMarkersInBounds(bounds) {

    this.filteredItems = [];

    for(let company of this.companyLocations){

      let companyPosition = {lat: company.latitude, lng: company.longitude};

      if (bounds.contains(companyPosition)){

        //Put the item in an Array which can be shown in the List

      }
    }
  }