diff --git a/src/core/directives/google-map-circle.ts b/src/core/directives/google-map-circle.ts index aedfd8059..1bf27901b 100644 --- a/src/core/directives/google-map-circle.ts +++ b/src/core/directives/google-map-circle.ts @@ -1,7 +1,7 @@ import {Directive, EventEmitter, OnChanges, OnDestroy, OnInit, SimpleChange} from '@angular/core'; import {Subscription} from 'rxjs/Subscription'; -import {MouseEvent} from '../events'; +import {MouseEvent} from '../map-types'; import {LatLng, LatLngBounds, LatLngLiteral} from '../services/google-maps-types'; import {MouseEvent as MapMouseEvent} from '../services/google-maps-types'; import {CircleManager} from '../services/managers/circle-manager'; diff --git a/src/core/directives/google-map-marker.ts b/src/core/directives/google-map-marker.ts index e63be4f4a..4e7443d96 100644 --- a/src/core/directives/google-map-marker.ts +++ b/src/core/directives/google-map-marker.ts @@ -1,7 +1,7 @@ import {AfterContentInit, ContentChild, Directive, EventEmitter, OnChanges, OnDestroy, SimpleChange} from '@angular/core'; import {Subscription} from 'rxjs/Subscription'; -import {MouseEvent} from '../events'; +import {MouseEvent} from '../map-types'; import * as mapTypes from '../services/google-maps-types'; import {MarkerManager} from '../services/managers/marker-manager'; @@ -38,7 +38,7 @@ let markerId = 0; selector: 'sebm-google-map-marker', inputs: [ 'latitude', 'longitude', 'title', 'label', 'draggable: markerDraggable', 'iconUrl', - 'openInfoWindow' + 'openInfoWindow', 'fitBounds' ], outputs: ['markerClick', 'dragEnd'] }) diff --git a/src/core/directives/google-map.ts b/src/core/directives/google-map.ts index 8ff4011fc..37d9ee4da 100644 --- a/src/core/directives/google-map.ts +++ b/src/core/directives/google-map.ts @@ -1,10 +1,10 @@ import {Component, ElementRef, EventEmitter, OnChanges, OnInit, SimpleChange} from '@angular/core'; import {Subscription} from 'rxjs/Subscription'; -import {MouseEvent} from '../events'; +import {MouseEvent} from '../map-types'; import {GoogleMapsAPIWrapper} from '../services/google-maps-api-wrapper'; import {LatLng, LatLngLiteral} from '../services/google-maps-types'; -import {LatLngBounds, MapTypeStyle} from '../services/google-maps-types'; +import {LatLngBounds, LatLngBoundsLiteral, MapTypeStyle} from '../services/google-maps-types'; import {CircleManager} from '../services/managers/circle-manager'; import {InfoWindowManager} from '../services/managers/info-window-manager'; import {MarkerManager} from '../services/managers/marker-manager'; @@ -40,7 +40,7 @@ import {MarkerManager} from '../services/managers/marker-manager'; inputs: [ 'longitude', 'latitude', 'zoom', 'disableDoubleClickZoom', 'disableDefaultUI', 'scrollwheel', 'backgroundColor', 'draggableCursor', 'draggingCursor', 'keyboardShortcuts', 'zoomControl', - 'styles', 'usePanning', 'streetViewControl' + 'styles', 'usePanning', 'streetViewControl', 'fitBounds' ], outputs: ['mapClick', 'mapRightClick', 'mapDblClick', 'centerChange', 'idle', 'boundsChange'], host: {'[class.sebm-google-map-container]': 'true'}, @@ -145,6 +145,11 @@ export class SebmGoogleMap implements OnChanges, OnInit { */ streetViewControl: boolean = true; + /** + * Sets the viewport to contain the given bounds. + */ + fitBounds: LatLngBoundsLiteral|LatLngBounds = null; + /** * Map option attributes that can change over time */ @@ -199,7 +204,7 @@ export class SebmGoogleMap implements OnChanges, OnInit { private _initMapInstance(el: HTMLElement) { this._mapsWrapper.createMap(el, { - center: {lat: this.latitude, lng: this.longitude}, + center: {lat: this.latitude || 0, lng: this.longitude || 0}, zoom: this.zoom, disableDefaultUI: this.disableDefaultUI, backgroundColor: this.backgroundColor, @@ -210,6 +215,8 @@ export class SebmGoogleMap implements OnChanges, OnInit { styles: this.styles, streetViewControl: this.streetViewControl }); + + // register event listeners this._handleMapCenterChange(); this._handleMapZoomChange(); this._handleMapMouseEvents(); @@ -226,9 +233,7 @@ export class SebmGoogleMap implements OnChanges, OnInit { /* @internal */ ngOnChanges(changes: {[propName: string]: SimpleChange}) { this._updateMapOptionsChanges(changes); - if (changes['latitude'] != null || changes['longitude'] != null) { - this._updateCenter(); - } + this._updatePosition(changes); } private _updateMapOptionsChanges(changes: {[propName: string]: SimpleChange}) { @@ -253,7 +258,19 @@ export class SebmGoogleMap implements OnChanges, OnInit { }); } - private _updateCenter() { + private _updatePosition(changes: {[propName: string]: SimpleChange}) { + if (changes['latitude'] == null && changes['longitude'] == null && + changes['fitBounds'] == null) { + // no position update needed + return; + } + + // we prefer fitBounds in changes + if (changes['fitBounds'] && this.fitBounds != null) { + this._fitBounds(); + return; + } + if (typeof this.latitude !== 'number' || typeof this.longitude !== 'number') { return; } @@ -268,6 +285,14 @@ export class SebmGoogleMap implements OnChanges, OnInit { } } + private _fitBounds() { + if (this.usePanning) { + this._mapsWrapper.panToBounds(this.fitBounds); + return; + } + this._mapsWrapper.fitBounds(this.fitBounds); + } + private _handleMapCenterChange() { const s = this._mapsWrapper.subscribeToMapEvent('center_changed').subscribe(() => { this._mapsWrapper.getCenter().then((center: LatLng) => { @@ -281,7 +306,8 @@ export class SebmGoogleMap implements OnChanges, OnInit { private _handleBoundsChange() { const s = this._mapsWrapper.subscribeToMapEvent('bounds_changed').subscribe(() => { - this._mapsWrapper.getBounds().then((bounds: LatLngBounds) => this.boundsChange.emit(bounds)); + this._mapsWrapper.getBounds().then( + (bounds: LatLngBounds) => { this.boundsChange.emit(bounds); }); }); this._observableSubscriptions.push(s); } diff --git a/src/core/index.ts b/src/core/index.ts index 5e20c6ad5..1ad41ae34 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -8,7 +8,7 @@ import {BROWSER_GLOBALS_PROVIDERS} from './utils/browser-globals'; // main modules export * from './directives'; export * from './services'; -export * from './events'; +export * from './map-types'; // Google Maps types export {LatLngBounds, LatLng, LatLngLiteral, MapTypeStyle} from './services/google-maps-types'; diff --git a/src/core/events.ts b/src/core/map-types.ts similarity index 70% rename from src/core/events.ts rename to src/core/map-types.ts index c75f85f1e..995ffbf26 100644 --- a/src/core/events.ts +++ b/src/core/map-types.ts @@ -1,7 +1,7 @@ import {LatLngLiteral} from './services/google-maps-types'; // exported map types -export {LatLngLiteral} from './services/google-maps-types'; +export {LatLngBounds, LatLngBoundsLiteral, LatLngLiteral} from './services/google-maps-types'; /** * MouseEvent gets emitted when the user triggers mouse events on the map. diff --git a/src/core/services/google-maps-api-wrapper.ts b/src/core/services/google-maps-api-wrapper.ts index f269ca299..4ae507ea6 100644 --- a/src/core/services/google-maps-api-wrapper.ts +++ b/src/core/services/google-maps-api-wrapper.ts @@ -89,6 +89,14 @@ export class GoogleMapsAPIWrapper { return this._map.then((map) => map.panTo(latLng)); } + fitBounds(latLng: mapTypes.LatLngBounds|mapTypes.LatLngBoundsLiteral): Promise { + return this._map.then((map) => map.fitBounds(latLng)); + } + + panToBounds(latLng: mapTypes.LatLngBounds|mapTypes.LatLngBoundsLiteral): Promise { + return this._map.then((map) => map.panToBounds(latLng)); + } + /** * Returns the native Google Maps Map instance. Be careful when using this instance directly. */ diff --git a/src/core/services/google-maps-types.ts b/src/core/services/google-maps-types.ts index c5598ff86..f57972bf1 100644 --- a/src/core/services/google-maps-types.ts +++ b/src/core/services/google-maps-types.ts @@ -1,15 +1,16 @@ export var google: any; -export interface GoogleMap { +export interface GoogleMap extends MVCObject { constructor(el: HTMLElement, opts?: MapOptions): void; panTo(latLng: LatLng|LatLngLiteral): void; setZoom(zoom: number): void; - addListener(eventName: string, fn: Function): void; getCenter(): LatLng; setCenter(latLng: LatLng|LatLngLiteral): void; getBounds(): LatLngBounds; getZoom(): number; setOptions(options: MapOptions): void; + panToBounds(latLngBounds: LatLngBounds|LatLngBoundsLiteral): void; + fitBounds(bounds: LatLngBounds|LatLngBoundsLiteral): void; } export interface LatLng { @@ -165,10 +166,7 @@ export interface InfoWindow { setZIndex(zIndex: number): void; } -export interface MVCObject { - constructor(): void; - addListener(eventName: string, handler: Function): MapsEventListener; -} +export interface MVCObject { addListener(eventName: string, handler: Function): MapsEventListener; } export interface MapsEventListener { remove(): void; }