Code

Changes between Version 75 and Version 76 of GeoDjango


Ignore:
Timestamp:
06/02/07 21:06:45 (7 years ago)
Author:
jbronn
Comment:

re-factored out database and model api sections

Legend:

Unmodified
Added
Removed
Modified
  • GeoDjango

    v75 v76  
    1 = Contents = 
     1= GeoDjango = 
    22The [http://code.djangoproject.com/browser/django/branches/gis GIS] branch intends to be a world-class geographic web framework.  Our goal is to make it as easy as possible to build GIS web applications and harness the power of spatially enabled data. 
    33 * [GeoDjango#FAQ FAQ] 
     
    1717   * [GeoDjango#PROJ.4 PROJ.4] ('''required''') 
    1818   * [GeoDjango#PostGIS PostGIS] ('''required''') 
    19    * [GeoDjango#GDAL GDAL] 
    20  * [GeoDjango#ModelAPI Model API] 
    21    * [GeoDjango#Fields Fields] 
    22    * [GeoDjango#FieldKeywords Field Keywords] 
    23    * [GeoDjango#CreatingandSavingModelswithGeometryFields Creating and Saving Models with Geometry Fields] 
    24  * [GeoDjango#DatabaseAPI Database API] 
    25    * [GeoDjango#PostGISOperatorFieldLookupTypes PostGIS Operator Field Lookup Types] 
    26    * [GeoDjango#PostGISGEOSFunctionFieldLookupTypes PostGIS GEOS Function Field Lookup Types] 
    27    * [GeoDjango#ExtraInstanceMethods Extra Instance Methods] 
     19   * [GeoDjango#GDAL GDAL] (''recommended'', required for some features) 
     20 * [wiki:GeoDjangoModelAPI Model API] 
     21 * [wiki:GeoDjangoDatabaseAPI Database API] 
    2822 
    2923= FAQ = 
     
    4640== Phase 2 == 
    4741 * '''Pending''' 
     42   * Distance queries, calculations, and related utilities. 
     43   * Utilities for importing vector and raster data (SHP files first) directly into Django models -- will be done with the forthcoming {{{LayerMapping}}} class. 
    4844   * Add as much from the PostGIS API as possible. 
    4945   * Support for a mapping framework (e.g. Google Maps/Earth, Yahoo Maps, MS Live, etc.) 
    5046     * Admin fields and forms (WKT field currently as of r4884, but we want widgets to view and manipulate geographic objects). 
    51    * Utilities for importing vector and raster data (SHP files first) directly into Django models -- will be done with the forthcoming {{{LayerMapping}}} class. 
    52    * Distance queries, calculations, and related utilities. 
     47 
    5348 * '''Complete''' 
    5449   * PostGIS indexing capability. 
    55    * As of r5008, added a GEOS wrapper object for geometry-enabled fields that call directly on GEOS routines (''e.g.'' {{{z.get_poly_geos().area}}}).  ''See'' [GeoDjango#ExtraInstanceMethods Extra Instance Methods] section below)  
     50   * As of r5008, added a GEOS wrapper object for geometry-enabled fields that call directly on GEOS routines (''e.g.'' {{{z.get_poly_geos().area}}}).  ''See'' [wiki:GeoDjangoDatabaseAPI#ExtraInstanceMethods Extra Instance Methods] section)  
    5651 
    5752== Phase 3 == 
     
    226221ogr2ogr -t_srs WGS84 output.shp input.shp 
    227222}}} 
    228  * Latest [http://www.gdal.org/download.html GDAL] version is 1.4.1.  Configure with GEOS and Python support, then make and install: 
    229 {{{ 
    230 $ ./configure --with-geos --with-python 
     223 * Latest [http://www.gdal.org/download.html GDAL] version is 1.4.1.  Configure with GEOS then make and install: 
     224{{{ 
     225$ ./configure --with-geos 
    231226$ make 
    232227# make install 
    233228}}} 
    234  * This is done without the 'next generation' SWIG Python bindings. The compilation flag to enable the new bindings is {{{--with-ngpython}}}. 
    235  *  ''Note'': As of 1.4.1, {{{ngpython}}} bindings don't work with Python 2.5.  While it's listed as fixed on trunk per their ticket [http://trac.osgeo.org/gdal/ticket/1379 1379], I've still had issues with using the trunk.  A {{{ctypes}}} interface, for needed GeoDjango functionality, is forthcoming. 
    236  
    237 = Model API = 
    238 == Fields == 
    239  
    240 The following geometry-enabled fields are available: 
    241  * {{{PointField}}} 
    242  * {{{LineStringField}}} 
    243  * {{{PolygonField}}} 
    244  * {{{MultiPointField}}} 
    245  * {{{MultiLineStringField}}} 
    246  * {{{MultiPolygonField}}} 
    247  * {{{GeometryCollectionField}}} 
    248  
    249 == Field Keywords == 
    250  * Field keywords are used during model creation, for example: 
    251 {{{ 
    252 #!python 
    253 from django.contrib.gis.db import models 
    254  
    255 class Zip(models.Model, models.GeoMixin): 
    256   code = models.IntegerField() 
    257   poly = models.PolygonField(srid=-1) 
    258  
    259   object = models.GeoManager() 
    260 }}} 
    261  
    262  * {{{srid}}} 
    263    * Sets the SRID (Spatial Reference System Identity) of geometry to the given value.  Defaults to 4326 (WGS84).  ''See'' Open GIS Consortium, Inc., ''[http://www.opengis.org/docs/99-049.pdf OpenGIS Simple Feature Specification For SQL]'', Document 99-049 (May 5, 1999), at  Ch. 2.3.8 (Geometry Values and Spatial Reference Systems, pg. 39). 
    264  * {{{index}}} 
    265    * Defaults to True.  Creates a GiST index for the given geometry.  Update the index with the PostgreSQL command {{{VACUUM ANALYZE}}} (may take a while to execute depending on how large your geographic-enabled tables are). 
    266  
    267 == Creating and Saving Models with Geometry Fields == 
    268 Here is an example of how to create a geometry object (assuming the {{{Zip}}} model example above): 
    269  
    270 {{{ 
    271 #!python 
    272 >>> from zipcode.models import Zip 
    273 >>> z = Zip(code=77096, poly='POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))') 
    274 >>> z.save() 
    275 }}} 
    276  
    277 Geometries are represented as '''strings''' in either of the formats WKT (Well Known Text) or HEXEWKB (PostGIS specific, essentially a WKB geometry in hexadecimal).  For example: 
    278  * WKT Polygon: {{{'POLYGON(( 10 10, 10 20, 20 20, 20 15, 10 10))'}}} 
    279    * ''See'' Open GIS Consortium, Inc., ''[http://www.opengis.org/docs/99-049.pdf OpenGIS Simple Feature Specification For SQL]'', Document 99-049 (May 5, 1999), at  Ch. 3.2.5 (SQL Textual Representation of Geometry, pg. 53). 
    280  * HEXEWKB Polygon: '{{{0103000000010000000 ... 00000000000002440'}}} 
    281    * ''See'' [http://postgis.refractions.net/docs/ch04.html#id2904792 "PostGIS EWKB, EWKT and Canonical Forms"], PostGIS documentation at Ch. 4.1.2.  
    282  
    283 = Database API = 
    284  
    285 '''Note:''' The following database lookup types can only be used with on geographic fields with {{{filter()}}}.  Filters on 'normal' fields (e.g. {{{CharField}}}) may be chained with those on geographic fields.  Thus, geographic queries take the following form (assuming the {{{Zip}}} model used in the [GeoDjango#ModelAPI Model API] section above): 
    286  
    287 {{{ 
    288 #!python 
    289 >>> qs = Zip.objects.filter(<geo field A>__<geo lookup type>=<geo string B>) 
    290 >>> qs = Zip.objects.exclude(...) 
    291 }}} 
    292  
    293 == PostGIS Operator Field Lookup Types == 
    294  
    295  * ''See generally'', [http://postgis.refractions.net/docs/ch06.html#id2854381 "Operators", PostGIS Documentation at Ch. 6.2.2] 
    296  * '''Note:'''  This API is subject to some change -- we're open to suggestions. 
    297  * {{{overlaps_left}}} 
    298    * Returns true if A's bounding box overlaps or is to the left of B's bounding box. 
    299    * PostGIS equivalent "{{{&<}}}" 
    300  * {{{overlaps_right}}}  
    301    * Returns true if A's bounding box overlaps or is to the right of B's bounding box. 
    302    * PostGIS equivalent "{{{&>}}}" 
    303  * {{{left}}} 
    304    * Returns true if A's bounding box is strictly to the left of B's bounding box. 
    305    * PostGIS equivalent "{{{<<}}}" 
    306  * {{{right}}} 
    307    * Returns true if A's bounding box is strictly to the right of B's bounding box. 
    308    * PostGIS equivalent "{{{>>}}}" 
    309  * {{{overlaps_below}}} 
    310    * Returns true if A's bounding box overlaps or is below B's bounding box. 
    311    * PostGIS equivalent "{{{&<|}}}" 
    312  * {{{overlaps_above}}} 
    313    * Returns true if A's bounding box overlaps or is above B's bounding box. 
    314    * PostGIS equivalent "{{{|&>}}}" 
    315  * {{{strictly_below}}} 
    316    * Returns true if A's bounding box is strictly below B's bounding box. 
    317    * PostGIS equivalent "{{{<<|}}}" 
    318  * {{{strictly_above}}} 
    319    * Returns true if A's bounding box is strictly above B's bounding box. 
    320    * PostGIS equivalent "{{{|>>}}}" 
    321  * {{{same_as}}} or {{{exact}}} 
    322    * The "same as" operator. It tests actual geometric equality of two features. So if A and B are the same feature, vertex-by-vertex, the operator returns true. 
    323    * PostGIS equivalent "{{{~=}}}" 
    324  * {{{contained}}} 
    325    * Returns true if A's bounding box is completely contained by B's bounding box. 
    326    * PostGIS equivalent "{{{@}}}" 
    327  * {{{bbcontains}}}  
    328    * Returns true if A's bounding box completely contains B's bounding box. 
    329    * PostGIS equivalent "{{{~}}}" 
    330  * {{{bboverlaps}}} 
    331    * Returns true if A's bounding box overlaps B's bounding box. 
    332    * PostGIS equivalent "{{{&&}}}" 
    333  
    334 == PostGIS GEOS Function Field Lookup Types == 
    335  * ''See generally'' [http://postgis.refractions.net/docs/ch06.html#id2615853 "Geometry Relationship Functions", PostGIS Documentation at Ch. 6.1.2].     
    336  * This documentation will be updated completely with the content from the aforementioned PostGIS docs. 
    337  * ~~{{{distance}}}~~ 
    338    * '''Warning:''' This function lookup type does not work, and will be moved to a routine as part of {{{GeoManager}}}. 
    339    * Return the cartesian distance between two geometries in projected units. 
    340    * PostGIS equivalent {{{Distance(geometry, geometry)}}} 
    341  * {{{equals}}} 
    342    * Requires GEOS 
    343    * Returns 1 (TRUE) if the given Geometries are "spatially equal".  
    344    * Use this for a 'better' answer than '='. equals('LINESTRING(0 0, 10 10)','LINESTRING(0 0, 5 5, 10 10)') is true. 
    345    * PostGIS equivalent {{{Equals(geometry, geometry)}}}, OGC SPEC s2.1.1.2 
    346  * {{{disjoint}}} 
    347    * Requires GEOS 
    348    * Returns 1 (TRUE) if the Geometries are "spatially disjoint". 
    349    * PostGIS equivalent {{{Disjoint(geometry, geometry)}}} 
    350  * {{{intersects}}} 
    351    * PostGIS equivalent {{{Intersects(geometry, geometry)}}} 
    352  * {{{touches}}} 
    353    * PostGIS equivalent {{{Touches(geometry, geometry)}}} 
    354  * {{{crosses}}} 
    355    * PostGIS equivalent {{{Crosses(geometry, geometry)}}} 
    356  * {{{overlaps}}} 
    357    * PostGIS equivalent {{{Overlaps(geometry, geometry)}}} 
    358  * {{{contains}}} 
    359    * PostGIS equivalent {{{Contains(geometry, geometry)}}} 
    360  * {{{intersects}}} 
    361    * PostGIS equivalent {{{Intersects(geometry, geometry)}}} 
    362  * {{{relate}}} 
    363    * PostGIS equivelent {{{Relate(geometry, geometry)}}} 
    364  
    365 == Extra Instance Methods == 
    366  
    367 A model with geometry fields will get the following methods, substitute {{{GEOM}}} with the name of the geometry field: 
    368  
    369 == get_GEOM_geos == 
    370 Returns a {{{GEOSGeometry}}} instance for the geometry.  For example (using the {{{District}}} model from above): 
    371  
    372 {{{ 
    373 #!python 
    374 >>> from django.contrib.gis.geos import GEOSGeometry 
    375 >>> dist = District.objects.get(name='Houston ISD') 
    376 >>> geom = dist.get_poly_geos() 
    377 >>> print geom.centroid.wkt 
    378 POINT(-95.231713 29.723235) 
    379 >>> print geom.area 
    380 0.08332 
    381 >>> print geom.geom_type 
    382 Polygon 
    383 >>> print geom.centroid.geom_type 
    384 Point 
    385 >>> print geom.intersects(GEOSGeometry('POINT(-95.395223 29.798088)')) 
    386 False 
    387 }}} 
    388  
    389 == get_GEOM_wkt == 
    390  
    391 Returns the OGC WKT (Well Known Text) for the geometry.  For example (using the {{{School}}} model from above): 
    392  
    393 {{{ 
    394 #!python 
    395 >>> skool = School.objects.get(name='PSAS') 
    396 >>> print skool.get_point_wkt() 
    397 POINT(-95.460822 29.745463) 
    398 }}} 
    399  
    400 == get_GEOM_centroid == 
    401  
    402 This routine will return the centroid of the geometry.  For example (using the {{{District}}} model from above): 
    403  
    404 {{{ 
    405 #!python 
    406 >>> dist = District.objects.get(name='Houston ISD') 
    407 >>> print dist.get_poly_centroid() 
    408 POINT(-95.231713 29.723235) 
    409 }}} 
    410  
    411 == get_GEOM_area == 
    412  
    413 This routine will return the area of the geometry field. 
    414  
    415 {{{ 
    416 #!python 
    417 >>> dist = District.objects.get(name='Houston ISD') 
    418 >>> print dist.get_poly_area() 
    419 0.08332 
    420 }}} 
    421  
    422 '''Note''': Units are in the projected units of the coordinate system.  In the example above, the units are in degrees since we're using WGS84.  ~~The units system needs to be figured out here, since I don't know what these units represent~~. 
     229 * As of r5397 there's a {{{ctypes}}} layer for GDAL/OGR, no python bindings needed. 
     230