postgresql - 使用 NetTopologySuite 与 EF Core 和 postgis 计算两点之间的地理距离

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

我正在使用 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();
}

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

enter image description here

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

rap

最佳答案

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

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);
    }
}

现在结果似乎更正确:

enter image description here

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

关于postgresql - 使用 NetTopologySuite 与 EF Core 和 postgis 计算两点之间的地理距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56841345/

相关文章:

c# - IdentityServer4 30 分钟后自动注销

docker - .Net核心角度模板dockerfile错误

c# - 自定义验证属性的依赖注入(inject)

c# - 表上的 EF Core 删除违反了表上的外键约束

mysql - 如何在 kettle pentaho 中将数据插入到具有枚举数据类型的 postgres 表中?

postgresql - 列中的空值违反了非空约束 PostgreSQL

sql - 对具有相同值的两列进行排序时出现奇怪的排序错误(这是错误吗?)

Postgresql 连接多个表

c# - 当一个实体具有复合主键时,Entity Framework Core 中的多对多关系

c# - 无法加载文件或程序集 '<project name>, Culture=neutral, PublicKeyToken=null'。有人建议修复吗?