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

如何用NetTopologySuite/ProjNet计算两点间米级距离(2022)

解决方案

错误原因

你提供的EPSG:27700的WKT包含EXTENSION扩展段,而ProjNet的WKT解析器不支持该扩展语法,导致解析报错。

简化方案(无需手动投影)

如果你的目标只是计算两点间的球面距离(单位:米),完全不需要手动转换坐标系,直接使用NetTopologySuite的相关工具即可,和TSQL的STDistance行为一致:

@using NetTopologySuite.Geometries
@using NetTopologySuite.Algorithm.Distance

@{
    // 注意:地理坐标点的顺序是 经度, 纬度,SRID=4326对应WGS84坐标系
    var windsorCastle = new Point(-0.604455, 51.483884) { SRID = 4326 };
    var buckinghamPalace = new Point(-0.141208, 51.501576) { SRID = 4326 };

    // 直接计算球面距离,单位为米
    var distanceCalculator = new SphericalDistanceCalculator();
    double distanceInMeters = distanceCalculator.Distance(windsorCastle, buckinghamPalace);

    Console.WriteLine($"两点距离:{distanceInMeters:F2} 米");
}

如需转换到EPSG:27700(英国国家网格)

如果必须转换坐标系,需要去掉WKT中的EXTENSION段(去掉后会忽略OSTN15校正,精度略有损失),修正后的代码如下:

@using NetTopologySuite.Geometries
@using ProjNet.CoordinateSystems
@using ProjNet.CoordinateSystems.Transformations

@{
    var windsorCastle = new Point(-0.604455, 51.483884) { SRID = 4326 };
    var buckinghamPalace = new Point(-0.141208, 51.501576) { SRID = 4326 };

    // 移除EXTENSION段的EPSG:27700 WKT
    const string epsg27700 = @"
        PROJCS[""OSGB36 / British National Grid"",
        GEOGCS[""OSGB36"",
            DATUM[""Ordnance_Survey_of_Great_Britain_1936"",
                SPHEROID[""Airy 1830"",6377563.396,299.3249646]],
            PRIMEM[""Greenwich"",0,
                AUTHORITY[""EPSG"",""8901""]],
            UNIT[""degree"",0.0174532925199433,
                AUTHORITY[""EPSG"",""9122""]],
            AUTHORITY[""EPSG"",""4277""]],
        PROJECTION[""Transverse_Mercator""],
        PARAMETER[""latitude_of_origin"",49],
        PARAMETER[""central_meridian"",-2],
        PARAMETER[""scale_factor"",0.9996012717],
        PARAMETER[""false_easting"",400000],
        PARAMETER[""false_northing"",-100000],
        UNIT[""metre"",1,
            AUTHORITY[""EPSG"",""9001""]],
        AXIS[""Easting"",EAST],
        AXIS[""Northing"",NORTH],
        AUTHORITY[""EPSG"",""27700""]]
    ";

    var csWgs84 = GeographicCoordinateSystem.WGS84;
    var cs27700 = (CoordinateSystem)CoordinateSystemWktReader.Parse(epsg27700);
    
    var ctFactory = new CoordinateTransformationFactory();
    var transformation = ctFactory.CreateFromCoordinateSystems(csWgs84, cs27700);

    // 转换坐标点到英国国家网格
    var windsorCastleOsgb = new Point(transformation.MathTransform.Transform(windsorCastle.Coordinate)) { SRID = 27700 };
    var buckinghamPalaceOsgb = new Point(transformation.MathTransform.Transform(buckinghamPalace.Coordinate)) { SRID = 27700 };

    // 计算平面距离,单位为米
    double distanceInMeters = windsorCastleOsgb.Distance(buckinghamPalaceOsgb);
    Console.WriteLine($"两点距离:{distanceInMeters:F2} 米");
}

关键注意事项

  • 地理坐标点的顺序是经度在前,纬度在后,和TSQL的geography::Point(Lat, Lon)相反,不要混淆。
  • 用EF Core查询数据库时,直接在LINQ中调用Distance方法,EF Core会自动转换为SQL的STDistance,返回米单位结果:
    var nearbyPlaces = db.Places
        .Where(p => p.Location.Distance(userLocation) < 1000) // 查询1000米以内的地点
        .ToList();
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:40:48