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に感謝します。

Source: https://habr.com/ru/post/J307294/


All Articles