lundi 9 avril 2007
Un petit importateur x3dTopgsql en C++ made by myself
Par david techer, lundi 9 avril 2007 à 16:41 :: PostGIS et PostgreSQL
PRE-REQUIS
Choix d'un parser(léger) XML en C++: TinyXML
J'ai recherché sur le Web des importateurs de données x3d vers postgis. Je n'ai rien trouvé pour le moment. La première chose que j'ai faite a donc été de trouver un parser c++ assez léger. Je me suis tournée pour celà vers TinyXML dont le site est http://tinyxml.sourceforge.net. Son installation n'a rien de compliquer
make
Installer la version de PostGIS modifié
A l'heure de la rédaction de ce billet, aucun patch officiel pour le moment dans le SVN de PostGIS n'a encore été envisagé pour la fonctionnalitéAsX3D()
. Pour l'installer, on peut se servir de mon repository disponible à http://www.davidgis.fr/download/postgis-svn-20070405.tar.gz
Pour se faire, j'ai dû modifier légèrement le patch de Olivier et de David de la ligne 148 à 152 du fichier lwgeom/lwgeom_x3d.c
/* -1 value are ignored (could be a way to code postgis-users@postgis.refractions.net> various faces dimension in Postgres array) *///if (value != -1) //{
j++; sprintf(buf,"%i,",value); add_str_simple(buf_face, buf);//}
Le programme
En examinant le tutorial proposé sur le même site, je suis donc parti d'un programme déjà proposé par l'auteur. Je l'ai agrémenté à ma sauce pour pouvoir le rendre compatible avec mes objectifs. J'avoue j'ai passé une bonne partie de la nuit à le faire - je n'avais pas fait de C++ depuis au moins 5 ans -. Le programme est à http://www.davidgis.fr/download/x3dtopgsql.cpp. Pour le compiler, il faut le mettre dans les sources de tinyxml, et faire
g++ -c -Wall -Wno-format -g -DDEBUG -DTIXML_USE_STL x3dtopgsql.cpp -o x3dtopgsql.o g++ -o x3dtopgsql -g tinyxml.o tinyxmlparser.o x3dtopgsql.o tinyxmlerror.o tinystr.o
Et pour l'utiliser par exemple:
x3dtopgsql [fichier.x3d] [table]où
[fichier.x3d]
est le nom du fichier .x3d que l'on souhaite importer;[table]
est le nom de la table qui sera associée et crée dans la base.
cd /mnt/sources/tinyxxml ./x3dtopgsql doc.x3d maison | psql -U postgres testgisaura pour effet de me générer les instructions SQL suivantes
SELECT DropGeometryTable('maison'); BEGIN TRANSACTION; CREATE TABLE maison (id SERIAL PRIMARY KEY,vertices integer[]); SELECT AddGeometryColumn('maison','the_geom',-1,'MULTIPOINT',3); INSERT INTO maison(id,vertices,the_geom) values (0,array[[0,1,2,3,4,-1,...,...-1,24,25,14,15,23,-1,25,24,20,19,-]],GeomFromEWKT('SRID=-1;MULTIPOINT((...)')); INSERT INTO maison(id,vertices,the_geom) values (1,array[[0,1,-1,2,3,-1,...,...,1,86,87,-1,88,89,-1,90,91,-1,92,93,-]],GeomFromEWKT('SRID=-1;MULTIPOINT(...)')); END TRANSACTION;En recrachant rapidement les lignes obtenues par AsX3D():
SELECT AsX3D(the_geom,vertices) from maison limit 1; <IndexedFaceSet coordIndex='0,1,2,3,4,-1,...,-1,25,24,20,19,-1'> <Coordinate point='5.924419 0 -3.077384,5.879113 0 -17.345828,...,16.230912 8.780875 -17.868433'/> </IndexedFaceSet>dans un fichier x3d, - faudra que je pense à automatiser tout ça -, avec freewrl on obtient par exemple les belles screenshots suivantes

Ma petite maison vu de face.

Ma petite maison vu d'en haut.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "http://www.web3d.org/specifications/x3d-3.0.dtd"> <X3D version="3.0" profile="Immersive" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.0.xsd"> <Scene> <Background groundColor="0.057 0.221 0.4" skyColor="0.057 0.221 0.4" /> <Shape> <Appearance > <Material DEF='test' diffuseColor='1.000000 1.000000 1.000000' transparency='-0.000000'/> </Appearance> <IndexedFaceSet coordIndex='0,1,2,3,4,-1,5,6,7,8,9,-1,1,0,6,5,-1,2,1,5,9,-1,4,3,8,7,-1,0,4,7,6,-1,2,10,11,3,-1,12,9,8,13,-1,10,2,9,12,14,-1,13,15,14,12,-1,3,11,15,13,8,-1,3,2,9,8,-1,16,11,10,17,18,-1,11,10,14,15,-1,17,10,14,19,-1,18,17,19,20,-1,7,21,6,-1,22,5,6,21,-1,9,22,21,7,8,-1,22,9,5,-1,15,23,20,19,14,-1,11,16,23,15,-1,16,18,20,23,-1,20,24,23,-1,25,19,14,-1,24,25,14,15,23,-1,25,24,20,19,-1'> <Coordinate point='5.924419 0 -3.077384,5.879113 0 -17.345828,8.63502 0 -17.354579,8.651169 0 -12.268231,8.680321 0 -3.086135,5.879113 5.6515 -17.345828,5.924419 5.6515 -3.077384,8.680321 5.6515 -3.086135,8.651169 5.6515 -12.268231,8.63502 5.6515 -17.354579,14.858036 0 -17.374334,14.87418 0 -12.287986,14.858036 5.6515 -17.374334,14.87418 5.6515 -12.287986,14.858036 5.63245 -17.374334,14.87418 5.63245 -12.287986,14.905019 0 -2.57249,18.299745 0 -17.385257,18.346721 0 -2.583413,18.299745 5.63245 -17.385257,18.346721 5.63245 -2.583413,7.37257 8.73204 -3.081982,7.32769 8.73204 -17.217077,14.905019 5.63245 -2.57249,16.279447 8.780875 -2.576852,16.230912 8.780875 -17.868433'/> </IndexedFaceSet> </Shape> <Viewpoint DEF='doc Front' position='12.112917 4.390437 16.128923' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Front View' /> <Viewpoint DEF='doc Left' position='41.290635 4.390437 -10.220461' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Left View' orientation='0 1 0 1.571'/> <Viewpoint DEF='doc Top' position='12.112917 31.724789 -10.220461' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Top View' orientation='-1 0 0 1.571'/> <Viewpoint DEF='doc Back' position='12.112917 4.390437 -36.569845' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Back View' orientation='0 1 0 3.142'/> <Viewpoint DEF='doc Right' position='-17.064802 4.390437 -10.220461' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Right View' orientation='0 -1 0 1.571'/> <Viewpoint DEF='doc Bottom' position='12.112917 -22.943915 -10.220461' jump='true' centerOfRotation='12.112917 4.390437 -10.220461' description='doc Bottom View' orientation='1 0 0 1.571'/> <NavigationInfo DEF='ExamineNavInfo' type='"EXAMINE","LOOKAT"' /> </Scene> </X3D>