2017-06-15 54 views
1

我在MSSQL服務器中有一些WKT/WKB數據,並希望在在小冊子,Openlayer,OpenStreetMaps或GoogleAPI的幫助下繪製地圖。我的數據看喜歡這樣的:將MSSQL中用於Web映射(Leaflet,Openlayer,OpenStreetMaps,GoogleAPI,...)的投影更改爲WSG48或任何其他格式

POLYGON ((1736946.0983 5923253.9175, 1736895.6852 5923333.9451, 1736936.0082 5923356.6991, ......)) 
這種格式

EPSG:2193 

如下圖所示

enter image description here 並想將它們轉換爲

WGS48 or EPSG:4326 

我想將它們添加到傳單中,似乎我需要將此數據轉換爲適當的f ormat是這樣的:

[[42.353770, -71.103606], [42.355447, -71.104475], [42.362681, -71.089830], [42.361829, -71.079230]] 

Unfortuanlty,我不知道如何做這種轉換。

我試圖像這樣的

[1.]的一些方法。錯誤:

A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 
System.FormatException: 24201: Latitude values must be between -90 and 90 degrees. 

[2.]查詢:

select GEOGRAPHY::STPolyFromText ([stastxt],4326) from mytable 
Error: 
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 
System.FormatException: 24201: Latitude values must be between -90 and 90 degrees. 

[3.] 沒有成功

[4]我能夠看到這個數據作爲一個GeoServer的一層,當我設置Declared SRSEPSG:2193

經過對這個問題做了更多的研究, 的問題是:

