2 字符串求交集_PostGIS教程十八:维数扩展的9交集模型
一、什么是維數擴展的9交集模型
"維數擴展的9交集模型-Dimensionally Extended 9-Intersection Model"(DE9IM)是一個用于建模兩個空間對象如何交互的框架。
首先,每個空間對象都具有:
- 內部(interior)
- 邊界(boundary)
- 外部(exterior)
內部是以環為邊界的里面的那一部分;邊界是環本身;外部是邊界外的一切。
對于線性要素,內部、邊界和外部不太為人所知:
內部是以端點為界限的線的那一部分;邊界是線性要素的端點;外部是平面中除內部和邊界外的所有其他部分。
對于點來說,更奇怪:內部是點,邊界是空集,外部是平面上除點以外的所有其他部分。
使用這些內部、外部和邊界的定義,任何一對空間要素之間的關系都可以用一對要素的內部/邊界/外部/之間九個可能的交集的維數來表征。
對于上例中的多邊形,內部的交集是二維區域,因此矩陣的對應部分用"2"填充。邊界僅在零維點處相交,因此對應矩陣部分用"0"填充。
當兩個幾何圖形的這三個部分(內部,邊界,外部)之間沒有交集時,將用"F"填充矩陣中對應的部分。
下面是另一個示例,關于線串的一部分和多邊形相交的例子:
關于它們的交集的DE9IM矩陣如下:
請注意,以上兩個要素的邊界實際上根本不相交(線的端點與多邊形的內部相交,而不是與多邊形的邊界相交,反之亦然),因此B/B單元用"F"填充。
雖然讓人從視覺上填寫DE9IM矩陣很有趣,但如果計算機能夠做到這一點就更好了,這就是ST_Relate函數的作用。
前面的示例可以使用簡單的矩形和直線進行簡化,其空間關系與上面的多邊形和線串的空間關系相同:
我們可以使用SQL生成DE9IM信息:
SELECT ST_Relate('LINESTRING(0 0, 2 0)','POLYGON((1 -1, 1 1, 3 1, 3 -1, 1 -1))' );答案(1010F0212)與我們視覺上計算的結果相同,但以9個字符的字符串形式返回。將結果以三行的形式呈現:
但是,DE9IM矩陣的強大之處不在于生成它們,而在于使用它們作為匹配參數來查找彼此之間具有特定關系的幾何圖形。
二、查找具有特定關系的幾何圖形
首先,在數據庫中加入如下數據:
CREATE TABLE lakes ( id serial primary key, geom geometry ); CREATE TABLE docks ( id serial primary key, good boolean, geom geometry );INSERT INTO lakes ( geom )VALUES ( 'POLYGON ((100 200, 140 230, 180 310, 280 310, 390 270, 400 210, 320 140, 215 141, 150 170, 100 200))');INSERT INTO docks ( geom, good )VALUES('LINESTRING (170 290, 205 272)',true),('LINESTRING (120 215, 176 197)',true),('LINESTRING (290 260, 340 250)',false),('LINESTRING (350 300, 400 320)',false),('LINESTRING (370 230, 420 240)',false),('LINESTRING (370 180, 390 160)',false);假設我們有一個湖泊(Lakes)和碼頭(Docks)的數據模型,進一步假設碼頭必須位于湖泊內部,并且必須在一端接觸到湖泊的邊界。我們能在數據庫中找到所有符合這一規則的碼頭嗎?
我們的合法碼頭具有以下特點:
- 它們的內部與湖泊內部有一個線性(一維)相交
- 它們的邊界與湖泊內部有一個點(0維)相交
- 它們的邊界與湖泊邊界也有一個點(0維)相交
- 它們的內部與湖泊外部沒有相交(F)
所以它們的DE9IM矩陣看起來像這樣:
因此,要找到所有符合規則的碼頭,我們需要先找到所有與湖泊相交的碼頭,然后再從該集合中找到符合具體規則的所有碼頭。
SELECT docks.* FROM docks JOIN lakes ON ST_Intersects(docks.geom, lakes.geom) WHERE ST_Relate(docks.geom, lakes.geom, '1FF00F212');-- Answer: our two good docks注意,ST_Relate的三參數版本(重載函數)的使用,如果前兩個幾何圖形參數的關系與第三個DE9IM模型參數匹配,則返回ture;如果不匹配,則返回false。
另外,對于更松散的匹配搜索,第三個參數允許DE9IM數據模型字符串使用通配符:
- "*"表示"此單元格中的任何值都可以接受"
- "T"表示"任何非假值(0、1或2)都可以接受"
例如,我們在示例圖形中添加一個與湖泊邊界具有二維相交的碼頭:
INSERT INTO docks ( geom, good ) VALUES ('LINESTRING (140 230, 150 250, 210 230)',true);如果要將這個新增的碼頭在ST_Relate函數檢查中被視為符合規則,則需要更改ST_Relate函數的第三個參數。
因為要使碼頭內部和湖泊邊界的相交可以是1(我們的新情況)或F(我們的原始情況)。因此,我們使用"*"通配符覆蓋所有情況。
SQL語句如下所示:
SELECT docks.* FROM docks JOIN lakes ON ST_Intersects(docks.geom, lakes.geom) WHERE ST_Relate(docks.geom, lakes.geom, '1*F00F212');-- Answer: our (now) three good docks三、數據質量測試
TIGER數據在準備時經過仔細的質量控制,因此我們希望我們的數據也符合嚴格的標準。例如:任何人口普查塊(census blocks)都不應與任何其他人口普查塊重疊。我們能對我們的數據進行測試嗎?
當然!
SELECT a.gid, b.gid FROM nyc_census_blocks a, nyc_census_blocks b WHERE ST_Intersects(a.geom, b.geom)AND ST_Relate(a.geom, b.geom, '2********')AND a.gid != b.gid LIMIT 10;-- Answer: 10, there's some funny business同樣,我們預計街道數據都是有尾節點的,也就是說,我們預計相交點只發生在街道直線的末端,而不是中點。
我們可以通過查找是否有相交但邊界之間的交點不是零維的街道(也就是,線端點之間沒有接觸)來測試這一點:
SELECT a.gid, b.gid FROM nyc_streets a, nyc_streets b WHERE ST_Intersects(a.geom, b.geom)AND NOT ST_Relate(a.geom, b.geom, '****0****')AND a.gid != b.gid LIMIT 10;-- Answer: This happens, so the data is not end-noded.四、本文涉及的函數
- ST_Relate(geometry A, geometry B): Returns a text string representing the DE9IM relationship between the geometries.
五、更多相關資料
- OpenGIS Simple Features Implementation Specification for SQL (version 1.1, section 2.1.13.2)
- Dimensionally Extended Nine-Intersection Model (DE-9IM)
- GeoTools: Point Set Theory and the DE-9IM Matrix
總結
以上是生活随笔為你收集整理的2 字符串求交集_PostGIS教程十八:维数扩展的9交集模型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++PrimerPlus学习——第四章
- 下一篇: java通过POI技术将HTML文件转成