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

Google Maps带路线规划的自动补全功能问题求解决方案

Fixing Google Maps Autocomplete + Routing in Ionic/Angular

Hey there! Let's work through your Google Maps autocomplete + routing issue in your Ionic/Angular app. I notice your code got cut off, so I’ll fill in the gaps and fix the most common pitfalls developers run into with this setup.

First, Let's Cover the Critical Setup Steps

Before diving into code, make sure you’ve got these basics sorted:

  • Enable Required APIs: Go to your Google Cloud Console and enable both the Maps JavaScript API and Places API for your API key.
  • Load the Library: Add this script to your index.html (replace YOUR_API_KEY with your actual key):
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
    
  • Map Container Styling: Add this to your test.scss to ensure the map renders properly:
    .map-container {
      height: 300px;
      width: 100%;
      margin: 10px 0;
    }
    

Full Working Component Code

test.html (Template)

<ion-content padding>
  <ion-list>
    <ion-item>
      <ion-label>起点</ion-label>
      <ion-input #originInput type="text" placeholder="输入起点或使用当前位置"></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>终点</ion-label>
      <ion-input #destinationInput type="text" placeholder="输入终点"></ion-input>
    </ion-item>
  </ion-list>

  <div #map class="map-container"></div>

  <ion-button full (click)="useCurrentLocation()" margin-bottom>使用当前位置作为起点</ion-button>
  <ion-button full color="primary" (click)="calculateRoute()">规划路线</ion-button>
</ion-content>

test.ts (Component Logic)

import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Geolocation, GeolocationOptions, Geoposition, PositionError } from '@ionic-native/geolocation';

declare var google;

@IonicPage()
@Component({
  selector: 'page-test',
  templateUrl: 'test.html',
})
export class TestPage implements OnInit {
  @ViewChild('map') mapElement: ElementRef;
  @ViewChild('originInput') originInput: ElementRef;
  @ViewChild('destinationInput') destinationInput: ElementRef;

  map: google.maps.Map;
  originAutocomplete: google.maps.places.Autocomplete;
  destinationAutocomplete: google.maps.places.Autocomplete;
  directionsService: google.maps.DirectionsService;
  directionsRenderer: google.maps.DirectionsRenderer;
  currentPosition: Geoposition;

  constructor(
    private navCtrl: NavController,
    private navParams: NavParams,
    private geolocation: Geolocation
  ) {}

  ngOnInit() {
    // Wait for the page to fully render before initializing map and autocomplete
    setTimeout(() => {
      this.initMap();
      this.setupAutocomplete();
    }, 500);
  }

  initMap() {
    const locationOptions: GeolocationOptions = {
      enableHighAccuracy: true,
      timeout: 10000
    };

    // Try to get user's current location first
    this.geolocation.getCurrentPosition(locationOptions).then((pos: Geoposition) => {
      this.currentPosition = pos;
      const initialLatLng = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
      this.initializeMap(initialLatLng);
    }).catch((err: PositionError) => {
      console.warn('Failed to get current location:', err.message);
      // Fallback to a default location if geolocation fails
      const defaultLatLng = new google.maps.LatLng(39.9042, 116.4074); // Beijing as default
      this.initializeMap(defaultLatLng);
    });
  }

  initializeMap(center: google.maps.LatLng) {
    const mapOptions: google.maps.MapOptions = {
      center: center,
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      disableDefaultUI: false
    };

    this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);
    
    // Initialize directions services for routing
    this.directionsService = new google.maps.DirectionsService();
    this.directionsRenderer = new google.maps.DirectionsRenderer();
    this.directionsRenderer.setMap(this.map);
  }

  setupAutocomplete() {
    if (!google.maps.places) {
      console.error('Google Places API is not loaded! Check your script tag.');
      return;
    }

    // Setup origin autocomplete
    this.originAutocomplete = new google.maps.places.Autocomplete(
      this.originInput.nativeElement,
      { types: ['geocode'], componentRestrictions: { country: 'cn' } } // Restrict to China, adjust as needed
    );

    // Setup destination autocomplete
    this.destinationAutocomplete = new google.maps.places.Autocomplete(
      this.destinationInput.nativeElement,
      { types: ['geocode'], componentRestrictions: { country: 'cn' } }
    );

    // Optional: Log selected place details
    this.originAutocomplete.addListener('place_changed', () => {
      const selectedPlace = this.originAutocomplete.getPlace();
      console.log('Selected origin:', selectedPlace.formatted_address);
    });

    this.destinationAutocomplete.addListener('place_changed', () => {
      const selectedPlace = this.destinationAutocomplete.getPlace();
      console.log('Selected destination:', selectedPlace.formatted_address);
    });
  }

  useCurrentLocation() {
    if (this.currentPosition) {
      // Reverse geocode to get address text for input
      const geocoder = new google.maps.Geocoder();
      const latLng = new google.maps.LatLng(
        this.currentPosition.coords.latitude,
        this.currentPosition.coords.longitude
      );

      geocoder.geocode({ location: latLng }, (results, status) => {
        if (status === google.maps.GeocoderStatus.OK && results[0]) {
          this.originInput.nativeElement.value = results[0].formatted_address;
        }
      });
    } else {
      alert('无法获取当前位置,请检查定位权限!');
    }
  }

  calculateRoute() {
    const origin = this.originInput.nativeElement.value.trim();
    const destination = this.destinationInput.nativeElement.value.trim();

    if (!origin || !destination) {
      alert('请输入起点和终点!');
      return;
    }

    const routeRequest: google.maps.DirectionsRequest = {
      origin: origin,
      destination: destination,
      travelMode: google.maps.TravelMode.DRIVING // Options: WALKING, TRANSIT, BICYCLING
    };

    this.directionsService.route(routeRequest, (result, status) => {
      if (status === google.maps.DirectionsStatus.OK) {
        this.directionsRenderer.setDirections(result);
      } else {
        console.error('Route calculation failed:', status);
        alert('无法规划路线,请检查输入的地点是否正确!');
      }
    });
  }
}

Key Fixes & Improvements

  • Proper Initialization: Uses setTimeout in ngOnInit to ensure the DOM is fully loaded before initializing map/autocomplete (avoids "map container not found" errors).
  • Geolocation Fallback: If getting the user's location fails, it uses a default location instead of breaking the map.
  • Autocomplete Restrictions: Adds country restrictions to narrow down results (adjust the componentRestrictions value as needed).
  • User-Friendly Features: Includes a button to use current location as the start point, with reverse geocoding to fill the input with a readable address.
  • Error Handling: Adds clear alerts and console logs for common failure points (missing inputs, geolocation errors, route calculation issues).

Common Troubleshooting Tips

  1. Autocomplete Not Working: Double-check that the Places API is enabled in your Google Cloud Console, and your API key has the correct permissions.
  2. Map Not Rendering: Ensure the map container has a fixed height (the CSS in test.scss is critical here).
  3. Route Calculation Failing: Verify that the input addresses are valid, and the selected travel mode is supported in the region.
  4. Geolocation Issues: Make sure you've added the geolocation plugin (cordova plugin add cordova-plugin-geolocation) and enabled location permissions in your app's config.xml.

内容的提问来源于stack exchange,提问作者K.Jarrad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:02:03