簡體   English   中英

谷歌地圖:如何更新標記

[英]Google Maps: How To Update Markers

我有一個可觀察的,它發出一個屬性列表。 基於屬性緯度經度,我正在使用谷歌 map 疊加層呈現自定義 HTML 標記。

第一次加載 map 時,標記和集群正在正確渲染。 從第二次開始,我試圖刪除以前的標記並放置新的標記。 此時,舊標記未被刪除(我已經添加了一個刪除方法)並添加了新標記。 此外,集群從第二次開始就沒有顯示。

問題:如何更新谷歌地圖中的標記?

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 = [];
}

嘗試通過 null 而不是在 setmap function 中傳遞 void

參考這個鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM