Guazzo Jean-Marc - 2010/08/25
Résumé
Cet article présente une introduction volontairement simplifiée des fonctionnalités spatiales maintenant fournies avec SQL Server. Le but étant d'exposer les différents types de données spatiales et en détailler certains en profondeur.Il est agrémenté de quelques exemples d'utilisation de données spatiales.
Cet article s'adresse aux architectes ou aux développeurs ayant des connaissances de base en SQL.
Qu'est-ce qu'une donnée spatiale ?
Une donnée spatiale est une coordonnée représentant une localisation dans un espace quelconque. L'exemple le plus connu étant les notions de longitude et de latitude utilisés pour se localiser sur terre.
De la même manière, l'affichage de composant logiciel (icônes, boutons,...) sur un ordinateur se fait avec des coordonnées spatiales, X indiquant la position sur le plan horizontal, Y celle sur le plan vertical et Z la notion de profondeur ou d'élévation qui permet d'indiquer la localisation dans les 3 dimensions. Ces notions ne sont pas étrangères aux mathématiciens...
Ces trois axes sont souvent représentées avec les variable X,Y & Z tel que montré sur le schéma ci-dessous
Cet article présente une donnée spatiale comme la représentation de ces trois points sous un format utilisable par un système automatique. La définition officielle de Industrie Canada est plus riche : Données et renseignements qui sont liés à un emplacement à la surface de la Terre par des coordonnées scientifiques précises, comme des cartes, des cartes spécialisées, des photos aériennes, des images satellitaires et des données d'arpentage ou des relevés hydrographiques. http://www.ic.gc.ca/eic/site/trm-crt.nsf/fra/rm00196.html
Qu'est-ce qu'une donnée spatiale pour SQL Server ?
Pour SQL Server, les données spatiales représentent autant les points "POINT" (représentés par une coordonnée) que les ensembles de points reliés sous forme de ligne "LINESTRING" ou de polygones "POLYGON".
Vecteurs "LINESTRING"
© 2010 Microsoft Corporation. All rights reserved.Polygones "POLYGON"
© 2010 Microsoft Corporation. All rights reserved.
Les types de données GEOMETRY et GEOGRAPHY font partie d'une hiérarchie d'objet présentés ici
© 2010 Microsoft Corporation. All rights reserved.
La différence entre GEOMETRY et GEOGRAPHY consiste en une application de règles de calcul différentes entre les deux. En effet, le calcul d'une distance en géométrie planaire se fait avec l'application du théorème de Pythagore alors que les calculs entre des degrés de latitude ou longitude n'est pas linéaire, mais dépendante de la courbure de la terre.
De là, il existe des différences dans les calculs entre GEOMETRY et GEOGRAPHY.
GEOMETRY donne des résultats sans unité de mesure alors que les résultats pour GEOGRAPHY sont exprimés en mètres ou m².
Il existe d'autres limitations liés aux types qui sont expliqués sur la page :
"Types de données spatiales"http://technet.microsoft.com/fr-fr/library/bb964711.aspx.
Les exemples de cet article concernent principalement les données de type GEOGRAPHY.
Il existe plusieurs méthodes pour assigner une(des) valeur(s) à une variable de type GEOGRAPHY:
- STGeomFromText http://technet.microsoft.com/fr-fr/library/bb933834.aspx
- STPointFromText http://technet.microsoft.com/fr-fr/library/bb933979.aspx
- Liste complète http://technet.microsoft.com/fr-fr/library/bb933988.aspx
Longitude et Latitude en X Y ?
Pour la spécification des "GEOGRAPHY", il faut utiliser les coordonnées Longitude et latitude sous forme "degré décimal" (DD).
La conversion de 44°23"18' se fait avec le calcul suivant :
D = Degrés = 44
.d = (Minutes + (Secondes / 60) / 60 = (23 + (18/60))/60
DD = D + .d = 44.03883333
La longitude exprime l'angle à partir d'un méridien de référence, Greenwich.
Cet angle indique les orientations Ouest ou Est. En DD, une longitude Ouest est négative, une Est positive.
La latitude exprime l'angle à partir d'un plan de référence, l'équateur.
Cet angle indique les orientations Nord ou Sud. En DD, une latitude Sud est négative, une Nord positive.
Exemples:
Plattsburgh (Etat de NY) 44° 40'N 73° 30'W ¦ 44.670 -73.500
Quebec 46° 49'N 71° 15'W ¦ 46.833 -71.250
Londres 51° 30'N 0° 10'W ¦ 51.500 -0.167 (Juste "à côté" du méridien de Greenwich)
Quito 0° 13'S 78° 30'W ¦ -0.233 -78.500 (Presque sur l'équateur)
Et 0° 0'S 0° 0'W, c'est où ? Océan atlantique, 600km au sud du Ghana !
Pour la simplification des exemples, la longitude sera représentée par L et la latitude par l.
Utilisation des données "POINT"
Comme son nom l'indique une donnée POINT représente un point dans un espace.
Un point est défini au minimum par X et Y. Il est aussi possible de spécifier l'élévation Z et une mesure quelconque M (au format DOUBLE).
M permet de définir plus finement votre point : la date de relevé, la station ayant effectué le relevé,...
Z et M peuvent être NULL.
La création d'un point avec STGeomFromText : GEOGRAPHY::STGeomFromText('POINT(L l élévation mesure)',4326)
La méthode STGeomFromText est souvent la plus utilisée car elle permet d'analyser une chaîne de caractère et d'en retourner l'information indépendamment de son type (Point, LineString,...)
De plus cette méthode permet d'indiquer le système de référence de calcul qui doit être utilisé. Cette référence est importante car elle permet à SQL Server de savoir s'il s'agit de coordonnées pour une représentation "plate" de la terre, d'une représentation Sphérique ou de tout autre modèle de référence.
SQL Server gère en natif ± 390 références, la plus utilisée est la N°4326 "WGS 84", utilisée par les GPS.
La longitude exprime l'angle à partir d'un méridien de référence, Greenwich.
Cet angle indique les orientations Ouest ou Est. En DD, une longitude Ouest est négative, une Est positive.
La latitude exprime l'angle à partir d'un plan de référence, l'équateur.
Cet angle indique les orientations Nord ou Sud. En DD, une latitude Sud est négative, une Nord positive.
Exemples:
Plattsburgh (Etat de NY) 44° 40'N 73° 30'W ¦ 44.670 -73.500
Quebec 46° 49'N 71° 15'W ¦ 46.833 -71.250
Londres 51° 30'N 0° 10'W ¦ 51.500 -0.167 (Juste "à côté" du méridien de Greenwich)
Quito 0° 13'S 78° 30'W ¦ -0.233 -78.500 (Presque sur l'équateur)
Et 0° 0'S 0° 0'W, c'est où ? Océan atlantique, 600km au sud du Ghana !
Pour la simplification des exemples, la longitude sera représentée par L et la latitude par l.
Utilisation des données "POINT"
Comme son nom l'indique une donnée POINT représente un point dans un espace.
Un point est défini au minimum par X et Y. Il est aussi possible de spécifier l'élévation Z et une mesure quelconque M (au format DOUBLE).
M permet de définir plus finement votre point : la date de relevé, la station ayant effectué le relevé,...
Z et M peuvent être NULL.
La création d'un point avec STGeomFromText : GEOGRAPHY::STGeomFromText('POINT(L l élévation mesure)',4326)
La méthode STGeomFromText est souvent la plus utilisée car elle permet d'analyser une chaîne de caractère et d'en retourner l'information indépendamment de son type (Point, LineString,...)
De plus cette méthode permet d'indiquer le système de référence de calcul qui doit être utilisé. Cette référence est importante car elle permet à SQL Server de savoir s'il s'agit de coordonnées pour une représentation "plate" de la terre, d'une représentation Sphérique ou de tout autre modèle de référence.
SQL Server gère en natif ± 390 références, la plus utilisée est la N°4326 "WGS 84", utilisée par les GPS.
la liste des références valides pour un sql server peut être obtenue avec l'instruction select * from sys.spatial_reference_systems
Attention Les coordonnées géographiques sont toujours exprimées en lat/Long, ce qui représente une coordonnées y/x.
Pour la création avec STGeomFromText, il faut alors utiliser la séquence Longitude/Latitude !
Selon la documentation Microsoft, la création d'un point peut aussi se faire avec : = GEOGRAPHY::Point(X, Y, 4326);
Hors, dans ce cas, X est la latitude et Y la longitude !
L'Instruction GEOGRAPHY::STGeomFromText('POINT(-71.306 46.831)',4326) est donc égale à GEOGRAPHY::Point(46.831, -71.306, 4326) !
Ceci est dû au fait que l'instruction STGeomFromText prend en paramètre une chaîne de caractère au format WKT qui défini le point sous la forme POINT(Longitude latitude Élévation).
Si vous utilisez une technique, il est conseillé de ne pas utiliser l'autre dans un même script !
Exemple SQL:
DECLARE @bureauDMR GEOGRAPHY
SET @bureauDMR= GEOGRAPHY::STGeomFromText('POINT(-71.306 46.831 25)',4326) --[i]Localisation de DMR sur un plan XYZ.
SELECT @bureauDMR
La valeur retournée est 0xE6100000010DEE7C3F355E6A4740DD24068195D351C00000000000003940.
Vu la difficulté d'interpréter cette valeur, il existe maintenant un onglet résultat dans SQL Server de type "Spatial" qui représente une grille :
La flèche bleue représente le point dessiné.
Attention Les coordonnées géographiques sont toujours exprimées en lat/Long, ce qui représente une coordonnées y/x.
Pour la création avec STGeomFromText, il faut alors utiliser la séquence Longitude/Latitude !
Selon la documentation Microsoft, la création d'un point peut aussi se faire avec : = GEOGRAPHY::Point(X, Y, 4326);
Hors, dans ce cas, X est la latitude et Y la longitude !
L'Instruction GEOGRAPHY::STGeomFromText('POINT(-71.306 46.831)',4326) est donc égale à GEOGRAPHY::Point(46.831, -71.306, 4326) !
Ceci est dû au fait que l'instruction STGeomFromText prend en paramètre une chaîne de caractère au format WKT qui défini le point sous la forme POINT(Longitude latitude Élévation).
Si vous utilisez une technique, il est conseillé de ne pas utiliser l'autre dans un même script !
Exemple SQL:
DECLARE @bureauDMR GEOGRAPHY
SET @bureauDMR= GEOGRAPHY::STGeomFromText('POINT(-71.306 46.831 25)',4326) --[i]Localisation de DMR sur un plan XYZ.
SELECT @bureauDMR
La valeur retournée est 0xE6100000010DEE7C3F355E6A4740DD24068195D351C00000000000003940.
Vu la difficulté d'interpréter cette valeur, il existe maintenant un onglet résultat dans SQL Server de type "Spatial" qui représente une grille :
La flèche bleue représente le point dessiné.
Opérations possibles sur des "POINT"
- Il est possible d'effectuer des opérations de calculs entre des points :
DECLARE @distanceTroisRiviersToronto GEOGRAPHY
SET @distanceTroisRiviersToronto= GEOGRAPHY::STGeomFromText('POINT(-72.567 46.350 )',4326)
select @distanceTroisRiviersToronto.STDistance(GEOGRAPHY::STGeomFromText('POINT(-79.417 43.700)',4326))
Résultat (en mètres)
614657,203710419 = ±615km
- Vérifier que 2 points sont identiques avec STEquals
- Vérifier qu'un point est à l'intérieur d'un polygon avec STWithin
LINESTRING est la représentation d'un vecteur composé au minimum de 2 points distincts, ou vide.
© 2010 Microsoft Corporation. All rights reserved.
La création d'un linestring avec STGeomFromText :
GEOGRAPHY::STGeomFromText('LINESTRING(L l [elevation] [mesure],L l [elevation] [mesure],...)',4326)
Exemple d'un vecteur représentant le trajet Québec,Trois Rivières,Montréal,toronto
GEOGRAPHY::STGeomFromText('LINESTRING(-71.250 46.833 ,-72.567 46.350 ,-73.600 45.500 ,-79.417 43.700)',4326)
et
1: Québec 2: Trois-Rivières 3: Montréal 4: Toronto
Transposition de ce vecteur sur google Earth:
© 2010 Google. All rights reserved.
La création d'un linestring avec STGeomFromText :
GEOGRAPHY::STGeomFromText('LINESTRING(L l [elevation] [mesure],L l [elevation] [mesure],...)',4326)
Exemple d'un vecteur représentant le trajet Québec,Trois Rivières,Montréal,toronto
GEOGRAPHY::STGeomFromText('LINESTRING(-71.250 46.833 ,-72.567 46.350 ,-73.600 45.500 ,-79.417 43.700)',4326)
et
1: Québec 2: Trois-Rivières 3: Montréal 4: Toronto
Transposition de ce vecteur sur google Earth:
© 2010 Google. All rights reserved.
Opérations possibles sur des "LINESTRING"
- Déterminer la longueur d'un vecteur avec STLength
set @g= GEOGRAPHY::STGeomFromText('LINESTRING(-71.250 46.833 ,-72.567 46.350 ,-73.600 45.500 ,-79.417 43.700)',4326)
select @g.STLength()
Résultat (en mètres)
741324,790446812 = ±741km
- Déterminer Le point d'intersection de deux vecteurs
declare @line2 geography
set @line1 = GEOGRAPHY::STGeomFromText('LINESTRING(0 0, 12 10)',4326)
set @line2 = GEOGRAPHY::STGeomFromText('LINESTRING(0 11, 10 00)',4326)
select @line1 --affichage de la ligne 1
union all
select @line1.STIntersection(@line2) --affichage du point d'intersection
union all
select @line2 --affichage de la ligne 1
Résultat
Utilisation des données "POLYGON"
POLYGON représente une surface définie par chacun de ses points d'angle.
© 2010 Microsoft Corporation. All rights reserved.
Le chemin parcouru entre les différents points d'un polygone ne peut se croiser.
Un POLYGON peu contenir des "trous".
Chaque point accepte 4 valeurs : X, Y, Z (l'élévation) et M.
Les coordonnées du dernier point d'un POLYGON doivent toujours être identique à celle du premier point.
La création d'un POLYGON avec STGeomFromText :
GEOGRAPHY::STGeomFromText('POLYGON((L1 l1, L2 l2, L3 l3, L4 l4, [U] L1 l1 [U]))',4326)
Exemple d'un polygone Québec,Trois Rivières,Montréal,toronto
DECLARE @g GEOGRAPHY
set @g= GEOGRAPHY::STGeomFromText('POLYGON((-71.250 46.833, -72.567 46.350, -73.600 45.500, -79.417 43.700, -71.250 46.833))',4326)
select @g
! Erreur ! :
Extrait : " Cette erreur a souvent pour origine une mauvaise orientation de l'anneau du polygone."
Ceci est dû au fait que la création d'un polygone doit se faire dans le sens anti horlogique pour le pourtour et dans le sens horlogique pour les "trous".
Notre exemple devient donc :
Exemple d'un polygone Québec,toronto,Montréal,Trois Rivières,
DECLARE @g GEOGRAPHY
set @g= GEOGRAPHY::STGeomFromText('POLYGON((-71.250 46.833,-79.417 43.700, -73.600 45.500, -72.567 46.350, -71.250 46.833))',4326)
select @g
1: Québec 2: Trois-Rivières 3: Montréal 4: Toronto
La définition d'un "trou" doit être ajoutée à la définition du POLYGON :
Exemple avec des données de type GEOMETRY:
select GEOMETRY ::STGeomFromText( 'POLYGON ((302 263, 303 263, 303 265, 305 268, 308 272, 310 275, 314 279, 316 282, 318 284, 319 284, 321 286, 323 288, 325 290, 327 292, 331 295, 334 297, 337 300, 341 303, 345 305, 346 306, 347 307, 349 309, 350 310, 353 312, 354 314, 356 316, 357 318, 358 320, 360 323, 362 325, 365 328, 367 331, 369 334, 371 337, 375 340, 377 342, 380 345, 384 348, 386 351, 390 353, 392 355, 393 356, 395 357, 395 358, 398 360, 399 361, 399 362, 399 363, 397 370, 395 375, 391 382, 378 397, 374 404, 368 410, 360 416, 355 420, 347 423, 339 427, 330 429, 327 430, 319 430, 307 430, 300 430, 282 427, 267 423, 253 418, 240 412, 229 405, 221 398, 214 393, 206 382, 199 373, 192 363, 176 343, 168 328, 160 312, 148 286, 141 262, 138 239, 138 207, 153 173, 166 154, 187 131, 201 121, 210 115, 222 108, 253 94, 276 84, 294 80, 319 73, 340 70, 356 72, 379 75, 398 82, 411 91, 421 102, 435 118, 436 122, 435 122, 434 122, 426 129, 403 148, 388 167, 369 185, 357 202, 350 211, 342 219, 330 230, 316 242, 313 246, 312 246, 311 247, 310 247, 310 248, 308 248, 302 263), (271 371, 271 372, 274 375, 280 378, 284 379, 294 379, 303 377, 307 375, 309 373, 312 367, 313 364, 314 358, 315 351, 314 346, 310 339, 307 336, 302 333, 299 333, 292 333, 284 336, 283 337, 280 340, 277 343, 273 350, 270 353, 270 354, 269 359, 268 360, 268 362, 268 363, 268 365, 268 367, 269 369, 270 370, 271 371))'
,0)
Cas pratiques
- Cas 1 : Respect d'une zone de pêche
geography::Parse('polygon((
-69.86402778 48.72454722,
-68.86096944 47.81318611,
-67.180925 47.01669722,
-66.47033611 43.1619,
-64.36702222 43.46948611,
-59.93453333 44.30665,
-56.79570556 45.03044444,
-53.26256389 44.82328333,
-51.64941667 46.93513611,
-63.43413333 50.99363333,
-69.86402778 48.72454722)
)');
Nous pouvons alors imaginer que certains bateaux de pêches sont munis de GPS qui génèrent des fichiers reprenant le parcours de pêche effectué.
Ceci servant à établir une base statistique des bateaux qui restent ou sortent de cette zone.
Représentation :
Dans notre exemple, 2 tracés de bateaux.
Le premier représenté en bleu est resté dans la zone limitée :
geography::Parse('LINESTRING(
-64.21 48.52,
-64.00 48.00,
-63.50 47.50,
-63.00 47.00,
-63.00 48.00,
-63.50 48.00,
-64.00 48.00
)')
Le deuxième représenté en rose a dépassé la zone limitée :
geography::Parse('LINESTRING(
-64.21 48.52,
-64.00 48.52,
-63.50 48.52,
-63.00 48.52,
-62.50 48.52,
-62.00 48.52,
-61.50 48.52,
-61.00 48.52,
-60.50 48.52,
-60.00 48.52,
-59.80 49.00,
-59.60 49.48,
-59.40 49.96,
-59.20 50.44,
-59.00 50.92,
-58.80 51.40,
-58.60 51.88,
-58.40 52.36
)')
SQL Server peut nous dire si un chemin est dans un polygone ou s'il en déborde.
En faisant une union entre le POLYGON et le LINESTRING, le résultat doit être égal au POLYGON.
S'il est différent, le LINESTRING a des points en dehors du POLYGON.
declare @zoneDePeche geography
set @zoneDePeche= geography::Parse('polygon((-69.86402778 48.72454722,-68.86096944 47.81318611,-67.180925 47.01669722,-66.47033611 43.1619,-64.36702222 43.46948611,-59.93453333 44.30665,-56.79570556 45.03044444,-53.26256389 44.82328333,-51.64941667 46.93513611,-63.43413333 50.99363333,-69.86402778 48.72454722))')
declare @bateau1 geography
set @bateau1= geography::Parse('LINESTRING(-64.21 48.52,-64.00 48.00,-63.50 47.50,-63.00 47.00,-63.00 48.00,-63.50 48.00,-64.00 48.00)')
declare @bateau2 geography
set @bateau2=geography::Parse('LINESTRING(-64.21 48.52,-64.00 48.52,-63.50 48.52,-63.00 48.52,-62.50 48.52,-62.00 48.52,-61.50 48.52,-61.00 48.52,-60.50 48.52,-60.00 48.52,-59.80 49.00,-59.60 49.48,-59.40 49.96,-59.20 50.44,-59.00 50.92,-58.80 51.40,-58.60 51.88,-58.40 52.36)')
select @zoneDePeche.STEquals( @zoneDePeche.STUnion(@bateau1))
==> Résultat = 1. Le bateau est resté dans la zone
select @zoneDePeche.STEquals( @zoneDePeche.STUnion(@bateau2))
==> Résultat = 0. Le bateau est sorti de la zone
- Cas 2 : Top 10 des villes Canadiennes par population
Pour cette requête, il faut une table reprenant les villes du monde entier extraites du fichier CITIES1000.ZIP du site Geonames, http://www.geonames.org.
Ce fichier, reprenant toutes les villes du monde de plus de 1000 habitants est disponible ici :http://download.geonames.org/export/dump/cities1000.zip
Etape 1 : Création de la table "Villes"
CREATE TABLE [dbo].[Villes]
(
[geonameid] INT PRIMARY KEY,
[Nom] NVARCHAR(200),
[NomAscii] VARCHAR(200),
[AutresNoms] VARCHAR(5000),
[latitude] DECIMAL(38,10),
[longitude] DECIMAL(38,10),
[classGeoname] VARCHAR(10),
[codeGeoname] VARCHAR(10),
[codePays] VARCHAR(2),
[cc2] VARCHAR(60),
[CodeAdmin1code] VARCHAR(20),
[CodeAdmin2code] VARCHAR(80),
[CodeAdmin3code] VARCHAR(20),
[CodeAdmin4code] VARCHAR(20),
[Population] bigINT,
[Elevation] INT,
[gtopo30] INT,
[TimeZone] VARCHAR(100),
[MAJdate] DATETIME
)
GO
Etape 2 : Insertion "BULK" des données dans la table :
DECLARE @bulk_cmd varchar(1000)
SET @bulk_cmd = 'BULK INSERT Villes
FROM ''D:\source\cities1000\cities1000.txt''
WITH (ROWTERMINATOR = '''+CHAR(10)+''')'
EXEC(@bulk_cmd)
GO
Etape 3 : Ajout de la colonne de type GEOGRAPHY
ALTER TABLE [dbo].[Villes]
ADD SQLLocalisation GEOGRAPHY
GO
Etape 4 : Calcul de la valeur de la colonne de type GEOGRAPHY
UPDATE [dbo].[Villes]
SET [SQLLocalisation] = Geography::Parse('POINT(' +
CAST([longitude] AS VARCHAR(20)) + ' ' +
CAST([latitude] AS VARCHAR(20)) + ')')
GO
La table Villes contient maintenant les données requises pour faire notre requête et en générer le graphique
select top 10 NomAscii,population,SQLLocalisation from Villes
where codePays='CA'
order by population desc
Dans ce cas, l'onglet de résultat Spatial de SQL Server Management Studio n'est pas très utile.
Il faut utiliser "SQL Server Business Intelligence Development Studio" qui permet de générer des rapports qui pourraient être hébergé sur le server.
Il existe un contrôle "Map" qui permet d'afficher une carte et de la lier à Microsoft Bing Maps.
Note : Les informations de localisation de Geonames sont correctes mais concernant la population, elles ne sont pas récentes et ne prennent pas en compte les valeurs renseignées par le recensement 2006 de "Statistique Canada" disponible ici : http://www12.statcan.ca/english/census06/data/popdwell/Table.cfm?T=201&S=3&O=D&RPP=150
Indexation
Comme tous la plupart des types de données utilisés par SQL Server, il possible de créer un index sur les données spatiales.
Instruction :
CREATE SPATIAL INDEX NomDeLIndex ON NomDeLaTable(NomDeLaColonne);
Néanmoins, il faut savoir que l'utilisation par défaut ne couvre pas toutes les possibilités et situations.
En effet, de par sa nature même, le type de données GEOGRAPHY nécessite une gestion des index très particulière.
En effet, de par sa nature même, le type de données GEOGRAPHY nécessite une gestion des index très particulière.
Les données géographiques simples telle que POINT sont déjà à deux dimensions alors qu'un index classique ne travaille que sur une dimension.
Les données multiples (LINESTRING,POLYGON,...) sont encore plus complexes à indexer.
Il existe donc plusieurs méthodes d'indexation qu'il est inutile d'expliquer ici vu l'excellent article de la documentation de SQL Server à ce sujet :
"Vue d'ensemble de l'indexation spatiale" http://technet.microsoft.com/fr-fr/library/bb964712.aspx.
Liens :
Industrie Canada - Définition de Donnée spatiale http://www.ic.gc.ca/eic/site/trm-crt.nsf/fra/rm00196.html
Microsoft - Types de données spatiales http://technet.microsoft.com/fr-fr/library/bb964711.aspx.
Wikipedia - WGS84 http://fr.wikipedia.org/wiki/WGS_84.
Go4Answers - Exemple de polygone avec "Trou" http://www.go4answers.com/Example/create-geography-multipolygon-wkt-51932.aspx.
Geonames - une base de données Open Source contenant les coordonnées de villes, pays, montagne,... http://www.geonames.org.
Statistique Canada - Liste des villes et leur population http://www12.statcan.ca/english/census06/data/popdwell/Table.cfm?T=201&S=3&O=D&RPP=150
Microsoft - Vue d'ensemble de l'indexation spatiale http://technet.microsoft.com/fr-fr/library/bb964712.aspx.
Microsoft - Getting Started with the geography Data Type http://msdn.microsoft.com/en-us/library/bb895266(v=SQL.100).aspx
Jason Follas - SQL Server Spatial Data part 1 http://www.jasonfollas.com/blog/archive/2008/03/14/sql-server-2008-spatial-data-part-1.aspx
SQLMusings - SQL Server Spatial Data for Canada http://www.sqlmusings.com/2010/03/19/sql-server-spatial-data-for-canada/
Industrie Canada - Définition de Donnée spatiale http://www.ic.gc.ca/eic/site/trm-crt.nsf/fra/rm00196.html
Microsoft - Types de données spatiales http://technet.microsoft.com/fr-fr/library/bb964711.aspx.
Wikipedia - WGS84 http://fr.wikipedia.org/wiki/WGS_84.
Go4Answers - Exemple de polygone avec "Trou" http://www.go4answers.com/Example/create-geography-multipolygon-wkt-51932.aspx.
Geonames - une base de données Open Source contenant les coordonnées de villes, pays, montagne,... http://www.geonames.org.
Statistique Canada - Liste des villes et leur population http://www12.statcan.ca/english/census06/data/popdwell/Table.cfm?T=201&S=3&O=D&RPP=150
Microsoft - Vue d'ensemble de l'indexation spatiale http://technet.microsoft.com/fr-fr/library/bb964712.aspx.
Microsoft - Getting Started with the geography Data Type http://msdn.microsoft.com/en-us/library/bb895266(v=SQL.100).aspx
Jason Follas - SQL Server Spatial Data part 1 http://www.jasonfollas.com/blog/archive/2008/03/14/sql-server-2008-spatial-data-part-1.aspx
SQLMusings - SQL Server Spatial Data for Canada http://www.sqlmusings.com/2010/03/19/sql-server-spatial-data-for-canada/