Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-foss4g/geography.rst @ 41

Revision 1, 13.4 KB checked in by djay, 13 years ago (diff)

Initial import of the svn tree

RevLine 
[1]1.. _geography:
2
3Section 17: Geography
4=====================
5
6It is very common to have data in which the coordinate are "geographics" or "latitude/longitude".
7
8Unlike coordinates in Mercator, UTM, or Stateplane, geographic coordinates are **not cartesian coordinates**. Geographic coordinates do not represent a linear distance from an origin as plotted on a plane. Rather, these **spherical coordinates** describe the angular distance between the equator and the poles. In spherical coordinates a point is specified by the distance from the origin (the radius), the angle of rotation from the initial meridian plane, and the angle from the polar axis (analogous to a vector from the origin through the North Pole).
9
10.. image:: ./geography/cartesian_spherical.jpg
11
12You can treat geographic coordinates as approximate cartesian coordinates and continue to do spatial calculations. However, measurements of distance, length and area will be nonsensical. Since spherical coordinates measure **angular** distance, the units are in "degrees." Further, the approximate results from indexes and true/false tests like intersects and contains can become terribly wrong. The distance between points get larger as problem areas like the poles or the international dateline are approached.
13
14For example, here are the coordinates of Los Angeles and Paris.
15
16 * Los Angeles: ``POINT(-118.4079 33.9434)``
17 * Paris: ``POINT(2.3490 48.8533)``
18 
19The following calculates the distance between Los Angeles and Paris using the standard PostGIS cartesian :command:`ST_Distance(geometry, geometry)`.  Note that the SRID of 4326 declares a geographic spatial reference system.
20
21.. code-block:: sql
22
23  SELECT ST_Distance(
24    ST_GeometryFromText('POINT(-118.4079 33.9434)', 4326), -- Los Angeles (LAX)
25    ST_GeometryFromText('POINT(2.5559 49.0083)', 4326)     -- Paris (CDG)
26    );
27
28::
29
30  121.898285970107
31 
32Aha! 121! But, what does that mean?
33
34The units for spatial reference 4326 are degrees. So our answer is 121 degrees. But (again), what does that mean?
35
36On a sphere, the size of one "degree square" is quite variable, becoming smaller as you move away from the equator. Think of the meridians (vertical lines) on the globe getting closer to each other as you go towards the poles. So, a distance of 121 degrees doesn't *mean* anything. It is a nonsense number.
37
38In order to calculate a meaningful distance, we must treat geographic coordinates not as approximate cartesian coordinates but rather as true spherical coordinates.  We must measure the distances between points as true paths over a sphere -- a portion of a great circle.
39
40Starting with version 1.5, PostGIS provides this functionality through the ``geography`` type.
41
42.. note::
43
44  Different spatial databases have different approaches for "handling geographics"
45 
46  * Oracle attempts to paper over the differences by transparently doing geographic calculations when the SRID is geographic.
47  * SQL Server uses two spatial types, "STGeometry" for cartesian data and "STGeography" for geographics.
48  * Informix Spatial is a pure cartesian extension to Informix, while Informix Geodetic is a pure geographic extension.
49  * Similar to SQL Server, PostGIS uses two types, "geometry" and "geography".
50 
51Using the ``geography`` instead of ``geometry`` type, let's try again to measure the distance between Los Angeles and Paris. Instead of :command:`ST_GeometryFromText(text)`, we will use :command:`ST_GeographyFromText(text)`.
52
53.. code-block:: sql
54
55  SELECT ST_Distance(
56    ST_GeographyFromText('POINT(-118.4079 33.9434)'), -- Los Angeles (LAX)
57    ST_GeographyFromText('POINT(2.5559 49.0083)')     -- Paris (CDG)
58    );
59
60::
61
62  9124665.26917268
63
64A big number! All return values from ``geography`` calculations are in meters, so our answer is 9124km.
65
66Older versions of PostGIS supported very basic calculations over the sphere using the :command:`ST_Distance_Spheroid(point, point, measurement)` function. However, :command:`ST_Distance_Spheroid` is substantially limited. The function only works on points and provides no support for indexing across the poles or international dateline.
67
68The need to support non-point geometries becomes very clear when posing a question like "How close will a flight from Los Angeles to Paris come to Iceland?"
69
70.. image:: ./geography/lax_cdg.jpg
71
72Working with geographic coordinates on a cartesian plane (the purple line) yields a *very* wrong answer indeed! Using great circle routes (the red lines) gives the right answer. If we convert our LAX-CDG flight into a line string and calculate the distance to a point in Iceland using ``geography`` we'll get the right answer (recall) in meters.
73
74.. code-block:: sql
75
76  SELECT ST_Distance(
77    ST_GeographyFromText('LINESTRING(-118.4079 33.9434, 2.5559 49.0083)'), -- LAX-CDG
78    ST_GeographyFromText('POINT(-21.8628 64.1286)')                        -- Iceland 
79  );
80
81::
82
83  531773.757079116
84 
85So the closest approach to Iceland on the LAX-CDG route is a relatively small 532km.
86 
87The cartesian approach to handling geographic coordinates breaks down entirely for features that cross the international dateline. The shortest great-circle route from Los Angeles to Tokyo crosses the Pacific Ocean. The shortest cartesian route crosses the Atlantic and Indian Oceans.
88
89.. image:: ./geography/lax_nrt.png
90
91.. code-block:: sql
92
93   SELECT ST_Distance(
94     ST_GeometryFromText('Point(-118.4079 33.9434)'),  -- LAX
95     ST_GeometryFromText('Point(139.733 35.567)'))     -- NRT (Tokyo/Narita)
96       AS geometry_distance,
97   ST_Distance(
98     ST_GeographyFromText('Point(-118.4079 33.9434)'), -- LAX
99     ST_GeographyFromText('Point(139.733 35.567)'))    -- NRT (Tokyo/Narita)
100       AS geography_distance;
101   
102::
103
104   geometry_distance | geography_distance
105  -------------------+--------------------
106    258.146005837336 |   8833954.76996256
107
108
109Using Geography
110---------------
111
112In order to load geometry data into a geography table, the geometry first needs to be projected into EPSG:4326 (longitude/latitude), then it needs to be changed into geography.  The :command:`ST_Transform(geometry,srid)` function converts coordinates to geographics and the :command:`Geography(geometry)` function "casts" them from geometry to geography.
113
114.. code-block:: sql
115
116  CREATE TABLE nyc_subway_stations_geog AS
117  SELECT
118    Geography(ST_Transform(the_geom,4326)) AS geog,
119    name,
120    routes
121  FROM nyc_subway_stations;
122   
123Building a spatial index on a geography table is exactly the same as for geometry:
124
125.. code-block:: sql
126
127  CREATE INDEX nyc_subway_stations_geog_gix
128  ON nyc_subway_stations_geog USING GIST (geog);
129
130The difference is under the covers: the geography index will correctly handle queries that cover the poles or the international date-line, while the geometry one will not.
131
132There are only a small number of native functions for the geography type:
133 
134 * :command:`ST_AsText(geography)` returns ``text``
135 * :command:`ST_GeographyFromText(text)` returns ``geography``
136 * :command:`ST_AsBinary(geography)` returns ``bytea``
137 * :command:`ST_GeogFromWKB(bytea)` returns ``geography``
138 * :command:`ST_AsSVG(geography)` returns ``text``
139 * :command:`ST_AsGML(geography)` returns ``text``
140 * :command:`ST_AsKML(geography)` returns ``text``
141 * :command:`ST_AsGeoJson(geography)` returns ``text``
142 * :command:`ST_Distance(geography, geography)` returns ``double``
143 * :command:`ST_DWithin(geography, geography, float8)` returns ``boolean``
144 * :command:`ST_Area(geography)` returns ``double``
145 * :command:`ST_Length(geography)` returns ``double``
146 * :command:`ST_Covers(geography, geography)` returns ``boolean``
147 * :command:`ST_CoveredBy(geography, geography)` returns ``boolean``
148 * :command:`ST_Intersects(geography, geography)` returns ``boolean``
149 * :command:`ST_Buffer(geography, float8)` returns ``geography`` [#Casting_note]_
150 * :command:`ST_Intersection(geography, geography)` returns ``geography`` [#Casting_note]_
151 
152Creating a Geography Table
153--------------------------
154 
155The SQL for creating a new table with a geography column is much like that for creating a geometry table. However, geography includes the ability to specify the object type directly at the time of table creation. For example:
156
157.. code-block:: sql
158
159  CREATE TABLE airports (
160    code VARCHAR(3),
161    geog GEOGRAPHY(Point)
162  );
163 
164  INSERT INTO airports VALUES ('LAX', 'POINT(-118.4079 33.9434)');
165  INSERT INTO airports VALUES ('CDG', 'POINT(2.5559 49.0083)');
166  INSERT INTO airports VALUES ('REK', 'POINT(-21.8628 64.1286)');
167 
168In the table definition, the ``GEOGRAPHY(Point)`` specifies our airport data type as points. The new geography fields don't get registered in the ``geometry_columns``. Instead, they are registered in a new view called ``geography_columns`` that is automatically kept up to date without need for an :command:`AddGeom...` like functions.
169
170.. code-block:: sql
171
172  SELECT * FROM geography_columns;
173 
174::
175
176           f_table_name         | f_geography_column | srid |   type   
177 -------------------------------+--------------------+------+----------
178  nyc_subway_stations_geography | geog               |    0 | Geometry
179  airports                      | geog               | 4326 | Point
180 
181.. note::
182
183  The ability to define geometry types and SRIDs inside the table ``CREATE`` statement, and the automatic update of the ``geometry_columns`` metadata are features that have been prototyped with ``geography`` and will be added to the ``geometry`` type for PostGIS 2.0.
184 
185
186Casting to Geometry
187-------------------
188
189While the basic functions for geography types can handle many use cases, there are times when you might need access to other functions only supported by the geometry type. Fortunately, you can convert objects back and forth from geography to geometry.
190
191The PostgreSQL syntax convention for casting is to append ``::typename`` to the end of the value you wish to cast. So, ``2::text`` with convert a numeric two to a text string '2'. And ``'POINT(0 0)'::geometry`` will convert the text representation of point into a geometry point.
192
193The :command:`ST_X(point)` function only supports the geometry type. How can we read the X coordinate from our geographies?
194
195.. code-block:: sql
196
197  SELECT code, ST_X(geog::geometry) AS longitude FROM airports;
198
199::
200
201  code | longitude
202 ------+-----------
203  LAX  | -118.4079
204  CDG  |    2.5559
205  REK  |  -21.8628
206
207By appending ``::geometry`` to our geography value, we convert the object to a geometry with an SRID of 4326. From there we can use as many geometry functions as strike our fancy. But, remember -- now that our object is a geometry, the coordinates will be interpretted as cartesian coordinates, not spherical ones.
208 
209 
210Why (Not) Use Geography
211-----------------------
212
213Geographics are universally accepted coordinates -- everyone understands what latitude/longitude mean, but very few people understand what UTM coordinates mean. Why not use geography all the time?
214
215 * First, as noted earlier, there are far fewer functions available (right now) that directly support the geography type. You may spend a lot of time working around geography type limitations.
216 * Second, the calculations on a sphere are computationally far more expensive than cartesian calculations. For example, the cartesian formula for distance (Pythagoras) involves one call to sqrt(). The spherical formula for distance (Haversine) involves two sqrt() calls, an arctan() call, four sin() calls and two cos() calls. Trigonometric functions are very costly, and spherical calculations involve a lot of them.
217 
218The conclusion?
219
220If your data is geographically compact (contained within a state, county or city), use the ``geometry`` type with a cartesian projection that makes sense with your data. See the http://spatialreference.org site and type in the name of your region for a selection of possible reference systems.
221
222If, on the other hand, you need to measure distance with a dataset that is geographically dispersed (covering much of the world), use the ``geography`` type. The application complexity you save by working in ``geography`` will offset any performance issues. And, casting to ``geometry`` can offset most functionality limitations.
223
224Function List
225-------------
226
227`ST_Distance(geometry, geometry) <http://postgis.org/docs/ST_Distance.html>`_: For geometry type Returns the 2-dimensional cartesian minimum distance (based on spatial ref) between two geometries in projected units. For geography type defaults to return spheroidal minimum distance between two geographies in meters.
228
229`ST_GeographyFromText(text) <http://postgis.org/docs/ST_GeographyFromText.html>`_: Returns a specified geography value from Well-Known Text representation or extended (WKT).
230
231`ST_Transform(geometry, srid) <http://postgis.org/docs/ST_Transform.html>`_: Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter.
232
233`ST_X(point) <http://postgis.org/docs/ST_X.html>`_: Returns the X coordinate of the point, or NULL if not available. Input must be a point.
234
235
236.. rubric:: Footnotes
237
238.. [#Casting_note] The buffer and intersection functions are actually wrappers on top of a cast to geometry, and are not carried out natively in spherical coordinates. As a result, they may fail to return correct results for objects with very large extents that cannot be cleanly converted to a planar representation.
239 
240   For example, the :command:`ST_Buffer(geography,distance)` function transforms the geography object into a "best" projection, buffers it, and then transforms it back to geographics. If there is no "best" projection (the object is too large), the operation can fail or return a malformed buffer.
241
Note: See TracBrowser for help on using the repository browser.