/**
 * Copyright 2019 Google LLC. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ import { MarkerClusterer , ClusterAugmentedMarker } from "./markerclusterer" ; import { ClusterIcon } from "./cluster-icon" ; /**
 * Creates a single cluster that manages a group of proximate markers.
 *  Used internally, do not call this constructor directly.
 */ export class Cluster { private map_ = this . markerClusterer_ . getMap ( ) as google . maps . Map ; private minClusterSize_ : number = this . markerClusterer_ . getMinimumClusterSize ( ) ; private averageCenter_ : boolean = this . markerClusterer_ . getAverageCenter ( ) ; private markers_ : ClusterAugmentedMarker [ ] = [ ] ; private center_ : google . maps . LatLng = null ; private bounds_ : google . maps . LatLngBounds = null ; private clusterIcon_ = new ClusterIcon ( this , this . markerClusterer_ . getStyles ( ) ) ; param markerClusterer_ constructor ( private markerClusterer_ ) { } return public getSize ( ) { return this . markers_ . length ; } return public getMarkers ( ) { return this . markers_ ; } return public getCenter ( ) { return this . center_ ; } return ignore public getMap ( ) { return this . map_ ; } return ignore public getMarkerClusterer ( ) { return this . markerClusterer_ ; } return ignore public getBounds ( ) { const bounds = new google . maps . LatLngBounds ( this . center_ , this . center_ ) ; const markers = this . getMarkers ( ) ; for ( let i = 0 ; i < markers . length ; i ++ ) { bounds . extend ( markers [ i ] . getPosition ( ) ) ; } return bounds ; } ignore public remove ( ) { this . clusterIcon_ . setMap ( null ) ; this . markers_ = [ ] ; delete this . markers_ ; } param marker return ignore public addMarker ( marker ) { if ( this . isMarkerAlreadyAdded_ ( marker ) ) { return false ; } if ( ! this . center_ ) { this . center_ = marker . getPosition ( ) ; this . calculateBounds_ ( ) ; } else { if ( this . averageCenter_ ) { const l = this . markers_ . length + 1 ; const lat = ( this . center_ . lat ( ) * ( l - 1 ) + marker . getPosition ( ) . lat ( ) ) / l ; const lng = ( this . center_ . lng ( ) * ( l - 1 ) + marker . getPosition ( ) . lng ( ) ) / l ; this . center_ = new google . maps . LatLng ( lat , lng ) ; this . calculateBounds_ ( ) ; } } marker . isAdded = true ; this . markers_ . push ( marker ) ; const mCount = this . markers_ . length ; const mz = this . markerClusterer_ . getMaxZoom ( ) ; if ( mz !== null && this . map_ . getZoom ( ) > mz ) { if ( marker . getMap ( ) !== this . map_ ) { marker . setMap ( this . map_ ) ; } } else if ( mCount < this . minClusterSize_ ) { if ( marker . getMap ( ) !== this . map_ ) { marker . setMap ( this . map_ ) ; } } else if ( mCount === this . minClusterSize_ ) { for ( let i = 0 ; i < mCount ; i ++ ) { this . markers_ [ i ] . setMap ( null ) ; } } else { marker . setMap ( null ) ; } return true ; } param marker return ignore public isMarkerInClusterBounds ( marker ) { return this . bounds_ . contains ( marker . getPosition ( ) ) ; } /**
     * Calculates the extended bounds of the cluster with the grid.
     */ private calculateBounds_ ( ) { const bounds = new google . maps . LatLngBounds ( this . center_ , this . center_ ) ; this . bounds_ = this . markerClusterer_ . getExtendedBounds ( bounds ) ; } /**
     * Updates the cluster icon.
     */ public updateIcon ( ) { const mCount = this . markers_ . length ; const mz = this . markerClusterer_ . getMaxZoom ( ) ; if ( mz !== null && this . map_ . getZoom ( ) > mz ) { this . clusterIcon_ . hide ( ) ; return ; } if ( mCount < this . minClusterSize_ ) { this . clusterIcon_ . hide ( ) ; return ; } const numStyles = this . markerClusterer_ . getStyles ( ) . length ; const sums = this . markerClusterer_ . getCalculator ( ) ( this . markers_ , numStyles ) ; this . clusterIcon_ . setCenter ( this . center_ ) ; this . clusterIcon_ . useStyle ( sums ) ; this . clusterIcon_ . show ( ) ; } param marker return private isMarkerAlreadyAdded_ ( marker ) { if ( this . markers_ . indexOf ) { return this . markers_ . indexOf ( marker ) !== - 1 ; } else { for ( let i = 0 ; i < this . markers_ . length ; i ++ ) { if ( marker === this . markers_ [ i ] ) { return true ; } } } return false ; } }