EntityFrameworkCore.PostgreSQL Transform point - c#

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

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

Related

How to convert between TFM (Target framework moniker) and FrameworkName?

E.g.
netstandard2.0 (from Supported target frameworks) which is used as <TargetFramework> in *.csproj files or as folder name in NuGet packages internal structure,
and
.NETStandard,Version=v2.0 which is accepted by System.Runtime.Versioning.FrameworkName class's constructor or can be a value of TargetFrameworkAttribute.FrameworkName.
How to convert those strings from one form to another? At least one (any) direction.
You can use the source code of NuGet.Frameworks:
Here is the method that converts TFM to FrameworkName:
https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Frameworks/NuGetFrameworkFactory.cs#L575
(e.g. netstandard2.0 to .NETStandard,Version=v2.0)
UPDATE #1
The good news is that it is available as a NuGet package:
https://www.nuget.org/packages/NuGet.Frameworks/
Here is a .NET 6 Console Application:
using NuGet.Frameworks;
using System.Runtime.Versioning;
var tfmNetstandard20 = NuGetFramework.ParseFolder("netstandard20");
var fwNetstandard20 = new FrameworkName(tfmNetstandard20.DotNetFrameworkName);
Console.WriteLine(tfmNetstandard20);
Console.WriteLine(fwNetstandard20);
The output will be:
.NETStandard,Version=v2.0
.NETStandard,Version=v2.0

Talking to SQL Integration Services with C#

I want to import and export SSIS packages (.DTSX files) on a SQL Server with a C# program. I found information on an "Integration Services" class, but I'm not seeing any methods related to exporting or importing packages. Is this the correct class? If not, where should I be looking?
https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.management.integrationservices.integrationservices?view=sqlserver-2017
public ref class IntegrationServices
It turned out to be what user #SMor suggested, the Application class of the Microsoft.SqlServer.Dts.Runtime namespace.
https://learn.microsoft.com/en-us/sql/integration-services/run-manage-packages-programmatically/enumerating-available-packages-programmatically?view=sql-server-2017
These two objects give you most of what you need:
Application ssisApplication;
PackageInfos sqlPackages;
I can get the list of packages with that class. Now I'm just working on how to actually do the imports/exports.
Sample code for Package export from SQL to File.
using Microsoft.SqlServer.Dts.Runtime;
public void pkgExtract()
{
// ...
Application app = new Application();
var events = new PackageEvents();
Package package = app.LoadFromSqlServer(packageName, server, etl.UserName, etl.Password, events);
// ...
string Package_File = #"C:\\Temp\ExportPkg.dtsx"
app.SaveToXml(Package_File, package, null);
}
For reverse directrion - you can use LoadPackage and SaveToSQLServer methods.

How can I list all local packages in the NuGet v3 API

