Manuel PostGIS avec JTS


Dans ce manuel nous allons vous présenter comment installer PostGIS en utilisant la librarie JTS à la place GEOS.

 Table des matières

Prérequis
Compilation des sources de JTS et création de l'archive JAR
Création des librairies dynamiques et des fichiers d'entêtes
Tester la liaison à la librairie libjts.so à l'aide des exemples fournis
Installation de JTS et création de l'utilitaire jts-config
Compilation de PostGIS et liaison avec JTS

Prérequis

Afin de pouvoir compiler PostGIS en utilisant la librairie JTS il vous faudra disposer de certains outils.

Tout d'abort, afin de compiler les source java du projet JTS qui se trouvent dans le répertoire src vous aurez besoin d'un compilateur JAVA : javac. À prioris, le moyen le plus simple pour vous assurer que vous disposez bien de cet outils consiste à utiliser la commande javac --help. Si vous n'avez pas de résultat ou une erreur vous informant que javac n'a pas été trouvé, installez un des jdk disponibles pour votre système.

Pour notre part nous avons utilisé le jdk de SUN® dont voici les informations relatives à l'environnement d'exécution, obtenues avec la commande java -version :

java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)

En plus des outils nécessaires à la compilation, vous aurez besoin d'installer un paquet java : jdbc3-oracle.

Pour pouvoir créer la librairie C libjts.so et libgeom_static.so vous aurez besoin d'avoir un compilateur gcj ainsi que les outils associés tel que gcjh qui permet de générer automatiquement des fichiers d'entêtes (.h) à partir de classes java compilées. Vous pouvez vérifier aisément si cet outil est déjà installé sur cotre système en utilisant la commande gcj --version, sur le système où nous avons effectuer les tests nous obtenons les informations ci-dessous :

gcj (GCC) 4.1.2 (Gentoo 4.1.2)
Copyright © 2006 Free Software Foundation, Inc.
Ce logiciel est libre; voir les sources pour les conditions de copie. Il n'y a PAS
GARANTIE; ni implicite pour le MARCHANDAGE ou pour un BUT PARTICULIER.

Je pense que si vous avez le compilateur gcj l'ensemble des ses outils annexes seront aussi disponibles (vous pouvez néanmoins tester la présence de gcjh en lançant la commende du même nom).

haut de la page | table des matières

Compilation des sources de JTS et création de l'archive JAR

Maintenant que vous savez que les outils nécessaires à la compilation des sources java du projet JTS sont installées sur votre système, nous allons les utiliser afin de créer les archives JAR contenant l'ensemble du code binaire de la machine virtuelle JAVA.

Dans ce qui suit nous considérons que vous savez où sont installés les jars du paquet java que nous avons mentioné dans la section précédente, nous supposerons qu'ils sont tous installés au même endroit, dans le répertoire que nous noterons : $JAR_DIR.

Pour ce faire, il suffit de suivre le indications fournits ci-dessous :

  1. Rendez-vous dans le répertoire où vous avez décompressé les sources du projet JTS :
    cd jts-1.7.2
  2. Mise à jour de la variable d'environnement CLASSPATH permettant de définir l'ensemble des paquets java à utiliser lors de la compilation :
    machine jts-1.7.2 # for i in ${JAR_DIR}/*jar; do
    export CLASSPATH="${CLASSPATH}:$i"
    done
    
  3. Création des répertoires où seront compiler les classes java :
    machine jts-1.7.2 # for i in jts jtsio; do mkdir build/$i; done
    
  4. Compilation de JTS et création de l'archive jar :
    machine jts-1.7.2 # javac -nowarn -d build/jts $(find ./src/com/vividsolutions/jts/ -name "*.java") 
    machine jts-1.7.2 # jar -cfm jts.jar src/MANIFEST.MF -C build/jts .
    
  5. Ajout de la librairie JTS fraichement compimlée à notre variable CLASSPATH :
    machine jts-1.7.2 # export CLASSPATH="${CLASSPATH}:./jts.jar"
  6. Compilation des classes du répertoire jtsexample et création de l'archive jar :
    machine jts-1.7.2 # javac -d build/jtsexample $(find ./src/com/vividsolutions/jtsexample -name "*.java")
    machine jts-1.7.2 # jar -cfm jtsexample.jar src/MANIFEST.MF -C build/jtsexample .
    
  7. Compilation des classes du répertoire jtsio et création de l'archive jar :
    machine jts-1.7.2 # javac -d build/jtsio $(find ./src/jtsio/src -name "*.java")
    machine jts-1.7.2 # jar -cfm jtsio.jar src/MANIFEST.MF -C build/jtsio .
    
