You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制agm-map的可拖拽agm-marker与自动完成仅在印度尼西亚范围内生效

实现方案

针对你提出的两点需求,只需要修改TypeScript逻辑代码即可,前端模板无需调整,具体修改如下:


核心修改点

1. 限制地址自动完成仅返回印度尼西亚结果

Google Places Autocomplete原生支持按国家过滤结果,只需要在初始化时传入componentRestrictions配置,指定印尼的国家代码id即可。

2. 限制Marker仅可在印度尼西亚境内拖拽

新增两个变量存储上一次有效的印尼境内坐标,拖拽结束后校验坐标所属国家,如果不属于印尼则回退到上一次有效坐标,同时给出提示。


完整修改后的TypeScript代码

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;
  // 新增:存储上一次有效的印度尼西亚境内坐标
  lastValidLat: number = -6.2146;
  lastValidLng: 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();
      
      // 修改:新增Autocomplete配置,仅返回印尼地址
      let autocomplete = new google.maps.places.Autocomplete(
        this.searchElementRef.nativeElement,
        {
          componentRestrictions: { country: 'id' },
          types: ['geocode'] // 可选,按需调整返回的地点类型
        }
      );
      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]) {
            let houseNumber = '';
            let streetName = '';
            let neighborhood = '';
            let cityName = '';
            let stateName = '';
            let countryName = '';
            let shortAddress = '';
            let zipCode = '';

            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 (countryName !== 'ID') {
              this.latitude = this.lastValidLat;
              this.longitude = this.lastValidLng;
              window.alert('仅支持选择印度尼西亚境内的地址');
              this.getAddress(this.lastValidLat, this.lastValidLng);
              return;
            }

            // 国家校验通过,更新有效坐标
            this.lastValidLat = latitude;
            this.lastValidLng = longitude;

            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('未找到对应地址');
          }
        } else {
          window.alert('地址解析失败: ' + status);
        }
      }
    );
  }
}

内容的提问来源于stack exchange,提问作者Bimlendu Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:54:03