2012-05-08 6 views
6

मेरे पास एक डेटाबेस तालिका है जिसमें वर्तमान में एसआरआईडी 27700 (ब्रिटिश नेशनल ग्रिड) में ज्यामितीय डेटा है। डेटा को पुनर्प्राप्त करते समय मुझे इसे SRID 4326 (WGS84) में बदलने की आवश्यकता है। क्या मुझे परिणाम प्राप्त करने के लिए पोस्टजीआईएस में मिले ST_Transform जैसे फ़ंक्शन को लागू करने का कोई तरीका है?एक एसआरआईडी से दूसरे में एक ज्यामिति को ट्रांसफॉर्म/प्रोजेक्ट करें

नोट: समाधान को टी-एसक्यूएल और संग्रहीत प्रक्रियाओं आदि का उपयोग करके कार्यान्वित करने में सक्षम होना आवश्यक है। मुझे एक कथन बनाने में सक्षम होना चाहिए और बाद में पुनर्प्राप्ति के लिए स्ट्रिंग फ़ील्ड के रूप में इसे तालिका में सहेजना होगा। ऐसा इसलिए है क्योंकि मेरा समाधान डेटाबेस अज्ञेयवादी है।

select CLUSTER_ID, 
     NUM_POINTS, 
     FEATURE_PK, 
     A.CELL_CENTROID.SDO_POINT.X, 
     A.CELL_CENTROID.SDO_POINT.Y, 
     A.CLUSTER_CENTROID.SDO_POINT.X, 
     A.CLUSTER_CENTROID.SDO_POINT.Y, 
     TO_CHAR (A.CLUSTER_EXTENT.GET_WKT()), 
     TO_CHAR (A.CELL_GEOM.GET_WKT()), 
     A.CLUSTER_EXTENT.SDO_SRID 
from (SELECT CLUSTER_ID, 
      NUM_POINTS, 
      FEATURE_PK, 
      SDO_CS.transform (CLUSTER_CENTROID, 4326) cluster_centroid, 
      CLUSTER_EXTENT, 
      SDO_CS.transform (CELL_CENTROID, 4326) cell_centroid, 
      CELL_GEOM FROM :0) a 
where sdo_filter(A.CELL_GEOM, 
        SDO_CS.transform(mdsys.sdo_geometry(2003, :1, NULL, mdsys.sdo_elem_info_array(1,1003,3),mdsys.sdo_ordinate_array(:2, :3, :4, :5)),81989)) = 'TRUE' 

PostgreSQL PostGIS का उपयोग कर में मैं इस तरह यह कर रहा हूँ:

select CLUSTER_ID, 
     NUM_POINTS, 
     FEATURE_PK, ST_X(a.CELL_CENTROID), 
     ST_Y(a.CELL_CENTROID), 
     ST_X(ST_TRANSFORM(a.CLUSTER_CENTROID, 4326)), 
     ST_Y(ST_TRANSFORM(a.CLUSTER_CENTROID, 4326)), 
     ST_AsText(a.CLUSTER_EXTENT), 
     ST_AsText(a.CELL_GEOM), 
     ST_SRID(a.CLUSTER_EXTENT) 
FROM (SELECT CLUSTER_ID, 
     NUM_POINTS, 
     FEATURE_PK, 
     ST_TRANSFORM(ST_SetSRID(CLUSTER_CENTROID, 27700), 4326) cluster_centroid, 
     CLUSTER_EXTENT, 
     ST_TRANSFORM(ST_SetSRID(CELL_CENTROID, 27700), 4326) cell_centroid, 
     CELL_GEOM 
from :0) AS a 
where ST_Intersects(ST_Transform(ST_SetSRID(a.CELL_GEOM, 27700), :1), ST_Transform(ST_GeomFromText('POLYGON(('||:2||' '||:3||', '||:4||' '||:3||', '||:4||' '||:5||', '||:2||' '||:5||', '||:2||' '||:3||'))', 4326), :1)) 

उत्तर

7

तुम एक में DotNetCoords की तरह कुछ लपेट सकता है

तरह से मैं वर्तमान में Oracle में यह कर रहा हूं इस प्रकार है ऐसा करने के लिए एसक्यूएल सीएलआर समारोह।

