再び地図をテーブルに引き込んだ方法

繰り返しますが、何とか2年以上前にすでにこの演習を行っていたからです。 それは長くて骨の折れるプロセスでした:

blogs.technet.com/b/isv_team/archive/2010/01/18/3306462.aspx

blogs.technet.com/b/isv_team/archive/2010/01/21/3307201.aspx

blogs.technet.com/b/isv_team/archive/2010/01/23/3307719.aspx

blogs.technet.com/b/isv_team/archive/2010/01/24/3307804.aspx

それ以来、科学は大きく前進しました。 この投稿では、広大な祖国の地図を再びSQL Serverにアップロードします。今回は、地図の作成者、新しいSQL Server機能、独立した開発者に感謝します。 必要なもの:



1.適切なカード

2. SQL Server 2012(Expressは可能)

3.マップを元の形式からSQL Serverに変換するツール。



作業の大部分は、デンマークのMVP MortenØdegaardNielsenによって書かれたすばらしい無料のShape2SQLユーティリティによって行われます。ESRIのGISリードソフトウェアエンジニアと協力して、神に健康を与えてください。 ESRI(Environmental Systems Research Institute)は、ロシアでも広く使用されているソフトウェア製品のArcGISファミリで知られています。 ベクター形式のファイル形式は 、90年代初頭にArcView GISバージョン2に導入されました 、今日では、その人気により、地理情報システム間のデータ交換の事実上の標準となっています。 名前が示すように、TulaはSQL Server 2008以降でシェイプファイルをロードできます。 2012年は、この記事で使用された幾何学的/地理的集合体のサポートのためにこの記事で使用されています-それは後で便利になります。 2008年には、カーソルを作成する必要がありました。

注1. SQL Serverの.shpインポートユーティリティに加えて、 SharpGIS WebサイトのSqlSpatialTools v1.3.0(348 kb)(ビルド3759)には、地理的パネルよりも機能が豊富なSqlSpatial Query Toolマップレンダリングクライアントが含まれています。 SSMSの結果。

注2.両方のツールは、著者が警告しているように、商用利用を目的としていないため、 彼自身のニーズや喜びのために彼によって書かれました。

注3.シェイプファイルを解析できるオープンソースの.NETライブラリは、 ここにあります



ロシア連邦の行政領土部門の形状ファイルを見つけることは残っています。 .shpを含むさまざまな形式のロシア地域の地図がGIS-Labウェブサイトで見つかりまし :このレイヤーはCC-BYの下でライセンスされており、作成、利用可能性に応じて、転送、修正、商用プロジェクトでの使用など、あらゆる使用を許可しますハイパーリンク。 マップのデータソースは、連邦政府登録、Cadastre and Cartography Service( Rosreestr )-エンティティの境界、OpenStreerMap Russia( OSM )-ロシアの国境、カリーニングラード地域+モスクワの国境、 VMap0-カリーニングラード地域とイニシアチブグループの国境GIS-Lab.infoプロジェクト。彼はこれについても深く感謝しています。

GIS-Labカードは、WGS 1984(GPS)、Pulkovo-1942、Albers-Siberiaの3つのプロジェクションで提供されます。 ロシアの領土を表示するには、3番目が最適です。





図1



最初の2つより:





図2



残念ながら、sys.spatial_reference_systemsでは、中央子午線= 1050東のアルバートの等しい円錐投影を見つけることができませんでした Krasovsky回転楕円体に基づいているため、ジオメトリとしてSQL Serverにドラッグして、たとえばレポートを視覚化する手段として使用できます。 最初の2つは地理タイプ(SRID = 4326、4284)にインポートされ、カートグラフィック計算に使用できます。



マップをインポートするには、3つのファイルが必要です。





図3