Si tout c'est passé correctement vous devriez trouver à la racine des sources du projet JTS (jts-1.7.2 dans notre exemple) trois archives binaires JAR : jts.jar, jtsexample.jar et jtsio.jar. haut de la page | table des matières

Création des librairies dynamiques et des fichiers d'entêtes

Maintenant que vous avez compiler les sources du projet JTS, vous devez créer des librairies dynamiques C. En effet vous savez sans doute que le code source de PostGIS est en C et non en java, un convertion est donc nécessaire. Heureusement GNU met à disposition, avec son compilateur gcc, un compilateur java permettant une telle convertion. Vous verrez de plus qu'il est aussi possible de générer des fichiers d'entête avec la commande gcjh.

Pour créer ces librairies dynamique ainsi que les fichiers d'entêtes requis lors de la compilation de PostGIS que nous verrons dans la section suivante, je vous invite à suivre les quelques instructions ci-dessous :

  1. Rendez vous dans le répertoire des sources du projet JTS et créez le répertoire où seront stoquées les classes java compilées :
    machine ~ # cd jts-1.7.2
    machine jts-1.7.2 # mkdir classes
    
  2. Compilation de l'ensemble des classes java avec gcj :
    machine jts-1.7.2 # gcj -C -d classes -classpath jts.jar $(find src/com/vividsolutions/jts -name '*.java')
    
  3. Définition de la variable d'environnement JTSCLASSES qui liste l'ensemble des classes requisent lors de la compimlation de PostGIS :
    machine jts-1.7.2 # export JTSCLASSES="com.vividsolutions.jts.geom.Geometry \
                com.vividsolutions.jts.geom.Point \
                com.vividsolutions.jts.geom.MultiPoint \
                com.vividsolutions.jts.geom.LineString \
                com.vividsolutions.jts.geom.LinearRing \
                com.vividsolutions.jts.geom.MultiLineString \
                com.vividsolutions.jts.geom.Polygon \
                com.vividsolutions.jts.geom.MultiPolygon \
                com.vividsolutions.jts.geom.GeometryCollection \
                com.vividsolutions.jts.geom.GeometryFactory \
                com.vividsolutions.jts.geom.PrecisionModel \
                com.vividsolutions.jts.geom.Coordinate \
                com.vividsolutions.jts.geom.CoordinateSequenceFactory \
                com.vividsolutions.jts.geom.CoordinateSequence \
                com.vividsolutions.jts.geom.IntersectionMatrix \
                com.vividsolutions.jts.io.WKTReader \
                com.vividsolutions.jts.io.WKTWriter \
                com.vividsolutions.jts.JTSVersion"
    
  4. Création du répertoire et de ses sous-répertoires destinés à contenir les fichiers d'entêtes générés avec gcjh :
    machine jts-1.7.2 # mkdir -p include
    machine jts-1.7.2 # jts_include_path="com/vividsolutions/jts/" \
    for i in geom io ;do
     mkdir -p include/${jts_include_path}/${i} ;
    done
    
  5. Rendez vous dans le répertoire nouvellemenet créé puis créez les fichiers d'entêtes correspondants :
    machine jts-1.7.2 # cd include
    machine jts-1.7.2/include # gcjh -classpath ../jts.jar ${JTSCLASSES}
    machine jts-1.7.2/include # cd ..
    machine jts-1.7.2 #
    
  6. Génération du fichier d'entête principal jts.h :
    machine jts-1.7.2 # gcjh -I jts.jar -stub -o ./include/jts.h ${JTSCLASSES}
    
  7. Génération de la librairie dynamique libjts.soà partir de l'archive binaire jts.jar :
    machine jts-1.7.2 # gcj -fPIC -O2 -shared -o libjts.so ./jts.jar
    
  8. Compilation de la classe Geometry.java :
    machine jts-1.7.2 # gcj -C -classpath jts.jar src/com/vividsolutions/jts/geom/Geometry.java
    machine jts-1.7.2 # mv src/com/vividsolutions/jts/geom/Geometry*class ./
    
  9. Génération de librairie libstatis_geom.so
    machine jts-1.7.2 # gcj -fPIC -classpath jts.jar -shared -o libstatic_geom.so "Geometry\$1.class"
    
