Changeset 62 for trunk/workshop-foss4g/joins_advanced.rst
- Timestamp:
- 17/03/2012 00:49:40 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/workshop-foss4g/joins_advanced.rst
r54 r62 4 4 ======================================= 5 5 6 Dans la partie précédente nous avons vu les fonctions :command:`ST_Centroid(geometry)` et :command:`ST_Union( [geometry])` ainsi que quelques exemples simples. Dans cette partie nous réaliseront des choses plus éllaborées.6 Dans la partie précédente nous avons vu les fonctions :command:`ST_Centroid(geometry)` et :command:`ST_Union(geometry)` ainsi que quelques exemples simples. Dans cette partie nous réaliserons des choses plus élaborées. 7 7 8 8 .. _creatingtractstable: … … 11 11 ------------------------------------------------ 12 12 13 Dans le répertoire ``\data\`` des travaux pratiques, il y a un fichier qui contient des données attributaires, mais pas de géométries, ce fichier est nommé ``nyc_census_sociodata.sql``. La table contient des données sociaux-économiques int erressantes à propos de New York : revenus financiers, éducation .... Il y a juste un problÚme, les données sont rassembléen "trace de recensement" et nous n'avons pas de données spatiales associées !13 Dans le répertoire ``\data\`` des travaux pratiques, il y a un fichier qui contient des données attributaires, mais pas de géométries, ce fichier est nommé ``nyc_census_sociodata.sql``. La table contient des données sociaux-économiques intéressantes à propos de New York : revenus financiers, éducation .... Il y a juste un problÚme, les données sont rassemblées en "trace de recensement" et nous n'avons pas de données spatiales associées ! 14 14 15 15 Dans cette partie nous allons … … 18 18 * Créer une table spatiale pour les traces de recensement 19 19 * Joindre les données attributaires à nos données spatiales 20 * Réaliser certaines anal ises sur nos nouvelles données21 20 * Réaliser certaines analyses sur nos nouvelles données 21 22 22 Chargement du fichier nyc_census_sociodata.sql 23 23 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 24 25 25 #. Ouvrez la fenêtre de requêtage SQL depuis PgAdmin 26 #. S electionnez **File->Open** depuis le menu et naviguez jusqu'au fichier ``nyc_census_sociodata.sql``26 #. Sélectionnez **File->Open** depuis le menu et naviguez jusqu'au fichier ``nyc_census_sociodata.sql`` 27 27 #. Cliquez sur le bouton "Run Query" 28 #. Si vous cliquez sur le bouton "Refresh" depuis PgAdmin, la liste des table devrait contenir votre nouvelle table ``nyc_census_sociodata``29 28 #. Si vous cliquez sur le bouton "Refresh" depuis PgAdmin, la liste des tables devrait contenir votre nouvelle table ``nyc_census_sociodata`` 29 30 30 Création de la table traces de recensement 31 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~32 33 Comme nous l'avons dans la partie précédente, nous pouvons construire des géométries de niveau suppérieur en utilisant nos blocks de base en utilisant une partie de la clef ``blkid``. Afin de calculer les traces de recensement, nous avons besoin de regrouper les blocks en uitlisant les 11 premiers caractÚres de la colonne ``blkid``.34 31 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 33 Comme nous l'avons fait dans la partie précédente, nous pouvons construire des géométries de niveau suppérieur en utilisant nos blocs de base en utilisant une partie de la clef ``blkid``. Afin de calculer les traces de recensement, nous avons besoin de regrouper les blocs en uitlisant les 11 premiers caractÚres de la colonne ``blkid``. 34 35 35 :: 36 36 37 37 360610001009000 = 36 061 00100 9000 38 38 39 36 = State of New York 39 36 = State of New York 40 40 061 = New York County (Manhattan) 41 41 000100 = Census Tract … … 44 44 45 45 Création de la nouvelle table en utilisant la fonction d'agrégation :command:`ST_Union` : 46 47 .. code-block:: sql 48 46 47 .. code-block:: sql 48 49 49 -- Création de la table 50 50 CREATE TABLE nyc_census_tract_geoms AS 51 SELECT 52 ST_Union(the_geom) AS the_geom, 51 SELECT 52 ST_Union(the_geom) AS the_geom, 53 53 SubStr(blkid,1,11) AS tractid 54 54 FROM nyc_census_blocks 55 55 GROUP BY tractid; 56 56 57 57 -- Indexation du champ tractid 58 58 CREATE INDEX nyc_census_tract_geoms_tractid_idx ON nyc_census_tract_geoms (tractid); 59 59 60 60 -- Mise à jour de la table geometry_columns 61 61 SELECT Populate_Geometry_Columns(); … … 64 64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 65 66 L'objectif est ici de regrouper les données spatiales que nous avons créé avec les don ées attributaires que nous avions chargé initialement.67 68 .. code-block:: sql 69 66 L'objectif est ici de regrouper les données spatiales que nous avons créé avec les données attributaires que nous avions chargé initialement. 67 68 .. code-block:: sql 69 70 70 -- Création de la table 71 71 CREATE TABLE nyc_census_tracts AS 72 SELECT 72 SELECT 73 73 g.the_geom, 74 74 a.* … … 76 76 JOIN nyc_census_sociodata a 77 77 ON g.tractid = a.tractid; 78 78 79 79 -- Indexation des géométries 80 80 CREATE INDEX nyc_census_tract_gidx ON nyc_census_tracts USING GIST (the_geom); 81 81 82 82 -- Mise à jour de la table geometry_columns 83 83 SELECT Populate_Geometry_Columns(); … … 85 85 .. _interestingquestion: 86 86 87 Répondre à une question int erressante88 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~89 90 Répondre à une question int erressante ! "Lister les 10 meilleurs quartiers ordonnées par la proportion de personne ayant acquis un diplome".91 92 .. code-block:: sql 93 94 SELECT 95 Round(100.0 * Sum(t.edu_graduate_dipl) / Sum(t.edu_total), 1) AS graduate_pct, 96 n.name, n.boroname 97 FROM nyc_neighborhoods n 98 JOIN nyc_census_tracts t 99 ON ST_Intersects(n.the_geom, t.the_geom) 87 Répondre à une question intéressante 88 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 89 90 Répondre à une question intéressante ! "Lister les 10 meilleurs quartiers ordonnés par la proportion de personnes ayant acquis un diplÃŽme". 91 92 .. code-block:: sql 93 94 SELECT 95 Round(100.0 * Sum(t.edu_graduate_dipl) / Sum(t.edu_total), 1) AS graduate_pct, 96 n.name, n.boroname 97 FROM nyc_neighborhoods n 98 JOIN nyc_census_tracts t 99 ON ST_Intersects(n.the_geom, t.the_geom) 100 100 WHERE t.edu_total > 0 101 101 GROUP BY n.name, n.boroname … … 103 103 LIMIT 10; 104 104 105 Nous sommons les statistiques qui nous int erressent, nous les divisons ensuite à la fin. Afin d'aviter l'erreur de non-division par zero, nous ne prennons pas en compte les quartiers qui n'ont aucune personne ayant obtenu un diplome.106 107 :: 108 109 graduate_pct | name | boroname 105 Nous sommons les statistiques qui nous intéressent, nous les divisons ensuite à la fin. Afin d'éviter l'erreur de non-division par zéro, nous ne prenons pas en compte les quartiers qui n'ont aucune personne ayant obtenu un diplÃŽme. 106 107 :: 108 109 graduate_pct | name | boroname 110 110 --------------+-------------------+----------- 111 111 40.4 | Carnegie Hill | Manhattan … … 119 119 29.8 | West Village | Manhattan 120 120 29.7 | Central Park | Manhattan 121 122 121 122 123 123 .. _polypolyjoins: 124 124 125 125 Polygones/Jointures de polygones 126 -------------------------------- -127 128 Dans notre requête int erressante (dans :ref:`interestingquestion`) nous avons utilisé la fonction :command:`ST_Intersects(geometry_a, geometry_b)` pour déterminer quelle entité polygonale à inclure dans chaque groupe de quartier. Ce qui nous conduit à la question : que ce passe-t-il si une entité tombe ntre deux quartier ? Il intersectera chacun d'entre eux et ainsi sera inclu dans **chacun** des résultats.126 -------------------------------- 127 128 Dans notre requête intéressante (dans :ref:`interestingquestion`) nous avons utilisé la fonction :command:`ST_Intersects(geometry_a, geometry_b)` pour déterminer quelle entité polygonale à inclure dans chaque groupe de quartier. Ce qui nous conduit à la question : que ce passe-t-il si une entité tombe entre deux quartiers ? Il intersectera chacun d'entre eux et ainsi sera inclut dans **chacun** des résultats. 129 129 130 130 .. image:: ./screenshots/centroid_neighborhood.png … … 132 132 Pour éviter ce cas de double comptage il existe trois méthodes : 133 133 134 * La méthode simple consiste a s'assurer que chaque entité ne se retrouve que dans **un** seul groupe géogra hique (en utilisant :command:`ST_Centroid(geometry)`)134 * La méthode simple consiste a s'assurer que chaque entité ne se retrouve que dans **un** seul groupe géographique (en utilisant :command:`ST_Centroid(geometry)`) 135 135 * La méthode complexe consiste à disviser les parties qui se croisent en utilisant les bordures (en utilisant :command:`ST_Intersection(geometry,geometry)`) 136 136 137 137 Voici un exemple d'utilisation de la méthode simple pour éviter le double comptage dans notre requête précédente : 138 138 139 139 .. code-block:: sql 140 140 141 SELECT 142 Round(100.0 * Sum(t.edu_graduate_dipl) / Sum(t.edu_total), 1) AS graduate_pct, 143 n.name, n.boroname 144 FROM nyc_neighborhoods n 145 JOIN nyc_census_tracts t 146 ON ST_Contains(n.the_geom, ST_Centroid(t.the_geom)) 141 SELECT 142 Round(100.0 * Sum(t.edu_graduate_dipl) / Sum(t.edu_total), 1) AS graduate_pct, 143 n.name, n.boroname 144 FROM nyc_neighborhoods n 145 JOIN nyc_census_tracts t 146 ON ST_Contains(n.the_geom, ST_Centroid(t.the_geom)) 147 147 WHERE t.edu_total > 0 148 148 GROUP BY n.name, n.boroname 149 149 ORDER BY graduate_pct DESC 150 150 LIMIT 10; 151 151 152 152 Remarquez que la requête prend plus de temps à s'exécuter, puisque la fonction :command:`ST_Centroid` doit être effectuée pour chaque entité. 153 153 154 154 :: 155 155 156 graduate_pct | name | boroname 156 graduate_pct | name | boroname 157 157 --------------+-------------------+----------- 158 158 49.2 | Carnegie Hill | Manhattan … … 166 166 30.1 | Downtown | Brooklyn 167 167 28.4 | Cobble Hill | Brooklyn 168 168 169 169 Ãviter le double comptage change le résultat ! 170 170 … … 175 175 ---------------------------------------------- 176 176 177 Une requête qu'il est sympat de demander est : "Comment les temps de permutation des gens proches (dans un rayon de 500 metres ) des stations de métros diffÚrent de ceuxqui en viveloin ? "178 179 Néanmoins, la question rencontre les même problÚme de double comptage : plusieurs personnes seront dans un rayon de 500 metres de plusieurs stations de métros différentes. Coparons la population de New York :177 Une requête qu'il est "sympa" de demander est : "Comment les temps de permutation des gens proches (dans un rayon de 500 mÚtres ) des stations de métro diffÚrent de ceux qui en vivent loin ? " 178 179 Néanmoins, la question rencontre les mêmes problÚmes de double comptage : plusieurs personnes seront dans un rayon de 500 mÚtres de plusieurs stations de métro différentes. Comparons la population de New York : 180 180 181 181 .. code-block:: sql … … 183 183 SELECT Sum(popn_total) 184 184 FROM nyc_census_blocks; 185 185 186 186 :: 187 187 188 188 8008278 189 190 Avec la population des gens de New York dans un rayon de 500 m etres d'une station de métros:189 190 Avec la population des gens de New York dans un rayon de 500 mÚtres d'une station de métro : 191 191 192 192 .. code-block:: sql … … 196 196 JOIN nyc_subway_stations subway 197 197 ON ST_DWithin(census.the_geom, subway.the_geom, 500); 198 198 199 199 :: 200 200 201 201 10556898 202 202 203 Il y a plus de personnes proches du métro qu'il y a de per onnes ! Clairement, notre requête SQL simple rencontre un gros problÚme de double comptage. Vous pouvez voir le problÚme en regardant l'image des zones tampons créées pour les stations.203 Il y a plus de personnes proches du métro qu'il y a de personnes ! Clairement, notre requête SQL simple rencontre un gros problÚme de double comptage. Vous pouvez voir le problÚme en regardant l'image des zones tampons créées pour les stations. 204 204 205 205 .. image:: ./screenshots/subways_buffered.png 206 206 207 La solution est de s'assurer que nous avons seulement des bloc ks distincts avant de les les regrouper. Nou spouvons réaliser cela en cassant notre requête en sous-requêtes qui récupÚre les blocks distincts, regroupé ensuite pour retrouner notre réponse :207 La solution est de s'assurer que nous avons seulement des blocs distincts avant de les regrouper. Nous pouvons réaliser cela en cassant notre requête en sous-requêtes qui récupÚrent les blocs distincts, les regroupent pour ensuite retourner notre réponse : 208 208 209 209 .. code-block:: sql … … 216 216 ON ST_DWithin(census.the_geom, subway.the_geom, 500) 217 217 ) AS distinct_blocks; 218 218 219 219 :: 220 220 221 221 4953599 222 222 223 C'est mieux ! Donc un peu plus de 50 % de la population de New York vit à proximité (50m environ 5 à 7 minutes de marche) du métro. 224 225 226 223 C'est mieux ! Donc un peu plus de 50 % de la population de New York vit à proximité (500m, environ 5 à 7 minutes de marche) du métro. 224
Note: See TracChangeset
for help on using the changeset viewer.