Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Transformieren/Projizieren Sie eine Geometrie von einem SRID zu einem anderen

Sie könnten dazu etwas wie DotNetCoords in eine SQL CLR-Funktion packen.

Siehe hier:- http://www.doogal.co.uk/dotnetcoords.php

Ich habe es in eine CLR-Funktion gepackt, um Koordinaten von Easting/Northing in Lat/Long zu konvertieren, was meiner Meinung nach das ist, wonach Sie fragen. Sobald die CLR-Funktion implementiert ist, handelt es sich um eine reine SQL-Lösung (d. h. Sie können alles in einer gespeicherten Prozedur oder Ansicht ausführen).

BEARBEITEN :Ich werde einen Beispielcode hier oben posten, wenn ich morgen zur Arbeit komme, hoffentlich hilft es.

BEARBEITEN :Sie müssen den Quellcode von http://www.doogal.co herunterladen. de/dotnetcoords.php und Sie benötigen Visual Studio, um es zu öffnen und zu ändern. Dokumentation für die Bibliothek finden Sie hier http://www.doogal.co.uk/Help /

Was Sie dann tun können, ist, dass Sie den Quelldateien eine neue Klasse hinzufügen können, ähnlich wie hier:-

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.SqlTypes;
using DotNetCoords;
using Microsoft.SqlServer.Server;

/// <summary>
/// Sql Server CLR functions for the DotNetCoords library.
/// </summary>
public class CLRFunctions
{

    /// <summary>
    /// Coordinateses the enumerable.
    /// </summary>
    /// <param name="Easting">The easting.</param>
    /// <param name="Northing">The northing.</param>
    /// <returns></returns>
    private static IEnumerable<OSRef> CoordinatesEnumerable(double Easting, double Northing)
    {
        return new List<OSRef> { new OSRef(Easting,Northing) };
    }

    /// <summary>
    /// Toes the lat long.
    /// </summary>
    /// <param name="Easting">The easting.</param>
    /// <param name="Northing">The northing.</param>
    /// <returns></returns>
    [SqlFunction(FillRowMethodName = "FillRow")]
    public static IEnumerable ToLatLong(double Easting, double Northing)
    {
        return CoordinatesEnumerable(Easting, Northing);
    }

    /// <summary>
    /// Fills the row.
    /// </summary>
    /// <param name="obj">The obj.</param>
    /// <param name="Lat">The lat.</param>
    /// <param name="Long">The long.</param>
    private static void FillRow(Object obj, out SqlDouble Lat, out SqlDouble Long)
    {
        OSRef Coordinates = (OSRef)obj;
        LatLng latlong = Coordinates.ToLatLng();
        latlong.ToWGS84();
        Lat = new SqlDouble(latlong.Latitude);
        Long = new SqlDouble(latlong.Longitude);
    }

}

Sie müssen dann die Assembly erstellen und in SQL Server importieren (Pfade durch Ihre eigenen Speicherorte ersetzen) (aus irgendeinem Grund kann ich die Assembly nicht installieren, wenn PERMISSION_SET 'SAFE' ist, also würde ich dies zuerst sortieren, bevor ich in einer Produktionsumgebung installiere ).

CREATE ASSEMBLY DotNetCoords
FROM N'C:\Projects\DotNetCoords\bin\Debug\DotNetCoords.dll'
WITH PERMISSION_SET = UNSAFE
GO

Anschließend müssen Sie eine SQL Server-Funktion als Schnittstelle zur CLR-Funktion erstellen:-

CREATE FUNCTION dbo.ToLatLong(@Easting float, @Northing float)
RETURNS TABLE
(Latitude float null, Longitude float null) with execute as caller
AS
EXTERNAL NAME [DotNetCoords].[CLRFunctions].[ToLatLong]

Dies ist die dann installierte CLR-Funktion.

Sie sollten dann in der Lage sein, die Funktion direkt von SQL Server aufzurufen, um Ihre Konvertierung durchzuführen (ich habe die Zahlen in diesem Beitrag verwechselt, um die Anonymität zu wahren, sodass sie hier möglicherweise keinen Sinn ergeben, aber die Funktion funktioniert einwandfrei).

/*------------------------
SELECT Latitude, Longitude FROM dbo.ToLatLong(327262, 357394)
------------------------*/
Latitude            Longitude
52.13413530182533       -9.34267170569508

(1 row(s) affected)

Um es in einer Ergebnismenge zu verwenden, müssen Sie die CROSS APPLY-Klausel verwenden:-

/*------------------------
SELECT TOP 2    a.[Column 0] AS osaddessp,
                            a.[Column 9] AS east,
                            a.[Column 10] AS north,
                            c.[Latitude] AS lat,
                            c.[Longitude] AS long
FROM    MyTable AS a CROSS APPLY ToLatLong (a.[Column 9], a.[Column 10]) AS c;
------------------------*/
osaddessp       east    north   lat         long
100134385607    327862  334794  52.3434530182533    -2.19342342569508
100123433149    780268  353406  52.3453417606796    -3.19252323679263

(10 row(s) affected)