यहाँ देखें: - http://www.doogal.co.uk/dotnetcoords.php

मैं एक CLR समारोह में लपेटा गया है अक्षांश/लांग जो मुझे लगता है कि आप क्या कह रहे हैं है पूर्व की ओर/उत्तर की ओर से निर्देशांक परिवर्तित करने के लिए। एक बार सीएलआर फ़ंक्शन लागू हो जाने पर यह एक शुद्ध SQL समाधान है (यानी आप इसे संग्रहीत प्रक्रिया या दृश्य में चला सकते हैं)।

संपादित करें: कल मैं काम करने के लिए यहां कुछ नमूना कोड पोस्ट करूंगा, उम्मीद है कि इससे मदद मिलेगी।

EDIT: आपको http://www.doogal.co.uk/dotnetcoords.php से स्रोत कोड डाउनलोड करने की आवश्यकता होगी और आपको इसे खोलने और संशोधित करने के लिए विजुअल स्टूडियो की आवश्यकता होगी। पुस्तकालय के लिए प्रलेखन यहाँ है http://www.doogal.co.uk/Help/Index.html

क्या आप तो कर सकते हैं आप स्रोत के लिए एक नया वर्ग जोड़ सकते हैं इस के समान फाइलें: -

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

} 

फिर आप का निर्माण और में विधानसभा आयात करने की आवश्यकता होगी एसक्यूएल सर्वर (अपने स्थानों के साथ पथों को प्रतिस्थापित करें) (किसी कारण से मैं विधानसभा को स्थापित नहीं कर सकता जब PERMISSION_SET 'सुरक्षित' है, इसलिए मैं इसे उत्पादन वातावरण में स्थापित करने से पहले इसे सॉर्ट करूंगा)।

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

फिर आप 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] 

यह CLR समारोह तो स्थापित है।

आपको अपने रूपांतरण को करने के लिए सीधे SQL सर्वर से फ़ंक्शन को कॉल करने में सक्षम होना चाहिए (मैंने इस पोस्ट में संख्याओं को मिश्रित भी किया है, इसलिए वे यहां समझ में नहीं आ सकते हैं लेकिन फ़ंक्शन ठीक काम करता है)।

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

(1 row(s) affected) 
एक resultset में उसका उपयोग करने

आप क्रॉस खंड लागू उपयोग करने की आवश्यकता: -

/*------------------------ 
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 
10.3453417606796 -3.19252323679263 

(10 row(s) affected) 
+1

हालांकि यह वर्तमान में मेरी स्थिति में अनचाहे है, लेकिन यह मेरी समस्या का सबसे अच्छा समाधान प्रतीत होता है जो मैं अब तक आया हूं और मैं इसे लागू करने में कोई समस्या नहीं देख सकता। इसे पोस्ट करने के लिए समय लेने के लिए धन्यवाद। मैंने आपको बक्षीस दिया है। – CSharpened

+2

धन्यवाद, मेरे पास आगे देखने के लिए समय था, लेकिन लाइब्रेरी के सभी कार्यों को सीएलआर कार्यों के रूप में कार्यान्वित करना अच्छा होगा और इसे सॉर्ट करें ताकि यह 'सुरक्षित' पेस्मिशन के साथ स्थापित हो। –

2

दुर्भाग्य से, यह बस संभव नहीं है।एसक्यूएल सर्वर स्थानिक उपकरण कुछ अपवर्तन कार्यों को प्रदान करते हैं, लेकिन वे केवल अनुमानों की बहुत कम संख्या के लिए हैं (और आपको आवश्यकता नहीं है)।

example from SQL server tools - https://bitbucket.org/geographika/sql-server-spatial-tools/src/5ca44b55d3f3/SQL%20Scripts/projection_example.sql है - लेकिन यह आपकी सहायता नहीं करेगा क्योंकि वे उस प्रक्षेपण का समर्थन नहीं करते हैं जिसके बारे में आप बात कर रहे हैं।

तो, आपको एक अलग समाधान अपनाने की आवश्यकता होगी - या तो अनुमानित मानों के साथ एक नया कॉलम जोड़ने के लिए डेटा को प्री-प्रोसेस करें या अपने कोड में दोबारा डालें।

संबंधित मुद्दे