.shp / .shxファイルは、上記のShape2SQLランタイムツールに送られます。 形状ファイルの完全な名前、SQL Serverへの接続、形状ファイルからデータがインポートされるテーブルの名前、テーブル内の地理空間列の名前、主キーとして機能する列の名前が示されます。 テーブルが存在しなかった場合、作成されます。 地理学としてAlbers Siberiaプロジェクションにデータをインポートすると失敗する SQL ServerはそのようなSRIDを認識せず、座標を誤って変換します-データの投影または範囲はSqlGeographyタイプでサポートされる範囲を超えているため、ジオメトリとしてインポートします。 必要に応じて、地理空間インデックスをすぐに構築できます。 [データベースにアップロード]ボタンをクリックすると、dbo.regions2010_albsibテーブルが正常に作成され、データが入力されます。





図4



select * from rfmap.dbo.regions2010_albsib



、SSMSの[空間結果]タブですべてがselect * from rfmap.dbo.regions2010_albsib



を確認できます(図1を参照)。 ただし、表のエントリ数はロシアの地域の数をわずかに超えています。 問題を理解するには、3つ目のファイルdbfが必要です。このファイルには、マップのメタデータが含まれています。 SQL Serverでdbfをロードする方法については、 以前の投稿で説明しました 。 テーブルを作成する



CREATE TABLE dbo.regions2010_captions (

ID int IDENTITY(1,1) NOT NULL,

AREA float NULL,

PERIMETER float NULL,

region varchar(50) NULL

)








インポート/エクスポートウィザードを使用します。 原則として、ソースと宛先のフィールドを同じ名前に自動的に関連付けますが、もう一度クリックしてこれを確認できます





図5



リージョンフィールドの長さが事前にわからない場合、つまり dbfリーダーは手元になく、バイナリエディターで怠withにヘッダーを解析し、最大長を設定し、インポート後にカットできます。 dbfのインポートが成功し、SQL Serverデータベース内のカートグラフィックオブジェクトのテーブルと共に、それらの署名のテーブルが表示されます。





図6



マップオブジェクトの領域2010_albsibのテーブルのレコードは、物理的な順序によって排他的に署名の領域2010_captionsのテーブルに関連付けられています。 インポート/エクスポートウィザードがdbfの場合と同じ順序でレコードを転送することを誰も約束しませんでした。 この状況から抜け出す最善の方法は、dbfおよびshpにPKが存在することです。これにより、それらを簡単に比較でき、Shape2SQLの作成者がサロゲートIDを思い付く必要がなくなります。 しかし、そのようなカードは配られます。 署名レコードが1506、地図作成オブジェクトのレコード-1505(図1)であることは注目に値しますが、図4の読み込みプロセス中に、Shape2SQLも1506があると書きました。 初期ツールの重大な省略が1つあることがわかります。これは、空のオブジェクトをロードしないという事実にあります。 彼女はそれらをスキップし、署名よりもカートグラフィックオブジェクトのテーブル内のエントリが少ない場合があります。その結果、物理的順序はいまいましい祖母と一致します。 署名内の空のマップオブジェクトに対応するレコードを計算できる領域と境界の列がここにあると便利です。





図7



署名テーブルdelete from regions2010_captions where area = 0



と、穴が表示されます。 私たちの場合、最後のレコードが1つだけで、最後の番号を単に1505に変更できるのは良いことです。それでも、削除されたレコードがいくつかあり、どこかに散らばっているかのように、IDを増やして署名を新しい順序で正直に番号付けします真ん中に。



alter table regions2010_captions add n int

;with cte as (select *, row_number() over (order by ID) n1 from regions2010_captions) update cte set n = n1

alter table regions2010_captions drop column ID








region2010_albsibテーブルもオブジェクトの物理スキャンの順序でNielsenを受け取ることを本当に望みます。 次に、regions2010_captionsテーブル(フィールドn)のIDフィールドに関連付けることができます。 署名からわかるように、1つの領域は複数のポリゴン(モスクワとゼレノグラード、沿岸地域、島など)で構成できるため、地図作成オブジェクトの数は実際の領域の数を超えています。 たとえば、 select s.geom from regions2010_captions c join regions2010_albsib s on s.ID = cn where c.region = ' '