可我只是做這個轉型MSSQL服務器或單張或我需要使用一些其他的工具,如Proj4net和替換「(」與「[」?

+1

您必須將這些座標重新映射到WGS84(EPSG:3857)的經緯度或[定義匹配的CRS](http://leafletjs.com/reference-1.0.3.html#crs)。這些座標來自哪個區域? – chrki

+0

感謝Chrki,新西蘭,我已經添加了更多信息給我的問題,將MSSQL中的'('轉換爲小冊子中的'['')? –

+0

當你說你在數據庫中有WKT時,我假設它只是存儲爲(根據你的嘗試將其轉換爲地理實例)從你從哪裏得到它?它看起來像我的幾何數據(而不是地理)。 –

回答

0

最後,我開發了一個有趣的解決方案,我會一步一步解釋我的解決方案,因爲我確信其他人面臨類似的問題。

第一點是要知道哪個投影數據是(src)和你想要的投影(dst)。通常,dst是EPSG:4326,EPSG:3857WGS48。對於這個解決方案,我需要找到正確的數學背後,所以我用這個網站 https://mygeodata.cloud/cs2cs/ 找到正確的格式爲src和dst(如果您熟悉R它有一個功能,這也稱爲spTransform)。另一個原因是我會使用Proj4組件進行這種轉換。另一個關鍵步驟是轉換爲GeoJson,因爲這些網絡地圖可以讀取GeoJson文件。我不想將數據寫入物理GeoJson文件,因此我在MSSQL上按需轉換(無需將它作爲GeoJson文件編寫)。

  1. 在C#中創建一個庫,並獲取一個DLL。
  2. 導入這MSSQL
  3. 享受它

的第一部分的代碼:經由金塊安裝DotSpatial

using Microsoft.SqlServer.Server; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 


public class classval 
{ 
    public string line; 
    public string src; 
    public string dst; 

    public classval(string line, string src, string dst) 
    { 
     this.line = line; 
     this.src = src; 
     this.dst = dst; 
    } 



} 

public class CLRProjection 
{ 
    private static IEnumerable<classval> ConvertedEnumerable(string line, string src, string dst) 
    { 
     return new List<classval> { new classval(line, src, dst) }; 
    } 

    [SqlFunction(FillRowMethodName = "FillRow")] 
    public static IEnumerable ToLatLong(string Geometry, string src, string dst) 
    { 
     return ConvertedEnumerable(Geometry, src, dst); 
    } 

    private static void FillRow(Object classvalobj, out string Geometry, out string srcprj, out string dstprj) 
    { 

     classval geomobj = (classval)classvalobj; 
     string _geometry = geomobj.line; //"POLYGON ((1736946.0983 5923253.9175,....))"; 
    string proj4_src = geomobj.src; //"+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs "; 
    string proj4_dst = geomobj.dst;//"+proj=longlat +datum=WGS84 +no_defs"; 
    _geometry = _geometry.Replace(",", " , "); 
    _geometry = _geometry.Remove(0, _geometry.IndexOf('(')); 
    _geometry = _geometry.Replace("(", "[ "); 
    _geometry = _geometry.Replace(")", " ]"); 
    string[] splitbycomma = _geometry.Split(','); 

    foreach (var itembycomma in splitbycomma) 
     { 

      string tmpitem = itembycomma; 
      tmpitem = tmpitem.Replace('[', ' '); 
      tmpitem = tmpitem.Replace(']', ' '); 
      tmpitem = tmpitem.Trim(); 
      string[] splitbyspace = tmpitem.Split(' '); 
      for (int ibs = 0; ibs < splitbyspace.Length - 1; ibs++) 
      { 

       double[] x = { double.Parse(splitbyspace[ibs]) }; 
       double[] y = { double.Parse(splitbyspace[ibs + 1]) }; 
       double[] z = new double[x.Length]; 
       //rewrite xy array for input into Proj4 
       double[] xy = new double[2 * x.Length]; 
       int ixy = 0; 
       for (int i = 0; i <= x.Length - 1; i++) 
       { 
        xy[ixy] = x[i]; 
        xy[ixy + 1] = y[i]; 
        z[i] = 0; 
        ixy += 2; 
       } 
       double[] xy_geometry = new double[xy.Length]; 
       Array.Copy(xy, xy_geometry, xy.Length); 



       DotSpatial.Projections.ProjectionInfo src = 
        DotSpatial.Projections.ProjectionInfo.FromProj4String(proj4_src); 
       DotSpatial.Projections.ProjectionInfo trg = 
        DotSpatial.Projections.ProjectionInfo.FromProj4String(proj4_dst); 

       DotSpatial.Projections.Reproject.ReprojectPoints(xy, z, src, trg, 0, x.Length); 


       ixy = 0; 
       for (int i = 0; i <= x.Length - 1; i++) 
       { 
       _geometry = _geometry.Replace(xy_geometry[ixy].ToString() + " ", "[" + xy[ixy + 1].ToString() + " , "); 
       _geometry = _geometry.Replace(xy_geometry[ixy + 1].ToString() + " ", xy[ixy].ToString() + " ] "); 
       _geometry = _geometry.Replace("- ", "-"); 
        string tt = (i + 1 + " " + xy[ixy] + " " + xy[ixy + 1]); 

        ixy += 2; 
       } 

      } 
     } 
    _geometry = _geometry.Replace(" ", " "); 
    _geometry = _geometry.Replace(" [ ", "["); 
    _geometry = _geometry.Replace(" ] ", "]"); 
    _geometry = _geometry.Replace(" , ", ","); 
    srcprj = proj4_src; 
    dstprj = proj4_dst; 
    Geometry = _geometry; 
    } 

} 

用於第二部分的代碼(內部MSSQL)

ALTER DATABASE test SET trustworthy ON 
CREATE ASSEMBLY CLRFunctionAssem 
FROM N'C:\Users\...\bin\Debug\Convertor_Projection.dll' 
WITH PERMISSION_SET = UNSAFE 
GO 


CREATE FUNCTION dbo.ToLatLong(@Geometry nvarchar(max), @src nvarchar(max),@dst nvarchar(max)) 
RETURNS TABLE 
(_geom nvarchar(max) ,srcprj nvarchar(max) ,dstprj nvarchar(max) 
) with execute as caller 
AS 
EXTERNAL NAME CLRFunctionAssem.[CLRProjection].[ToLatLong] 

MSSQL代碼

SELECT  
    [parcelid] 
    ,[Geom1] 
    ,[stastxt] 
    ,conv._geom 

FROM [test].[dbo].[TEST_JSON] as a CROSS APPLY dbo.ToLatLong (a. 
[stastxt],'+proj=tmerc +lat_0=0 +lon_0=173 +k=0.9996 +x_0=1600000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs','+proj=longlat +datum=WGS84 +no_defs') as conv 
where [stastxt] is not null 

MSSQL2016有JSON functiality,而舊版本沒有這種能力。

輸出 enter image description here

資源,這讓我有:

123

1

你可以使用插件Proj4Leaflet做在單張轉換。

+0

這是一個比我的更快的解決方案,但不會改變([也不會改變long和lat訂購。 –