返回 Skill 列表
extension
分类: 开发与工程无需 API Key

maui-maps

指导如何在使用Microsoft.Maui.Controls.Maps的.NET MAUI应用程序中添加地图控件、标记、多边形、折线、地理编码、配置Google Maps API密钥以及平台设置。适用于:“添加地图”、“地图控件”、“地图标记”、“地图上的多边形”、“折线”、“地理编码”、“Google Maps API密钥”、“Microsoft.Maui.Controls.Maps”、“地图设置”、“反向地理编码”、“地图区域”。不适用于:获取设备GPS坐标(请使用maui-geolocation)、自定义绘制覆盖层(请使用maui-graphics-drawing)或仅位置权限(请使用maui-permissions)。

person作者: jakexiaohubgithub

.NET MAUI Maps

Common gotchas

| Issue | Fix | |---|---| | Map is blank on Android | Google Maps API key missing or wrong in AndroidManifest.xml | | Map crashes on startup | .UseMauiMaps() not called in MauiProgram.cs | | Map type ambiguous | Conflicts with Microsoft.Maui.ApplicationModel.Map — add namespace alias | | Map doesn't show on Windows | Windows has no native support — must use CommunityToolkit.Maui.Maps | | User location dot missing | IsShowingUser="True" set but location permission not granted | | Android 11+ can't launch external map app | Missing <queries> for geo scheme in manifest |

⚠️ Name conflict — always alias

Microsoft.Maui.Controls.Maps.Map conflicts with Microsoft.Maui.ApplicationModel.Map. This causes confusing compile errors.

// ✅ Correct — explicit alias
using Map = Microsoft.Maui.Controls.Maps.Map;
<!-- ✅ Correct — namespace prefix in XAML -->
xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
<maps:Map ... />

<!-- ❌ Wrong — bare <Map> is ambiguous -->
<Map ... />

Platform setup pitfalls

Android — API key must be inside <application>

<!-- ✅ Correct -->
<application ...>
  <meta-data android:name="com.google.android.geo.API_KEY"
             android:value="YOUR_GOOGLE_MAPS_KEY" />
</application>

<!-- ❌ Outside <application> — key is silently ignored -->

⚠️ Also required: Google Play Services version meta-data and <queries> for geo scheme on API 30+ (see references/maps-api.md).

iOS / Mac Catalyst

⚠️ Without NSLocationWhenInUseUsageDescription in Info.plist, location permission is denied without prompt.

Windows — no native support

Must add CommunityToolkit.Maui.Maps + Bing key. Use conditional package reference and #if WINDOWS for setup.

MauiProgram.cs — don't forget UseMauiMaps

// ✅ Required — without this, Map control throws at runtime
builder.UseMauiMaps();

// ❌ Forgetting this causes "No registered handler for Map" crash

Performance tips

  • ⚠️ Don't add hundreds of pins directly — use ItemsSource with data binding for large pin sets.
  • Set initial region with MoveToRegion() to avoid the default world view zoom animation.
  • Avoid frequent MoveToRegion() calls — each triggers a map animation; debounce if driven by data changes.

Data-bound pins — do this for dynamic data

<!-- ✅ Correct — data-bound pins for dynamic collections -->
<maps:Map ItemsSource="{Binding Locations}">
    <maps:Map.ItemTemplate>
        <DataTemplate>
            <maps:Pin Label="{Binding Name}"
                      Address="{Binding Description}"
                      Location="{Binding Position}" />
        </DataTemplate>
    </maps:Map.ItemTemplate>
</maps:Map>

<!-- ❌ Wrong — manually adding pins in code-behind for data-driven scenarios -->

Decision framework

| Need | Approach | |---|---| | Basic map with pins | Map control + Pins.Add() or ItemsSource binding | | Map with shapes | MapElementsPolygon, Polyline, Circle | | Address → coordinates | Geocoding.Default.GetLocationsAsync(address) | | Coordinates → address | Geocoding.Default.GetPlacemarksAsync(lat, lon) | | Custom map overlays | Use handlers to access native map APIs | | Windows support | Must add CommunityToolkit.Maui.Maps + Bing key |

Quick checklist

  • [ ] NuGet: Microsoft.Maui.Controls.Maps added
  • [ ] .UseMauiMaps() called in MauiProgram.cs
  • [ ] Android: Google Maps API key inside <application> in AndroidManifest.xml
  • [ ] Android: Google Play Services version meta-data present
  • [ ] Android 11+: <queries> for geo scheme added
  • [ ] iOS/Mac: NSLocationWhenInUseUsageDescription in Info.plist
  • [ ] Windows: CommunityToolkit.Maui.Maps + Bing Maps key (conditional)
  • [ ] Namespace alias added to avoid Map type conflict