Skip to content

Commit

Permalink
feat(google-maps): deprecate marker cluster component
Browse files Browse the repository at this point in the history
Deprecates the existing `MapMarkerClusterer`, because it's based on a deprecated library that doesn't support advanced markers.
A new clusterer component will be introduced that supports both regular markers and advanced ones, and is based on the current marker library.

BREAKING CHANGE:
* The new @googlemaps/markerclusterer API should be imported instead of the old one. Read more at: https://github.com/googlemaps/js-markerclusterer
* The `MapMarkerClusterer` class has been renamed to `DeprecatedMapMarkerClusterer`.
* The `map-marker-clusterer` selector has been changed to `deprecated-map-marker-clusterer`.
  • Loading branch information
crisbeto committed Oct 17, 2024
1 parent b84ebdc commit a05475e
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 149 deletions.
4 changes: 2 additions & 2 deletions src/dev-app/google-map/google-map-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
(mapRightclick)="handleRightclick()"
[mapTypeId]="mapTypeId"
[mapId]="mapId">
<map-marker-clusterer [imagePath]="markerClustererImagePath">
<deprecated-map-marker-clusterer [imagePath]="markerClustererImagePath">
<map-marker #firstMarker="mapMarker"
[position]="center"
(mapClick)="infoWindow.open(firstMarker)"></map-marker>
Expand All @@ -20,7 +20,7 @@
[options]="markerOptions"
(mapClick)="infoWindow.open(marker)"></map-marker>
}
</map-marker-clusterer>
</deprecated-map-marker-clusterer>
@if (hasAdvancedMarker) {
<map-advanced-marker
#secondMarker="mapAdvancedMarker"
Expand Down
4 changes: 2 additions & 2 deletions src/dev-app/google-map/google-map-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
MapInfoWindow,
MapKmlLayer,
MapMarker,
MapMarkerClusterer,
DeprecatedMapMarkerClusterer,
MapPolygon,
MapPolyline,
MapRectangle,
Expand Down Expand Up @@ -76,7 +76,7 @@ let apiLoadingPromise: Promise<unknown> | null = null;
MapInfoWindow,
MapKmlLayer,
MapMarker,
MapMarkerClusterer,
DeprecatedMapMarkerClusterer,
MapAdvancedMarker,
MapPolygon,
MapPolyline,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#MapMarkerClusterer
# Deprecation warning ⚠️
This component is based on the deprecated `@googlemaps/markerclustererplus` library. Use the `map-marker-clusterer` component instead.

The `MapMarkerClusterer` component wraps the [`MarkerClusterer` class](https://googlemaps.github.io/js-markerclustererplus/classes/markerclusterer.html) from the [Google Maps JavaScript MarkerClustererPlus Library](https://github.com/googlemaps/js-markerclustererplus). The `MapMarkerClusterer` component displays a cluster of markers that are children of the `<map-marker-clusterer>` tag. Unlike the other Google Maps components, MapMarkerClusterer does not have an `options` input, so any input (listed in the [documentation](https://googlemaps.github.io/js-markerclustererplus/index.html) for the `MarkerClusterer` class) should be set directly.
## DeprecatedMapMarkerClusterer

The `DeprecatedMapMarkerClusterer` component wraps the [`MarkerClusterer` class](https://googlemaps.github.io/js-markerclustererplus/classes/markerclusterer.html) from the [Google Maps JavaScript MarkerClustererPlus Library](https://github.com/googlemaps/js-markerclustererplus). The `DeprecatedMapMarkerClusterer` component displays a cluster of markers that are children of the `<deprecated-map-marker-clusterer>` tag. Unlike the other Google Maps components, MapMarkerClusterer does not have an `options` input, so any input (listed in the [documentation](https://googlemaps.github.io/js-markerclustererplus/index.html) for the `MarkerClusterer` class) should be set directly.

## Loading the Library

Expand All @@ -17,12 +20,12 @@ Additional information can be found by looking at [Marker Clustering](https://de
```typescript
// google-map-demo.component.ts
import {Component} from '@angular/core';
import {GoogleMap, MapMarker, MapMarkerClusterer} from '@angular/google-maps';
import {GoogleMap, MapMarker, DeprecatedMapMarkerClusterer} from '@angular/google-maps';

@Component({
selector: 'google-map-demo',
templateUrl: 'google-map-demo.html',
imports: [GoogleMap, MapMarker, MapMarkerClusterer],
imports: [GoogleMap, MapMarker, DeprecatedMapMarkerClusterer],
})
export class GoogleMapDemo {
center: google.maps.LatLngLiteral = {lat: 24, lng: 12};
Expand All @@ -45,10 +48,10 @@ export class GoogleMapDemo {
[center]="center"
[zoom]="zoom"
(mapClick)="addMarker($event)">
<map-marker-clusterer [imagePath]="markerClustererImagePath">
<deprecated-map-marker-clusterer [imagePath]="markerClustererImagePath">
@for (position of markerPositions; track position) {
<map-marker [position]="position" />
}
</map-marker-clusterer>
</deprecated-map-marker-clusterer>
</google-map>
```
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ import {MapMarker} from '../map-marker/map-marker';
import {
createMapConstructorSpy,
createMapSpy,
createMarkerClustererConstructorSpy,
createMarkerClustererSpy,
createDeprecatedMarkerClustererConstructorSpy,
createDeprecatedMarkerClustererSpy,
createMarkerConstructorSpy,
createMarkerSpy,
} from '../testing/fake-google-map-utils';
import {MapMarkerClusterer} from './map-marker-clusterer';
import {DeprecatedMapMarkerClusterer} from './deprecated-map-marker-clusterer';
import {
AriaLabelFn,
Calculator,
ClusterIconStyle,
MarkerClusterer,
MarkerClustererOptions,
} from './marker-clusterer-types';
} from './deprecated-marker-clusterer-types';

describe('MapMarkerClusterer', () => {
describe('DeprecatedMapMarkerClusterer', () => {
let mapSpy: jasmine.SpyObj<google.maps.Map>;
let markerClustererSpy: jasmine.SpyObj<MarkerClusterer>;
let markerClustererConstructorSpy: jasmine.Spy;
Expand All @@ -39,8 +39,9 @@ describe('MapMarkerClusterer', () => {
return createMarkerSpy({});
});

markerClustererSpy = createMarkerClustererSpy();
markerClustererConstructorSpy = createMarkerClustererConstructorSpy(markerClustererSpy);
markerClustererSpy = createDeprecatedMarkerClustererSpy();
markerClustererConstructorSpy =
createDeprecatedMarkerClustererConstructorSpy(markerClustererSpy);

fixture = TestBed.createComponent(TestApp);
});
Expand All @@ -52,7 +53,10 @@ describe('MapMarkerClusterer', () => {

it('throws an error if the clustering library has not been loaded', fakeAsync(() => {
(window as any).MarkerClusterer = undefined;
markerClustererConstructorSpy = createMarkerClustererConstructorSpy(markerClustererSpy, false);
markerClustererConstructorSpy = createDeprecatedMarkerClustererConstructorSpy(
markerClustererSpy,
false,
);

expect(() => {
fixture.detectChanges();
Expand Down Expand Up @@ -304,7 +308,7 @@ describe('MapMarkerClusterer', () => {
selector: 'test-app',
template: `
<google-map>
<map-marker-clusterer
<deprecated-map-marker-clusterer
[ariaLabelFn]="ariaLabelFn"
[averageCenter]="averageCenter"
[batchSize]="batchSize"
Expand Down Expand Up @@ -335,14 +339,14 @@ describe('MapMarkerClusterer', () => {
@if (state === 'state2') {
<map-marker />
}
</map-marker-clusterer>
</deprecated-map-marker-clusterer>
</google-map>
`,
standalone: true,
imports: [GoogleMap, MapMarker, MapMarkerClusterer],
imports: [GoogleMap, MapMarker, DeprecatedMapMarkerClusterer],
})
class TestApp {
@ViewChild(MapMarkerClusterer) markerClusterer: MapMarkerClusterer;
@ViewChild(DeprecatedMapMarkerClusterer) markerClusterer: DeprecatedMapMarkerClusterer;

ariaLabelFn?: AriaLabelFn;
averageCenter?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import {
ClusterIconStyle,
MarkerClusterer as MarkerClustererInstance,
MarkerClustererOptions,
} from './marker-clusterer-types';
} from './deprecated-marker-clusterer-types';

/** Default options for a clusterer. */
const DEFAULT_CLUSTERER_OPTIONS: MarkerClustererOptions = {};
Expand All @@ -52,17 +52,23 @@ declare const MarkerClusterer: typeof MarkerClustererInstance;

/**
* Angular component for implementing a Google Maps Marker Clusterer.
*
* See https://developers.google.com/maps/documentation/javascript/marker-clustering
*
* @deprecated This component is using a deprecated clustering implementation. Use the
* `map-marker-clusterer` component instead.
* @breaking-change 21.0.0
*
*/
@Component({
selector: 'map-marker-clusterer',
selector: 'deprecated-map-marker-clusterer',
exportAs: 'mapMarkerClusterer',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content/>',
encapsulation: ViewEncapsulation.None,
})
export class MapMarkerClusterer implements OnInit, AfterContentInit, OnChanges, OnDestroy {
export class DeprecatedMapMarkerClusterer
implements OnInit, AfterContentInit, OnChanges, OnDestroy
{
private readonly _googleMap = inject(GoogleMap);
private readonly _ngZone = inject(NgZone);
private readonly _currentMarkers = new Set<google.maps.Marker>();
Expand Down
4 changes: 2 additions & 2 deletions src/google-maps/google-maps-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {MapGroundOverlay} from './map-ground-overlay/map-ground-overlay';
import {MapInfoWindow} from './map-info-window/map-info-window';
import {MapKmlLayer} from './map-kml-layer/map-kml-layer';
import {MapMarker} from './map-marker/map-marker';
import {MapMarkerClusterer} from './map-marker-clusterer/map-marker-clusterer';
import {DeprecatedMapMarkerClusterer} from './deprecated-map-marker-clusterer/deprecated-map-marker-clusterer';
import {MapPolygon} from './map-polygon/map-polygon';
import {MapPolyline} from './map-polyline/map-polyline';
import {MapRectangle} from './map-rectangle/map-rectangle';
Expand All @@ -38,7 +38,7 @@ const COMPONENTS = [
MapKmlLayer,
MapMarker,
MapAdvancedMarker,
MapMarkerClusterer,
DeprecatedMapMarkerClusterer,
MapPolygon,
MapPolyline,
MapRectangle,
Expand Down
4 changes: 2 additions & 2 deletions src/google-maps/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export {MapInfoWindow} from './map-info-window/map-info-window';
export {MapKmlLayer} from './map-kml-layer/map-kml-layer';
export {MapMarker} from './map-marker/map-marker';
export {MapAdvancedMarker} from './map-advanced-marker/map-advanced-marker';
export {MapMarkerClusterer} from './map-marker-clusterer/map-marker-clusterer';
export {DeprecatedMapMarkerClusterer} from './deprecated-map-marker-clusterer/deprecated-map-marker-clusterer';
export {MapPolygon} from './map-polygon/map-polygon';
export {MapPolyline} from './map-polyline/map-polyline';
export {MapRectangle} from './map-rectangle/map-rectangle';
Expand All @@ -35,5 +35,5 @@ export {
ClusterIconStyle,
AriaLabelFn,
Calculator,
} from './map-marker-clusterer/marker-clusterer-types';
} from './deprecated-map-marker-clusterer/deprecated-marker-clusterer-types';
export {MapEventManager} from './map-event-manager';
24 changes: 12 additions & 12 deletions src/google-maps/testing/fake-google-map-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import {MarkerClusterer} from '../map-marker-clusterer/marker-clusterer-types';
import {MarkerClusterer as DeprecatedMarkerClusterer} from '../deprecated-map-marker-clusterer/deprecated-marker-clusterer-types';

// The global `window` variable is typed as an intersection of `Window` and `globalThis`.
// We re-declare `window` here and omit `globalThis` as it is typed with the actual Google
Expand Down Expand Up @@ -574,8 +574,8 @@ export function createBicyclingLayerConstructorSpy(
}

/** Creates a jasmine.SpyObj for a MarkerClusterer */
export function createMarkerClustererSpy(): jasmine.SpyObj<MarkerClusterer> {
const markerClustererSpy = jasmine.createSpyObj('MarkerClusterer', [
export function createDeprecatedMarkerClustererSpy(): jasmine.SpyObj<DeprecatedMarkerClusterer> {
const deprecatedMarkerClustererSpy = jasmine.createSpyObj('DeprecatedMarkerClusterer', [
'addListener',
'addMarkers',
'fitMapToMarkers',
Expand Down Expand Up @@ -619,26 +619,26 @@ export function createMarkerClustererSpy(): jasmine.SpyObj<MarkerClusterer> {
'setZoomOnClick',
'setOptions',
]);
markerClustererSpy.addListener.and.returnValue({remove: () => {}});
return markerClustererSpy;
deprecatedMarkerClustererSpy.addListener.and.returnValue({remove: () => {}});
return deprecatedMarkerClustererSpy;
}

/** Creates a jasmine.Spy to watch for the constructor of a MarkerClusterer */
export function createMarkerClustererConstructorSpy(
markerClustererSpy: jasmine.SpyObj<MarkerClusterer>,
export function createDeprecatedMarkerClustererConstructorSpy(
deprecatedMarkerClustererSpy: jasmine.SpyObj<DeprecatedMarkerClusterer>,
apiLoaded = true,
): jasmine.Spy {
// The spy target function cannot be an arrow-function as this breaks when created through `new`.
const markerClustererConstructorSpy = jasmine
.createSpy('MarkerClusterer constructor', function () {
return markerClustererSpy;
const deprecatedMarkerClustererConstructorSpy = jasmine
.createSpy('DeprecatedMarkerClusterer constructor', function () {
return deprecatedMarkerClustererSpy;
})
.and.callThrough();
if (apiLoaded) {
const testingWindow: TestingWindow = window;
testingWindow['MarkerClusterer'] = markerClustererConstructorSpy;
testingWindow['MarkerClusterer'] = deprecatedMarkerClustererConstructorSpy;
}
return markerClustererConstructorSpy;
return deprecatedMarkerClustererConstructorSpy;
}

/** Creates a jasmine.SpyObj for DirectionsRenderer */
Expand Down
4 changes: 2 additions & 2 deletions src/universal-app/kitchen-sink/kitchen-sink.html
Original file line number Diff line number Diff line change
Expand Up @@ -641,13 +641,13 @@ <h2>Google Map</h2>
]"
></map-heatmap-layer>

<map-marker-clusterer
<deprecated-map-marker-clusterer
imagePath="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m"
>
<map-marker [position]="{lat: 24, lng: 12}"></map-marker>
<map-marker [position]="{lat: 12, lng: 24}"></map-marker>
<map-marker [position]="{lat: 12, lng: 12}"></map-marker>
</map-marker-clusterer>
</deprecated-map-marker-clusterer>
</google-map>

<h2>Popover edit</h2>
Expand Down
4 changes: 2 additions & 2 deletions src/universal-app/kitchen-sink/kitchen-sink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
MapInfoWindow,
MapKmlLayer,
MapMarker,
MapMarkerClusterer,
DeprecatedMapMarkerClusterer,
MapPolygon,
MapPolyline,
MapRectangle,
Expand Down Expand Up @@ -196,7 +196,7 @@ export class TestEntryComponent {}
MapKmlLayer,
MapMarker,
MapAdvancedMarker,
MapMarkerClusterer,
DeprecatedMapMarkerClusterer,
MapPolygon,
MapPolyline,
MapRectangle,
Expand Down
Loading

0 comments on commit a05475e

Please sign in to comment.