Google 地图 Api V3 - 隐藏重叠的自定义叠加层
Google Maps Api V3 - Hide overlapping custom overlays
我在地图上为不同城市放置了许多自定义叠加层,并正在尝试 hide/collapse 重叠的叠加层。哪里有space,我就show/expand人口最多的
我想实现与 google flights (explore section) 完全相同的行为。
我试过的
我尝试了以下方法。我循环浏览所有自定义叠加层,检查是否存在重叠,然后隐藏是否存在人口较多的叠加层。问题是太多被隐藏了,看下面的例子:
- A市(3000人口)
- B市(2000人口)
- C市(1000人口)
- A 和 B 重叠
- B 和 C 重叠
- A 和 C 不重叠
A 和 C 应该都可见,但 C 隐藏了,因为 B 和 C 重叠并且 B 的人口较多。
请注意我使用的是Angular,但这是一个一般的js问题。
hideOverlays(){
this.overlays.forEach(mainElement => {
let hide = false;
this.overlays.forEach(compareElement => {
if(this.checkOverlap(mainElement.nativeElement, compareElement.nativeElement)){
if(mainElement.nativeElement.dataset.population < compareElement.nativeElement.dataset.population){
hide = true
}
}
})
if(hide){
mainElement.nativeElement.style.display = "none";
}else{
mainElement.nativeElement.style.display = "flex";
}
});
}
checkOverlap(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();
const overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
return overlap;
}
有谁知道如何正确地做到这一点?如果我前进的方向效率不高,我也愿意采用完全不同的方法。
我找到了解决办法。不确定这是否是执行此操作的最佳方法,但它确实有效。
我首先使用覆盖元素、人口和 hidden=false
创建一个对象数组。然后我循环遍历并将每个元素与所有其他元素进行比较。如果元素重叠 main.hidden == true
和 main.population >= compare.population
,我将比较元素设置为 hidden == true
。这样隐藏的元素不会导致其他元素隐藏。
请注意,我的原始数组已按人口排序,此顺序对于它以正确的方式工作很重要。
最后,我再次循环遍历元素,并根据元素是否隐藏向元素添加 类 和样式。
filterLocations(){
let overlayArray = [];
this.overlays.forEach(element => {
const overlayObj = {element: element.nativeElement, population: Number(element.nativeElement.dataset.population), hidden: false};
overlayArray.push(overlayObj);
})
overlayArray.forEach( (main, i) => {
overlayArray.forEach( (compare, j) => {
if(i != j && !main.hidden && main.population >= compare.population && this.checkOverlap(compare.element, main.element)){
overlayArray[j].hidden = true;
}
})
})
overlayArray.forEach( (obj, i) => {
if(!obj.hidden){
obj.element.classList.add("expanded");
obj.element.style.pointerEvents = 'auto';
obj.element.style.zIndex = overlayArray.length + overlayArray.length - i;
}else{
obj.element.classList.remove("expanded");
obj.element.style.pointerEvents = 'none';
obj.element.style.zIndex = overlayArray.length - i;
}
})
}
checkOverlap(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();
return !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
}
我在地图上为不同城市放置了许多自定义叠加层,并正在尝试 hide/collapse 重叠的叠加层。哪里有space,我就show/expand人口最多的
我想实现与 google flights (explore section) 完全相同的行为。
我试过的
我尝试了以下方法。我循环浏览所有自定义叠加层,检查是否存在重叠,然后隐藏是否存在人口较多的叠加层。问题是太多被隐藏了,看下面的例子:
- A市(3000人口)
- B市(2000人口)
- C市(1000人口)
- A 和 B 重叠
- B 和 C 重叠
- A 和 C 不重叠
A 和 C 应该都可见,但 C 隐藏了,因为 B 和 C 重叠并且 B 的人口较多。
请注意我使用的是Angular,但这是一个一般的js问题。
hideOverlays(){
this.overlays.forEach(mainElement => {
let hide = false;
this.overlays.forEach(compareElement => {
if(this.checkOverlap(mainElement.nativeElement, compareElement.nativeElement)){
if(mainElement.nativeElement.dataset.population < compareElement.nativeElement.dataset.population){
hide = true
}
}
})
if(hide){
mainElement.nativeElement.style.display = "none";
}else{
mainElement.nativeElement.style.display = "flex";
}
});
}
checkOverlap(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();
const overlap = !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
return overlap;
}
有谁知道如何正确地做到这一点?如果我前进的方向效率不高,我也愿意采用完全不同的方法。
我找到了解决办法。不确定这是否是执行此操作的最佳方法,但它确实有效。
我首先使用覆盖元素、人口和 hidden=false
创建一个对象数组。然后我循环遍历并将每个元素与所有其他元素进行比较。如果元素重叠 main.hidden == true
和 main.population >= compare.population
,我将比较元素设置为 hidden == true
。这样隐藏的元素不会导致其他元素隐藏。
请注意,我的原始数组已按人口排序,此顺序对于它以正确的方式工作很重要。
最后,我再次循环遍历元素,并根据元素是否隐藏向元素添加 类 和样式。
filterLocations(){
let overlayArray = [];
this.overlays.forEach(element => {
const overlayObj = {element: element.nativeElement, population: Number(element.nativeElement.dataset.population), hidden: false};
overlayArray.push(overlayObj);
})
overlayArray.forEach( (main, i) => {
overlayArray.forEach( (compare, j) => {
if(i != j && !main.hidden && main.population >= compare.population && this.checkOverlap(compare.element, main.element)){
overlayArray[j].hidden = true;
}
})
})
overlayArray.forEach( (obj, i) => {
if(!obj.hidden){
obj.element.classList.add("expanded");
obj.element.style.pointerEvents = 'auto';
obj.element.style.zIndex = overlayArray.length + overlayArray.length - i;
}else{
obj.element.classList.remove("expanded");
obj.element.style.pointerEvents = 'none';
obj.element.style.zIndex = overlayArray.length - i;
}
})
}
checkOverlap(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();
return !(rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom)
}