MoneyTree.GeoLocation 地理位置服务
📋 概述
MoneyTree.GeoLocation 提供统一的地理位置服务抽象层,屏蔽底层地图服务商差异。核心包内置本地球面距离计算(基于 Haversine 公式),扩展包支持高德地图、百度地图、腾讯地图的完整 API(地理编码、逆地理编码、驾车距离计算等)。
| 属性 |
说明 |
| NuGet 包 |
MoneyTree.GeoLocation |
| 外部依赖 |
MoneyTree.Core |
| 定位 |
地理位置服务抽象与多服务商桥接 |
📦 包体系结构
MoneyTree.GeoLocation ← 核心包:接口 + 本地球面距离计算
├── MoneyTree.GeoLocation.Amap ← 扩展包:高德地图 API
├── MoneyTree.GeoLocation.Baidu ← 扩展包:百度地图 API
└── MoneyTree.GeoLocation.Tencent ← 扩展包:腾讯地图 API
🏗️ 项目文件结构
MoneyTree.GeoLocation/
├── MoneyTree.GeoLocation.csproj
├── GlobalUsings.cs
├── Abstractions/
│ └── IGeoLocationService.cs # 统一地理位置服务接口
├── Core/
│ ├── GeoLocationOptions.cs # 全局配置选项
│ ├── GeoPoint.cs # 地理坐标点模型
│ ├── GeoAddress.cs # 地址信息模型
│ └── GeoDistanceResult.cs # 距离计算结果
├── Services/
│ └── LocalGeoLocationService.cs # 本地球面距离计算
└── Extensions/
├── GeoLocationBuilder.cs # 流畅配置构造器
└── GeoLocationExtensions.cs # DI 注册扩展
🎯 核心能力
| 能力 |
说明 |
| 球面距离计算 |
基于 Haversine 公式,无需外部 API |
| 坐标有效性验证 |
自动校验经纬度范围 |
| 坐标类型转换 |
支持 WGS84 / GCJ02 / BD09 三种坐标系 |
| 地理编码 |
地址 → 坐标(需扩展包) |
| 逆地理编码 |
坐标 → 地址(需扩展包) |
| 驾车距离 |
路径规划距离(需扩展包) |
🌍 坐标系说明
| 坐标系 |
说明 |
使用方 |
| WGS84 |
GPS 原始坐标 |
Google Earth、国际标准 |
| GCJ02 |
国测局坐标(火星坐标) |
高德地图、腾讯地图 |
| BD09 |
百度坐标系 |
百度地图 |
🚀 快速开始
本地服务(基础距离计算,无需 API Key)
// Program.cs
using MoneyTree.GeoLocation.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMoneyTreeGeoLocation(); // 默认本地实现
高德地图(需 API Key)
builder.Services.AddMoneyTreeGeoLocation(g =>
{
g.UseAmap("your-amap-api-key");
});
百度地图
builder.Services.AddMoneyTreeGeoLocation(g =>
{
g.UseBaidu("your-baidu-api-key");
});
腾讯地图
builder.Services.AddMoneyTreeGeoLocation(g =>
{
g.UseTencentMap("your-tencent-api-key");
});
📖 使用示例
距离计算
public class StoreService
{
private readonly IGeoLocationService _geoLocation;
public StoreService(IGeoLocationService geoLocation)
{
_geoLocation = geoLocation;
}
// 查找附近的商店
public List<Store> FindNearbyStores(GeoPoint userLocation, double radiusKm = 5)
{
return _allStores
.Where(s => _geoLocation.IsWithinRadius(
userLocation,
new GeoPoint(s.Latitude, s.Longitude),
radiusKm * 1000))
.ToList();
}
// 计算距离并格式化显示
public string GetDistanceText(GeoPoint from, GeoPoint to)
{
var result = _geoLocation.CalculateDistance(from, to);
return result.GetFormattedDistance();
}
}
地理编码(需扩展包)
// 地址 → 坐标
var point = await geoLocation.GeocodeAsync("北京市朝阳区");
// 坐标 → 地址
var address = await geoLocation.ReverseGeocodeAsync(new GeoPoint(39.9, 116.4));
驾车距离(需扩展包)
var distance = await geoLocation.CalculateDrivingDistanceAsync(origin, destination);
🔌 服务商能力对比
| 能力 |
本地 |
高德 |
百度 |
腾讯 |
| 球面距离 |
✅ |
✅ |
✅ |
✅ |
| 驾车距离 |
❌ |
✅ |
✅ |
✅ |
| 地理编码 |
❌ |
✅ |
✅ |
✅ |
| 逆地理编码 |
❌ |
✅ |
✅ |
✅ |
| IP 定位 |
❌ |
✅ |
✅ |
✅ |
| 坐标系 |
WGS84 |
GCJ02 |
BD09 |
GCJ02 |
| 免费额度 |
无限制 |
有 |
有 |
有 |
| 需要 API Key |
❌ |
✅ |
✅ |
✅ |
📐 GeoPoint 坐标模型
var point1 = new GeoPoint(39.9042, 116.4074); // 北京(默认 GCJ02)
var point2 = new GeoPoint(31.2304, 121.4737, GeoCoordinateType.GCJ02); // 上海
var point3 = new GeoPoint { Latitude = 22.5431, Longitude = 114.0579 }; // 深圳
// 坐标有效性校验
bool isValid = point1.IsValid(); // true
// 隐式转换为字符串 "lng,lat"
string coordStr = point2; // "121.473700,31.230400"