Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Transformer/Projeter une géométrie d'un SRID à un autre

Vous pouvez encapsuler quelque chose comme DotNetCoords dans une fonction SQL CLR pour ce faire.

Voir ici :- http://www.doogal.co.uk/dotnetcoords.php

Je l'ai enveloppé dans une fonction CLR pour convertir les coordonnées de Easting/Northing en Lat/Long, ce que je pense être ce que vous demandez. Une fois la fonction CLR implémentée, il s'agit d'une solution SQL pure (c'est-à-dire que vous pouvez tout exécuter dans une procédure stockée ou une vue).

MODIFIER :Je posterai un exemple de code ici quand j'arriverai au travail demain, j'espère que cela aidera.

MODIFIER :Vous devrez télécharger le code source depuis http://www.doogal.co. fr/dotnetcoords.php et vous aurez besoin de Visual Studio pour l'ouvrir et le modifier. La documentation de la bibliothèque est ici http://www.doogal.co.uk/Help /

Ce que vous pouvez faire ensuite, c'est ajouter une nouvelle classe aux fichiers source de la manière suivante :-

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

}

Vous devrez ensuite créer et importer l'assembly dans SQL Server (remplacez les chemins par vos propres emplacements) (pour une raison quelconque, je ne parviens pas à installer l'assembly lorsque PERMISSION_SET est 'SAFE', donc je voudrais d'abord trier cela avant d'installer dans un environnement de production ).

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

Vous devrez ensuite créer une fonction SQL Server pour s'interfacer avec la fonction CLR :-

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]

Il s'agit de la fonction CLR installée alors.

Vous devriez alors être en mesure d'appeler la fonction directement depuis SQL Server pour effectuer votre conversion (j'ai mélangé les chiffres dans cet article pour garder l'anonymat afin qu'ils n'aient peut-être pas de sens ici, mais la fonction fonctionne bien).

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

(1 row(s) affected)

Pour l'utiliser dans un jeu de résultats, vous devez utiliser la clause CROSS APPLY :-

/*------------------------
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)