From: Kevin Neufeld Date: Wed, 2 Dec 2009 23:25:21 +0000 (+0000) Subject: added some thoughts on DE-9IM X-Git-Tag: 1.5.0b1~112 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1ddf27aad5eed4c49687cfdcb75f953edb62d491;p=postgis added some thoughts on DE-9IM git-svn-id: http://svn.osgeo.org/postgis/trunk@4979 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/doc/html/style.css b/doc/html/style.css index 8d859ff77..497e4f212 100644 --- a/doc/html/style.css +++ b/doc/html/style.css @@ -44,3 +44,6 @@ pre, .literallayout { border-right-width: 0px; border-left-width: 0px; border-bo .remark { background: #ffff00; } .equation {font-style: italic; font-size: 90%;} .command, .code {font-weight: normal; font-family: "Courier New", Courier, Monaco, monospace; color: #000000;} +.styledtable table thead th { border-right-width: 0px; border-left-width: 0px; border-bottom-width: 1px; border-top-width: 0px; border-color: #f7931e; border-style: solid; } +.styledtable > table { border-right-width: 0px; border-left-width: 0px; border-bottom-width: 2px; border-top-width: 2px; border-color: #f7931e; border-style: solid; } +.styledtable table td,th { color: #000000; font-style: italic; padding-right:10px; padding-left:10px; border-right-width: 0px; border-left-width: 0px; border-bottom-width: 2px; border-top-width: 2px; border-width: 0px;} diff --git a/doc/using_postgis_dataman.xml b/doc/using_postgis_dataman.xml index a79652139..af231d76b 100644 --- a/doc/using_postgis_dataman.xml +++ b/doc/using_postgis_dataman.xml @@ -975,6 +975,478 @@ gisdb=# SELECT there. + + + Dimensionally Extended 9 Intersection Model (DE-9IM) + + It is sometimes the case that the typical spatial predicates + (ST_Contains, ST_Crosses, ST_Intersects, ST_Touches, ...) are + insufficient in and of themselves to adequately provide that desired + spatial filter. + + + + + + + + For example, consider a linear + dataset representing a road network. It may be the task of a + GIS analyst to identify all road segments that cross + eachother, not at a point, but on a line, perhaps invalidating + some business rule. In this case, ST_Crosses does not + adequately provide the necessary spatial filter since, for + linear features, it returns true only where + they cross at a point. One two-step solution + might be to first perform the actual intersection + (ST_Intersection) of pairs of road segments that spatially + intersect (ST_Intersects), and then compare the intersection's + ST_GeometryType with 'LINESTRING' (properly + dealing with cases that return + GEOMETRYCOLLECTIONs of + [MULTI]POINTs, + [MULTI]LINESTRINGs, etc.). A + more elegant / faster solution may indeed be + desireable. + + + + + + + + + + + + A second [theoretical] + example may be that of a GIS analyst trying to locate all + wharfs or docks that intersect a lake's boundary on a line and + where only one end of the wharf is up on shore. In other + words, where a wharf is within, but not completely within a + lake, intersecting the boundary of a lake on a line, and where + the wharf's endpoints are both completely within and on the + boundary of the lake. The analyst may need to use a + combination of spatial predicates to isolate the sought after + features: + + ST_Contains(lake, wharf) = TRUE + + + + ST_ContainsProperly(lake, wharf) = FALSE + + + + ST_GeometryType(ST_Intersection(wharf, lake)) = + 'LINESTRING' + + + + ST_NumGeometries(ST_Multi(ST_Intersection(ST_Boundary(wharf), + ST_Boundary(lake)))) = 1 + + ... (needless to say, this could get quite + complicated) + + + + + + + + So enters the Dimensionally Extended 9 Intersection Model, or + DE-9IM for short. + + + Theory + + According to the OpenGIS Simple + Features Implementation Specification for SQL, "the basic + approach to comparing two geometries is to make pair-wise tests of + the intersections between the Interiors, Boundaries and Exteriors of + the two geometries and to classify the relationship between the two + geometries based on the entries in the resulting 'intersection' + matrix." + + + + Boundary + + + The boundary of a geometry is the set of geometries of + the next lower dimension. For POINTs, which + have a dimension of 0, the boundary is the empty set. The + boundary of a LINESTRING are the two + endpoints. For POLYGONs, the boundary is + the linework that make up the exterior and interior + rings. + + + + + Interior + + + The interior of a geometry are those points of a + geometry that are left when the boundary is removed. For + POINTs, the interior is the + POINT itself. The interior of a + LINESTRING are the set of real points + between the endpoints. For POLYGONs, the + interior is the areal surface inside the polygon. + + + + + Exterior + + + The exterior of a geometry is the universe, an areal + surface, not on the interior or boundary of the + geometry. + + + + + Given geometry a, where the + I(a), B(a), and + E(a) are the Interior, + Boundary, and Exterior of + a, the mathematical representation of the matrix is: + + + + + + + + Interior + + Boundary + + Exterior + + + + + + Interior + + + + + dim( + I(a) + + ∩ + + I(b) ) + + + + + + + + dim( + I(a) + + ∩ + + B(b) ) + + + + + + + + dim( + I(a) + + ∩ + + E(b) ) + + + + + + + Boundary + + + + + dim( + B(a) + + ∩ + + I(b) ) + + + + + + + + dim( + B(a) + + ∩ + + B(b) ) + + + + + + + + dim( + B(a) + + ∩ + + E(b) ) + + + + + + + Exterior + + + + + dim( + E(a) + + ∩ + + I(b) ) + + + + + + + + dim( + E(a) + + ∩ + + B(b) ) + + + + + + + + dim( + E(a) + + ∩ + + E(b) ) + + + + + + + + + Where dim(a) is the dimension of + a as specified by + ST_Dimension() but has the domain of + {0,1,2,T,F,*} + + + + 0 => point + + + + 1 => line + + + + 2 => area + + + + T => + {0,1,2} + + + + F => empty set + + + + * => don't care + + + + Visually, for two overlapping polygonal geometries, this looks + like: + + + + + + + + + + + + + + + + + + + + + + + + + + Interior + + Boundary + + Exterior + + + + + + Interior + + + + dim(...) = + 2 + + + + dim(...) = + 1 + + + + dim(...) = + 2 + + + + Boundary + + + + dim(...) = + 1 + + + + dim(...) = + 0 + + + + dim(...) = + 1 + + + + Exterior + + + + dim(...) = + 2 + + + + dim(...) = + 1 + + + + dim(...) = + 2 + + + + + + + + + + Read from left to right, the dimensional matrix is + represented, '212010212'. + + A relate matrix that would therefore represent our first + example of two lines that intersect on a line would be: '1*1***1**' + + -- Identify road segments that cross on a line +SELECT a.id +FROM roads a, roads b +WHERE a.id != b.id +AND a.geom && b.geom +AND ST_Relate(a.geom, b.geom, '1*1***1**'); + + A relate matrix that represents the second example of wharfs + partly on the lake's shoreline would be '102101FF2' + + -- Identify wharfs partly on a lake's shoreline +SELECT a.lake_id, b.wharf_id +FROM lakes a, wharfs b +WHERE a.geom && b.geom +AND ST_Relate(a.geom, b.geom, '102101FF2'); + + +