Oracle et les performances de ArcGis SDE.st_intersects

Posté le Wed 20 January 2016 dans Boulot
Temps de lecture estimé : 2 minute(s).

Prenons un Feature-DataSet créé grâce à ArcGis dans une base Oracle. Remplissons ce nouveau dataset avec environ 2 000 000 de points en 3 dimensions. Immaginons maintenant qu'on veuille identifier les doublons en 2 dimension, c'est à dire les points qui ont les mêmes coordonnées X et Y (à la tolérance du système de coordonnées près) avec une requête SQL.

A priori, rien de bien compliqué, il suffit d'utiliser la couche de fonctions SQL fournies par ce merveilleux st_shapelib. J'écris donc le code suivant :

select n1.objectid, sde.st_astext(n1.shape)
from nodes n1
inner join nodes n2 on sde.st_intersects(n1.shape, n2.shape) = 1
where n1.objectid <> n2.objectid;

Et cela donne une liste de doublons en un temps d'exécution record d'environ... 19h40. Oui, 19h40... Non mais j'hallucine...

Je ne peux décemment pas proposer une solution qui dure 19h40 à mon client... Je décide donc d'écrire un autre code, qui n'utilise pas la fonction sde.st_intersects. Voilà ce que ca donne :

declare
  previousShape sde.st_geometry;
  tolerance decimal(10, 5);
begin
tolerance := 0.001;
previousShape := null;
for r in (select objectid, shape from nodes order by sde.st_x(shape), sde.st_y(shape))
loop
if (previousShape is not null) then
  if (Abs(previousShape.minX - r.shape.minX) < tolerance
and Abs(previousShape.minY - r.shape.minY) < tolerance) then
  dbms_output.put_line('POINT Z (' || round(r.shape.MinX, 4) || ' ' || round(r.shape.MinY, 4) || ' ' || round(r.shape.minZ, 4) || ')');
end if;
end if;
previousShape := r.shape;
end loop;
end;

Contrairement à sde.st_intersects, cette solution ne fonctionne qu'avec des points. Par contre, en triant par X et Y, cela permet de ne comparer que 2 lignes consécutives, ce qui est un gain de performance indéniable. De plus, cette solution permettrait également de comparer les coordonnées Z, ce qui donnerait un test d'intersection en 3 dimensions, chose que ne permet pas sde.st_intersects aujourd'hui.

Mais le plus important est le résultat : Non seulement j'obtiens des résultats en 1min30 (oui, 1min 30 au lieu de 17h40 !!), mais en plus je n'obtiens pas tout à fait les mêmes résultats... Et après vérification, il s'est avéré que les résultats renvoyés par sde.st_intersects étaient incomplets !

Mais comment quelque-chose comme ça peut arriver ? Si je ne peux pas faire confiance aux fonctions mises à disposition par ArcGis, comment puis-je réaliser une application stable ?

st_shapelib me réserve encore beaucoup de mauvaises surprises, j'en ai bien peur...