For context, I'm building an application that needs to download/unpack packages and their dependencies from arbitrary package sources (including the public gallery by default) and upgrade those packages to the latest version when requested. There are no project.json files or similar, it's all code driven. It's not a particularly complicated use case and didn't require too much code in the v2 APIs.
In v3 however, I can't figure out how to correctly interact with the local package store. For example, the FolderNuGetProject class that I would have thought lists all the packages on disk at a given location in FolderNuGetProject.GetInstalledPackagesAsync() just returns an empty enumerable. To make matters more confusing, FolderNuGetProject.PackageExists() actually does return whether the package exists on disk, which means GetInstalledPackagesAsync() and PackageExists() appear to be inconsistent.
None of the other NuGetProject derivatives appear related to the file system. Is there some other way of listing the packages that have been installed into a particular folder? If I need to create my own NuGetProject (and I'm hoping I don't), are there any methods that will help with parsing NuGet-generated folder names into package IDs and versions, or is the only reliable way of getting the ID and version to open the nuspec (and are there any easy to find methods for that)?
One interpretation of why this isn't working as I expect is that NuGetProject.GetInstalledPackagesAsync() isn't actually intended to get the installed packages (I.e., those that have been downloaded and unpacked), but rather those that have been declared in whatever project system is in use. For example, the BuildIntegratedNuGetProject class appears to return package references for the packages in the project.json, regardless of their status on disk. That would also explain why FolderNuGetProject just returns an empty enumerable, because there are no "declared" packages if you're just looking at the local repository.
TL;DR: What is the best way to crawl the local package store and get the packages and versions that are present there?
(this was also issue #2664 on the NuGet GitHub project, but was moved here by request)
Introduction
I have the same question and I looked your post on GitHub, Google and here. I try a lot of things to find the local packages.
I found some solutions, but I don't know if it's the best way to do it.
I posted a question about local packages too, because I can list all local packages, but I can't have the AssemblyReferences property (dll).
Code example
var rootPath = #"pathWhereNuGetPackagesAre";
var logger = new Logger();
List<Lazy<INuGetResourceProvider>> providers = new List<Lazy<INuGetResourceProvider>>();
providers.AddRange(Repository.Provider.GetCoreV3());
FindLocalPackagesResourceV2 findLocalPackagev2 = new FindLocalPackagesResourceV2(rootPath);
var packageFound = findLocalPackagev2.GetPackages(logger, CancellationToken.None).FirstOrDefault();
//found, but missing a lot of informations...
var supportedFramework = new[] { ".NETFramework,Version=v4.6" };
var searchFilter = new SearchFilter(true)
{
SupportedFrameworks = supportedFramework,
IncludeDelisted = false
};
// The trick here is to put the local nuget path, not using the URL : https://api.nuget.org/v3/index.json
PackageSource localSource = new PackageSource(rootPath);
SourceRepository localRepository = new SourceRepository(localSource, providers);
PackageSearchResource searchLocalResource = await localRepository
.GetResourceAsync<PackageSearchResource>();
var packageFound3 = await searchLocalResource
.SearchAsync("Newtonsoft.Json", searchFilter, 0, 10, logger, CancellationToken.None);
var thePackage = packageFound3.FirstOrDefault();
// found but missing the assemblies property
public class Logger : ILogger
{
private List<string> logs = new List<string>();
public void LogDebug(string data)
{
logs.Add(data);
}
public void LogVerbose(string data)
{
logs.Add(data);
}
public void LogInformation(string data)
{
logs.Add(data);
}
public void LogMinimal(string data)
{
logs.Add(data);
}
public void LogWarning(string data)
{
logs.Add(data);
}
public void LogError(string data)
{
logs.Add(data);
}
public void LogInformationSummary(string data)
{
logs.Add(data);
}
public void LogErrorSummary(string data)
{
logs.Add(data);
}
}
Hope this will help!
In Visual Studio, Open package manager console.
List local (installed) packages use following command.
Get-Package
You can list all available packages on feed with following command
Get-Package -ListAvailable
If this commands are not working, check "Packege Manager Settings"->"Package Source" and confirm nuget feed configured correctly. (If you dont see your feed URL, You should add your feed there.) for details: Consume nuget package from VS
You can also check nuget feed configuration from this file
C:\Users{{user}}\AppData\Roaming\NuGet\NuGet.config
for more details about nuget config file: nuget config file
Also, Local nuget packages should ve stored at this path
C:\Users{{user}}.nuget\packages

How can I add SQLite3.dll to my Project?

I'm building an WPF C# Application with an embedded SQLite Database.
But when I debug it I always get an exception of type 'SQLite.SQLiteException'.
using System.Collections.Generic;
using System.Linq;
using SQLite;
using System.Collections;
namespace SheepMaster
{
class SheepDao : IEnumerable
{
private List<Sheep> sheeps { get; set; }
private SQLiteConnection con = new SQLiteConnection("sheeps.db");
public SheepDao()
{
con.CreateTable<Sheep>();
sheeps = con.Table<Sheep>().ToList();
}
public IEnumerator GetEnumerator()
{
return sheeps.GetEnumerator();
}
public void add(Sheep value)
{
sheeps.Add(value);
}
}
}
When I try to install sqlite from nuget I am getting the following error message:
Could not install package 'sqlite.redist 3.8.4.2'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
and when I manually install it I get this message:
A reference to path could not be added...
System.Data.SQLite
I installed it trought nuget but it didn't change anything.
Either download and install sqlite3.dll from: http://sqlite.org/download.html
or Find on nuget package SQLite v3.13.

Setting Sqlite ThreadingMode when using sqlite-net + async

I'm trying to set Sqlite ThreadMode to Serialized in my Xamarin.iOS project. Using classic Sqlite, one finds this method on the connection class:
SqliteConnection.SetConfig(SQLiteConfig.Serialized);
However I'm using sqlite-net (+async) and can't find a way to set this configuration property.
Any suggestions?
Ok, I had to update SQLite-Net (and SQLite-Net-PCL etc) to 2.5.
Then this option can be accessed through the platform specific implementation:
public Repository(IPlatform platform)
{
_platform = platform;
_platform.SqlitePlatform.SQLiteApi.Config(ConfigOption.Serialized);
_db = new SQLiteAsyncConnection(() =>
new SQLite.Net.SQLiteConnectionWithLock(
_platform.SqlitePlatform,
new SQLite.Net.SQLiteConnectionString(_platform.DatabasePath, true)));
}

Categories

Resources