4

I have been trying to use DrawingManager with official Angular components wrapper of Maps API but it didn't worked as it should. If anyone could have made it work it I would be thankful to get a solution for this. Here is the snippet and stackblitz link for solution I tried but no luck. (In stackblitz it didn't recognized the google namespace but if you download it would be ok on local machine)

this.drawingManager = new google.maps.drawing.DrawingManager({
      drawingMode: google.maps.drawing.OverlayType.POLYGON,
      drawingControl: true,
      drawingControlOptions: {
        position: google.maps.ControlPosition.TOP_CENTER,
        drawingModes: [google.maps.drawing.OverlayType.POLYGON]
      }
});
this.drawingManager.setMap(this.map._googleMap);

https://stackblitz.com/edit/angular-vvwbdg

Github issue link: https://github.com/angular/components/issues/18599

Edit 1: It turned out the issue is with map not being fully loaded and setting DrawingManager before that doesn't takes effect. There is no load callback in the wrapper module. But AfterViewInit of Angular seems to do the job well.

Innomalist
  • 43
  • 2
  • 5

3 Answers3

6

Create the DrawingManager once the component is available using a @ViewChild setter:

home.component.html:

<div *ngIf="apiLoaded | async">
    <google-map [options]="options"></google-map>
</div>

home.component.ts:

export class HomeComponent implements OnInit {

  @ViewChild(GoogleMap, { static: false }) set map(m: GoogleMap) {
    if (m) {
      this.initDrawingManager(m);
    }
  }

  apiLoaded: Observable<boolean>;
  drawingManager: any;

  options: google.maps.MapOptions = {
    zoom: 18,
    mapTypeId: 'satellite',
    disableDefaultUI: true
  };

  constructor(httpClient: HttpClient) {
    this.apiLoaded = httpClient.jsonp('https://maps.googleapis.com/maps/api/js?key=<API_KEY>&libraries=drawing', 'callback')
      .pipe(
        map(() => true),
        catchError(() => of(false)),
      );
  }

  initDrawingManager(map: GoogleMap) {
    const drawingOptions = {
      drawingMode: google.maps.drawing.OverlayType.POLYGON,
      drawingControl: true,
      drawingControlOptions: {
        position: google.maps.ControlPosition.TOP_CENTER,
        drawingModes: [
          google.maps.drawing.OverlayType.POLYGON,
        ],
      },
      polygonOptions: {
        strokeColor: '#00ff00',
      },
    };
    this.drawingManager = new google.maps.drawing.DrawingManager(drawingOptions);
    this.drawingManager.setMap(map.googleMap);
  }
DaveO
  • 1,909
  • 4
  • 33
  • 63
0

First you need to add a Google API Key to use the maps api, described here.

For angular it is recommendable to use angular-maps components. Here you can find a working Stackblitz.

If you want to work without agm you have to implement your own service to load the script, like it is done in this Stackblitz.

zerocewl
  • 11,401
  • 6
  • 27
  • 53
  • Thanks for your answer, I have removed the api key intentionally from stackblitz because couldn't expose an unrestricted api key and besides it works in dev mode regardless. Loading manually is an option but not exactly what I was looking for. My point is possibility of using official Google Maps component as it could be much cleaner than loading manually and I consider using official one a better option than agm. If no solution found I'll go with agm, Thanks again – Innomalist Feb 29 '20 at 16:21
  • Np, if you like look here https://stackoverflow.com/help/someone-answers – zerocewl Feb 29 '20 at 16:39
0

I have came across this discussions:

https://github.com/angular/components/issues/17828

https://github.com/angular/components/issues/18015

How can I check whether Google Maps is fully loaded?

Main contributor of Maps component stated he doesn't plans to add load callback or anything related to underlying map API so I have taken another hacky approach to know if the map is loaded inside component or not.

component.ts:

mapLoaded = false;
idleMap(event: any)  {
    if(this.mapLoaded)
      return;
    this.mapLoaded = true;
    this.drawingManager = new google.maps.drawing.DrawingManager({
      drawingMode: google.maps.drawing.OverlayType.POLYGON,
      drawingControl: true,
      map:this.map._googleMap,
      drawingControlOptions: {
        position: google.maps.ControlPosition.TOP_CENTER,
        drawingModes: [google.maps.drawing.OverlayType.POLYGON]
      }
    });
    google.maps.event.addListener(this.drawingManager, 'overlaycomplete', (event) => {
      if (event.type === google.maps.drawing.OverlayType.POLYGON) {
        let ar = event.overlay.getPath().getArray();
        ar.push(ar[0]);
        this.model.location.push(ar);
      }
    });
  }

html:

<google-map
    (tilesloaded)="idleMap($event)">
  </google-map>
Innomalist
  • 43
  • 2
  • 5