Django

Code

Changeset 5397

Show
Ignore:
Timestamp:
05/31/07 20:15:35 (2 years ago)
Author:
jbronn
Message:

gis: Added an intial ctypes interface to GDAL/OGR

(1) SpatialReference? allows for rich access to properties of spatial

reference systems.

(2) OGRGeometry provides access to the OGR Geometry classes -- may be

accessed from models with the get_GEOM_ogr() extra instance method.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/gis/django/contrib/gis/db/models/fields/__init__.py

    r5382 r5397  
    77 
    88#TODO: Flesh out widgets. 
    9 #TODO: geos operations through fields as proxy. 
     9#TODO: GEOS and GDAL/OGR operations through fields as proxy. 
    1010#TODO: pythonic usage, like "for point in zip.polygon" and "if point in polygon". 
    1111 
     
    3939 
    4040        Takes the style object (provides syntax highlighting) as well as the 
    41          database table and field.  The dimensions can be specified via 
    42          the dim keyword as well. 
     41         database table and field. 
    4342        """ 
    4443        sql = style.SQL_KEYWORD('SELECT ') + \ 
     
    8281        super(GeometryField, self).contribute_to_class(cls, name) 
    8382 
    84         # Adding the WKT accessor function for geometry 
     83        # Adding needed accessor functions 
    8584        setattr(cls, 'get_%s_geos' % self.name, curry(cls._get_GEOM_geos, field=self)) 
     85        setattr(cls, 'get_%s_ogr' % self.name, curry(cls._get_GEOM_ogr, field=self, srid=self._srid)) 
    8686        setattr(cls, 'get_%s_wkt' % self.name, curry(cls._get_GEOM_wkt, field=self)) 
    8787        setattr(cls, 'get_%s_centroid' % self.name, curry(cls._get_GEOM_centroid, field=self)) 
  • django/branches/gis/django/contrib/gis/db/models/GeoMixin.py

    r5008 r5397  
    11# GEOS Routines 
    22from django.contrib.gis.geos import GEOSGeometry, hex_to_wkt, centroid, area 
     3from django.contrib.gis.gdal import OGRGeometry, SpatialReference 
    34 
    45# Until model subclassing is a possibility, a mixin class is used to add 
     
    1213        "Gets a GEOS Python object for the geometry." 
    1314        return GEOSGeometry(getattr(self, field.attname), 'hex') 
     15 
     16    def _get_GEOM_ogr(self, field, srid): 
     17        "Gets an OGR Python object for the geometry." 
     18        return OGRGeometry(hex_to_wkt(getattr(self, field.attname)), 
     19                           SpatialReference('EPSG:%d' % srid)) 
    1420 
    1521    def _get_GEOM_wkt(self, field): 
  • django/branches/gis/django/contrib/gis/db/models/postgis.py

    r5336 r5397  
    11# This module is meant to re-define the helper routines used by the 
    22# django.db.models.query objects to be customized for PostGIS. 
    3 from copy import copy 
    43from django.db import backend 
    54from django.db.models.query import LOOKUP_SEPARATOR, find_field, FieldFound, QUERY_TERMS, get_where_clause 
  • django/branches/gis/django/contrib/gis/models.py

    r4997 r5397  
    11import re 
    22from django.db import models 
     3 
     4# Checking for the presence of GDAL 
     5try: 
     6    from django.contrib.gis.gdal import SpatialReference 
     7    HAS_OSR = True 
     8except ImportError: 
     9    HAS_OSR = False 
    310 
    411""" 
     
    613""" 
    714 
    8 # For pulling out the spheroid from the spatial reference string. 
     15# For pulling out the spheroid from the spatial reference string. This 
     16# regular expression is used only if the user does not have GDAL installed. 
    917#  TODO: Flattening not used in all ellipsoids, could also be a minor axis, or 'b' 
    1018#        parameter. 
    1119spheroid_regex = re.compile(r'.+SPHEROID\[\"(?P<name>.+)\",(?P<major>\d+(\.\d+)?),(?P<flattening>\d{3}\.\d+),') 
    12  
    13 # For pulling out the projected coordinate system units.  Python regexs are greedy 
    14 #  by default, so this should get the units of the projection instead (PROJCS) 
    15 #  of the units for the geographic coordinate system (GEOGCS). 
    16 unit_regex = re.compile(r'^PROJCS.+UNIT\[\"(?P<units>[a-z]+)\", ?(?P<conversion>[0-9\.]+), ?(AUTHORITY\[\"(?P<authority>[a-z0-9 \.]+)\",[ ]?\"(?P<code>\d+)\"\])?', re.I) 
    1720 
    1821# This is the global 'geometry_columns' from PostGIS. 
     
    2124    f_table_catalog = models.CharField(maxlength=256) 
    2225    f_table_schema = models.CharField(maxlength=256) 
    23     f_table_name = models.CharField(maxlength=256
     26    f_table_name = models.CharField(maxlength=256, primary_key=True
    2427    f_geometry_column = models.CharField(maxlength=256) 
    2528    coord_dimension = models.IntegerField() 
     
    3033        db_table = 'geometry_columns' 
    3134 
     35    def __str__(self): 
     36        return "%s.%s - %dD %s field (SRID: %d)" % (self.f_table_name, self.f_geometry_column, self.coord_dimension, self.type, self.srid) 
     37 
    3238# This is the global 'spatial_ref_sys' table from PostGIS. 
    3339#   See PostGIS Documentation at Ch. 4.2.1 
     
    3743    auth_srid = models.IntegerField() 
    3844    srtext = models.CharField(maxlength=2048) 
    39     proj4text = models.CharField(maxlength=2048
     45    proj4 = models.CharField(maxlength=2048, db_column='proj4text'
    4046 
    4147    class Meta: 
    4248        db_table = 'spatial_ref_sys' 
     49 
     50    def _cache_osr(self): 
     51        "Caches a GDAL OSR object for this Spatial Reference." 
     52        if HAS_OSR: 
     53            if not hasattr(self, '_srs'): 
     54                # Trying to get from WKT first 
     55                try: 
     56                    self._srs = SpatialReference(self.srtext, 'wkt') 
     57                    return 
     58                except: 
     59                    pass 
     60 
     61                # Trying the proj4 text next 
     62                try: 
     63                    self._srs = SpatialReference(self.proj4, 'proj4') 
     64                    return 
     65                except: 
     66                    pass 
     67 
     68                raise Exception, 'Could not get a OSR Spatial Reference.' 
     69        else: 
     70            raise Exception, 'GDAL is not installed!' 
     71 
     72    @property 
     73    def srs(self): 
     74        self._cache_osr() 
     75        return self._srs.clone() 
    4376                                                                                 
    4477    @property 
    45     def spheroid(self): 
    46         "Pulls out the spheroid from the srtext." 
    47         m = spheroid_regex.match(self.srtext) 
    48         if m: 
    49             return (m.group('name'), float(m.group('major')), float(m.group('flattening'))) 
     78    def ellipsoid(self): 
     79        """Returns a tuple of the ellipsoid parameters: 
     80        (semimajor axis, semiminor axis, and inverse flattening).""" 
     81        if HAS_OSR: 
     82            # Setting values initially to False 
     83            self._cache_osr() 
     84            major = self._srs.semi_major 
     85            minor = self._srs.semi_minor 
     86            invflat  = self._srs.inverse_flattening 
     87            return (major, minor, invflat) 
    5088        else: 
    51             return None 
     89            m = spheroid_regex.match(self.srtext) 
     90            if m: return (float(m.group('major')), float(m.group('flattening'))) 
     91            else: return None 
    5292 
    5393    @property 
    54     def projected_units(self): 
    55         "If the spatial reference system is projected, get the units or return None." 
    56         m = unit_regex.match(self.srtext) 
    57         if m: 
    58             if m.group('authority'): 
    59                 authority = (m.group('authority'), int(m.group('code'))) 
    60             else: 
    61                 authority = None 
    62             return (m.group('units'), float(m.group('conversion')), authority) 
    63         else: 
    64             return None 
     94    def name(self): 
     95        "Returns the projection name." 
     96        self._cache_osr() 
     97        return self._srs.name 
     98 
     99    @property 
     100    def spheroid(self): 
     101        "Returns the spheroid for this spatial reference." 
     102        self._cache_osr() 
     103        return self._srs['spheroid'] 
     104 
     105    @property 
     106    def datum(self): 
     107        "Returns the datum for this spatial reference." 
     108        self._cache_osr() 
     109        return self._srs['datum'] 
     110 
     111    @property 
     112    def projected(self): 
     113        "Is this Spatial Reference projected?" 
     114        self._cache_osr() 
     115        return self._srs.projected 
     116 
     117    @property 
     118    def local(self): 
     119        "Is this Spatial Reference local?" 
     120        self._cache_osr() 
     121        return self._srs.local 
     122 
     123    @property 
     124    def geographic(self): 
     125        "Is this Spatial Reference geographic?" 
     126        self._cache_osr() 
     127        return self._srs.geographic 
     128 
     129    @property 
     130    def linear_name(self): 
     131        "Returns the linear units name." 
     132        self._cache_osr() 
     133        return self._srs.linear_name 
     134 
     135    @property 
     136    def linear_units(self): 
     137        "Returns the linear units." 
     138        self._cache_osr() 
     139        return self._srs.linear_units 
     140 
     141    @property 
     142    def angular_units(self): 
     143        "Returns the angular units." 
     144        self._cache_osr() 
     145        return self._srs.angular_units 
     146 
     147    @property 
     148    def angular_name(self): 
     149        "Returns the name of the angular units." 
     150        self._cache_osr() 
     151        return self._srs.angular_name 
    65152 
    66153    def __str__(self): 
    67         return "%d - %s " % (self.srid, self.auth_name) 
     154        "Returns the string representation.  If GDAL is installed, it will be 'pretty' OGC WKT." 
     155        if HAS_OSR: 
     156            self._cache_osr() 
     157            if hasattr(self, '_srs'): return str(self._srs) 
     158        return "%d:%s " % (self.srid, self.auth_name) 
  • django/branches/gis/django/contrib/gis/tests/__init__.py

    r5008 r5397  
     1from unittest import TestSuite, makeSuite, TextTestRunner 
     2import test_geos, test_gdal_ds, test_gdal_srs, test_gdal_geom, test_spatialrefsys 
     3 
     4def suite(): 
     5    s = TestSuite() 
     6    s.addTest(test_geos.suite()) 
     7    s.addTest(test_gdal_ds.suite()) 
     8    s.addTest(test_gdal_srs.suite()) 
     9    s.addTest(test_gdal_geom.suite()) 
     10    s.addTest(test_spatialrefsys.suite()) 
     11    return s 
     12 
     13def run(verbosity=2): 
     14    TextTestRunner(verbosity=verbosity).run(suite())