【问题标题】:Calculate the geographic distance between two points using NetTopologySuite with EF Core and postgis使用带有 EF Core 和 postgis 的 NetTopologySuite 计算两点之间的地理距离
【发布时间】:2019-11-12 10:41:07
【问题描述】:

我正在使用kartoza docker 映像来运行带有 postgis 的 postgres 服务器。我有一个使用 ASP.NET Core 应用程序和 Enity Framework Core 使用的数据库。该数据库包含一个名为 Park 的表,由以下实体表示:

[Table("Park")]
public class Park
{
     [Key]
     public int Id { get; set; }

     [Column(TypeName = "geography (point)")]
     public Point Location { get; set; }
}

我正在创建文档中指定的 DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasPostgresExtension("postgis");

    modelBuilder.Entity<Park>()
        .Property(p => p.Location)
        .HasColumnType("geography (point)");
}

我使用以下代码为数据库播种:

if (!Parks.Any())
{
    var park = new Park
    {
        Location = new Point(48.8566, 2.3522)
        {
            SRID = 4326
        }
    };

    Parks.Add(park);
    this.SaveChanges();
}

现在为了测试我的代码,我计算了这个公园和某个点之间的距离:

结果对应于笛卡尔坐标系中两点之间的几何距离,而不是地理距离。是否有可能获得以下查询的等价物:

【问题讨论】:

    标签: postgresql .net-core entity-framework-core postgis nettopologysuite


    【解决方案1】:

    here 所述,需要坐标系的投影来计算地理距离。 ProjNet4GeoAPI 用于使用 extetion 方法执行投影:

    static class GeometryExtensions
    {
        static readonly IGeometryServices _geometryServices = NtsGeometryServices.Instance;
        static readonly ICoordinateSystemServices _coordinateSystemServices
            = new CoordinateSystemServices(
                new CoordinateSystemFactory(),
                new CoordinateTransformationFactory(),
                new Dictionary<int, string>
                {
                    // Coordinate systems:
    
                    // (3857 and 4326 included automatically)
    
                    // This coordinate system covers the area of our data.
                    // Different data requires a different coordinate system.
                    [2855] =
                    @"
                        PROJCS[""NAD83(HARN) / Washington North"",
                            GEOGCS[""NAD83(HARN)"",
                                DATUM[""NAD83_High_Accuracy_Regional_Network"",
                                    SPHEROID[""GRS 1980"",6378137,298.257222101,
                                        AUTHORITY[""EPSG"",""7019""]],
                                    AUTHORITY[""EPSG"",""6152""]],
                                PRIMEM[""Greenwich"",0,
                                    AUTHORITY[""EPSG"",""8901""]],
                                UNIT[""degree"",0.01745329251994328,
                                    AUTHORITY[""EPSG"",""9122""]],
                                AUTHORITY[""EPSG"",""4152""]],
                            PROJECTION[""Lambert_Conformal_Conic_2SP""],
                            PARAMETER[""standard_parallel_1"",48.73333333333333],
                            PARAMETER[""standard_parallel_2"",47.5],
                            PARAMETER[""latitude_of_origin"",47],
                            PARAMETER[""central_meridian"",-120.8333333333333],
                            PARAMETER[""false_easting"",500000],
                            PARAMETER[""false_northing"",0],
                            UNIT[""metre"",1,
                                AUTHORITY[""EPSG"",""9001""]],
                            AUTHORITY[""EPSG"",""2855""]]
                    "
                });
    
        public static IGeometry ProjectTo(this IGeometry geometry, int srid)
        {
            var geometryFactory = _geometryServices.CreateGeometryFactory(srid);
            var transformation = _coordinateSystemServices.CreateTransformation(geometry.SRID, srid);
    
            return GeometryTransform.TransformGeometry(
                geometryFactory,
                geometry,
                transformation.MathTransform);
        }
    }
    

    现在结果似乎更正确了:

    PS:除了ProjNet4GeoAPI nugget包外,扩展方法还需要NetTopologySuite。

    【讨论】:

    • 只是一个警告,随着 NTS2 的更新,此代码将不再编译。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    相关资源
    最近更新 更多