agm-map & agm-marker drag

1.2k views Asked by At

This is the code for adding my agm-map for Indonesia. Right now center is at Jakarta as per latitude and longitude and whole map shows in map section.
What I want is to allow marker movement to only Indonesia country.

What is the way achieve, please note I want to restrict only marker movement to Indonesia, but I want to show whole world map.
And I also want Autocomplete also to be restricted to Indonesia only.

import {
  Component,
  OnInit,
  ViewChild,
  ElementRef,
  NgZone,
} from '@angular/core';
import { MapsAPILoader, MouseEvent } from '@agm/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title: string = '';
  latitude: number = -6.2146;
  longitude: number = 106.8451;
  zoom!: number;
  address!: string;
  fullAddress!: string;
  private geoCoder!: google.maps.Geocoder;

  @ViewChild('search')
  public searchElementRef!: ElementRef;

  constructor(private mapsAPILoader: MapsAPILoader, private ngZone: NgZone) {}

  ngOnInit() {
    this.mapsAPILoader.load().then(() => {
      this.setCurrentLocation();
      this.geoCoder = new google.maps.Geocoder();
      

      let autocomplete = new google.maps.places.Autocomplete(
        this.searchElementRef.nativeElement
      );
      autocomplete.addListener('place_changed', () => {
        this.ngZone.run(() => {
          let place: google.maps.places.PlaceResult = autocomplete.getPlace();

          if (place.geometry === undefined || place.geometry === null) {
            return;
          }

          this.latitude = place.geometry.location.lat();
          this.longitude = place.geometry.location.lng();
          this.zoom = 12;
          this.getAddress(this.latitude, this.longitude);
        });
      });
    });
  }

  private setCurrentLocation() {
    if ('geolocation' in navigator) {
      navigator.geolocation.getCurrentPosition((position) => {
       /*  this.latitude = position.coords.latitude;
        this.longitude = position.coords.longitude; */
        this.zoom = 8;
        this.getAddress(this.latitude, this.longitude);
      });
    }
  }

  markerDragEnd($event: MouseEvent) {
    console.log($event);
    this.latitude = $event.coords.lat;
    this.longitude = $event.coords.lng;
    this.getAddress(this.latitude, this.longitude);
  }

  getAddress(latitude: number, longitude: number) {
    this.geoCoder.geocode(
      { location: { lat: latitude, lng: longitude } },
      (results: any, status: string) => {
        console.log(latitude, longitude);
        if (status === 'OK') {
          if (results[0]) {
            // console.log('Location: ' + results[0].formatted_address);
            let houseNumber = '';
            let streetName = '';
            let neighborhood = '';
            let cityName = '';
            let stateName = '';
            let countryName = '';
            let shortAddress = '';
            let zipCode = '';

            // console.log(results[0].address_components.length);
            console.log(results[0].address_components);

            if (results[0].address_components.length === 3) {
              if (results[0].address_components[0].long_name !== null) {
                cityName = results[0].address_components[0].long_name;
              }

              if (results[0].address_components[1].short_name) {
                stateName = results[0].address_components[1].short_name;
              }

              if (results[0].address_components[2].short_name !== null) {
                countryName = results[0].address_components[2].short_name;
              }
            }

            if (results[0].address_components.length === 4) {
              if (results[0].address_components[0].long_name !== null) {
                streetName = results[0].address_components[0].long_name;
              }

              if (results[0].address_components[1].long_name !== null) {
                cityName = results[0].address_components[1].long_name;
              }

              if (results[0].address_components[2].short_name) {
                stateName = results[0].address_components[2].short_name;
              }

              if (results[0].address_components[3].short_name !== null) {
                countryName = results[0].address_components[3].short_name;
              }
            }

            if (results[0].address_components.length === 5) {
              if (results[0].address_components[0].long_name !== null) {
                streetName = results[0].address_components[0].long_name;
              }

              if (results[0].address_components[1].long_name !== null) {
                cityName = results[0].address_components[1].long_name;
              }

              if (results[0].address_components[2].short_name !== null) {
                stateName = results[0].address_components[2].short_name;
              }

              if (results[0].address_components[3].short_name !== null) {
                countryName = results[0].address_components[3].short_name;
              }

              if (results[0].address_components[4].short_name !== null) {
                zipCode = results[0].address_components[4].short_name;
              }
            }

            if (results[0].address_components.length === 6) {
              if (results[0].address_components[0].long_name !== null) {
                houseNumber = results[0].address_components[0].long_name;
              }

              if (results[0].address_components[1].long_name !== null) {
                streetName = results[0].address_components[1].long_name;
              }

              if (results[0].address_components[2].long_name !== null) {
                cityName = results[0].address_components[2].long_name;
              }

              if (results[0].address_components[3].short_name) {
                stateName = results[0].address_components[3].short_name;
              }

              if (results[0].address_components[4].short_name !== null) {
                countryName = results[0].address_components[4].short_name;
              }
            }

            if (results[0].address_components.length === 7) {
              if (results[0].address_components[0].long_name !== null) {
                houseNumber = results[0].address_components[0].long_name;
              }

              if (results[0].address_components[1].long_name !== null) {
                streetName = results[0].address_components[1].long_name;
              }

              if (results[0].address_components[2].long_name !== null) {
                neighborhood = results[0].address_components[2].long_name;
              }

              if (results[0].address_components[3].long_name !== null) {
                cityName = results[0].address_components[3].long_name;
              }

              if (results[0].address_components[4].short_name) {
                stateName = results[0].address_components[4].short_name;
              }

              if (results[0].address_components[5].short_name !== null) {
                countryName = results[0].address_components[5].short_name;
              }
            }

            if (cityName !== '') {
              shortAddress = cityName;
            }
            if (cityName !== '' && stateName !== '') {
              shortAddress += '-' + stateName;
            }
            if (shortAddress !== '' && countryName !== '') {
              shortAddress += ', ' + countryName;
            }
            if (cityName === '' && stateName === '' && countryName === '') {
              shortAddress = '???';
            }

            console.log('shortAddress:', shortAddress);

            // Set addresses
            this.address = shortAddress;
            this.fullAddress = results[0].formatted_address;

            const newPlace = {
              lat: this.latitude,
              lng: this.longitude,
              shortAddress: this.address,
              fullAddress: this.fullAddress,
            };
            console.log(newPlace);
            // this.events.publish('location:changed', newPlace);
          } else {
            window.alert('No results found');
          }
        } else {
          window.alert('Geocoder failed due to: ' + status);
        }
      }
    );
  }
}
Below is Front-end
<div class="container">
  <h1>Angular Google Map with Search Box Example - ItSolutionStuff.com</h1>

  <div class="form-group">
    <label>Enter address</label>
    <input
      type="text"
      class="form-control"
      (keydown.enter)="$event.preventDefault()"
      placeholder="Search Nearest Location"
      autocorrect="off"
      autocapitalize="off"
      spellcheck="off"
      type="text"
      #search
    />
  </div>

  <agm-map [latitude]="latitude" [longitude]="longitude" [zoom]="zoom">
    <agm-marker
      (dragEnd)="markerDragEnd($event)"
      [latitude]="latitude"
      [longitude]="longitude"
      [markerDraggable]="true"
    ></agm-marker>
  </agm-map>

  <h5>Address: {{ fullAddress }}</h5>
  <div>Latitude: {{ latitude }}</div>
  <div>Longitude: {{ longitude }}</div>
