EntityFrameworkCore.PostgreSQL转换点

时间:2018-05-19 09:30:04

标签: c# postgresql .net-core entity-framework-core postgis

有没有办法使用EntityFrameworkCore将点转换为另一个SRID?

之前我使用了ST_Transform(ST_GeomFromText(@coord,4326),32661)

我目前的代码如下所示

var postgisGeometry = new PostgisPoint(lon, lat) {SRID = 4326};

coord的SRID是4326,需要变为32661 这是出于向后兼容性原因而完成的,并且没有选项将数据库转换为另一个SRID

是否有几何图形库或PostGIS EntityFrameworkCore方法将点转换为另一个SRID

1 个答案:

答案 0 :(得分:1)

PostgreSQL的发布版Npgsql.EntityFrameworkCore.PostgreSQL实体框架核心提供程序不支持空间类型。

好消息是空间类型支持和支持某些空间操作SQL翻译已作为预发布候选者提供。

如果要使用这些库,还需要使用Eregy Framework Core的预备版候选版本。

首先,卸载现有的实体框架或npgsql软件包。

标准NuGet源中没有一个所需的软件包(GeoAPI),因此我们将使用myget.org源代码。

要使用它,您需要在Visual Studio中添加一个新的NuGet源,方法是转到Tools - >选项 - > NuGet包管理器 - >包来源

创建一个新来源并将其命名为myget.org,并在源文本字段中使用以下URL:

https://www.myget.org/F/imageprocessor/api/v3/index.json

请记住点击更新以保存更改,否则不会保存(很奇怪,我知道)。

要添加所需的软件包,请使用软件包管理器控制台(查看 - >其他Windows - >软件包管理器控制台),然后从软件包源下拉列表中选择 myget.org ,然后执行以下命令:

Install-Package Microsoft.EntityFrameworkCore -Version 2.1.0-rc1-final

Install-Package GeoAPI -Version 1.7.5-pre024

Install-Package Npgsql -Version 4.0.0-rc1 

Install-Package Npgsql.EntityFrameworkCore.PostgreSQL -Version 2.1.0-rc1

Install-Package Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite -Version 2.1.0-rc1

安装软件包后,在DbContext班级中,覆盖OnConfiguring以添加UseNetTopologySuite选项:

protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
    builder.UseNpgsql("Host=localhost;Database=your_database;
                                Username=your_user;Password=your_password",
        o => o.UseNetTopologySuite());
}

要确保数据库支持扩展,请将以下内容添加到DbContext:

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

现在您应该能够使用PostgreSql空间类型并将一些操作转换为SQL,(例如ST_AreaST_ContainsST_As_Text等。)

此处提供了支持的操作的完整列表以及如何在EF查询中使用它们:http://www.npgsql.org/efcore/mapping/nts.html#operation-translation

不幸的是,ST_TransformST_Project目前似乎不受支持,但上面的网站中有一个链接,您可以联系开发人员并请求添加。

与此同时,您可以使用GDAL转换坐标投影。

安装包:

Install-Package Gdal.Core -Version 1.0.0

此软件包为GDAL for .NET核心提供了一个多平台包装器,因此您需要安装这些库,并且程序应该可以访问这些库。

您可以在此处找到适用于Windows和Linux的二进制文件:https://trac.osgeo.org/gdal/wiki/DownloadingGdalBinaries

如果您使用的是Windows,则可以使用以下安装程序:http://download.osgeo.org/osgeo4w/osgeo4w-setup-x86_64.exe

只需在“选择包”窗口中选择“快速桌面安装”和GDAL即可。

默认情况下,所需的库安装在C:\ OSGeo4W64 \ bin。

您需要将此文件夹添加到系统路径并重新启动Visual Studio。

顺便说一下,为了转换坐标,来自C:\ OSGeo4W64 \ bin中的所有库我认为你只需要proj.dll,所以你可以将它包含在你的项目中(确保它被复制到输出中)你的项目)然后它应该工作,你不需要安装GDAL。

以下是如何将其用于问题中提供的坐标系的示例:

using System;
using NetTopologySuite.Geometries;
using OSGeo.OSR;
using OSGeo.OGR;

namespace YourNamespace
{
    public class SomeLocation
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Point Location { get; } = new Point(40.1234, 1.4321) { SRID = 4326 };

        public Point LocationUpsNorth { get { return Wgs84ToWgs84UpsNorth(Location); } }


        private static NetTopologySuite.Geometries.Point Wgs84ToWgs84UpsNorth(Point location)
        {
            if (location.SRID != 4326)
                throw new Exception("Unsupported coordinate system: " + location.SRID);

            OSGeo.OSR.SpatialReference wgs84Src = new OSGeo.OSR.SpatialReference("");
            wgs84Src.ImportFromProj4("+proj=longlat +datum=WGS84 +no_defs");

            OSGeo.OSR.SpatialReference stereoNorthPoleDest = new OSGeo.OSR.SpatialReference("");
            stereoNorthPoleDest.ImportFromProj4("+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +datum=WGS84 +units=m +no_defs");

            OSGeo.OSR.CoordinateTransformation ct = new OSGeo.OSR.CoordinateTransformation(wgs84Src, stereoNorthPoleDest);

            double[] point = new double[3];
            point[0] = location.X;
            point[1] = location.Y;
            point[2] = location.Z;

            ct.TransformPoint(point);

            return new Point(point[0], point[1]);
        }
    }
}

<强>结果

Input: POINT (40.1234 1.4321)
Output: POINT (9944217.1796359234 -7426244.9918885585)

参考文献:

http://www.npgsql.org/efcore/mapping/nts.html

http://spatialreference.org/ref/epsg/32661/

https://github.com/NetTopologySuite/

https://github.com/NetTopologySuite/ProjNet4GeoAPI/blob/develop/ProjNet.Tests/CoordinateTransformTests.cs

https://gis.stackexchange.com/questions/61541/searching-for-c-code-to-convert-from-utm-to-wgs1984-and-back#61574