SQLおよびXPathとRosReestr

RosReestrは数年前からXML形式でデータを発行してきましたが、最近ではXMLのみで発行しています。 そしてこれは素晴らしい! 結局のところ、これは非常に多くのツールが存在する作業に便利で、人間が読める形式と機械が読める形式です。 しかし、何らかの理由で、Cadastral Engineersに.tabや.shpなどの古い形式でデータを送信してください。これらの形式でのみGISで作業できるからです。 この問題を解決するために、 多くの利己的で無関心な人々が関与しました。その結果、KIは彼らのお気に入りのプログラムに多くのコンバーターを導入しました。 しかし、小さな問題があります-RosRestrにはxml-schemes静かに、警告なし変更する習慣があります 。 結果として、 CI作業は麻痺します。なぜなら、それらはXMLで作業できないからです!



個人的には、SQLを使用してDBMSのデータを操作することを好みます。 Microsoft SQL ServerとSQL Server Management Studioを使用します。



テーブルを作成します。

CREATE TABLE [dbo].[T1]( [IntCol] [int] IDENTITY(1,1) NOT NULL, [XmlCol] [xml] NULL)
      
      







データの読み込み:

 INSERT INTO T1(XmlCol) SELECT * FROM OPENROWSET(BULK 'C:\work1\doc8652442.xml', SINGLE_BLOB) AS x;
      
      







座標テーブルを取得します。

 DECLARE @Xdoc xml; SET @Xdoc = (select [XmlCol] FROM [test1].[dbo].[T1]); WITH XMLNAMESPACES (DEFAULT 'urn://x-artefacts-rosreestr-ru/outgoing/kpt/10.0.1', 'urn://x-artefacts-rosreestr-ru/commons/complex-types/entity-spatial/5.0.1' as ns3) SELECT Parcel.value('@CadastralNumber', 'nvarchar(50)')as data, Ordinate.value('@X', 'nvarchar(50)') as X,Ordinate.value('@Y', 'nvarchar(50)') as Y FROM @Xdoc.nodes('//Parcel') col(Parcel) CROSS APPLY Parcel.nodes('//ns3:Ordinate') tab(Ordinate)
      
      











それだけです! これで、データを使って何でもできます。 たとえば、パーセルのジオメトリ(パーセル)を取得します。 ジオメトリはEntitySpatial要素に格納され、複数のSpatialElement輪郭を含むことができます。セクションは、穴のある多角形または複数の多角形にすることができます。 SpatialElementをLineStringとして取得してみましょう。これにはいくつかの関数が必要です



SpatialElement => LineString

 CREATE FUNCTION [dbo].[SpatialElementToLineString](@wXml xml) RETURNS geometry AS BEGIN DECLARE @BuildString NVARCHAR(MAX); WITH XMLNAMESPACES ('urn://x-artefacts-rosreestr-ru/commons/complex-types/entity-spatial/5.0.1' as ns3) SELECT @BuildString = COALESCE(@BuildString + ',', '') + Ordinate.value('@Y', 'NVARCHAR(50)') + ' ' + Ordinate.value('@X', 'NVARCHAR(50)') FROM @wXml.nodes('//ns3:Ordinate') col(Ordinate); SET @BuildString = 'LineString(' + @BuildString + ')'; return geometry::STGeomFromText(@BuildString, 0); END
      
      







サイトのすべての輪郭を取得する:

 CREATE FUNCTION [dbo].[ParcelToLineString](@Xdoc xml) RETURNS @Tbl TABLE ( CadastralNumber nvarchar(max), Geom geometry ) AS begin WITH XMLNAMESPACES (DEFAULT 'urn://x-artefacts-rosreestr-ru/outgoing/kpt/10.0.1', 'urn://x-artefacts-rosreestr-ru/commons/complex-types/entity-spatial/5.0.1' as ns3) insert into @Tbl(CadastralNumber, Geom) SELECT @Xdoc.value('/*[1]/@CadastralNumber', 'nvarchar(max)') as CadastralNumber, [dbo].[SpatialElementToLineString](Parcel.query('.')) as geom FROM @Xdoc.nodes('//ns3:SpatialElement') col(Parcel); RETURN; end
      
      







次に、ジオメトリを保存するテーブルを作成します。

 CREATE TABLE [dbo].[CadastrTbl]( [id] [int] IDENTITY(1,1) NOT NULL, [CadastralNumber] [nvarchar](255) NULL, [geom] [geometry] NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
      
      







そしてそれを埋める

 DECLARE @Xdoc xml; SET @Xdoc = (select [XmlCol] FROM [test1].[dbo].[T1]); DECLARE @CURSOR CURSOR SET @CURSOR = CURSOR SCROLL FOR WITH XMLNAMESPACES (DEFAULT 'urn://x-artefacts-rosreestr-ru/outgoing/kpt/10.0.1') SELECT Parcel.query('.') FROM @Xdoc.nodes('//Parcel') col(Parcel); DECLARE @Parcel xml; OPEN @CURSOR FETCH NEXT FROM @CURSOR INTO @Parcel WHILE @@FETCH_STATUS = 0 BEGIN insert into [test1].[dbo].[CadastrTbl]([CadastralNumber],[geom]) select * from dbo.ParcelToLineString(@Parcel); FETCH NEXT FROM @CURSOR INTO @Parcel END CLOSE @CURSOR
      
      











これで、GIS( 例:QGIS )で開くことができるジオメトリができました





QGISでは、 レイヤーを便利な形式(kmlなど)で保存し、GEでデータを表示できます。







今、私たちは彼らが私たちを救うまで待つ必要はありません、そして私たちは私たちの人生を手にすることができます! そしてすべてSQLに感謝します。



All Articles