Si tout c'est déroulé correctement vous devriez avoir des fichiers d'entêtes dans le répertoire include (find ./include pour s'en assurer) et les libraries dynamiques dans le répertoire où vous avez décompmressé les sources du projet JTS (jts-1.7.2 dans notre exemple). haut de la page | table des matières

Tester la liaison à la librairie libjts.so à l'aide des exemples fournis

Maintenant que nous avons créé notre librairie dynamique, il serait bon de la tester avant de tenter une installation.

Pour ce faire nous avons créé une boucle simple permettant la compilation et l'exécution des binaires compilé (en utilisant la classe java puis le binaire C correspondant). C'est ce que vous trouverez ci-dessous :

count=1;
sep="########################################################################" ;
for jf in $(find src/com/vividsolutions/jtsexample/ | grep .java); do 
    echo $sep;
    echo "Test n° $count : $jf";
    echo $sep;
    jc=$(echo $jf | sed "s:src.::g;s:.java::g;s:/:.:g") ;
    target=$(echo $jc | cut -d'.' -f5); 
    echo $jf \($jc\) $target; 
    gcj -L./ -ljts -O2 -classpath ./jts.jar $jf --main=$jc -o $target && \
    echo $sep && \
    echo "Executing in java mode" && \
    time java $jc &&  \
    echo && \
    echo $sep && \
    echo "Executing in C mode" && \
    time LD_LIBRARY_PATH="./" ./$target && \
    echo && \
    echo $sep && \
    echo; count=$(expr $count + 1); 
done
Si tout c'est passé correctement vous devriez obtenir des résultat équivalents à ceux fournis ci-dessous :
########################################################################
Test n° 1 : src/com/vividsolutions/jtsexample/geom/BasicExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/BasicExample.java (com.vividsolutions.jtsexample.geom.BasicExample) BasicExample
########################################################################
Executing in java mode
Geometry 1: LINESTRING (0 0, 10 10, 20 20)
Geometry 2: LINESTRING (0 0, 10 10, 20 20)
G1 intersection G2: MULTILINESTRING ((0 0, 10 10), (10 10, 20 20))

real    0m0.299s
user    0m0.230s
sys     0m0.024s

########################################################################
Executing in C mode
Geometry 1: LINESTRING (0 0, 10 10, 20 20)
Geometry 2: LINESTRING (0 0, 10 10, 20 20)
G1 intersection G2: MULTILINESTRING ((0 0, 10 10), (10 10, 20 20))

real    0m0.138s
user    0m0.115s
sys     0m0.023s

########################################################################

########################################################################
Test n° 2 : src/com/vividsolutions/jtsexample/geom/ConstructionExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/ConstructionExample.java (com.vividsolutions.jtsexample.geom.ConstructionExample) ConstructionExample
########################################################################
Executing in java mode
POINT (0 0)
POINT (0 0)
MULTIPOINT (0 0, 1 1)

real    0m0.194s
user    0m0.153s
sys     0m0.023s

########################################################################
Executing in C mode
POINT (0 0)
POINT (0 0)
MULTIPOINT (0 0, 1 1)

real    0m0.139s
user    0m0.118s
sys     0m0.021s

########################################################################

########################################################################
Test n° 7 : src/com/vividsolutions/jtsexample/geom/PrecisionModelExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/PrecisionModelExample.java (com.vividsolutions.jtsexample.geom.PrecisionModelExample) PrecisionModelExample
########################################################################
Executing in java mode
-------------------------------------------
Example 1 shows roundoff from computing in different precision models
A = POLYGON ((60 180, 160 260, 240 80, 60 180))
B = POLYGON ((200 260, 280 160, 80 100, 200 260))
Running example using Precision Model = Floating
A intersection B = POLYGON ((174.88372093023256 226.51162790697674, 213.33333333333334 140, 160.5194805194805 124.15584415584415, 116.47058823529412 148.62745098039215, 174.88372093023256 226.51162790697674))
Running example using Precision Model = Floating-Single
A intersection B = POLYGON ((174.883728 226.511627, 213.333328 140, 160.519485 124.155846, 116.470589 148.627457, 174.883728 226.511627))
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = POLYGON ((175 227, 213 140, 161 124, 116 149, 175 227))
-------------------------------------------
Example 2 shows that roundoff can change the topology of geometry computed in different precision models
A = POLYGON ((0 0, 160 0, 160 1, 0 0))
B = POLYGON ((40 60, 40 -20, 140 -20, 140 60, 40 60))
-------------------------------------------
Running example using Precision Model = Floating
A intersection B = MULTIPOLYGON (((40 0, 0 0, 40 0.25, 40 0)), ((140 0.875, 160 1, 160 0, 140 0, 140 0.875)))
-------------------------------------------
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = GEOMETRYCOLLECTION (LINESTRING (0 0, 40 0), POLYGON ((140 1, 160 1, 160 0, 140 0, 140 1)))

real    0m0.303s
user    0m0.237s
sys     0m0.028s

########################################################################
Executing in C mode
-------------------------------------------
Example 1 shows roundoff from computing in different precision models
A = POLYGON ((60 180, 160 260, 240 80, 60 180))
B = POLYGON ((200 260, 280 160, 80 100, 200 260))
Running example using Precision Model = Floating
A intersection B = POLYGON ((174.8837209302325561 226.5116279069767415, 213.3333333333333428 140, 160.5194805194805098 124.1558441558441501, 116.4705882352941159 148.6274509803921546, 174.8837209302325561 226.5116279069767415))
Running example using Precision Model = Floating-Single
A intersection B = POLYGON ((174.883728 226.511627, 213.333328 140, 160.519485 124.155846, 116.470589 148.627457, 174.883728 226.511627))
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = POLYGON ((175 227, 213 140, 161 124, 116 149, 175 227))
-------------------------------------------
Example 2 shows that roundoff can change the topology of geometry computed in different precision models
A = POLYGON ((0 0, 160 0, 160 1, 0 0))
B = POLYGON ((40 60, 40 -20, 140 -20, 140 60, 40 60))
-------------------------------------------
Running example using Precision Model = Floating
A intersection B = MULTIPOLYGON (((40 0, 0 0, 40 0.25, 40 0)), ((140 0.875, 160 1, 160 0, 140 0, 140 0.875)))
-------------------------------------------
Running example using Precision Model = Fixed (Scale=1.0)
A intersection B = GEOMETRYCOLLECTION (LINESTRING (0 0, 40 0), POLYGON ((140 1, 160 1, 160 0, 140 0, 140 1)))

real    0m0.131s
user    0m0.110s
sys     0m0.021s

########################################################################

########################################################################
Test n° 8 : src/com/vividsolutions/jtsexample/geom/SimpleMethodsExample.java
########################################################################
src/com/vividsolutions/jtsexample/geom/SimpleMethodsExample.java (com.vividsolutions.jtsexample.geom.SimpleMethodsExample) SimpleMethodsExample
########################################################################
Executing in java mode
A = POLYGON ((40 100, 40 20, 120 20, 120 100, 40 100))
B = LINESTRING (20 80, 80 60, 100 140)
A intersection B = LINESTRING (40 73.33333333333333, 80 60, 90 100)
A relate C = 1F20F1102

real    0m0.297s
user    0m0.223s
sys     0m0.025s

########################################################################
Executing in C mode
A = POLYGON ((40 100, 40 20, 120 20, 120 100, 40 100))
B = LINESTRING (20 80, 80 60, 100 140)
A intersection B = LINESTRING (40 73.3333333333333285, 80 60, 90 100)
A relate C = 1F20F1102

real    0m0.127s
user    0m0.105s
sys     0m0.022s

########################################################################

########################################################################
Test n° 9 : src/com/vividsolutions/jtsexample/linearref/LinearRefExample.java
########################################################################
src/com/vividsolutions/jtsexample/linearref/LinearRefExample.java (com.vividsolutions.jtsexample.linearref.LinearRefExample) LinearRefExample
########################################################################
Executing in java mode
=========================
Input Geometry: LINESTRING (0 0, 10 10, 20 20)
Indices to extract: 1.0 10.0
Extracted Line: LINESTRING (0.7071067811865475 0.7071067811865475, 7.071067811865475 7.071067811865475)
Indices of extracted line: 1.0 10.0
Midpoint of extracted line: (3.8890872965260117, 3.8890872965260117, NaN)
=========================
Input Geometry: MULTILINESTRING ((0 0, 10 10), (20 20, 25 25, 30 40))
Indices to extract: 1.0 20.0
Extracted Line: MULTILINESTRING ((0.7071067811865475 0.7071067811865475, 10 10), (20 20, 24.14213562373095 24.14213562373095))
Indices of extracted line: 1.0 20.0
Midpoint of extracted line: (7.424621202458749, 7.424621202458749, NaN)

real    0m0.193s
user    0m0.155s
sys     0m0.030s

########################################################################
Executing in C mode
=========================
Input Geometry: LINESTRING (0 0, 10 10, 20 20)
Indices to extract: 1.0 10.0
Extracted Line: LINESTRING (0.7071067811865474 0.7071067811865474, 7.0710678118654746 7.0710678118654746)
Indices of extracted line: 1.0 10.0
Midpoint of extracted line: (3.8890872965260117, 3.8890872965260117, NaN)
=========================
Input Geometry: MULTILINESTRING ((0 0, 10 10), (20 20, 25 25, 30 40))
Indices to extract: 1.0 20.0
Extracted Line: MULTILINESTRING ((0.7071067811865474 0.7071067811865474, 10 10), (20 20, 24.142135623730951 24.142135623730951))
Indices of extracted line: 1.0 20.0
Midpoint of extracted line: (7.424621202458749, 7.424621202458749, NaN)

real    0m0.127s
user    0m0.105s
sys     0m0.022s

########################################################################

########################################################################
Test n° 10 : src/com/vividsolutions/jtsexample/operation/distance/ClosestPointExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/distance/ClosestPointExample.java (com.vividsolutions.jtsexample.operation.distance.ClosestPointExample) distance
########################################################################
Executing in java mode
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: POINT (140 280)
Distance = 57.05597791103589
Closest points: LINESTRING (111.6923076923077 230.46153846153845, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: MULTIPOINT (140 280, 140 320)
Distance = 57.05597791103589
Closest points: LINESTRING (111.6923076923077 230.46153846153845, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 100, 200 200, 100 200, 100 100)
Geometry B: POINT (10 10)
Distance = 127.27922061357856
Closest points: LINESTRING (100 100, 10 10) (distance = 127.27922061357856)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (100 200, 200 100)
Distance = 0.0
Closest points: LINESTRING (150 150, 150 150) (distance = 0.0)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (150 121, 200 0)
Distance = 20.506096654409877
Closest points: LINESTRING (135.5 135.5, 150 121) (distance = 20.506096654409877)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (153 204, 185 224, 209 207, 238 222, 254 186)
Distance = 13.788860460124573
Closest points: LINESTRING (139.4956500724988 206.78661188980183, 153 204) (distance = 13.788860460124573)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (120 215, 185 224, 209 207, 238 222, 254 186)
Distance = 0.0
Closest points: LINESTRING (120 215, 120 215) (distance = 0.0)

real    0m0.247s
user    0m0.175s
sys     0m0.027s

########################################################################
Executing in C mode
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: POINT (140 280)
Distance = 57.055977911035896
Closest points: LINESTRING (111.6923076923076934 230.4615384615384527, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: POLYGON ((200 180, 60 140, 60 260, 200 180))
Geometry B: MULTIPOINT (140 280, 140 320)
Distance = 57.055977911035896
Closest points: LINESTRING (111.6923076923076934 230.4615384615384527, 140 280) (distance = 57.055977911035896)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 100, 200 200, 100 200, 100 100)
Geometry B: POINT (10 10)
Distance = 127.27922061357856
Closest points: LINESTRING (100 100, 10 10) (distance = 127.27922061357856)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (100 200, 200 100)
Distance = 0.0
Closest points: LINESTRING (150 150, 150 150) (distance = 0.0)
-------------------------------------
Geometry A: LINESTRING (100 100, 200 200)
Geometry B: LINESTRING (150 121, 200 0)
Distance = 20.506096654409877
Closest points: LINESTRING (135.5 135.5, 150 121) (distance = 20.506096654409877)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (153 204, 185 224, 209 207, 238 222, 254 186)
Distance = 13.788860460124573
Closest points: LINESTRING (139.4956500724987904 206.7866118898018328, 153 204) (distance = 13.788860460124573)
-------------------------------------
Geometry A: POLYGON ((76 185, 125 283, 331 276, 324 122, 177 70, 184 155, 69 123, 76 185), (267 237, 148 248, 135 185, 223 189, 251 151, 286 183, 267 237))
Geometry B: LINESTRING (120 215, 185 224, 209 207, 238 222, 254 186)
Distance = 0.0
Closest points: LINESTRING (120 215, 120 215) (distance = 0.0)

real    0m0.130s
user    0m0.107s
sys     0m0.023s

########################################################################

########################################################################
Test n° 11 : src/com/vividsolutions/jtsexample/operation/linemerge/LineMergeExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/linemerge/LineMergeExample.java (com.vividsolutions.jtsexample.operation.linemerge.LineMergeExample) linemerge
########################################################################
Executing in java mode
Lines formed (5):
[LINESTRING (60 210, 30 190, 30 160, 40 150, 70 150, 100 180, 100 200, 90 210, 60 210), LINESTRING (160 310, 130 300, 100 290, 70 270, 60 260, 50 240, 50 220, 60 210), LINESTRING (70 430, 100 430, 120 420, 140 400, 150 370, 160 340, 
160 310), LINESTRING (160 310, 200 330, 220 340, 240 360, 260 390, 260 410, 250 430), LINESTRING (160 310, 160 280, 160 250, 170 230, 180 210, 200 180, 220 160, 240 150, 270 150, 290 170)]

real    0m0.299s
user    0m0.240s
sys     0m0.031s

########################################################################
Executing in C mode
Lines formed (5):
[LINESTRING (60 210, 30 190, 30 160, 40 150, 70 150, 100 180, 100 200, 90 210, 60 210), LINESTRING (160 310, 130 300, 100 290, 70 270, 60 260, 50 240, 50 220, 60 210), LINESTRING (70 430, 100 430, 120 420, 140 400, 150 370, 160 340, 
160 310), LINESTRING (160 310, 200 330, 220 340, 240 360, 260 390, 260 410, 250 430), LINESTRING (160 310, 160 280, 160 250, 170 230, 180 210, 200 180, 220 160, 240 150, 270 150, 290 170)]

real    0m0.270s
user    0m0.207s
sys     0m0.044s

########################################################################

########################################################################
Test n° 12 : src/com/vividsolutions/jtsexample/operation/polygonize/PolygonizeExample.java
########################################################################
src/com/vividsolutions/jtsexample/operation/polygonize/PolygonizeExample.java (com.vividsolutions.jtsexample.operation.polygonize.PolygonizeExample) polygonize
########################################################################
Executing in java mode
Polygons formed (2):
[POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221)), POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98))]