</div>
1

There are 1 answers

3
Apoorva Chikara On BEST ANSWER

I also want Autocomplete also to be restricted to Indonesia only.

What is the way achieve, please note i want to restrict only marker movement to Indonesia,

I'm not sure that you can so this explicitly on the agm-map though, they provide restriction to the area itself using lat lng and pass it to the restriction input property. However, it won't allow to show other countries. So it won't work. (I'm adding it for the reference).

 countryRestriction = {
    latLngBounds: {
      east: 14.49234,
      north: 45.808455,
      south: 45.81792,
      west: 5.95608
    },
    strictBounds: true
  };

Pass this config to agm like this:

<agm-map 

  [restriction]="countryRestriction"
  [disableDefaultUI]="false"
  [zoomControl]="false"
  (mapClick)="mapClicked($event)">
</agm-map>

You can check if the marker lat/lng comes out to be in Indonesia bounds then you can keep the marker at any position within those bounds else don't add it to the map. You can check this link if the lat/lng exist in any given bounds(you can find the bounds of Indonesia easily on google).

I also want Autocomplete also to be restricted to Indonesia only.

If you are using autocomplete from google API, you can pass country as query param in it as Indonesia and the search results will be restricted to the given country.

You can also add the radius to specific search, it also narrows down the search. You can check here for more documentation.