【问题标题】:Google Maps: How To Update Markers谷歌地图:如何更新标记
【发布时间】:2022-09-26 13:36:48
【问题描述】:

我有一个可观察的,它发出一个属性列表。基于属性纬度经度,我正在使用谷歌地图叠加层呈现自定义 HTML 标记。

第一次加载地图时,标记和集群正确渲染。从第二次开始,我试图删除以前的标记并放置新的标记。此时,旧标记不会被删除(我已经添加了一个删除方法)并且会添加新标记。此外,集群从第二次开始就没有显示。

问题:如何更新谷歌地图中的标记?

html-map-marker.ts

export const createHTMLMapMarker = ({
    OverlayView = google.maps.OverlayView,
    ...args
}) => {
    class HTMLMapMarker extends google.maps.OverlayView {
        private label!: string;
        private marker!: HTMLElement | null;
        private latlng!: google.maps.LatLng;

        constructor() {
            super();
            this.latlng = args[\'latlng\'];
            this.label = args[\'label\'];
            this.setMap(args[\'map\']);
        }

        public createDiv() {
            this.marker = document.createElement(\'div\') as HTMLElement;
            this.marker.classList.add(\'custom-marker-box\');

            if (this.label && this.marker !== null) {
                const markerInnerEl = document.createElement(\'div\');
                markerInnerEl.classList.add(\'custom-marker\');
                const markerInnerTextEl = document.createElement(\'span\');
                markerInnerTextEl.innerText = this.label;
                markerInnerEl.appendChild(markerInnerTextEl);
                this.marker.appendChild(markerInnerEl);
                this.marker.style.cssText = `position: absolute; cursor: pointer;`;

                /**
                 * !Stops click or tap on the element from bubbling up to the map.
                 * !Use this to prevent the map from triggering \"click\" events.
                 */
                google.maps.OverlayView.preventMapHitsFrom(this.marker);
            }

            google.maps.event.addDomListener(
                this.marker,
                \'click\',
                (event: MouseEvent) => {
                    const targetEl = event.target as HTMLElement;
                    const ClickedMarkerEl =
                        targetEl.tagName.toLocaleLowerCase() === \'span\'
                            ? targetEl.parentNode
                            : targetEl;

                    const markers =
                        document.querySelectorAll(\'.custom-marker-box\');

                    markers.forEach((markerParent) => {
                        const markerEl = markerParent
                            .children[0] as HTMLElement;

                        if (markerEl === ClickedMarkerEl) {
                            if (
                                !markerEl.classList.contains(
                                    \'custom-marker-active\'
                                )
                            ) {
                                markerEl.classList.add(\'custom-marker-active\');
                            }
                        } else {
                            markerEl.classList.remove(\'custom-marker-active\');
                        }
                    });
                    google.maps.event.trigger(this, \'click\');
                }
            );
        }

        public appendDivToOverlay() {
            const panes = this.getPanes() as google.maps.MapPanes;
            panes.floatPane.appendChild(this.marker as HTMLElement);
        }

        public positionDiv() {
            const point = this.getProjection().fromLatLngToDivPixel(
                this.latlng
            );
            if (point) {
                const markerWidth = (
                    this.marker as HTMLElement
                ).getBoundingClientRect().width;
                const marginAmount = (markerWidth / 2).toFixed();

                (this.marker as HTMLElement).style.left = `${point.x}px`;
                (this.marker as HTMLElement).style.top = `${point.y}px`;
                (
                    this.marker as HTMLElement
                ).style.marginLeft = `-${marginAmount}px`;
            }
        }

        public override draw() {
            if (!this.marker) {
                this.createDiv();
                this.appendDivToOverlay();
            }
            this.positionDiv();
        }

        public remove() {
            if (this.marker) {
                this.marker.parentNode?.removeChild(this.marker);
                this.marker = null;
            }
        }

        public getPosition() {
            return this.latlng;
        }

        public getDraggable() {
            return false;
        }
    }
    return new HTMLMapMarker();
};

google-map.component.ts

    private markers: any[] = [];
    private initialZoom!: boolean;
    private googleMap!: google.maps.Map;
    private properties: IProperty[] = [];
        
    ngOnInit(): void {
       this.initMap();
       this.getLocations();
    }
        
    initMap() {
            const mapEl = document.getElementById(\'map\') as HTMLElement;
            const mapOptions = {
                minZoom: 6,
                zoom: 10,
                disableDefaultUI: true
            };
            this.googleMap = new google.maps.Map(mapEl, mapOptions);
            this.initialZoom = true;
   }
        
   getLocations() {
            this.locationsSource$.subscribe({
                next: (properties: IProperty[]) => {
                    this.properties = properties;
                    this.resetMapMarkers();
                    this.setMapMarkers();
                }
            })
    }
        
setMapMarkers() {
            const bounds = new google.maps.LatLngBounds();
            const infowindow = new google.maps.InfoWindow();
    
            this.markers = this.properties.map((property) => {
                const location = property.location;
                const propertyPrice = property.prices;
                const currencySymbol = getCurrenySymbol(propertyPrice.currency);
    
                const marker = createHTMLMapMarker({
                    latlng: new google.maps.LatLng(
                        Number(location.lattitude),
                        Number(location.longitude)
                    ),
                    map: this.googleMap,
                    label: `${currencySymbol}${propertyPrice.fee_value}`
                });
    
                bounds.extend(marker.getPosition());
    
                /**
                 * *Showing info window on click marker
                 */
                google.maps.event.addListener(marker, \'click\', (event: Event) => {
                    const infoContent = createHTMLInfoWindow(property);
                    infowindow.setContent(infoContent);
                    infowindow.setOptions({
                        zIndex: 90
                    });
                    infowindow.open({
                        anchor: marker,
                        map: this.googleMap,
                        shouldFocus: true
                    });
                });
        
                return marker;
            });
    
            /**
             * *Adding marker cluster
             */
            const markerCluster = new MarkerClusterer(this.googleMap, this.markers, {
                zoomOnClick: true,
                maxZoom: 10,
                gridSize: 20,
                styles: [
                    {
                        width: 35,
                        height: 35,
                        anchorIcon: [35, 35],
                        backgroundPosition: \'0 0\',
                        className: \'custom-clustericon\'
                    }
                ]
            });
    
            /**
             * *fitbounds happens asynchronously,
             * *have to wait for a bounds_changed event before setting zoom
             */
            google.maps.event.addListener(
                this.googleMap,
                \'bounds_changed\',
                (event: Event) => {
                    const mapZoom = this.googleMap.getZoom();
                    if (mapZoom && mapZoom > 15 && this.initialZoom) {
                        this.googleMap.setZoom(10);
                        this.initialZoom = false;
                    }
                }
            );
    
            this.googleMap.fitBounds(bounds);

}
    
resetMapMarkers() {
      for (var i = 0; i < this.markers.length; i++) {
           this.markers[i].setMap(null);
      }
      this.markers = [];
}

    标签: javascript angular google-maps google-maps-api-3 google-maps-markers


    【解决方案1】:

    尝试在 setmap 函数中传递 null 而不是传递 void

    refer this link

    【讨论】:

      猜你喜欢
      • 2012-02-21
      • 1970-01-01
      • 2019-06-07
      • 2013-07-31
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-30
      相关资源
      最近更新 更多