Recette #6:
Créer une nouvelle colonne géométrique

Février 2011


Précédent

Table des matières

Suivant


Nous allons maintenant étudier en détail comment définir correctement une colonne géométrique.
L'approche de SpatiaLite est très proche de celle adoptée par PostgreSQL/PostGIS;
i.e. la création d'une colonne géométrique en même temps qu'une table n'est pas permis.
Vous devez toujours commencer par créer la table puis, dans un second temps, ajouter la colonne géométrique.


CREATE TABLE test_geom (
  id INTEGER NOT NULL
    PRIMARY KEY AUTOINCREMENT,
  name TEXT NOT NULL,
  measured_value DOUBLE NOT NULL);


SELECT AddGeometryColumn('test_geom', 'the_geom',
  4326, 'POINT', 'XY');

C'est la seule façon d'obtenir une colonne géométrique valide.
Toutes autres approches entraînera nécessairement des erreurs.

SELECT AddGeometryColumn('test_geom', 'the_geom',
  4326, 'POINT', 'XY', 0);


SELECT AddGeometryColumn('test_geom', 'the_geom',
  4326, 'POINT', 'XY', 1);

Bien que la syntaxe précédente soit la plus courante, celle ci est la plus complète admise par AddGeometryColumn():



Choix du SRIDs:

Les types Géométriques supportés:

Geometry Type

Notes

POINT

Types géométriques communs:
Correspondent aux standards Shapefile et supportés
par tous les logiciels SIG

LINESTRING

POLYGON

MULTIPOINT

MULTILINESTRING

MULTIPOLYGON

GEOMETRYCOLLECTION

Peu utilisé: non supporté par les Shapefiles et les logiciels SIG

GEOMETRY

Classe non instanciable, regroupant l'ensemble des types géométriques
précédents. Non supporté par les Shapefiles et les logiciels SIG,
donc très peu utilisé


Choix de la Dimension:

Dimension model

Alias

Notes

XY

2

X et Y coords (simple 2D)

XYZ

3

X, Y et Z coords (3D)

XYM


X et Y coords + valeur mesurée M

XYZM


X, Y et Z coords + valeur mesurée M



Erreur courante:
Beaucoup de développeurs, professionnels des SIG etc... se croient plus malins que les autres et inventent des astuces farfelues pour créer leur propre colonne géométrique.
e.g. la modification manuelle de la table geometry_columns semble être une pratique très répandue.

De telles méthodes marcheront peut-être avec des versions très spécifiques de SpatiaLite; mais seront très probablement incompatibles avec des versions ultérieures ou antérieures.

Attention: Seules les colonnes géométriques créées avec AddGeometryColumn() sont 100% légitimes.
Toute autre approche est risquée (et non supportée ..)


Je suppose qu'un coup d’œil rapide à la façon dont AddGeometryColumn() affecte la BDD vous permettra de mieux comprendre.

PRAGMA table_info(test_geom);


cid

name

type

notnull

dflt_value

pk

0

id

INTEGER

1

NULL

1

1

name

TEXT

1

NULL

0

2

measured_value

DOUBLE

1

NULL

0

3

the_geom

POINT

0

NULL

0

étape 1: une nouvelle colonne test_geom a été ajoutée à la table correspondante.

SELECT *
FROM geometry_columns
WHERE f_table_name LIKE 'test_geom';


f_table_name

f_geometry_column

type

coord_dimension

srid

spatial_index_enabled

test_geom

the_geom

POINT

XY

4326

0

étape 2: la ligne correspondante a été insérée dans la table metadata geometry_columns.

SELECT *
FROM sqlite_master
WHERE type = 'trigger'
  AND tbl_name LIKE 'test_geom';


type

name

tbl_name

rootpage

sql

trigger

ggi_test_geom_the_geom

test_geom

0

CREATE TRIGGER "ggi_test_geom_the_geom" BEFORE INSERT ON "test_geom"
FOR EACH ROW BEGIN
SELECT RAISE(ROLLBACK, 'test_geom.the_geom violates Geometry constraint [geom-type or SRID not allowed]')
WHERE (SELECT type FROM geometry_columns
WHERE f_table_name = 'test_geom' AND f_geometry_column = 'the_geom'
AND GeometryConstraints(NEW."the_geom", type, srid, 'XY') = 1) IS NULL;
END

trigger

ggu_test_geom_the_geom

test_geom

0

CREATE TRIGGER "ggu_test_geom_the_geom" BEFORE UPDATE ON "test_geom"
FOR EACH ROW BEGIN
SELECT RAISE(ROLLBACK, 'test_geom.the_geom violates Geometry constraint [geom-type or SRID not allowed]')
WHERE (SELECT type FROM geometry_columns
WHERE f_table_name = 'test_geom' AND f_geometry_column = 'the_geom'
AND GeometryConstraints(NEW."the_geom", type, srid, 'XY') = 1) IS NULL;
END

étape 3: la table sqlite_master est la table metadata principale utilisée par SQLite pour stocker les objets géométriques.
Comme vous pouvez le constater, chaque géométrie nécessite des triggers pour être pleinement comprises et gérées par la BDD.
Rien de bien surprenant, tout ceci doit être définit d'une manière très robuste afin de permettre à SpatiaLite de fonctionner correctement.
Si des éléments viennent à manquer ou à être modifiés, la BDD spatiale sera inévitablement défectueuse 



SELECT DiscardGeometryColumn('test_geom', 'the_geom');

Cette commande va supprimer toutes les tables metadata ainsi que les trigger liés à la colonne géométrique. note: cependant, tous les objects géométriques stockés dans la table seront indemnes.

Simplement, suite l'appel de la fonction DiscardGeometryColumn(...) ils ne seront plus considérés comme des géométries légitimes, mais comme des valeurs BLOB anonymes et génériques.

SELECT RecoverGeometryColumn('test_geom', 'the_geom',
  4326, 'POINT', 'XY');

Ceci va tenter de recréer toutes les tables metadata et les trigger associé à la colonne géométrique correspondante.
Si cette opération réussie, la colonne géométrique deviens alors légitime.
En d'autres termes, il n'y a absolument pas de différences entre une colonne géométrique créée avec AddGeometryColumn() et une autre créée avec RecoverGeometryColumn().
Très simplement:

Problèmes de compatibilité entre les différentes versions

SpatiaLite peut être amené à évoluer, et il en va de même pour SQLite.

Principe de base: Vous êtes sûrs que tout fichier créé avec une version plus ancienne de SpatiaLite ne posera pas de soucis avec une version plus récente.

Attention: le contraire n'est pas toujours vrai.


Dans certains cas, cette incompatibilité est majeure: e.g. l'utilisation de la géométrie 3D est impossible dans les versions antérieures de SpatiaLite
Mais dans la plupart des cas, il s'agit simplement de petites incompatibilités au niveau de fonctions binaires utilisées par les triggers.

Astuce utile

Pour tenter de résoudre d'éventuels problèmes d'incompatibilité:

  • dans un premier temps, éliminez tous les triggers: le meilleur moyen d'y parvenir est d'utiliser DiscardGeometryColumn()

  • puis les remettre en place avec AddGeometryColumn()

Ceci va permettre de s'assurer que les tables metadata et que les trigger soient compatibles avec la version utilisée.


Précédent

Table des matières

Suivant


Author: Alessandro Furieri a.furieri@lqt.it
Traduced from English by RIVIERE Romain

This work is licensed under the Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license.


Permission is granted to copy, distribute and/or modify this document under the terms of the
GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.