sql >> Base de Datos >  >> RDS >> Sqlserver

Transformar/Proyectar una geometría de un SRID a otro

Podría envolver algo como DotNetCoords en una función SQL CLR para hacer esto.

Consulte aquí:- http://www.doogal.co.uk/dotnetcoords.php

Lo envolví en una función CLR para convertir coordenadas de Easting/North a Lat/Long, que creo que es lo que está pidiendo. Una vez que se implementa la función CLR, es una solución SQL pura (es decir, puede ejecutarlo todo en un Procedimiento almacenado o Vista).

EDITAR :Publicaré un código de muestra aquí cuando llegue al trabajo mañana, espero que ayude.

EDITAR :deberá descargar el código fuente de http://www.doogal.co. es/dotnetcoords.php y necesitará Visual Studio para abrirlo y modificarlo. La documentación de la biblioteca está aquí http://www.doogal.co.uk/Help /

Lo que puede hacer entonces es agregar una nueva clase a los archivos fuente similar a esta:-

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

}

Luego deberá compilar e importar el ensamblaje en SQL Server (reemplazar las rutas con sus propias ubicaciones) (por alguna razón, no puedo instalar el ensamblaje cuando PERMISSION_SET es 'SEGURO', por lo que ordenaría esto primero antes de instalarlo en un entorno de producción ).

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

Luego deberá crear una función de SQL Server para interactuar con la función 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]

Esta es la función CLR instalada entonces.

Entonces debería poder llamar a la función directamente desde SQL Server para hacer su conversión (he mezclado los números en esta publicación para mantener el anonimato, por lo que es posible que no tengan sentido aquí, pero la función funciona bien).

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

(1 row(s) affected)

Para usarlo en un conjunto de resultados, debe usar la cláusula 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)