real    0m0.480s
user    0m0.411s
sys     0m0.047s

########################################################################
Executing in C mode
Polygons formed (2):
[POLYGON ((189 98, 83 187, 185 221, 325 168, 189 98)), POLYGON ((185 221, 88 275, 180 316, 292 281, 185 221))]

real    0m0.252s
user    0m0.206s
sys     0m0.045s

########################################################################

########################################################################
Test n° 13 : src/com/vividsolutions/jtsexample/precision/EnhancedPrecisionOpExample.java
########################################################################
src/com/vividsolutions/jtsexample/precision/EnhancedPrecisionOpExample.java (com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample) EnhancedPrecisionOpExample
########################################################################
Executing in java mode
This call to intersection will throw a topology exception due to robustness problems:
com.vividsolutions.jts.geom.TopologyException: Directed Edge visited twice during ring-building at (708522.7796120486, 2402268.6542990115, NaN)
        at com.vividsolutions.jts.geomgraph.EdgeRing.computePoints(EdgeRing.java:141)
        at com.vividsolutions.jts.geomgraph.EdgeRing.(EdgeRing.java:70)
        at com.vividsolutions.jts.operation.overlay.MaximalEdgeRing.(MaximalEdgeRing.java:65)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.buildMaximalEdgeRings(PolygonBuilder.java:106)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(PolygonBuilder.java:80)
        at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(PolygonBuilder.java:69)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.computeOverlay(OverlayOp.java:180)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.getResultGeometry(OverlayOp.java:127)
        at com.vividsolutions.jts.operation.overlay.OverlayOp.overlayOp(OverlayOp.java:66)
        at com.vividsolutions.jts.geom.Geometry.intersection(Geometry.java:1051)
        at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.run(EnhancedPrecisionOpExample.java:77)
        at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.main(EnhancedPrecisionOpExample.java:53)
Using EnhancedPrecisionOp allows the intersection to be performed with no errors:
MULTIPOLYGON (((708653.498611049 2402311.54647056, 708657.0443590372 2402304.6290913913, 708522.7796120486 2402268.6542990115, 708653.498611049 2402311.54647056)), ((708258.7634430077 2402197.914011042, 708257.0393502527 2402206.5716
68428, 708257.0393502527 2402206.571668428, 708258.7634430077 2402197.9140110426, 708258.7634430077 2402197.914011042)))

real    0m0.589s
user    0m0.529s
sys     0m0.049s

########################################################################
Executing in C mode
This call to intersection will throw a topology exception due to robustness problems:
com.vividsolutions.jts.geom.TopologyException: Directed Edge visited twice during ring-building at (708522.7796120486, 2402268.6542990115, NaN)
   at com.vividsolutions.jts.geomgraph.EdgeRing.computePoints(libjts.so)
   at com.vividsolutions.jts.geomgraph.EdgeRing.(libjts.so)
   at com.vividsolutions.jts.operation.overlay.MaximalEdgeRing.(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.buildMaximalEdgeRings(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(libjts.so)
   at com.vividsolutions.jts.operation.overlay.PolygonBuilder.add(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.computeOverlay(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.getResultGeometry(libjts.so)
   at com.vividsolutions.jts.operation.overlay.OverlayOp.overlayOp(libjts.so)
   at com.vividsolutions.jts.geom.Geometry.intersection(libjts.so)
   at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.run(EnhancedPrecisionOpExample)
   at com.vividsolutions.jtsexample.precision.EnhancedPrecisionOpExample.main(EnhancedPrecisionOpExample)
Using EnhancedPrecisionOp allows the intersection to be performed with no errors:
MULTIPOLYGON (((708653.4986110490281134 2402311.5464705601334571, 708657.0443590371869504 2402304.6290913913398981, 708522.7796120486455038 2402268.6542990114539861, 708653.4986110490281134 2402311.5464705601334571)), ((708258.763443
0077159777 2402197.914011042099446, 708257.0393502527149394 2402206.5716684279032051, 708257.0393502527149394 2402206.5716684279032051, 708258.7634430077159777 2402197.9140110425651073, 708258.7634430077159777 2402197.914011042099446
)))

real    0m0.309s
user    0m0.220s
sys     0m0.052s

########################################################################

########################################################################
Test n° 14 : src/com/vividsolutions/jtsexample/technique/LineStringSelfIntersections.java
########################################################################
src/com/vividsolutions/jtsexample/technique/LineStringSelfIntersections.java (com.vividsolutions.jtsexample.technique.LineStringSelfIntersections) LineStringSelfIntersections
########################################################################
Executing in java mode
Line: LINESTRING (0 0, 10 10, 20 20)
Self Intersections: GEOMETRYCOLLECTION EMPTY
Line: LINESTRING (0 40, 60 40, 60 0, 20 0, 20 60)
Self Intersections: POINT (20 40)

real    0m0.528s
user    0m0.427s
sys     0m0.051s

########################################################################
Executing in C mode
Line: LINESTRING (0 0, 10 10, 20 20)
Self Intersections: GEOMETRYCOLLECTION EMPTY
Line: LINESTRING (0 40, 60 40, 60 0, 20 0, 20 60)
Self Intersections: POINT (20 40)

real    0m0.251s
user    0m0.203s
sys     0m0.047s

########################################################################

########################################################################
Test n° 15 : src/com/vividsolutions/jtsexample/technique/PolygonUnionUsingBuffer.java
########################################################################
src/com/vividsolutions/jtsexample/technique/PolygonUnionUsingBuffer.java (com.vividsolutions.jtsexample.technique.PolygonUnionUsingBuffer) PolygonUnionUsingBuffer
########################################################################
Executing in java mode
POLYGON ((80 140, 80 200, 100 200, 100 260, 180 260, 180 240, 240 240, 240 160, 200 160, 200 140, 80 140))

real    0m0.531s
user    0m0.470s
sys     0m0.057s

########################################################################
Executing in C mode
POLYGON ((80 140, 80 200, 100 200, 100 260, 180 260, 180 240, 240 240, 240 160, 200 160, 200 140, 80 140))

real    0m0.253s
user    0m0.212s
sys     0m0.039s

########################################################################

Vous aurez noté que les test numérotés de 3 à 6 n'ont pas été stipulés ici. En effet, ils renvoient tous une erreur qui est simplement liée au fait que la classe java ne contient pas de méthode main ce qui implique que la compilation échoue. Néanmoins grâce à ces quelques vérifications vous pouvez être assuré que votre librairie dynamique est utilisable. Vous aurez noté au passage que l'exécution des binaires C générés sont plus rapide que leurs équivalents java. haut de la page | table des matières

Installation de JTS et création de l'utilitaire jts-config

Maintenant que nous avons compiler les classes java, généré les fichiers d'entêtes et les librairies dynamique, il ne reste plus qu'à installer JTS dans notre système afin que nous souyons capable de compiler PostGIS en utilisant JTS à la place de GEOS.

Pour ce faire, rien de plus simple, il suffit d'installer les archives binaires jar où vous les installez d'habitude ($JAR_ DIR dans notre exemple) puis d'installer les fichier d'entêtes et le librairies dynamiques.

Comme d'habitude nous respecterons le standard FHS et nous installerons donc les librairies dans /usr/lib (sur un système x86, ou encore lib64 dans le cas d'une architecture amd64 ...) et le fichiers d'entêtes dans le répertoire /usr/include.

Voici les quelques commandes qui vous permettrons d'installer JTS dans l'arborescence de votre système :

machine jts-1.7.2 # mkdir /usr/share/doc/jts-1.7.2
machine jts-1.7.2 # cp -r ./test /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp -r doc/javadoc/ /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp *so /usr/lib/
machine jts-1.7.2 # cp -r include/* /usr/include/
machine jts-1.7.2 # cp -r src/ /usr/share/doc/jts-1.7.2/
machine jts-1.7.2 # cp *jar lib/JTS_Test.jar lib/acme.jar ${JAR_DIR}
Notez que JAR_DIR est une variable d'environnement que nous avons déjà utilisé et qui permet de savoir où sont installé les archives binaires jar sur votre système. Voilà tout est en ordre, vous devriez même être capable d'exécuter les binaires que nous avons généré lors de nos tests (cf section précédente) sans avoir à utiliser la variable d'environnement LD_LIBRARY_PATH que nous utilisions du fait que les librairies dynamiques que nous utilisions n'étaient pas encore installées. Comme vous le savez déjà, PostGIS lors de l'exécution du script condigure cherche un utilitaire du doux nom de jts-config, vous savez de plus que la librairie GEOS fournie un tel outils. Nous allons donc le copier dans notre répertoire courant (jts-1.7.2 dans notre exemple) afin de le modifier pour qu'il fournisse les informations nécessaire au bon déroulement de la compilation de PostGIS.
  1. Copie de geos-config et renomage en jts-config :
    machine jts-1.7.2 # cp $(type -P geos-config) ./jts-config
    
  2. Éditez le fichier pour qu'il fournisse les bonnes informations lors de la compilation de PostGIS, ili devrait donc contenir les informations suivantes :
    #!/bin/sh
    prefix=/usr
    exec_prefix=${prefix}
    libdir=${exec_prefix}/lib
    
    usage()
    {
        cat <&2
    fi
    while test $# -gt 0; do
    case "$1" in
        -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
        *) optarg= ;;
    esac
    case $1 in
        --prefix)
        echo ${prefix}
         ;;
        --version)
        echo 1.7.2
         ;;
        --libdir)
          echo ${libdir}
          ;;
        --includedir)
          echo ${prefix}/include
          ;;
        *)
          usage 1 1>&2
          ;;
      esac
      shift
    done
    
  3. Copiez ce fichier dans le répertoire /usr/bin puis donnez lui les droits nécessaires à son exécution :
    machine jts-1.7.2 # cp jts-config /usr/bin
    machine jts-1.7.2 # chmod 755 /usr/bin/jts-config
    
