Spatial database :: PostGIS

Voyons comment utiliser l'extension PostGIS de Postgresql pour stocker et gérer de l'information géographique dans un SGBD.

Installer PostGIS selon les instructions ici http://postgis.net/install. En résumé :

pour Mac, préférer l'approche “tout-en-un” http://postgresapp.com

pour Windows, installer d'abord Postgresql par EnterpriseDB, puis activer l'add-on PostGIS

si aucune ne fonctionne, explorer les autres approches pour réaliser cette installation

Compléter l'installation par la création d'une geodatabase :

lancer le serveur Postgresql et s'y connecter avec un client type pgAdmin

créer une database (ex. nommée ogo)

dans le contexte de cette base, exécuter la commande SQL suivante

CREATE EXTENSION postgis;

Pour la suite, ne pas oublier l'indispensable documentation avec son chapitre PostGIS Reference

Une première "geotable"

Créer une géotable

CREATE TABLE my4capitals (id serial PRIMARY KEY, name text);
SELECT AddGeometryColumn( 'my4capitals', 'the_geom', 4326, 'POINT', 2 );

Alimenter la table (cf. http://fr.wikipedia.org/wiki/Well-known_text)

INSERT INTO my4capitals VALUES ( nextval('my4capitals_id_seq'), 'Paris', ST_GeometryFromText( 'POINT(2.333 48.867)', 4326));
INSERT INTO my4capitals VALUES ( nextval('my4capitals_id_seq'), 'Bern', ST_GeometryFromText( 'POINT(7.433 46.95)', 4326));
INSERT INTO my4capitals VALUES ( nextval('my4capitals_id_seq'), 'Rome', ST_GeometryFromText( 'POINT(12.5 41.883)', 4326));
INSERT INTO my4capitals VALUES ( nextval('my4capitals_id_seq'), 'Madrid', ST_GeometryFromText( 'POINT(-3.71 40.41)', 4326));

Lire la table et ses données géographiques

SELECT ST_AsEWKT(the_geom) FROM my4capitals;
SELECT ST_AsGeoJSON(the_geom) FROM my4capitals;

Transformer des coordonnées d'une projection à une autre

SELECT ST_AsEWKT(ST_Transform(the_geom, 21781)) FROM my4capitals;

Géoservice Get4Capitals.php

Cet exemple montre comment créer un service sur mesure qui va publier l'information géographique de la géotable. Il est notamment faire usage du format GeoJSON pour transmettre ces données au client. OpenLayers saura par exemple l'exploiter facilement.

<?php
require_once 'GeoManager.php';
$conn = new Connection("host=10.192.57.14 port=5432 dbname=ogo user=ogo password=1234");
$query = "SELECT name, ST_AsGeoJSON(the_geom) from my4capitals";
$result = $conn->selectQuery($query);
$i = 0;
$fc = new FeatureCollection();
while ($row = pg_fetch_row($result)) {
$fc->addFeature(new Feature($i++, (json_decode($row[1])), array("name" => $row[0])));
}
echo json_encode($fc);
?>

On a besoin d'un GeoManager (GeoManager.php) qui sait communiquer avec la geodatabase.

<?php
class Connection {
private $CONFIG;
private $CONN;
function __construct($cfg) {
$this->CONFIG = $cfg;
return $this->CONN = pg_connect($this->CONFIG) or die('connection failed');
}
function selectQuery($query) {
$result = pg_query($this->CONN, $query);
if (!$result) throw new ErrorException($query);
return $result;
}
function insertQuery($query) {
pg_query($this->CONN, "BEGIN WORK");
$result = pg_query($this->CONN, $query);
if (!$result) {
pg_query($this->CONN, "ROLLBACK");
} else {
pg_query($this->CONN, "COMMIT");
}
}
}
class Feature
{
var $type;
var $geometry;
var $id;
var $properties;
function Feature($id,$geom,$properties) {
$this->type = "Feature";
$this->geometry = $geom;
$this->id = $id;
$this->properties = $properties;
}
}
class FeatureCollection
{
var $type;
var $features;
function FeatureCollection()
{
$this->type = "FeatureCollection";
$this->features = array();
}
function addFeature($feature) {
array_push($this->features,$feature);
}
}
?>

TODO

Tester ce géoservice et analyser les différentes étapes du processus

Terminer l'exemple en exploitant le géoservice dans OpenLayers avec une OpenLayers.Layer.Vector

Spatial database :: CartoDB

Créer un compte chez www.cartodb.com et s'y loguer

Première "CartoTable"

Créer une Empty table

Renommer la table (Edit Metadata) my4capitals

Exécuter dans le panneau SQL les insertions ci-dessous

INSERT INTO my4capitals (cartodb_id, name, the_geom) VALUES ( 0, 'Paris', ST_GeometryFromText( 'POINT(2.333 48.867)', 4326));
INSERT INTO my4capitals (cartodb_id, name, the_geom) VALUES ( 1, 'Bern', ST_GeometryFromText( 'POINT(7.433 46.95)', 4326));
INSERT INTO my4capitals (cartodb_id, name, the_geom) VALUES ( 2, 'Rome', ST_GeometryFromText( 'POINT(12.5 41.883)', 4326));
INSERT INTO my4capitals (cartodb_id, name, the_geom) VALUES ( 3, 'Madrid', ST_GeometryFromText( 'POINT(-3.71 40.41)', 4326));

Executer dans le panneau SQL et comparer la colonne the_geom et the_geom_webmercator

SELECT * from my4capitals

Basculer en mode MAP VIEW

Editer la CartoCSS à votre goût (onglet CSS)

Utilisation de la SQL API de CartoDB

Le Geomanager précédent est maintenant remplacé par une API Web. On peut y lancer des requêtes GQL. Par exemple :

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$api_key = "2e957be5f1e9c0793ca1725aab08274a795f2c3f";
$q = "select name, ST_AsGeoJSON(the_geom) as geom from my4capitals";
$url = "http://oertz.cartodb.com/api/v2/sql?api_key=" . $api_key. "&q=" . urlencode($q);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
header("Content-type: application/json");
echo $result;
?>

TODO

Adapter le géoservice Get4Capitals.php en utilisant l'API SQL de CartoDB pour afficher les 4 villes dans votre application OpenLayers.