Dies ist der zweite Teil einer zweiteiligen Serie über die Risiken für Softwareanwender durch schlechte Dokumentation; insbesondere die Verwirrung und unerwarteten Ergebnisse, die durch schwach dokumentierte spatial operators in GIS-Software entstehen. Der erste Teil der Serie <\/A>behandelt, wie inkonsistente und unvollständige Dokumentation die Benutzer dazu zwingt, zu erraten, wie spatial operators implementiert sind. Der zweite Teil der Serie<\/STRONG> betrachtet die inkonsistenten Ergebnisse, die sich aus der Vermischung verschiedener Implementierungen von spatial operators ergeben.<\/EM><\/P><\/P>Einer der vielen von mir kürzlich gemeldeten Fehler mit leeren Geometrien wurde diese Woche auf die vordere Prioritätsliste gesetzt, als ich bemerkte, dass Esri den Status auf "Geschlossen: Wird nicht behoben" aktualisiert hat. Daraus entstand eine Diskussion, die sich noch entfaltet über erwartetes Verhalten versus unerwartete Ergebnisse. Zufälligerweise lässt sich das Problem gut im Rahmen der Diskussion und Beispiele aus dem ersten Beitrag dieser Serie darstellen (Was ist Within: Wenn (Esri != Clementini) = ?<\/A>).<\/P><\/P>Der erste Beitrag dieser Serie erläuterte, dass es keine einheitliche Definition von spatial relations für Geometriebibliotheken und geospatial Anwendungen gibt und wie das Dimensionally Extended 9 Intersection Model (DE-9IM) nach der Aufnahme in die OpenGIS Implementation Specification for Geographic information - Simple feature access - Part 1: Common architecture<\/A> zur vorherrschenden 2D-Definition wurde. Der Beitrag konzentrierte sich darauf, wie unvollständige Dokumentation von spatial operators Benutzer dazu zwingt zu raten und wahrscheinlich manchmal falsch zu liegen, wie Software funktioniert, anstatt zu wissen, wie die Software funktionieren sollte. So bedauerlich unvollständige Dokumentation für Benutzer auch sein kann, ist das Vermischen unterschiedlicher Definitionen von spatial relations innerhalb desselben spatial operators viel schlimmer, und genau das scheint Esri getan zu haben.<\/P><\/P>Angelehnt an die Beispiele im vorherigen Beitrag betrachten wir drei Features und die ArcPy Geometry.within()<\/SPAN>-Methode.<\/P><\/P>>>> #Erstelle Quadratpolygon>>> polygon = arcpy.FromWKT('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))')>>> #Erstelle Linie, die vollständig auf der Polygongrenze liegt>>> line = arcpy.FromWKT('LINESTRING(1 0, 2 0)')>>> #Erstelle leere Linie>>> line_empty = arcpy.FromWKT('LINESTRING EMPTY')>>>>>> #Teste ob Linie innerhalb des Polygons ist>>> line.within(polygon)False>>> #Teste ob line_empty innerhalb des Polygons ist>>> line_empty.within(polygon)True<\/PRE><\/P>Zum Vergleich führen wir dieselben beiden Tests aus Zeile 9 und 12 mit Esris ST_Geometry in Oracle aus:<\/P><\/P>SQL> --Teste ob Linie innerhalb des Polygons istSQL> SELECT sde.st_within(sde.st_geomfromtext('LINESTRING(1 0, 2 0)', 0), sde.st_geomfromtext('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0)) FROM dual;SDE.ST_WITHIN(SDE.ST_GEOMFROMTEXT('LINESTRING(10,20)',0),SDE.ST_GEOMFROMTEXT('PO'-------------------------------------------------------------------------------- SQL> --Teste ob line_empty innerhalb des Polygons istSQL> SELECT sde.st_within(sde.st_geomfromtext('LINESTRING EMPTY', 0), sde.st_geomfromtext('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0)) FROM dual;SDE.ST_WITHIN(SDE.ST_GEOMFROMTEXT('LINESTRINGEMPTY',0),SDE.ST_GEOMFROMTEXT('POLY'-------------------------------------------------------------------------------- 7<\/P>Interessant ist, dass die Ergebnisse bei Verwendung von ST_Geometry von denen mit ArcPy abweichen.  Da bekannt ist, dass ST_Geometry-Funktionen OGC simple feature access und SQL-konform sind und somit DE-9IM implementieren, sind die Ergebnisse von ST_Geometry in Oracle erwartungsgemäß: Eine Linie nur auf der Grenze eines Polygons wird nicht als innerhalb des Polygons betrachtet und eine leere Geometrie kann nicht innerhalb einer anderen Geometrie sein.<\/P><\/P>Bei Betrachtung der ArcPy-Ergebnisse ist Zeile 10 nur dann korrekt wenn<\/SPAN> die ArcPy Geometry Classes <\/A>Clementinis Definition implementieren, da wir im ersten Beitrag dieser Serie gesehen haben, dass Esris Definition von Within in dieser Situation True ergibt.  Leider gibt die ArcPy-Dokumentation keine Auskunft darüber, welche Definition sie implementiert.  Das Ergebnis in Zeile 13 ist nur dann korrekt wenn<\/SPAN> die ArcPy Geometry Classes <\/A>Esris Definition implementieren, da Clementinis Definition nicht zulässt, dass eine leere Geometrie innerhalb einer anderen Geometrie liegt.  Klar wie Kloßbrühe, oder? <\/P><\/> Die Haltung von Esri bis heute ist, dass alles wie vorgesehen funktioniert.  Was?!  Wenn dem so ist, erkennt Esri implizit an, dass sie unterschiedliche Definitionen einer spatial relation innerhalb desselben spatial operators implementieren – es kommt nur darauf an, welche Geometrien man übergibt!!  Zwischen geschlossenem Quellcode, unvollständiger Dokumentation und scheinbar willkürlicher Implementierung sind ArcPy Geometry Classes auf eigene Gefahr zu verwenden. Caveat utilitor<\EM>.<\P><\BODY><\HTML>
<\/P>
Der erste Beitrag dieser Serie erläuterte, dass es keine einheitliche Definition von spatial relations für Geometriebibliotheken und geospatial Anwendungen gibt und wie das Dimensionally Extended 9 Intersection Model (DE-9IM) nach der Aufnahme in die
Angelehnt an die Beispiele im vorherigen Beitrag betrachten wir drei Features und die ArcPy Geometry.within()<\/SPAN>-Methode.<\/P><\/P>>>> #Erstelle Quadratpolygon>>> polygon = arcpy.FromWKT('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))')>>> #Erstelle Linie, die vollständig auf der Polygongrenze liegt>>> line = arcpy.FromWKT('LINESTRING(1 0, 2 0)')>>> #Erstelle leere Linie>>> line_empty = arcpy.FromWKT('LINESTRING EMPTY')>>>>>> #Teste ob Linie innerhalb des Polygons ist>>> line.within(polygon)False>>> #Teste ob line_empty innerhalb des Polygons ist>>> line_empty.within(polygon)True<\/PRE><\/P>Zum Vergleich führen wir dieselben beiden Tests aus Zeile 9 und 12 mit Esris ST_Geometry in Oracle aus:<\/P><\/P>SQL> --Teste ob Linie innerhalb des Polygons istSQL> SELECT sde.st_within(sde.st_geomfromtext('LINESTRING(1 0, 2 0)', 0), sde.st_geomfromtext('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0)) FROM dual;SDE.ST_WITHIN(SDE.ST_GEOMFROMTEXT('LINESTRING(10,20)',0),SDE.ST_GEOMFROMTEXT('PO'-------------------------------------------------------------------------------- SQL> --Teste ob line_empty innerhalb des Polygons istSQL> SELECT sde.st_within(sde.st_geomfromtext('LINESTRING EMPTY', 0), sde.st_geomfromtext('POLYGON((0 0, 3 0, 3 3, 0 3, 0 0))', 0)) FROM dual;SDE.ST_WITHIN(SDE.ST_GEOMFROMTEXT('LINESTRINGEMPTY',0),SDE.ST_GEOMFROMTEXT('POLY'-------------------------------------------------------------------------------- 7<\/P>Interessant ist, dass die Ergebnisse bei Verwendung von ST_Geometry von denen mit ArcPy abweichen.  Da bekannt ist, dass ST_Geometry-Funktionen OGC simple feature access und SQL-konform sind und somit DE-9IM implementieren, sind die Ergebnisse von ST_Geometry in Oracle erwartungsgemäß: Eine Linie nur auf der Grenze eines Polygons wird nicht als innerhalb des Polygons betrachtet und eine leere Geometrie kann nicht innerhalb einer anderen Geometrie sein.<\/P><\/P>Bei Betrachtung der ArcPy-Ergebnisse ist Zeile 10 nur dann korrekt wenn<\/SPAN> die
<\/>
Die Haltung von Esri bis heute ist, dass alles wie vorgesehen funktioniert.  Was?!  Wenn dem so ist, erkennt Esri implizit an, dass sie unterschiedliche Definitionen einer spatial relation innerhalb desselben spatial operators implementieren – es kommt nur darauf an, welche Geometrien man übergibt!!  Zwischen geschlossenem Quellcode, unvollständiger Dokumentation und scheinbar willkürlicher Implementierung sind ArcPy Geometry Classes auf eigene Gefahr zu verwenden. Caveat utilitor<\EM>.<\P><\BODY><\HTML>
I think the risk is assuming Clementini operators exist where no mention of "Clementini" is found. Esri has supported a WITHIN operator since long before the Clementini paper was written.
The creation of SDE (at 3.0) provided a new opportunity to implement a spatial operators library, and Clementini was chosen to be the basis of that library. SDE.ST_GEOMETRY was implemented using that library, and OpenGIS adopted Clementini (probably at Esri's suggestion, though I'm not certain of that). I've got a copy of the Clementini paper (actually, I have several, one in each boot partition of every system I manage), and I use it to check for defects and cross-check for desired functionality, but the average user is not going to want a 2-hour lecture on geometry algebra (and another on geometry calculus) before using a theme-on-theme query tool.
Choosing to break existing functionality on upgrade is a dangerous endeavor. The rules become even more slippery when additional functionality is added. And Clementini treats a number of common topological relationships as multiple discrete cases, which would have removed functionality. So, yes, there are multiple geometric relationship libraries within Esri code. When you add in the absurdity of having an "empty line" discrete from an "empty point" and don't support a true "Nil" (which is a feature of WKT), then you've also got multiple conflicting standards to address. And that means that yes, there are multiple possible oddities when asking a computer to answer a nonsensical Boolean question. Personally, I would return FALSE to all Boolean questions outside of defined behavior, but because it is undefined, any outcome, including a division by zero exception would be technically correct.
Vince Angelo, thanks for the comments, I know you have a long history with SDE and spatial operators. Your background and perspective is always good reading, even if we aren't always in perfect agreement.
Regarding your first paragraph, I completely agree. It seems I may have failed to put what was in my head down in writing. When it comes to the ArcPy Geometry Classes specifically, which is really what I am selfishly most concerned about, I expected the Geometry.within() method to return the same results as the Select Layer By Location tool, but that isn't the case with a line on a polygon boundary. With no reference to Clementini or DE-9IM, I expected to see results consistent with Esri's definition but the line on boundary results from Geometry.within() are consistent with Clementini instead.
Vince ... got notes???
..... but the average user is not going to want a 2-hour lecture on geometry algebra (and another on geometry calculus) before using a theme-on-theme query tool.....
doing my sabbatical stuff so anything interesting pass on!!!
I do, somewhere, but they were part of the 'C' API training materials, so I can't give them away.
The Clementini paper itself ("A Small Set of Topological Relationships Suitable for End-User Interaction") formed the basis of my slides, with a table for the function calls and how they were defined with respect to features, boundaries, exterior, and interior. I usually lost most of the students before the end, so I never went on the calculus-based method (CBM). But I did design some exercises that could construct geometries from the command line, then test the various relationships possible (and those tools made their way into se_toolkit).
- V
Angemeldete Mitglieder können Beiträge verfassen, Updates folgen und mehr. Neu hier? Registrieren Sie ein kostenloses Konto.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.