Voilà, si tout déroulé correctement vous devriez maintenant être capable de lancer la commande jts-config. haut de la page | table des matières

Compilation de PostGIS et liaison avec JTS

Mainetant que JTS est convenablement installée, il nous faut encore compiler PostGIS en utilisant cette librairie à la place de GEOS.

Pour ce faire, il suffiit de lancer le script configue avec les options : --with-proj pour activer le support de la reprojection (cf. lwgeom/lwgeom_transform.c du répertoire des source de PostGIS pour plus d'information) et --with-jts=$(type -P jts-config) afin que PostGIS soit informé de notre souhait de compiler la librairie dynamique liblwgeom.so en la liant à la libjts.so.

Pour résuler, il suffit de lancer les commandes ci-dessous :

machine postgis-1.2.1 # ./configure  --prefix=/usr --datadir=/usr/share/postgresql/contrib/ --libdir=/usr/lib/postgresql/ --with-proj --with-jts=$(type -P jts-config)
machine postgis-1.2.1 # make
machine postgis-1.2.1 # make install
Si tout c'est bien passé vous devriez être capable de vérifier si la liaison a été correctement effectué en utilisant l'outil ldd de lma manière suivante :
machine postgis-1.2.1 # ldd /usr/lib/postgresql/liblwgeom.so
        linux-gate.so.1 =>  (0xffffe000)
        libgcj.so.7 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libgcj.so.7 (0xb69df000)
        libjts.so => /usr/X11R6/lib/libjts.so (0xb68aa000)
        libstdc++.so.6 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libstdc++.so.6 (0xb67c8000)
        libproj.so.0 => /usr/X11R6/lib/libproj.so.0 (0xb6796000)
        libgcc_s.so.1 => /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libgcc_s.so.1 (0xb678a000)
        libc.so.6 => /lib/libc.so.6 (0xb6664000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb664d000)
        libdl.so.2 => /lib/libdl.so.2 (0xb6649000)
        libz.so.1 => /lib/libz.so.1 (0xb6637000)
        /lib/ld-linux.so.2 (0x80000000)
        libm.so.6 => /lib/libm.so.6 (0xb6612000)
Faite ici attention à ne pas avoir de lien cassé, c'est à dire des liens innexistant (des lignes contenant les charactères "not found"). Si le ldd vous a renvoyé les valeurs correctes, vous êtes alors fin prêt à créer votre première base de données spatiales utilisant JTS. Une fois votre base créé, connectez-vous à celle-ci et lancez ces deux commandes afin de vérifier que votre base PostGIS utilise bien JTS et non GEOS :
test_jts=# select postgis_full_version();
                         postgis_full_version     
---------------------------------------------------------------------- 
POSTGIS="1.2.1" JTS="1.7.2" PROJ="Rel. 4.5.0, 22 Oct 2006" USE_STATS
(1 ligne)

test_jts=# select postgis_jts_version(); 
 postgis_jts_version
 --------------------- 
 1.7.2
(1 ligne)
haut de la page | table des matières