EntityFrameworkCore.PostgreSQL Transform point

.net-core c# entity-framework-core postgis postgresql

Question

Is there a way to Transform a point to another SRID using EntityFrameworkCore?

previously I used ST_Transform(ST_GeomFromText(@coord,4326),32661)

My current code looks like this

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

The SRID of the coord is 4326 and needs to become 32661 This is done for backwards compatibility reasons and there is no option converting the database to another SRID

Is there a geometry library or a PostGIS EntityFrameworkCore method to transform a point to another SRID

1
2
5/25/2018 6:35:33 AM

Accepted Answer

The release version Npgsql.EntityFrameworkCore.PostgreSQL Entity Framework Core provider for PostgreSQL does not support spatial types.

The good news is that spatial types support and support for some spatial operations SQL translations are already available as a pre-release candidate.

If you want to use these libraries, you need to also use the pre-realease candidate version of Entify Framework Core.

First, uninstall your existing entity framework or npgsql packages.

One of the packages needed (GeoAPI) is not available in the standard NuGet source so we are gonna use the myget.org source.

To use it, you need to add a new NuGet source in Visual Studio by going to Tools -> Options -> NuGet Package Manager -> Packages Sources

Create a new source and name it myget.org and use the following URL in the source text field:

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

Remember to click on update to save the changes, otherwise they are not saved (weird, I know).

To add the required packages, use the Package Manager Console (View -> Other Windows -> Package Manager Console) and select myget.org from the Package Source drop down, then, execute the following commands:

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

Once your packages are installed, in your DbContext class, override OnConfiguring to add the UseNetTopologySuite option:

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

To make sure that the extension is supported by your database add the following to your DbContext:

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

Now you should be able to use PostgreSql spatial types and translate some operations to SQL, (e.g. ST_Area, ST_Contains, ST_As_Text, etc.).

The whole list of supported operations and how to use them in your EF queries is available here: http://www.npgsql.org/efcore/mapping/nts.html#operation-translation

Unfortunately ST_Transform or ST_Project do not seem to be supported as of now, but there is a link in the Website above where you can contact the developers and request them to be added.

In the meantime, you can use GDAL to transform the projection of your coordinates.

Install the package:

Install-Package Gdal.Core -Version 1.0.0

This package provides a multi-platform wrapper for GDAL for .NET core so you need to install the libraries and they should be accessible by your program.

You can find binaries for Windows and Linux here: https://trac.osgeo.org/gdal/wiki/DownloadingGdalBinaries

If you are using Windows you can use the following installer: http://download.osgeo.org/osgeo4w/osgeo4w-setup-x86_64.exe

Just select "Express Desktop Install" and GDAL in the "Select Packages" window.

By default the needed libraries are installed in C:\OSGeo4W64\bin.

You need to add this folder to your system path and restart Visual Studio.

By the way, to convert the coordinates, from all the libraries in C:\OSGeo4W64\bin I think you only need proj.dll so may be you can include this in your project (make sure it is copied to the output of your project) and then it should work and you don't need to install GDAL.

Here is an example of how to use it for the coordinate systems provided in your question:

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

Result

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

References:

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

2
5/30/2018 7:51:15 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow