我在 Angular 6 项目中使用此框架:
- https://github.com/SebastianM/angular-google-maps
- https://angular-maps.com/
这是我与 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._mapsWrapper.getBounds().contains(loc)
切换this.agmMap.getBounds().contains(loc)
时,它会抛出:
TypeError: this.agmMap._mapsWrapper.getBounds(...(.包含不是函数。
我已经在这里和其他地方尝试了几种解决方案,用于不同但相似的意图,并将其适应我的应用程序:
- https://github.com/allenhwkim/angularjs-google-maps/issues/762
- https://github.com/SebastianM/angular-google-maps/issues/696
- 角度 5 谷歌地图:仅显示半径为 # 公里的标记
- 如何使用谷歌地图 v3 检查标记是否在边界内
我希望有人有一些提示甚至解决方案。几天来我一直在为此苦苦挣扎。也许我只是对这个问题的解决视而不见,我忽略了一些重要的东西......
我找到了解决这个问题的方法。 在模板中,将事件输出添加到地图的(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
}
}
}
如果未过滤的列表很长,则可能需要添加去抖动计时器。
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);
}