図8



そのため、同じ地域に基づいて集約することにより、これらを結合する必要があります。



if exists (select 1 from sys.sequences where name = 'Seq') drop sequence Seq

create sequence Seq as int start with 1 increment by 1



if object_id('regions2010', 'U') is not null drop table regions2010



select (next value for Seq) ID, c.region, geometry::UnionAggregate(s.geom) geom

into regions2010

from regions2010_captions c join regions2010_albsib s on s.ID = cn

group by c.region



select * from regions2010








このコードは、SQL Server 2012の2つの新機能、シーケンスと地理空間集計を示しています。





図9



色から判断すると、それは本当のようです。 そのため、署名とポリゴンをリンクすることで、間違えられませんでした。

同じ領域に属するポリゴンは同じ色でペイントされますが、それらは別々のオブジェクトであり、同じ幾何学的コレクションが領域(マルチポリゴン)です。 これを検証するにはselect ID, Region, geom.STGeometryType(), geom.STNumGeometries() from regions2010



クエリselect ID, Region, geom.STGeometryType(), geom.STNumGeometries() from regions2010



ます。





図10



コレクションから選択したリージョンのテーブルにそれらをデプロイするために、単純な関数を作成しました:



if object_id('dbo.ufnGeometries', 'TF') is not null drop function dbo.ufnGeometries

go

create function dbo.ufnGeometries(@g geometry) returns @t table (id int identity(1, 1), g geometry) as begin

declare @i int = 1

while @i <= @g.STNumGeometries() begin

insert @t (g) values (@g.STGeometryN(@i))

set @i += 1

end

return

end








これにより、集計から、本質的に、regions2010テーブルが再び元のregions2010_albsibに戻ることができます:



select r.ID, r.Region, f.ID, fg from regions2010 r cross apply dbo.ufnGeometries(geom) f









図11



実際には、彼女ではありません。 1505ではなく、すでに1503の詳細なポリゴンがあることに注意してください。同じ領域内に2組の交差するポリゴンまたは3つの交差するポリゴンがあり、それらが1つに結合されたという事実によって説明します。 確認しましょう:



with cte as (select s.ID, s.geom, c.region from regions2010_albsib s join regions2010_captions c on s.ID = cn)

select cte1.ID, cte1.geom, cte2.ID, cte2.geom, cte1.geom.STIntersection(cte2.geom).STGeometryType() from cte cte1 join cte cte2 on cte1.ID < cte2.ID and cte1.region = cte2.region

where cte1.geom.STIntersects(cte2.geom) = 1








実際、このような交差点は合計で7つあり、そのうち5つは結合されたときに1つのポリゴンに崩壊しない点交差点であり、2つの隣接するポリゴンのペア、つまり 破線の形で共通の境界線を持っている。 これらのペアはそれぞれ1つのポリゴンに結合されたため、それらの数は2つ減少しました。





図12



結論として、Reduce()メソッドの実際的な効果を検討します。 regions2010マップが2〜3秒の遅延で描画されることに注意してください(図9)。 これは、各領域の輪郭を定義するかなりの数のポイント(数千または数万)によって引き起こされます。 レポートに表示されるサイズのマップの場合、そのような綿密さは不必要であり、レンダリング時間を不当に増加させます。 粗大化には、Douglas-Peckerアルゴリズムに従って動作するReduce()メソッドが使用されます。 パラメーターの値が大きいほど、粗大化が強くなります( ここでトレラントメソッドを調べました )。 たとえば、 select ID, Region, geom.STNumPoints() [Points Total], geom.Reduce(100).STNumPoints() Reduce100, geom.Reduce(500).STNumPoints() Reduce500, geom.Reduce(1000).STNumPoints() Reduce1000 from regions2010









図13



したがって、 select ID, Region, geom.Reduce(1000) from regions2010



表示される品質マップを保存するときの高速化select ID, Region, geom.Reduce(1000) from regions2010



レンダリング速度が速くなります。





図14




All Articles