diff options
Diffstat (limited to 'parts/django/django/contrib/gis')
205 files changed, 0 insertions, 19908 deletions
diff --git a/parts/django/django/contrib/gis/__init__.py b/parts/django/django/contrib/gis/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/admin/__init__.py b/parts/django/django/contrib/gis/admin/__init__.py deleted file mode 100644 index 2b56276..0000000 --- a/parts/django/django/contrib/gis/admin/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -# Getting the normal admin routines, classes, and `site` instance. -from django.contrib.admin import autodiscover, site, AdminSite, ModelAdmin, StackedInline, TabularInline, HORIZONTAL, VERTICAL - -# Geographic admin options classes and widgets. -from django.contrib.gis.admin.options import GeoModelAdmin -from django.contrib.gis.admin.widgets import OpenLayersWidget - -try: - from django.contrib.gis.admin.options import OSMGeoAdmin - HAS_OSM = True -except ImportError: - HAS_OSM = False diff --git a/parts/django/django/contrib/gis/admin/options.py b/parts/django/django/contrib/gis/admin/options.py deleted file mode 100644 index 1814933..0000000 --- a/parts/django/django/contrib/gis/admin/options.py +++ /dev/null @@ -1,124 +0,0 @@ -from django.conf import settings -from django.contrib.admin import ModelAdmin -from django.contrib.gis.admin.widgets import OpenLayersWidget -from django.contrib.gis.gdal import OGRGeomType -from django.contrib.gis.db import models - -class GeoModelAdmin(ModelAdmin): - """ - The administration options class for Geographic models. Map settings - may be overloaded from their defaults to create custom maps. - """ - # The default map settings that may be overloaded -- still subject - # to API changes. - default_lon = 0 - default_lat = 0 - default_zoom = 4 - display_wkt = False - display_srid = False - extra_js = [] - num_zoom = 18 - max_zoom = False - min_zoom = False - units = False - max_resolution = False - max_extent = False - modifiable = True - mouse_position = True - scale_text = True - layerswitcher = True - scrollable = True - map_width = 600 - map_height = 400 - map_srid = 4326 - map_template = 'gis/admin/openlayers.html' - openlayers_url = 'http://openlayers.org/api/2.8/OpenLayers.js' - point_zoom = num_zoom - 6 - wms_url = 'http://labs.metacarta.com/wms/vmap0' - wms_layer = 'basic' - wms_name = 'OpenLayers WMS' - debug = False - widget = OpenLayersWidget - - def _media(self): - "Injects OpenLayers JavaScript into the admin." - media = super(GeoModelAdmin, self)._media() - media.add_js([self.openlayers_url]) - media.add_js(self.extra_js) - return media - media = property(_media) - - def formfield_for_dbfield(self, db_field, **kwargs): - """ - Overloaded from ModelAdmin so that an OpenLayersWidget is used - for viewing/editing GeometryFields. - """ - if isinstance(db_field, models.GeometryField): - request = kwargs.pop('request', None) - # Setting the widget with the newly defined widget. - kwargs['widget'] = self.get_map_widget(db_field) - return db_field.formfield(**kwargs) - else: - return super(GeoModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) - - def get_map_widget(self, db_field): - """ - Returns a subclass of the OpenLayersWidget (or whatever was specified - in the `widget` attribute) using the settings from the attributes set - in this class. - """ - is_collection = db_field.geom_type in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION') - if is_collection: - if db_field.geom_type == 'GEOMETRYCOLLECTION': collection_type = 'Any' - else: collection_type = OGRGeomType(db_field.geom_type.replace('MULTI', '')) - else: - collection_type = 'None' - - class OLMap(self.widget): - template = self.map_template - geom_type = db_field.geom_type - params = {'default_lon' : self.default_lon, - 'default_lat' : self.default_lat, - 'default_zoom' : self.default_zoom, - 'display_wkt' : self.debug or self.display_wkt, - 'geom_type' : OGRGeomType(db_field.geom_type), - 'field_name' : db_field.name, - 'is_collection' : is_collection, - 'scrollable' : self.scrollable, - 'layerswitcher' : self.layerswitcher, - 'collection_type' : collection_type, - 'is_linestring' : db_field.geom_type in ('LINESTRING', 'MULTILINESTRING'), - 'is_polygon' : db_field.geom_type in ('POLYGON', 'MULTIPOLYGON'), - 'is_point' : db_field.geom_type in ('POINT', 'MULTIPOINT'), - 'num_zoom' : self.num_zoom, - 'max_zoom' : self.max_zoom, - 'min_zoom' : self.min_zoom, - 'units' : self.units, #likely shoud get from object - 'max_resolution' : self.max_resolution, - 'max_extent' : self.max_extent, - 'modifiable' : self.modifiable, - 'mouse_position' : self.mouse_position, - 'scale_text' : self.scale_text, - 'map_width' : self.map_width, - 'map_height' : self.map_height, - 'point_zoom' : self.point_zoom, - 'srid' : self.map_srid, - 'display_srid' : self.display_srid, - 'wms_url' : self.wms_url, - 'wms_layer' : self.wms_layer, - 'wms_name' : self.wms_name, - 'debug' : self.debug, - } - return OLMap - -from django.contrib.gis import gdal -if gdal.HAS_GDAL: - class OSMGeoAdmin(GeoModelAdmin): - map_template = 'gis/admin/osm.html' - extra_js = ['http://openstreetmap.org/openlayers/OpenStreetMap.js'] - num_zoom = 20 - map_srid = 900913 - max_extent = '-20037508,-20037508,20037508,20037508' - max_resolution = '156543.0339' - point_zoom = num_zoom - 6 - units = 'm' diff --git a/parts/django/django/contrib/gis/admin/widgets.py b/parts/django/django/contrib/gis/admin/widgets.py deleted file mode 100644 index be26261..0000000 --- a/parts/django/django/contrib/gis/admin/widgets.py +++ /dev/null @@ -1,107 +0,0 @@ -from django.conf import settings -from django.contrib.gis.gdal import OGRException -from django.contrib.gis.geos import GEOSGeometry, GEOSException -from django.forms.widgets import Textarea -from django.template import loader, Context -from django.utils import translation - -# Creating a template context that contains Django settings -# values needed by admin map templates. -geo_context = Context({'ADMIN_MEDIA_PREFIX' : settings.ADMIN_MEDIA_PREFIX, - 'LANGUAGE_BIDI' : translation.get_language_bidi(), - }) - -class OpenLayersWidget(Textarea): - """ - Renders an OpenLayers map using the WKT of the geometry. - """ - def render(self, name, value, attrs=None): - # Update the template parameters with any attributes passed in. - if attrs: self.params.update(attrs) - - # Defaulting the WKT value to a blank string -- this - # will be tested in the JavaScript and the appropriate - # interface will be constructed. - self.params['wkt'] = '' - - # If a string reaches here (via a validation error on another - # field) then just reconstruct the Geometry. - if isinstance(value, basestring): - try: - value = GEOSGeometry(value) - except (GEOSException, ValueError): - value = None - - if value and value.geom_type.upper() != self.geom_type: - value = None - - # Constructing the dictionary of the map options. - self.params['map_options'] = self.map_options() - - # Constructing the JavaScript module name using the name of - # the GeometryField (passed in via the `attrs` keyword). - # Use the 'name' attr for the field name (rather than 'field') - self.params['name'] = name - # note: we must switch out dashes for underscores since js - # functions are created using the module variable - js_safe_name = self.params['name'].replace('-','_') - self.params['module'] = 'geodjango_%s' % js_safe_name - - if value: - # Transforming the geometry to the projection used on the - # OpenLayers map. - srid = self.params['srid'] - if value.srid != srid: - try: - ogr = value.ogr - ogr.transform(srid) - wkt = ogr.wkt - except OGRException: - wkt = '' - else: - wkt = value.wkt - - # Setting the parameter WKT with that of the transformed - # geometry. - self.params['wkt'] = wkt - - return loader.render_to_string(self.template, self.params, - context_instance=geo_context) - - def map_options(self): - "Builds the map options hash for the OpenLayers template." - - # JavaScript construction utilities for the Bounds and Projection. - def ol_bounds(extent): - return 'new OpenLayers.Bounds(%s)' % str(extent) - def ol_projection(srid): - return 'new OpenLayers.Projection("EPSG:%s")' % srid - - # An array of the parameter name, the name of their OpenLayers - # counterpart, and the type of variable they are. - map_types = [('srid', 'projection', 'srid'), - ('display_srid', 'displayProjection', 'srid'), - ('units', 'units', str), - ('max_resolution', 'maxResolution', float), - ('max_extent', 'maxExtent', 'bounds'), - ('num_zoom', 'numZoomLevels', int), - ('max_zoom', 'maxZoomLevels', int), - ('min_zoom', 'minZoomLevel', int), - ] - - # Building the map options hash. - map_options = {} - for param_name, js_name, option_type in map_types: - if self.params.get(param_name, False): - if option_type == 'srid': - value = ol_projection(self.params[param_name]) - elif option_type == 'bounds': - value = ol_bounds(self.params[param_name]) - elif option_type in (float, int): - value = self.params[param_name] - elif option_type in (str,): - value = '"%s"' % self.params[param_name] - else: - raise TypeError - map_options[js_name] = value - return map_options diff --git a/parts/django/django/contrib/gis/db/__init__.py b/parts/django/django/contrib/gis/db/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backend/__init__.py b/parts/django/django/contrib/gis/db/backend/__init__.py deleted file mode 100644 index 72ebdfe..0000000 --- a/parts/django/django/contrib/gis/db/backend/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.db import connection - -if hasattr(connection.ops, 'spatial_version'): - from warnings import warn - warn('The `django.contrib.gis.db.backend` module was refactored and ' - 'renamed to `django.contrib.gis.db.backends` in 1.2. ' - 'All functionality of `SpatialBackend` ' - 'has been moved to the `ops` attribute of the spatial database ' - 'backend. A `SpatialBackend` alias is provided here for ' - 'backwards-compatibility, but will be removed in 1.3.') - SpatialBackend = connection.ops diff --git a/parts/django/django/contrib/gis/db/backends/__init__.py b/parts/django/django/contrib/gis/db/backends/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/backends/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backends/adapter.py b/parts/django/django/contrib/gis/db/backends/adapter.py deleted file mode 100644 index 9766ef0..0000000 --- a/parts/django/django/contrib/gis/db/backends/adapter.py +++ /dev/null @@ -1,17 +0,0 @@ -class WKTAdapter(object): - """ - This provides an adaptor for Geometries sent to the - MySQL and Oracle database backends. - """ - def __init__(self, geom): - self.wkt = geom.wkt - self.srid = geom.srid - - def __eq__(self, other): - return self.wkt == other.wkt and self.srid == other.srid - - def __str__(self): - return self.wkt - - def prepare_database_save(self, unused): - return self diff --git a/parts/django/django/contrib/gis/db/backends/base.py b/parts/django/django/contrib/gis/db/backends/base.py deleted file mode 100644 index 0eaacae..0000000 --- a/parts/django/django/contrib/gis/db/backends/base.py +++ /dev/null @@ -1,336 +0,0 @@ -""" -Base/mixin classes for the spatial backend database operations and the -`SpatialRefSys` model the backend. -""" -import re -from django.conf import settings -from django.contrib.gis import gdal - -class BaseSpatialOperations(object): - """ - This module holds the base `BaseSpatialBackend` object, which is - instantiated by each spatial database backend with the features - it has. - """ - distance_functions = {} - geometry_functions = {} - geometry_operators = {} - geography_operators = {} - geography_functions = {} - gis_terms = {} - truncate_params = {} - - # Quick booleans for the type of this spatial backend, and - # an attribute for the spatial database version tuple (if applicable) - postgis = False - spatialite = False - mysql = False - oracle = False - spatial_version = None - - # How the geometry column should be selected. - select = None - - # Does the spatial database have a geography type? - geography = False - - area = False - centroid = False - difference = False - distance = False - distance_sphere = False - distance_spheroid = False - envelope = False - force_rhr = False - mem_size = False - bounding_circle = False - num_geom = False - num_points = False - perimeter = False - perimeter3d = False - point_on_surface = False - polygonize = False - reverse = False - scale = False - snap_to_grid = False - sym_difference = False - transform = False - translate = False - union = False - - # Aggregates - collect = False - extent = False - extent3d = False - make_line = False - unionagg = False - - # Serialization - geohash = False - geojson = False - gml = False - kml = False - svg = False - - # Constructors - from_text = False - from_wkb = False - - # Default conversion functions for aggregates; will be overridden if implemented - # for the spatial backend. - def convert_extent(self, box): - raise NotImplementedError('Aggregate extent not implemented for this spatial backend.') - - def convert_extent3d(self, box): - raise NotImplementedError('Aggregate 3D extent not implemented for this spatial backend.') - - def convert_geom(self, geom_val, geom_field): - raise NotImplementedError('Aggregate method not implemented for this spatial backend.') - - # For quoting column values, rather than columns. - def geo_quote_name(self, name): - if isinstance(name, unicode): - name = name.encode('ascii') - return "'%s'" % name - - # GeometryField operations - def geo_db_type(self, f): - """ - Returns the database column type for the geometry field on - the spatial backend. - """ - raise NotImplementedError - - def get_distance(self, f, value, lookup_type): - """ - Returns the distance parameters for the given geometry field, - lookup value, and lookup type. - """ - raise NotImplementedError('Distance operations not available on this spatial backend.') - - def get_geom_placeholder(self, f, value): - """ - Returns the placeholder for the given geometry field with the given - value. Depending on the spatial backend, the placeholder may contain a - stored procedure call to the transformation function of the spatial - backend. - """ - raise NotImplementedError - - # Spatial SQL Construction - def spatial_aggregate_sql(self, agg): - raise NotImplementedError('Aggregate support not implemented for this spatial backend.') - - def spatial_lookup_sql(self, lvalue, lookup_type, value, field): - raise NotImplmentedError - - # Routines for getting the OGC-compliant models. - def geometry_columns(self): - raise NotImplementedError - - def spatial_ref_sys(self): - raise NotImplementedError - -class SpatialRefSysMixin(object): - """ - The SpatialRefSysMixin is a class used by the database-dependent - SpatialRefSys objects to reduce redundnant code. - """ - # For pulling out the spheroid from the spatial reference string. This - # regular expression is used only if the user does not have GDAL installed. - # TODO: Flattening not used in all ellipsoids, could also be a minor axis, - # or 'b' parameter. - spheroid_regex = re.compile(r'.+SPHEROID\[\"(?P<name>.+)\",(?P<major>\d+(\.\d+)?),(?P<flattening>\d{3}\.\d+),') - - # For pulling out the units on platforms w/o GDAL installed. - # TODO: Figure out how to pull out angular units of projected coordinate system and - # fix for LOCAL_CS types. GDAL should be highly recommended for performing - # distance queries. - units_regex = re.compile(r'.+UNIT ?\["(?P<unit_name>[\w \'\(\)]+)", ?(?P<unit>[\d\.]+)(,AUTHORITY\["(?P<unit_auth_name>[\w \'\(\)]+)","(?P<unit_auth_val>\d+)"\])?\]([\w ]+)?(,AUTHORITY\["(?P<auth_name>[\w \'\(\)]+)","(?P<auth_val>\d+)"\])?\]$') - - @property - def srs(self): - """ - Returns a GDAL SpatialReference object, if GDAL is installed. - """ - if gdal.HAS_GDAL: - # TODO: Is caching really necessary here? Is complexity worth it? - if hasattr(self, '_srs'): - # Returning a clone of the cached SpatialReference object. - return self._srs.clone() - else: - # Attempting to cache a SpatialReference object. - - # Trying to get from WKT first. - try: - self._srs = gdal.SpatialReference(self.wkt) - return self.srs - except Exception, msg: - pass - - try: - self._srs = gdal.SpatialReference(self.proj4text) - return self.srs - except Exception, msg: - pass - - raise Exception('Could not get OSR SpatialReference from WKT: %s\nError:\n%s' % (self.wkt, msg)) - else: - raise Exception('GDAL is not installed.') - - @property - def ellipsoid(self): - """ - Returns a tuple of the ellipsoid parameters: - (semimajor axis, semiminor axis, and inverse flattening). - """ - if gdal.HAS_GDAL: - return self.srs.ellipsoid - else: - m = self.spheroid_regex.match(self.wkt) - if m: return (float(m.group('major')), float(m.group('flattening'))) - else: return None - - @property - def name(self): - "Returns the projection name." - return self.srs.name - - @property - def spheroid(self): - "Returns the spheroid name for this spatial reference." - return self.srs['spheroid'] - - @property - def datum(self): - "Returns the datum for this spatial reference." - return self.srs['datum'] - - @property - def projected(self): - "Is this Spatial Reference projected?" - if gdal.HAS_GDAL: - return self.srs.projected - else: - return self.wkt.startswith('PROJCS') - - @property - def local(self): - "Is this Spatial Reference local?" - if gdal.HAS_GDAL: - return self.srs.local - else: - return self.wkt.startswith('LOCAL_CS') - - @property - def geographic(self): - "Is this Spatial Reference geographic?" - if gdal.HAS_GDAL: - return self.srs.geographic - else: - return self.wkt.startswith('GEOGCS') - - @property - def linear_name(self): - "Returns the linear units name." - if gdal.HAS_GDAL: - return self.srs.linear_name - elif self.geographic: - return None - else: - m = self.units_regex.match(self.wkt) - return m.group('unit_name') - - @property - def linear_units(self): - "Returns the linear units." - if gdal.HAS_GDAL: - return self.srs.linear_units - elif self.geographic: - return None - else: - m = self.units_regex.match(self.wkt) - return m.group('unit') - - @property - def angular_name(self): - "Returns the name of the angular units." - if gdal.HAS_GDAL: - return self.srs.angular_name - elif self.projected: - return None - else: - m = self.units_regex.match(self.wkt) - return m.group('unit_name') - - @property - def angular_units(self): - "Returns the angular units." - if gdal.HAS_GDAL: - return self.srs.angular_units - elif self.projected: - return None - else: - m = self.units_regex.match(self.wkt) - return m.group('unit') - - @property - def units(self): - "Returns a tuple of the units and the name." - if self.projected or self.local: - return (self.linear_units, self.linear_name) - elif self.geographic: - return (self.angular_units, self.angular_name) - else: - return (None, None) - - @classmethod - def get_units(cls, wkt): - """ - Class method used by GeometryField on initialization to - retrive the units on the given WKT, without having to use - any of the database fields. - """ - if gdal.HAS_GDAL: - return gdal.SpatialReference(wkt).units - else: - m = cls.units_regex.match(wkt) - return m.group('unit'), m.group('unit_name') - - @classmethod - def get_spheroid(cls, wkt, string=True): - """ - Class method used by GeometryField on initialization to - retrieve the `SPHEROID[..]` parameters from the given WKT. - """ - if gdal.HAS_GDAL: - srs = gdal.SpatialReference(wkt) - sphere_params = srs.ellipsoid - sphere_name = srs['spheroid'] - else: - m = cls.spheroid_regex.match(wkt) - if m: - sphere_params = (float(m.group('major')), float(m.group('flattening'))) - sphere_name = m.group('name') - else: - return None - - if not string: - return sphere_name, sphere_params - else: - # `string` parameter used to place in format acceptable by PostGIS - if len(sphere_params) == 3: - radius, flattening = sphere_params[0], sphere_params[2] - else: - radius, flattening = sphere_params - return 'SPHEROID["%s",%s,%s]' % (sphere_name, radius, flattening) - - def __unicode__(self): - """ - Returns the string representation. If GDAL is installed, - it will be 'pretty' OGC WKT. - """ - try: - return unicode(self.srs) - except: - return unicode(self.wkt) diff --git a/parts/django/django/contrib/gis/db/backends/mysql/__init__.py b/parts/django/django/contrib/gis/db/backends/mysql/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/backends/mysql/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backends/mysql/base.py b/parts/django/django/contrib/gis/db/backends/mysql/base.py deleted file mode 100644 index 7f0fc48..0000000 --- a/parts/django/django/contrib/gis/db/backends/mysql/base.py +++ /dev/null @@ -1,13 +0,0 @@ -from django.db.backends.mysql.base import * -from django.db.backends.mysql.base import DatabaseWrapper as MySQLDatabaseWrapper -from django.contrib.gis.db.backends.mysql.creation import MySQLCreation -from django.contrib.gis.db.backends.mysql.introspection import MySQLIntrospection -from django.contrib.gis.db.backends.mysql.operations import MySQLOperations - -class DatabaseWrapper(MySQLDatabaseWrapper): - - def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) - self.creation = MySQLCreation(self) - self.ops = MySQLOperations() - self.introspection = MySQLIntrospection(self) diff --git a/parts/django/django/contrib/gis/db/backends/mysql/creation.py b/parts/django/django/contrib/gis/db/backends/mysql/creation.py deleted file mode 100644 index dda77ea..0000000 --- a/parts/django/django/contrib/gis/db/backends/mysql/creation.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.db.backends.mysql.creation import DatabaseCreation - -class MySQLCreation(DatabaseCreation): - - def sql_indexes_for_field(self, model, f, style): - from django.contrib.gis.db.models.fields import GeometryField - output = super(MySQLCreation, self).sql_indexes_for_field(model, f, style) - - if isinstance(f, GeometryField) and f.spatial_index: - qn = self.connection.ops.quote_name - db_table = model._meta.db_table - idx_name = '%s_%s_id' % (db_table, f.column) - output.append(style.SQL_KEYWORD('CREATE SPATIAL INDEX ') + - style.SQL_TABLE(qn(idx_name)) + - style.SQL_KEYWORD(' ON ') + - style.SQL_TABLE(qn(db_table)) + '(' + - style.SQL_FIELD(qn(f.column)) + ');') - return output diff --git a/parts/django/django/contrib/gis/db/backends/mysql/introspection.py b/parts/django/django/contrib/gis/db/backends/mysql/introspection.py deleted file mode 100644 index 59d0f62..0000000 --- a/parts/django/django/contrib/gis/db/backends/mysql/introspection.py +++ /dev/null @@ -1,32 +0,0 @@ -from MySQLdb.constants import FIELD_TYPE - -from django.contrib.gis.gdal import OGRGeomType -from django.db.backends.mysql.introspection import DatabaseIntrospection - -class MySQLIntrospection(DatabaseIntrospection): - # Updating the data_types_reverse dictionary with the appropriate - # type for Geometry fields. - data_types_reverse = DatabaseIntrospection.data_types_reverse.copy() - data_types_reverse[FIELD_TYPE.GEOMETRY] = 'GeometryField' - - def get_geometry_type(self, table_name, geo_col): - cursor = self.connection.cursor() - try: - # In order to get the specific geometry type of the field, - # we introspect on the table definition using `DESCRIBE`. - cursor.execute('DESCRIBE %s' % - self.connection.ops.quote_name(table_name)) - # Increment over description info until we get to the geometry - # column. - for column, typ, null, key, default, extra in cursor.fetchall(): - if column == geo_col: - # Using OGRGeomType to convert from OGC name to Django field. - # MySQL does not support 3D or SRIDs, so the field params - # are empty. - field_type = OGRGeomType(typ).django - field_params = {} - break - finally: - cursor.close() - - return field_type, field_params diff --git a/parts/django/django/contrib/gis/db/backends/mysql/operations.py b/parts/django/django/contrib/gis/db/backends/mysql/operations.py deleted file mode 100644 index 1653636..0000000 --- a/parts/django/django/contrib/gis/db/backends/mysql/operations.py +++ /dev/null @@ -1,65 +0,0 @@ -from django.db.backends.mysql.base import DatabaseOperations - -from django.contrib.gis.db.backends.adapter import WKTAdapter -from django.contrib.gis.db.backends.base import BaseSpatialOperations - -class MySQLOperations(DatabaseOperations, BaseSpatialOperations): - - compiler_module = 'django.contrib.gis.db.models.sql.compiler' - mysql = True - name = 'mysql' - select = 'AsText(%s)' - from_wkb = 'GeomFromWKB' - from_text = 'GeomFromText' - - Adapter = WKTAdapter - Adaptor = Adapter # Backwards-compatibility alias. - - geometry_functions = { - 'bbcontains' : 'MBRContains', # For consistency w/PostGIS API - 'bboverlaps' : 'MBROverlaps', # .. .. - 'contained' : 'MBRWithin', # .. .. - 'contains' : 'MBRContains', - 'disjoint' : 'MBRDisjoint', - 'equals' : 'MBREqual', - 'exact' : 'MBREqual', - 'intersects' : 'MBRIntersects', - 'overlaps' : 'MBROverlaps', - 'same_as' : 'MBREqual', - 'touches' : 'MBRTouches', - 'within' : 'MBRWithin', - } - - gis_terms = dict([(term, None) for term in geometry_functions.keys() + ['isnull']]) - - def geo_db_type(self, f): - return f.geom_type - - def get_geom_placeholder(self, value, srid): - """ - The placeholder here has to include MySQL's WKT constructor. Because - MySQL does not support spatial transformations, there is no need to - modify the placeholder based on the contents of the given value. - """ - if hasattr(value, 'expression'): - placeholder = '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression])) - else: - placeholder = '%s(%%s)' % self.from_text - return placeholder - - def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn): - alias, col, db_type = lvalue - - geo_col = '%s.%s' % (qn(alias), qn(col)) - - lookup_info = self.geometry_functions.get(lookup_type, False) - if lookup_info: - return "%s(%s, %s)" % (lookup_info, geo_col, - self.get_geom_placeholder(value, field.srid)) - - # TODO: Is this really necessary? MySQL can't handle NULL geometries - # in its spatial indexes anyways. - if lookup_type == 'isnull': - return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or '')) - - raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) diff --git a/parts/django/django/contrib/gis/db/backends/oracle/__init__.py b/parts/django/django/contrib/gis/db/backends/oracle/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backends/oracle/adapter.py b/parts/django/django/contrib/gis/db/backends/oracle/adapter.py deleted file mode 100644 index ea340d9..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/adapter.py +++ /dev/null @@ -1,5 +0,0 @@ -from cx_Oracle import CLOB -from django.contrib.gis.db.backends.adapter import WKTAdapter - -class OracleSpatialAdapter(WKTAdapter): - input_size = CLOB diff --git a/parts/django/django/contrib/gis/db/backends/oracle/base.py b/parts/django/django/contrib/gis/db/backends/oracle/base.py deleted file mode 100644 index 398b3d3..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/base.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.db.backends.oracle.base import * -from django.db.backends.oracle.base import DatabaseWrapper as OracleDatabaseWrapper -from django.contrib.gis.db.backends.oracle.creation import OracleCreation -from django.contrib.gis.db.backends.oracle.introspection import OracleIntrospection -from django.contrib.gis.db.backends.oracle.operations import OracleOperations - -class DatabaseWrapper(OracleDatabaseWrapper): - def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) - self.ops = OracleOperations(self) - self.creation = OracleCreation(self) - self.introspection = OracleIntrospection(self) diff --git a/parts/django/django/contrib/gis/db/backends/oracle/compiler.py b/parts/django/django/contrib/gis/db/backends/oracle/compiler.py deleted file mode 100644 index f0eb5ca..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/compiler.py +++ /dev/null @@ -1,44 +0,0 @@ -from django.contrib.gis.db.models.sql.compiler import GeoSQLCompiler as BaseGeoSQLCompiler -from django.db.backends.oracle import compiler - -SQLCompiler = compiler.SQLCompiler - -class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler): - pass - -class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler): - def placeholder(self, field, val): - if field is None: - # A field value of None means the value is raw. - return val - elif hasattr(field, 'get_placeholder'): - # Some fields (e.g. geo fields) need special munging before - # they can be inserted. - ph = field.get_placeholder(val, self.connection) - if ph == 'NULL': - # If the placeholder returned is 'NULL', then we need to - # to remove None from the Query parameters. Specifically, - # cx_Oracle will assume a CHAR type when a placeholder ('%s') - # is used for columns of MDSYS.SDO_GEOMETRY. Thus, we use - # 'NULL' for the value, and remove None from the query params. - # See also #10888. - param_idx = self.query.columns.index(field.column) - params = list(self.query.params) - params.pop(param_idx) - self.query.params = tuple(params) - return ph - else: - # Return the common case for the placeholder - return '%s' - -class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler): - pass - -class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler): - pass - -class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler): - pass - -class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler): - pass diff --git a/parts/django/django/contrib/gis/db/backends/oracle/creation.py b/parts/django/django/contrib/gis/db/backends/oracle/creation.py deleted file mode 100644 index 043da91..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/creation.py +++ /dev/null @@ -1,42 +0,0 @@ -from django.db.backends.oracle.creation import DatabaseCreation -from django.db.backends.util import truncate_name - -class OracleCreation(DatabaseCreation): - - def sql_indexes_for_field(self, model, f, style): - "Return any spatial index creation SQL for the field." - from django.contrib.gis.db.models.fields import GeometryField - - output = super(OracleCreation, self).sql_indexes_for_field(model, f, style) - - if isinstance(f, GeometryField): - gqn = self.connection.ops.geo_quote_name - qn = self.connection.ops.quote_name - db_table = model._meta.db_table - - output.append(style.SQL_KEYWORD('INSERT INTO ') + - style.SQL_TABLE('USER_SDO_GEOM_METADATA') + - ' (%s, %s, %s, %s)\n ' % tuple(map(qn, ['TABLE_NAME', 'COLUMN_NAME', 'DIMINFO', 'SRID'])) + - style.SQL_KEYWORD(' VALUES ') + '(\n ' + - style.SQL_TABLE(gqn(db_table)) + ',\n ' + - style.SQL_FIELD(gqn(f.column)) + ',\n ' + - style.SQL_KEYWORD("MDSYS.SDO_DIM_ARRAY") + '(\n ' + - style.SQL_KEYWORD("MDSYS.SDO_DIM_ELEMENT") + - ("('LONG', %s, %s, %s),\n " % (f._extent[0], f._extent[2], f._tolerance)) + - style.SQL_KEYWORD("MDSYS.SDO_DIM_ELEMENT") + - ("('LAT', %s, %s, %s)\n ),\n" % (f._extent[1], f._extent[3], f._tolerance)) + - ' %s\n );' % f.srid) - - if f.spatial_index: - # Getting the index name, Oracle doesn't allow object - # names > 30 characters. - idx_name = truncate_name('%s_%s_id' % (db_table, f.column), 30) - - output.append(style.SQL_KEYWORD('CREATE INDEX ') + - style.SQL_TABLE(qn(idx_name)) + - style.SQL_KEYWORD(' ON ') + - style.SQL_TABLE(qn(db_table)) + '(' + - style.SQL_FIELD(qn(f.column)) + ') ' + - style.SQL_KEYWORD('INDEXTYPE IS ') + - style.SQL_TABLE('MDSYS.SPATIAL_INDEX') + ';') - return output diff --git a/parts/django/django/contrib/gis/db/backends/oracle/introspection.py b/parts/django/django/contrib/gis/db/backends/oracle/introspection.py deleted file mode 100644 index 58dd3f3..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/introspection.py +++ /dev/null @@ -1,39 +0,0 @@ -import cx_Oracle -from django.db.backends.oracle.introspection import DatabaseIntrospection - -class OracleIntrospection(DatabaseIntrospection): - # Associating any OBJECTVAR instances with GeometryField. Of course, - # this won't work right on Oracle objects that aren't MDSYS.SDO_GEOMETRY, - # but it is the only object type supported within Django anyways. - data_types_reverse = DatabaseIntrospection.data_types_reverse.copy() - data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField' - - def get_geometry_type(self, table_name, geo_col): - cursor = self.connection.cursor() - try: - # Querying USER_SDO_GEOM_METADATA to get the SRID and dimension information. - try: - cursor.execute('SELECT "DIMINFO", "SRID" FROM "USER_SDO_GEOM_METADATA" WHERE "TABLE_NAME"=%s AND "COLUMN_NAME"=%s', - (table_name.upper(), geo_col.upper())) - row = cursor.fetchone() - except Exception, msg: - raise Exception('Could not find entry in USER_SDO_GEOM_METADATA corresponding to "%s"."%s"\n' - 'Error message: %s.' % (table_name, geo_col, msg)) - - # TODO: Research way to find a more specific geometry field type for - # the column's contents. - field_type = 'GeometryField' - - # Getting the field parameters. - field_params = {} - dim, srid = row - if srid != 4326: - field_params['srid'] = srid - # Length of object array ( SDO_DIM_ARRAY ) is number of dimensions. - dim = len(dim) - if dim != 2: - field_params['dim'] = dim - finally: - cursor.close() - - return field_type, field_params diff --git a/parts/django/django/contrib/gis/db/backends/oracle/models.py b/parts/django/django/contrib/gis/db/backends/oracle/models.py deleted file mode 100644 index de757ff..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/models.py +++ /dev/null @@ -1,65 +0,0 @@ -""" - The GeometryColumns and SpatialRefSys models for the Oracle spatial - backend. - - It should be noted that Oracle Spatial does not have database tables - named according to the OGC standard, so the closest analogs are used. - For example, the `USER_SDO_GEOM_METADATA` is used for the GeometryColumns - model and the `SDO_COORD_REF_SYS` is used for the SpatialRefSys model. -""" -from django.contrib.gis.db import models -from django.contrib.gis.db.models.fields import GeometryField -from django.contrib.gis.db.backends.base import SpatialRefSysMixin - -class GeometryColumns(models.Model): - "Maps to the Oracle USER_SDO_GEOM_METADATA table." - table_name = models.CharField(max_length=32) - column_name = models.CharField(max_length=1024) - srid = models.IntegerField(primary_key=True) - # TODO: Add support for `diminfo` column (type MDSYS.SDO_DIM_ARRAY). - class Meta: - db_table = 'USER_SDO_GEOM_METADATA' - managed = False - - @classmethod - def table_name_col(cls): - """ - Returns the name of the metadata column used to store the - the feature table name. - """ - return 'table_name' - - @classmethod - def geom_col_name(cls): - """ - Returns the name of the metadata column used to store the - the feature geometry column. - """ - return 'column_name' - - def __unicode__(self): - return '%s - %s (SRID: %s)' % (self.table_name, self.column_name, self.srid) - -class SpatialRefSys(models.Model, SpatialRefSysMixin): - "Maps to the Oracle MDSYS.CS_SRS table." - cs_name = models.CharField(max_length=68) - srid = models.IntegerField(primary_key=True) - auth_srid = models.IntegerField() - auth_name = models.CharField(max_length=256) - wktext = models.CharField(max_length=2046) - # Optional geometry representing the bounds of this coordinate - # system. By default, all are NULL in the table. - cs_bounds = models.PolygonField(null=True) - objects = models.GeoManager() - - class Meta: - db_table = 'CS_SRS' - managed = False - - @property - def wkt(self): - return self.wktext - - @classmethod - def wkt_col(cls): - return 'wktext' diff --git a/parts/django/django/contrib/gis/db/backends/oracle/operations.py b/parts/django/django/contrib/gis/db/backends/oracle/operations.py deleted file mode 100644 index 97f7b6c..0000000 --- a/parts/django/django/contrib/gis/db/backends/oracle/operations.py +++ /dev/null @@ -1,293 +0,0 @@ -""" - This module contains the spatial lookup types, and the `get_geo_where_clause` - routine for Oracle Spatial. - - Please note that WKT support is broken on the XE version, and thus - this backend will not work on such platforms. Specifically, XE lacks - support for an internal JVM, and Java libraries are required to use - the WKT constructors. -""" -import re -from decimal import Decimal - -from django.db.backends.oracle.base import DatabaseOperations -from django.contrib.gis.db.backends.base import BaseSpatialOperations -from django.contrib.gis.db.backends.oracle.adapter import OracleSpatialAdapter -from django.contrib.gis.db.backends.util import SpatialFunction -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Distance - -class SDOOperation(SpatialFunction): - "Base class for SDO* Oracle operations." - sql_template = "%(function)s(%(geo_col)s, %(geometry)s) %(operator)s '%(result)s'" - - def __init__(self, func, **kwargs): - kwargs.setdefault('operator', '=') - kwargs.setdefault('result', 'TRUE') - super(SDOOperation, self).__init__(func, **kwargs) - -class SDODistance(SpatialFunction): - "Class for Distance queries." - sql_template = ('%(function)s(%(geo_col)s, %(geometry)s, %(tolerance)s) ' - '%(operator)s %(result)s') - dist_func = 'SDO_GEOM.SDO_DISTANCE' - def __init__(self, op, tolerance=0.05): - super(SDODistance, self).__init__(self.dist_func, - tolerance=tolerance, - operator=op, result='%s') - -class SDODWithin(SpatialFunction): - dwithin_func = 'SDO_WITHIN_DISTANCE' - sql_template = "%(function)s(%(geo_col)s, %(geometry)s, %%s) = 'TRUE'" - def __init__(self): - super(SDODWithin, self).__init__(self.dwithin_func) - -class SDOGeomRelate(SpatialFunction): - "Class for using SDO_GEOM.RELATE." - relate_func = 'SDO_GEOM.RELATE' - sql_template = ("%(function)s(%(geo_col)s, '%(mask)s', %(geometry)s, " - "%(tolerance)s) %(operator)s '%(mask)s'") - def __init__(self, mask, tolerance=0.05): - # SDO_GEOM.RELATE(...) has a peculiar argument order: column, mask, geom, tolerance. - # Moreover, the runction result is the mask (e.g., 'DISJOINT' instead of 'TRUE'). - super(SDOGeomRelate, self).__init__(self.relate_func, operator='=', - mask=mask, tolerance=tolerance) - -class SDORelate(SpatialFunction): - "Class for using SDO_RELATE." - masks = 'TOUCH|OVERLAPBDYDISJOINT|OVERLAPBDYINTERSECT|EQUAL|INSIDE|COVEREDBY|CONTAINS|COVERS|ANYINTERACT|ON' - mask_regex = re.compile(r'^(%s)(\+(%s))*$' % (masks, masks), re.I) - sql_template = "%(function)s(%(geo_col)s, %(geometry)s, 'mask=%(mask)s') = 'TRUE'" - relate_func = 'SDO_RELATE' - def __init__(self, mask): - if not self.mask_regex.match(mask): - raise ValueError('Invalid %s mask: "%s"' % (self.relate_func, mask)) - super(SDORelate, self).__init__(self.relate_func, mask=mask) - -# Valid distance types and substitutions -dtypes = (Decimal, Distance, float, int, long) - -class OracleOperations(DatabaseOperations, BaseSpatialOperations): - compiler_module = "django.contrib.gis.db.backends.oracle.compiler" - - name = 'oracle' - oracle = True - valid_aggregates = dict([(a, None) for a in ('Union', 'Extent')]) - - Adapter = OracleSpatialAdapter - Adaptor = Adapter # Backwards-compatibility alias. - - area = 'SDO_GEOM.SDO_AREA' - gml= 'SDO_UTIL.TO_GMLGEOMETRY' - centroid = 'SDO_GEOM.SDO_CENTROID' - difference = 'SDO_GEOM.SDO_DIFFERENCE' - distance = 'SDO_GEOM.SDO_DISTANCE' - extent= 'SDO_AGGR_MBR' - intersection= 'SDO_GEOM.SDO_INTERSECTION' - length = 'SDO_GEOM.SDO_LENGTH' - num_geom = 'SDO_UTIL.GETNUMELEM' - num_points = 'SDO_UTIL.GETNUMVERTICES' - perimeter = length - point_on_surface = 'SDO_GEOM.SDO_POINTONSURFACE' - reverse = 'SDO_UTIL.REVERSE_LINESTRING' - sym_difference = 'SDO_GEOM.SDO_XOR' - transform = 'SDO_CS.TRANSFORM' - union = 'SDO_GEOM.SDO_UNION' - unionagg = 'SDO_AGGR_UNION' - - # We want to get SDO Geometries as WKT because it is much easier to - # instantiate GEOS proxies from WKT than SDO_GEOMETRY(...) strings. - # However, this adversely affects performance (i.e., Java is called - # to convert to WKT on every query). If someone wishes to write a - # SDO_GEOMETRY(...) parser in Python, let me know =) - select = 'SDO_UTIL.TO_WKTGEOMETRY(%s)' - - distance_functions = { - 'distance_gt' : (SDODistance('>'), dtypes), - 'distance_gte' : (SDODistance('>='), dtypes), - 'distance_lt' : (SDODistance('<'), dtypes), - 'distance_lte' : (SDODistance('<='), dtypes), - 'dwithin' : (SDODWithin(), dtypes), - } - - geometry_functions = { - 'contains' : SDOOperation('SDO_CONTAINS'), - 'coveredby' : SDOOperation('SDO_COVEREDBY'), - 'covers' : SDOOperation('SDO_COVERS'), - 'disjoint' : SDOGeomRelate('DISJOINT'), - 'intersects' : SDOOperation('SDO_OVERLAPBDYINTERSECT'), # TODO: Is this really the same as ST_Intersects()? - 'equals' : SDOOperation('SDO_EQUAL'), - 'exact' : SDOOperation('SDO_EQUAL'), - 'overlaps' : SDOOperation('SDO_OVERLAPS'), - 'same_as' : SDOOperation('SDO_EQUAL'), - 'relate' : (SDORelate, basestring), # Oracle uses a different syntax, e.g., 'mask=inside+touch' - 'touches' : SDOOperation('SDO_TOUCH'), - 'within' : SDOOperation('SDO_INSIDE'), - } - geometry_functions.update(distance_functions) - - gis_terms = ['isnull'] - gis_terms += geometry_functions.keys() - gis_terms = dict([(term, None) for term in gis_terms]) - - truncate_params = {'relate' : None} - - def __init__(self, connection): - super(OracleOperations, self).__init__() - self.connection = connection - - def convert_extent(self, clob): - if clob: - # Generally, Oracle returns a polygon for the extent -- however, - # it can return a single point if there's only one Point in the - # table. - ext_geom = Geometry(clob.read()) - gtype = str(ext_geom.geom_type) - if gtype == 'Polygon': - # Construct the 4-tuple from the coordinates in the polygon. - shell = ext_geom.shell - ll, ur = shell[0][:2], shell[2][:2] - elif gtype == 'Point': - ll = ext_geom.coords[:2] - ur = ll - else: - raise Exception('Unexpected geometry type returned for extent: %s' % gtype) - xmin, ymin = ll - xmax, ymax = ur - return (xmin, ymin, xmax, ymax) - else: - return None - - def convert_geom(self, clob, geo_field): - if clob: - return Geometry(clob.read(), geo_field.srid) - else: - return None - - def geo_db_type(self, f): - """ - Returns the geometry database type for Oracle. Unlike other spatial - backends, no stored procedure is necessary and it's the same for all - geometry types. - """ - return 'MDSYS.SDO_GEOMETRY' - - def get_distance(self, f, value, lookup_type): - """ - Returns the distance parameters given the value and the lookup type. - On Oracle, geometry columns with a geodetic coordinate system behave - implicitly like a geography column, and thus meters will be used as - the distance parameter on them. - """ - if not value: - return [] - value = value[0] - if isinstance(value, Distance): - if f.geodetic(self.connection): - dist_param = value.m - else: - dist_param = getattr(value, Distance.unit_attname(f.units_name(self.connection))) - else: - dist_param = value - - # dwithin lookups on oracle require a special string parameter - # that starts with "distance=". - if lookup_type == 'dwithin': - dist_param = 'distance=%s' % dist_param - - return [dist_param] - - def get_geom_placeholder(self, f, value): - """ - Provides a proper substitution value for Geometries that are not in the - SRID of the field. Specifically, this routine will substitute in the - SDO_CS.TRANSFORM() function call. - """ - if value is None: - return 'NULL' - - def transform_value(val, srid): - return val.srid != srid - - if hasattr(value, 'expression'): - if transform_value(value, f.srid): - placeholder = '%s(%%s, %s)' % (self.transform, f.srid) - else: - placeholder = '%s' - # No geometry value used for F expression, substitue in - # the column name instead. - return placeholder % '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression])) - else: - if transform_value(value, f.srid): - return '%s(SDO_GEOMETRY(%%s, %s), %s)' % (self.transform, value.srid, f.srid) - else: - return 'SDO_GEOMETRY(%%s, %s)' % f.srid - - def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn): - "Returns the SQL WHERE clause for use in Oracle spatial SQL construction." - alias, col, db_type = lvalue - - # Getting the quoted table name as `geo_col`. - geo_col = '%s.%s' % (qn(alias), qn(col)) - - # See if a Oracle Geometry function matches the lookup type next - lookup_info = self.geometry_functions.get(lookup_type, False) - if lookup_info: - # Lookup types that are tuples take tuple arguments, e.g., 'relate' and - # 'dwithin' lookup types. - if isinstance(lookup_info, tuple): - # First element of tuple is lookup type, second element is the type - # of the expected argument (e.g., str, float) - sdo_op, arg_type = lookup_info - geom = value[0] - - # Ensuring that a tuple _value_ was passed in from the user - if not isinstance(value, tuple): - raise ValueError('Tuple required for `%s` lookup type.' % lookup_type) - if len(value) != 2: - raise ValueError('2-element tuple required for %s lookup type.' % lookup_type) - - # Ensuring the argument type matches what we expect. - if not isinstance(value[1], arg_type): - raise ValueError('Argument type should be %s, got %s instead.' % (arg_type, type(value[1]))) - - if lookup_type == 'relate': - # The SDORelate class handles construction for these queries, - # and verifies the mask argument. - return sdo_op(value[1]).as_sql(geo_col, self.get_geom_placeholder(field, geom)) - else: - # Otherwise, just call the `as_sql` method on the SDOOperation instance. - return sdo_op.as_sql(geo_col, self.get_geom_placeholder(field, geom)) - else: - # Lookup info is a SDOOperation instance, whose `as_sql` method returns - # the SQL necessary for the geometry function call. For example: - # SDO_CONTAINS("geoapp_country"."poly", SDO_GEOMTRY('POINT(5 23)', 4326)) = 'TRUE' - return lookup_info.as_sql(geo_col, self.get_geom_placeholder(field, value)) - elif lookup_type == 'isnull': - # Handling 'isnull' lookup type - return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or '')) - - raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) - - def spatial_aggregate_sql(self, agg): - """ - Returns the spatial aggregate SQL template and function for the - given Aggregate instance. - """ - agg_name = agg.__class__.__name__.lower() - if agg_name == 'union' : agg_name += 'agg' - if agg.is_extent: - sql_template = '%(function)s(%(field)s)' - else: - sql_template = '%(function)s(SDOAGGRTYPE(%(field)s,%(tolerance)s))' - sql_function = getattr(self, agg_name) - return self.select % sql_template, sql_function - - # Routines for getting the OGC-compliant models. - def geometry_columns(self): - from django.contrib.gis.db.backends.oracle.models import GeometryColumns - return GeometryColumns - - def spatial_ref_sys(self): - from django.contrib.gis.db.backends.oracle.models import SpatialRefSys - return SpatialRefSys diff --git a/parts/django/django/contrib/gis/db/backends/postgis/__init__.py b/parts/django/django/contrib/gis/db/backends/postgis/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backends/postgis/adapter.py b/parts/django/django/contrib/gis/db/backends/postgis/adapter.py deleted file mode 100644 index 3f8603e..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/adapter.py +++ /dev/null @@ -1,35 +0,0 @@ -""" - This object provides quoting for GEOS geometries into PostgreSQL/PostGIS. -""" - -from psycopg2 import Binary -from psycopg2.extensions import ISQLQuote - -class PostGISAdapter(object): - def __init__(self, geom): - "Initializes on the geometry." - # Getting the WKB (in string form, to allow easy pickling of - # the adaptor) and the SRID from the geometry. - self.ewkb = str(geom.ewkb) - self.srid = geom.srid - - def __conform__(self, proto): - # Does the given protocol conform to what Psycopg2 expects? - if proto == ISQLQuote: - return self - else: - raise Exception('Error implementing psycopg2 protocol. Is psycopg2 installed?') - - def __eq__(self, other): - return (self.ewkb == other.ewkb) and (self.srid == other.srid) - - def __str__(self): - return self.getquoted() - - def getquoted(self): - "Returns a properly quoted string for use in PostgreSQL/PostGIS." - # Want to use WKB, so wrap with psycopg2 Binary() to quote properly. - return 'ST_GeomFromEWKB(E%s)' % Binary(self.ewkb) - - def prepare_database_save(self, unused): - return self diff --git a/parts/django/django/contrib/gis/db/backends/postgis/base.py b/parts/django/django/contrib/gis/db/backends/postgis/base.py deleted file mode 100644 index 634a7d5..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/base.py +++ /dev/null @@ -1,12 +0,0 @@ -from django.db.backends.postgresql_psycopg2.base import * -from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper as Psycopg2DatabaseWrapper -from django.contrib.gis.db.backends.postgis.creation import PostGISCreation -from django.contrib.gis.db.backends.postgis.introspection import PostGISIntrospection -from django.contrib.gis.db.backends.postgis.operations import PostGISOperations - -class DatabaseWrapper(Psycopg2DatabaseWrapper): - def __init__(self, *args, **kwargs): - super(DatabaseWrapper, self).__init__(*args, **kwargs) - self.creation = PostGISCreation(self) - self.ops = PostGISOperations(self) - self.introspection = PostGISIntrospection(self) diff --git a/parts/django/django/contrib/gis/db/backends/postgis/creation.py b/parts/django/django/contrib/gis/db/backends/postgis/creation.py deleted file mode 100644 index e14c792..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/creation.py +++ /dev/null @@ -1,60 +0,0 @@ -from django.conf import settings -from django.db.backends.postgresql.creation import DatabaseCreation - -class PostGISCreation(DatabaseCreation): - geom_index_type = 'GIST' - geom_index_opts = 'GIST_GEOMETRY_OPS' - - def sql_indexes_for_field(self, model, f, style): - "Return any spatial index creation SQL for the field." - from django.contrib.gis.db.models.fields import GeometryField - - output = super(PostGISCreation, self).sql_indexes_for_field(model, f, style) - - if isinstance(f, GeometryField): - gqn = self.connection.ops.geo_quote_name - qn = self.connection.ops.quote_name - db_table = model._meta.db_table - - if f.geography: - # Geogrophy columns are created normally. - pass - else: - # Geometry columns are created by `AddGeometryColumn` - # stored procedure. - output.append(style.SQL_KEYWORD('SELECT ') + - style.SQL_TABLE('AddGeometryColumn') + '(' + - style.SQL_TABLE(gqn(db_table)) + ', ' + - style.SQL_FIELD(gqn(f.column)) + ', ' + - style.SQL_FIELD(str(f.srid)) + ', ' + - style.SQL_COLTYPE(gqn(f.geom_type)) + ', ' + - style.SQL_KEYWORD(str(f.dim)) + ');') - - if not f.null: - # Add a NOT NULL constraint to the field - output.append(style.SQL_KEYWORD('ALTER TABLE ') + - style.SQL_TABLE(qn(db_table)) + - style.SQL_KEYWORD(' ALTER ') + - style.SQL_FIELD(qn(f.column)) + - style.SQL_KEYWORD(' SET NOT NULL') + ';') - - - if f.spatial_index: - # Spatial indexes created the same way for both Geometry and - # Geography columns - if f.geography: - index_opts = '' - else: - index_opts = ' ' + style.SQL_KEYWORD(self.geom_index_opts) - output.append(style.SQL_KEYWORD('CREATE INDEX ') + - style.SQL_TABLE(qn('%s_%s_id' % (db_table, f.column))) + - style.SQL_KEYWORD(' ON ') + - style.SQL_TABLE(qn(db_table)) + - style.SQL_KEYWORD(' USING ') + - style.SQL_COLTYPE(self.geom_index_type) + ' ( ' + - style.SQL_FIELD(qn(f.column)) + index_opts + ' );') - return output - - def sql_table_creation_suffix(self): - qn = self.connection.ops.quote_name - return ' TEMPLATE %s' % qn(getattr(settings, 'POSTGIS_TEMPLATE', 'template_postgis')) diff --git a/parts/django/django/contrib/gis/db/backends/postgis/introspection.py b/parts/django/django/contrib/gis/db/backends/postgis/introspection.py deleted file mode 100644 index 7962d19..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/introspection.py +++ /dev/null @@ -1,95 +0,0 @@ -from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection -from django.contrib.gis.gdal import OGRGeomType - -class GeoIntrospectionError(Exception): - pass - -class PostGISIntrospection(DatabaseIntrospection): - # Reverse dictionary for PostGIS geometry types not populated until - # introspection is actually performed. - postgis_types_reverse = {} - - def get_postgis_types(self): - """ - Returns a dictionary with keys that are the PostgreSQL object - identification integers for the PostGIS geometry and/or - geography types (if supported). - """ - cursor = self.connection.cursor() - # The OID integers associated with the geometry type may - # be different across versions; hence, this is why we have - # to query the PostgreSQL pg_type table corresponding to the - # PostGIS custom data types. - oid_sql = 'SELECT "oid" FROM "pg_type" WHERE "typname" = %s' - try: - cursor.execute(oid_sql, ('geometry',)) - GEOM_TYPE = cursor.fetchone()[0] - postgis_types = { GEOM_TYPE : 'GeometryField' } - if self.connection.ops.geography: - cursor.execute(oid_sql, ('geography',)) - GEOG_TYPE = cursor.fetchone()[0] - # The value for the geography type is actually a tuple - # to pass in the `geography=True` keyword to the field - # definition. - postgis_types[GEOG_TYPE] = ('GeometryField', {'geography' : True}) - finally: - cursor.close() - - return postgis_types - - def get_field_type(self, data_type, description): - if not self.postgis_types_reverse: - # If the PostGIS types reverse dictionary is not populated, do so - # now. In order to prevent unnecessary requests upon connection - # intialization, the `data_types_reverse` dictionary is not updated - # with the PostGIS custom types until introspection is actually - # performed -- in other words, when this function is called. - self.postgis_types_reverse = self.get_postgis_types() - self.data_types_reverse.update(self.postgis_types_reverse) - return super(PostGISIntrospection, self).get_field_type(data_type, description) - - def get_geometry_type(self, table_name, geo_col): - """ - The geometry type OID used by PostGIS does not indicate the particular - type of field that a geometry column is (e.g., whether it's a - PointField or a PolygonField). Thus, this routine queries the PostGIS - metadata tables to determine the geometry type, - """ - cursor = self.connection.cursor() - try: - try: - # First seeing if this geometry column is in the `geometry_columns` - cursor.execute('SELECT "coord_dimension", "srid", "type" ' - 'FROM "geometry_columns" ' - 'WHERE "f_table_name"=%s AND "f_geometry_column"=%s', - (table_name, geo_col)) - row = cursor.fetchone() - if not row: raise GeoIntrospectionError - except GeoIntrospectionError: - if self.connection.ops.geography: - cursor.execute('SELECT "coord_dimension", "srid", "type" ' - 'FROM "geography_columns" ' - 'WHERE "f_table_name"=%s AND "f_geography_column"=%s', - (table_name, geo_col)) - row = cursor.fetchone() - - if not row: - raise Exception('Could not find a geometry or geography column for "%s"."%s"' % - (table_name, geo_col)) - - # OGRGeomType does not require GDAL and makes it easy to convert - # from OGC geom type name to Django field. - field_type = OGRGeomType(row[2]).django - - # Getting any GeometryField keyword arguments that are not the default. - dim = row[0] - srid = row[1] - field_params = {} - if srid != 4326: - field_params['srid'] = srid - if dim != 2: - field_params['dim'] = dim - finally: - cursor.close() - - return field_type, field_params diff --git a/parts/django/django/contrib/gis/db/backends/postgis/models.py b/parts/django/django/contrib/gis/db/backends/postgis/models.py deleted file mode 100644 index a385983..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/models.py +++ /dev/null @@ -1,66 +0,0 @@ -""" - The GeometryColumns and SpatialRefSys models for the PostGIS backend. -""" -from django.db import models -from django.contrib.gis.db.backends.base import SpatialRefSysMixin - -class GeometryColumns(models.Model): - """ - The 'geometry_columns' table from the PostGIS. See the PostGIS - documentation at Ch. 4.2.2. - """ - f_table_catalog = models.CharField(max_length=256) - f_table_schema = models.CharField(max_length=256) - f_table_name = models.CharField(max_length=256) - f_geometry_column = models.CharField(max_length=256) - coord_dimension = models.IntegerField() - srid = models.IntegerField(primary_key=True) - type = models.CharField(max_length=30) - - class Meta: - db_table = 'geometry_columns' - managed = False - - @classmethod - def table_name_col(cls): - """ - Returns the name of the metadata column used to store the - the feature table name. - """ - return 'f_table_name' - - @classmethod - def geom_col_name(cls): - """ - Returns the name of the metadata column used to store the - the feature geometry column. - """ - return 'f_geometry_column' - - def __unicode__(self): - return "%s.%s - %dD %s field (SRID: %d)" % \ - (self.f_table_name, self.f_geometry_column, - self.coord_dimension, self.type, self.srid) - -class SpatialRefSys(models.Model, SpatialRefSysMixin): - """ - The 'spatial_ref_sys' table from PostGIS. See the PostGIS - documentaiton at Ch. 4.2.1. - """ - srid = models.IntegerField(primary_key=True) - auth_name = models.CharField(max_length=256) - auth_srid = models.IntegerField() - srtext = models.CharField(max_length=2048) - proj4text = models.CharField(max_length=2048) - - class Meta: - db_table = 'spatial_ref_sys' - managed = False - - @property - def wkt(self): - return self.srtext - - @classmethod - def wkt_col(cls): - return 'srtext' diff --git a/parts/django/django/contrib/gis/db/backends/postgis/operations.py b/parts/django/django/contrib/gis/db/backends/postgis/operations.py deleted file mode 100644 index 5affcf9..0000000 --- a/parts/django/django/contrib/gis/db/backends/postgis/operations.py +++ /dev/null @@ -1,589 +0,0 @@ -import re -from decimal import Decimal - -from django.conf import settings -from django.contrib.gis.db.backends.base import BaseSpatialOperations -from django.contrib.gis.db.backends.util import SpatialOperation, SpatialFunction -from django.contrib.gis.db.backends.postgis.adapter import PostGISAdapter -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Distance -from django.core.exceptions import ImproperlyConfigured -from django.db.backends.postgresql_psycopg2.base import DatabaseOperations -from django.db.utils import DatabaseError - -#### Classes used in constructing PostGIS spatial SQL #### -class PostGISOperator(SpatialOperation): - "For PostGIS operators (e.g. `&&`, `~`)." - def __init__(self, operator): - super(PostGISOperator, self).__init__(operator=operator) - -class PostGISFunction(SpatialFunction): - "For PostGIS function calls (e.g., `ST_Contains(table, geom)`)." - def __init__(self, prefix, function, **kwargs): - super(PostGISFunction, self).__init__(prefix + function, **kwargs) - -class PostGISFunctionParam(PostGISFunction): - "For PostGIS functions that take another parameter (e.g. DWithin, Relate)." - sql_template = '%(function)s(%(geo_col)s, %(geometry)s, %%s)' - -class PostGISDistance(PostGISFunction): - "For PostGIS distance operations." - dist_func = 'Distance' - sql_template = '%(function)s(%(geo_col)s, %(geometry)s) %(operator)s %%s' - - def __init__(self, prefix, operator): - super(PostGISDistance, self).__init__(prefix, self.dist_func, - operator=operator) - -class PostGISSpheroidDistance(PostGISFunction): - "For PostGIS spherical distance operations (using the spheroid)." - dist_func = 'distance_spheroid' - sql_template = '%(function)s(%(geo_col)s, %(geometry)s, %%s) %(operator)s %%s' - def __init__(self, prefix, operator): - # An extra parameter in `end_subst` is needed for the spheroid string. - super(PostGISSpheroidDistance, self).__init__(prefix, self.dist_func, - operator=operator) - -class PostGISSphereDistance(PostGISDistance): - "For PostGIS spherical distance operations." - dist_func = 'distance_sphere' - -class PostGISRelate(PostGISFunctionParam): - "For PostGIS Relate(<geom>, <pattern>) calls." - pattern_regex = re.compile(r'^[012TF\*]{9}$') - def __init__(self, prefix, pattern): - if not self.pattern_regex.match(pattern): - raise ValueError('Invalid intersection matrix pattern "%s".' % pattern) - super(PostGISRelate, self).__init__(prefix, 'Relate') - - -class PostGISOperations(DatabaseOperations, BaseSpatialOperations): - compiler_module = 'django.contrib.gis.db.models.sql.compiler' - name = 'postgis' - postgis = True - version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)') - valid_aggregates = dict([(k, None) for k in - ('Collect', 'Extent', 'Extent3D', 'MakeLine', 'Union')]) - - Adapter = PostGISAdapter - Adaptor = Adapter # Backwards-compatibility alias. - - def __init__(self, connection): - super(PostGISOperations, self).__init__(connection) - - # Trying to get the PostGIS version because the function - # signatures will depend on the version used. The cost - # here is a database query to determine the version, which - # can be mitigated by setting `POSTGIS_VERSION` with a 3-tuple - # comprising user-supplied values for the major, minor, and - # subminor revision of PostGIS. - try: - if hasattr(settings, 'POSTGIS_VERSION'): - vtup = settings.POSTGIS_VERSION - if len(vtup) == 3: - # The user-supplied PostGIS version. - version = vtup - else: - # This was the old documented way, but it's stupid to - # include the string. - version = vtup[1:4] - else: - vtup = self.postgis_version_tuple() - version = vtup[1:] - - # Getting the prefix -- even though we don't officially support - # PostGIS 1.2 anymore, keeping it anyway in case a prefix change - # for something else is necessary. - if version >= (1, 2, 2): - prefix = 'ST_' - else: - prefix = '' - - self.geom_func_prefix = prefix - self.spatial_version = version - except DatabaseError: - raise ImproperlyConfigured('Cannot determine PostGIS version for database "%s". ' - 'GeoDjango requires at least PostGIS version 1.3. ' - 'Was the database created from a spatial database ' - 'template?' % self.connection.settings_dict['NAME'] - ) - except Exception, e: - # TODO: Raise helpful exceptions as they become known. - raise - - # PostGIS-specific operators. The commented descriptions of these - # operators come from Section 7.6 of the PostGIS 1.4 documentation. - self.geometry_operators = { - # The "&<" operator returns true if A's bounding box overlaps or - # is to the left of B's bounding box. - 'overlaps_left' : PostGISOperator('&<'), - # The "&>" operator returns true if A's bounding box overlaps or - # is to the right of B's bounding box. - 'overlaps_right' : PostGISOperator('&>'), - # The "<<" operator returns true if A's bounding box is strictly - # to the left of B's bounding box. - 'left' : PostGISOperator('<<'), - # The ">>" operator returns true if A's bounding box is strictly - # to the right of B's bounding box. - 'right' : PostGISOperator('>>'), - # The "&<|" operator returns true if A's bounding box overlaps or - # is below B's bounding box. - 'overlaps_below' : PostGISOperator('&<|'), - # The "|&>" operator returns true if A's bounding box overlaps or - # is above B's bounding box. - 'overlaps_above' : PostGISOperator('|&>'), - # The "<<|" operator returns true if A's bounding box is strictly - # below B's bounding box. - 'strictly_below' : PostGISOperator('<<|'), - # The "|>>" operator returns true if A's bounding box is strictly - # above B's bounding box. - 'strictly_above' : PostGISOperator('|>>'), - # The "~=" operator is 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. - 'same_as' : PostGISOperator('~='), - 'exact' : PostGISOperator('~='), - # The "@" operator returns true if A's bounding box is completely contained - # by B's bounding box. - 'contained' : PostGISOperator('@'), - # The "~" operator returns true if A's bounding box completely contains - # by B's bounding box. - 'bbcontains' : PostGISOperator('~'), - # The "&&" operator returns true if A's bounding box overlaps - # B's bounding box. - 'bboverlaps' : PostGISOperator('&&'), - } - - self.geometry_functions = { - 'equals' : PostGISFunction(prefix, 'Equals'), - 'disjoint' : PostGISFunction(prefix, 'Disjoint'), - 'touches' : PostGISFunction(prefix, 'Touches'), - 'crosses' : PostGISFunction(prefix, 'Crosses'), - 'within' : PostGISFunction(prefix, 'Within'), - 'overlaps' : PostGISFunction(prefix, 'Overlaps'), - 'contains' : PostGISFunction(prefix, 'Contains'), - 'intersects' : PostGISFunction(prefix, 'Intersects'), - 'relate' : (PostGISRelate, basestring), - } - - # Valid distance types and substitutions - dtypes = (Decimal, Distance, float, int, long) - def get_dist_ops(operator): - "Returns operations for both regular and spherical distances." - return {'cartesian' : PostGISDistance(prefix, operator), - 'sphere' : PostGISSphereDistance(prefix, operator), - 'spheroid' : PostGISSpheroidDistance(prefix, operator), - } - self.distance_functions = { - 'distance_gt' : (get_dist_ops('>'), dtypes), - 'distance_gte' : (get_dist_ops('>='), dtypes), - 'distance_lt' : (get_dist_ops('<'), dtypes), - 'distance_lte' : (get_dist_ops('<='), dtypes), - } - - # Versions 1.2.2+ have KML serialization support. - if version < (1, 2, 2): - ASKML = False - else: - ASKML = 'ST_AsKML' - self.geometry_functions.update( - {'coveredby' : PostGISFunction(prefix, 'CoveredBy'), - 'covers' : PostGISFunction(prefix, 'Covers'), - }) - self.distance_functions['dwithin'] = (PostGISFunctionParam(prefix, 'DWithin'), dtypes) - - # Adding the distance functions to the geometries lookup. - self.geometry_functions.update(self.distance_functions) - - # The union aggregate and topology operation use the same signature - # in versions 1.3+. - if version < (1, 3, 0): - UNIONAGG = 'GeomUnion' - UNION = 'Union' - MAKELINE = False - else: - UNIONAGG = 'ST_Union' - UNION = 'ST_Union' - MAKELINE = 'ST_MakeLine' - - # Only PostGIS versions 1.3.4+ have GeoJSON serialization support. - if version < (1, 3, 4): - GEOJSON = False - else: - GEOJSON = prefix + 'AsGeoJson' - - # ST_ContainsProperly ST_MakeLine, and ST_GeoHash added in 1.4. - if version >= (1, 4, 0): - GEOHASH = 'ST_GeoHash' - BOUNDINGCIRCLE = 'ST_MinimumBoundingCircle' - self.geometry_functions['contains_properly'] = PostGISFunction(prefix, 'ContainsProperly') - else: - GEOHASH, BOUNDINGCIRCLE = False, False - - # Geography type support added in 1.5. - if version >= (1, 5, 0): - self.geography = True - # Only a subset of the operators and functions are available - # for the geography type. - self.geography_functions = self.distance_functions.copy() - self.geography_functions.update({ - 'coveredby' : self.geometry_functions['coveredby'], - 'covers' : self.geometry_functions['covers'], - 'intersects' : self.geometry_functions['intersects'], - }) - self.geography_operators = { - 'bboverlaps' : PostGISOperator('&&'), - } - - # Creating a dictionary lookup of all GIS terms for PostGIS. - gis_terms = ['isnull'] - gis_terms += self.geometry_operators.keys() - gis_terms += self.geometry_functions.keys() - self.gis_terms = dict([(term, None) for term in gis_terms]) - - self.area = prefix + 'Area' - self.bounding_circle = BOUNDINGCIRCLE - self.centroid = prefix + 'Centroid' - self.collect = prefix + 'Collect' - self.difference = prefix + 'Difference' - self.distance = prefix + 'Distance' - self.distance_sphere = prefix + 'distance_sphere' - self.distance_spheroid = prefix + 'distance_spheroid' - self.envelope = prefix + 'Envelope' - self.extent = prefix + 'Extent' - self.extent3d = prefix + 'Extent3D' - self.force_rhr = prefix + 'ForceRHR' - self.geohash = GEOHASH - self.geojson = GEOJSON - self.gml = prefix + 'AsGML' - self.intersection = prefix + 'Intersection' - self.kml = ASKML - self.length = prefix + 'Length' - self.length3d = prefix + 'Length3D' - self.length_spheroid = prefix + 'length_spheroid' - self.makeline = MAKELINE - self.mem_size = prefix + 'mem_size' - self.num_geom = prefix + 'NumGeometries' - self.num_points =prefix + 'npoints' - self.perimeter = prefix + 'Perimeter' - self.perimeter3d = prefix + 'Perimeter3D' - self.point_on_surface = prefix + 'PointOnSurface' - self.polygonize = prefix + 'Polygonize' - self.reverse = prefix + 'Reverse' - self.scale = prefix + 'Scale' - self.snap_to_grid = prefix + 'SnapToGrid' - self.svg = prefix + 'AsSVG' - self.sym_difference = prefix + 'SymDifference' - self.transform = prefix + 'Transform' - self.translate = prefix + 'Translate' - self.union = UNION - self.unionagg = UNIONAGG - - def check_aggregate_support(self, aggregate): - """ - Checks if the given aggregate name is supported (that is, if it's - in `self.valid_aggregates`). - """ - agg_name = aggregate.__class__.__name__ - return agg_name in self.valid_aggregates - - def convert_extent(self, box): - """ - Returns a 4-tuple extent for the `Extent` aggregate by converting - the bounding box text returned by PostGIS (`box` argument), for - example: "BOX(-90.0 30.0, -85.0 40.0)". - """ - ll, ur = box[4:-1].split(',') - xmin, ymin = map(float, ll.split()) - xmax, ymax = map(float, ur.split()) - return (xmin, ymin, xmax, ymax) - - def convert_extent3d(self, box3d): - """ - Returns a 6-tuple extent for the `Extent3D` aggregate by converting - the 3d bounding-box text returnded by PostGIS (`box3d` argument), for - example: "BOX3D(-90.0 30.0 1, -85.0 40.0 2)". - """ - ll, ur = box3d[6:-1].split(',') - xmin, ymin, zmin = map(float, ll.split()) - xmax, ymax, zmax = map(float, ur.split()) - return (xmin, ymin, zmin, xmax, ymax, zmax) - - def convert_geom(self, hex, geo_field): - """ - Converts the geometry returned from PostGIS aggretates. - """ - if hex: - return Geometry(hex) - else: - return None - - def geo_db_type(self, f): - """ - Return the database field type for the given geometry field. - Typically this is `None` because geometry columns are added via - the `AddGeometryColumn` stored procedure, unless the field - has been specified to be of geography type instead. - """ - if f.geography: - if not self.geography: - raise NotImplementedError('PostGIS 1.5 required for geography column support.') - - if f.srid != 4326: - raise NotImplementedError('PostGIS 1.5 supports geography columns ' - 'only with an SRID of 4326.') - - return 'geography(%s,%d)'% (f.geom_type, f.srid) - else: - return None - - def get_distance(self, f, dist_val, lookup_type): - """ - Retrieve the distance parameters for the given geometry field, - distance lookup value, and the distance lookup type. - - This is the most complex implementation of the spatial backends due to - what is supported on geodetic geometry columns vs. what's available on - projected geometry columns. In addition, it has to take into account - the newly introduced geography column type introudced in PostGIS 1.5. - """ - # Getting the distance parameter and any options. - if len(dist_val) == 1: - value, option = dist_val[0], None - else: - value, option = dist_val - - # Shorthand boolean flags. - geodetic = f.geodetic(self.connection) - geography = f.geography and self.geography - - if isinstance(value, Distance): - if geography: - dist_param = value.m - elif geodetic: - if lookup_type == 'dwithin': - raise ValueError('Only numeric values of degree units are ' - 'allowed on geographic DWithin queries.') - dist_param = value.m - else: - dist_param = getattr(value, Distance.unit_attname(f.units_name(self.connection))) - else: - # Assuming the distance is in the units of the field. - dist_param = value - - if (not geography and geodetic and lookup_type != 'dwithin' - and option == 'spheroid'): - # using distance_spheroid requires the spheroid of the field as - # a parameter. - return [f._spheroid, dist_param] - else: - return [dist_param] - - def get_geom_placeholder(self, f, value): - """ - Provides a proper substitution value for Geometries that are not in the - SRID of the field. Specifically, this routine will substitute in the - ST_Transform() function call. - """ - if value is None or value.srid == f.srid: - placeholder = '%s' - else: - # Adding Transform() to the SQL placeholder. - placeholder = '%s(%%s, %s)' % (self.transform, f.srid) - - if hasattr(value, 'expression'): - # If this is an F expression, then we don't really want - # a placeholder and instead substitute in the column - # of the expression. - placeholder = placeholder % '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression])) - - return placeholder - - def _get_postgis_func(self, func): - """ - Helper routine for calling PostGIS functions and returning their result. - """ - cursor = self.connection._cursor() - try: - try: - cursor.execute('SELECT %s()' % func) - row = cursor.fetchone() - except: - # Responsibility of callers to perform error handling. - raise - finally: - # Close out the connection. See #9437. - self.connection.close() - return row[0] - - def postgis_geos_version(self): - "Returns the version of the GEOS library used with PostGIS." - return self._get_postgis_func('postgis_geos_version') - - def postgis_lib_version(self): - "Returns the version number of the PostGIS library used with PostgreSQL." - return self._get_postgis_func('postgis_lib_version') - - def postgis_proj_version(self): - "Returns the version of the PROJ.4 library used with PostGIS." - return self._get_postgis_func('postgis_proj_version') - - def postgis_version(self): - "Returns PostGIS version number and compile-time options." - return self._get_postgis_func('postgis_version') - - def postgis_full_version(self): - "Returns PostGIS version number and compile-time options." - return self._get_postgis_func('postgis_full_version') - - def postgis_version_tuple(self): - """ - Returns the PostGIS version as a tuple (version string, major, - minor, subminor). - """ - # Getting the PostGIS version - version = self.postgis_lib_version() - m = self.version_regex.match(version) - - if m: - major = int(m.group('major')) - minor1 = int(m.group('minor1')) - minor2 = int(m.group('minor2')) - else: - raise Exception('Could not parse PostGIS version string: %s' % version) - - return (version, major, minor1, minor2) - - def proj_version_tuple(self): - """ - Return the version of PROJ.4 used by PostGIS as a tuple of the - major, minor, and subminor release numbers. - """ - proj_regex = re.compile(r'(\d+)\.(\d+)\.(\d+)') - proj_ver_str = self.postgis_proj_version() - m = proj_regex.search(proj_ver_str) - if m: - return tuple(map(int, [m.group(1), m.group(2), m.group(3)])) - else: - raise Exception('Could not determine PROJ.4 version from PostGIS.') - - def num_params(self, lookup_type, num_param): - """ - Helper routine that returns a boolean indicating whether the number of - parameters is correct for the lookup type. - """ - def exactly_two(np): return np == 2 - def two_to_three(np): return np >= 2 and np <=3 - if (lookup_type in self.distance_functions and - lookup_type != 'dwithin'): - return two_to_three(num_param) - else: - return exactly_two(num_param) - - def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn): - """ - Constructs spatial SQL from the given lookup value tuple a - (alias, col, db_type), the lookup type string, lookup value, and - the geometry field. - """ - alias, col, db_type = lvalue - - # Getting the quoted geometry column. - geo_col = '%s.%s' % (qn(alias), qn(col)) - - if lookup_type in self.geometry_operators: - if field.geography and not lookup_type in self.geography_operators: - raise ValueError('PostGIS geography does not support the ' - '"%s" lookup.' % lookup_type) - # Handling a PostGIS operator. - op = self.geometry_operators[lookup_type] - return op.as_sql(geo_col, self.get_geom_placeholder(field, value)) - elif lookup_type in self.geometry_functions: - if field.geography and not lookup_type in self.geography_functions: - raise ValueError('PostGIS geography type does not support the ' - '"%s" lookup.' % lookup_type) - - # See if a PostGIS geometry function matches the lookup type. - tmp = self.geometry_functions[lookup_type] - - # Lookup types that are tuples take tuple arguments, e.g., 'relate' and - # distance lookups. - if isinstance(tmp, tuple): - # First element of tuple is the PostGISOperation instance, and the - # second element is either the type or a tuple of acceptable types - # that may passed in as further parameters for the lookup type. - op, arg_type = tmp - - # Ensuring that a tuple _value_ was passed in from the user - if not isinstance(value, (tuple, list)): - raise ValueError('Tuple required for `%s` lookup type.' % lookup_type) - - # Geometry is first element of lookup tuple. - geom = value[0] - - # Number of valid tuple parameters depends on the lookup type. - nparams = len(value) - if not self.num_params(lookup_type, nparams): - raise ValueError('Incorrect number of parameters given for `%s` lookup type.' % lookup_type) - - # Ensuring the argument type matches what we expect. - if not isinstance(value[1], arg_type): - raise ValueError('Argument type should be %s, got %s instead.' % (arg_type, type(value[1]))) - - # For lookup type `relate`, the op instance is not yet created (has - # to be instantiated here to check the pattern parameter). - if lookup_type == 'relate': - op = op(self.geom_func_prefix, value[1]) - elif lookup_type in self.distance_functions and lookup_type != 'dwithin': - if not field.geography and field.geodetic(self.connection): - # Geodetic distances are only availble from Points to - # PointFields on PostGIS 1.4 and below. - if not self.connection.ops.geography: - if field.geom_type != 'POINT': - raise ValueError('PostGIS spherical operations are only valid on PointFields.') - - if str(geom.geom_type) != 'Point': - raise ValueError('PostGIS geometry distance parameter is required to be of type Point.') - - # Setting up the geodetic operation appropriately. - if nparams == 3 and value[2] == 'spheroid': - op = op['spheroid'] - else: - op = op['sphere'] - else: - op = op['cartesian'] - else: - op = tmp - geom = value - - # Calling the `as_sql` function on the operation instance. - return op.as_sql(geo_col, self.get_geom_placeholder(field, geom)) - - elif lookup_type == 'isnull': - # Handling 'isnull' lookup type - return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or '')) - - raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) - - def spatial_aggregate_sql(self, agg): - """ - Returns the spatial aggregate SQL template and function for the - given Aggregate instance. - """ - agg_name = agg.__class__.__name__ - if not self.check_aggregate_support(agg): - raise NotImplementedError('%s spatial aggregate is not implmented for this backend.' % agg_name) - agg_name = agg_name.lower() - if agg_name == 'union': agg_name += 'agg' - sql_template = '%(function)s(%(field)s)' - sql_function = getattr(self, agg_name) - return sql_template, sql_function - - # Routines for getting the OGC-compliant models. - def geometry_columns(self): - from django.contrib.gis.db.backends.postgis.models import GeometryColumns - return GeometryColumns - - def spatial_ref_sys(self): - from django.contrib.gis.db.backends.postgis.models import SpatialRefSys - return SpatialRefSys diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/__init__.py b/parts/django/django/contrib/gis/db/backends/spatialite/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/adapter.py b/parts/django/django/contrib/gis/db/backends/spatialite/adapter.py deleted file mode 100644 index d8fefba..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/adapter.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.db.backends.sqlite3.base import Database -from django.contrib.gis.db.backends.adapter import WKTAdapter - -class SpatiaLiteAdapter(WKTAdapter): - "SQLite adaptor for geometry objects." - def __conform__(self, protocol): - if protocol is Database.PrepareProtocol: - return str(self) diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/base.py b/parts/django/django/contrib/gis/db/backends/spatialite/base.py deleted file mode 100644 index 729fc15..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/base.py +++ /dev/null @@ -1,77 +0,0 @@ -from ctypes.util import find_library -from django.conf import settings - -from django.core.exceptions import ImproperlyConfigured -from django.db.backends.sqlite3.base import * -from django.db.backends.sqlite3.base import DatabaseWrapper as SqliteDatabaseWrapper, \ - _sqlite_extract, _sqlite_date_trunc, _sqlite_regexp -from django.contrib.gis.db.backends.spatialite.client import SpatiaLiteClient -from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation -from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection -from django.contrib.gis.db.backends.spatialite.operations import SpatiaLiteOperations - -class DatabaseWrapper(SqliteDatabaseWrapper): - def __init__(self, *args, **kwargs): - # Before we get too far, make sure pysqlite 2.5+ is installed. - if Database.version_info < (2, 5, 0): - raise ImproperlyConfigured('Only versions of pysqlite 2.5+ are ' - 'compatible with SpatiaLite and GeoDjango.') - - # Trying to find the location of the SpatiaLite library. - # Here we are figuring out the path to the SpatiaLite library - # (`libspatialite`). If it's not in the system library path (e.g., it - # cannot be found by `ctypes.util.find_library`), then it may be set - # manually in the settings via the `SPATIALITE_LIBRARY_PATH` setting. - self.spatialite_lib = getattr(settings, 'SPATIALITE_LIBRARY_PATH', - find_library('spatialite')) - if not self.spatialite_lib: - raise ImproperlyConfigured('Unable to locate the SpatiaLite library. ' - 'Make sure it is in your library path, or set ' - 'SPATIALITE_LIBRARY_PATH in your settings.' - ) - super(DatabaseWrapper, self).__init__(*args, **kwargs) - self.ops = SpatiaLiteOperations(self) - self.client = SpatiaLiteClient(self) - self.creation = SpatiaLiteCreation(self) - self.introspection = SpatiaLiteIntrospection(self) - - def _cursor(self): - if self.connection is None: - ## The following is the same as in django.db.backends.sqlite3.base ## - settings_dict = self.settings_dict - if not settings_dict['NAME']: - raise ImproperlyConfigured("Please fill out the database NAME in the settings module before using the database.") - kwargs = { - 'database': settings_dict['NAME'], - 'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES, - } - kwargs.update(settings_dict['OPTIONS']) - self.connection = Database.connect(**kwargs) - # Register extract, date_trunc, and regexp functions. - self.connection.create_function("django_extract", 2, _sqlite_extract) - self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc) - self.connection.create_function("regexp", 2, _sqlite_regexp) - connection_created.send(sender=self.__class__, connection=self) - - ## From here on, customized for GeoDjango ## - - # Enabling extension loading on the SQLite connection. - try: - self.connection.enable_load_extension(True) - except AttributeError: - raise ImproperlyConfigured('The pysqlite library does not support C extension loading. ' - 'Both SQLite and pysqlite must be configured to allow ' - 'the loading of extensions to use SpatiaLite.' - ) - - # Loading the SpatiaLite library extension on the connection, and returning - # the created cursor. - cur = self.connection.cursor(factory=SQLiteCursorWrapper) - try: - cur.execute("SELECT load_extension(%s)", (self.spatialite_lib,)) - except Exception, msg: - raise ImproperlyConfigured('Unable to load the SpatiaLite library extension ' - '"%s" because: %s' % (self.spatialite_lib, msg)) - return cur - else: - return self.connection.cursor(factory=SQLiteCursorWrapper) diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/client.py b/parts/django/django/contrib/gis/db/backends/spatialite/client.py deleted file mode 100644 index 536065a..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/client.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.db.backends.sqlite3.client import DatabaseClient - -class SpatiaLiteClient(DatabaseClient): - executable_name = 'spatialite' - diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/creation.py b/parts/django/django/contrib/gis/db/backends/spatialite/creation.py deleted file mode 100644 index cbe4a29..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/creation.py +++ /dev/null @@ -1,96 +0,0 @@ -import os -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.core.management import call_command -from django.db.backends.sqlite3.creation import DatabaseCreation - -class SpatiaLiteCreation(DatabaseCreation): - - def create_test_db(self, verbosity=1, autoclobber=False): - """ - Creates a test database, prompting the user for confirmation if the - database already exists. Returns the name of the test database created. - - This method is overloaded to load up the SpatiaLite initialization - SQL prior to calling the `syncdb` command. - """ - if verbosity >= 1: - print "Creating test database '%s'..." % self.connection.alias - - test_database_name = self._create_test_db(verbosity, autoclobber) - - self.connection.close() - - self.connection.settings_dict["NAME"] = test_database_name - can_rollback = self._rollback_works() - self.connection.settings_dict["SUPPORTS_TRANSACTIONS"] = can_rollback - # Need to load the SpatiaLite initialization SQL before running `syncdb`. - self.load_spatialite_sql() - call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias) - - if settings.CACHE_BACKEND.startswith('db://'): - from django.core.cache import parse_backend_uri - _, cache_name, _ = parse_backend_uri(settings.CACHE_BACKEND) - call_command('createcachetable', cache_name) - - # Get a cursor (even though we don't need one yet). This has - # the side effect of initializing the test database. - cursor = self.connection.cursor() - - return test_database_name - - def sql_indexes_for_field(self, model, f, style): - "Return any spatial index creation SQL for the field." - from django.contrib.gis.db.models.fields import GeometryField - - output = super(SpatiaLiteCreation, self).sql_indexes_for_field(model, f, style) - - if isinstance(f, GeometryField): - gqn = self.connection.ops.geo_quote_name - qn = self.connection.ops.quote_name - db_table = model._meta.db_table - - output.append(style.SQL_KEYWORD('SELECT ') + - style.SQL_TABLE('AddGeometryColumn') + '(' + - style.SQL_TABLE(gqn(db_table)) + ', ' + - style.SQL_FIELD(gqn(f.column)) + ', ' + - style.SQL_FIELD(str(f.srid)) + ', ' + - style.SQL_COLTYPE(gqn(f.geom_type)) + ', ' + - style.SQL_KEYWORD(str(f.dim)) + ', ' + - style.SQL_KEYWORD(str(int(not f.null))) + - ');') - - if f.spatial_index: - output.append(style.SQL_KEYWORD('SELECT ') + - style.SQL_TABLE('CreateSpatialIndex') + '(' + - style.SQL_TABLE(gqn(db_table)) + ', ' + - style.SQL_FIELD(gqn(f.column)) + ');') - - return output - - def load_spatialite_sql(self): - """ - This routine loads up the SpatiaLite SQL file. - """ - # Getting the location of the SpatiaLite SQL file, and confirming - # it exists. - spatialite_sql = self.spatialite_init_file() - if not os.path.isfile(spatialite_sql): - raise ImproperlyConfigured('Could not find the required SpatiaLite initialization ' - 'SQL file (necessary for testing): %s' % spatialite_sql) - - # Opening up the SpatiaLite SQL initialization file and executing - # as a script. - sql_fh = open(spatialite_sql, 'r') - try: - cur = self.connection._cursor() - cur.executescript(sql_fh.read()) - finally: - sql_fh.close() - - def spatialite_init_file(self): - # SPATIALITE_SQL may be placed in settings to tell GeoDjango - # to use a specific path to the SpatiaLite initilization SQL. - return getattr(settings, 'SPATIALITE_SQL', - 'init_spatialite-%s.%s.sql' % - self.connection.ops.spatial_version[:2]) diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/introspection.py b/parts/django/django/contrib/gis/db/backends/spatialite/introspection.py deleted file mode 100644 index 1b5952c..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/introspection.py +++ /dev/null @@ -1,51 +0,0 @@ -from django.contrib.gis.gdal import OGRGeomType -from django.db.backends.sqlite3.introspection import DatabaseIntrospection, FlexibleFieldLookupDict - -class GeoFlexibleFieldLookupDict(FlexibleFieldLookupDict): - """ - Sublcass that includes updates the `base_data_types_reverse` dict - for geometry field types. - """ - base_data_types_reverse = FlexibleFieldLookupDict.base_data_types_reverse.copy() - base_data_types_reverse.update( - {'point' : 'GeometryField', - 'linestring' : 'GeometryField', - 'polygon' : 'GeometryField', - 'multipoint' : 'GeometryField', - 'multilinestring' : 'GeometryField', - 'multipolygon' : 'GeometryField', - 'geometrycollection' : 'GeometryField', - }) - -class SpatiaLiteIntrospection(DatabaseIntrospection): - data_types_reverse = GeoFlexibleFieldLookupDict() - - def get_geometry_type(self, table_name, geo_col): - cursor = self.connection.cursor() - try: - # Querying the `geometry_columns` table to get additional metadata. - cursor.execute('SELECT "coord_dimension", "srid", "type" ' - 'FROM "geometry_columns" ' - 'WHERE "f_table_name"=%s AND "f_geometry_column"=%s', - (table_name, geo_col)) - row = cursor.fetchone() - if not row: - raise Exception('Could not find a geometry column for "%s"."%s"' % - (table_name, geo_col)) - - # OGRGeomType does not require GDAL and makes it easy to convert - # from OGC geom type name to Django field. - field_type = OGRGeomType(row[2]).django - - # Getting any GeometryField keyword arguments that are not the default. - dim = row[0] - srid = row[1] - field_params = {} - if srid != 4326: - field_params['srid'] = srid - if isinstance(dim, basestring) and 'Z' in dim: - field_params['dim'] = 3 - finally: - cursor.close() - - return field_type, field_params diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/models.py b/parts/django/django/contrib/gis/db/backends/spatialite/models.py deleted file mode 100644 index 684c5d8..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/models.py +++ /dev/null @@ -1,60 +0,0 @@ -""" - The GeometryColumns and SpatialRefSys models for the SpatiaLite backend. -""" -from django.db import models -from django.contrib.gis.db.backends.base import SpatialRefSysMixin - -class GeometryColumns(models.Model): - """ - The 'geometry_columns' table from SpatiaLite. - """ - f_table_name = models.CharField(max_length=256) - f_geometry_column = models.CharField(max_length=256) - type = models.CharField(max_length=30) - coord_dimension = models.IntegerField() - srid = models.IntegerField(primary_key=True) - spatial_index_enabled = models.IntegerField() - - class Meta: - db_table = 'geometry_columns' - managed = False - - @classmethod - def table_name_col(cls): - """ - Returns the name of the metadata column used to store the - the feature table name. - """ - return 'f_table_name' - - @classmethod - def geom_col_name(cls): - """ - Returns the name of the metadata column used to store the - the feature geometry column. - """ - return 'f_geometry_column' - - def __unicode__(self): - return "%s.%s - %dD %s field (SRID: %d)" % \ - (self.f_table_name, self.f_geometry_column, - self.coord_dimension, self.type, self.srid) - -class SpatialRefSys(models.Model, SpatialRefSysMixin): - """ - The 'spatial_ref_sys' table from SpatiaLite. - """ - srid = models.IntegerField(primary_key=True) - auth_name = models.CharField(max_length=256) - auth_srid = models.IntegerField() - ref_sys_name = models.CharField(max_length=256) - proj4text = models.CharField(max_length=2048) - - @property - def wkt(self): - from django.contrib.gis.gdal import SpatialReference - return SpatialReference(self.proj4text).wkt - - class Meta: - db_table = 'spatial_ref_sys' - managed = False diff --git a/parts/django/django/contrib/gis/db/backends/spatialite/operations.py b/parts/django/django/contrib/gis/db/backends/spatialite/operations.py deleted file mode 100644 index e6f8409..0000000 --- a/parts/django/django/contrib/gis/db/backends/spatialite/operations.py +++ /dev/null @@ -1,343 +0,0 @@ -import re -from decimal import Decimal - -from django.contrib.gis.db.backends.base import BaseSpatialOperations -from django.contrib.gis.db.backends.util import SpatialOperation, SpatialFunction -from django.contrib.gis.db.backends.spatialite.adapter import SpatiaLiteAdapter -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Distance -from django.core.exceptions import ImproperlyConfigured -from django.db.backends.sqlite3.base import DatabaseOperations -from django.db.utils import DatabaseError - -class SpatiaLiteOperator(SpatialOperation): - "For SpatiaLite operators (e.g. `&&`, `~`)." - def __init__(self, operator): - super(SpatiaLiteOperator, self).__init__(operator=operator) - -class SpatiaLiteFunction(SpatialFunction): - "For SpatiaLite function calls." - def __init__(self, function, **kwargs): - super(SpatiaLiteFunction, self).__init__(function, **kwargs) - -class SpatiaLiteFunctionParam(SpatiaLiteFunction): - "For SpatiaLite functions that take another parameter." - sql_template = '%(function)s(%(geo_col)s, %(geometry)s, %%s)' - -class SpatiaLiteDistance(SpatiaLiteFunction): - "For SpatiaLite distance operations." - dist_func = 'Distance' - sql_template = '%(function)s(%(geo_col)s, %(geometry)s) %(operator)s %%s' - - def __init__(self, operator): - super(SpatiaLiteDistance, self).__init__(self.dist_func, - operator=operator) - -class SpatiaLiteRelate(SpatiaLiteFunctionParam): - "For SpatiaLite Relate(<geom>, <pattern>) calls." - pattern_regex = re.compile(r'^[012TF\*]{9}$') - def __init__(self, pattern): - if not self.pattern_regex.match(pattern): - raise ValueError('Invalid intersection matrix pattern "%s".' % pattern) - super(SpatiaLiteRelate, self).__init__('Relate') - -# Valid distance types and substitutions -dtypes = (Decimal, Distance, float, int, long) -def get_dist_ops(operator): - "Returns operations for regular distances; spherical distances are not currently supported." - return (SpatiaLiteDistance(operator),) - -class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations): - compiler_module = 'django.contrib.gis.db.models.sql.compiler' - name = 'spatialite' - spatialite = True - version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)') - valid_aggregates = dict([(k, None) for k in ('Extent', 'Union')]) - - Adapter = SpatiaLiteAdapter - Adaptor = Adapter # Backwards-compatibility alias. - - area = 'Area' - centroid = 'Centroid' - contained = 'MbrWithin' - difference = 'Difference' - distance = 'Distance' - envelope = 'Envelope' - intersection = 'Intersection' - length = 'GLength' # OpenGis defines Length, but this conflicts with an SQLite reserved keyword - num_geom = 'NumGeometries' - num_points = 'NumPoints' - point_on_surface = 'PointOnSurface' - scale = 'ScaleCoords' - svg = 'AsSVG' - sym_difference = 'SymDifference' - transform = 'Transform' - translate = 'ShiftCoords' - union = 'GUnion' # OpenGis defines Union, but this conflicts with an SQLite reserved keyword - unionagg = 'GUnion' - - from_text = 'GeomFromText' - from_wkb = 'GeomFromWKB' - select = 'AsText(%s)' - - geometry_functions = { - 'equals' : SpatiaLiteFunction('Equals'), - 'disjoint' : SpatiaLiteFunction('Disjoint'), - 'touches' : SpatiaLiteFunction('Touches'), - 'crosses' : SpatiaLiteFunction('Crosses'), - 'within' : SpatiaLiteFunction('Within'), - 'overlaps' : SpatiaLiteFunction('Overlaps'), - 'contains' : SpatiaLiteFunction('Contains'), - 'intersects' : SpatiaLiteFunction('Intersects'), - 'relate' : (SpatiaLiteRelate, basestring), - # Retruns true if B's bounding box completely contains A's bounding box. - 'contained' : SpatiaLiteFunction('MbrWithin'), - # Returns true if A's bounding box completely contains B's bounding box. - 'bbcontains' : SpatiaLiteFunction('MbrContains'), - # Returns true if A's bounding box overlaps B's bounding box. - 'bboverlaps' : SpatiaLiteFunction('MbrOverlaps'), - # These are implemented here as synonyms for Equals - 'same_as' : SpatiaLiteFunction('Equals'), - 'exact' : SpatiaLiteFunction('Equals'), - } - - distance_functions = { - 'distance_gt' : (get_dist_ops('>'), dtypes), - 'distance_gte' : (get_dist_ops('>='), dtypes), - 'distance_lt' : (get_dist_ops('<'), dtypes), - 'distance_lte' : (get_dist_ops('<='), dtypes), - } - geometry_functions.update(distance_functions) - - def __init__(self, connection): - super(DatabaseOperations, self).__init__() - self.connection = connection - - # Determine the version of the SpatiaLite library. - try: - vtup = self.spatialite_version_tuple() - version = vtup[1:] - if version < (2, 3, 0): - raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions ' - '2.3.0 and above') - self.spatial_version = version - except ImproperlyConfigured: - raise - except Exception, msg: - raise ImproperlyConfigured('Cannot determine the SpatiaLite version for the "%s" ' - 'database (error was "%s"). Was the SpatiaLite initialization ' - 'SQL loaded on this database?' % - (self.connection.settings_dict['NAME'], msg)) - - # Creating the GIS terms dictionary. - gis_terms = ['isnull'] - gis_terms += self.geometry_functions.keys() - self.gis_terms = dict([(term, None) for term in gis_terms]) - - def check_aggregate_support(self, aggregate): - """ - Checks if the given aggregate name is supported (that is, if it's - in `self.valid_aggregates`). - """ - agg_name = aggregate.__class__.__name__ - return agg_name in self.valid_aggregates - - def convert_geom(self, wkt, geo_field): - """ - Converts geometry WKT returned from a SpatiaLite aggregate. - """ - if wkt: - return Geometry(wkt, geo_field.srid) - else: - return None - - def geo_db_type(self, f): - """ - Returns None because geometry columnas are added via the - `AddGeometryColumn` stored procedure on SpatiaLite. - """ - return None - - def get_distance(self, f, value, lookup_type): - """ - Returns the distance parameters for the given geometry field, - lookup value, and lookup type. SpatiaLite only supports regular - cartesian-based queries (no spheroid/sphere calculations for point - geometries like PostGIS). - """ - if not value: - return [] - value = value[0] - if isinstance(value, Distance): - if f.geodetic(self.connection): - raise ValueError('SpatiaLite does not support distance queries on ' - 'geometry fields with a geodetic coordinate system. ' - 'Distance objects; use a numeric value of your ' - 'distance in degrees instead.') - else: - dist_param = getattr(value, Distance.unit_attname(f.units_name(self.connection))) - else: - dist_param = value - return [dist_param] - - def get_geom_placeholder(self, f, value): - """ - Provides a proper substitution value for Geometries that are not in the - SRID of the field. Specifically, this routine will substitute in the - Transform() and GeomFromText() function call(s). - """ - def transform_value(value, srid): - return not (value is None or value.srid == srid) - if hasattr(value, 'expression'): - if transform_value(value, f.srid): - placeholder = '%s(%%s, %s)' % (self.transform, f.srid) - else: - placeholder = '%s' - # No geometry value used for F expression, substitue in - # the column name instead. - return placeholder % '%s.%s' % tuple(map(self.quote_name, value.cols[value.expression])) - else: - if transform_value(value, f.srid): - # Adding Transform() to the SQL placeholder. - return '%s(%s(%%s,%s), %s)' % (self.transform, self.from_text, value.srid, f.srid) - else: - return '%s(%%s,%s)' % (self.from_text, f.srid) - - def _get_spatialite_func(self, func): - """ - Helper routine for calling SpatiaLite functions and returning - their result. - """ - cursor = self.connection._cursor() - try: - try: - cursor.execute('SELECT %s' % func) - row = cursor.fetchone() - except: - # Responsibility of caller to perform error handling. - raise - finally: - cursor.close() - return row[0] - - def geos_version(self): - "Returns the version of GEOS used by SpatiaLite as a string." - return self._get_spatialite_func('geos_version()') - - def proj4_version(self): - "Returns the version of the PROJ.4 library used by SpatiaLite." - return self._get_spatialite_func('proj4_version()') - - def spatialite_version(self): - "Returns the SpatiaLite library version as a string." - return self._get_spatialite_func('spatialite_version()') - - def spatialite_version_tuple(self): - """ - Returns the SpatiaLite version as a tuple (version string, major, - minor, subminor). - """ - # Getting the SpatiaLite version. - try: - version = self.spatialite_version() - except DatabaseError: - # The `spatialite_version` function first appeared in version 2.3.1 - # of SpatiaLite, so doing a fallback test for 2.3.0 (which is - # used by popular Debian/Ubuntu packages). - version = None - try: - tmp = self._get_spatialite_func("X(GeomFromText('POINT(1 1)'))") - if tmp == 1.0: version = '2.3.0' - except DatabaseError: - pass - # If no version string defined, then just re-raise the original - # exception. - if version is None: raise - - m = self.version_regex.match(version) - if m: - major = int(m.group('major')) - minor1 = int(m.group('minor1')) - minor2 = int(m.group('minor2')) - else: - raise Exception('Could not parse SpatiaLite version string: %s' % version) - - return (version, major, minor1, minor2) - - def spatial_aggregate_sql(self, agg): - """ - Returns the spatial aggregate SQL template and function for the - given Aggregate instance. - """ - agg_name = agg.__class__.__name__ - if not self.check_aggregate_support(agg): - raise NotImplementedError('%s spatial aggregate is not implmented for this backend.' % agg_name) - agg_name = agg_name.lower() - if agg_name == 'union': agg_name += 'agg' - sql_template = self.select % '%(function)s(%(field)s)' - sql_function = getattr(self, agg_name) - return sql_template, sql_function - - def spatial_lookup_sql(self, lvalue, lookup_type, value, field, qn): - """ - Returns the SpatiaLite-specific SQL for the given lookup value - [a tuple of (alias, column, db_type)], lookup type, lookup - value, the model field, and the quoting function. - """ - alias, col, db_type = lvalue - - # Getting the quoted field as `geo_col`. - geo_col = '%s.%s' % (qn(alias), qn(col)) - - if lookup_type in self.geometry_functions: - # See if a SpatiaLite geometry function matches the lookup type. - tmp = self.geometry_functions[lookup_type] - - # Lookup types that are tuples take tuple arguments, e.g., 'relate' and - # distance lookups. - if isinstance(tmp, tuple): - # First element of tuple is the SpatiaLiteOperation instance, and the - # second element is either the type or a tuple of acceptable types - # that may passed in as further parameters for the lookup type. - op, arg_type = tmp - - # Ensuring that a tuple _value_ was passed in from the user - if not isinstance(value, (tuple, list)): - raise ValueError('Tuple required for `%s` lookup type.' % lookup_type) - - # Geometry is first element of lookup tuple. - geom = value[0] - - # Number of valid tuple parameters depends on the lookup type. - if len(value) != 2: - raise ValueError('Incorrect number of parameters given for `%s` lookup type.' % lookup_type) - - # Ensuring the argument type matches what we expect. - if not isinstance(value[1], arg_type): - raise ValueError('Argument type should be %s, got %s instead.' % (arg_type, type(value[1]))) - - # For lookup type `relate`, the op instance is not yet created (has - # to be instantiated here to check the pattern parameter). - if lookup_type == 'relate': - op = op(value[1]) - elif lookup_type in self.distance_functions: - op = op[0] - else: - op = tmp - geom = value - # Calling the `as_sql` function on the operation instance. - return op.as_sql(geo_col, self.get_geom_placeholder(field, geom)) - elif lookup_type == 'isnull': - # Handling 'isnull' lookup type - return "%s IS %sNULL" % (geo_col, (not value and 'NOT ' or '')) - - raise TypeError("Got invalid lookup_type: %s" % repr(lookup_type)) - - # Routines for getting the OGC-compliant models. - def geometry_columns(self): - from django.contrib.gis.db.backends.spatialite.models import GeometryColumns - return GeometryColumns - - def spatial_ref_sys(self): - from django.contrib.gis.db.backends.spatialite.models import SpatialRefSys - return SpatialRefSys diff --git a/parts/django/django/contrib/gis/db/backends/util.py b/parts/django/django/contrib/gis/db/backends/util.py deleted file mode 100644 index b50c8e2..0000000 --- a/parts/django/django/contrib/gis/db/backends/util.py +++ /dev/null @@ -1,56 +0,0 @@ -""" -A collection of utility routines and classes used by the spatial -backends. -""" - -def gqn(val): - """ - The geographic quote name function; used for quoting tables and - geometries (they use single rather than the double quotes of the - backend quotename function). - """ - if isinstance(val, basestring): - if isinstance(val, unicode): val = val.encode('ascii') - return "'%s'" % val - else: - return str(val) - -class SpatialOperation(object): - """ - Base class for generating spatial SQL. - """ - sql_template = '%(geo_col)s %(operator)s %(geometry)s' - - def __init__(self, function='', operator='', result='', **kwargs): - self.function = function - self.operator = operator - self.result = result - self.extra = kwargs - - def as_sql(self, geo_col, geometry='%s'): - return self.sql_template % self.params(geo_col, geometry) - - def params(self, geo_col, geometry): - params = {'function' : self.function, - 'geo_col' : geo_col, - 'geometry' : geometry, - 'operator' : self.operator, - 'result' : self.result, - } - params.update(self.extra) - return params - -class SpatialFunction(SpatialOperation): - """ - Base class for generating spatial SQL related to a function. - """ - sql_template = '%(function)s(%(geo_col)s, %(geometry)s)' - - def __init__(self, func, result='', operator='', **kwargs): - # Getting the function prefix. - default = {'function' : func, - 'operator' : operator, - 'result' : result - } - kwargs.update(default) - super(SpatialFunction, self).__init__(**kwargs) diff --git a/parts/django/django/contrib/gis/db/models/__init__.py b/parts/django/django/contrib/gis/db/models/__init__.py deleted file mode 100644 index 87e2b68..0000000 --- a/parts/django/django/contrib/gis/db/models/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# Want to get everything from the 'normal' models package. -from django.db.models import * - -# Geographic aggregate functions -from django.contrib.gis.db.models.aggregates import * - -# The GeoManager -from django.contrib.gis.db.models.manager import GeoManager - -# The geographic-enabled fields. -from django.contrib.gis.db.models.fields import \ - GeometryField, PointField, LineStringField, PolygonField, \ - MultiPointField, MultiLineStringField, MultiPolygonField, \ - GeometryCollectionField diff --git a/parts/django/django/contrib/gis/db/models/aggregates.py b/parts/django/django/contrib/gis/db/models/aggregates.py deleted file mode 100644 index cd26839..0000000 --- a/parts/django/django/contrib/gis/db/models/aggregates.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.db.models import Aggregate -from django.contrib.gis.db.models.sql import GeomField - -class Collect(Aggregate): - name = 'Collect' - -class Extent(Aggregate): - name = 'Extent' - -class Extent3D(Aggregate): - name = 'Extent3D' - -class MakeLine(Aggregate): - name = 'MakeLine' - -class Union(Aggregate): - name = 'Union' diff --git a/parts/django/django/contrib/gis/db/models/fields.py b/parts/django/django/contrib/gis/db/models/fields.py deleted file mode 100644 index 2b16607..0000000 --- a/parts/django/django/contrib/gis/db/models/fields.py +++ /dev/null @@ -1,294 +0,0 @@ -from django.db.models.fields import Field -from django.db.models.sql.expressions import SQLEvaluator -from django.utils.translation import ugettext_lazy as _ -from django.contrib.gis import forms -from django.contrib.gis.db.models.proxy import GeometryProxy -from django.contrib.gis.geometry.backend import Geometry, GeometryException - -# Local cache of the spatial_ref_sys table, which holds SRID data for each -# spatial database alias. This cache exists so that the database isn't queried -# for SRID info each time a distance query is constructed. -_srid_cache = {} - -def get_srid_info(srid, connection): - """ - Returns the units, unit name, and spheroid WKT associated with the - given SRID from the `spatial_ref_sys` (or equivalent) spatial database - table for the given database connection. These results are cached. - """ - global _srid_cache - - try: - # The SpatialRefSys model for the spatial backend. - SpatialRefSys = connection.ops.spatial_ref_sys() - except NotImplementedError: - # No `spatial_ref_sys` table in spatial backend (e.g., MySQL). - return None, None, None - - if not connection.alias in _srid_cache: - # Initialize SRID dictionary for database if it doesn't exist. - _srid_cache[connection.alias] = {} - - if not srid in _srid_cache[connection.alias]: - # Use `SpatialRefSys` model to query for spatial reference info. - sr = SpatialRefSys.objects.using(connection.alias).get(srid=srid) - units, units_name = sr.units - spheroid = SpatialRefSys.get_spheroid(sr.wkt) - _srid_cache[connection.alias][srid] = (units, units_name, spheroid) - - return _srid_cache[connection.alias][srid] - -class GeometryField(Field): - "The base GIS field -- maps to the OpenGIS Specification Geometry type." - - # The OpenGIS Geometry name. - geom_type = 'GEOMETRY' - - # Geodetic units. - geodetic_units = ('Decimal Degree', 'degree') - - description = _("The base GIS field -- maps to the OpenGIS Specification Geometry type.") - - def __init__(self, verbose_name=None, srid=4326, spatial_index=True, dim=2, - geography=False, **kwargs): - """ - The initialization function for geometry fields. Takes the following - as keyword arguments: - - srid: - The spatial reference system identifier, an OGC standard. - Defaults to 4326 (WGS84). - - spatial_index: - Indicates whether to create a spatial index. Defaults to True. - Set this instead of 'db_index' for geographic fields since index - creation is different for geometry columns. - - dim: - The number of dimensions for this geometry. Defaults to 2. - - extent: - Customize the extent, in a 4-tuple of WGS 84 coordinates, for the - geometry field entry in the `USER_SDO_GEOM_METADATA` table. Defaults - to (-180.0, -90.0, 180.0, 90.0). - - tolerance: - Define the tolerance, in meters, to use for the geometry field - entry in the `USER_SDO_GEOM_METADATA` table. Defaults to 0.05. - """ - - # Setting the index flag with the value of the `spatial_index` keyword. - self.spatial_index = spatial_index - - # Setting the SRID and getting the units. Unit information must be - # easily available in the field instance for distance queries. - self.srid = srid - - # Setting the dimension of the geometry field. - self.dim = dim - - # Setting the verbose_name keyword argument with the positional - # first parameter, so this works like normal fields. - kwargs['verbose_name'] = verbose_name - - # Is this a geography rather than a geometry column? - self.geography = geography - - # Oracle-specific private attributes for creating the entrie in - # `USER_SDO_GEOM_METADATA` - self._extent = kwargs.pop('extent', (-180.0, -90.0, 180.0, 90.0)) - self._tolerance = kwargs.pop('tolerance', 0.05) - - super(GeometryField, self).__init__(**kwargs) - - # The following functions are used to get the units, their name, and - # the spheroid corresponding to the SRID of the GeometryField. - def _get_srid_info(self, connection): - # Get attributes from `get_srid_info`. - self._units, self._units_name, self._spheroid = get_srid_info(self.srid, connection) - - def spheroid(self, connection): - if not hasattr(self, '_spheroid'): - self._get_srid_info(connection) - return self._spheroid - - def units(self, connection): - if not hasattr(self, '_units'): - self._get_srid_info(connection) - return self._units - - def units_name(self, connection): - if not hasattr(self, '_units_name'): - self._get_srid_info(connection) - return self._units_name - - ### Routines specific to GeometryField ### - def geodetic(self, connection): - """ - Returns true if this field's SRID corresponds with a coordinate - system that uses non-projected units (e.g., latitude/longitude). - """ - return self.units_name(connection) in self.geodetic_units - - def get_distance(self, value, lookup_type, connection): - """ - Returns a distance number in units of the field. For example, if - `D(km=1)` was passed in and the units of the field were in meters, - then 1000 would be returned. - """ - return connection.ops.get_distance(self, value, lookup_type) - - def get_prep_value(self, value): - """ - Spatial lookup values are either a parameter that is (or may be - converted to) a geometry, or a sequence of lookup values that - begins with a geometry. This routine will setup the geometry - value properly, and preserve any other lookup parameters before - returning to the caller. - """ - if isinstance(value, SQLEvaluator): - return value - elif isinstance(value, (tuple, list)): - geom = value[0] - seq_value = True - else: - geom = value - seq_value = False - - # When the input is not a GEOS geometry, attempt to construct one - # from the given string input. - if isinstance(geom, Geometry): - pass - elif isinstance(geom, basestring) or hasattr(geom, '__geo_interface__'): - try: - geom = Geometry(geom) - except GeometryException: - raise ValueError('Could not create geometry from lookup value.') - else: - raise ValueError('Cannot use object with type %s for a geometry lookup parameter.' % type(geom).__name__) - - # Assigning the SRID value. - geom.srid = self.get_srid(geom) - - if seq_value: - lookup_val = [geom] - lookup_val.extend(value[1:]) - return tuple(lookup_val) - else: - return geom - - def get_srid(self, geom): - """ - Returns the default SRID for the given geometry, taking into account - the SRID set for the field. For example, if the input geometry - has no SRID, then that of the field will be returned. - """ - gsrid = geom.srid # SRID of given geometry. - if gsrid is None or self.srid == -1 or (gsrid == -1 and self.srid != -1): - return self.srid - else: - return gsrid - - ### Routines overloaded from Field ### - def contribute_to_class(self, cls, name): - super(GeometryField, self).contribute_to_class(cls, name) - - # Setup for lazy-instantiated Geometry object. - setattr(cls, self.attname, GeometryProxy(Geometry, self)) - - def db_type(self, connection): - return connection.ops.geo_db_type(self) - - def formfield(self, **kwargs): - defaults = {'form_class' : forms.GeometryField, - 'null' : self.null, - 'geom_type' : self.geom_type, - 'srid' : self.srid, - } - defaults.update(kwargs) - return super(GeometryField, self).formfield(**defaults) - - def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False): - """ - Prepare for the database lookup, and return any spatial parameters - necessary for the query. This includes wrapping any geometry - parameters with a backend-specific adapter and formatting any distance - parameters into the correct units for the coordinate system of the - field. - """ - if lookup_type in connection.ops.gis_terms: - # special case for isnull lookup - if lookup_type == 'isnull': - return [] - - # Populating the parameters list, and wrapping the Geometry - # with the Adapter of the spatial backend. - if isinstance(value, (tuple, list)): - params = [connection.ops.Adapter(value[0])] - if lookup_type in connection.ops.distance_functions: - # Getting the distance parameter in the units of the field. - params += self.get_distance(value[1:], lookup_type, connection) - elif lookup_type in connection.ops.truncate_params: - # Lookup is one where SQL parameters aren't needed from the - # given lookup value. - pass - else: - params += value[1:] - elif isinstance(value, SQLEvaluator): - params = [] - else: - params = [connection.ops.Adapter(value)] - - return params - else: - raise ValueError('%s is not a valid spatial lookup for %s.' % - (lookup_type, self.__class__.__name__)) - - def get_prep_lookup(self, lookup_type, value): - if lookup_type == 'isnull': - return bool(value) - else: - return self.get_prep_value(value) - - def get_db_prep_save(self, value, connection): - "Prepares the value for saving in the database." - if value is None: - return None - else: - return connection.ops.Adapter(self.get_prep_value(value)) - - def get_placeholder(self, value, connection): - """ - Returns the placeholder for the geometry column for the - given value. - """ - return connection.ops.get_geom_placeholder(self, value) - -# The OpenGIS Geometry Type Fields -class PointField(GeometryField): - geom_type = 'POINT' - description = _("Point") - -class LineStringField(GeometryField): - geom_type = 'LINESTRING' - description = _("Line string") - -class PolygonField(GeometryField): - geom_type = 'POLYGON' - description = _("Polygon") - -class MultiPointField(GeometryField): - geom_type = 'MULTIPOINT' - description = _("Multi-point") - -class MultiLineStringField(GeometryField): - geom_type = 'MULTILINESTRING' - description = _("Multi-line string") - -class MultiPolygonField(GeometryField): - geom_type = 'MULTIPOLYGON' - description = _("Multi polygon") - -class GeometryCollectionField(GeometryField): - geom_type = 'GEOMETRYCOLLECTION' - description = _("Geometry collection") diff --git a/parts/django/django/contrib/gis/db/models/manager.py b/parts/django/django/contrib/gis/db/models/manager.py deleted file mode 100644 index 61fb821..0000000 --- a/parts/django/django/contrib/gis/db/models/manager.py +++ /dev/null @@ -1,103 +0,0 @@ -from django.db.models.manager import Manager -from django.contrib.gis.db.models.query import GeoQuerySet - -class GeoManager(Manager): - "Overrides Manager to return Geographic QuerySets." - - # This manager should be used for queries on related fields - # so that geometry columns on Oracle and MySQL are selected - # properly. - use_for_related_fields = True - - def get_query_set(self): - return GeoQuerySet(self.model, using=self._db) - - def area(self, *args, **kwargs): - return self.get_query_set().area(*args, **kwargs) - - def centroid(self, *args, **kwargs): - return self.get_query_set().centroid(*args, **kwargs) - - def collect(self, *args, **kwargs): - return self.get_query_set().collect(*args, **kwargs) - - def difference(self, *args, **kwargs): - return self.get_query_set().difference(*args, **kwargs) - - def distance(self, *args, **kwargs): - return self.get_query_set().distance(*args, **kwargs) - - def envelope(self, *args, **kwargs): - return self.get_query_set().envelope(*args, **kwargs) - - def extent(self, *args, **kwargs): - return self.get_query_set().extent(*args, **kwargs) - - def extent3d(self, *args, **kwargs): - return self.get_query_set().extent3d(*args, **kwargs) - - def force_rhr(self, *args, **kwargs): - return self.get_query_set().force_rhr(*args, **kwargs) - - def geohash(self, *args, **kwargs): - return self.get_query_set().geohash(*args, **kwargs) - - def geojson(self, *args, **kwargs): - return self.get_query_set().geojson(*args, **kwargs) - - def gml(self, *args, **kwargs): - return self.get_query_set().gml(*args, **kwargs) - - def intersection(self, *args, **kwargs): - return self.get_query_set().intersection(*args, **kwargs) - - def kml(self, *args, **kwargs): - return self.get_query_set().kml(*args, **kwargs) - - def length(self, *args, **kwargs): - return self.get_query_set().length(*args, **kwargs) - - def make_line(self, *args, **kwargs): - return self.get_query_set().make_line(*args, **kwargs) - - def mem_size(self, *args, **kwargs): - return self.get_query_set().mem_size(*args, **kwargs) - - def num_geom(self, *args, **kwargs): - return self.get_query_set().num_geom(*args, **kwargs) - - def num_points(self, *args, **kwargs): - return self.get_query_set().num_points(*args, **kwargs) - - def perimeter(self, *args, **kwargs): - return self.get_query_set().perimeter(*args, **kwargs) - - def point_on_surface(self, *args, **kwargs): - return self.get_query_set().point_on_surface(*args, **kwargs) - - def reverse_geom(self, *args, **kwargs): - return self.get_query_set().reverse_geom(*args, **kwargs) - - def scale(self, *args, **kwargs): - return self.get_query_set().scale(*args, **kwargs) - - def snap_to_grid(self, *args, **kwargs): - return self.get_query_set().snap_to_grid(*args, **kwargs) - - def svg(self, *args, **kwargs): - return self.get_query_set().svg(*args, **kwargs) - - def sym_difference(self, *args, **kwargs): - return self.get_query_set().sym_difference(*args, **kwargs) - - def transform(self, *args, **kwargs): - return self.get_query_set().transform(*args, **kwargs) - - def translate(self, *args, **kwargs): - return self.get_query_set().translate(*args, **kwargs) - - def union(self, *args, **kwargs): - return self.get_query_set().union(*args, **kwargs) - - def unionagg(self, *args, **kwargs): - return self.get_query_set().unionagg(*args, **kwargs) diff --git a/parts/django/django/contrib/gis/db/models/proxy.py b/parts/django/django/contrib/gis/db/models/proxy.py deleted file mode 100644 index e569dd5..0000000 --- a/parts/django/django/contrib/gis/db/models/proxy.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -The GeometryProxy object, allows for lazy-geometries. The proxy uses -Python descriptors for instantiating and setting Geometry objects -corresponding to geographic model fields. - -Thanks to Robert Coup for providing this functionality (see #4322). -""" - -class GeometryProxy(object): - def __init__(self, klass, field): - """ - Proxy initializes on the given Geometry class (not an instance) and - the GeometryField. - """ - self._field = field - self._klass = klass - - def __get__(self, obj, type=None): - """ - This accessor retrieves the geometry, initializing it using the geometry - class specified during initialization and the HEXEWKB value of the field. - Currently, only GEOS or OGR geometries are supported. - """ - if obj is None: - # Accessed on a class, not an instance - return self - - # Getting the value of the field. - geom_value = obj.__dict__[self._field.attname] - - if isinstance(geom_value, self._klass): - geom = geom_value - elif (geom_value is None) or (geom_value==''): - geom = None - else: - # Otherwise, a Geometry object is built using the field's contents, - # and the model's corresponding attribute is set. - geom = self._klass(geom_value) - setattr(obj, self._field.attname, geom) - return geom - - def __set__(self, obj, value): - """ - This accessor sets the proxied geometry with the geometry class - specified during initialization. Values of None, HEXEWKB, or WKT may - be used to set the geometry as well. - """ - # The OGC Geometry type of the field. - gtype = self._field.geom_type - - # The geometry type must match that of the field -- unless the - # general GeometryField is used. - if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'): - # Assigning the SRID to the geometry. - if value.srid is None: value.srid = self._field.srid - elif value is None or isinstance(value, (basestring, buffer)): - # Set with None, WKT, HEX, or WKB - pass - else: - raise TypeError('cannot set %s GeometryProxy with value of type: %s' % (obj.__class__.__name__, type(value))) - - # Setting the objects dictionary with the value, and returning. - obj.__dict__[self._field.attname] = value - return value diff --git a/parts/django/django/contrib/gis/db/models/query.py b/parts/django/django/contrib/gis/db/models/query.py deleted file mode 100644 index 4df1a3a..0000000 --- a/parts/django/django/contrib/gis/db/models/query.py +++ /dev/null @@ -1,777 +0,0 @@ -from django.db import connections -from django.db.models.query import QuerySet, Q, ValuesQuerySet, ValuesListQuerySet - -from django.contrib.gis.db.models import aggregates -from django.contrib.gis.db.models.fields import get_srid_info, GeometryField, PointField, LineStringField -from django.contrib.gis.db.models.sql import AreaField, DistanceField, GeomField, GeoQuery, GeoWhereNode -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Area, Distance - -class GeoQuerySet(QuerySet): - "The Geographic QuerySet." - - ### Methods overloaded from QuerySet ### - def __init__(self, model=None, query=None, using=None): - super(GeoQuerySet, self).__init__(model=model, query=query, using=using) - self.query = query or GeoQuery(self.model) - - def values(self, *fields): - return self._clone(klass=GeoValuesQuerySet, setup=True, _fields=fields) - - def values_list(self, *fields, **kwargs): - flat = kwargs.pop('flat', False) - if kwargs: - raise TypeError('Unexpected keyword arguments to values_list: %s' - % (kwargs.keys(),)) - if flat and len(fields) > 1: - raise TypeError("'flat' is not valid when values_list is called with more than one field.") - return self._clone(klass=GeoValuesListQuerySet, setup=True, flat=flat, - _fields=fields) - - ### GeoQuerySet Methods ### - def area(self, tolerance=0.05, **kwargs): - """ - Returns the area of the geographic field in an `area` attribute on - each element of this GeoQuerySet. - """ - # Peforming setup here rather than in `_spatial_attribute` so that - # we can get the units for `AreaField`. - procedure_args, geo_field = self._spatial_setup('area', field_name=kwargs.get('field_name', None)) - s = {'procedure_args' : procedure_args, - 'geo_field' : geo_field, - 'setup' : False, - } - connection = connections[self.db] - backend = connection.ops - if backend.oracle: - s['procedure_fmt'] = '%(geo_col)s,%(tolerance)s' - s['procedure_args']['tolerance'] = tolerance - s['select_field'] = AreaField('sq_m') # Oracle returns area in units of meters. - elif backend.postgis or backend.spatialite: - if backend.geography: - # Geography fields support area calculation, returns square meters. - s['select_field'] = AreaField('sq_m') - elif not geo_field.geodetic(connection): - # Getting the area units of the geographic field. - s['select_field'] = AreaField(Area.unit_attname(geo_field.units_name(connection))) - else: - # TODO: Do we want to support raw number areas for geodetic fields? - raise Exception('Area on geodetic coordinate systems not supported.') - return self._spatial_attribute('area', s, **kwargs) - - def centroid(self, **kwargs): - """ - Returns the centroid of the geographic field in a `centroid` - attribute on each element of this GeoQuerySet. - """ - return self._geom_attribute('centroid', **kwargs) - - def collect(self, **kwargs): - """ - Performs an aggregate collect operation on the given geometry field. - This is analagous to a union operation, but much faster because - boundaries are not dissolved. - """ - return self._spatial_aggregate(aggregates.Collect, **kwargs) - - def difference(self, geom, **kwargs): - """ - Returns the spatial difference of the geographic field in a `difference` - attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('difference', geom, **kwargs) - - def distance(self, geom, **kwargs): - """ - Returns the distance from the given geographic field name to the - given geometry in a `distance` attribute on each element of the - GeoQuerySet. - - Keyword Arguments: - `spheroid` => If the geometry field is geodetic and PostGIS is - the spatial database, then the more accurate - spheroid calculation will be used instead of the - quicker sphere calculation. - - `tolerance` => Used only for Oracle. The tolerance is - in meters -- a default of 5 centimeters (0.05) - is used. - """ - return self._distance_attribute('distance', geom, **kwargs) - - def envelope(self, **kwargs): - """ - Returns a Geometry representing the bounding box of the - Geometry field in an `envelope` attribute on each element of - the GeoQuerySet. - """ - return self._geom_attribute('envelope', **kwargs) - - def extent(self, **kwargs): - """ - Returns the extent (aggregate) of the features in the GeoQuerySet. The - extent will be returned as a 4-tuple, consisting of (xmin, ymin, xmax, ymax). - """ - return self._spatial_aggregate(aggregates.Extent, **kwargs) - - def extent3d(self, **kwargs): - """ - Returns the aggregate extent, in 3D, of the features in the - GeoQuerySet. It is returned as a 6-tuple, comprising: - (xmin, ymin, zmin, xmax, ymax, zmax). - """ - return self._spatial_aggregate(aggregates.Extent3D, **kwargs) - - def force_rhr(self, **kwargs): - """ - Returns a modified version of the Polygon/MultiPolygon in which - all of the vertices follow the Right-Hand-Rule. By default, - this is attached as the `force_rhr` attribute on each element - of the GeoQuerySet. - """ - return self._geom_attribute('force_rhr', **kwargs) - - def geojson(self, precision=8, crs=False, bbox=False, **kwargs): - """ - Returns a GeoJSON representation of the geomtry field in a `geojson` - attribute on each element of the GeoQuerySet. - - The `crs` and `bbox` keywords may be set to True if the users wants - the coordinate reference system and the bounding box to be included - in the GeoJSON representation of the geometry. - """ - backend = connections[self.db].ops - if not backend.geojson: - raise NotImplementedError('Only PostGIS 1.3.4+ supports GeoJSON serialization.') - - if not isinstance(precision, (int, long)): - raise TypeError('Precision keyword must be set with an integer.') - - # Setting the options flag -- which depends on which version of - # PostGIS we're using. - if backend.spatial_version >= (1, 4, 0): - options = 0 - if crs and bbox: options = 3 - elif bbox: options = 1 - elif crs: options = 2 - else: - options = 0 - if crs and bbox: options = 3 - elif crs: options = 1 - elif bbox: options = 2 - s = {'desc' : 'GeoJSON', - 'procedure_args' : {'precision' : precision, 'options' : options}, - 'procedure_fmt' : '%(geo_col)s,%(precision)s,%(options)s', - } - return self._spatial_attribute('geojson', s, **kwargs) - - def geohash(self, precision=20, **kwargs): - """ - Returns a GeoHash representation of the given field in a `geohash` - attribute on each element of the GeoQuerySet. - - The `precision` keyword may be used to custom the number of - _characters_ used in the output GeoHash, the default is 20. - """ - s = {'desc' : 'GeoHash', - 'procedure_args': {'precision': precision}, - 'procedure_fmt': '%(geo_col)s,%(precision)s', - } - return self._spatial_attribute('geohash', s, **kwargs) - - def gml(self, precision=8, version=2, **kwargs): - """ - Returns GML representation of the given field in a `gml` attribute - on each element of the GeoQuerySet. - """ - backend = connections[self.db].ops - s = {'desc' : 'GML', 'procedure_args' : {'precision' : precision}} - if backend.postgis: - # PostGIS AsGML() aggregate function parameter order depends on the - # version -- uggh. - if backend.spatial_version > (1, 3, 1): - procedure_fmt = '%(version)s,%(geo_col)s,%(precision)s' - else: - procedure_fmt = '%(geo_col)s,%(precision)s,%(version)s' - s['procedure_args'] = {'precision' : precision, 'version' : version} - - return self._spatial_attribute('gml', s, **kwargs) - - def intersection(self, geom, **kwargs): - """ - Returns the spatial intersection of the Geometry field in - an `intersection` attribute on each element of this - GeoQuerySet. - """ - return self._geomset_attribute('intersection', geom, **kwargs) - - def kml(self, **kwargs): - """ - Returns KML representation of the geometry field in a `kml` - attribute on each element of this GeoQuerySet. - """ - s = {'desc' : 'KML', - 'procedure_fmt' : '%(geo_col)s,%(precision)s', - 'procedure_args' : {'precision' : kwargs.pop('precision', 8)}, - } - return self._spatial_attribute('kml', s, **kwargs) - - def length(self, **kwargs): - """ - Returns the length of the geometry field as a `Distance` object - stored in a `length` attribute on each element of this GeoQuerySet. - """ - return self._distance_attribute('length', None, **kwargs) - - def make_line(self, **kwargs): - """ - Creates a linestring from all of the PointField geometries in the - this GeoQuerySet and returns it. This is a spatial aggregate - method, and thus returns a geometry rather than a GeoQuerySet. - """ - return self._spatial_aggregate(aggregates.MakeLine, geo_field_type=PointField, **kwargs) - - def mem_size(self, **kwargs): - """ - Returns the memory size (number of bytes) that the geometry field takes - in a `mem_size` attribute on each element of this GeoQuerySet. - """ - return self._spatial_attribute('mem_size', {}, **kwargs) - - def num_geom(self, **kwargs): - """ - Returns the number of geometries if the field is a - GeometryCollection or Multi* Field in a `num_geom` - attribute on each element of this GeoQuerySet; otherwise - the sets with None. - """ - return self._spatial_attribute('num_geom', {}, **kwargs) - - def num_points(self, **kwargs): - """ - Returns the number of points in the first linestring in the - Geometry field in a `num_points` attribute on each element of - this GeoQuerySet; otherwise sets with None. - """ - return self._spatial_attribute('num_points', {}, **kwargs) - - def perimeter(self, **kwargs): - """ - Returns the perimeter of the geometry field as a `Distance` object - stored in a `perimeter` attribute on each element of this GeoQuerySet. - """ - return self._distance_attribute('perimeter', None, **kwargs) - - def point_on_surface(self, **kwargs): - """ - Returns a Point geometry guaranteed to lie on the surface of the - Geometry field in a `point_on_surface` attribute on each element - of this GeoQuerySet; otherwise sets with None. - """ - return self._geom_attribute('point_on_surface', **kwargs) - - def reverse_geom(self, **kwargs): - """ - Reverses the coordinate order of the geometry, and attaches as a - `reverse` attribute on each element of this GeoQuerySet. - """ - s = {'select_field' : GeomField(),} - kwargs.setdefault('model_att', 'reverse_geom') - if connections[self.db].ops.oracle: - s['geo_field_type'] = LineStringField - return self._spatial_attribute('reverse', s, **kwargs) - - def scale(self, x, y, z=0.0, **kwargs): - """ - Scales the geometry to a new size by multiplying the ordinates - with the given x,y,z scale factors. - """ - if connections[self.db].ops.spatialite: - if z != 0.0: - raise NotImplementedError('SpatiaLite does not support 3D scaling.') - s = {'procedure_fmt' : '%(geo_col)s,%(x)s,%(y)s', - 'procedure_args' : {'x' : x, 'y' : y}, - 'select_field' : GeomField(), - } - else: - s = {'procedure_fmt' : '%(geo_col)s,%(x)s,%(y)s,%(z)s', - 'procedure_args' : {'x' : x, 'y' : y, 'z' : z}, - 'select_field' : GeomField(), - } - return self._spatial_attribute('scale', s, **kwargs) - - def snap_to_grid(self, *args, **kwargs): - """ - Snap all points of the input geometry to the grid. How the - geometry is snapped to the grid depends on how many arguments - were given: - - 1 argument : A single size to snap both the X and Y grids to. - - 2 arguments: X and Y sizes to snap the grid to. - - 4 arguments: X, Y sizes and the X, Y origins. - """ - if False in [isinstance(arg, (float, int, long)) for arg in args]: - raise TypeError('Size argument(s) for the grid must be a float or integer values.') - - nargs = len(args) - if nargs == 1: - size = args[0] - procedure_fmt = '%(geo_col)s,%(size)s' - procedure_args = {'size' : size} - elif nargs == 2: - xsize, ysize = args - procedure_fmt = '%(geo_col)s,%(xsize)s,%(ysize)s' - procedure_args = {'xsize' : xsize, 'ysize' : ysize} - elif nargs == 4: - xsize, ysize, xorigin, yorigin = args - procedure_fmt = '%(geo_col)s,%(xorigin)s,%(yorigin)s,%(xsize)s,%(ysize)s' - procedure_args = {'xsize' : xsize, 'ysize' : ysize, - 'xorigin' : xorigin, 'yorigin' : yorigin} - else: - raise ValueError('Must provide 1, 2, or 4 arguments to `snap_to_grid`.') - - s = {'procedure_fmt' : procedure_fmt, - 'procedure_args' : procedure_args, - 'select_field' : GeomField(), - } - - return self._spatial_attribute('snap_to_grid', s, **kwargs) - - def svg(self, relative=False, precision=8, **kwargs): - """ - Returns SVG representation of the geographic field in a `svg` - attribute on each element of this GeoQuerySet. - - Keyword Arguments: - `relative` => If set to True, this will evaluate the path in - terms of relative moves (rather than absolute). - - `precision` => May be used to set the maximum number of decimal - digits used in output (defaults to 8). - """ - relative = int(bool(relative)) - if not isinstance(precision, (int, long)): - raise TypeError('SVG precision keyword argument must be an integer.') - s = {'desc' : 'SVG', - 'procedure_fmt' : '%(geo_col)s,%(rel)s,%(precision)s', - 'procedure_args' : {'rel' : relative, - 'precision' : precision, - } - } - return self._spatial_attribute('svg', s, **kwargs) - - def sym_difference(self, geom, **kwargs): - """ - Returns the symmetric difference of the geographic field in a - `sym_difference` attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('sym_difference', geom, **kwargs) - - def translate(self, x, y, z=0.0, **kwargs): - """ - Translates the geometry to a new location using the given numeric - parameters as offsets. - """ - if connections[self.db].ops.spatialite: - if z != 0.0: - raise NotImplementedError('SpatiaLite does not support 3D translation.') - s = {'procedure_fmt' : '%(geo_col)s,%(x)s,%(y)s', - 'procedure_args' : {'x' : x, 'y' : y}, - 'select_field' : GeomField(), - } - else: - s = {'procedure_fmt' : '%(geo_col)s,%(x)s,%(y)s,%(z)s', - 'procedure_args' : {'x' : x, 'y' : y, 'z' : z}, - 'select_field' : GeomField(), - } - return self._spatial_attribute('translate', s, **kwargs) - - def transform(self, srid=4326, **kwargs): - """ - Transforms the given geometry field to the given SRID. If no SRID is - provided, the transformation will default to using 4326 (WGS84). - """ - if not isinstance(srid, (int, long)): - raise TypeError('An integer SRID must be provided.') - field_name = kwargs.get('field_name', None) - tmp, geo_field = self._spatial_setup('transform', field_name=field_name) - - # Getting the selection SQL for the given geographic field. - field_col = self._geocol_select(geo_field, field_name) - - # Why cascading substitutions? Because spatial backends like - # Oracle and MySQL already require a function call to convert to text, thus - # when there's also a transformation we need to cascade the substitutions. - # For example, 'SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM( ... )' - geo_col = self.query.custom_select.get(geo_field, field_col) - - # Setting the key for the field's column with the custom SELECT SQL to - # override the geometry column returned from the database. - custom_sel = '%s(%s, %s)' % (connections[self.db].ops.transform, geo_col, srid) - # TODO: Should we have this as an alias? - # custom_sel = '(%s(%s, %s)) AS %s' % (SpatialBackend.transform, geo_col, srid, qn(geo_field.name)) - self.query.transformed_srid = srid # So other GeoQuerySet methods - self.query.custom_select[geo_field] = custom_sel - return self._clone() - - def union(self, geom, **kwargs): - """ - Returns the union of the geographic field with the given - Geometry in a `union` attribute on each element of this GeoQuerySet. - """ - return self._geomset_attribute('union', geom, **kwargs) - - def unionagg(self, **kwargs): - """ - Performs an aggregate union on the given geometry field. Returns - None if the GeoQuerySet is empty. The `tolerance` keyword is for - Oracle backends only. - """ - return self._spatial_aggregate(aggregates.Union, **kwargs) - - ### Private API -- Abstracted DRY routines. ### - def _spatial_setup(self, att, desc=None, field_name=None, geo_field_type=None): - """ - Performs set up for executing the spatial function. - """ - # Does the spatial backend support this? - connection = connections[self.db] - func = getattr(connection.ops, att, False) - if desc is None: desc = att - if not func: - raise NotImplementedError('%s stored procedure not available on ' - 'the %s backend.' % - (desc, connection.ops.name)) - - # Initializing the procedure arguments. - procedure_args = {'function' : func} - - # Is there a geographic field in the model to perform this - # operation on? - geo_field = self.query._geo_field(field_name) - if not geo_field: - raise TypeError('%s output only available on GeometryFields.' % func) - - # If the `geo_field_type` keyword was used, then enforce that - # type limitation. - if not geo_field_type is None and not isinstance(geo_field, geo_field_type): - raise TypeError('"%s" stored procedures may only be called on %ss.' % (func, geo_field_type.__name__)) - - # Setting the procedure args. - procedure_args['geo_col'] = self._geocol_select(geo_field, field_name) - - return procedure_args, geo_field - - def _spatial_aggregate(self, aggregate, field_name=None, - geo_field_type=None, tolerance=0.05): - """ - DRY routine for calling aggregate spatial stored procedures and - returning their result to the caller of the function. - """ - # Getting the field the geographic aggregate will be called on. - geo_field = self.query._geo_field(field_name) - if not geo_field: - raise TypeError('%s aggregate only available on GeometryFields.' % aggregate.name) - - # Checking if there are any geo field type limitations on this - # aggregate (e.g. ST_Makeline only operates on PointFields). - if not geo_field_type is None and not isinstance(geo_field, geo_field_type): - raise TypeError('%s aggregate may only be called on %ss.' % (aggregate.name, geo_field_type.__name__)) - - # Getting the string expression of the field name, as this is the - # argument taken by `Aggregate` objects. - agg_col = field_name or geo_field.name - - # Adding any keyword parameters for the Aggregate object. Oracle backends - # in particular need an additional `tolerance` parameter. - agg_kwargs = {} - if connections[self.db].ops.oracle: agg_kwargs['tolerance'] = tolerance - - # Calling the QuerySet.aggregate, and returning only the value of the aggregate. - return self.aggregate(geoagg=aggregate(agg_col, **agg_kwargs))['geoagg'] - - def _spatial_attribute(self, att, settings, field_name=None, model_att=None): - """ - DRY routine for calling a spatial stored procedure on a geometry column - and attaching its output as an attribute of the model. - - Arguments: - att: - The name of the spatial attribute that holds the spatial - SQL function to call. - - settings: - Dictonary of internal settings to customize for the spatial procedure. - - Public Keyword Arguments: - - field_name: - The name of the geographic field to call the spatial - function on. May also be a lookup to a geometry field - as part of a foreign key relation. - - model_att: - The name of the model attribute to attach the output of - the spatial function to. - """ - # Default settings. - settings.setdefault('desc', None) - settings.setdefault('geom_args', ()) - settings.setdefault('geom_field', None) - settings.setdefault('procedure_args', {}) - settings.setdefault('procedure_fmt', '%(geo_col)s') - settings.setdefault('select_params', []) - - connection = connections[self.db] - backend = connection.ops - - # Performing setup for the spatial column, unless told not to. - if settings.get('setup', True): - default_args, geo_field = self._spatial_setup(att, desc=settings['desc'], field_name=field_name, - geo_field_type=settings.get('geo_field_type', None)) - for k, v in default_args.iteritems(): settings['procedure_args'].setdefault(k, v) - else: - geo_field = settings['geo_field'] - - # The attribute to attach to the model. - if not isinstance(model_att, basestring): model_att = att - - # Special handling for any argument that is a geometry. - for name in settings['geom_args']: - # Using the field's get_placeholder() routine to get any needed - # transformation SQL. - geom = geo_field.get_prep_value(settings['procedure_args'][name]) - params = geo_field.get_db_prep_lookup('contains', geom, connection=connection) - geom_placeholder = geo_field.get_placeholder(geom, connection) - - # Replacing the procedure format with that of any needed - # transformation SQL. - old_fmt = '%%(%s)s' % name - new_fmt = geom_placeholder % '%%s' - settings['procedure_fmt'] = settings['procedure_fmt'].replace(old_fmt, new_fmt) - settings['select_params'].extend(params) - - # Getting the format for the stored procedure. - fmt = '%%(function)s(%s)' % settings['procedure_fmt'] - - # If the result of this function needs to be converted. - if settings.get('select_field', False): - sel_fld = settings['select_field'] - if isinstance(sel_fld, GeomField) and backend.select: - self.query.custom_select[model_att] = backend.select - if connection.ops.oracle: - sel_fld.empty_strings_allowed = False - self.query.extra_select_fields[model_att] = sel_fld - - # Finally, setting the extra selection attribute with - # the format string expanded with the stored procedure - # arguments. - return self.extra(select={model_att : fmt % settings['procedure_args']}, - select_params=settings['select_params']) - - def _distance_attribute(self, func, geom=None, tolerance=0.05, spheroid=False, **kwargs): - """ - DRY routine for GeoQuerySet distance attribute routines. - """ - # Setting up the distance procedure arguments. - procedure_args, geo_field = self._spatial_setup(func, field_name=kwargs.get('field_name', None)) - - # If geodetic defaulting distance attribute to meters (Oracle and - # PostGIS spherical distances return meters). Otherwise, use the - # units of the geometry field. - connection = connections[self.db] - geodetic = geo_field.geodetic(connection) - geography = geo_field.geography - - if geodetic: - dist_att = 'm' - else: - dist_att = Distance.unit_attname(geo_field.units_name(connection)) - - # Shortcut booleans for what distance function we're using and - # whether the geometry field is 3D. - distance = func == 'distance' - length = func == 'length' - perimeter = func == 'perimeter' - if not (distance or length or perimeter): - raise ValueError('Unknown distance function: %s' % func) - geom_3d = geo_field.dim == 3 - - # The field's get_db_prep_lookup() is used to get any - # extra distance parameters. Here we set up the - # parameters that will be passed in to field's function. - lookup_params = [geom or 'POINT (0 0)', 0] - - # Getting the spatial backend operations. - backend = connection.ops - - # If the spheroid calculation is desired, either by the `spheroid` - # keyword or when calculating the length of geodetic field, make - # sure the 'spheroid' distance setting string is passed in so we - # get the correct spatial stored procedure. - if spheroid or (backend.postgis and geodetic and - (not geography) and length): - lookup_params.append('spheroid') - lookup_params = geo_field.get_prep_value(lookup_params) - params = geo_field.get_db_prep_lookup('distance_lte', lookup_params, connection=connection) - - # The `geom_args` flag is set to true if a geometry parameter was - # passed in. - geom_args = bool(geom) - - if backend.oracle: - if distance: - procedure_fmt = '%(geo_col)s,%(geom)s,%(tolerance)s' - elif length or perimeter: - procedure_fmt = '%(geo_col)s,%(tolerance)s' - procedure_args['tolerance'] = tolerance - else: - # Getting whether this field is in units of degrees since the field may have - # been transformed via the `transform` GeoQuerySet method. - if self.query.transformed_srid: - u, unit_name, s = get_srid_info(self.query.transformed_srid, connection) - geodetic = unit_name in geo_field.geodetic_units - - if backend.spatialite and geodetic: - raise ValueError('SQLite does not support linear distance calculations on geodetic coordinate systems.') - - if distance: - if self.query.transformed_srid: - # Setting the `geom_args` flag to false because we want to handle - # transformation SQL here, rather than the way done by default - # (which will transform to the original SRID of the field rather - # than to what was transformed to). - geom_args = False - procedure_fmt = '%s(%%(geo_col)s, %s)' % (backend.transform, self.query.transformed_srid) - if geom.srid is None or geom.srid == self.query.transformed_srid: - # If the geom parameter srid is None, it is assumed the coordinates - # are in the transformed units. A placeholder is used for the - # geometry parameter. `GeomFromText` constructor is also needed - # to wrap geom placeholder for SpatiaLite. - if backend.spatialite: - procedure_fmt += ', %s(%%%%s, %s)' % (backend.from_text, self.query.transformed_srid) - else: - procedure_fmt += ', %%s' - else: - # We need to transform the geom to the srid specified in `transform()`, - # so wrapping the geometry placeholder in transformation SQL. - # SpatiaLite also needs geometry placeholder wrapped in `GeomFromText` - # constructor. - if backend.spatialite: - procedure_fmt += ', %s(%s(%%%%s, %s), %s)' % (backend.transform, backend.from_text, - geom.srid, self.query.transformed_srid) - else: - procedure_fmt += ', %s(%%%%s, %s)' % (backend.transform, self.query.transformed_srid) - else: - # `transform()` was not used on this GeoQuerySet. - procedure_fmt = '%(geo_col)s,%(geom)s' - - if not geography and geodetic: - # Spherical distance calculation is needed (because the geographic - # field is geodetic). However, the PostGIS ST_distance_sphere/spheroid() - # procedures may only do queries from point columns to point geometries - # some error checking is required. - if not backend.geography: - if not isinstance(geo_field, PointField): - raise ValueError('Spherical distance calculation only supported on PointFields.') - if not str(Geometry(buffer(params[0].ewkb)).geom_type) == 'Point': - raise ValueError('Spherical distance calculation only supported with Point Geometry parameters') - # The `function` procedure argument needs to be set differently for - # geodetic distance calculations. - if spheroid: - # Call to distance_spheroid() requires spheroid param as well. - procedure_fmt += ",'%(spheroid)s'" - procedure_args.update({'function' : backend.distance_spheroid, 'spheroid' : params[1]}) - else: - procedure_args.update({'function' : backend.distance_sphere}) - elif length or perimeter: - procedure_fmt = '%(geo_col)s' - if not geography and geodetic and length: - # There's no `length_sphere`, and `length_spheroid` also - # works on 3D geometries. - procedure_fmt += ",'%(spheroid)s'" - procedure_args.update({'function' : backend.length_spheroid, 'spheroid' : params[1]}) - elif geom_3d and backend.postgis: - # Use 3D variants of perimeter and length routines on PostGIS. - if perimeter: - procedure_args.update({'function' : backend.perimeter3d}) - elif length: - procedure_args.update({'function' : backend.length3d}) - - # Setting up the settings for `_spatial_attribute`. - s = {'select_field' : DistanceField(dist_att), - 'setup' : False, - 'geo_field' : geo_field, - 'procedure_args' : procedure_args, - 'procedure_fmt' : procedure_fmt, - } - if geom_args: - s['geom_args'] = ('geom',) - s['procedure_args']['geom'] = geom - elif geom: - # The geometry is passed in as a parameter because we handled - # transformation conditions in this routine. - s['select_params'] = [backend.Adapter(geom)] - return self._spatial_attribute(func, s, **kwargs) - - def _geom_attribute(self, func, tolerance=0.05, **kwargs): - """ - DRY routine for setting up a GeoQuerySet method that attaches a - Geometry attribute (e.g., `centroid`, `point_on_surface`). - """ - s = {'select_field' : GeomField(),} - if connections[self.db].ops.oracle: - s['procedure_fmt'] = '%(geo_col)s,%(tolerance)s' - s['procedure_args'] = {'tolerance' : tolerance} - return self._spatial_attribute(func, s, **kwargs) - - def _geomset_attribute(self, func, geom, tolerance=0.05, **kwargs): - """ - DRY routine for setting up a GeoQuerySet method that attaches a - Geometry attribute and takes a Geoemtry parameter. This is used - for geometry set-like operations (e.g., intersection, difference, - union, sym_difference). - """ - s = {'geom_args' : ('geom',), - 'select_field' : GeomField(), - 'procedure_fmt' : '%(geo_col)s,%(geom)s', - 'procedure_args' : {'geom' : geom}, - } - if connections[self.db].ops.oracle: - s['procedure_fmt'] += ',%(tolerance)s' - s['procedure_args']['tolerance'] = tolerance - return self._spatial_attribute(func, s, **kwargs) - - def _geocol_select(self, geo_field, field_name): - """ - Helper routine for constructing the SQL to select the geographic - column. Takes into account if the geographic field is in a - ForeignKey relation to the current model. - """ - opts = self.model._meta - if not geo_field in opts.fields: - # Is this operation going to be on a related geographic field? - # If so, it'll have to be added to the select related information - # (e.g., if 'location__point' was given as the field name). - self.query.add_select_related([field_name]) - compiler = self.query.get_compiler(self.db) - compiler.pre_sql_setup() - rel_table, rel_col = self.query.related_select_cols[self.query.related_select_fields.index(geo_field)] - return compiler._field_column(geo_field, rel_table) - elif not geo_field in opts.local_fields: - # This geographic field is inherited from another model, so we have to - # use the db table for the _parent_ model instead. - tmp_fld, parent_model, direct, m2m = opts.get_field_by_name(geo_field.name) - return self.query.get_compiler(self.db)._field_column(geo_field, parent_model._meta.db_table) - else: - return self.query.get_compiler(self.db)._field_column(geo_field) - -class GeoValuesQuerySet(ValuesQuerySet): - def __init__(self, *args, **kwargs): - super(GeoValuesQuerySet, self).__init__(*args, **kwargs) - # This flag tells `resolve_columns` to run the values through - # `convert_values`. This ensures that Geometry objects instead - # of string values are returned with `values()` or `values_list()`. - self.query.geo_values = True - -class GeoValuesListQuerySet(GeoValuesQuerySet, ValuesListQuerySet): - pass diff --git a/parts/django/django/contrib/gis/db/models/sql/__init__.py b/parts/django/django/contrib/gis/db/models/sql/__init__.py deleted file mode 100644 index 38d9507..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib.gis.db.models.sql.conversion import AreaField, DistanceField, GeomField -from django.contrib.gis.db.models.sql.query import GeoQuery -from django.contrib.gis.db.models.sql.where import GeoWhereNode diff --git a/parts/django/django/contrib/gis/db/models/sql/aggregates.py b/parts/django/django/contrib/gis/db/models/sql/aggregates.py deleted file mode 100644 index fed2a2e..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/aggregates.py +++ /dev/null @@ -1,61 +0,0 @@ -from django.db.models.sql.aggregates import * -from django.contrib.gis.db.models.fields import GeometryField -from django.contrib.gis.db.models.sql.conversion import GeomField - -class GeoAggregate(Aggregate): - # Default SQL template for spatial aggregates. - sql_template = '%(function)s(%(field)s)' - - # Conversion class, if necessary. - conversion_class = None - - # Flags for indicating the type of the aggregate. - is_extent = False - - def __init__(self, col, source=None, is_summary=False, tolerance=0.05, **extra): - super(GeoAggregate, self).__init__(col, source, is_summary, **extra) - - # Required by some Oracle aggregates. - self.tolerance = tolerance - - # Can't use geographic aggregates on non-geometry fields. - if not isinstance(self.source, GeometryField): - raise ValueError('Geospatial aggregates only allowed on geometry fields.') - - def as_sql(self, qn, connection): - "Return the aggregate, rendered as SQL." - - if connection.ops.oracle: - self.extra['tolerance'] = self.tolerance - - if hasattr(self.col, 'as_sql'): - field_name = self.col.as_sql(qn, connection) - elif isinstance(self.col, (list, tuple)): - field_name = '.'.join([qn(c) for c in self.col]) - else: - field_name = self.col - - sql_template, sql_function = connection.ops.spatial_aggregate_sql(self) - - params = { - 'function': sql_function, - 'field': field_name - } - params.update(self.extra) - - return sql_template % params - -class Collect(GeoAggregate): - pass - -class Extent(GeoAggregate): - is_extent = '2D' - -class Extent3D(GeoAggregate): - is_extent = '3D' - -class MakeLine(GeoAggregate): - pass - -class Union(GeoAggregate): - pass diff --git a/parts/django/django/contrib/gis/db/models/sql/compiler.py b/parts/django/django/contrib/gis/db/models/sql/compiler.py deleted file mode 100644 index dea0fd3..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/compiler.py +++ /dev/null @@ -1,278 +0,0 @@ -from itertools import izip -from django.db.backends.util import truncate_name -from django.db.models.sql import compiler -from django.db.models.sql.constants import TABLE_NAME -from django.db.models.sql.query import get_proxied_model - -SQLCompiler = compiler.SQLCompiler - -class GeoSQLCompiler(compiler.SQLCompiler): - - def get_columns(self, with_aliases=False): - """ - Return the list of columns to use in the select statement. If no - columns have been specified, returns all columns relating to fields in - the model. - - If 'with_aliases' is true, any column names that are duplicated - (without the table names) are given unique aliases. This is needed in - some cases to avoid ambiguitity with nested queries. - - This routine is overridden from Query to handle customized selection of - geometry columns. - """ - qn = self.quote_name_unless_alias - qn2 = self.connection.ops.quote_name - result = ['(%s) AS %s' % (self.get_extra_select_format(alias) % col[0], qn2(alias)) - for alias, col in self.query.extra_select.iteritems()] - aliases = set(self.query.extra_select.keys()) - if with_aliases: - col_aliases = aliases.copy() - else: - col_aliases = set() - if self.query.select: - only_load = self.deferred_to_columns() - # This loop customized for GeoQuery. - for col, field in izip(self.query.select, self.query.select_fields): - if isinstance(col, (list, tuple)): - alias, column = col - table = self.query.alias_map[alias][TABLE_NAME] - if table in only_load and col not in only_load[table]: - continue - r = self.get_field_select(field, alias, column) - if with_aliases: - if col[1] in col_aliases: - c_alias = 'Col%d' % len(col_aliases) - result.append('%s AS %s' % (r, c_alias)) - aliases.add(c_alias) - col_aliases.add(c_alias) - else: - result.append('%s AS %s' % (r, qn2(col[1]))) - aliases.add(r) - col_aliases.add(col[1]) - else: - result.append(r) - aliases.add(r) - col_aliases.add(col[1]) - else: - result.append(col.as_sql(qn, self.connection)) - - if hasattr(col, 'alias'): - aliases.add(col.alias) - col_aliases.add(col.alias) - - elif self.query.default_cols: - cols, new_aliases = self.get_default_columns(with_aliases, - col_aliases) - result.extend(cols) - aliases.update(new_aliases) - - max_name_length = self.connection.ops.max_name_length() - result.extend([ - '%s%s' % ( - self.get_extra_select_format(alias) % aggregate.as_sql(qn, self.connection), - alias is not None - and ' AS %s' % qn(truncate_name(alias, max_name_length)) - or '' - ) - for alias, aggregate in self.query.aggregate_select.items() - ]) - - # This loop customized for GeoQuery. - for (table, col), field in izip(self.query.related_select_cols, self.query.related_select_fields): - r = self.get_field_select(field, table, col) - if with_aliases and col in col_aliases: - c_alias = 'Col%d' % len(col_aliases) - result.append('%s AS %s' % (r, c_alias)) - aliases.add(c_alias) - col_aliases.add(c_alias) - else: - result.append(r) - aliases.add(r) - col_aliases.add(col) - - self._select_aliases = aliases - return result - - def get_default_columns(self, with_aliases=False, col_aliases=None, - start_alias=None, opts=None, as_pairs=False, local_only=False): - """ - Computes the default columns for selecting every field in the base - model. Will sometimes be called to pull in related models (e.g. via - select_related), in which case "opts" and "start_alias" will be given - to provide a starting point for the traversal. - - Returns a list of strings, quoted appropriately for use in SQL - directly, as well as a set of aliases used in the select statement (if - 'as_pairs' is True, returns a list of (alias, col_name) pairs instead - of strings as the first component and None as the second component). - - This routine is overridden from Query to handle customized selection of - geometry columns. - """ - result = [] - if opts is None: - opts = self.query.model._meta - aliases = set() - only_load = self.deferred_to_columns() - # Skip all proxy to the root proxied model - proxied_model = get_proxied_model(opts) - - if start_alias: - seen = {None: start_alias} - for field, model in opts.get_fields_with_model(): - if local_only and model is not None: - continue - if start_alias: - try: - alias = seen[model] - except KeyError: - if model is proxied_model: - alias = start_alias - else: - link_field = opts.get_ancestor_link(model) - alias = self.query.join((start_alias, model._meta.db_table, - link_field.column, model._meta.pk.column)) - seen[model] = alias - else: - # If we're starting from the base model of the queryset, the - # aliases will have already been set up in pre_sql_setup(), so - # we can save time here. - alias = self.query.included_inherited_models[model] - table = self.query.alias_map[alias][TABLE_NAME] - if table in only_load and field.column not in only_load[table]: - continue - if as_pairs: - result.append((alias, field.column)) - aliases.add(alias) - continue - # This part of the function is customized for GeoQuery. We - # see if there was any custom selection specified in the - # dictionary, and set up the selection format appropriately. - field_sel = self.get_field_select(field, alias) - if with_aliases and field.column in col_aliases: - c_alias = 'Col%d' % len(col_aliases) - result.append('%s AS %s' % (field_sel, c_alias)) - col_aliases.add(c_alias) - aliases.add(c_alias) - else: - r = field_sel - result.append(r) - aliases.add(r) - if with_aliases: - col_aliases.add(field.column) - return result, aliases - - def resolve_columns(self, row, fields=()): - """ - This routine is necessary so that distances and geometries returned - from extra selection SQL get resolved appropriately into Python - objects. - """ - values = [] - aliases = self.query.extra_select.keys() - if self.query.aggregates: - # If we have an aggregate annotation, must extend the aliases - # so their corresponding row values are included. - aliases.extend([None for i in xrange(len(self.query.aggregates))]) - - # Have to set a starting row number offset that is used for - # determining the correct starting row index -- needed for - # doing pagination with Oracle. - rn_offset = 0 - if self.connection.ops.oracle: - if self.query.high_mark is not None or self.query.low_mark: rn_offset = 1 - index_start = rn_offset + len(aliases) - - # Converting any extra selection values (e.g., geometries and - # distance objects added by GeoQuerySet methods). - values = [self.query.convert_values(v, - self.query.extra_select_fields.get(a, None), - self.connection) - for v, a in izip(row[rn_offset:index_start], aliases)] - if self.connection.ops.oracle or getattr(self.query, 'geo_values', False): - # We resolve the rest of the columns if we're on Oracle or if - # the `geo_values` attribute is defined. - for value, field in map(None, row[index_start:], fields): - values.append(self.query.convert_values(value, field, connection=self.connection)) - else: - values.extend(row[index_start:]) - return tuple(values) - - #### Routines unique to GeoQuery #### - def get_extra_select_format(self, alias): - sel_fmt = '%s' - if alias in self.query.custom_select: - sel_fmt = sel_fmt % self.query.custom_select[alias] - return sel_fmt - - def get_field_select(self, field, alias=None, column=None): - """ - Returns the SELECT SQL string for the given field. Figures out - if any custom selection SQL is needed for the column The `alias` - keyword may be used to manually specify the database table where - the column exists, if not in the model associated with this - `GeoQuery`. Similarly, `column` may be used to specify the exact - column name, rather than using the `column` attribute on `field`. - """ - sel_fmt = self.get_select_format(field) - if field in self.query.custom_select: - field_sel = sel_fmt % self.query.custom_select[field] - else: - field_sel = sel_fmt % self._field_column(field, alias, column) - return field_sel - - def get_select_format(self, fld): - """ - Returns the selection format string, depending on the requirements - of the spatial backend. For example, Oracle and MySQL require custom - selection formats in order to retrieve geometries in OGC WKT. For all - other fields a simple '%s' format string is returned. - """ - if self.connection.ops.select and hasattr(fld, 'geom_type'): - # This allows operations to be done on fields in the SELECT, - # overriding their values -- used by the Oracle and MySQL - # spatial backends to get database values as WKT, and by the - # `transform` method. - sel_fmt = self.connection.ops.select - - # Because WKT doesn't contain spatial reference information, - # the SRID is prefixed to the returned WKT to ensure that the - # transformed geometries have an SRID different than that of the - # field -- this is only used by `transform` for Oracle and - # SpatiaLite backends. - if self.query.transformed_srid and ( self.connection.ops.oracle or - self.connection.ops.spatialite ): - sel_fmt = "'SRID=%d;'||%s" % (self.query.transformed_srid, sel_fmt) - else: - sel_fmt = '%s' - return sel_fmt - - # Private API utilities, subject to change. - def _field_column(self, field, table_alias=None, column=None): - """ - Helper function that returns the database column for the given field. - The table and column are returned (quoted) in the proper format, e.g., - `"geoapp_city"."point"`. If `table_alias` is not specified, the - database table associated with the model of this `GeoQuery` will be - used. If `column` is specified, it will be used instead of the value - in `field.column`. - """ - if table_alias is None: table_alias = self.query.model._meta.db_table - return "%s.%s" % (self.quote_name_unless_alias(table_alias), - self.connection.ops.quote_name(column or field.column)) - -class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler): - pass - -class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler): - pass - -class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler): - pass - -class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler): - pass - -class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler): - pass diff --git a/parts/django/django/contrib/gis/db/models/sql/conversion.py b/parts/django/django/contrib/gis/db/models/sql/conversion.py deleted file mode 100644 index 941c257..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/conversion.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -This module holds simple classes used by GeoQuery.convert_values -to convert geospatial values from the database. -""" - -class BaseField(object): - empty_strings_allowed = True - def get_internal_type(self): - "Overloaded method so OracleQuery.convert_values doesn't balk." - return None - -class AreaField(BaseField): - "Wrapper for Area values." - def __init__(self, area_att): - self.area_att = area_att - -class DistanceField(BaseField): - "Wrapper for Distance values." - def __init__(self, distance_att): - self.distance_att = distance_att - -class GeomField(BaseField): - """ - Wrapper for Geometry values. It is a lightweight alternative to - using GeometryField (which requires a SQL query upon instantiation). - """ - pass diff --git a/parts/django/django/contrib/gis/db/models/sql/query.py b/parts/django/django/contrib/gis/db/models/sql/query.py deleted file mode 100644 index c300dcd..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/query.py +++ /dev/null @@ -1,119 +0,0 @@ -from django.db import connections -from django.db.models.query import sql - -from django.contrib.gis.db.models.fields import GeometryField -from django.contrib.gis.db.models.sql import aggregates as gis_aggregates -from django.contrib.gis.db.models.sql.conversion import AreaField, DistanceField, GeomField -from django.contrib.gis.db.models.sql.where import GeoWhereNode -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.measure import Area, Distance - - -ALL_TERMS = dict([(x, None) for x in ( - 'bbcontains', 'bboverlaps', 'contained', 'contains', - 'contains_properly', 'coveredby', 'covers', 'crosses', 'disjoint', - 'distance_gt', 'distance_gte', 'distance_lt', 'distance_lte', - 'dwithin', 'equals', 'exact', - 'intersects', 'overlaps', 'relate', 'same_as', 'touches', 'within', - 'left', 'right', 'overlaps_left', 'overlaps_right', - 'overlaps_above', 'overlaps_below', - 'strictly_above', 'strictly_below' - )]) -ALL_TERMS.update(sql.constants.QUERY_TERMS) - -class GeoQuery(sql.Query): - """ - A single spatial SQL query. - """ - # Overridding the valid query terms. - query_terms = ALL_TERMS - aggregates_module = gis_aggregates - - compiler = 'GeoSQLCompiler' - - #### Methods overridden from the base Query class #### - def __init__(self, model, where=GeoWhereNode): - super(GeoQuery, self).__init__(model, where) - # The following attributes are customized for the GeoQuerySet. - # The GeoWhereNode and SpatialBackend classes contain backend-specific - # routines and functions. - self.custom_select = {} - self.transformed_srid = None - self.extra_select_fields = {} - - def clone(self, *args, **kwargs): - obj = super(GeoQuery, self).clone(*args, **kwargs) - # Customized selection dictionary and transformed srid flag have - # to also be added to obj. - obj.custom_select = self.custom_select.copy() - obj.transformed_srid = self.transformed_srid - obj.extra_select_fields = self.extra_select_fields.copy() - return obj - - def convert_values(self, value, field, connection): - """ - Using the same routines that Oracle does we can convert our - extra selection objects into Geometry and Distance objects. - TODO: Make converted objects 'lazy' for less overhead. - """ - if connection.ops.oracle: - # Running through Oracle's first. - value = super(GeoQuery, self).convert_values(value, field or GeomField(), connection) - - if value is None: - # Output from spatial function is NULL (e.g., called - # function on a geometry field with NULL value). - pass - elif isinstance(field, DistanceField): - # Using the field's distance attribute, can instantiate - # `Distance` with the right context. - value = Distance(**{field.distance_att : value}) - elif isinstance(field, AreaField): - value = Area(**{field.area_att : value}) - elif isinstance(field, (GeomField, GeometryField)) and value: - value = Geometry(value) - return value - - def get_aggregation(self, using): - # Remove any aggregates marked for reduction from the subquery - # and move them to the outer AggregateQuery. - connection = connections[using] - for alias, aggregate in self.aggregate_select.items(): - if isinstance(aggregate, gis_aggregates.GeoAggregate): - if not getattr(aggregate, 'is_extent', False) or connection.ops.oracle: - self.extra_select_fields[alias] = GeomField() - return super(GeoQuery, self).get_aggregation(using) - - def resolve_aggregate(self, value, aggregate, connection): - """ - Overridden from GeoQuery's normalize to handle the conversion of - GeoAggregate objects. - """ - if isinstance(aggregate, self.aggregates_module.GeoAggregate): - if aggregate.is_extent: - if aggregate.is_extent == '3D': - return connection.ops.convert_extent3d(value) - else: - return connection.ops.convert_extent(value) - else: - return connection.ops.convert_geom(value, aggregate.source) - else: - return super(GeoQuery, self).resolve_aggregate(value, aggregate, connection) - - # Private API utilities, subject to change. - def _geo_field(self, field_name=None): - """ - Returns the first Geometry field encountered; or specified via the - `field_name` keyword. The `field_name` may be a string specifying - the geometry field on this GeoQuery's model, or a lookup string - to a geometry field via a ForeignKey relation. - """ - if field_name is None: - # Incrementing until the first geographic field is found. - for fld in self.model._meta.fields: - if isinstance(fld, GeometryField): return fld - return False - else: - # Otherwise, check by the given field name -- which may be - # a lookup to a _related_ geographic field. - return GeoWhereNode._check_geo_field(self.model._meta, field_name) diff --git a/parts/django/django/contrib/gis/db/models/sql/where.py b/parts/django/django/contrib/gis/db/models/sql/where.py deleted file mode 100644 index 17c210b..0000000 --- a/parts/django/django/contrib/gis/db/models/sql/where.py +++ /dev/null @@ -1,89 +0,0 @@ -from django.db.models.fields import Field, FieldDoesNotExist -from django.db.models.sql.constants import LOOKUP_SEP -from django.db.models.sql.expressions import SQLEvaluator -from django.db.models.sql.where import Constraint, WhereNode -from django.contrib.gis.db.models.fields import GeometryField - -class GeoConstraint(Constraint): - """ - This subclass overrides `process` to better handle geographic SQL - construction. - """ - def __init__(self, init_constraint): - self.alias = init_constraint.alias - self.col = init_constraint.col - self.field = init_constraint.field - - def process(self, lookup_type, value, connection): - if isinstance(value, SQLEvaluator): - # Make sure the F Expression destination field exists, and - # set an `srid` attribute with the same as that of the - # destination. - geo_fld = GeoWhereNode._check_geo_field(value.opts, value.expression.name) - if not geo_fld: - raise ValueError('No geographic field found in expression.') - value.srid = geo_fld.srid - db_type = self.field.db_type(connection=connection) - params = self.field.get_db_prep_lookup(lookup_type, value, connection=connection) - return (self.alias, self.col, db_type), params - -class GeoWhereNode(WhereNode): - """ - Used to represent the SQL where-clause for spatial databases -- - these are tied to the GeoQuery class that created it. - """ - def add(self, data, connector): - if isinstance(data, (list, tuple)): - obj, lookup_type, value = data - if ( isinstance(obj, Constraint) and - isinstance(obj.field, GeometryField) ): - data = (GeoConstraint(obj), lookup_type, value) - super(GeoWhereNode, self).add(data, connector) - - def make_atom(self, child, qn, connection): - lvalue, lookup_type, value_annot, params_or_value = child - if isinstance(lvalue, GeoConstraint): - data, params = lvalue.process(lookup_type, params_or_value, connection) - spatial_sql = connection.ops.spatial_lookup_sql(data, lookup_type, params_or_value, lvalue.field, qn) - return spatial_sql, params - else: - return super(GeoWhereNode, self).make_atom(child, qn, connection) - - @classmethod - def _check_geo_field(cls, opts, lookup): - """ - Utility for checking the given lookup with the given model options. - The lookup is a string either specifying the geographic field, e.g. - 'point, 'the_geom', or a related lookup on a geographic field like - 'address__point'. - - If a GeometryField exists according to the given lookup on the model - options, it will be returned. Otherwise returns None. - """ - # This takes into account the situation where the lookup is a - # lookup to a related geographic field, e.g., 'address__point'. - field_list = lookup.split(LOOKUP_SEP) - - # Reversing so list operates like a queue of related lookups, - # and popping the top lookup. - field_list.reverse() - fld_name = field_list.pop() - - try: - geo_fld = opts.get_field(fld_name) - # If the field list is still around, then it means that the - # lookup was for a geometry field across a relationship -- - # thus we keep on getting the related model options and the - # model field associated with the next field in the list - # until there's no more left. - while len(field_list): - opts = geo_fld.rel.to._meta - geo_fld = opts.get_field(field_list.pop()) - except (FieldDoesNotExist, AttributeError): - return False - - # Finally, make sure we got a Geographic field and return. - if isinstance(geo_fld, GeometryField): - return geo_fld - else: - return False diff --git a/parts/django/django/contrib/gis/feeds.py b/parts/django/django/contrib/gis/feeds.py deleted file mode 100644 index 4105ef7..0000000 --- a/parts/django/django/contrib/gis/feeds.py +++ /dev/null @@ -1,135 +0,0 @@ -from django.contrib.syndication.feeds import Feed as BaseFeed, FeedDoesNotExist -from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed - -class GeoFeedMixin(object): - """ - This mixin provides the necessary routines for SyndicationFeed subclasses - to produce simple GeoRSS or W3C Geo elements. - """ - - def georss_coords(self, coords): - """ - In GeoRSS coordinate pairs are ordered by lat/lon and separated by - a single white space. Given a tuple of coordinates, this will return - a unicode GeoRSS representation. - """ - return u' '.join([u'%f %f' % (coord[1], coord[0]) for coord in coords]) - - def add_georss_point(self, handler, coords, w3c_geo=False): - """ - Adds a GeoRSS point with the given coords using the given handler. - Handles the differences between simple GeoRSS and the more pouplar - W3C Geo specification. - """ - if w3c_geo: - lon, lat = coords[:2] - handler.addQuickElement(u'geo:lat', u'%f' % lat) - handler.addQuickElement(u'geo:lon', u'%f' % lon) - else: - handler.addQuickElement(u'georss:point', self.georss_coords((coords,))) - - def add_georss_element(self, handler, item, w3c_geo=False): - """ - This routine adds a GeoRSS XML element using the given item and handler. - """ - # Getting the Geometry object. - geom = item.get('geometry', None) - if not geom is None: - if isinstance(geom, (list, tuple)): - # Special case if a tuple/list was passed in. The tuple may be - # a point or a box - box_coords = None - if isinstance(geom[0], (list, tuple)): - # Box: ( (X0, Y0), (X1, Y1) ) - if len(geom) == 2: - box_coords = geom - else: - raise ValueError('Only should be two sets of coordinates.') - else: - if len(geom) == 2: - # Point: (X, Y) - self.add_georss_point(handler, geom, w3c_geo=w3c_geo) - elif len(geom) == 4: - # Box: (X0, Y0, X1, Y1) - box_coords = (geom[:2], geom[2:]) - else: - raise ValueError('Only should be 2 or 4 numeric elements.') - # If a GeoRSS box was given via tuple. - if not box_coords is None: - if w3c_geo: raise ValueError('Cannot use simple GeoRSS box in W3C Geo feeds.') - handler.addQuickElement(u'georss:box', self.georss_coords(box_coords)) - else: - # Getting the lower-case geometry type. - gtype = str(geom.geom_type).lower() - if gtype == 'point': - self.add_georss_point(handler, geom.coords, w3c_geo=w3c_geo) - else: - if w3c_geo: raise ValueError('W3C Geo only supports Point geometries.') - # For formatting consistent w/the GeoRSS simple standard: - # http://georss.org/1.0#simple - if gtype in ('linestring', 'linearring'): - handler.addQuickElement(u'georss:line', self.georss_coords(geom.coords)) - elif gtype in ('polygon',): - # Only support the exterior ring. - handler.addQuickElement(u'georss:polygon', self.georss_coords(geom[0].coords)) - else: - raise ValueError('Geometry type "%s" not supported.' % geom.geom_type) - -### SyndicationFeed subclasses ### -class GeoRSSFeed(Rss201rev2Feed, GeoFeedMixin): - def rss_attributes(self): - attrs = super(GeoRSSFeed, self).rss_attributes() - attrs[u'xmlns:georss'] = u'http://www.georss.org/georss' - return attrs - - def add_item_elements(self, handler, item): - super(GeoRSSFeed, self).add_item_elements(handler, item) - self.add_georss_element(handler, item) - - def add_root_elements(self, handler): - super(GeoRSSFeed, self).add_root_elements(handler) - self.add_georss_element(handler, self.feed) - -class GeoAtom1Feed(Atom1Feed, GeoFeedMixin): - def root_attributes(self): - attrs = super(GeoAtom1Feed, self).root_attributes() - attrs[u'xmlns:georss'] = u'http://www.georss.org/georss' - return attrs - - def add_item_elements(self, handler, item): - super(GeoAtom1Feed, self).add_item_elements(handler, item) - self.add_georss_element(handler, item) - - def add_root_elements(self, handler): - super(GeoAtom1Feed, self).add_root_elements(handler) - self.add_georss_element(handler, self.feed) - -class W3CGeoFeed(Rss201rev2Feed, GeoFeedMixin): - def rss_attributes(self): - attrs = super(W3CGeoFeed, self).rss_attributes() - attrs[u'xmlns:geo'] = u'http://www.w3.org/2003/01/geo/wgs84_pos#' - return attrs - - def add_item_elements(self, handler, item): - super(W3CGeoFeed, self).add_item_elements(handler, item) - self.add_georss_element(handler, item, w3c_geo=True) - - def add_root_elements(self, handler): - super(W3CGeoFeed, self).add_root_elements(handler) - self.add_georss_element(handler, self.feed, w3c_geo=True) - -### Feed subclass ### -class Feed(BaseFeed): - """ - This is a subclass of the `Feed` from `django.contrib.syndication`. - This allows users to define a `geometry(obj)` and/or `item_geometry(item)` - methods on their own subclasses so that geo-referenced information may - placed in the feed. - """ - feed_type = GeoRSSFeed - - def feed_extra_kwargs(self, obj): - return {'geometry' : self.__get_dynamic_attr('geometry', obj)} - - def item_extra_kwargs(self, item): - return {'geometry' : self.__get_dynamic_attr('item_geometry', item)} diff --git a/parts/django/django/contrib/gis/forms/__init__.py b/parts/django/django/contrib/gis/forms/__init__.py deleted file mode 100644 index 82971da..0000000 --- a/parts/django/django/contrib/gis/forms/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from django.forms import * -from django.contrib.gis.forms.fields import GeometryField diff --git a/parts/django/django/contrib/gis/forms/fields.py b/parts/django/django/contrib/gis/forms/fields.py deleted file mode 100644 index f806dcb..0000000 --- a/parts/django/django/contrib/gis/forms/fields.py +++ /dev/null @@ -1,67 +0,0 @@ -from django import forms -from django.utils.translation import ugettext_lazy as _ - -# While this couples the geographic forms to the GEOS library, -# it decouples from database (by not importing SpatialBackend). -from django.contrib.gis.geos import GEOSGeometry - -class GeometryField(forms.Field): - """ - This is the basic form field for a Geometry. Any textual input that is - accepted by GEOSGeometry is accepted by this form. By default, - this includes WKT, HEXEWKB, WKB (in a buffer), and GeoJSON. - """ - widget = forms.Textarea - - default_error_messages = { - 'no_geom' : _(u'No geometry value provided.'), - 'invalid_geom' : _(u'Invalid geometry value.'), - 'invalid_geom_type' : _(u'Invalid geometry type.'), - 'transform_error' : _(u'An error occurred when transforming the geometry ' - 'to the SRID of the geometry form field.'), - } - - def __init__(self, **kwargs): - # Pop out attributes from the database field, or use sensible - # defaults (e.g., allow None). - self.srid = kwargs.pop('srid', None) - self.geom_type = kwargs.pop('geom_type', 'GEOMETRY') - self.null = kwargs.pop('null', True) - super(GeometryField, self).__init__(**kwargs) - - def clean(self, value): - """ - Validates that the input value can be converted to a Geometry - object (which is returned). A ValidationError is raised if - the value cannot be instantiated as a Geometry. - """ - if not value: - if self.null and not self.required: - # The geometry column allows NULL and is not required. - return None - else: - raise forms.ValidationError(self.error_messages['no_geom']) - - # Trying to create a Geometry object from the form value. - try: - geom = GEOSGeometry(value) - except: - raise forms.ValidationError(self.error_messages['invalid_geom']) - - # Ensuring that the geometry is of the correct type (indicated - # using the OGC string label). - if str(geom.geom_type).upper() != self.geom_type and not self.geom_type == 'GEOMETRY': - raise forms.ValidationError(self.error_messages['invalid_geom_type']) - - # Transforming the geometry if the SRID was set. - if self.srid: - if not geom.srid: - # Should match that of the field if not given. - geom.srid = self.srid - elif self.srid != -1 and self.srid != geom.srid: - try: - geom.transform(self.srid) - except: - raise forms.ValidationError(self.error_messages['transform_error']) - - return geom diff --git a/parts/django/django/contrib/gis/gdal/LICENSE b/parts/django/django/contrib/gis/gdal/LICENSE deleted file mode 100644 index 30d410e..0000000 --- a/parts/django/django/contrib/gis/gdal/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2007-2009, Justin Bronn -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of OGRGeometry nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/parts/django/django/contrib/gis/gdal/__init__.py b/parts/django/django/contrib/gis/gdal/__init__.py deleted file mode 100644 index cc47ae9..0000000 --- a/parts/django/django/contrib/gis/gdal/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -""" - This module houses ctypes interfaces for GDAL objects. The following GDAL - objects are supported: - - CoordTransform: Used for coordinate transformations from one spatial - reference system to another. - - Driver: Wraps an OGR data source driver. - - DataSource: Wrapper for the OGR data source object, supports - OGR-supported data sources. - - Envelope: A ctypes structure for bounding boxes (GDAL library - not required). - - OGRGeometry: Object for accessing OGR Geometry functionality. - - OGRGeomType: A class for representing the different OGR Geometry - types (GDAL library not required). - - SpatialReference: Represents OSR Spatial Reference objects. - - The GDAL library will be imported from the system path using the default - library name for the current OS. The default library path may be overridden - by setting `GDAL_LIBRARY_PATH` in your settings with the path to the GDAL C - library on your system. - - GDAL links to a large number of external libraries that consume RAM when - loaded. Thus, it may desirable to disable GDAL on systems with limited - RAM resources -- this may be accomplished by setting `GDAL_LIBRARY_PATH` - to a non-existant file location (e.g., `GDAL_LIBRARY_PATH='/null/path'`; - setting to None/False/'' will not work as a string must be given). -""" -# Attempting to import objects that depend on the GDAL library. The -# HAS_GDAL flag will be set to True if the library is present on -# the system. -try: - from django.contrib.gis.gdal.driver import Driver - from django.contrib.gis.gdal.datasource import DataSource - from django.contrib.gis.gdal.libgdal import gdal_version, gdal_full_version, gdal_release_date, GEOJSON, GDAL_VERSION - from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform - from django.contrib.gis.gdal.geometries import OGRGeometry - HAS_GDAL = True -except: - HAS_GDAL, GEOJSON = False, False - -try: - from django.contrib.gis.gdal.envelope import Envelope -except ImportError: - # No ctypes, but don't raise an exception. - pass - -from django.contrib.gis.gdal.error import check_err, OGRException, OGRIndexError, SRSException -from django.contrib.gis.gdal.geomtype import OGRGeomType diff --git a/parts/django/django/contrib/gis/gdal/base.py b/parts/django/django/contrib/gis/gdal/base.py deleted file mode 100644 index f9455c7..0000000 --- a/parts/django/django/contrib/gis/gdal/base.py +++ /dev/null @@ -1,35 +0,0 @@ -from ctypes import c_void_p -from types import NoneType -from django.contrib.gis.gdal.error import GDALException - -class GDALBase(object): - """ - Base object for GDAL objects that has a pointer access property - that controls access to the underlying C pointer. - """ - # Initially the pointer is NULL. - _ptr = None - - # Default allowed pointer type. - ptr_type = c_void_p - - # Pointer access property. - def _get_ptr(self): - # Raise an exception if the pointer isn't valid don't - # want to be passing NULL pointers to routines -- - # that's very bad. - if self._ptr: return self._ptr - else: raise GDALException('GDAL %s pointer no longer valid.' % self.__class__.__name__) - - def _set_ptr(self, ptr): - # Only allow the pointer to be set with pointers of the - # compatible type or None (NULL). - if isinstance(ptr, (int, long)): - self._ptr = self.ptr_type(ptr) - elif isinstance(ptr, (self.ptr_type, NoneType)): - self._ptr = ptr - else: - raise TypeError('Incompatible pointer type') - - ptr = property(_get_ptr, _set_ptr) - diff --git a/parts/django/django/contrib/gis/gdal/datasource.py b/parts/django/django/contrib/gis/gdal/datasource.py deleted file mode 100644 index 7db5fd9..0000000 --- a/parts/django/django/contrib/gis/gdal/datasource.py +++ /dev/null @@ -1,128 +0,0 @@ -""" - DataSource is a wrapper for the OGR Data Source object, which provides - an interface for reading vector geometry data from many different file - formats (including ESRI shapefiles). - - When instantiating a DataSource object, use the filename of a - GDAL-supported data source. For example, a SHP file or a - TIGER/Line file from the government. - - The ds_driver keyword is used internally when a ctypes pointer - is passed in directly. - - Example: - ds = DataSource('/home/foo/bar.shp') - for layer in ds: - for feature in layer: - # Getting the geometry for the feature. - g = feature.geom - - # Getting the 'description' field for the feature. - desc = feature['description'] - - # We can also increment through all of the fields - # attached to this feature. - for field in feature: - # Get the name of the field (e.g. 'description') - nm = field.name - - # Get the type (integer) of the field, e.g. 0 => OFTInteger - t = field.type - - # Returns the value the field; OFTIntegers return ints, - # OFTReal returns floats, all else returns string. - val = field.value -""" -# ctypes prerequisites. -from ctypes import byref, c_void_p - -# The GDAL C library, OGR exceptions, and the Layer object. -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.driver import Driver -from django.contrib.gis.gdal.error import OGRException, OGRIndexError -from django.contrib.gis.gdal.layer import Layer - -# Getting the ctypes prototypes for the DataSource. -from django.contrib.gis.gdal.prototypes import ds as capi - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_DS_* routines are relevant here. -class DataSource(GDALBase): - "Wraps an OGR Data Source object." - - #### Python 'magic' routines #### - def __init__(self, ds_input, ds_driver=False, write=False): - # The write flag. - if write: - self._write = 1 - else: - self._write = 0 - - # Registering all the drivers, this needs to be done - # _before_ we try to open up a data source. - if not capi.get_driver_count(): - capi.register_all() - - if isinstance(ds_input, basestring): - # The data source driver is a void pointer. - ds_driver = Driver.ptr_type() - try: - # OGROpen will auto-detect the data source type. - ds = capi.open_ds(ds_input, self._write, byref(ds_driver)) - except OGRException: - # Making the error message more clear rather than something - # like "Invalid pointer returned from OGROpen". - raise OGRException('Could not open the datasource at "%s"' % ds_input) - elif isinstance(ds_input, self.ptr_type) and isinstance(ds_driver, Driver.ptr_type): - ds = ds_input - else: - raise OGRException('Invalid data source input type: %s' % type(ds_input)) - - if bool(ds): - self.ptr = ds - self.driver = Driver(ds_driver) - else: - # Raise an exception if the returned pointer is NULL - raise OGRException('Invalid data source file "%s"' % ds_input) - - def __del__(self): - "Destroys this DataStructure object." - if self._ptr: capi.destroy_ds(self._ptr) - - def __iter__(self): - "Allows for iteration over the layers in a data source." - for i in xrange(self.layer_count): - yield self[i] - - def __getitem__(self, index): - "Allows use of the index [] operator to get a layer at the index." - if isinstance(index, basestring): - l = capi.get_layer_by_name(self.ptr, index) - if not l: raise OGRIndexError('invalid OGR Layer name given: "%s"' % index) - elif isinstance(index, int): - if index < 0 or index >= self.layer_count: - raise OGRIndexError('index out of range') - l = capi.get_layer(self._ptr, index) - else: - raise TypeError('Invalid index type: %s' % type(index)) - return Layer(l, self) - - def __len__(self): - "Returns the number of layers within the data source." - return self.layer_count - - def __str__(self): - "Returns OGR GetName and Driver for the Data Source." - return '%s (%s)' % (self.name, str(self.driver)) - - @property - def layer_count(self): - "Returns the number of layers in the data source." - return capi.get_layer_count(self._ptr) - - @property - def name(self): - "Returns the name of the data source." - return capi.get_ds_name(self._ptr) diff --git a/parts/django/django/contrib/gis/gdal/driver.py b/parts/django/django/contrib/gis/gdal/driver.py deleted file mode 100644 index 1753db2..0000000 --- a/parts/django/django/contrib/gis/gdal/driver.py +++ /dev/null @@ -1,65 +0,0 @@ -# prerequisites imports -from ctypes import c_void_p -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.error import OGRException -from django.contrib.gis.gdal.prototypes import ds as capi - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_Dr_* routines are relevant here. -class Driver(GDALBase): - "Wraps an OGR Data Source Driver." - - # Case-insensitive aliases for OGR Drivers. - _alias = {'esri' : 'ESRI Shapefile', - 'shp' : 'ESRI Shapefile', - 'shape' : 'ESRI Shapefile', - 'tiger' : 'TIGER', - 'tiger/line' : 'TIGER', - } - - def __init__(self, dr_input): - "Initializes an OGR driver on either a string or integer input." - - if isinstance(dr_input, basestring): - # If a string name of the driver was passed in - self._register() - - # Checking the alias dictionary (case-insensitive) to see if an alias - # exists for the given driver. - if dr_input.lower() in self._alias: - name = self._alias[dr_input.lower()] - else: - name = dr_input - - # Attempting to get the OGR driver by the string name. - dr = capi.get_driver_by_name(name) - elif isinstance(dr_input, int): - self._register() - dr = capi.get_driver(dr_input) - elif isinstance(dr_input, c_void_p): - dr = dr_input - else: - raise OGRException('Unrecognized input type for OGR Driver: %s' % str(type(dr_input))) - - # Making sure we get a valid pointer to the OGR Driver - if not dr: - raise OGRException('Could not initialize OGR Driver on input: %s' % str(dr_input)) - self.ptr = dr - - def __str__(self): - "Returns the string name of the OGR Driver." - return capi.get_driver_name(self.ptr) - - def _register(self): - "Attempts to register all the data source drivers." - # Only register all if the driver count is 0 (or else all drivers - # will be registered over and over again) - if not self.driver_count: capi.register_all() - - # Driver properties - @property - def driver_count(self): - "Returns the number of OGR data source drivers registered." - return capi.get_driver_count() diff --git a/parts/django/django/contrib/gis/gdal/envelope.py b/parts/django/django/contrib/gis/gdal/envelope.py deleted file mode 100644 index 0e6aa0e..0000000 --- a/parts/django/django/contrib/gis/gdal/envelope.py +++ /dev/null @@ -1,175 +0,0 @@ -""" - The GDAL/OGR library uses an Envelope structure to hold the bounding - box information for a geometry. The envelope (bounding box) contains - two pairs of coordinates, one for the lower left coordinate and one - for the upper right coordinate: - - +----------o Upper right; (max_x, max_y) - | | - | | - | | - Lower left (min_x, min_y) o----------+ -""" -from ctypes import Structure, c_double -from django.contrib.gis.gdal.error import OGRException - -# The OGR definition of an Envelope is a C structure containing four doubles. -# See the 'ogr_core.h' source file for more information: -# http://www.gdal.org/ogr/ogr__core_8h-source.html -class OGREnvelope(Structure): - "Represents the OGREnvelope C Structure." - _fields_ = [("MinX", c_double), - ("MaxX", c_double), - ("MinY", c_double), - ("MaxY", c_double), - ] - -class Envelope(object): - """ - The Envelope object is a C structure that contains the minimum and - maximum X, Y coordinates for a rectangle bounding box. The naming - of the variables is compatible with the OGR Envelope structure. - """ - - def __init__(self, *args): - """ - The initialization function may take an OGREnvelope structure, 4-element - tuple or list, or 4 individual arguments. - """ - - if len(args) == 1: - if isinstance(args[0], OGREnvelope): - # OGREnvelope (a ctypes Structure) was passed in. - self._envelope = args[0] - elif isinstance(args[0], (tuple, list)): - # A tuple was passed in. - if len(args[0]) != 4: - raise OGRException('Incorrect number of tuple elements (%d).' % len(args[0])) - else: - self._from_sequence(args[0]) - else: - raise TypeError('Incorrect type of argument: %s' % str(type(args[0]))) - elif len(args) == 4: - # Individiual parameters passed in. - # Thanks to ww for the help - self._from_sequence(map(float, args)) - else: - raise OGRException('Incorrect number (%d) of arguments.' % len(args)) - - # Checking the x,y coordinates - if self.min_x > self.max_x: - raise OGRException('Envelope minimum X > maximum X.') - if self.min_y > self.max_y: - raise OGRException('Envelope minimum Y > maximum Y.') - - def __eq__(self, other): - """ - Returns True if the envelopes are equivalent; can compare against - other Envelopes and 4-tuples. - """ - if isinstance(other, Envelope): - return (self.min_x == other.min_x) and (self.min_y == other.min_y) and \ - (self.max_x == other.max_x) and (self.max_y == other.max_y) - elif isinstance(other, tuple) and len(other) == 4: - return (self.min_x == other[0]) and (self.min_y == other[1]) and \ - (self.max_x == other[2]) and (self.max_y == other[3]) - else: - raise OGRException('Equivalence testing only works with other Envelopes.') - - def __str__(self): - "Returns a string representation of the tuple." - return str(self.tuple) - - def _from_sequence(self, seq): - "Initializes the C OGR Envelope structure from the given sequence." - self._envelope = OGREnvelope() - self._envelope.MinX = seq[0] - self._envelope.MinY = seq[1] - self._envelope.MaxX = seq[2] - self._envelope.MaxY = seq[3] - - def expand_to_include(self, *args): - """ - Modifies the envelope to expand to include the boundaries of - the passed-in 2-tuple (a point), 4-tuple (an extent) or - envelope. - """ - # We provide a number of different signatures for this method, - # and the logic here is all about converting them into a - # 4-tuple single parameter which does the actual work of - # expanding the envelope. - if len(args) == 1: - if isinstance(args[0], Envelope): - return self.expand_to_include(args[0].tuple) - elif hasattr(args[0], 'x') and hasattr(args[0], 'y'): - return self.expand_to_include(args[0].x, args[0].y, args[0].x, args[0].y) - elif isinstance(args[0], (tuple, list)): - # A tuple was passed in. - if len(args[0]) == 2: - return self.expand_to_include((args[0][0], args[0][1], args[0][0], args[0][1])) - elif len(args[0]) == 4: - (minx, miny, maxx, maxy) = args[0] - if minx < self._envelope.MinX: - self._envelope.MinX = minx - if miny < self._envelope.MinY: - self._envelope.MinY = miny - if maxx > self._envelope.MaxX: - self._envelope.MaxX = maxx - if maxy > self._envelope.MaxY: - self._envelope.MaxY = maxy - else: - raise OGRException('Incorrect number of tuple elements (%d).' % len(args[0])) - else: - raise TypeError('Incorrect type of argument: %s' % str(type(args[0]))) - elif len(args) == 2: - # An x and an y parameter were passed in - return self.expand_to_include((args[0], args[1], args[0], args[1])) - elif len(args) == 4: - # Individiual parameters passed in. - return self.expand_to_include(args) - else: - raise OGRException('Incorrect number (%d) of arguments.' % len(args[0])) - - @property - def min_x(self): - "Returns the value of the minimum X coordinate." - return self._envelope.MinX - - @property - def min_y(self): - "Returns the value of the minimum Y coordinate." - return self._envelope.MinY - - @property - def max_x(self): - "Returns the value of the maximum X coordinate." - return self._envelope.MaxX - - @property - def max_y(self): - "Returns the value of the maximum Y coordinate." - return self._envelope.MaxY - - @property - def ur(self): - "Returns the upper-right coordinate." - return (self.max_x, self.max_y) - - @property - def ll(self): - "Returns the lower-left coordinate." - return (self.min_x, self.min_y) - - @property - def tuple(self): - "Returns a tuple representing the envelope." - return (self.min_x, self.min_y, self.max_x, self.max_y) - - @property - def wkt(self): - "Returns WKT representing a Polygon for this envelope." - # TODO: Fix significant figures. - return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % \ - (self.min_x, self.min_y, self.min_x, self.max_y, - self.max_x, self.max_y, self.max_x, self.min_y, - self.min_x, self.min_y) diff --git a/parts/django/django/contrib/gis/gdal/error.py b/parts/django/django/contrib/gis/gdal/error.py deleted file mode 100644 index 58ca891..0000000 --- a/parts/django/django/contrib/gis/gdal/error.py +++ /dev/null @@ -1,42 +0,0 @@ -""" - This module houses the OGR & SRS Exception objects, and the - check_err() routine which checks the status code returned by - OGR methods. -""" -#### OGR & SRS Exceptions #### -class GDALException(Exception): pass -class OGRException(Exception): pass -class SRSException(Exception): pass -class OGRIndexError(OGRException, KeyError): - """ - This exception is raised when an invalid index is encountered, and has - the 'silent_variable_feature' attribute set to true. This ensures that - django's templates proceed to use the next lookup type gracefully when - an Exception is raised. Fixes ticket #4740. - """ - silent_variable_failure = True - -#### OGR error checking codes and routine #### - -# OGR Error Codes -OGRERR_DICT = { 1 : (OGRException, 'Not enough data.'), - 2 : (OGRException, 'Not enough memory.'), - 3 : (OGRException, 'Unsupported geometry type.'), - 4 : (OGRException, 'Unsupported operation.'), - 5 : (OGRException, 'Corrupt data.'), - 6 : (OGRException, 'OGR failure.'), - 7 : (SRSException, 'Unsupported SRS.'), - 8 : (OGRException, 'Invalid handle.'), - } -OGRERR_NONE = 0 - -def check_err(code): - "Checks the given OGRERR, and raises an exception where appropriate." - - if code == OGRERR_NONE: - return - elif code in OGRERR_DICT: - e, msg = OGRERR_DICT[code] - raise e, msg - else: - raise OGRException('Unknown error code: "%s"' % code) diff --git a/parts/django/django/contrib/gis/gdal/feature.py b/parts/django/django/contrib/gis/gdal/feature.py deleted file mode 100644 index b5c173a..0000000 --- a/parts/django/django/contrib/gis/gdal/feature.py +++ /dev/null @@ -1,110 +0,0 @@ -# The GDAL C library, OGR exception, and the Field object -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.error import OGRException, OGRIndexError -from django.contrib.gis.gdal.field import Field -from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType -from django.contrib.gis.gdal.srs import SpatialReference - -# ctypes function prototypes -from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_F_* routines are relevant here. -class Feature(GDALBase): - "A class that wraps an OGR Feature, needs to be instantiated from a Layer object." - - #### Python 'magic' routines #### - def __init__(self, feat, fdefn): - "Initializes on the pointers for the feature and the layer definition." - if not feat or not fdefn: - raise OGRException('Cannot create OGR Feature, invalid pointer given.') - self.ptr = feat - self._fdefn = fdefn - - def __del__(self): - "Releases a reference to this object." - if self._ptr: capi.destroy_feature(self._ptr) - - def __getitem__(self, index): - """ - Gets the Field object at the specified index, which may be either - an integer or the Field's string label. Note that the Field object - is not the field's _value_ -- use the `get` method instead to - retrieve the value (e.g. an integer) instead of a Field instance. - """ - if isinstance(index, basestring): - i = self.index(index) - else: - if index < 0 or index > self.num_fields: - raise OGRIndexError('index out of range') - i = index - return Field(self.ptr, i) - - def __iter__(self): - "Iterates over each field in the Feature." - for i in xrange(self.num_fields): - yield self[i] - - def __len__(self): - "Returns the count of fields in this feature." - return self.num_fields - - def __str__(self): - "The string name of the feature." - return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name) - - def __eq__(self, other): - "Does equivalence testing on the features." - return bool(capi.feature_equal(self.ptr, other._ptr)) - - #### Feature Properties #### - @property - def fid(self): - "Returns the feature identifier." - return capi.get_fid(self.ptr) - - @property - def layer_name(self): - "Returns the name of the layer for the feature." - return capi.get_feat_name(self._fdefn) - - @property - def num_fields(self): - "Returns the number of fields in the Feature." - return capi.get_feat_field_count(self.ptr) - - @property - def fields(self): - "Returns a list of fields in the Feature." - return [capi.get_field_name(capi.get_field_defn(self._fdefn, i)) - for i in xrange(self.num_fields)] - - @property - def geom(self): - "Returns the OGR Geometry for this Feature." - # Retrieving the geometry pointer for the feature. - geom_ptr = capi.get_feat_geom_ref(self.ptr) - return OGRGeometry(geom_api.clone_geom(geom_ptr)) - - @property - def geom_type(self): - "Returns the OGR Geometry Type for this Feture." - return OGRGeomType(capi.get_fd_geom_type(self._fdefn)) - - #### Feature Methods #### - def get(self, field): - """ - Returns the value of the field, instead of an instance of the Field - object. May take a string of the field name or a Field object as - parameters. - """ - field_name = getattr(field, 'name', field) - return self[field_name].value - - def index(self, field_name): - "Returns the index of the given field name." - i = capi.get_field_index(self.ptr, field_name) - if i < 0: raise OGRIndexError('invalid OFT field name given: "%s"' % field_name) - return i diff --git a/parts/django/django/contrib/gis/gdal/field.py b/parts/django/django/contrib/gis/gdal/field.py deleted file mode 100644 index 46dbc86..0000000 --- a/parts/django/django/contrib/gis/gdal/field.py +++ /dev/null @@ -1,178 +0,0 @@ -from ctypes import byref, c_int -from datetime import date, datetime, time -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.error import OGRException -from django.contrib.gis.gdal.prototypes import ds as capi - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_Fld_* routines are relevant here. -class Field(GDALBase): - "A class that wraps an OGR Field, needs to be instantiated from a Feature object." - - #### Python 'magic' routines #### - def __init__(self, feat, index): - """ - Initializes on the feature pointer and the integer index of - the field within the feature. - """ - # Setting the feature pointer and index. - self._feat = feat - self._index = index - - # Getting the pointer for this field. - fld_ptr = capi.get_feat_field_defn(feat, index) - if not fld_ptr: - raise OGRException('Cannot create OGR Field, invalid pointer given.') - self.ptr = fld_ptr - - # Setting the class depending upon the OGR Field Type (OFT) - self.__class__ = OGRFieldTypes[self.type] - - # OFTReal with no precision should be an OFTInteger. - if isinstance(self, OFTReal) and self.precision == 0: - self.__class__ = OFTInteger - - def __str__(self): - "Returns the string representation of the Field." - return str(self.value).strip() - - #### Field Methods #### - def as_double(self): - "Retrieves the Field's value as a double (float)." - return capi.get_field_as_double(self._feat, self._index) - - def as_int(self): - "Retrieves the Field's value as an integer." - return capi.get_field_as_integer(self._feat, self._index) - - def as_string(self): - "Retrieves the Field's value as a string." - return capi.get_field_as_string(self._feat, self._index) - - def as_datetime(self): - "Retrieves the Field's value as a tuple of date & time components." - yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)] - status = capi.get_field_as_datetime(self._feat, self._index, byref(yy), byref(mm), byref(dd), - byref(hh), byref(mn), byref(ss), byref(tz)) - if status: - return (yy, mm, dd, hh, mn, ss, tz) - else: - raise OGRException('Unable to retrieve date & time information from the field.') - - #### Field Properties #### - @property - def name(self): - "Returns the name of this Field." - return capi.get_field_name(self.ptr) - - @property - def precision(self): - "Returns the precision of this Field." - return capi.get_field_precision(self.ptr) - - @property - def type(self): - "Returns the OGR type of this Field." - return capi.get_field_type(self.ptr) - - @property - def type_name(self): - "Return the OGR field type name for this Field." - return capi.get_field_type_name(self.type) - - @property - def value(self): - "Returns the value of this Field." - # Default is to get the field as a string. - return self.as_string() - - @property - def width(self): - "Returns the width of this Field." - return capi.get_field_width(self.ptr) - -### The Field sub-classes for each OGR Field type. ### -class OFTInteger(Field): - @property - def value(self): - "Returns an integer contained in this field." - return self.as_int() - - @property - def type(self): - """ - GDAL uses OFTReals to represent OFTIntegers in created - shapefiles -- forcing the type here since the underlying field - type may actually be OFTReal. - """ - return 0 - -class OFTReal(Field): - @property - def value(self): - "Returns a float contained in this field." - return self.as_double() - -# String & Binary fields, just subclasses -class OFTString(Field): pass -class OFTWideString(Field): pass -class OFTBinary(Field): pass - -# OFTDate, OFTTime, OFTDateTime fields. -class OFTDate(Field): - @property - def value(self): - "Returns a Python `date` object for the OFTDate field." - try: - yy, mm, dd, hh, mn, ss, tz = self.as_datetime() - return date(yy.value, mm.value, dd.value) - except (ValueError, OGRException): - return None - -class OFTDateTime(Field): - @property - def value(self): - "Returns a Python `datetime` object for this OFTDateTime field." - # TODO: Adapt timezone information. - # See http://lists.maptools.org/pipermail/gdal-dev/2006-February/007990.html - # The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous), - # 100=GMT, 104=GMT+1, 80=GMT-5, etc. - try: - yy, mm, dd, hh, mn, ss, tz = self.as_datetime() - return datetime(yy.value, mm.value, dd.value, hh.value, mn.value, ss.value) - except (ValueError, OGRException): - return None - -class OFTTime(Field): - @property - def value(self): - "Returns a Python `time` object for this OFTTime field." - try: - yy, mm, dd, hh, mn, ss, tz = self.as_datetime() - return time(hh.value, mn.value, ss.value) - except (ValueError, OGRException): - return None - -# List fields are also just subclasses -class OFTIntegerList(Field): pass -class OFTRealList(Field): pass -class OFTStringList(Field): pass -class OFTWideStringList(Field): pass - -# Class mapping dictionary for OFT Types and reverse mapping. -OGRFieldTypes = { 0 : OFTInteger, - 1 : OFTIntegerList, - 2 : OFTReal, - 3 : OFTRealList, - 4 : OFTString, - 5 : OFTStringList, - 6 : OFTWideString, - 7 : OFTWideStringList, - 8 : OFTBinary, - 9 : OFTDate, - 10 : OFTTime, - 11 : OFTDateTime, - } -ROGRFieldTypes = dict([(cls, num) for num, cls in OGRFieldTypes.items()]) diff --git a/parts/django/django/contrib/gis/gdal/geometries.py b/parts/django/django/contrib/gis/gdal/geometries.py deleted file mode 100644 index 30125d5..0000000 --- a/parts/django/django/contrib/gis/gdal/geometries.py +++ /dev/null @@ -1,737 +0,0 @@ -""" - The OGRGeometry is a wrapper for using the OGR Geometry class - (see http://www.gdal.org/ogr/classOGRGeometry.html). OGRGeometry - may be instantiated when reading geometries from OGR Data Sources - (e.g. SHP files), or when given OGC WKT (a string). - - While the 'full' API is not present yet, the API is "pythonic" unlike - the traditional and "next-generation" OGR Python bindings. One major - advantage OGR Geometries have over their GEOS counterparts is support - for spatial reference systems and their transformation. - - Example: - >>> from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, SpatialReference - >>> wkt1, wkt2 = 'POINT(-90 30)', 'POLYGON((0 0, 5 0, 5 5, 0 5)' - >>> pnt = OGRGeometry(wkt1) - >>> print pnt - POINT (-90 30) - >>> mpnt = OGRGeometry(OGRGeomType('MultiPoint'), SpatialReference('WGS84')) - >>> mpnt.add(wkt1) - >>> mpnt.add(wkt1) - >>> print mpnt - MULTIPOINT (-90 30,-90 30) - >>> print mpnt.srs.name - WGS 84 - >>> print mpnt.srs.proj - +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs - >>> mpnt.transform_to(SpatialReference('NAD27')) - >>> print mpnt.proj - +proj=longlat +ellps=clrk66 +datum=NAD27 +no_defs - >>> print mpnt - MULTIPOINT (-89.999930378602485 29.999797886557641,-89.999930378602485 29.999797886557641) - - The OGRGeomType class is to make it easy to specify an OGR geometry type: - >>> from django.contrib.gis.gdal import OGRGeomType - >>> gt1 = OGRGeomType(3) # Using an integer for the type - >>> gt2 = OGRGeomType('Polygon') # Using a string - >>> gt3 = OGRGeomType('POLYGON') # It's case-insensitive - >>> print gt1 == 3, gt1 == 'Polygon' # Equivalence works w/non-OGRGeomType objects - True -""" -# Python library requisites. -import sys -from binascii import a2b_hex -from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p - -# Getting GDAL prerequisites -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope -from django.contrib.gis.gdal.error import OGRException, OGRIndexError, SRSException -from django.contrib.gis.gdal.geomtype import OGRGeomType -from django.contrib.gis.gdal.libgdal import GEOJSON, GDAL_VERSION -from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform - -# Getting the ctypes prototype functions that interface w/the GDAL C library. -from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api - -# For recognizing geometry input. -from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_G_* routines are relevant here. - -#### OGRGeometry Class #### -class OGRGeometry(GDALBase): - "Generally encapsulates an OGR geometry." - - def __init__(self, geom_input, srs=None): - "Initializes Geometry on either WKT or an OGR pointer as input." - - str_instance = isinstance(geom_input, basestring) - - # If HEX, unpack input to to a binary buffer. - if str_instance and hex_regex.match(geom_input): - geom_input = buffer(a2b_hex(geom_input.upper())) - str_instance = False - - # Constructing the geometry, - if str_instance: - # Checking if unicode - if isinstance(geom_input, unicode): - # Encoding to ASCII, WKT or HEX doesn't need any more. - geom_input = geom_input.encode('ascii') - - wkt_m = wkt_regex.match(geom_input) - json_m = json_regex.match(geom_input) - if wkt_m: - if wkt_m.group('srid'): - # If there's EWKT, set the SRS w/value of the SRID. - srs = int(wkt_m.group('srid')) - if wkt_m.group('type').upper() == 'LINEARRING': - # OGR_G_CreateFromWkt doesn't work with LINEARRING WKT. - # See http://trac.osgeo.org/gdal/ticket/1992. - g = capi.create_geom(OGRGeomType(wkt_m.group('type')).num) - capi.import_wkt(g, byref(c_char_p(wkt_m.group('wkt')))) - else: - g = capi.from_wkt(byref(c_char_p(wkt_m.group('wkt'))), None, byref(c_void_p())) - elif json_m: - if GEOJSON: - g = capi.from_json(geom_input) - else: - raise NotImplementedError('GeoJSON input only supported on GDAL 1.5+.') - else: - # Seeing if the input is a valid short-hand string - # (e.g., 'Point', 'POLYGON'). - ogr_t = OGRGeomType(geom_input) - g = capi.create_geom(OGRGeomType(geom_input).num) - elif isinstance(geom_input, buffer): - # WKB was passed in - g = capi.from_wkb(str(geom_input), None, byref(c_void_p()), len(geom_input)) - elif isinstance(geom_input, OGRGeomType): - # OGRGeomType was passed in, an empty geometry will be created. - g = capi.create_geom(geom_input.num) - elif isinstance(geom_input, self.ptr_type): - # OGR pointer (c_void_p) was the input. - g = geom_input - else: - raise OGRException('Invalid input type for OGR Geometry construction: %s' % type(geom_input)) - - # Now checking the Geometry pointer before finishing initialization - # by setting the pointer for the object. - if not g: - raise OGRException('Cannot create OGR Geometry from input: %s' % str(geom_input)) - self.ptr = g - - # Assigning the SpatialReference object to the geometry, if valid. - if bool(srs): self.srs = srs - - # Setting the class depending upon the OGR Geometry Type - self.__class__ = GEO_CLASSES[self.geom_type.num] - - def __del__(self): - "Deletes this Geometry." - if self._ptr: capi.destroy_geom(self._ptr) - - # Pickle routines - def __getstate__(self): - srs = self.srs - if srs: - srs = srs.wkt - else: - srs = None - return str(self.wkb), srs - - def __setstate__(self, state): - wkb, srs = state - ptr = capi.from_wkb(wkb, None, byref(c_void_p()), len(wkb)) - if not ptr: raise OGRException('Invalid OGRGeometry loaded from pickled state.') - self.ptr = ptr - self.srs = srs - - @classmethod - def from_bbox(cls, bbox): - "Constructs a Polygon from a bounding box (4-tuple)." - x0, y0, x1, y1 = bbox - return OGRGeometry( 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % ( - x0, y0, x0, y1, x1, y1, x1, y0, x0, y0) ) - - ### Geometry set-like operations ### - # g = g1 | g2 - def __or__(self, other): - "Returns the union of the two geometries." - return self.union(other) - - # g = g1 & g2 - def __and__(self, other): - "Returns the intersection of this Geometry and the other." - return self.intersection(other) - - # g = g1 - g2 - def __sub__(self, other): - "Return the difference this Geometry and the other." - return self.difference(other) - - # g = g1 ^ g2 - def __xor__(self, other): - "Return the symmetric difference of this Geometry and the other." - return self.sym_difference(other) - - def __eq__(self, other): - "Is this Geometry equal to the other?" - if isinstance(other, OGRGeometry): - return self.equals(other) - else: - return False - - def __ne__(self, other): - "Tests for inequality." - return not (self == other) - - def __str__(self): - "WKT is used for the string representation." - return self.wkt - - #### Geometry Properties #### - @property - def dimension(self): - "Returns 0 for points, 1 for lines, and 2 for surfaces." - return capi.get_dims(self.ptr) - - def _get_coord_dim(self): - "Returns the coordinate dimension of the Geometry." - if isinstance(self, GeometryCollection) and GDAL_VERSION < (1, 5, 2): - # On GDAL versions prior to 1.5.2, there exists a bug in which - # the coordinate dimension of geometry collections is always 2: - # http://trac.osgeo.org/gdal/ticket/2334 - # Here we workaround by returning the coordinate dimension of the - # first geometry in the collection instead. - if len(self): - return capi.get_coord_dim(capi.get_geom_ref(self.ptr, 0)) - return capi.get_coord_dim(self.ptr) - - def _set_coord_dim(self, dim): - "Sets the coordinate dimension of this Geometry." - if not dim in (2, 3): - raise ValueError('Geometry dimension must be either 2 or 3') - capi.set_coord_dim(self.ptr, dim) - - coord_dim = property(_get_coord_dim, _set_coord_dim) - - @property - def geom_count(self): - "The number of elements in this Geometry." - return capi.get_geom_count(self.ptr) - - @property - def point_count(self): - "Returns the number of Points in this Geometry." - return capi.get_point_count(self.ptr) - - @property - def num_points(self): - "Alias for `point_count` (same name method in GEOS API.)" - return self.point_count - - @property - def num_coords(self): - "Alais for `point_count`." - return self.point_count - - @property - def geom_type(self): - "Returns the Type for this Geometry." - return OGRGeomType(capi.get_geom_type(self.ptr)) - - @property - def geom_name(self): - "Returns the Name of this Geometry." - return capi.get_geom_name(self.ptr) - - @property - def area(self): - "Returns the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise." - return capi.get_area(self.ptr) - - @property - def envelope(self): - "Returns the envelope for this Geometry." - # TODO: Fix Envelope() for Point geometries. - return Envelope(capi.get_envelope(self.ptr, byref(OGREnvelope()))) - - @property - def extent(self): - "Returns the envelope as a 4-tuple, instead of as an Envelope object." - return self.envelope.tuple - - #### SpatialReference-related Properties #### - - # The SRS property - def _get_srs(self): - "Returns the Spatial Reference for this Geometry." - try: - srs_ptr = capi.get_geom_srs(self.ptr) - return SpatialReference(srs_api.clone_srs(srs_ptr)) - except SRSException: - return None - - def _set_srs(self, srs): - "Sets the SpatialReference for this geometry." - # Do not have to clone the `SpatialReference` object pointer because - # when it is assigned to this `OGRGeometry` it's internal OGR - # reference count is incremented, and will likewise be released - # (decremented) when this geometry's destructor is called. - if isinstance(srs, SpatialReference): - srs_ptr = srs.ptr - elif isinstance(srs, (int, long, basestring)): - sr = SpatialReference(srs) - srs_ptr = sr.ptr - else: - raise TypeError('Cannot assign spatial reference with object of type: %s' % type(srs)) - capi.assign_srs(self.ptr, srs_ptr) - - srs = property(_get_srs, _set_srs) - - # The SRID property - def _get_srid(self): - srs = self.srs - if srs: return srs.srid - return None - - def _set_srid(self, srid): - if isinstance(srid, (int, long)): - self.srs = srid - else: - raise TypeError('SRID must be set with an integer.') - - srid = property(_get_srid, _set_srid) - - #### Output Methods #### - @property - def geos(self): - "Returns a GEOSGeometry object from this OGRGeometry." - from django.contrib.gis.geos import GEOSGeometry - return GEOSGeometry(self.wkb, self.srid) - - @property - def gml(self): - "Returns the GML representation of the Geometry." - return capi.to_gml(self.ptr) - - @property - def hex(self): - "Returns the hexadecimal representation of the WKB (a string)." - return str(self.wkb).encode('hex').upper() - #return b2a_hex(self.wkb).upper() - - @property - def json(self): - """ - Returns the GeoJSON representation of this Geometry (requires - GDAL 1.5+). - """ - if GEOJSON: - return capi.to_json(self.ptr) - else: - raise NotImplementedError('GeoJSON output only supported on GDAL 1.5+.') - geojson = json - - @property - def kml(self): - "Returns the KML representation of the Geometry." - if GEOJSON: - return capi.to_kml(self.ptr, None) - else: - raise NotImplementedError('KML output only supported on GDAL 1.5+.') - - @property - def wkb_size(self): - "Returns the size of the WKB buffer." - return capi.get_wkbsize(self.ptr) - - @property - def wkb(self): - "Returns the WKB representation of the Geometry." - if sys.byteorder == 'little': - byteorder = 1 # wkbNDR (from ogr_core.h) - else: - byteorder = 0 # wkbXDR - sz = self.wkb_size - # Creating the unsigned character buffer, and passing it in by reference. - buf = (c_ubyte * sz)() - wkb = capi.to_wkb(self.ptr, byteorder, byref(buf)) - # Returning a buffer of the string at the pointer. - return buffer(string_at(buf, sz)) - - @property - def wkt(self): - "Returns the WKT representation of the Geometry." - return capi.to_wkt(self.ptr, byref(c_char_p())) - - @property - def ewkt(self): - "Returns the EWKT representation of the Geometry." - srs = self.srs - if srs and srs.srid: - return 'SRID=%s;%s' % (srs.srid, self.wkt) - else: - return self.wkt - - #### Geometry Methods #### - def clone(self): - "Clones this OGR Geometry." - return OGRGeometry(capi.clone_geom(self.ptr), self.srs) - - def close_rings(self): - """ - If there are any rings within this geometry that have not been - closed, this routine will do so by adding the starting point at the - end. - """ - # Closing the open rings. - capi.geom_close_rings(self.ptr) - - def transform(self, coord_trans, clone=False): - """ - Transforms this geometry to a different spatial reference system. - May take a CoordTransform object, a SpatialReference object, string - WKT or PROJ.4, and/or an integer SRID. By default nothing is returned - and the geometry is transformed in-place. However, if the `clone` - keyword is set, then a transformed clone of this geometry will be - returned. - """ - if clone: - klone = self.clone() - klone.transform(coord_trans) - return klone - - # Have to get the coordinate dimension of the original geometry - # so it can be used to reset the transformed geometry's dimension - # afterwards. This is done because of GDAL bug (in versions prior - # to 1.7) that turns geometries 3D after transformation, see: - # http://trac.osgeo.org/gdal/changeset/17792 - if GDAL_VERSION < (1, 7): - orig_dim = self.coord_dim - - # Depending on the input type, use the appropriate OGR routine - # to perform the transformation. - if isinstance(coord_trans, CoordTransform): - capi.geom_transform(self.ptr, coord_trans.ptr) - elif isinstance(coord_trans, SpatialReference): - capi.geom_transform_to(self.ptr, coord_trans.ptr) - elif isinstance(coord_trans, (int, long, basestring)): - sr = SpatialReference(coord_trans) - capi.geom_transform_to(self.ptr, sr.ptr) - else: - raise TypeError('Transform only accepts CoordTransform, ' - 'SpatialReference, string, and integer objects.') - - # Setting with original dimension, see comment above. - if GDAL_VERSION < (1, 7): - if isinstance(self, GeometryCollection): - # With geometry collections have to set dimension on - # each internal geometry reference, as the collection - # dimension isn't affected. - for i in xrange(len(self)): - internal_ptr = capi.get_geom_ref(self.ptr, i) - if orig_dim != capi.get_coord_dim(internal_ptr): - capi.set_coord_dim(internal_ptr, orig_dim) - else: - if self.coord_dim != orig_dim: - self.coord_dim = orig_dim - - def transform_to(self, srs): - "For backwards-compatibility." - self.transform(srs) - - #### Topology Methods #### - def _topology(self, func, other): - """A generalized function for topology operations, takes a GDAL function and - the other geometry to perform the operation on.""" - if not isinstance(other, OGRGeometry): - raise TypeError('Must use another OGRGeometry object for topology operations!') - - # Returning the output of the given function with the other geometry's - # pointer. - return func(self.ptr, other.ptr) - - def intersects(self, other): - "Returns True if this geometry intersects with the other." - return self._topology(capi.ogr_intersects, other) - - def equals(self, other): - "Returns True if this geometry is equivalent to the other." - return self._topology(capi.ogr_equals, other) - - def disjoint(self, other): - "Returns True if this geometry and the other are spatially disjoint." - return self._topology(capi.ogr_disjoint, other) - - def touches(self, other): - "Returns True if this geometry touches the other." - return self._topology(capi.ogr_touches, other) - - def crosses(self, other): - "Returns True if this geometry crosses the other." - return self._topology(capi.ogr_crosses, other) - - def within(self, other): - "Returns True if this geometry is within the other." - return self._topology(capi.ogr_within, other) - - def contains(self, other): - "Returns True if this geometry contains the other." - return self._topology(capi.ogr_contains, other) - - def overlaps(self, other): - "Returns True if this geometry overlaps the other." - return self._topology(capi.ogr_overlaps, other) - - #### Geometry-generation Methods #### - def _geomgen(self, gen_func, other=None): - "A helper routine for the OGR routines that generate geometries." - if isinstance(other, OGRGeometry): - return OGRGeometry(gen_func(self.ptr, other.ptr), self.srs) - else: - return OGRGeometry(gen_func(self.ptr), self.srs) - - @property - def boundary(self): - "Returns the boundary of this geometry." - return self._geomgen(capi.get_boundary) - - @property - def convex_hull(self): - """ - Returns the smallest convex Polygon that contains all the points in - this Geometry. - """ - return self._geomgen(capi.geom_convex_hull) - - def difference(self, other): - """ - Returns a new geometry consisting of the region which is the difference - of this geometry and the other. - """ - return self._geomgen(capi.geom_diff, other) - - def intersection(self, other): - """ - Returns a new geometry consisting of the region of intersection of this - geometry and the other. - """ - return self._geomgen(capi.geom_intersection, other) - - def sym_difference(self, other): - """ - Returns a new geometry which is the symmetric difference of this - geometry and the other. - """ - return self._geomgen(capi.geom_sym_diff, other) - - def union(self, other): - """ - Returns a new geometry consisting of the region which is the union of - this geometry and the other. - """ - return self._geomgen(capi.geom_union, other) - -# The subclasses for OGR Geometry. -class Point(OGRGeometry): - - @property - def x(self): - "Returns the X coordinate for this Point." - return capi.getx(self.ptr, 0) - - @property - def y(self): - "Returns the Y coordinate for this Point." - return capi.gety(self.ptr, 0) - - @property - def z(self): - "Returns the Z coordinate for this Point." - if self.coord_dim == 3: - return capi.getz(self.ptr, 0) - - @property - def tuple(self): - "Returns the tuple of this point." - if self.coord_dim == 2: - return (self.x, self.y) - elif self.coord_dim == 3: - return (self.x, self.y, self.z) - coords = tuple - -class LineString(OGRGeometry): - - def __getitem__(self, index): - "Returns the Point at the given index." - if index >= 0 and index < self.point_count: - x, y, z = c_double(), c_double(), c_double() - capi.get_point(self.ptr, index, byref(x), byref(y), byref(z)) - dim = self.coord_dim - if dim == 1: - return (x.value,) - elif dim == 2: - return (x.value, y.value) - elif dim == 3: - return (x.value, y.value, z.value) - else: - raise OGRIndexError('index out of range: %s' % str(index)) - - def __iter__(self): - "Iterates over each point in the LineString." - for i in xrange(self.point_count): - yield self[i] - - def __len__(self): - "The length returns the number of points in the LineString." - return self.point_count - - @property - def tuple(self): - "Returns the tuple representation of this LineString." - return tuple([self[i] for i in xrange(len(self))]) - coords = tuple - - def _listarr(self, func): - """ - Internal routine that returns a sequence (list) corresponding with - the given function. - """ - return [func(self.ptr, i) for i in xrange(len(self))] - - @property - def x(self): - "Returns the X coordinates in a list." - return self._listarr(capi.getx) - - @property - def y(self): - "Returns the Y coordinates in a list." - return self._listarr(capi.gety) - - @property - def z(self): - "Returns the Z coordinates in a list." - if self.coord_dim == 3: - return self._listarr(capi.getz) - -# LinearRings are used in Polygons. -class LinearRing(LineString): pass - -class Polygon(OGRGeometry): - - def __len__(self): - "The number of interior rings in this Polygon." - return self.geom_count - - def __iter__(self): - "Iterates through each ring in the Polygon." - for i in xrange(self.geom_count): - yield self[i] - - def __getitem__(self, index): - "Gets the ring at the specified index." - if index < 0 or index >= self.geom_count: - raise OGRIndexError('index out of range: %s' % index) - else: - return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs) - - # Polygon Properties - @property - def shell(self): - "Returns the shell of this Polygon." - return self[0] # First ring is the shell - exterior_ring = shell - - @property - def tuple(self): - "Returns a tuple of LinearRing coordinate tuples." - return tuple([self[i].tuple for i in xrange(self.geom_count)]) - coords = tuple - - @property - def point_count(self): - "The number of Points in this Polygon." - # Summing up the number of points in each ring of the Polygon. - return sum([self[i].point_count for i in xrange(self.geom_count)]) - - @property - def centroid(self): - "Returns the centroid (a Point) of this Polygon." - # The centroid is a Point, create a geometry for this. - p = OGRGeometry(OGRGeomType('Point')) - capi.get_centroid(self.ptr, p.ptr) - return p - -# Geometry Collection base class. -class GeometryCollection(OGRGeometry): - "The Geometry Collection class." - - def __getitem__(self, index): - "Gets the Geometry at the specified index." - if index < 0 or index >= self.geom_count: - raise OGRIndexError('index out of range: %s' % index) - else: - return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs) - - def __iter__(self): - "Iterates over each Geometry." - for i in xrange(self.geom_count): - yield self[i] - - def __len__(self): - "The number of geometries in this Geometry Collection." - return self.geom_count - - def add(self, geom): - "Add the geometry to this Geometry Collection." - if isinstance(geom, OGRGeometry): - if isinstance(geom, self.__class__): - for g in geom: capi.add_geom(self.ptr, g.ptr) - else: - capi.add_geom(self.ptr, geom.ptr) - elif isinstance(geom, basestring): - tmp = OGRGeometry(geom) - capi.add_geom(self.ptr, tmp.ptr) - else: - raise OGRException('Must add an OGRGeometry.') - - @property - def point_count(self): - "The number of Points in this Geometry Collection." - # Summing up the number of points in each geometry in this collection - return sum([self[i].point_count for i in xrange(self.geom_count)]) - - @property - def tuple(self): - "Returns a tuple representation of this Geometry Collection." - return tuple([self[i].tuple for i in xrange(self.geom_count)]) - coords = tuple - -# Multiple Geometry types. -class MultiPoint(GeometryCollection): pass -class MultiLineString(GeometryCollection): pass -class MultiPolygon(GeometryCollection): pass - -# Class mapping dictionary (using the OGRwkbGeometryType as the key) -GEO_CLASSES = {1 : Point, - 2 : LineString, - 3 : Polygon, - 4 : MultiPoint, - 5 : MultiLineString, - 6 : MultiPolygon, - 7 : GeometryCollection, - 101: LinearRing, - 1 + OGRGeomType.wkb25bit : Point, - 2 + OGRGeomType.wkb25bit : LineString, - 3 + OGRGeomType.wkb25bit : Polygon, - 4 + OGRGeomType.wkb25bit : MultiPoint, - 5 + OGRGeomType.wkb25bit : MultiLineString, - 6 + OGRGeomType.wkb25bit : MultiPolygon, - 7 + OGRGeomType.wkb25bit : GeometryCollection, - } diff --git a/parts/django/django/contrib/gis/gdal/geomtype.py b/parts/django/django/contrib/gis/gdal/geomtype.py deleted file mode 100644 index 3bf94d4..0000000 --- a/parts/django/django/contrib/gis/gdal/geomtype.py +++ /dev/null @@ -1,85 +0,0 @@ -from django.contrib.gis.gdal.error import OGRException - -#### OGRGeomType #### -class OGRGeomType(object): - "Encapulates OGR Geometry Types." - - wkb25bit = -2147483648 - - # Dictionary of acceptable OGRwkbGeometryType s and their string names. - _types = {0 : 'Unknown', - 1 : 'Point', - 2 : 'LineString', - 3 : 'Polygon', - 4 : 'MultiPoint', - 5 : 'MultiLineString', - 6 : 'MultiPolygon', - 7 : 'GeometryCollection', - 100 : 'None', - 101 : 'LinearRing', - 1 + wkb25bit: 'Point25D', - 2 + wkb25bit: 'LineString25D', - 3 + wkb25bit: 'Polygon25D', - 4 + wkb25bit: 'MultiPoint25D', - 5 + wkb25bit : 'MultiLineString25D', - 6 + wkb25bit : 'MultiPolygon25D', - 7 + wkb25bit : 'GeometryCollection25D', - } - # Reverse type dictionary, keyed by lower-case of the name. - _str_types = dict([(v.lower(), k) for k, v in _types.items()]) - - def __init__(self, type_input): - "Figures out the correct OGR Type based upon the input." - if isinstance(type_input, OGRGeomType): - num = type_input.num - elif isinstance(type_input, basestring): - type_input = type_input.lower() - if type_input == 'geometry': type_input='unknown' - num = self._str_types.get(type_input, None) - if num is None: - raise OGRException('Invalid OGR String Type "%s"' % type_input) - elif isinstance(type_input, int): - if not type_input in self._types: - raise OGRException('Invalid OGR Integer Type: %d' % type_input) - num = type_input - else: - raise TypeError('Invalid OGR input type given.') - - # Setting the OGR geometry type number. - self.num = num - - def __str__(self): - "Returns the value of the name property." - return self.name - - def __eq__(self, other): - """ - Does an equivalence test on the OGR type with the given - other OGRGeomType, the short-hand string, or the integer. - """ - if isinstance(other, OGRGeomType): - return self.num == other.num - elif isinstance(other, basestring): - return self.name.lower() == other.lower() - elif isinstance(other, int): - return self.num == other - else: - return False - - def __ne__(self, other): - return not (self == other) - - @property - def name(self): - "Returns a short-hand string form of the OGR Geometry type." - return self._types[self.num] - - @property - def django(self): - "Returns the Django GeometryField for this OGR Type." - s = self.name.replace('25D', '') - if s in ('LinearRing', 'None'): - return None - elif s == 'Unknown': - s = 'Geometry' - return s + 'Field' diff --git a/parts/django/django/contrib/gis/gdal/layer.py b/parts/django/django/contrib/gis/gdal/layer.py deleted file mode 100644 index a2163bc..0000000 --- a/parts/django/django/contrib/gis/gdal/layer.py +++ /dev/null @@ -1,212 +0,0 @@ -# Needed ctypes routines -from ctypes import c_double, byref - -# Other GDAL imports. -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.envelope import Envelope, OGREnvelope -from django.contrib.gis.gdal.error import OGRException, OGRIndexError, SRSException -from django.contrib.gis.gdal.feature import Feature -from django.contrib.gis.gdal.field import OGRFieldTypes -from django.contrib.gis.gdal.geomtype import OGRGeomType -from django.contrib.gis.gdal.geometries import OGRGeometry -from django.contrib.gis.gdal.srs import SpatialReference - -# GDAL ctypes function prototypes. -from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api, srs as srs_api - -# For more information, see the OGR C API source code: -# http://www.gdal.org/ogr/ogr__api_8h.html -# -# The OGR_L_* routines are relevant here. -class Layer(GDALBase): - "A class that wraps an OGR Layer, needs to be instantiated from a DataSource object." - - #### Python 'magic' routines #### - def __init__(self, layer_ptr, ds): - """ - Initializes on an OGR C pointer to the Layer and the `DataSource` object - that owns this layer. The `DataSource` object is required so that a - reference to it is kept with this Layer. This prevents garbage - collection of the `DataSource` while this Layer is still active. - """ - if not layer_ptr: - raise OGRException('Cannot create Layer, invalid pointer given') - self.ptr = layer_ptr - self._ds = ds - self._ldefn = capi.get_layer_defn(self._ptr) - # Does the Layer support random reading? - self._random_read = self.test_capability('RandomRead') - - def __getitem__(self, index): - "Gets the Feature at the specified index." - if isinstance(index, (int, long)): - # An integer index was given -- we cannot do a check based on the - # number of features because the beginning and ending feature IDs - # are not guaranteed to be 0 and len(layer)-1, respectively. - if index < 0: raise OGRIndexError('Negative indices are not allowed on OGR Layers.') - return self._make_feature(index) - elif isinstance(index, slice): - # A slice was given - start, stop, stride = index.indices(self.num_feat) - return [self._make_feature(fid) for fid in xrange(start, stop, stride)] - else: - raise TypeError('Integers and slices may only be used when indexing OGR Layers.') - - def __iter__(self): - "Iterates over each Feature in the Layer." - # ResetReading() must be called before iteration is to begin. - capi.reset_reading(self._ptr) - for i in xrange(self.num_feat): - yield Feature(capi.get_next_feature(self._ptr), self._ldefn) - - def __len__(self): - "The length is the number of features." - return self.num_feat - - def __str__(self): - "The string name of the layer." - return self.name - - def _make_feature(self, feat_id): - """ - Helper routine for __getitem__ that constructs a Feature from the given - Feature ID. If the OGR Layer does not support random-access reading, - then each feature of the layer will be incremented through until the - a Feature is found matching the given feature ID. - """ - if self._random_read: - # If the Layer supports random reading, return. - try: - return Feature(capi.get_feature(self.ptr, feat_id), self._ldefn) - except OGRException: - pass - else: - # Random access isn't supported, have to increment through - # each feature until the given feature ID is encountered. - for feat in self: - if feat.fid == feat_id: return feat - # Should have returned a Feature, raise an OGRIndexError. - raise OGRIndexError('Invalid feature id: %s.' % feat_id) - - #### Layer properties #### - @property - def extent(self): - "Returns the extent (an Envelope) of this layer." - env = OGREnvelope() - capi.get_extent(self.ptr, byref(env), 1) - return Envelope(env) - - @property - def name(self): - "Returns the name of this layer in the Data Source." - return capi.get_fd_name(self._ldefn) - - @property - def num_feat(self, force=1): - "Returns the number of features in the Layer." - return capi.get_feature_count(self.ptr, force) - - @property - def num_fields(self): - "Returns the number of fields in the Layer." - return capi.get_field_count(self._ldefn) - - @property - def geom_type(self): - "Returns the geometry type (OGRGeomType) of the Layer." - return OGRGeomType(capi.get_fd_geom_type(self._ldefn)) - - @property - def srs(self): - "Returns the Spatial Reference used in this Layer." - try: - ptr = capi.get_layer_srs(self.ptr) - return SpatialReference(srs_api.clone_srs(ptr)) - except SRSException: - return None - - @property - def fields(self): - """ - Returns a list of string names corresponding to each of the Fields - available in this Layer. - """ - return [capi.get_field_name(capi.get_field_defn(self._ldefn, i)) - for i in xrange(self.num_fields) ] - - @property - def field_types(self): - """ - Returns a list of the types of fields in this Layer. For example, - the list [OFTInteger, OFTReal, OFTString] would be returned for - an OGR layer that had an integer, a floating-point, and string - fields. - """ - return [OGRFieldTypes[capi.get_field_type(capi.get_field_defn(self._ldefn, i))] - for i in xrange(self.num_fields)] - - @property - def field_widths(self): - "Returns a list of the maximum field widths for the features." - return [capi.get_field_width(capi.get_field_defn(self._ldefn, i)) - for i in xrange(self.num_fields)] - - @property - def field_precisions(self): - "Returns the field precisions for the features." - return [capi.get_field_precision(capi.get_field_defn(self._ldefn, i)) - for i in xrange(self.num_fields)] - - def _get_spatial_filter(self): - try: - return OGRGeometry(geom_api.clone_geom(capi.get_spatial_filter(self.ptr))) - except OGRException: - return None - - def _set_spatial_filter(self, filter): - if isinstance(filter, OGRGeometry): - capi.set_spatial_filter(self.ptr, filter.ptr) - elif isinstance(filter, (tuple, list)): - if not len(filter) == 4: - raise ValueError('Spatial filter list/tuple must have 4 elements.') - # Map c_double onto params -- if a bad type is passed in it - # will be caught here. - xmin, ymin, xmax, ymax = map(c_double, filter) - capi.set_spatial_filter_rect(self.ptr, xmin, ymin, xmax, ymax) - elif filter is None: - capi.set_spatial_filter(self.ptr, None) - else: - raise TypeError('Spatial filter must be either an OGRGeometry instance, a 4-tuple, or None.') - - spatial_filter = property(_get_spatial_filter, _set_spatial_filter) - - #### Layer Methods #### - def get_fields(self, field_name): - """ - Returns a list containing the given field name for every Feature - in the Layer. - """ - if not field_name in self.fields: - raise OGRException('invalid field name: %s' % field_name) - return [feat.get(field_name) for feat in self] - - def get_geoms(self, geos=False): - """ - Returns a list containing the OGRGeometry for every Feature in - the Layer. - """ - if geos: - from django.contrib.gis.geos import GEOSGeometry - return [GEOSGeometry(feat.geom.wkb) for feat in self] - else: - return [feat.geom for feat in self] - - def test_capability(self, capability): - """ - Returns a bool indicating whether the this Layer supports the given - capability (a string). Valid capability strings include: - 'RandomRead', 'SequentialWrite', 'RandomWrite', 'FastSpatialFilter', - 'FastFeatureCount', 'FastGetExtent', 'CreateField', 'Transactions', - 'DeleteFeature', and 'FastSetNextByIndex'. - """ - return bool(capi.test_capability(self.ptr, capability)) diff --git a/parts/django/django/contrib/gis/gdal/libgdal.py b/parts/django/django/contrib/gis/gdal/libgdal.py deleted file mode 100644 index a7a5658..0000000 --- a/parts/django/django/contrib/gis/gdal/libgdal.py +++ /dev/null @@ -1,104 +0,0 @@ -import os, re, sys -from ctypes import c_char_p, CDLL -from ctypes.util import find_library -from django.contrib.gis.gdal.error import OGRException - -# Custom library path set? -try: - from django.conf import settings - lib_path = settings.GDAL_LIBRARY_PATH -except (AttributeError, EnvironmentError, ImportError): - lib_path = None - -if lib_path: - lib_names = None -elif os.name == 'nt': - # Windows NT shared library - lib_names = ['gdal17', 'gdal16', 'gdal15'] -elif os.name == 'posix': - # *NIX library names. - lib_names = ['gdal', 'GDAL', 'gdal1.7.0', 'gdal1.6.0', 'gdal1.5.0', 'gdal1.4.0'] -else: - raise OGRException('Unsupported OS "%s"' % os.name) - -# Using the ctypes `find_library` utility to find the -# path to the GDAL library from the list of library names. -if lib_names: - for lib_name in lib_names: - lib_path = find_library(lib_name) - if not lib_path is None: break - -if lib_path is None: - raise OGRException('Could not find the GDAL library (tried "%s"). ' - 'Try setting GDAL_LIBRARY_PATH in your settings.' % - '", "'.join(lib_names)) - -# This loads the GDAL/OGR C library -lgdal = CDLL(lib_path) - -# On Windows, the GDAL binaries have some OSR routines exported with -# STDCALL, while others are not. Thus, the library will also need to -# be loaded up as WinDLL for said OSR functions that require the -# different calling convention. -if os.name == 'nt': - from ctypes import WinDLL - lwingdal = WinDLL(lib_path) - -def std_call(func): - """ - Returns the correct STDCALL function for certain OSR routines on Win32 - platforms. - """ - if os.name == 'nt': - return lwingdal[func] - else: - return lgdal[func] - -#### Version-information functions. #### - -# Returns GDAL library version information with the given key. -_version_info = std_call('GDALVersionInfo') -_version_info.argtypes = [c_char_p] -_version_info.restype = c_char_p - -def gdal_version(): - "Returns only the GDAL version number information." - return _version_info('RELEASE_NAME') - -def gdal_full_version(): - "Returns the full GDAL version information." - return _version_info('') - -def gdal_release_date(date=False): - """ - Returns the release date in a string format, e.g, "2007/06/27". - If the date keyword argument is set to True, a Python datetime object - will be returned instead. - """ - from datetime import date as date_type - rel = _version_info('RELEASE_DATE') - yy, mm, dd = map(int, (rel[0:4], rel[4:6], rel[6:8])) - d = date_type(yy, mm, dd) - if date: return d - else: return d.strftime('%Y/%m/%d') - -version_regex = re.compile(r'^(?P<major>\d+)\.(?P<minor>\d+)(\.(?P<subminor>\d+))?') -def gdal_version_info(): - ver = gdal_version() - m = version_regex.match(ver) - if not m: raise OGRException('Could not parse GDAL version string "%s"' % ver) - return dict([(key, m.group(key)) for key in ('major', 'minor', 'subminor')]) - -_verinfo = gdal_version_info() -GDAL_MAJOR_VERSION = int(_verinfo['major']) -GDAL_MINOR_VERSION = int(_verinfo['minor']) -GDAL_SUBMINOR_VERSION = _verinfo['subminor'] and int(_verinfo['subminor']) -GDAL_VERSION = (GDAL_MAJOR_VERSION, GDAL_MINOR_VERSION, GDAL_SUBMINOR_VERSION) -del _verinfo - -# GeoJSON support is available only in GDAL 1.5+. -if GDAL_VERSION >= (1, 5): - GEOJSON = True -else: - GEOJSON = False - diff --git a/parts/django/django/contrib/gis/gdal/prototypes/__init__.py b/parts/django/django/contrib/gis/gdal/prototypes/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/gdal/prototypes/ds.py b/parts/django/django/contrib/gis/gdal/prototypes/ds.py deleted file mode 100644 index 44828ee..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/ds.py +++ /dev/null @@ -1,71 +0,0 @@ -""" - This module houses the ctypes function prototypes for OGR DataSource - related data structures. OGR_Dr_*, OGR_DS_*, OGR_L_*, OGR_F_*, - OGR_Fld_* routines are relevant here. -""" -from ctypes import c_char_p, c_double, c_int, c_long, c_void_p, POINTER -from django.contrib.gis.gdal.envelope import OGREnvelope -from django.contrib.gis.gdal.libgdal import lgdal -from django.contrib.gis.gdal.prototypes.generation import \ - const_string_output, double_output, geom_output, int_output, \ - srs_output, void_output, voidptr_output - -c_int_p = POINTER(c_int) # shortcut type - -### Driver Routines ### -register_all = void_output(lgdal.OGRRegisterAll, [], errcheck=False) -cleanup_all = void_output(lgdal.OGRCleanupAll, [], errcheck=False) -get_driver = voidptr_output(lgdal.OGRGetDriver, [c_int]) -get_driver_by_name = voidptr_output(lgdal.OGRGetDriverByName, [c_char_p]) -get_driver_count = int_output(lgdal.OGRGetDriverCount, []) -get_driver_name = const_string_output(lgdal.OGR_Dr_GetName, [c_void_p]) - -### DataSource ### -open_ds = voidptr_output(lgdal.OGROpen, [c_char_p, c_int, POINTER(c_void_p)]) -destroy_ds = void_output(lgdal.OGR_DS_Destroy, [c_void_p], errcheck=False) -release_ds = void_output(lgdal.OGRReleaseDataSource, [c_void_p]) -get_ds_name = const_string_output(lgdal.OGR_DS_GetName, [c_void_p]) -get_layer = voidptr_output(lgdal.OGR_DS_GetLayer, [c_void_p, c_int]) -get_layer_by_name = voidptr_output(lgdal.OGR_DS_GetLayerByName, [c_void_p, c_char_p]) -get_layer_count = int_output(lgdal.OGR_DS_GetLayerCount, [c_void_p]) - -### Layer Routines ### -get_extent = void_output(lgdal.OGR_L_GetExtent, [c_void_p, POINTER(OGREnvelope), c_int]) -get_feature = voidptr_output(lgdal.OGR_L_GetFeature, [c_void_p, c_long]) -get_feature_count = int_output(lgdal.OGR_L_GetFeatureCount, [c_void_p, c_int]) -get_layer_defn = voidptr_output(lgdal.OGR_L_GetLayerDefn, [c_void_p]) -get_layer_srs = srs_output(lgdal.OGR_L_GetSpatialRef, [c_void_p]) -get_next_feature = voidptr_output(lgdal.OGR_L_GetNextFeature, [c_void_p]) -reset_reading = void_output(lgdal.OGR_L_ResetReading, [c_void_p], errcheck=False) -test_capability = int_output(lgdal.OGR_L_TestCapability, [c_void_p, c_char_p]) -get_spatial_filter = geom_output(lgdal.OGR_L_GetSpatialFilter, [c_void_p]) -set_spatial_filter = void_output(lgdal.OGR_L_SetSpatialFilter, [c_void_p, c_void_p], errcheck=False) -set_spatial_filter_rect = void_output(lgdal.OGR_L_SetSpatialFilterRect, [c_void_p, c_double, c_double, c_double, c_double], errcheck=False) - -### Feature Definition Routines ### -get_fd_geom_type = int_output(lgdal.OGR_FD_GetGeomType, [c_void_p]) -get_fd_name = const_string_output(lgdal.OGR_FD_GetName, [c_void_p]) -get_feat_name = const_string_output(lgdal.OGR_FD_GetName, [c_void_p]) -get_field_count = int_output(lgdal.OGR_FD_GetFieldCount, [c_void_p]) -get_field_defn = voidptr_output(lgdal.OGR_FD_GetFieldDefn, [c_void_p, c_int]) - -### Feature Routines ### -clone_feature = voidptr_output(lgdal.OGR_F_Clone, [c_void_p]) -destroy_feature = void_output(lgdal.OGR_F_Destroy, [c_void_p], errcheck=False) -feature_equal = int_output(lgdal.OGR_F_Equal, [c_void_p, c_void_p]) -get_feat_geom_ref = geom_output(lgdal.OGR_F_GetGeometryRef, [c_void_p]) -get_feat_field_count = int_output(lgdal.OGR_F_GetFieldCount, [c_void_p]) -get_feat_field_defn = voidptr_output(lgdal.OGR_F_GetFieldDefnRef, [c_void_p, c_int]) -get_fid = int_output(lgdal.OGR_F_GetFID, [c_void_p]) -get_field_as_datetime = int_output(lgdal.OGR_F_GetFieldAsDateTime, [c_void_p, c_int, c_int_p, c_int_p, c_int_p, c_int_p, c_int_p, c_int_p]) -get_field_as_double = double_output(lgdal.OGR_F_GetFieldAsDouble, [c_void_p, c_int]) -get_field_as_integer = int_output(lgdal.OGR_F_GetFieldAsInteger, [c_void_p, c_int]) -get_field_as_string = const_string_output(lgdal.OGR_F_GetFieldAsString, [c_void_p, c_int]) -get_field_index = int_output(lgdal.OGR_F_GetFieldIndex, [c_void_p, c_char_p]) - -### Field Routines ### -get_field_name = const_string_output(lgdal.OGR_Fld_GetNameRef, [c_void_p]) -get_field_precision = int_output(lgdal.OGR_Fld_GetPrecision, [c_void_p]) -get_field_type = int_output(lgdal.OGR_Fld_GetType, [c_void_p]) -get_field_type_name = const_string_output(lgdal.OGR_GetFieldTypeName, [c_int]) -get_field_width = int_output(lgdal.OGR_Fld_GetWidth, [c_void_p]) diff --git a/parts/django/django/contrib/gis/gdal/prototypes/errcheck.py b/parts/django/django/contrib/gis/gdal/prototypes/errcheck.py deleted file mode 100644 index 91858ea..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/errcheck.py +++ /dev/null @@ -1,127 +0,0 @@ -""" - This module houses the error-checking routines used by the GDAL - ctypes prototypes. -""" -from ctypes import c_void_p, string_at -from django.contrib.gis.gdal.error import check_err, OGRException, SRSException -from django.contrib.gis.gdal.libgdal import lgdal - -# Helper routines for retrieving pointers and/or values from -# arguments passed in by reference. -def arg_byref(args, offset=-1): - "Returns the pointer argument's by-refernece value." - return args[offset]._obj.value - -def ptr_byref(args, offset=-1): - "Returns the pointer argument passed in by-reference." - return args[offset]._obj - -def check_bool(result, func, cargs): - "Returns the boolean evaluation of the value." - if bool(result): return True - else: return False - -### String checking Routines ### -def check_const_string(result, func, cargs, offset=None): - """ - Similar functionality to `check_string`, but does not free the pointer. - """ - if offset: - check_err(result) - ptr = ptr_byref(cargs, offset) - return ptr.value - else: - return result - -def check_string(result, func, cargs, offset=-1, str_result=False): - """ - Checks the string output returned from the given function, and frees - the string pointer allocated by OGR. The `str_result` keyword - may be used when the result is the string pointer, otherwise - the OGR error code is assumed. The `offset` keyword may be used - to extract the string pointer passed in by-reference at the given - slice offset in the function arguments. - """ - if str_result: - # For routines that return a string. - ptr = result - if not ptr: s = None - else: s = string_at(result) - else: - # Error-code return specified. - check_err(result) - ptr = ptr_byref(cargs, offset) - # Getting the string value - s = ptr.value - # Correctly freeing the allocated memory beind GDAL pointer - # w/the VSIFree routine. - if ptr: lgdal.VSIFree(ptr) - return s - -### DataSource, Layer error-checking ### - -### Envelope checking ### -def check_envelope(result, func, cargs, offset=-1): - "Checks a function that returns an OGR Envelope by reference." - env = ptr_byref(cargs, offset) - return env - -### Geometry error-checking routines ### -def check_geom(result, func, cargs): - "Checks a function that returns a geometry." - # OGR_G_Clone may return an integer, even though the - # restype is set to c_void_p - if isinstance(result, (int, long)): - result = c_void_p(result) - if not result: - raise OGRException('Invalid geometry pointer returned from "%s".' % func.__name__) - return result - -def check_geom_offset(result, func, cargs, offset=-1): - "Chcks the geometry at the given offset in the C parameter list." - check_err(result) - geom = ptr_byref(cargs, offset=offset) - return check_geom(geom, func, cargs) - -### Spatial Reference error-checking routines ### -def check_srs(result, func, cargs): - if isinstance(result, (int, long)): - result = c_void_p(result) - if not result: - raise SRSException('Invalid spatial reference pointer returned from "%s".' % func.__name__) - return result - -### Other error-checking routines ### -def check_arg_errcode(result, func, cargs): - """ - The error code is returned in the last argument, by reference. - Check its value with `check_err` before returning the result. - """ - check_err(arg_byref(cargs)) - return result - -def check_errcode(result, func, cargs): - """ - Check the error code returned (c_int). - """ - check_err(result) - return - -def check_pointer(result, func, cargs): - "Makes sure the result pointer is valid." - if isinstance(result, (int, long)): - result = c_void_p(result) - if bool(result): - return result - else: - raise OGRException('Invalid pointer returned from "%s"' % func.__name__) - -def check_str_arg(result, func, cargs): - """ - This is for the OSRGet[Angular|Linear]Units functions, which - require that the returned string pointer not be freed. This - returns both the double and tring values. - """ - dbl = result - ptr = cargs[-1]._obj - return dbl, ptr.value diff --git a/parts/django/django/contrib/gis/gdal/prototypes/generation.py b/parts/django/django/contrib/gis/gdal/prototypes/generation.py deleted file mode 100644 index 1303532..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/generation.py +++ /dev/null @@ -1,119 +0,0 @@ -""" - This module contains functions that generate ctypes prototypes for the - GDAL routines. -""" - -from ctypes import c_char_p, c_double, c_int, c_void_p -from django.contrib.gis.gdal.prototypes.errcheck import \ - check_arg_errcode, check_errcode, check_geom, check_geom_offset, \ - check_pointer, check_srs, check_str_arg, check_string, check_const_string - -class gdal_char_p(c_char_p): - pass - -def double_output(func, argtypes, errcheck=False, strarg=False): - "Generates a ctypes function that returns a double value." - func.argtypes = argtypes - func.restype = c_double - if errcheck: func.errcheck = check_arg_errcode - if strarg: func.errcheck = check_str_arg - return func - -def geom_output(func, argtypes, offset=None): - """ - Generates a function that returns a Geometry either by reference - or directly (if the return_geom keyword is set to True). - """ - # Setting the argument types - func.argtypes = argtypes - - if not offset: - # When a geometry pointer is directly returned. - func.restype = c_void_p - func.errcheck = check_geom - else: - # Error code returned, geometry is returned by-reference. - func.restype = c_int - def geomerrcheck(result, func, cargs): - return check_geom_offset(result, func, cargs, offset) - func.errcheck = geomerrcheck - - return func - -def int_output(func, argtypes): - "Generates a ctypes function that returns an integer value." - func.argtypes = argtypes - func.restype = c_int - return func - -def srs_output(func, argtypes): - """ - Generates a ctypes prototype for the given function with - the given C arguments that returns a pointer to an OGR - Spatial Reference System. - """ - func.argtypes = argtypes - func.restype = c_void_p - func.errcheck = check_srs - return func - -def const_string_output(func, argtypes, offset=None): - func.argtypes = argtypes - if offset: - func.restype = c_int - else: - func.restype = c_char_p - - def _check_const(result, func, cargs): - return check_const_string(result, func, cargs, offset=offset) - func.errcheck = _check_const - - return func - -def string_output(func, argtypes, offset=-1, str_result=False): - """ - Generates a ctypes prototype for the given function with the - given argument types that returns a string from a GDAL pointer. - The `const` flag indicates whether the allocated pointer should - be freed via the GDAL library routine VSIFree -- but only applies - only when `str_result` is True. - """ - func.argtypes = argtypes - if str_result: - # Use subclass of c_char_p so the error checking routine - # can free the memory at the pointer's address. - func.restype = gdal_char_p - else: - # Error code is returned - func.restype = c_int - - # Dynamically defining our error-checking function with the - # given offset. - def _check_str(result, func, cargs): - return check_string(result, func, cargs, - offset=offset, str_result=str_result) - func.errcheck = _check_str - return func - -def void_output(func, argtypes, errcheck=True): - """ - For functions that don't only return an error code that needs to - be examined. - """ - if argtypes: func.argtypes = argtypes - if errcheck: - # `errcheck` keyword may be set to False for routines that - # return void, rather than a status code. - func.restype = c_int - func.errcheck = check_errcode - else: - func.restype = None - - return func - -def voidptr_output(func, argtypes): - "For functions that return c_void_p." - func.argtypes = argtypes - func.restype = c_void_p - func.errcheck = check_pointer - return func diff --git a/parts/django/django/contrib/gis/gdal/prototypes/geom.py b/parts/django/django/contrib/gis/gdal/prototypes/geom.py deleted file mode 100644 index e002590..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/geom.py +++ /dev/null @@ -1,106 +0,0 @@ -import re -from datetime import date -from ctypes import c_char, c_char_p, c_double, c_int, c_ubyte, c_void_p, POINTER -from django.contrib.gis.gdal.envelope import OGREnvelope -from django.contrib.gis.gdal.libgdal import lgdal, GEOJSON -from django.contrib.gis.gdal.prototypes.errcheck import check_bool, check_envelope -from django.contrib.gis.gdal.prototypes.generation import \ - const_string_output, double_output, geom_output, int_output, \ - srs_output, string_output, void_output - -### Generation routines specific to this module ### -def env_func(f, argtypes): - "For getting OGREnvelopes." - f.argtypes = argtypes - f.restype = None - f.errcheck = check_envelope - return f - -def pnt_func(f): - "For accessing point information." - return double_output(f, [c_void_p, c_int]) - -def topology_func(f): - f.argtypes = [c_void_p, c_void_p] - f.restype = c_int - f.errchck = check_bool - return f - -### OGR_G ctypes function prototypes ### - -# GeoJSON routines, if supported. -if GEOJSON: - from_json = geom_output(lgdal.OGR_G_CreateGeometryFromJson, [c_char_p]) - to_json = string_output(lgdal.OGR_G_ExportToJson, [c_void_p], str_result=True) - to_kml = string_output(lgdal.OGR_G_ExportToKML, [c_void_p, c_char_p], str_result=True) -else: - from_json = False - to_json = False - to_kml = False - -# GetX, GetY, GetZ all return doubles. -getx = pnt_func(lgdal.OGR_G_GetX) -gety = pnt_func(lgdal.OGR_G_GetY) -getz = pnt_func(lgdal.OGR_G_GetZ) - -# Geometry creation routines. -from_wkb = geom_output(lgdal.OGR_G_CreateFromWkb, [c_char_p, c_void_p, POINTER(c_void_p), c_int], offset=-2) -from_wkt = geom_output(lgdal.OGR_G_CreateFromWkt, [POINTER(c_char_p), c_void_p, POINTER(c_void_p)], offset=-1) -create_geom = geom_output(lgdal.OGR_G_CreateGeometry, [c_int]) -clone_geom = geom_output(lgdal.OGR_G_Clone, [c_void_p]) -get_geom_ref = geom_output(lgdal.OGR_G_GetGeometryRef, [c_void_p, c_int]) -get_boundary = geom_output(lgdal.OGR_G_GetBoundary, [c_void_p]) -geom_convex_hull = geom_output(lgdal.OGR_G_ConvexHull, [c_void_p]) -geom_diff = geom_output(lgdal.OGR_G_Difference, [c_void_p, c_void_p]) -geom_intersection = geom_output(lgdal.OGR_G_Intersection, [c_void_p, c_void_p]) -geom_sym_diff = geom_output(lgdal.OGR_G_SymmetricDifference, [c_void_p, c_void_p]) -geom_union = geom_output(lgdal.OGR_G_Union, [c_void_p, c_void_p]) - -# Geometry modification routines. -add_geom = void_output(lgdal.OGR_G_AddGeometry, [c_void_p, c_void_p]) -import_wkt = void_output(lgdal.OGR_G_ImportFromWkt, [c_void_p, POINTER(c_char_p)]) - -# Destroys a geometry -destroy_geom = void_output(lgdal.OGR_G_DestroyGeometry, [c_void_p], errcheck=False) - -# Geometry export routines. -to_wkb = void_output(lgdal.OGR_G_ExportToWkb, None, errcheck=True) # special handling for WKB. -to_wkt = string_output(lgdal.OGR_G_ExportToWkt, [c_void_p, POINTER(c_char_p)]) -to_gml = string_output(lgdal.OGR_G_ExportToGML, [c_void_p], str_result=True) -get_wkbsize = int_output(lgdal.OGR_G_WkbSize, [c_void_p]) - -# Geometry spatial-reference related routines. -assign_srs = void_output(lgdal.OGR_G_AssignSpatialReference, [c_void_p, c_void_p], errcheck=False) -get_geom_srs = srs_output(lgdal.OGR_G_GetSpatialReference, [c_void_p]) - -# Geometry properties -get_area = double_output(lgdal.OGR_G_GetArea, [c_void_p]) -get_centroid = void_output(lgdal.OGR_G_Centroid, [c_void_p, c_void_p]) -get_dims = int_output(lgdal.OGR_G_GetDimension, [c_void_p]) -get_coord_dim = int_output(lgdal.OGR_G_GetCoordinateDimension, [c_void_p]) -set_coord_dim = void_output(lgdal.OGR_G_SetCoordinateDimension, [c_void_p, c_int], errcheck=False) - -get_geom_count = int_output(lgdal.OGR_G_GetGeometryCount, [c_void_p]) -get_geom_name = const_string_output(lgdal.OGR_G_GetGeometryName, [c_void_p]) -get_geom_type = int_output(lgdal.OGR_G_GetGeometryType, [c_void_p]) -get_point_count = int_output(lgdal.OGR_G_GetPointCount, [c_void_p]) -get_point = void_output(lgdal.OGR_G_GetPoint, [c_void_p, c_int, POINTER(c_double), POINTER(c_double), POINTER(c_double)], errcheck=False) -geom_close_rings = void_output(lgdal.OGR_G_CloseRings, [c_void_p], errcheck=False) - -# Topology routines. -ogr_contains = topology_func(lgdal.OGR_G_Contains) -ogr_crosses = topology_func(lgdal.OGR_G_Crosses) -ogr_disjoint = topology_func(lgdal.OGR_G_Disjoint) -ogr_equals = topology_func(lgdal.OGR_G_Equals) -ogr_intersects = topology_func(lgdal.OGR_G_Intersects) -ogr_overlaps = topology_func(lgdal.OGR_G_Overlaps) -ogr_touches = topology_func(lgdal.OGR_G_Touches) -ogr_within = topology_func(lgdal.OGR_G_Within) - -# Transformation routines. -geom_transform = void_output(lgdal.OGR_G_Transform, [c_void_p, c_void_p]) -geom_transform_to = void_output(lgdal.OGR_G_TransformTo, [c_void_p, c_void_p]) - -# For retrieving the envelope of the geometry. -get_envelope = env_func(lgdal.OGR_G_GetEnvelope, [c_void_p, POINTER(OGREnvelope)]) - diff --git a/parts/django/django/contrib/gis/gdal/prototypes/srs.py b/parts/django/django/contrib/gis/gdal/prototypes/srs.py deleted file mode 100644 index 411cec9..0000000 --- a/parts/django/django/contrib/gis/gdal/prototypes/srs.py +++ /dev/null @@ -1,72 +0,0 @@ -from ctypes import c_char_p, c_int, c_void_p, POINTER -from django.contrib.gis.gdal.libgdal import lgdal, std_call -from django.contrib.gis.gdal.prototypes.generation import \ - const_string_output, double_output, int_output, \ - srs_output, string_output, void_output - -## Shortcut generation for routines with known parameters. -def srs_double(f): - """ - Creates a function prototype for the OSR routines that take - the OSRSpatialReference object and - """ - return double_output(f, [c_void_p, POINTER(c_int)], errcheck=True) - -def units_func(f): - """ - Creates a ctypes function prototype for OSR units functions, e.g., - OSRGetAngularUnits, OSRGetLinearUnits. - """ - return double_output(f, [c_void_p, POINTER(c_char_p)], strarg=True) - -# Creation & destruction. -clone_srs = srs_output(std_call('OSRClone'), [c_void_p]) -new_srs = srs_output(std_call('OSRNewSpatialReference'), [c_char_p]) -release_srs = void_output(lgdal.OSRRelease, [c_void_p], errcheck=False) -destroy_srs = void_output(std_call('OSRDestroySpatialReference'), [c_void_p], errcheck=False) -srs_validate = void_output(lgdal.OSRValidate, [c_void_p]) - -# Getting the semi_major, semi_minor, and flattening functions. -semi_major = srs_double(lgdal.OSRGetSemiMajor) -semi_minor = srs_double(lgdal.OSRGetSemiMinor) -invflattening = srs_double(lgdal.OSRGetInvFlattening) - -# WKT, PROJ, EPSG, XML importation routines. -from_wkt = void_output(lgdal.OSRImportFromWkt, [c_void_p, POINTER(c_char_p)]) -from_proj = void_output(lgdal.OSRImportFromProj4, [c_void_p, c_char_p]) -from_epsg = void_output(std_call('OSRImportFromEPSG'), [c_void_p, c_int]) -from_xml = void_output(lgdal.OSRImportFromXML, [c_void_p, c_char_p]) -from_user_input = void_output(std_call('OSRSetFromUserInput'), [c_void_p, c_char_p]) - -# Morphing to/from ESRI WKT. -morph_to_esri = void_output(lgdal.OSRMorphToESRI, [c_void_p]) -morph_from_esri = void_output(lgdal.OSRMorphFromESRI, [c_void_p]) - -# Identifying the EPSG -identify_epsg = void_output(lgdal.OSRAutoIdentifyEPSG, [c_void_p]) - -# Getting the angular_units, linear_units functions -linear_units = units_func(lgdal.OSRGetLinearUnits) -angular_units = units_func(lgdal.OSRGetAngularUnits) - -# For exporting to WKT, PROJ.4, "Pretty" WKT, and XML. -to_wkt = string_output(std_call('OSRExportToWkt'), [c_void_p, POINTER(c_char_p)]) -to_proj = string_output(std_call('OSRExportToProj4'), [c_void_p, POINTER(c_char_p)]) -to_pretty_wkt = string_output(std_call('OSRExportToPrettyWkt'), [c_void_p, POINTER(c_char_p), c_int], offset=-2) - -# Memory leak fixed in GDAL 1.5; still exists in 1.4. -to_xml = string_output(lgdal.OSRExportToXML, [c_void_p, POINTER(c_char_p), c_char_p], offset=-2) - -# String attribute retrival routines. -get_attr_value = const_string_output(std_call('OSRGetAttrValue'), [c_void_p, c_char_p, c_int]) -get_auth_name = const_string_output(lgdal.OSRGetAuthorityName, [c_void_p, c_char_p]) -get_auth_code = const_string_output(lgdal.OSRGetAuthorityCode, [c_void_p, c_char_p]) - -# SRS Properties -isgeographic = int_output(lgdal.OSRIsGeographic, [c_void_p]) -islocal = int_output(lgdal.OSRIsLocal, [c_void_p]) -isprojected = int_output(lgdal.OSRIsProjected, [c_void_p]) - -# Coordinate transformation -new_ct= srs_output(std_call('OCTNewCoordinateTransformation'), [c_void_p, c_void_p]) -destroy_ct = void_output(std_call('OCTDestroyCoordinateTransformation'), [c_void_p], errcheck=False) diff --git a/parts/django/django/contrib/gis/gdal/srs.py b/parts/django/django/contrib/gis/gdal/srs.py deleted file mode 100644 index 95e71f1..0000000 --- a/parts/django/django/contrib/gis/gdal/srs.py +++ /dev/null @@ -1,337 +0,0 @@ -""" - The Spatial Reference class, represensents OGR Spatial Reference objects. - - Example: - >>> from django.contrib.gis.gdal import SpatialReference - >>> srs = SpatialReference('WGS84') - >>> print srs - GEOGCS["WGS 84", - DATUM["WGS_1984", - SPHEROID["WGS 84",6378137,298.257223563, - AUTHORITY["EPSG","7030"]], - TOWGS84[0,0,0,0,0,0,0], - AUTHORITY["EPSG","6326"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.01745329251994328, - AUTHORITY["EPSG","9122"]], - AUTHORITY["EPSG","4326"]] - >>> print srs.proj - +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs - >>> print srs.ellipsoid - (6378137.0, 6356752.3142451793, 298.25722356300003) - >>> print srs.projected, srs.geographic - False True - >>> srs.import_epsg(32140) - >>> print srs.name - NAD83 / Texas South Central -""" -import re -from ctypes import byref, c_char_p, c_int, c_void_p - -# Getting the error checking routine and exceptions -from django.contrib.gis.gdal.base import GDALBase -from django.contrib.gis.gdal.error import OGRException, SRSException -from django.contrib.gis.gdal.prototypes import srs as capi - -#### Spatial Reference class. #### -class SpatialReference(GDALBase): - """ - A wrapper for the OGRSpatialReference object. According to the GDAL Web site, - the SpatialReference object "provide[s] services to represent coordinate - systems (projections and datums) and to transform between them." - """ - - #### Python 'magic' routines #### - def __init__(self, srs_input=''): - """ - Creates a GDAL OSR Spatial Reference object from the given input. - The input may be string of OGC Well Known Text (WKT), an integer - EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand - string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83'). - """ - buf = c_char_p('') - srs_type = 'user' - - if isinstance(srs_input, basestring): - # Encoding to ASCII if unicode passed in. - if isinstance(srs_input, unicode): - srs_input = srs_input.encode('ascii') - try: - # If SRID is a string, e.g., '4326', then make acceptable - # as user input. - srid = int(srs_input) - srs_input = 'EPSG:%d' % srid - except ValueError: - pass - elif isinstance(srs_input, (int, long)): - # EPSG integer code was input. - srs_type = 'epsg' - elif isinstance(srs_input, self.ptr_type): - srs = srs_input - srs_type = 'ogr' - else: - raise TypeError('Invalid SRS type "%s"' % srs_type) - - if srs_type == 'ogr': - # Input is already an SRS pointer. - srs = srs_input - else: - # Creating a new SRS pointer, using the string buffer. - srs = capi.new_srs(buf) - - # If the pointer is NULL, throw an exception. - if not srs: - raise SRSException('Could not create spatial reference from: %s' % srs_input) - else: - self.ptr = srs - - # Importing from either the user input string or an integer SRID. - if srs_type == 'user': - self.import_user_input(srs_input) - elif srs_type == 'epsg': - self.import_epsg(srs_input) - - def __del__(self): - "Destroys this spatial reference." - if self._ptr: capi.release_srs(self._ptr) - - def __getitem__(self, target): - """ - Returns the value of the given string attribute node, None if the node - doesn't exist. Can also take a tuple as a parameter, (target, child), - where child is the index of the attribute in the WKT. For example: - - >>> wkt = 'GEOGCS["WGS 84", DATUM["WGS_1984, ... AUTHORITY["EPSG","4326"]]') - >>> srs = SpatialReference(wkt) # could also use 'WGS84', or 4326 - >>> print srs['GEOGCS'] - WGS 84 - >>> print srs['DATUM'] - WGS_1984 - >>> print srs['AUTHORITY'] - EPSG - >>> print srs['AUTHORITY', 1] # The authority value - 4326 - >>> print srs['TOWGS84', 4] # the fourth value in this wkt - 0 - >>> print srs['UNIT|AUTHORITY'] # For the units authority, have to use the pipe symbole. - EPSG - >>> print srs['UNIT|AUTHORITY', 1] # The authority value for the untis - 9122 - """ - if isinstance(target, tuple): - return self.attr_value(*target) - else: - return self.attr_value(target) - - def __str__(self): - "The string representation uses 'pretty' WKT." - return self.pretty_wkt - - #### SpatialReference Methods #### - def attr_value(self, target, index=0): - """ - The attribute value for the given target node (e.g. 'PROJCS'). The index - keyword specifies an index of the child node to return. - """ - if not isinstance(target, basestring) or not isinstance(index, int): - raise TypeError - return capi.get_attr_value(self.ptr, target, index) - - def auth_name(self, target): - "Returns the authority name for the given string target node." - return capi.get_auth_name(self.ptr, target) - - def auth_code(self, target): - "Returns the authority code for the given string target node." - return capi.get_auth_code(self.ptr, target) - - def clone(self): - "Returns a clone of this SpatialReference object." - return SpatialReference(capi.clone_srs(self.ptr)) - - def from_esri(self): - "Morphs this SpatialReference from ESRI's format to EPSG." - capi.morph_from_esri(self.ptr) - - def identify_epsg(self): - """ - This method inspects the WKT of this SpatialReference, and will - add EPSG authority nodes where an EPSG identifier is applicable. - """ - capi.identify_epsg(self.ptr) - - def to_esri(self): - "Morphs this SpatialReference to ESRI's format." - capi.morph_to_esri(self.ptr) - - def validate(self): - "Checks to see if the given spatial reference is valid." - capi.srs_validate(self.ptr) - - #### Name & SRID properties #### - @property - def name(self): - "Returns the name of this Spatial Reference." - if self.projected: return self.attr_value('PROJCS') - elif self.geographic: return self.attr_value('GEOGCS') - elif self.local: return self.attr_value('LOCAL_CS') - else: return None - - @property - def srid(self): - "Returns the SRID of top-level authority, or None if undefined." - try: - return int(self.attr_value('AUTHORITY', 1)) - except (TypeError, ValueError): - return None - - #### Unit Properties #### - @property - def linear_name(self): - "Returns the name of the linear units." - units, name = capi.linear_units(self.ptr, byref(c_char_p())) - return name - - @property - def linear_units(self): - "Returns the value of the linear units." - units, name = capi.linear_units(self.ptr, byref(c_char_p())) - return units - - @property - def angular_name(self): - "Returns the name of the angular units." - units, name = capi.angular_units(self.ptr, byref(c_char_p())) - return name - - @property - def angular_units(self): - "Returns the value of the angular units." - units, name = capi.angular_units(self.ptr, byref(c_char_p())) - return units - - @property - def units(self): - """ - Returns a 2-tuple of the units value and the units name, - and will automatically determines whether to return the linear - or angular units. - """ - if self.projected or self.local: - return capi.linear_units(self.ptr, byref(c_char_p())) - elif self.geographic: - return capi.angular_units(self.ptr, byref(c_char_p())) - else: - return (None, None) - - #### Spheroid/Ellipsoid Properties #### - @property - def ellipsoid(self): - """ - Returns a tuple of the ellipsoid parameters: - (semimajor axis, semiminor axis, and inverse flattening) - """ - return (self.semi_major, self.semi_minor, self.inverse_flattening) - - @property - def semi_major(self): - "Returns the Semi Major Axis for this Spatial Reference." - return capi.semi_major(self.ptr, byref(c_int())) - - @property - def semi_minor(self): - "Returns the Semi Minor Axis for this Spatial Reference." - return capi.semi_minor(self.ptr, byref(c_int())) - - @property - def inverse_flattening(self): - "Returns the Inverse Flattening for this Spatial Reference." - return capi.invflattening(self.ptr, byref(c_int())) - - #### Boolean Properties #### - @property - def geographic(self): - """ - Returns True if this SpatialReference is geographic - (root node is GEOGCS). - """ - return bool(capi.isgeographic(self.ptr)) - - @property - def local(self): - "Returns True if this SpatialReference is local (root node is LOCAL_CS)." - return bool(capi.islocal(self.ptr)) - - @property - def projected(self): - """ - Returns True if this SpatialReference is a projected coordinate system - (root node is PROJCS). - """ - return bool(capi.isprojected(self.ptr)) - - #### Import Routines ##### - def import_epsg(self, epsg): - "Imports the Spatial Reference from the EPSG code (an integer)." - capi.from_epsg(self.ptr, epsg) - - def import_proj(self, proj): - "Imports the Spatial Reference from a PROJ.4 string." - capi.from_proj(self.ptr, proj) - - def import_user_input(self, user_input): - "Imports the Spatial Reference from the given user input string." - capi.from_user_input(self.ptr, user_input) - - def import_wkt(self, wkt): - "Imports the Spatial Reference from OGC WKT (string)" - capi.from_wkt(self.ptr, byref(c_char_p(wkt))) - - def import_xml(self, xml): - "Imports the Spatial Reference from an XML string." - capi.from_xml(self.ptr, xml) - - #### Export Properties #### - @property - def wkt(self): - "Returns the WKT representation of this Spatial Reference." - return capi.to_wkt(self.ptr, byref(c_char_p())) - - @property - def pretty_wkt(self, simplify=0): - "Returns the 'pretty' representation of the WKT." - return capi.to_pretty_wkt(self.ptr, byref(c_char_p()), simplify) - - @property - def proj(self): - "Returns the PROJ.4 representation for this Spatial Reference." - return capi.to_proj(self.ptr, byref(c_char_p())) - - @property - def proj4(self): - "Alias for proj()." - return self.proj - - @property - def xml(self, dialect=''): - "Returns the XML representation of this Spatial Reference." - return capi.to_xml(self.ptr, byref(c_char_p()), dialect) - -class CoordTransform(GDALBase): - "The coordinate system transformation object." - - def __init__(self, source, target): - "Initializes on a source and target SpatialReference objects." - if not isinstance(source, SpatialReference) or not isinstance(target, SpatialReference): - raise TypeError('source and target must be of type SpatialReference') - self.ptr = capi.new_ct(source._ptr, target._ptr) - self._srs1_name = source.name - self._srs2_name = target.name - - def __del__(self): - "Deletes this Coordinate Transformation object." - if self._ptr: capi.destroy_ct(self._ptr) - - def __str__(self): - return 'Transform from "%s" to "%s"' % (self._srs1_name, self._srs2_name) diff --git a/parts/django/django/contrib/gis/gdal/tests/__init__.py b/parts/django/django/contrib/gis/gdal/tests/__init__.py deleted file mode 100644 index aada5f4..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Module for executing all of the GDAL tests. None -of these tests require the use of the database. -""" -from unittest import TestSuite, TextTestRunner - -# Importing the GDAL test modules. -import test_driver, test_ds, test_envelope, test_geom, test_srs - -test_suites = [test_driver.suite(), - test_ds.suite(), - test_envelope.suite(), - test_geom.suite(), - test_srs.suite(), - ] - -def suite(): - "Builds a test suite for the GDAL tests." - s = TestSuite() - map(s.addTest, test_suites) - return s - -def run(verbosity=1): - "Runs the GDAL tests." - TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/gdal/tests/test_driver.py b/parts/django/django/contrib/gis/gdal/tests/test_driver.py deleted file mode 100644 index 1ff65ac..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/test_driver.py +++ /dev/null @@ -1,40 +0,0 @@ -import os, os.path, unittest -from django.contrib.gis.gdal import Driver, OGRException - -valid_drivers = ('ESRI Shapefile', 'MapInfo File', 'TIGER', 'S57', 'DGN', - 'Memory', 'CSV', 'GML', 'KML') - -invalid_drivers = ('Foo baz', 'clucka', 'ESRI Shp') - -aliases = {'eSrI' : 'ESRI Shapefile', - 'TigER/linE' : 'TIGER', - 'SHAPE' : 'ESRI Shapefile', - 'sHp' : 'ESRI Shapefile', - } - -class DriverTest(unittest.TestCase): - - def test01_valid_driver(self): - "Testing valid OGR Data Source Drivers." - for d in valid_drivers: - dr = Driver(d) - self.assertEqual(d, str(dr)) - - def test02_invalid_driver(self): - "Testing invalid OGR Data Source Drivers." - for i in invalid_drivers: - self.assertRaises(OGRException, Driver, i) - - def test03_aliases(self): - "Testing driver aliases." - for alias, full_name in aliases.items(): - dr = Driver(alias) - self.assertEqual(full_name, str(dr)) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(DriverTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/gdal/tests/test_ds.py b/parts/django/django/contrib/gis/gdal/tests/test_ds.py deleted file mode 100644 index e1083b2..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/test_ds.py +++ /dev/null @@ -1,226 +0,0 @@ -import os, os.path, unittest -from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError, GDAL_VERSION -from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString -from django.contrib.gis.geometry.test_data import get_ds_file, TestDS - -# List of acceptable data sources. -ds_list = (TestDS('test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='ESRI Shapefile', - fields={'dbl' : OFTReal, 'int' : OFTInteger, 'str' : OFTString,}, - extent=(-1.35011,0.166623,-0.524093,0.824508), # Got extent from QGIS - srs_wkt='GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]', - field_values={'dbl' : [float(i) for i in range(1, 6)], 'int' : range(1, 6), 'str' : [str(i) for i in range(1, 6)]}, - fids=range(5)), - TestDS('test_vrt', ext='vrt', nfeat=3, nfld=3, geom='POINT', gtype='Point25D', driver='VRT', - fields={'POINT_X' : OFTString, 'POINT_Y' : OFTString, 'NUM' : OFTString}, # VRT uses CSV, which all types are OFTString. - extent=(1.0, 2.0, 100.0, 523.5), # Min/Max from CSV - field_values={'POINT_X' : ['1.0', '5.0', '100.0'], 'POINT_Y' : ['2.0', '23.0', '523.5'], 'NUM' : ['5', '17', '23']}, - fids=range(1,4)), - TestDS('test_poly', nfeat=3, nfld=3, geom='POLYGON', gtype=3, - driver='ESRI Shapefile', - fields={'float' : OFTReal, 'int' : OFTInteger, 'str' : OFTString,}, - extent=(-1.01513,-0.558245,0.161876,0.839637), # Got extent from QGIS - srs_wkt='GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]'), - ) - -bad_ds = (TestDS('foo'), - ) - -class DataSourceTest(unittest.TestCase): - - def test01_valid_shp(self): - "Testing valid SHP Data Source files." - - for source in ds_list: - # Loading up the data source - ds = DataSource(source.ds) - - # Making sure the layer count is what's expected (only 1 layer in a SHP file) - self.assertEqual(1, len(ds)) - - # Making sure GetName works - self.assertEqual(source.ds, ds.name) - - # Making sure the driver name matches up - self.assertEqual(source.driver, str(ds.driver)) - - # Making sure indexing works - try: - ds[len(ds)] - except OGRIndexError: - pass - else: - self.fail('Expected an IndexError!') - - def test02_invalid_shp(self): - "Testing invalid SHP files for the Data Source." - for source in bad_ds: - self.assertRaises(OGRException, DataSource, source.ds) - - def test03a_layers(self): - "Testing Data Source Layers." - print "\nBEGIN - expecting out of range feature id error; safe to ignore.\n" - for source in ds_list: - ds = DataSource(source.ds) - - # Incrementing through each layer, this tests DataSource.__iter__ - for layer in ds: - # Making sure we get the number of features we expect - self.assertEqual(len(layer), source.nfeat) - - # Making sure we get the number of fields we expect - self.assertEqual(source.nfld, layer.num_fields) - self.assertEqual(source.nfld, len(layer.fields)) - - # Testing the layer's extent (an Envelope), and it's properties - if source.driver == 'VRT' and (GDAL_VERSION > (1, 7, 0) and GDAL_VERSION < (1, 7, 3)): - # There's a known GDAL regression with retrieving the extent - # of a VRT layer in versions 1.7.0-1.7.2: - # http://trac.osgeo.org/gdal/ticket/3783 - pass - else: - self.assertEqual(True, isinstance(layer.extent, Envelope)) - self.assertAlmostEqual(source.extent[0], layer.extent.min_x, 5) - self.assertAlmostEqual(source.extent[1], layer.extent.min_y, 5) - self.assertAlmostEqual(source.extent[2], layer.extent.max_x, 5) - self.assertAlmostEqual(source.extent[3], layer.extent.max_y, 5) - - # Now checking the field names. - flds = layer.fields - for f in flds: self.assertEqual(True, f in source.fields) - - # Negative FIDs are not allowed. - self.assertRaises(OGRIndexError, layer.__getitem__, -1) - self.assertRaises(OGRIndexError, layer.__getitem__, 50000) - - if hasattr(source, 'field_values'): - fld_names = source.field_values.keys() - - # Testing `Layer.get_fields` (which uses Layer.__iter__) - for fld_name in fld_names: - self.assertEqual(source.field_values[fld_name], layer.get_fields(fld_name)) - - # Testing `Layer.__getitem__`. - for i, fid in enumerate(source.fids): - feat = layer[fid] - self.assertEqual(fid, feat.fid) - # Maybe this should be in the test below, but we might as well test - # the feature values here while in this loop. - for fld_name in fld_names: - self.assertEqual(source.field_values[fld_name][i], feat.get(fld_name)) - print "\nEND - expecting out of range feature id error; safe to ignore." - - def test03b_layer_slice(self): - "Test indexing and slicing on Layers." - # Using the first data-source because the same slice - # can be used for both the layer and the control values. - source = ds_list[0] - ds = DataSource(source.ds) - - sl = slice(1, 3) - feats = ds[0][sl] - - for fld_name in ds[0].fields: - test_vals = [feat.get(fld_name) for feat in feats] - control_vals = source.field_values[fld_name][sl] - self.assertEqual(control_vals, test_vals) - - def test03c_layer_references(self): - "Test to make sure Layer access is still available without the DataSource." - source = ds_list[0] - - # See ticket #9448. - def get_layer(): - # This DataSource object is not accessible outside this - # scope. However, a reference should still be kept alive - # on the `Layer` returned. - ds = DataSource(source.ds) - return ds[0] - - # Making sure we can call OGR routines on the Layer returned. - lyr = get_layer() - self.assertEqual(source.nfeat, len(lyr)) - self.assertEqual(source.gtype, lyr.geom_type.num) - - def test04_features(self): - "Testing Data Source Features." - for source in ds_list: - ds = DataSource(source.ds) - - # Incrementing through each layer - for layer in ds: - # Incrementing through each feature in the layer - for feat in layer: - # Making sure the number of fields, and the geometry type - # are what's expected. - self.assertEqual(source.nfld, len(list(feat))) - self.assertEqual(source.gtype, feat.geom_type) - - # Making sure the fields match to an appropriate OFT type. - for k, v in source.fields.items(): - # Making sure we get the proper OGR Field instance, using - # a string value index for the feature. - self.assertEqual(True, isinstance(feat[k], v)) - - # Testing Feature.__iter__ - for fld in feat: self.assertEqual(True, fld.name in source.fields.keys()) - - def test05_geometries(self): - "Testing Geometries from Data Source Features." - for source in ds_list: - ds = DataSource(source.ds) - - # Incrementing through each layer and feature. - for layer in ds: - for feat in layer: - g = feat.geom - - # Making sure we get the right Geometry name & type - self.assertEqual(source.geom, g.geom_name) - self.assertEqual(source.gtype, g.geom_type) - - # Making sure the SpatialReference is as expected. - if hasattr(source, 'srs_wkt'): - self.assertEqual(source.srs_wkt, g.srs.wkt) - - def test06_spatial_filter(self): - "Testing the Layer.spatial_filter property." - ds = DataSource(get_ds_file('cities', 'shp')) - lyr = ds[0] - - # When not set, it should be None. - self.assertEqual(None, lyr.spatial_filter) - - # Must be set a/an OGRGeometry or 4-tuple. - self.assertRaises(TypeError, lyr._set_spatial_filter, 'foo') - - # Setting the spatial filter with a tuple/list with the extent of - # a buffer centering around Pueblo. - self.assertRaises(ValueError, lyr._set_spatial_filter, range(5)) - filter_extent = (-105.609252, 37.255001, -103.609252, 39.255001) - lyr.spatial_filter = (-105.609252, 37.255001, -103.609252, 39.255001) - self.assertEqual(OGRGeometry.from_bbox(filter_extent), lyr.spatial_filter) - feats = [feat for feat in lyr] - self.assertEqual(1, len(feats)) - self.assertEqual('Pueblo', feats[0].get('Name')) - - # Setting the spatial filter with an OGRGeometry for buffer centering - # around Houston. - filter_geom = OGRGeometry('POLYGON((-96.363151 28.763374,-94.363151 28.763374,-94.363151 30.763374,-96.363151 30.763374,-96.363151 28.763374))') - lyr.spatial_filter = filter_geom - self.assertEqual(filter_geom, lyr.spatial_filter) - feats = [feat for feat in lyr] - self.assertEqual(1, len(feats)) - self.assertEqual('Houston', feats[0].get('Name')) - - # Clearing the spatial filter by setting it to None. Now - # should indicate that there are 3 features in the Layer. - lyr.spatial_filter = None - self.assertEqual(3, len(lyr)) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(DataSourceTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/gdal/tests/test_envelope.py b/parts/django/django/contrib/gis/gdal/tests/test_envelope.py deleted file mode 100644 index f181fa2..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/test_envelope.py +++ /dev/null @@ -1,94 +0,0 @@ -import unittest -from django.contrib.gis.gdal import Envelope, OGRException - -class TestPoint(object): - def __init__(self, x, y): - self.x = x - self.y = y - -class EnvelopeTest(unittest.TestCase): - - def setUp(self): - self.e = Envelope(0, 0, 5, 5) - - def test01_init(self): - "Testing Envelope initilization." - e1 = Envelope((0, 0, 5, 5)) - e2 = Envelope(0, 0, 5, 5) - e3 = Envelope(0, '0', '5', 5) # Thanks to ww for this - e4 = Envelope(e1._envelope) - self.assertRaises(OGRException, Envelope, (5, 5, 0, 0)) - self.assertRaises(OGRException, Envelope, 5, 5, 0, 0) - self.assertRaises(OGRException, Envelope, (0, 0, 5, 5, 3)) - self.assertRaises(OGRException, Envelope, ()) - self.assertRaises(ValueError, Envelope, 0, 'a', 5, 5) - self.assertRaises(TypeError, Envelope, u'foo') - self.assertRaises(OGRException, Envelope, (1, 1, 0, 0)) - try: - Envelope(0, 0, 0, 0) - except OGRException: - self.fail("shouldn't raise an exception for min_x == max_x or min_y == max_y") - - def test02_properties(self): - "Testing Envelope properties." - e = Envelope(0, 0, 2, 3) - self.assertEqual(0, e.min_x) - self.assertEqual(0, e.min_y) - self.assertEqual(2, e.max_x) - self.assertEqual(3, e.max_y) - self.assertEqual((0, 0), e.ll) - self.assertEqual((2, 3), e.ur) - self.assertEqual((0, 0, 2, 3), e.tuple) - self.assertEqual('POLYGON((0.0 0.0,0.0 3.0,2.0 3.0,2.0 0.0,0.0 0.0))', e.wkt) - self.assertEqual('(0.0, 0.0, 2.0, 3.0)', str(e)) - - def test03_equivalence(self): - "Testing Envelope equivalence." - e1 = Envelope(0.523, 0.217, 253.23, 523.69) - e2 = Envelope((0.523, 0.217, 253.23, 523.69)) - self.assertEqual(e1, e2) - self.assertEqual((0.523, 0.217, 253.23, 523.69), e1) - - def test04_expand_to_include_pt_2_params(self): - "Testing Envelope expand_to_include -- point as two parameters." - self.e.expand_to_include(2, 6) - self.assertEqual((0, 0, 5, 6), self.e) - self.e.expand_to_include(-1, -1) - self.assertEqual((-1, -1, 5, 6), self.e) - - def test05_expand_to_include_pt_2_tuple(self): - "Testing Envelope expand_to_include -- point as a single 2-tuple parameter." - self.e.expand_to_include((10, 10)) - self.assertEqual((0, 0, 10, 10), self.e) - self.e.expand_to_include((-10, -10)) - self.assertEqual((-10, -10, 10, 10), self.e) - - def test06_expand_to_include_extent_4_params(self): - "Testing Envelope expand_to_include -- extent as 4 parameters." - self.e.expand_to_include(-1, 1, 3, 7) - self.assertEqual((-1, 0, 5, 7), self.e) - - def test06_expand_to_include_extent_4_tuple(self): - "Testing Envelope expand_to_include -- extent as a single 4-tuple parameter." - self.e.expand_to_include((-1, 1, 3, 7)) - self.assertEqual((-1, 0, 5, 7), self.e) - - def test07_expand_to_include_envelope(self): - "Testing Envelope expand_to_include with Envelope as parameter." - self.e.expand_to_include(Envelope(-1, 1, 3, 7)) - self.assertEqual((-1, 0, 5, 7), self.e) - - def test08_expand_to_include_point(self): - "Testing Envelope expand_to_include with Point as parameter." - self.e.expand_to_include(TestPoint(-1, 1)) - self.assertEqual((-1, 0, 5, 5), self.e) - self.e.expand_to_include(TestPoint(10, 10)) - self.assertEqual((-1, 0, 10, 10), self.e) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(EnvelopeTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/gdal/tests/test_geom.py b/parts/django/django/contrib/gis/gdal/tests/test_geom.py deleted file mode 100644 index f3d1ffb..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/test_geom.py +++ /dev/null @@ -1,490 +0,0 @@ -import unittest -from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, \ - OGRException, OGRIndexError, SpatialReference, CoordTransform, \ - gdal_version -from django.contrib.gis.geometry.test_data import TestDataMixin - -class OGRGeomTest(unittest.TestCase, TestDataMixin): - "This tests the OGR Geometry." - - def test00a_geomtype(self): - "Testing OGRGeomType object." - - # OGRGeomType should initialize on all these inputs. - try: - g = OGRGeomType(1) - g = OGRGeomType(7) - g = OGRGeomType('point') - g = OGRGeomType('GeometrycollectioN') - g = OGRGeomType('LINearrING') - g = OGRGeomType('Unknown') - except: - self.fail('Could not create an OGRGeomType object!') - - # Should throw TypeError on this input - self.assertRaises(OGRException, OGRGeomType, 23) - self.assertRaises(OGRException, OGRGeomType, 'fooD') - self.assertRaises(OGRException, OGRGeomType, 9) - - # Equivalence can take strings, ints, and other OGRGeomTypes - self.assertEqual(True, OGRGeomType(1) == OGRGeomType(1)) - self.assertEqual(True, OGRGeomType(7) == 'GeometryCollection') - self.assertEqual(True, OGRGeomType('point') == 'POINT') - self.assertEqual(False, OGRGeomType('point') == 2) - self.assertEqual(True, OGRGeomType('unknown') == 0) - self.assertEqual(True, OGRGeomType(6) == 'MULtiPolyGON') - self.assertEqual(False, OGRGeomType(1) != OGRGeomType('point')) - self.assertEqual(True, OGRGeomType('POINT') != OGRGeomType(6)) - - # Testing the Django field name equivalent property. - self.assertEqual('PointField', OGRGeomType('Point').django) - self.assertEqual('GeometryField', OGRGeomType('Unknown').django) - self.assertEqual(None, OGRGeomType('none').django) - - # 'Geometry' initialization implies an unknown geometry type. - gt = OGRGeomType('Geometry') - self.assertEqual(0, gt.num) - self.assertEqual('Unknown', gt.name) - - def test00b_geomtype_25d(self): - "Testing OGRGeomType object with 25D types." - wkb25bit = OGRGeomType.wkb25bit - self.failUnless(OGRGeomType(wkb25bit + 1) == 'Point25D') - self.failUnless(OGRGeomType('MultiLineString25D') == (5 + wkb25bit)) - self.assertEqual('GeometryCollectionField', OGRGeomType('GeometryCollection25D').django) - - def test01a_wkt(self): - "Testing WKT output." - for g in self.geometries.wkt_out: - geom = OGRGeometry(g.wkt) - self.assertEqual(g.wkt, geom.wkt) - - def test01a_ewkt(self): - "Testing EWKT input/output." - for ewkt_val in ('POINT (1 2 3)', 'LINEARRING (0 0,1 1,2 1,0 0)'): - # First with ewkt output when no SRID in EWKT - self.assertEqual(ewkt_val, OGRGeometry(ewkt_val).ewkt) - # No test consumption with an SRID specified. - ewkt_val = 'SRID=4326;%s' % ewkt_val - geom = OGRGeometry(ewkt_val) - self.assertEqual(ewkt_val, geom.ewkt) - self.assertEqual(4326, geom.srs.srid) - - def test01b_gml(self): - "Testing GML output." - for g in self.geometries.wkt_out: - geom = OGRGeometry(g.wkt) - self.assertEqual(g.gml, geom.gml) - - def test01c_hex(self): - "Testing HEX input/output." - for g in self.geometries.hex_wkt: - geom1 = OGRGeometry(g.wkt) - self.assertEqual(g.hex, geom1.hex) - # Constructing w/HEX - geom2 = OGRGeometry(g.hex) - self.assertEqual(geom1, geom2) - - def test01d_wkb(self): - "Testing WKB input/output." - from binascii import b2a_hex - for g in self.geometries.hex_wkt: - geom1 = OGRGeometry(g.wkt) - wkb = geom1.wkb - self.assertEqual(b2a_hex(wkb).upper(), g.hex) - # Constructing w/WKB. - geom2 = OGRGeometry(wkb) - self.assertEqual(geom1, geom2) - - def test01e_json(self): - "Testing GeoJSON input/output." - from django.contrib.gis.gdal.prototypes.geom import GEOJSON - if not GEOJSON: return - for g in self.geometries.json_geoms: - geom = OGRGeometry(g.wkt) - if not hasattr(g, 'not_equal'): - self.assertEqual(g.json, geom.json) - self.assertEqual(g.json, geom.geojson) - self.assertEqual(OGRGeometry(g.wkt), OGRGeometry(geom.json)) - - def test02_points(self): - "Testing Point objects." - - prev = OGRGeometry('POINT(0 0)') - for p in self.geometries.points: - if not hasattr(p, 'z'): # No 3D - pnt = OGRGeometry(p.wkt) - self.assertEqual(1, pnt.geom_type) - self.assertEqual('POINT', pnt.geom_name) - self.assertEqual(p.x, pnt.x) - self.assertEqual(p.y, pnt.y) - self.assertEqual((p.x, p.y), pnt.tuple) - - def test03_multipoints(self): - "Testing MultiPoint objects." - for mp in self.geometries.multipoints: - mgeom1 = OGRGeometry(mp.wkt) # First one from WKT - self.assertEqual(4, mgeom1.geom_type) - self.assertEqual('MULTIPOINT', mgeom1.geom_name) - mgeom2 = OGRGeometry('MULTIPOINT') # Creating empty multipoint - mgeom3 = OGRGeometry('MULTIPOINT') - for g in mgeom1: - mgeom2.add(g) # adding each point from the multipoints - mgeom3.add(g.wkt) # should take WKT as well - self.assertEqual(mgeom1, mgeom2) # they should equal - self.assertEqual(mgeom1, mgeom3) - self.assertEqual(mp.coords, mgeom2.coords) - self.assertEqual(mp.n_p, mgeom2.point_count) - - def test04_linestring(self): - "Testing LineString objects." - prev = OGRGeometry('POINT(0 0)') - for ls in self.geometries.linestrings: - linestr = OGRGeometry(ls.wkt) - self.assertEqual(2, linestr.geom_type) - self.assertEqual('LINESTRING', linestr.geom_name) - self.assertEqual(ls.n_p, linestr.point_count) - self.assertEqual(ls.coords, linestr.tuple) - self.assertEqual(True, linestr == OGRGeometry(ls.wkt)) - self.assertEqual(True, linestr != prev) - self.assertRaises(OGRIndexError, linestr.__getitem__, len(linestr)) - prev = linestr - - # Testing the x, y properties. - x = [tmpx for tmpx, tmpy in ls.coords] - y = [tmpy for tmpx, tmpy in ls.coords] - self.assertEqual(x, linestr.x) - self.assertEqual(y, linestr.y) - - def test05_multilinestring(self): - "Testing MultiLineString objects." - prev = OGRGeometry('POINT(0 0)') - for mls in self.geometries.multilinestrings: - mlinestr = OGRGeometry(mls.wkt) - self.assertEqual(5, mlinestr.geom_type) - self.assertEqual('MULTILINESTRING', mlinestr.geom_name) - self.assertEqual(mls.n_p, mlinestr.point_count) - self.assertEqual(mls.coords, mlinestr.tuple) - self.assertEqual(True, mlinestr == OGRGeometry(mls.wkt)) - self.assertEqual(True, mlinestr != prev) - prev = mlinestr - for ls in mlinestr: - self.assertEqual(2, ls.geom_type) - self.assertEqual('LINESTRING', ls.geom_name) - self.assertRaises(OGRIndexError, mlinestr.__getitem__, len(mlinestr)) - - def test06_linearring(self): - "Testing LinearRing objects." - prev = OGRGeometry('POINT(0 0)') - for rr in self.geometries.linearrings: - lr = OGRGeometry(rr.wkt) - #self.assertEqual(101, lr.geom_type.num) - self.assertEqual('LINEARRING', lr.geom_name) - self.assertEqual(rr.n_p, len(lr)) - self.assertEqual(True, lr == OGRGeometry(rr.wkt)) - self.assertEqual(True, lr != prev) - prev = lr - - def test07a_polygons(self): - "Testing Polygon objects." - - # Testing `from_bbox` class method - bbox = (-180,-90,180,90) - p = OGRGeometry.from_bbox( bbox ) - self.assertEqual(bbox, p.extent) - - prev = OGRGeometry('POINT(0 0)') - for p in self.geometries.polygons: - poly = OGRGeometry(p.wkt) - self.assertEqual(3, poly.geom_type) - self.assertEqual('POLYGON', poly.geom_name) - self.assertEqual(p.n_p, poly.point_count) - self.assertEqual(p.n_i + 1, len(poly)) - - # Testing area & centroid. - self.assertAlmostEqual(p.area, poly.area, 9) - x, y = poly.centroid.tuple - self.assertAlmostEqual(p.centroid[0], x, 9) - self.assertAlmostEqual(p.centroid[1], y, 9) - - # Testing equivalence - self.assertEqual(True, poly == OGRGeometry(p.wkt)) - self.assertEqual(True, poly != prev) - - if p.ext_ring_cs: - ring = poly[0] - self.assertEqual(p.ext_ring_cs, ring.tuple) - self.assertEqual(p.ext_ring_cs, poly[0].tuple) - self.assertEqual(len(p.ext_ring_cs), ring.point_count) - - for r in poly: - self.assertEqual('LINEARRING', r.geom_name) - - def test07b_closepolygons(self): - "Testing closing Polygon objects." - # Both rings in this geometry are not closed. - poly = OGRGeometry('POLYGON((0 0, 5 0, 5 5, 0 5), (1 1, 2 1, 2 2, 2 1))') - self.assertEqual(8, poly.point_count) - print "\nBEGIN - expecting IllegalArgumentException; safe to ignore.\n" - try: - c = poly.centroid - except OGRException: - # Should raise an OGR exception, rings are not closed - pass - else: - self.fail('Should have raised an OGRException!') - print "\nEND - expecting IllegalArgumentException; safe to ignore.\n" - - # Closing the rings -- doesn't work on GDAL versions 1.4.1 and below: - # http://trac.osgeo.org/gdal/ticket/1673 - major, minor1, minor2 = gdal_version().split('.') - if major == '1': - iminor1 = int(minor1) - if iminor1 < 4 or (iminor1 == 4 and minor2.startswith('1')): return - poly.close_rings() - self.assertEqual(10, poly.point_count) # Two closing points should've been added - self.assertEqual(OGRGeometry('POINT(2.5 2.5)'), poly.centroid) - - def test08_multipolygons(self): - "Testing MultiPolygon objects." - prev = OGRGeometry('POINT(0 0)') - for mp in self.geometries.multipolygons: - mpoly = OGRGeometry(mp.wkt) - self.assertEqual(6, mpoly.geom_type) - self.assertEqual('MULTIPOLYGON', mpoly.geom_name) - if mp.valid: - self.assertEqual(mp.n_p, mpoly.point_count) - self.assertEqual(mp.num_geom, len(mpoly)) - self.assertRaises(OGRIndexError, mpoly.__getitem__, len(mpoly)) - for p in mpoly: - self.assertEqual('POLYGON', p.geom_name) - self.assertEqual(3, p.geom_type) - self.assertEqual(mpoly.wkt, OGRGeometry(mp.wkt).wkt) - - def test09a_srs(self): - "Testing OGR Geometries with Spatial Reference objects." - for mp in self.geometries.multipolygons: - # Creating a geometry w/spatial reference - sr = SpatialReference('WGS84') - mpoly = OGRGeometry(mp.wkt, sr) - self.assertEqual(sr.wkt, mpoly.srs.wkt) - - # Ensuring that SRS is propagated to clones. - klone = mpoly.clone() - self.assertEqual(sr.wkt, klone.srs.wkt) - - # Ensuring all children geometries (polygons and their rings) all - # return the assigned spatial reference as well. - for poly in mpoly: - self.assertEqual(sr.wkt, poly.srs.wkt) - for ring in poly: - self.assertEqual(sr.wkt, ring.srs.wkt) - - # Ensuring SRS propagate in topological ops. - a = OGRGeometry(self.geometries.topology_geoms[0].wkt_a, sr) - b = OGRGeometry(self.geometries.topology_geoms[0].wkt_b, sr) - diff = a.difference(b) - union = a.union(b) - self.assertEqual(sr.wkt, diff.srs.wkt) - self.assertEqual(sr.srid, union.srs.srid) - - # Instantiating w/an integer SRID - mpoly = OGRGeometry(mp.wkt, 4326) - self.assertEqual(4326, mpoly.srid) - mpoly.srs = SpatialReference(4269) - self.assertEqual(4269, mpoly.srid) - self.assertEqual('NAD83', mpoly.srs.name) - - # Incrementing through the multipolyogn after the spatial reference - # has been re-assigned. - for poly in mpoly: - self.assertEqual(mpoly.srs.wkt, poly.srs.wkt) - poly.srs = 32140 - for ring in poly: - # Changing each ring in the polygon - self.assertEqual(32140, ring.srs.srid) - self.assertEqual('NAD83 / Texas South Central', ring.srs.name) - ring.srs = str(SpatialReference(4326)) # back to WGS84 - self.assertEqual(4326, ring.srs.srid) - - # Using the `srid` property. - ring.srid = 4322 - self.assertEqual('WGS 72', ring.srs.name) - self.assertEqual(4322, ring.srid) - - def test09b_srs_transform(self): - "Testing transform()." - orig = OGRGeometry('POINT (-104.609 38.255)', 4326) - trans = OGRGeometry('POINT (992385.4472045 481455.4944650)', 2774) - - # Using an srid, a SpatialReference object, and a CoordTransform object - # or transformations. - t1, t2, t3 = orig.clone(), orig.clone(), orig.clone() - t1.transform(trans.srid) - t2.transform(SpatialReference('EPSG:2774')) - ct = CoordTransform(SpatialReference('WGS84'), SpatialReference(2774)) - t3.transform(ct) - - # Testing use of the `clone` keyword. - k1 = orig.clone() - k2 = k1.transform(trans.srid, clone=True) - self.assertEqual(k1, orig) - self.assertNotEqual(k1, k2) - - prec = 3 - for p in (t1, t2, t3, k2): - self.assertAlmostEqual(trans.x, p.x, prec) - self.assertAlmostEqual(trans.y, p.y, prec) - - def test09c_transform_dim(self): - "Testing coordinate dimension is the same on transformed geometries." - ls_orig = OGRGeometry('LINESTRING(-104.609 38.255)', 4326) - ls_trans = OGRGeometry('LINESTRING(992385.4472045 481455.4944650)', 2774) - - prec = 3 - ls_orig.transform(ls_trans.srs) - # Making sure the coordinate dimension is still 2D. - self.assertEqual(2, ls_orig.coord_dim) - self.assertAlmostEqual(ls_trans.x[0], ls_orig.x[0], prec) - self.assertAlmostEqual(ls_trans.y[0], ls_orig.y[0], prec) - - def test10_difference(self): - "Testing difference()." - for i in xrange(len(self.geometries.topology_geoms)): - a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a) - b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b) - d1 = OGRGeometry(self.geometries.diff_geoms[i].wkt) - d2 = a.difference(b) - self.assertEqual(d1, d2) - self.assertEqual(d1, a - b) # __sub__ is difference operator - a -= b # testing __isub__ - self.assertEqual(d1, a) - - def test11_intersection(self): - "Testing intersects() and intersection()." - for i in xrange(len(self.geometries.topology_geoms)): - a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a) - b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b) - i1 = OGRGeometry(self.geometries.intersect_geoms[i].wkt) - self.assertEqual(True, a.intersects(b)) - i2 = a.intersection(b) - self.assertEqual(i1, i2) - self.assertEqual(i1, a & b) # __and__ is intersection operator - a &= b # testing __iand__ - self.assertEqual(i1, a) - - def test12_symdifference(self): - "Testing sym_difference()." - for i in xrange(len(self.geometries.topology_geoms)): - a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a) - b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b) - d1 = OGRGeometry(self.geometries.sdiff_geoms[i].wkt) - d2 = a.sym_difference(b) - self.assertEqual(d1, d2) - self.assertEqual(d1, a ^ b) # __xor__ is symmetric difference operator - a ^= b # testing __ixor__ - self.assertEqual(d1, a) - - def test13_union(self): - "Testing union()." - for i in xrange(len(self.geometries.topology_geoms)): - a = OGRGeometry(self.geometries.topology_geoms[i].wkt_a) - b = OGRGeometry(self.geometries.topology_geoms[i].wkt_b) - u1 = OGRGeometry(self.geometries.union_geoms[i].wkt) - u2 = a.union(b) - self.assertEqual(u1, u2) - self.assertEqual(u1, a | b) # __or__ is union operator - a |= b # testing __ior__ - self.assertEqual(u1, a) - - def test14_add(self): - "Testing GeometryCollection.add()." - # Can't insert a Point into a MultiPolygon. - mp = OGRGeometry('MultiPolygon') - pnt = OGRGeometry('POINT(5 23)') - self.assertRaises(OGRException, mp.add, pnt) - - # GeometryCollection.add may take an OGRGeometry (if another collection - # of the same type all child geoms will be added individually) or WKT. - for mp in self.geometries.multipolygons: - mpoly = OGRGeometry(mp.wkt) - mp1 = OGRGeometry('MultiPolygon') - mp2 = OGRGeometry('MultiPolygon') - mp3 = OGRGeometry('MultiPolygon') - - for poly in mpoly: - mp1.add(poly) # Adding a geometry at a time - mp2.add(poly.wkt) # Adding WKT - mp3.add(mpoly) # Adding a MultiPolygon's entire contents at once. - for tmp in (mp1, mp2, mp3): self.assertEqual(mpoly, tmp) - - def test15_extent(self): - "Testing `extent` property." - # The xmin, ymin, xmax, ymax of the MultiPoint should be returned. - mp = OGRGeometry('MULTIPOINT(5 23, 0 0, 10 50)') - self.assertEqual((0.0, 0.0, 10.0, 50.0), mp.extent) - # Testing on the 'real world' Polygon. - poly = OGRGeometry(self.geometries.polygons[3].wkt) - ring = poly.shell - x, y = ring.x, ring.y - xmin, ymin = min(x), min(y) - xmax, ymax = max(x), max(y) - self.assertEqual((xmin, ymin, xmax, ymax), poly.extent) - - def test16_25D(self): - "Testing 2.5D geometries." - pnt_25d = OGRGeometry('POINT(1 2 3)') - self.assertEqual('Point25D', pnt_25d.geom_type.name) - self.assertEqual(3.0, pnt_25d.z) - self.assertEqual(3, pnt_25d.coord_dim) - ls_25d = OGRGeometry('LINESTRING(1 1 1,2 2 2,3 3 3)') - self.assertEqual('LineString25D', ls_25d.geom_type.name) - self.assertEqual([1.0, 2.0, 3.0], ls_25d.z) - self.assertEqual(3, ls_25d.coord_dim) - - def test17_pickle(self): - "Testing pickle support." - import cPickle - g1 = OGRGeometry('LINESTRING(1 1 1,2 2 2,3 3 3)', 'WGS84') - g2 = cPickle.loads(cPickle.dumps(g1)) - self.assertEqual(g1, g2) - self.assertEqual(4326, g2.srs.srid) - self.assertEqual(g1.srs.wkt, g2.srs.wkt) - - def test18_ogrgeometry_transform_workaround(self): - "Testing coordinate dimensions on geometries after transformation." - # A bug in GDAL versions prior to 1.7 changes the coordinate - # dimension of a geometry after it has been transformed. - # This test ensures that the bug workarounds employed within - # `OGRGeometry.transform` indeed work. - wkt_2d = "MULTILINESTRING ((0 0,1 1,2 2))" - wkt_3d = "MULTILINESTRING ((0 0 0,1 1 1,2 2 2))" - srid = 4326 - - # For both the 2D and 3D MultiLineString, ensure _both_ the dimension - # of the collection and the component LineString have the expected - # coordinate dimension after transform. - geom = OGRGeometry(wkt_2d, srid) - geom.transform(srid) - self.assertEqual(2, geom.coord_dim) - self.assertEqual(2, geom[0].coord_dim) - self.assertEqual(wkt_2d, geom.wkt) - - geom = OGRGeometry(wkt_3d, srid) - geom.transform(srid) - self.assertEqual(3, geom.coord_dim) - self.assertEqual(3, geom[0].coord_dim) - self.assertEqual(wkt_3d, geom.wkt) - - def test19_equivalence_regression(self): - "Testing equivalence methods with non-OGRGeometry instances." - self.assertNotEqual(None, OGRGeometry('POINT(0 0)')) - self.assertEqual(False, OGRGeometry('LINESTRING(0 0, 1 1)') == 3) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(OGRGeomTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/gdal/tests/test_srs.py b/parts/django/django/contrib/gis/gdal/tests/test_srs.py deleted file mode 100644 index 2742c7a..0000000 --- a/parts/django/django/contrib/gis/gdal/tests/test_srs.py +++ /dev/null @@ -1,169 +0,0 @@ -import unittest -from django.contrib.gis.gdal import SpatialReference, CoordTransform, OGRException, SRSException - -class TestSRS: - def __init__(self, wkt, **kwargs): - self.wkt = wkt - for key, value in kwargs.items(): - setattr(self, key, value) - -# Some Spatial Reference examples -srlist = (TestSRS('GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', - proj='+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ', - epsg=4326, projected=False, geographic=True, local=False, - lin_name='unknown', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, - auth={'GEOGCS' : ('EPSG', '4326'), 'spheroid' : ('EPSG', '7030')}, - attr=(('DATUM', 'WGS_1984'), (('SPHEROID', 1), '6378137'),('primem|authority', 'EPSG'),), - ), - TestSRS('PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",30.28333333333333],PARAMETER["standard_parallel_2",28.38333333333333],PARAMETER["latitude_of_origin",27.83333333333333],PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],PARAMETER["false_northing",4000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32140"]]', - proj='+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=4000000 +ellps=GRS80 +datum=NAD83 +units=m +no_defs ', - epsg=32140, projected=True, geographic=False, local=False, - lin_name='metre', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, - auth={'PROJCS' : ('EPSG', '32140'), 'spheroid' : ('EPSG', '7019'), 'unit' : ('EPSG', '9001'),}, - attr=(('DATUM', 'North_American_Datum_1983'),(('SPHEROID', 2), '298.257222101'),('PROJECTION','Lambert_Conformal_Conic_2SP'),), - ), - TestSRS('PROJCS["NAD_1983_StatePlane_Texas_South_Central_FIPS_4204_Feet",GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["False_Easting",1968500.0],PARAMETER["False_Northing",13123333.33333333],PARAMETER["Central_Meridian",-99.0],PARAMETER["Standard_Parallel_1",28.38333333333333],PARAMETER["Standard_Parallel_2",30.28333333333334],PARAMETER["Latitude_Of_Origin",27.83333333333333],UNIT["Foot_US",0.3048006096012192]]', - proj='+proj=lcc +lat_1=28.38333333333333 +lat_2=30.28333333333334 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=3999999.999999999 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs ', - epsg=None, projected=True, geographic=False, local=False, - lin_name='Foot_US', ang_name='Degree', lin_units=0.3048006096012192, ang_units=0.0174532925199, - auth={'PROJCS' : (None, None),}, - attr=(('PROJCS|GeOgCs|spheroid', 'GRS_1980'),(('projcs', 9), 'UNIT'), (('projcs', 11), None),), - ), - # This is really ESRI format, not WKT -- but the import should work the same - TestSRS('LOCAL_CS["Non-Earth (Meter)",LOCAL_DATUM["Local Datum",0],UNIT["Meter",1.0],AXIS["X",EAST],AXIS["Y",NORTH]]', - esri=True, proj=None, epsg=None, projected=False, geographic=False, local=True, - lin_name='Meter', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, - attr=(('LOCAL_DATUM', 'Local Datum'), ('unit', 'Meter')), - ), - ) - -# Well-Known Names -well_known = (TestSRS('GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', wk='WGS84', name='WGS 84', attrs=(('GEOGCS|AUTHORITY', 1, '4326'), ('SPHEROID', 'WGS 84'))), - TestSRS('GEOGCS["WGS 72",DATUM["WGS_1972",SPHEROID["WGS 72",6378135,298.26,AUTHORITY["EPSG","7043"]],AUTHORITY["EPSG","6322"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4322"]]', wk='WGS72', name='WGS 72', attrs=(('GEOGCS|AUTHORITY', 1, '4322'), ('SPHEROID', 'WGS 72'))), - TestSRS('GEOGCS["NAD27",DATUM["North_American_Datum_1927",SPHEROID["Clarke 1866",6378206.4,294.9786982138982,AUTHORITY["EPSG","7008"]],AUTHORITY["EPSG","6267"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4267"]]', wk='NAD27', name='NAD27', attrs=(('GEOGCS|AUTHORITY', 1, '4267'), ('SPHEROID', 'Clarke 1866'))), - TestSRS('GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]]', wk='NAD83', name='NAD83', attrs=(('GEOGCS|AUTHORITY', 1, '4269'), ('SPHEROID', 'GRS 1980'))), - TestSRS('PROJCS["NZGD49 / Karamea Circuit",GEOGCS["NZGD49",DATUM["New_Zealand_Geodetic_Datum_1949",SPHEROID["International 1924",6378388,297,AUTHORITY["EPSG","7022"]],TOWGS84[59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993],AUTHORITY["EPSG","6272"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4272"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",-41.28991152777778],PARAMETER["central_meridian",172.1090281944444],PARAMETER["scale_factor",1],PARAMETER["false_easting",300000],PARAMETER["false_northing",700000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","27216"]]', wk='EPSG:27216', name='NZGD49 / Karamea Circuit', attrs=(('PROJECTION','Transverse_Mercator'), ('SPHEROID', 'International 1924'))), - ) - -bad_srlist = ('Foobar', 'OOJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",30.28333333333333],PARAMETER["standard_parallel_2",28.38333333333333],PARAMETER["latitude_of_origin",27.83333333333333],PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],PARAMETER["false_northing",4000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32140"]]',) - -class SpatialRefTest(unittest.TestCase): - - def test01_wkt(self): - "Testing initialization on valid OGC WKT." - for s in srlist: - srs = SpatialReference(s.wkt) - - def test02_bad_wkt(self): - "Testing initialization on invalid WKT." - for bad in bad_srlist: - try: - srs = SpatialReference(bad) - srs.validate() - except (SRSException, OGRException): - pass - else: - self.fail('Should not have initialized on bad WKT "%s"!') - - def test03_get_wkt(self): - "Testing getting the WKT." - for s in srlist: - srs = SpatialReference(s.wkt) - self.assertEqual(s.wkt, srs.wkt) - - def test04_proj(self): - "Test PROJ.4 import and export." - - for s in srlist: - if s.proj: - srs1 = SpatialReference(s.wkt) - srs2 = SpatialReference(s.proj) - self.assertEqual(srs1.proj, srs2.proj) - - def test05_epsg(self): - "Test EPSG import." - for s in srlist: - if s.epsg: - srs1 = SpatialReference(s.wkt) - srs2 = SpatialReference(s.epsg) - srs3 = SpatialReference(str(s.epsg)) - srs4 = SpatialReference('EPSG:%d' % s.epsg) - #self.assertEqual(srs1.wkt, srs2.wkt) - for srs in (srs1, srs2, srs3, srs4): - for attr, expected in s.attr: - self.assertEqual(expected, srs[attr]) - - def test07_boolean_props(self): - "Testing the boolean properties." - for s in srlist: - srs = SpatialReference(s.wkt) - self.assertEqual(s.projected, srs.projected) - self.assertEqual(s.geographic, srs.geographic) - - def test08_angular_linear(self): - "Testing the linear and angular units routines." - for s in srlist: - srs = SpatialReference(s.wkt) - self.assertEqual(s.ang_name, srs.angular_name) - self.assertEqual(s.lin_name, srs.linear_name) - self.assertAlmostEqual(s.ang_units, srs.angular_units, 9) - self.assertAlmostEqual(s.lin_units, srs.linear_units, 9) - - def test09_authority(self): - "Testing the authority name & code routines." - for s in srlist: - if hasattr(s, 'auth'): - srs = SpatialReference(s.wkt) - for target, tup in s.auth.items(): - self.assertEqual(tup[0], srs.auth_name(target)) - self.assertEqual(tup[1], srs.auth_code(target)) - - def test10_attributes(self): - "Testing the attribute retrieval routines." - for s in srlist: - srs = SpatialReference(s.wkt) - for tup in s.attr: - att = tup[0] # Attribute to test - exp = tup[1] # Expected result - self.assertEqual(exp, srs[att]) - - def test11_wellknown(self): - "Testing Well Known Names of Spatial References." - for s in well_known: - srs = SpatialReference(s.wk) - self.assertEqual(s.name, srs.name) - for tup in s.attrs: - if len(tup) == 2: - key = tup[0] - exp = tup[1] - elif len(tup) == 3: - key = tup[:2] - exp = tup[2] - self.assertEqual(srs[key], exp) - - def test12_coordtransform(self): - "Testing initialization of a CoordTransform." - target = SpatialReference('WGS84') - for s in srlist: - if s.proj: - ct = CoordTransform(SpatialReference(s.wkt), target) - - def test13_attr_value(self): - "Testing the attr_value() method." - s1 = SpatialReference('WGS84') - self.assertRaises(TypeError, s1.__getitem__, 0) - self.assertRaises(TypeError, s1.__getitem__, ('GEOGCS', 'foo')) - self.assertEqual('WGS 84', s1['GEOGCS']) - self.assertEqual('WGS_1984', s1['DATUM']) - self.assertEqual('EPSG', s1['AUTHORITY']) - self.assertEqual(4326, int(s1['AUTHORITY', 1])) - #for i in range(7): self.assertEqual(0, int(s1['TOWGS84', i])) - self.assertEqual(None, s1['FOOBAR']) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(SpatialRefTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/geometry/__init__.py b/parts/django/django/contrib/gis/geometry/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/geometry/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/geometry/backend/__init__.py b/parts/django/django/contrib/gis/geometry/backend/__init__.py deleted file mode 100644 index d79a556..0000000 --- a/parts/django/django/contrib/gis/geometry/backend/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.utils.importlib import import_module - -geom_backend = getattr(settings, 'GEOMETRY_BACKEND', 'geos') - -try: - module = import_module('.%s' % geom_backend, 'django.contrib.gis.geometry.backend') -except ImportError, e: - try: - module = import_module(geom_backend) - except ImportError, e_user: - raise ImproperlyConfigured('Could not import user-defined GEOMETRY_BACKEND ' - '"%s".' % geom_backend) - -try: - Geometry = module.Geometry - GeometryException = module.GeometryException -except AttributeError: - raise ImproperlyConfigured('Cannot import Geometry from the "%s" ' - 'geometry backend.' % geom_backend) diff --git a/parts/django/django/contrib/gis/geometry/backend/geos.py b/parts/django/django/contrib/gis/geometry/backend/geos.py deleted file mode 100644 index a1ac096..0000000 --- a/parts/django/django/contrib/gis/geometry/backend/geos.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib.gis.geos import \ - GEOSGeometry as Geometry, \ - GEOSException as GeometryException diff --git a/parts/django/django/contrib/gis/geometry/regex.py b/parts/django/django/contrib/gis/geometry/regex.py deleted file mode 100644 index 1b9e2f4..0000000 --- a/parts/django/django/contrib/gis/geometry/regex.py +++ /dev/null @@ -1,12 +0,0 @@ -import re - -# Regular expression for recognizing HEXEWKB and WKT. A prophylactic measure -# to prevent potentially malicious input from reaching the underlying C -# library. Not a substitute for good Web security programming practices. -hex_regex = re.compile(r'^[0-9A-F]+$', re.I) -wkt_regex = re.compile(r'^(SRID=(?P<srid>\d+);)?' - r'(?P<wkt>' - r'(?P<type>POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)' - r'[ACEGIMLONPSRUTYZ\d,\.\-\(\) ]+)$', - re.I) -json_regex = re.compile(r'^(\s+)?\{[\s\w,\[\]\{\}\-\."\':]+\}(\s+)?$') diff --git a/parts/django/django/contrib/gis/geometry/test_data.py b/parts/django/django/contrib/gis/geometry/test_data.py deleted file mode 100644 index 4e07348..0000000 --- a/parts/django/django/contrib/gis/geometry/test_data.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -This module has the mock object definitions used to hold reference geometry -for the GEOS and GDAL tests. -""" -import gzip -import os - -from django.contrib import gis -from django.utils import simplejson - - -# This global used to store reference geometry data. -GEOMETRIES = None - -# Path where reference test data is located. -TEST_DATA = os.path.join(os.path.dirname(gis.__file__), 'tests', 'data') - - -def tuplize(seq): - "Turn all nested sequences to tuples in given sequence." - if isinstance(seq, (list, tuple)): - return tuple([tuplize(i) for i in seq]) - return seq - - -def strconvert(d): - "Converts all keys in dictionary to str type." - return dict([(str(k), v) for k, v in d.iteritems()]) - - -def get_ds_file(name, ext): - return os.path.join(TEST_DATA, - name, - name + '.%s' % ext - ) - - -class TestObj(object): - """ - Base testing object, turns keyword args into attributes. - """ - def __init__(self, **kwargs): - for key, value in kwargs.items(): - setattr(self, key, value) - - -class TestDS(TestObj): - """ - Object for testing GDAL data sources. - """ - def __init__(self, name, **kwargs): - # Shapefile is default extension, unless specified otherwise. - ext = kwargs.pop('ext', 'shp') - self.ds = get_ds_file(name, ext) - super(TestDS, self).__init__(**kwargs) - - -class TestGeom(TestObj): - """ - Testing object used for wrapping reference geometry data - in GEOS/GDAL tests. - """ - def __init__(self, **kwargs): - # Converting lists to tuples of certain keyword args - # so coordinate test cases will match (JSON has no - # concept of tuple). - coords = kwargs.pop('coords', None) - if coords: - self.coords = tuplize(coords) - - centroid = kwargs.pop('centroid', None) - if centroid: - self.centroid = tuple(centroid) - - ext_ring_cs = kwargs.pop('ext_ring_cs', None) - if ext_ring_cs: - ext_ring_cs = tuplize(ext_ring_cs) - self.ext_ring_cs = ext_ring_cs - - super(TestGeom, self).__init__(**kwargs) - - -class TestGeomSet(object): - """ - Each attribute of this object is a list of `TestGeom` instances. - """ - def __init__(self, **kwargs): - for key, value in kwargs.items(): - setattr(self, key, [TestGeom(**strconvert(kw)) for kw in value]) - - -class TestDataMixin(object): - """ - Mixin used for GEOS/GDAL test cases that defines a `geometries` - property, which returns and/or loads the reference geometry data. - """ - @property - def geometries(self): - global GEOMETRIES - if GEOMETRIES is None: - # Load up the test geometry data from fixture into global. - gzf = gzip.GzipFile(os.path.join(TEST_DATA, 'geometries.json.gz')) - geometries = simplejson.loads(gzf.read()) - GEOMETRIES = TestGeomSet(**strconvert(geometries)) - return GEOMETRIES diff --git a/parts/django/django/contrib/gis/geos/LICENSE b/parts/django/django/contrib/gis/geos/LICENSE deleted file mode 100644 index 0479b07..0000000 --- a/parts/django/django/contrib/gis/geos/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2007-2009 Justin Bronn -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of GEOSGeometry nor the names of its contributors may be used - to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/parts/django/django/contrib/gis/geos/__init__.py b/parts/django/django/contrib/gis/geos/__init__.py deleted file mode 100644 index 5885a30..0000000 --- a/parts/django/django/contrib/gis/geos/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -The GeoDjango GEOS module. Please consult the GeoDjango documentation -for more details: - http://geodjango.org/docs/geos.html -""" -from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex -from django.contrib.gis.geos.point import Point -from django.contrib.gis.geos.linestring import LineString, LinearRing -from django.contrib.gis.geos.polygon import Polygon -from django.contrib.gis.geos.collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError -from django.contrib.gis.geos.io import WKTReader, WKTWriter, WKBReader, WKBWriter -from django.contrib.gis.geos.factory import fromfile, fromstr -from django.contrib.gis.geos.libgeos import geos_version, geos_version_info, GEOS_PREPARE diff --git a/parts/django/django/contrib/gis/geos/base.py b/parts/django/django/contrib/gis/geos/base.py deleted file mode 100644 index 34c03c8..0000000 --- a/parts/django/django/contrib/gis/geos/base.py +++ /dev/null @@ -1,52 +0,0 @@ -from ctypes import c_void_p -from types import NoneType -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError - -# Trying to import GDAL libraries, if available. Have to place in -# try/except since this package may be used outside GeoDjango. -try: - from django.contrib.gis import gdal -except ImportError: - # A 'dummy' gdal module. - class GDALInfo(object): - HAS_GDAL = False - GEOJSON = False - gdal = GDALInfo() - -# NumPy supported? -try: - import numpy -except ImportError: - numpy = False - -class GEOSBase(object): - """ - Base object for GEOS objects that has a pointer access property - that controls access to the underlying C pointer. - """ - # Initially the pointer is NULL. - _ptr = None - - # Default allowed pointer type. - ptr_type = c_void_p - - # Pointer access property. - def _get_ptr(self): - # Raise an exception if the pointer isn't valid don't - # want to be passing NULL pointers to routines -- - # that's very bad. - if self._ptr: return self._ptr - else: raise GEOSException('NULL GEOS %s pointer encountered.' % self.__class__.__name__) - - def _set_ptr(self, ptr): - # Only allow the pointer to be set with pointers of the - # compatible type or None (NULL). - if isinstance(ptr, (self.ptr_type, NoneType)): - self._ptr = ptr - else: - raise TypeError('Incompatible pointer type') - - # Property for controlling access to the GEOS object pointers. Using - # this raises an exception when the pointer is NULL, thus preventing - # the C library from attempting to access an invalid memory location. - ptr = property(_get_ptr, _set_ptr) diff --git a/parts/django/django/contrib/gis/geos/collections.py b/parts/django/django/contrib/gis/geos/collections.py deleted file mode 100644 index 515f80e..0000000 --- a/parts/django/django/contrib/gis/geos/collections.py +++ /dev/null @@ -1,123 +0,0 @@ -""" - This module houses the Geometry Collection objects: - GeometryCollection, MultiPoint, MultiLineString, and MultiPolygon -""" -from ctypes import c_int, c_uint, byref -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.libgeos import get_pointer_arr, GEOM_PTR, GEOS_PREPARE -from django.contrib.gis.geos.linestring import LineString, LinearRing -from django.contrib.gis.geos.point import Point -from django.contrib.gis.geos.polygon import Polygon -from django.contrib.gis.geos import prototypes as capi - -class GeometryCollection(GEOSGeometry): - _typeid = 7 - - def __init__(self, *args, **kwargs): - "Initializes a Geometry Collection from a sequence of Geometry objects." - - # Checking the arguments - if not args: - raise TypeError('Must provide at least one Geometry to initialize %s.' % self.__class__.__name__) - - if len(args) == 1: - # If only one geometry provided or a list of geometries is provided - # in the first argument. - if isinstance(args[0], (tuple, list)): - init_geoms = args[0] - else: - init_geoms = args - else: - init_geoms = args - - # Ensuring that only the permitted geometries are allowed in this collection - # this is moved to list mixin super class - self._check_allowed(init_geoms) - - # Creating the geometry pointer array. - collection = self._create_collection(len(init_geoms), iter(init_geoms)) - super(GeometryCollection, self).__init__(collection, **kwargs) - - def __iter__(self): - "Iterates over each Geometry in the Collection." - for i in xrange(len(self)): - yield self[i] - - def __len__(self): - "Returns the number of geometries in this Collection." - return self.num_geom - - ### Methods for compatibility with ListMixin ### - def _create_collection(self, length, items): - # Creating the geometry pointer array. - geoms = get_pointer_arr(length) - for i, g in enumerate(items): - # this is a little sloppy, but makes life easier - # allow GEOSGeometry types (python wrappers) or pointer types - geoms[i] = capi.geom_clone(getattr(g, 'ptr', g)) - - return capi.create_collection(c_int(self._typeid), byref(geoms), c_uint(length)) - - def _get_single_internal(self, index): - return capi.get_geomn(self.ptr, index) - - def _get_single_external(self, index): - "Returns the Geometry from this Collection at the given index (0-based)." - # Checking the index and returning the corresponding GEOS geometry. - return GEOSGeometry(capi.geom_clone(self._get_single_internal(index)), srid=self.srid) - - def _set_list(self, length, items): - "Create a new collection, and destroy the contents of the previous pointer." - prev_ptr = self.ptr - srid = self.srid - self.ptr = self._create_collection(length, items) - if srid: self.srid = srid - capi.destroy_geom(prev_ptr) - - _set_single = GEOSGeometry._set_single_rebuild - _assign_extended_slice = GEOSGeometry._assign_extended_slice_rebuild - - @property - def kml(self): - "Returns the KML for this Geometry Collection." - return '<MultiGeometry>%s</MultiGeometry>' % ''.join([g.kml for g in self]) - - @property - def tuple(self): - "Returns a tuple of all the coordinates in this Geometry Collection" - return tuple([g.tuple for g in self]) - coords = tuple - -# MultiPoint, MultiLineString, and MultiPolygon class definitions. -class MultiPoint(GeometryCollection): - _allowed = Point - _typeid = 4 - -class MultiLineString(GeometryCollection): - _allowed = (LineString, LinearRing) - _typeid = 5 - - @property - def merged(self): - """ - Returns a LineString representing the line merge of this - MultiLineString. - """ - return self._topology(capi.geos_linemerge(self.ptr)) - -class MultiPolygon(GeometryCollection): - _allowed = Polygon - _typeid = 6 - - @property - def cascaded_union(self): - "Returns a cascaded union of this MultiPolygon." - if GEOS_PREPARE: - return GEOSGeometry(capi.geos_cascaded_union(self.ptr), self.srid) - else: - raise GEOSException('The cascaded union operation requires GEOS 3.1+.') - -# Setting the allowed types here since GeometryCollection is defined before -# its subclasses. -GeometryCollection._allowed = (Point, LineString, LinearRing, Polygon, MultiPoint, MultiLineString, MultiPolygon) diff --git a/parts/django/django/contrib/gis/geos/coordseq.py b/parts/django/django/contrib/gis/geos/coordseq.py deleted file mode 100644 index 027d34e..0000000 --- a/parts/django/django/contrib/gis/geos/coordseq.py +++ /dev/null @@ -1,156 +0,0 @@ -""" - This module houses the GEOSCoordSeq object, which is used internally - by GEOSGeometry to house the actual coordinates of the Point, - LineString, and LinearRing geometries. -""" -from ctypes import c_double, c_uint, byref -from django.contrib.gis.geos.base import GEOSBase, numpy -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError -from django.contrib.gis.geos.libgeos import CS_PTR -from django.contrib.gis.geos import prototypes as capi - -class GEOSCoordSeq(GEOSBase): - "The internal representation of a list of coordinates inside a Geometry." - - ptr_type = CS_PTR - - #### Python 'magic' routines #### - def __init__(self, ptr, z=False): - "Initializes from a GEOS pointer." - if not isinstance(ptr, CS_PTR): - raise TypeError('Coordinate sequence should initialize with a CS_PTR.') - self._ptr = ptr - self._z = z - - def __iter__(self): - "Iterates over each point in the coordinate sequence." - for i in xrange(self.size): - yield self[i] - - def __len__(self): - "Returns the number of points in the coordinate sequence." - return int(self.size) - - def __str__(self): - "Returns the string representation of the coordinate sequence." - return str(self.tuple) - - def __getitem__(self, index): - "Returns the coordinate sequence value at the given index." - coords = [self.getX(index), self.getY(index)] - if self.dims == 3 and self._z: - coords.append(self.getZ(index)) - return tuple(coords) - - def __setitem__(self, index, value): - "Sets the coordinate sequence value at the given index." - # Checking the input value - if isinstance(value, (list, tuple)): - pass - elif numpy and isinstance(value, numpy.ndarray): - pass - else: - raise TypeError('Must set coordinate with a sequence (list, tuple, or numpy array).') - # Checking the dims of the input - if self.dims == 3 and self._z: - n_args = 3 - set_3d = True - else: - n_args = 2 - set_3d = False - if len(value) != n_args: - raise TypeError('Dimension of value does not match.') - # Setting the X, Y, Z - self.setX(index, value[0]) - self.setY(index, value[1]) - if set_3d: self.setZ(index, value[2]) - - #### Internal Routines #### - def _checkindex(self, index): - "Checks the given index." - sz = self.size - if (sz < 1) or (index < 0) or (index >= sz): - raise GEOSIndexError('invalid GEOS Geometry index: %s' % str(index)) - - def _checkdim(self, dim): - "Checks the given dimension." - if dim < 0 or dim > 2: - raise GEOSException('invalid ordinate dimension "%d"' % dim) - - #### Ordinate getting and setting routines #### - def getOrdinate(self, dimension, index): - "Returns the value for the given dimension and index." - self._checkindex(index) - self._checkdim(dimension) - return capi.cs_getordinate(self.ptr, index, dimension, byref(c_double())) - - def setOrdinate(self, dimension, index, value): - "Sets the value for the given dimension and index." - self._checkindex(index) - self._checkdim(dimension) - capi.cs_setordinate(self.ptr, index, dimension, value) - - def getX(self, index): - "Get the X value at the index." - return self.getOrdinate(0, index) - - def setX(self, index, value): - "Set X with the value at the given index." - self.setOrdinate(0, index, value) - - def getY(self, index): - "Get the Y value at the given index." - return self.getOrdinate(1, index) - - def setY(self, index, value): - "Set Y with the value at the given index." - self.setOrdinate(1, index, value) - - def getZ(self, index): - "Get Z with the value at the given index." - return self.getOrdinate(2, index) - - def setZ(self, index, value): - "Set Z with the value at the given index." - self.setOrdinate(2, index, value) - - ### Dimensions ### - @property - def size(self): - "Returns the size of this coordinate sequence." - return capi.cs_getsize(self.ptr, byref(c_uint())) - - @property - def dims(self): - "Returns the dimensions of this coordinate sequence." - return capi.cs_getdims(self.ptr, byref(c_uint())) - - @property - def hasz(self): - """ - Returns whether this coordinate sequence is 3D. This property value is - inherited from the parent Geometry. - """ - return self._z - - ### Other Methods ### - def clone(self): - "Clones this coordinate sequence." - return GEOSCoordSeq(capi.cs_clone(self.ptr), self.hasz) - - @property - def kml(self): - "Returns the KML representation for the coordinates." - # Getting the substitution string depending on whether the coordinates have - # a Z dimension. - if self.hasz: substr = '%s,%s,%s ' - else: substr = '%s,%s,0 ' - return '<coordinates>%s</coordinates>' % \ - ''.join([substr % self[i] for i in xrange(len(self))]).strip() - - @property - def tuple(self): - "Returns a tuple version of this coordinate sequence." - n = self.size - if n == 1: return self[0] - else: return tuple([self[i] for i in xrange(n)]) diff --git a/parts/django/django/contrib/gis/geos/error.py b/parts/django/django/contrib/gis/geos/error.py deleted file mode 100644 index 46bdfe6..0000000 --- a/parts/django/django/contrib/gis/geos/error.py +++ /dev/null @@ -1,20 +0,0 @@ -""" - This module houses the GEOS exceptions, specifically, GEOSException and - GEOSGeometryIndexError. -""" - -class GEOSException(Exception): - "The base GEOS exception, indicates a GEOS-related error." - pass - -class GEOSIndexError(GEOSException, KeyError): - """ - This exception is raised when an invalid index is encountered, and has - the 'silent_variable_feature' attribute set to true. This ensures that - django's templates proceed to use the next lookup type gracefully when - an Exception is raised. Fixes ticket #4740. - """ - # "If, during the method lookup, a method raises an exception, the exception - # will be propagated, unless the exception has an attribute - # `silent_variable_failure` whose value is True." -- Django template docs. - silent_variable_failure = True diff --git a/parts/django/django/contrib/gis/geos/factory.py b/parts/django/django/contrib/gis/geos/factory.py deleted file mode 100644 index df29976..0000000 --- a/parts/django/django/contrib/gis/geos/factory.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex - -def fromfile(file_h): - """ - Given a string file name, returns a GEOSGeometry. The file may contain WKB, - WKT, or HEX. - """ - # If given a file name, get a real handle. - if isinstance(file_h, basestring): - file_h = open(file_h, 'rb') - - # Reading in the file's contents, - buf = file_h.read() - - # If we get WKB need to wrap in buffer(), so run through regexes. - if wkt_regex.match(buf) or hex_regex.match(buf): - return GEOSGeometry(buf) - else: - return GEOSGeometry(buffer(buf)) - -def fromstr(string, **kwargs): - "Given a string value, returns a GEOSGeometry object." - return GEOSGeometry(string, **kwargs) diff --git a/parts/django/django/contrib/gis/geos/geometry.py b/parts/django/django/contrib/gis/geos/geometry.py deleted file mode 100644 index 51666bc..0000000 --- a/parts/django/django/contrib/gis/geos/geometry.py +++ /dev/null @@ -1,661 +0,0 @@ -""" - This module contains the 'base' GEOSGeometry object -- all GEOS Geometries - inherit from this object. -""" -# Python, ctypes and types dependencies. -import re -from ctypes import addressof, byref, c_double, c_size_t - -# super-class for mutable list behavior -from django.contrib.gis.geos.mutable_list import ListMixin - -# GEOS-related dependencies. -from django.contrib.gis.geos.base import GEOSBase, gdal -from django.contrib.gis.geos.coordseq import GEOSCoordSeq -from django.contrib.gis.geos.error import GEOSException, GEOSIndexError -from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE -from django.contrib.gis.geos.mutable_list import ListMixin - -# All other functions in this module come from the ctypes -# prototypes module -- which handles all interaction with -# the underlying GEOS library. -from django.contrib.gis.geos import prototypes as capi - -# These functions provide access to a thread-local instance -# of their corresponding GEOS I/O class. -from django.contrib.gis.geos.prototypes.io import wkt_r, wkt_w, wkb_r, wkb_w, ewkb_w, ewkb_w3d - -# For recognizing geometry input. -from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex - -class GEOSGeometry(GEOSBase, ListMixin): - "A class that, generally, encapsulates a GEOS geometry." - - # Raise GEOSIndexError instead of plain IndexError - # (see ticket #4740 and GEOSIndexError docstring) - _IndexError = GEOSIndexError - - ptr_type = GEOM_PTR - - #### Python 'magic' routines #### - def __init__(self, geo_input, srid=None): - """ - The base constructor for GEOS geometry objects, and may take the - following inputs: - - * strings: - - WKT - - HEXEWKB (a PostGIS-specific canonical form) - - GeoJSON (requires GDAL) - * buffer: - - WKB - - The `srid` keyword is used to specify the Source Reference Identifier - (SRID) number for this Geometry. If not set, the SRID will be None. - """ - if isinstance(geo_input, basestring): - if isinstance(geo_input, unicode): - # Encoding to ASCII, WKT or HEXEWKB doesn't need any more. - geo_input = geo_input.encode('ascii') - - wkt_m = wkt_regex.match(geo_input) - if wkt_m: - # Handling WKT input. - if wkt_m.group('srid'): srid = int(wkt_m.group('srid')) - g = wkt_r().read(wkt_m.group('wkt')) - elif hex_regex.match(geo_input): - # Handling HEXEWKB input. - g = wkb_r().read(geo_input) - elif gdal.GEOJSON and json_regex.match(geo_input): - # Handling GeoJSON input. - g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb) - else: - raise ValueError('String or unicode input unrecognized as WKT EWKT, and HEXEWKB.') - elif isinstance(geo_input, GEOM_PTR): - # When the input is a pointer to a geomtry (GEOM_PTR). - g = geo_input - elif isinstance(geo_input, buffer): - # When the input is a buffer (WKB). - g = wkb_r().read(geo_input) - elif isinstance(geo_input, GEOSGeometry): - g = capi.geom_clone(geo_input.ptr) - else: - # Invalid geometry type. - raise TypeError('Improper geometry input type: %s' % str(type(geo_input))) - - if bool(g): - # Setting the pointer object with a valid pointer. - self.ptr = g - else: - raise GEOSException('Could not initialize GEOS Geometry with given input.') - - # Post-initialization setup. - self._post_init(srid) - - def _post_init(self, srid): - "Helper routine for performing post-initialization setup." - # Setting the SRID, if given. - if srid and isinstance(srid, int): self.srid = srid - - # Setting the class type (e.g., Point, Polygon, etc.) - self.__class__ = GEOS_CLASSES[self.geom_typeid] - - # Setting the coordinate sequence for the geometry (will be None on - # geometries that do not have coordinate sequences) - self._set_cs() - - def __del__(self): - """ - Destroys this Geometry; in other words, frees the memory used by the - GEOS C++ object. - """ - if self._ptr: capi.destroy_geom(self._ptr) - - def __copy__(self): - """ - Returns a clone because the copy of a GEOSGeometry may contain an - invalid pointer location if the original is garbage collected. - """ - return self.clone() - - def __deepcopy__(self, memodict): - """ - The `deepcopy` routine is used by the `Node` class of django.utils.tree; - thus, the protocol routine needs to be implemented to return correct - copies (clones) of these GEOS objects, which use C pointers. - """ - return self.clone() - - def __str__(self): - "WKT is used for the string representation." - return self.wkt - - def __repr__(self): - "Short-hand representation because WKT may be very large." - return '<%s object at %s>' % (self.geom_type, hex(addressof(self.ptr))) - - # Pickling support - def __getstate__(self): - # The pickled state is simply a tuple of the WKB (in string form) - # and the SRID. - return str(self.wkb), self.srid - - def __setstate__(self, state): - # Instantiating from the tuple state that was pickled. - wkb, srid = state - ptr = wkb_r().read(buffer(wkb)) - if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.') - self.ptr = ptr - self._post_init(srid) - - # Comparison operators - def __eq__(self, other): - """ - Equivalence testing, a Geometry may be compared with another Geometry - or a WKT representation. - """ - if isinstance(other, basestring): - return self.wkt == other - elif isinstance(other, GEOSGeometry): - return self.equals_exact(other) - else: - return False - - def __ne__(self, other): - "The not equals operator." - return not (self == other) - - ### Geometry set-like operations ### - # Thanks to Sean Gillies for inspiration: - # http://lists.gispython.org/pipermail/community/2007-July/001034.html - # g = g1 | g2 - def __or__(self, other): - "Returns the union of this Geometry and the other." - return self.union(other) - - # g = g1 & g2 - def __and__(self, other): - "Returns the intersection of this Geometry and the other." - return self.intersection(other) - - # g = g1 - g2 - def __sub__(self, other): - "Return the difference this Geometry and the other." - return self.difference(other) - - # g = g1 ^ g2 - def __xor__(self, other): - "Return the symmetric difference of this Geometry and the other." - return self.sym_difference(other) - - #### Coordinate Sequence Routines #### - @property - def has_cs(self): - "Returns True if this Geometry has a coordinate sequence, False if not." - # Only these geometries are allowed to have coordinate sequences. - if isinstance(self, (Point, LineString, LinearRing)): - return True - else: - return False - - def _set_cs(self): - "Sets the coordinate sequence for this Geometry." - if self.has_cs: - self._cs = GEOSCoordSeq(capi.get_cs(self.ptr), self.hasz) - else: - self._cs = None - - @property - def coord_seq(self): - "Returns a clone of the coordinate sequence for this Geometry." - if self.has_cs: - return self._cs.clone() - - #### Geometry Info #### - @property - def geom_type(self): - "Returns a string representing the Geometry type, e.g. 'Polygon'" - return capi.geos_type(self.ptr) - - @property - def geom_typeid(self): - "Returns an integer representing the Geometry type." - return capi.geos_typeid(self.ptr) - - @property - def num_geom(self): - "Returns the number of geometries in the Geometry." - return capi.get_num_geoms(self.ptr) - - @property - def num_coords(self): - "Returns the number of coordinates in the Geometry." - return capi.get_num_coords(self.ptr) - - @property - def num_points(self): - "Returns the number points, or coordinates, in the Geometry." - return self.num_coords - - @property - def dims(self): - "Returns the dimension of this Geometry (0=point, 1=line, 2=surface)." - return capi.get_dims(self.ptr) - - def normalize(self): - "Converts this Geometry to normal form (or canonical form)." - return capi.geos_normalize(self.ptr) - - #### Unary predicates #### - @property - def empty(self): - """ - Returns a boolean indicating whether the set of points in this Geometry - are empty. - """ - return capi.geos_isempty(self.ptr) - - @property - def hasz(self): - "Returns whether the geometry has a 3D dimension." - return capi.geos_hasz(self.ptr) - - @property - def ring(self): - "Returns whether or not the geometry is a ring." - return capi.geos_isring(self.ptr) - - @property - def simple(self): - "Returns false if the Geometry not simple." - return capi.geos_issimple(self.ptr) - - @property - def valid(self): - "This property tests the validity of this Geometry." - return capi.geos_isvalid(self.ptr) - - #### Binary predicates. #### - def contains(self, other): - "Returns true if other.within(this) returns true." - return capi.geos_contains(self.ptr, other.ptr) - - def crosses(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is T*T****** (for a point and a curve,a point and an area or a line and - an area) 0******** (for two curves). - """ - return capi.geos_crosses(self.ptr, other.ptr) - - def disjoint(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is FF*FF****. - """ - return capi.geos_disjoint(self.ptr, other.ptr) - - def equals(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is T*F**FFF*. - """ - return capi.geos_equals(self.ptr, other.ptr) - - def equals_exact(self, other, tolerance=0): - """ - Returns true if the two Geometries are exactly equal, up to a - specified tolerance. - """ - return capi.geos_equalsexact(self.ptr, other.ptr, float(tolerance)) - - def intersects(self, other): - "Returns true if disjoint returns false." - return capi.geos_intersects(self.ptr, other.ptr) - - def overlaps(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is T*T***T** (for two points or two surfaces) 1*T***T** (for two curves). - """ - return capi.geos_overlaps(self.ptr, other.ptr) - - def relate_pattern(self, other, pattern): - """ - Returns true if the elements in the DE-9IM intersection matrix for the - two Geometries match the elements in pattern. - """ - if not isinstance(pattern, basestring) or len(pattern) > 9: - raise GEOSException('invalid intersection matrix pattern') - return capi.geos_relatepattern(self.ptr, other.ptr, pattern) - - def touches(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is FT*******, F**T***** or F***T****. - """ - return capi.geos_touches(self.ptr, other.ptr) - - def within(self, other): - """ - Returns true if the DE-9IM intersection matrix for the two Geometries - is T*F**F***. - """ - return capi.geos_within(self.ptr, other.ptr) - - #### SRID Routines #### - def get_srid(self): - "Gets the SRID for the geometry, returns None if no SRID is set." - s = capi.geos_get_srid(self.ptr) - if s == 0: return None - else: return s - - def set_srid(self, srid): - "Sets the SRID for the geometry." - capi.geos_set_srid(self.ptr, srid) - srid = property(get_srid, set_srid) - - #### Output Routines #### - @property - def ewkt(self): - """ - Returns the EWKT (WKT + SRID) of the Geometry. Note that Z values - are *not* included in this representation because GEOS does not yet - support serializing them. - """ - if self.get_srid(): return 'SRID=%s;%s' % (self.srid, self.wkt) - else: return self.wkt - - @property - def wkt(self): - "Returns the WKT (Well-Known Text) representation of this Geometry." - return wkt_w().write(self) - - @property - def hex(self): - """ - Returns the WKB of this Geometry in hexadecimal form. Please note - that the SRID and Z values are not included in this representation - because it is not a part of the OGC specification (use the `hexewkb` - property instead). - """ - # A possible faster, all-python, implementation: - # str(self.wkb).encode('hex') - return wkb_w().write_hex(self) - - @property - def hexewkb(self): - """ - Returns the EWKB of this Geometry in hexadecimal form. This is an - extension of the WKB specification that includes SRID and Z values - that are a part of this geometry. - """ - if self.hasz: - if not GEOS_PREPARE: - # See: http://trac.osgeo.org/geos/ticket/216 - raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D HEXEWKB.') - return ewkb_w3d().write_hex(self) - else: - return ewkb_w().write_hex(self) - - @property - def json(self): - """ - Returns GeoJSON representation of this Geometry if GDAL 1.5+ - is installed. - """ - if gdal.GEOJSON: - return self.ogr.json - else: - raise GEOSException('GeoJSON output only supported on GDAL 1.5+.') - geojson = json - - @property - def wkb(self): - """ - Returns the WKB (Well-Known Binary) representation of this Geometry - as a Python buffer. SRID and Z values are not included, use the - `ewkb` property instead. - """ - return wkb_w().write(self) - - @property - def ewkb(self): - """ - Return the EWKB representation of this Geometry as a Python buffer. - This is an extension of the WKB specification that includes any SRID - and Z values that are a part of this geometry. - """ - if self.hasz: - if not GEOS_PREPARE: - # See: http://trac.osgeo.org/geos/ticket/216 - raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D EWKB.') - return ewkb_w3d().write(self) - else: - return ewkb_w().write(self) - - @property - def kml(self): - "Returns the KML representation of this Geometry." - gtype = self.geom_type - return '<%s>%s</%s>' % (gtype, self.coord_seq.kml, gtype) - - @property - def prepared(self): - """ - Returns a PreparedGeometry corresponding to this geometry -- it is - optimized for the contains, intersects, and covers operations. - """ - if GEOS_PREPARE: - return PreparedGeometry(self) - else: - raise GEOSException('GEOS 3.1+ required for prepared geometry support.') - - #### GDAL-specific output routines #### - @property - def ogr(self): - "Returns the OGR Geometry for this Geometry." - if gdal.HAS_GDAL: - if self.srid: - return gdal.OGRGeometry(self.wkb, self.srid) - else: - return gdal.OGRGeometry(self.wkb) - else: - raise GEOSException('GDAL required to convert to an OGRGeometry.') - - @property - def srs(self): - "Returns the OSR SpatialReference for SRID of this Geometry." - if gdal.HAS_GDAL: - if self.srid: - return gdal.SpatialReference(self.srid) - else: - return None - else: - raise GEOSException('GDAL required to return a SpatialReference object.') - - @property - def crs(self): - "Alias for `srs` property." - return self.srs - - def transform(self, ct, clone=False): - """ - Requires GDAL. Transforms the geometry according to the given - transformation object, which may be an integer SRID, and WKT or - PROJ.4 string. By default, the geometry is transformed in-place and - nothing is returned. However if the `clone` keyword is set, then this - geometry will not be modified and a transformed clone will be returned - instead. - """ - srid = self.srid - if gdal.HAS_GDAL and srid: - # Creating an OGR Geometry, which is then transformed. - g = gdal.OGRGeometry(self.wkb, srid) - g.transform(ct) - # Getting a new GEOS pointer - ptr = wkb_r().read(g.wkb) - if clone: - # User wants a cloned transformed geometry returned. - return GEOSGeometry(ptr, srid=g.srid) - if ptr: - # Reassigning pointer, and performing post-initialization setup - # again due to the reassignment. - capi.destroy_geom(self.ptr) - self.ptr = ptr - self._post_init(g.srid) - else: - raise GEOSException('Transformed WKB was invalid.') - - #### Topology Routines #### - def _topology(self, gptr): - "Helper routine to return Geometry from the given pointer." - return GEOSGeometry(gptr, srid=self.srid) - - @property - def boundary(self): - "Returns the boundary as a newly allocated Geometry object." - return self._topology(capi.geos_boundary(self.ptr)) - - def buffer(self, width, quadsegs=8): - """ - Returns a geometry that represents all points whose distance from this - Geometry is less than or equal to distance. Calculations are in the - Spatial Reference System of this Geometry. The optional third parameter sets - the number of segment used to approximate a quarter circle (defaults to 8). - (Text from PostGIS documentation at ch. 6.1.3) - """ - return self._topology(capi.geos_buffer(self.ptr, width, quadsegs)) - - @property - def centroid(self): - """ - The centroid is equal to the centroid of the set of component Geometries - of highest dimension (since the lower-dimension geometries contribute zero - "weight" to the centroid). - """ - return self._topology(capi.geos_centroid(self.ptr)) - - @property - def convex_hull(self): - """ - Returns the smallest convex Polygon that contains all the points - in the Geometry. - """ - return self._topology(capi.geos_convexhull(self.ptr)) - - def difference(self, other): - """ - Returns a Geometry representing the points making up this Geometry - that do not make up other. - """ - return self._topology(capi.geos_difference(self.ptr, other.ptr)) - - @property - def envelope(self): - "Return the envelope for this geometry (a polygon)." - return self._topology(capi.geos_envelope(self.ptr)) - - def intersection(self, other): - "Returns a Geometry representing the points shared by this Geometry and other." - return self._topology(capi.geos_intersection(self.ptr, other.ptr)) - - @property - def point_on_surface(self): - "Computes an interior point of this Geometry." - return self._topology(capi.geos_pointonsurface(self.ptr)) - - def relate(self, other): - "Returns the DE-9IM intersection matrix for this Geometry and the other." - return capi.geos_relate(self.ptr, other.ptr) - - def simplify(self, tolerance=0.0, preserve_topology=False): - """ - Returns the Geometry, simplified using the Douglas-Peucker algorithm - to the specified tolerance (higher tolerance => less points). If no - tolerance provided, defaults to 0. - - By default, this function does not preserve topology - e.g. polygons can - be split, collapse to lines or disappear holes can be created or - disappear, and lines can cross. By specifying preserve_topology=True, - the result will have the same dimension and number of components as the - input. This is significantly slower. - """ - if preserve_topology: - return self._topology(capi.geos_preservesimplify(self.ptr, tolerance)) - else: - return self._topology(capi.geos_simplify(self.ptr, tolerance)) - - def sym_difference(self, other): - """ - Returns a set combining the points in this Geometry not in other, - and the points in other not in this Geometry. - """ - return self._topology(capi.geos_symdifference(self.ptr, other.ptr)) - - def union(self, other): - "Returns a Geometry representing all the points in this Geometry and other." - return self._topology(capi.geos_union(self.ptr, other.ptr)) - - #### Other Routines #### - @property - def area(self): - "Returns the area of the Geometry." - return capi.geos_area(self.ptr, byref(c_double())) - - def distance(self, other): - """ - Returns the distance between the closest points on this Geometry - and the other. Units will be in those of the coordinate system of - the Geometry. - """ - if not isinstance(other, GEOSGeometry): - raise TypeError('distance() works only on other GEOS Geometries.') - return capi.geos_distance(self.ptr, other.ptr, byref(c_double())) - - @property - def extent(self): - """ - Returns the extent of this geometry as a 4-tuple, consisting of - (xmin, ymin, xmax, ymax). - """ - env = self.envelope - if isinstance(env, Point): - xmin, ymin = env.tuple - xmax, ymax = xmin, ymin - else: - xmin, ymin = env[0][0] - xmax, ymax = env[0][2] - return (xmin, ymin, xmax, ymax) - - @property - def length(self): - """ - Returns the length of this Geometry (e.g., 0 for point, or the - circumfrence of a Polygon). - """ - return capi.geos_length(self.ptr, byref(c_double())) - - def clone(self): - "Clones this Geometry." - return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid) - -# Class mapping dictionary. Has to be at the end to avoid import -# conflicts with GEOSGeometry. -from django.contrib.gis.geos.linestring import LineString, LinearRing -from django.contrib.gis.geos.point import Point -from django.contrib.gis.geos.polygon import Polygon -from django.contrib.gis.geos.collections import GeometryCollection, MultiPoint, MultiLineString, MultiPolygon -GEOS_CLASSES = {0 : Point, - 1 : LineString, - 2 : LinearRing, - 3 : Polygon, - 4 : MultiPoint, - 5 : MultiLineString, - 6 : MultiPolygon, - 7 : GeometryCollection, - } - -# If supported, import the PreparedGeometry class. -if GEOS_PREPARE: - from django.contrib.gis.geos.prepared import PreparedGeometry diff --git a/parts/django/django/contrib/gis/geos/io.py b/parts/django/django/contrib/gis/geos/io.py deleted file mode 100644 index 54ba6b4..0000000 --- a/parts/django/django/contrib/gis/geos/io.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -Module that holds classes for performing I/O operations on GEOS geometry -objects. Specifically, this has Python implementations of WKB/WKT -reader and writer classes. -""" -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.prototypes.io import _WKTReader, _WKBReader, WKBWriter, WKTWriter - -# Public classes for (WKB|WKT)Reader, which return GEOSGeometry -class WKBReader(_WKBReader): - def read(self, wkb): - "Returns a GEOSGeometry for the given WKB buffer." - return GEOSGeometry(super(WKBReader, self).read(wkb)) - -class WKTReader(_WKTReader): - def read(self, wkt): - "Returns a GEOSGeometry for the given WKT string." - return GEOSGeometry(super(WKTReader, self).read(wkt)) - - diff --git a/parts/django/django/contrib/gis/geos/libgeos.py b/parts/django/django/contrib/gis/geos/libgeos.py deleted file mode 100644 index 84299a0..0000000 --- a/parts/django/django/contrib/gis/geos/libgeos.py +++ /dev/null @@ -1,141 +0,0 @@ -""" - This module houses the ctypes initialization procedures, as well - as the notice and error handler function callbacks (get called - when an error occurs in GEOS). - - This module also houses GEOS Pointer utilities, including - get_pointer_arr(), and GEOM_PTR. -""" -import os, re, sys -from ctypes import c_char_p, Structure, CDLL, CFUNCTYPE, POINTER -from ctypes.util import find_library -from django.contrib.gis.geos.error import GEOSException - -# Custom library path set? -try: - from django.conf import settings - lib_path = settings.GEOS_LIBRARY_PATH -except (AttributeError, EnvironmentError, ImportError): - lib_path = None - -# Setting the appropriate names for the GEOS-C library. -if lib_path: - lib_names = None -elif os.name == 'nt': - # Windows NT libraries - lib_names = ['libgeos_c-1'] -elif os.name == 'posix': - # *NIX libraries - lib_names = ['geos_c', 'GEOS'] -else: - raise ImportError('Unsupported OS "%s"' % os.name) - -# Using the ctypes `find_library` utility to find the path to the GEOS -# shared library. This is better than manually specifiying each library name -# and extension (e.g., libgeos_c.[so|so.1|dylib].). -if lib_names: - for lib_name in lib_names: - lib_path = find_library(lib_name) - if not lib_path is None: break - -# No GEOS library could be found. -if lib_path is None: - raise ImportError('Could not find the GEOS library (tried "%s"). ' - 'Try setting GEOS_LIBRARY_PATH in your settings.' % - '", "'.join(lib_names)) - -# Getting the GEOS C library. The C interface (CDLL) is used for -# both *NIX and Windows. -# See the GEOS C API source code for more details on the library function calls: -# http://geos.refractions.net/ro/doxygen_docs/html/geos__c_8h-source.html -lgeos = CDLL(lib_path) - -# The notice and error handler C function callback definitions. -# Supposed to mimic the GEOS message handler (C below): -# typedef void (*GEOSMessageHandler)(const char *fmt, ...); -NOTICEFUNC = CFUNCTYPE(None, c_char_p, c_char_p) -def notice_h(fmt, lst, output_h=sys.stdout): - try: - warn_msg = fmt % lst - except: - warn_msg = fmt - output_h.write('GEOS_NOTICE: %s\n' % warn_msg) -notice_h = NOTICEFUNC(notice_h) - -ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p) -def error_h(fmt, lst, output_h=sys.stderr): - try: - err_msg = fmt % lst - except: - err_msg = fmt - output_h.write('GEOS_ERROR: %s\n' % err_msg) -error_h = ERRORFUNC(error_h) - -#### GEOS Geometry C data structures, and utility functions. #### - -# Opaque GEOS geometry structures, used for GEOM_PTR and CS_PTR -class GEOSGeom_t(Structure): pass -class GEOSPrepGeom_t(Structure): pass -class GEOSCoordSeq_t(Structure): pass -class GEOSContextHandle_t(Structure): pass - -# Pointers to opaque GEOS geometry structures. -GEOM_PTR = POINTER(GEOSGeom_t) -PREPGEOM_PTR = POINTER(GEOSPrepGeom_t) -CS_PTR = POINTER(GEOSCoordSeq_t) -CONTEXT_PTR = POINTER(GEOSContextHandle_t) - -# Used specifically by the GEOSGeom_createPolygon and GEOSGeom_createCollection -# GEOS routines -def get_pointer_arr(n): - "Gets a ctypes pointer array (of length `n`) for GEOSGeom_t opaque pointer." - GeomArr = GEOM_PTR * n - return GeomArr() - -# Returns the string version of the GEOS library. Have to set the restype -# explicitly to c_char_p to ensure compatibility accross 32 and 64-bit platforms. -geos_version = lgeos.GEOSversion -geos_version.argtypes = None -geos_version.restype = c_char_p - -# Regular expression should be able to parse version strings such as -# '3.0.0rc4-CAPI-1.3.3', or '3.0.0-CAPI-1.4.1' -version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.(?P<subminor>\d+))(rc(?P<release_candidate>\d+))?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)$') -def geos_version_info(): - """ - Returns a dictionary containing the various version metadata parsed from - the GEOS version string, including the version number, whether the version - is a release candidate (and what number release candidate), and the C API - version. - """ - ver = geos_version() - m = version_regex.match(ver) - if not m: raise GEOSException('Could not parse version info string "%s"' % ver) - return dict((key, m.group(key)) for key in ('version', 'release_candidate', 'capi_version', 'major', 'minor', 'subminor')) - -# Version numbers and whether or not prepared geometry support is available. -_verinfo = geos_version_info() -GEOS_MAJOR_VERSION = int(_verinfo['major']) -GEOS_MINOR_VERSION = int(_verinfo['minor']) -GEOS_SUBMINOR_VERSION = int(_verinfo['subminor']) -del _verinfo -GEOS_VERSION = (GEOS_MAJOR_VERSION, GEOS_MINOR_VERSION, GEOS_SUBMINOR_VERSION) -GEOS_PREPARE = GEOS_VERSION >= (3, 1, 0) - -if GEOS_PREPARE: - # Here we set up the prototypes for the initGEOS_r and finishGEOS_r - # routines. These functions aren't actually called until they are - # attached to a GEOS context handle -- this actually occurs in - # geos/prototypes/threadsafe.py. - lgeos.initGEOS_r.restype = CONTEXT_PTR - lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] -else: - # When thread-safety isn't available, the initGEOS routine must be called - # first. This function takes the notice and error functions, defined - # as Python callbacks above, as parameters. Here is the C code that is - # wrapped: - # extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function, GEOSMessageHandler error_function); - lgeos.initGEOS(notice_h, error_h) - # Calling finishGEOS() upon exit of the interpreter. - import atexit - atexit.register(lgeos.finishGEOS) diff --git a/parts/django/django/contrib/gis/geos/linestring.py b/parts/django/django/contrib/gis/geos/linestring.py deleted file mode 100644 index ecf7741..0000000 --- a/parts/django/django/contrib/gis/geos/linestring.py +++ /dev/null @@ -1,152 +0,0 @@ -from django.contrib.gis.geos.base import numpy -from django.contrib.gis.geos.coordseq import GEOSCoordSeq -from django.contrib.gis.geos.error import GEOSException -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.point import Point -from django.contrib.gis.geos import prototypes as capi - -class LineString(GEOSGeometry): - _init_func = capi.create_linestring - _minlength = 2 - - #### Python 'magic' routines #### - def __init__(self, *args, **kwargs): - """ - Initializes on the given sequence -- may take lists, tuples, NumPy arrays - of X,Y pairs, or Point objects. If Point objects are used, ownership is - _not_ transferred to the LineString object. - - Examples: - ls = LineString((1, 1), (2, 2)) - ls = LineString([(1, 1), (2, 2)]) - ls = LineString(array([(1, 1), (2, 2)])) - ls = LineString(Point(1, 1), Point(2, 2)) - """ - # If only one argument provided, set the coords array appropriately - if len(args) == 1: coords = args[0] - else: coords = args - - if isinstance(coords, (tuple, list)): - # Getting the number of coords and the number of dimensions -- which - # must stay the same, e.g., no LineString((1, 2), (1, 2, 3)). - ncoords = len(coords) - if coords: ndim = len(coords[0]) - else: raise TypeError('Cannot initialize on empty sequence.') - self._checkdim(ndim) - # Incrementing through each of the coordinates and verifying - for i in xrange(1, ncoords): - if not isinstance(coords[i], (tuple, list, Point)): - raise TypeError('each coordinate should be a sequence (list or tuple)') - if len(coords[i]) != ndim: raise TypeError('Dimension mismatch.') - numpy_coords = False - elif numpy and isinstance(coords, numpy.ndarray): - shape = coords.shape # Using numpy's shape. - if len(shape) != 2: raise TypeError('Too many dimensions.') - self._checkdim(shape[1]) - ncoords = shape[0] - ndim = shape[1] - numpy_coords = True - else: - raise TypeError('Invalid initialization input for LineStrings.') - - # Creating a coordinate sequence object because it is easier to - # set the points using GEOSCoordSeq.__setitem__(). - cs = GEOSCoordSeq(capi.create_cs(ncoords, ndim), z=bool(ndim==3)) - - for i in xrange(ncoords): - if numpy_coords: cs[i] = coords[i,:] - elif isinstance(coords[i], Point): cs[i] = coords[i].tuple - else: cs[i] = coords[i] - - # If SRID was passed in with the keyword arguments - srid = kwargs.get('srid', None) - - # Calling the base geometry initialization with the returned pointer - # from the function. - super(LineString, self).__init__(self._init_func(cs.ptr), srid=srid) - - def __iter__(self): - "Allows iteration over this LineString." - for i in xrange(len(self)): - yield self[i] - - def __len__(self): - "Returns the number of points in this LineString." - return len(self._cs) - - def _get_single_external(self, index): - return self._cs[index] - - _get_single_internal = _get_single_external - - def _set_list(self, length, items): - ndim = self._cs.dims # - hasz = self._cs.hasz # I don't understand why these are different - - # create a new coordinate sequence and populate accordingly - cs = GEOSCoordSeq(capi.create_cs(length, ndim), z=hasz) - for i, c in enumerate(items): - cs[i] = c - - ptr = self._init_func(cs.ptr) - if ptr: - capi.destroy_geom(self.ptr) - self.ptr = ptr - self._post_init(self.srid) - else: - # can this happen? - raise GEOSException('Geometry resulting from slice deletion was invalid.') - - def _set_single(self, index, value): - self._checkindex(index) - self._cs[index] = value - - def _checkdim(self, dim): - if dim not in (2, 3): raise TypeError('Dimension mismatch.') - - #### Sequence Properties #### - @property - def tuple(self): - "Returns a tuple version of the geometry from the coordinate sequence." - return self._cs.tuple - coords = tuple - - def _listarr(self, func): - """ - Internal routine that returns a sequence (list) corresponding with - the given function. Will return a numpy array if possible. - """ - lst = [func(i) for i in xrange(len(self))] - if numpy: return numpy.array(lst) # ARRRR! - else: return lst - - @property - def array(self): - "Returns a numpy array for the LineString." - return self._listarr(self._cs.__getitem__) - - @property - def merged(self): - "Returns the line merge of this LineString." - return self._topology(capi.geos_linemerge(self.ptr)) - - @property - def x(self): - "Returns a list or numpy array of the X variable." - return self._listarr(self._cs.getX) - - @property - def y(self): - "Returns a list or numpy array of the Y variable." - return self._listarr(self._cs.getY) - - @property - def z(self): - "Returns a list or numpy array of the Z variable." - if not self.hasz: return None - else: return self._listarr(self._cs.getZ) - -# LinearRings are LineStrings used within Polygons. -class LinearRing(LineString): - _minLength = 4 - _init_func = capi.create_linearring diff --git a/parts/django/django/contrib/gis/geos/mutable_list.py b/parts/django/django/contrib/gis/geos/mutable_list.py deleted file mode 100644 index cc28147..0000000 --- a/parts/django/django/contrib/gis/geos/mutable_list.py +++ /dev/null @@ -1,309 +0,0 @@ -# Copyright (c) 2008-2009 Aryeh Leib Taurog, all rights reserved. -# Released under the New BSD license. -""" -This module contains a base type which provides list-style mutations -without specific data storage methods. - -See also http://www.aryehleib.com/MutableLists.html - -Author: Aryeh Leib Taurog. -""" -class ListMixin(object): - """ - A base class which provides complete list interface. - Derived classes must call ListMixin's __init__() function - and implement the following: - - function _get_single_external(self, i): - Return single item with index i for general use. - The index i will always satisfy 0 <= i < len(self). - - function _get_single_internal(self, i): - Same as above, but for use within the class [Optional] - Note that if _get_single_internal and _get_single_internal return - different types of objects, _set_list must distinguish - between the two and handle each appropriately. - - function _set_list(self, length, items): - Recreate the entire object. - - NOTE: items may be a generator which calls _get_single_internal. - Therefore, it is necessary to cache the values in a temporary: - temp = list(items) - before clobbering the original storage. - - function _set_single(self, i, value): - Set the single item at index i to value [Optional] - If left undefined, all mutations will result in rebuilding - the object using _set_list. - - function __len__(self): - Return the length - - int _minlength: - The minimum legal length [Optional] - - int _maxlength: - The maximum legal length [Optional] - - type or tuple _allowed: - A type or tuple of allowed item types [Optional] - - class _IndexError: - The type of exception to be raise on invalid index [Optional] - """ - - _minlength = 0 - _maxlength = None - _IndexError = IndexError - - ### Python initialization and special list interface methods ### - - def __init__(self, *args, **kwargs): - if not hasattr(self, '_get_single_internal'): - self._get_single_internal = self._get_single_external - - if not hasattr(self, '_set_single'): - self._set_single = self._set_single_rebuild - self._assign_extended_slice = self._assign_extended_slice_rebuild - - super(ListMixin, self).__init__(*args, **kwargs) - - def __getitem__(self, index): - "Get the item(s) at the specified index/slice." - if isinstance(index, slice): - return [self._get_single_external(i) for i in xrange(*index.indices(len(self)))] - else: - index = self._checkindex(index) - return self._get_single_external(index) - - def __delitem__(self, index): - "Delete the item(s) at the specified index/slice." - if not isinstance(index, (int, long, slice)): - raise TypeError("%s is not a legal index" % index) - - # calculate new length and dimensions - origLen = len(self) - if isinstance(index, (int, long)): - index = self._checkindex(index) - indexRange = [index] - else: - indexRange = range(*index.indices(origLen)) - - newLen = origLen - len(indexRange) - newItems = ( self._get_single_internal(i) - for i in xrange(origLen) - if i not in indexRange ) - - self._rebuild(newLen, newItems) - - def __setitem__(self, index, val): - "Set the item(s) at the specified index/slice." - if isinstance(index, slice): - self._set_slice(index, val) - else: - index = self._checkindex(index) - self._check_allowed((val,)) - self._set_single(index, val) - - def __iter__(self): - "Iterate over the items in the list" - for i in xrange(len(self)): - yield self[i] - - ### Special methods for arithmetic operations ### - def __add__(self, other): - 'add another list-like object' - return self.__class__(list(self) + list(other)) - - def __radd__(self, other): - 'add to another list-like object' - return other.__class__(list(other) + list(self)) - - def __iadd__(self, other): - 'add another list-like object to self' - self.extend(list(other)) - return self - - def __mul__(self, n): - 'multiply' - return self.__class__(list(self) * n) - - def __rmul__(self, n): - 'multiply' - return self.__class__(list(self) * n) - - def __imul__(self, n): - 'multiply' - if n <= 0: - del self[:] - else: - cache = list(self) - for i in range(n-1): - self.extend(cache) - return self - - def __cmp__(self, other): - 'cmp' - slen = len(self) - for i in range(slen): - try: - c = cmp(self[i], other[i]) - except IndexError: - # must be other is shorter - return 1 - else: - # elements not equal - if c: return c - - return cmp(slen, len(other)) - - ### Public list interface Methods ### - ## Non-mutating ## - def count(self, val): - "Standard list count method" - count = 0 - for i in self: - if val == i: count += 1 - return count - - def index(self, val): - "Standard list index method" - for i in xrange(0, len(self)): - if self[i] == val: return i - raise ValueError('%s not found in object' % str(val)) - - ## Mutating ## - def append(self, val): - "Standard list append method" - self[len(self):] = [val] - - def extend(self, vals): - "Standard list extend method" - self[len(self):] = vals - - def insert(self, index, val): - "Standard list insert method" - if not isinstance(index, (int, long)): - raise TypeError("%s is not a legal index" % index) - self[index:index] = [val] - - def pop(self, index=-1): - "Standard list pop method" - result = self[index] - del self[index] - return result - - def remove(self, val): - "Standard list remove method" - del self[self.index(val)] - - def reverse(self): - "Standard list reverse method" - self[:] = self[-1::-1] - - def sort(self, cmp=cmp, key=None, reverse=False): - "Standard list sort method" - if key: - temp = [(key(v),v) for v in self] - temp.sort(cmp=cmp, key=lambda x: x[0], reverse=reverse) - self[:] = [v[1] for v in temp] - else: - temp = list(self) - temp.sort(cmp=cmp, reverse=reverse) - self[:] = temp - - ### Private routines ### - def _rebuild(self, newLen, newItems): - if newLen < self._minlength: - raise ValueError('Must have at least %d items' % self._minlength) - if self._maxlength is not None and newLen > self._maxlength: - raise ValueError('Cannot have more than %d items' % self._maxlength) - - self._set_list(newLen, newItems) - - def _set_single_rebuild(self, index, value): - self._set_slice(slice(index, index + 1, 1), [value]) - - def _checkindex(self, index, correct=True): - length = len(self) - if 0 <= index < length: - return index - if correct and -length <= index < 0: - return index + length - raise self._IndexError('invalid index: %s' % str(index)) - - def _check_allowed(self, items): - if hasattr(self, '_allowed'): - if False in [isinstance(val, self._allowed) for val in items]: - raise TypeError('Invalid type encountered in the arguments.') - - def _set_slice(self, index, values): - "Assign values to a slice of the object" - try: - iter(values) - except TypeError: - raise TypeError('can only assign an iterable to a slice') - - self._check_allowed(values) - - origLen = len(self) - valueList = list(values) - start, stop, step = index.indices(origLen) - - # CAREFUL: index.step and step are not the same! - # step will never be None - if index.step is None: - self._assign_simple_slice(start, stop, valueList) - else: - self._assign_extended_slice(start, stop, step, valueList) - - def _assign_extended_slice_rebuild(self, start, stop, step, valueList): - 'Assign an extended slice by rebuilding entire list' - indexList = range(start, stop, step) - # extended slice, only allow assigning slice of same size - if len(valueList) != len(indexList): - raise ValueError('attempt to assign sequence of size %d ' - 'to extended slice of size %d' - % (len(valueList), len(indexList))) - - # we're not changing the length of the sequence - newLen = len(self) - newVals = dict(zip(indexList, valueList)) - def newItems(): - for i in xrange(newLen): - if i in newVals: - yield newVals[i] - else: - yield self._get_single_internal(i) - - self._rebuild(newLen, newItems()) - - def _assign_extended_slice(self, start, stop, step, valueList): - 'Assign an extended slice by re-assigning individual items' - indexList = range(start, stop, step) - # extended slice, only allow assigning slice of same size - if len(valueList) != len(indexList): - raise ValueError('attempt to assign sequence of size %d ' - 'to extended slice of size %d' - % (len(valueList), len(indexList))) - - for i, val in zip(indexList, valueList): - self._set_single(i, val) - - def _assign_simple_slice(self, start, stop, valueList): - 'Assign a simple slice; Can assign slice of any length' - origLen = len(self) - stop = max(start, stop) - newLen = origLen - stop + start + len(valueList) - def newItems(): - for i in xrange(origLen + 1): - if i == start: - for val in valueList: - yield val - - if i < origLen: - if i < start or i >= stop: - yield self._get_single_internal(i) - - self._rebuild(newLen, newItems()) diff --git a/parts/django/django/contrib/gis/geos/point.py b/parts/django/django/contrib/gis/geos/point.py deleted file mode 100644 index 5c00a93..0000000 --- a/parts/django/django/contrib/gis/geos/point.py +++ /dev/null @@ -1,135 +0,0 @@ -from ctypes import c_uint -from django.contrib.gis.geos.error import GEOSException -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos import prototypes as capi - -class Point(GEOSGeometry): - _minlength = 2 - _maxlength = 3 - - def __init__(self, x, y=None, z=None, srid=None): - """ - The Point object may be initialized with either a tuple, or individual - parameters. - - For Example: - >>> p = Point((5, 23)) # 2D point, passed in as a tuple - >>> p = Point(5, 23, 8) # 3D point, passed in with individual parameters - """ - if isinstance(x, (tuple, list)): - # Here a tuple or list was passed in under the `x` parameter. - ndim = len(x) - coords = x - elif isinstance(x, (int, float, long)) and isinstance(y, (int, float, long)): - # Here X, Y, and (optionally) Z were passed in individually, as parameters. - if isinstance(z, (int, float, long)): - ndim = 3 - coords = [x, y, z] - else: - ndim = 2 - coords = [x, y] - else: - raise TypeError('Invalid parameters given for Point initialization.') - - point = self._create_point(ndim, coords) - - # Initializing using the address returned from the GEOS - # createPoint factory. - super(Point, self).__init__(point, srid=srid) - - def _create_point(self, ndim, coords): - """ - Create a coordinate sequence, set X, Y, [Z], and create point - """ - if ndim < 2 or ndim > 3: - raise TypeError('Invalid point dimension: %s' % str(ndim)) - - cs = capi.create_cs(c_uint(1), c_uint(ndim)) - i = iter(coords) - capi.cs_setx(cs, 0, i.next()) - capi.cs_sety(cs, 0, i.next()) - if ndim == 3: capi.cs_setz(cs, 0, i.next()) - - return capi.create_point(cs) - - def _set_list(self, length, items): - ptr = self._create_point(length, items) - if ptr: - capi.destroy_geom(self.ptr) - self._ptr = ptr - self._set_cs() - else: - # can this happen? - raise GEOSException('Geometry resulting from slice deletion was invalid.') - - def _set_single(self, index, value): - self._cs.setOrdinate(index, 0, value) - - def __iter__(self): - "Allows iteration over coordinates of this Point." - for i in xrange(len(self)): - yield self[i] - - def __len__(self): - "Returns the number of dimensions for this Point (either 0, 2 or 3)." - if self.empty: return 0 - if self.hasz: return 3 - else: return 2 - - def _get_single_external(self, index): - if index == 0: - return self.x - elif index == 1: - return self.y - elif index == 2: - return self.z - - _get_single_internal = _get_single_external - - def get_x(self): - "Returns the X component of the Point." - return self._cs.getOrdinate(0, 0) - - def set_x(self, value): - "Sets the X component of the Point." - self._cs.setOrdinate(0, 0, value) - - def get_y(self): - "Returns the Y component of the Point." - return self._cs.getOrdinate(1, 0) - - def set_y(self, value): - "Sets the Y component of the Point." - self._cs.setOrdinate(1, 0, value) - - def get_z(self): - "Returns the Z component of the Point." - if self.hasz: - return self._cs.getOrdinate(2, 0) - else: - return None - - def set_z(self, value): - "Sets the Z component of the Point." - if self.hasz: - self._cs.setOrdinate(2, 0, value) - else: - raise GEOSException('Cannot set Z on 2D Point.') - - # X, Y, Z properties - x = property(get_x, set_x) - y = property(get_y, set_y) - z = property(get_z, set_z) - - ### Tuple setting and retrieval routines. ### - def get_coords(self): - "Returns a tuple of the point." - return self._cs.tuple - - def set_coords(self, tup): - "Sets the coordinates of the point with the given tuple." - self._cs[0] = tup - - # The tuple and coords properties - tuple = property(get_coords, set_coords) - coords = tuple diff --git a/parts/django/django/contrib/gis/geos/polygon.py b/parts/django/django/contrib/gis/geos/polygon.py deleted file mode 100644 index 92b2e4c..0000000 --- a/parts/django/django/contrib/gis/geos/polygon.py +++ /dev/null @@ -1,166 +0,0 @@ -from ctypes import c_uint, byref -from django.contrib.gis.geos.error import GEOSIndexError -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.libgeos import get_pointer_arr, GEOM_PTR -from django.contrib.gis.geos.linestring import LinearRing -from django.contrib.gis.geos import prototypes as capi - -class Polygon(GEOSGeometry): - _minlength = 1 - - def __init__(self, *args, **kwargs): - """ - Initializes on an exterior ring and a sequence of holes (both - instances may be either LinearRing instances, or a tuple/list - that may be constructed into a LinearRing). - - Examples of initialization, where shell, hole1, and hole2 are - valid LinearRing geometries: - >>> poly = Polygon(shell, hole1, hole2) - >>> poly = Polygon(shell, (hole1, hole2)) - - Example where a tuple parameters are used: - >>> poly = Polygon(((0, 0), (0, 10), (10, 10), (0, 10), (0, 0)), - ((4, 4), (4, 6), (6, 6), (6, 4), (4, 4))) - """ - if not args: - raise TypeError('Must provide at least one LinearRing, or a tuple, to initialize a Polygon.') - - # Getting the ext_ring and init_holes parameters from the argument list - ext_ring = args[0] - init_holes = args[1:] - n_holes = len(init_holes) - - # If initialized as Polygon(shell, (LinearRing, LinearRing)) [for backward-compatibility] - if n_holes == 1 and isinstance(init_holes[0], (tuple, list)): - if len(init_holes[0]) == 0: - init_holes = () - n_holes = 0 - elif isinstance(init_holes[0][0], LinearRing): - init_holes = init_holes[0] - n_holes = len(init_holes) - - polygon = self._create_polygon(n_holes + 1, (ext_ring,) + init_holes) - super(Polygon, self).__init__(polygon, **kwargs) - - def __iter__(self): - "Iterates over each ring in the polygon." - for i in xrange(len(self)): - yield self[i] - - def __len__(self): - "Returns the number of rings in this Polygon." - return self.num_interior_rings + 1 - - @classmethod - def from_bbox(cls, bbox): - "Constructs a Polygon from a bounding box (4-tuple)." - x0, y0, x1, y1 = bbox - return GEOSGeometry( 'POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % ( - x0, y0, x0, y1, x1, y1, x1, y0, x0, y0) ) - - ### These routines are needed for list-like operation w/ListMixin ### - def _create_polygon(self, length, items): - # Instantiate LinearRing objects if necessary, but don't clone them yet - # _construct_ring will throw a TypeError if a parameter isn't a valid ring - # If we cloned the pointers here, we wouldn't be able to clean up - # in case of error. - rings = [] - for r in items: - if isinstance(r, GEOM_PTR): - rings.append(r) - else: - rings.append(self._construct_ring(r)) - - shell = self._clone(rings.pop(0)) - - n_holes = length - 1 - if n_holes: - holes = get_pointer_arr(n_holes) - for i, r in enumerate(rings): - holes[i] = self._clone(r) - holes_param = byref(holes) - else: - holes_param = None - - return capi.create_polygon(shell, holes_param, c_uint(n_holes)) - - def _clone(self, g): - if isinstance(g, GEOM_PTR): - return capi.geom_clone(g) - else: - return capi.geom_clone(g.ptr) - - def _construct_ring(self, param, msg='Parameter must be a sequence of LinearRings or objects that can initialize to LinearRings'): - "Helper routine for trying to construct a ring from the given parameter." - if isinstance(param, LinearRing): return param - try: - ring = LinearRing(param) - return ring - except TypeError: - raise TypeError(msg) - - def _set_list(self, length, items): - # Getting the current pointer, replacing with the newly constructed - # geometry, and destroying the old geometry. - prev_ptr = self.ptr - srid = self.srid - self.ptr = self._create_polygon(length, items) - if srid: self.srid = srid - capi.destroy_geom(prev_ptr) - - def _get_single_internal(self, index): - """ - Returns the ring at the specified index. The first index, 0, will - always return the exterior ring. Indices > 0 will return the - interior ring at the given index (e.g., poly[1] and poly[2] would - return the first and second interior ring, respectively). - - CAREFUL: Internal/External are not the same as Interior/Exterior! - _get_single_internal returns a pointer from the existing geometries for use - internally by the object's methods. _get_single_external returns a clone - of the same geometry for use by external code. - """ - if index == 0: - return capi.get_extring(self.ptr) - else: - # Getting the interior ring, have to subtract 1 from the index. - return capi.get_intring(self.ptr, index-1) - - def _get_single_external(self, index): - return GEOSGeometry(capi.geom_clone(self._get_single_internal(index)), srid=self.srid) - - _set_single = GEOSGeometry._set_single_rebuild - _assign_extended_slice = GEOSGeometry._assign_extended_slice_rebuild - - #### Polygon Properties #### - @property - def num_interior_rings(self): - "Returns the number of interior rings." - # Getting the number of rings - return capi.get_nrings(self.ptr) - - def _get_ext_ring(self): - "Gets the exterior ring of the Polygon." - return self[0] - - def _set_ext_ring(self, ring): - "Sets the exterior ring of the Polygon." - self[0] = ring - - # Properties for the exterior ring/shell. - exterior_ring = property(_get_ext_ring, _set_ext_ring) - shell = exterior_ring - - @property - def tuple(self): - "Gets the tuple for each ring in this Polygon." - return tuple([self[i].tuple for i in xrange(len(self))]) - coords = tuple - - @property - def kml(self): - "Returns the KML representation of this Polygon." - inner_kml = ''.join(["<innerBoundaryIs>%s</innerBoundaryIs>" % self[i+1].kml - for i in xrange(self.num_interior_rings)]) - return "<Polygon><outerBoundaryIs>%s</outerBoundaryIs>%s</Polygon>" % (self[0].kml, inner_kml) diff --git a/parts/django/django/contrib/gis/geos/prepared.py b/parts/django/django/contrib/gis/geos/prepared.py deleted file mode 100644 index 68b812d..0000000 --- a/parts/django/django/contrib/gis/geos/prepared.py +++ /dev/null @@ -1,30 +0,0 @@ -from django.contrib.gis.geos.base import GEOSBase -from django.contrib.gis.geos.geometry import GEOSGeometry -from django.contrib.gis.geos.prototypes import prepared as capi - -class PreparedGeometry(GEOSBase): - """ - A geometry that is prepared for performing certain operations. - At the moment this includes the contains covers, and intersects - operations. - """ - ptr_type = capi.PREPGEOM_PTR - - def __init__(self, geom): - if not isinstance(geom, GEOSGeometry): raise TypeError - self.ptr = capi.geos_prepare(geom.ptr) - - def __del__(self): - if self._ptr: capi.prepared_destroy(self._ptr) - - def contains(self, other): - return capi.prepared_contains(self.ptr, other.ptr) - - def contains_properly(self, other): - return capi.prepared_contains_properly(self.ptr, other.ptr) - - def covers(self, other): - return capi.prepared_covers(self.ptr, other.ptr) - - def intersects(self, other): - return capi.prepared_intersects(self.ptr, other.ptr) diff --git a/parts/django/django/contrib/gis/geos/prototypes/__init__.py b/parts/django/django/contrib/gis/geos/prototypes/__init__.py deleted file mode 100644 index 2355928..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -""" - This module contains all of the GEOS ctypes function prototypes. Each - prototype handles the interaction between the GEOS library and Python - via ctypes. -""" - -# Coordinate sequence routines. -from django.contrib.gis.geos.prototypes.coordseq import create_cs, get_cs, \ - cs_clone, cs_getordinate, cs_setordinate, cs_getx, cs_gety, cs_getz, \ - cs_setx, cs_sety, cs_setz, cs_getsize, cs_getdims - -# Geometry routines. -from django.contrib.gis.geos.prototypes.geom import from_hex, from_wkb, from_wkt, \ - create_point, create_linestring, create_linearring, create_polygon, create_collection, \ - destroy_geom, get_extring, get_intring, get_nrings, get_geomn, geom_clone, \ - geos_normalize, geos_type, geos_typeid, geos_get_srid, geos_set_srid, \ - get_dims, get_num_coords, get_num_geoms, \ - to_hex, to_wkb, to_wkt - -# Miscellaneous routines. -from django.contrib.gis.geos.prototypes.misc import geos_area, geos_distance, geos_length - -# Predicates -from django.contrib.gis.geos.prototypes.predicates import geos_hasz, geos_isempty, \ - geos_isring, geos_issimple, geos_isvalid, geos_contains, geos_crosses, \ - geos_disjoint, geos_equals, geos_equalsexact, geos_intersects, \ - geos_intersects, geos_overlaps, geos_relatepattern, geos_touches, geos_within - -# Topology routines -from django.contrib.gis.geos.prototypes.topology import * diff --git a/parts/django/django/contrib/gis/geos/prototypes/coordseq.py b/parts/django/django/contrib/gis/geos/prototypes/coordseq.py deleted file mode 100644 index 68b9480..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/coordseq.py +++ /dev/null @@ -1,83 +0,0 @@ -from ctypes import c_double, c_int, c_uint, POINTER -from django.contrib.gis.geos.libgeos import GEOM_PTR, CS_PTR -from django.contrib.gis.geos.prototypes.errcheck import last_arg_byref, GEOSException -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -## Error-checking routines specific to coordinate sequences. ## -def check_cs_ptr(result, func, cargs): - "Error checking on routines that return Geometries." - if not result: - raise GEOSException('Error encountered checking Coordinate Sequence returned from GEOS C function "%s".' % func.__name__) - return result - -def check_cs_op(result, func, cargs): - "Checks the status code of a coordinate sequence operation." - if result == 0: - raise GEOSException('Could not set value on coordinate sequence') - else: - return result - -def check_cs_get(result, func, cargs): - "Checking the coordinate sequence retrieval." - check_cs_op(result, func, cargs) - # Object in by reference, return its value. - return last_arg_byref(cargs) - -## Coordinate sequence prototype generation functions. ## -def cs_int(func): - "For coordinate sequence routines that return an integer." - func.argtypes = [CS_PTR, POINTER(c_uint)] - func.restype = c_int - func.errcheck = check_cs_get - return func - -def cs_operation(func, ordinate=False, get=False): - "For coordinate sequence operations." - if get: - # Get routines get double parameter passed-in by reference. - func.errcheck = check_cs_get - dbl_param = POINTER(c_double) - else: - func.errcheck = check_cs_op - dbl_param = c_double - - if ordinate: - # Get/Set ordinate routines have an extra uint parameter. - func.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] - else: - func.argtypes = [CS_PTR, c_uint, dbl_param] - - func.restype = c_int - return func - -def cs_output(func, argtypes): - "For routines that return a coordinate sequence." - func.argtypes = argtypes - func.restype = CS_PTR - func.errcheck = check_cs_ptr - return func - -## Coordinate Sequence ctypes prototypes ## - -# Coordinate Sequence constructors & cloning. -cs_clone = cs_output(GEOSFunc('GEOSCoordSeq_clone'), [CS_PTR]) -create_cs = cs_output(GEOSFunc('GEOSCoordSeq_create'), [c_uint, c_uint]) -get_cs = cs_output(GEOSFunc('GEOSGeom_getCoordSeq'), [GEOM_PTR]) - -# Getting, setting ordinate -cs_getordinate = cs_operation(GEOSFunc('GEOSCoordSeq_getOrdinate'), ordinate=True, get=True) -cs_setordinate = cs_operation(GEOSFunc('GEOSCoordSeq_setOrdinate'), ordinate=True) - -# For getting, x, y, z -cs_getx = cs_operation(GEOSFunc('GEOSCoordSeq_getX'), get=True) -cs_gety = cs_operation(GEOSFunc('GEOSCoordSeq_getY'), get=True) -cs_getz = cs_operation(GEOSFunc('GEOSCoordSeq_getZ'), get=True) - -# For setting, x, y, z -cs_setx = cs_operation(GEOSFunc('GEOSCoordSeq_setX')) -cs_sety = cs_operation(GEOSFunc('GEOSCoordSeq_setY')) -cs_setz = cs_operation(GEOSFunc('GEOSCoordSeq_setZ')) - -# These routines return size & dimensions. -cs_getsize = cs_int(GEOSFunc('GEOSCoordSeq_getSize')) -cs_getdims = cs_int(GEOSFunc('GEOSCoordSeq_getDimensions')) diff --git a/parts/django/django/contrib/gis/geos/prototypes/errcheck.py b/parts/django/django/contrib/gis/geos/prototypes/errcheck.py deleted file mode 100644 index 97fcd21..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/errcheck.py +++ /dev/null @@ -1,95 +0,0 @@ -""" - Error checking functions for GEOS ctypes prototype functions. -""" -import os -from ctypes import c_void_p, string_at, CDLL -from django.contrib.gis.geos.error import GEOSException -from django.contrib.gis.geos.libgeos import GEOS_VERSION -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -# Getting the `free` routine used to free the memory allocated for -# string pointers returned by GEOS. -if GEOS_VERSION >= (3, 1, 1): - # In versions 3.1.1 and above, `GEOSFree` was added to the C API - # because `free` isn't always available on all platforms. - free = GEOSFunc('GEOSFree') - free.argtypes = [c_void_p] - free.restype = None -else: - # Getting the `free` routine from the C library of the platform. - if os.name == 'nt': - # On NT, use the MS C library. - libc = CDLL('msvcrt') - else: - # On POSIX platforms C library is obtained by passing None into `CDLL`. - libc = CDLL(None) - free = libc.free - -### ctypes error checking routines ### -def last_arg_byref(args): - "Returns the last C argument's value by reference." - return args[-1]._obj.value - -def check_dbl(result, func, cargs): - "Checks the status code and returns the double value passed in by reference." - # Checking the status code - if result != 1: return None - # Double passed in by reference, return its value. - return last_arg_byref(cargs) - -def check_geom(result, func, cargs): - "Error checking on routines that return Geometries." - if not result: - raise GEOSException('Error encountered checking Geometry returned from GEOS C function "%s".' % func.__name__) - return result - -def check_minus_one(result, func, cargs): - "Error checking on routines that should not return -1." - if result == -1: - raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__) - else: - return result - -def check_predicate(result, func, cargs): - "Error checking for unary/binary predicate functions." - val = ord(result) # getting the ordinal from the character - if val == 1: return True - elif val == 0: return False - else: - raise GEOSException('Error encountered on GEOS C predicate function "%s".' % func.__name__) - -def check_sized_string(result, func, cargs): - """ - Error checking for routines that return explicitly sized strings. - - This frees the memory allocated by GEOS at the result pointer. - """ - if not result: - raise GEOSException('Invalid string pointer returned by GEOS C function "%s"' % func.__name__) - # A c_size_t object is passed in by reference for the second - # argument on these routines, and its needed to determine the - # correct size. - s = string_at(result, last_arg_byref(cargs)) - # Freeing the memory allocated within GEOS - free(result) - return s - -def check_string(result, func, cargs): - """ - Error checking for routines that return strings. - - This frees the memory allocated by GEOS at the result pointer. - """ - if not result: raise GEOSException('Error encountered checking string return value in GEOS C function "%s".' % func.__name__) - # Getting the string value at the pointer address. - s = string_at(result) - # Freeing the memory allocated within GEOS - free(result) - return s - -def check_zero(result, func, cargs): - "Error checking on routines that should not return 0." - if result == 0: - raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__) - else: - return result diff --git a/parts/django/django/contrib/gis/geos/prototypes/geom.py b/parts/django/django/contrib/gis/geos/prototypes/geom.py deleted file mode 100644 index 03f9897..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/geom.py +++ /dev/null @@ -1,119 +0,0 @@ -from ctypes import c_char_p, c_int, c_size_t, c_ubyte, c_uint, POINTER -from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, PREPGEOM_PTR, GEOS_PREPARE -from django.contrib.gis.geos.prototypes.errcheck import \ - check_geom, check_minus_one, check_sized_string, check_string, check_zero -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -# This is the return type used by binary output (WKB, HEX) routines. -c_uchar_p = POINTER(c_ubyte) - -# We create a simple subclass of c_char_p here because when the response -# type is set to c_char_p, you get a _Python_ string and there's no way -# to access the string's address inside the error checking function. -# In other words, you can't free the memory allocated inside GEOS. Previously, -# the return type would just be omitted and the integer address would be -# used -- but this allows us to be specific in the function definition and -# keeps the reference so it may be free'd. -class geos_char_p(c_char_p): - pass - -### ctypes generation functions ### -def bin_constructor(func): - "Generates a prototype for binary construction (HEX, WKB) GEOS routines." - func.argtypes = [c_char_p, c_size_t] - func.restype = GEOM_PTR - func.errcheck = check_geom - return func - -# HEX & WKB output -def bin_output(func): - "Generates a prototype for the routines that return a a sized string." - func.argtypes = [GEOM_PTR, POINTER(c_size_t)] - func.errcheck = check_sized_string - func.restype = c_uchar_p - return func - -def geom_output(func, argtypes): - "For GEOS routines that return a geometry." - if argtypes: func.argtypes = argtypes - func.restype = GEOM_PTR - func.errcheck = check_geom - return func - -def geom_index(func): - "For GEOS routines that return geometries from an index." - return geom_output(func, [GEOM_PTR, c_int]) - -def int_from_geom(func, zero=False): - "Argument is a geometry, return type is an integer." - func.argtypes = [GEOM_PTR] - func.restype = c_int - if zero: - func.errcheck = check_zero - else: - func.errcheck = check_minus_one - return func - -def string_from_geom(func): - "Argument is a Geometry, return type is a string." - func.argtypes = [GEOM_PTR] - func.restype = geos_char_p - func.errcheck = check_string - return func - -### ctypes prototypes ### - -# Deprecated creation routines from WKB, HEX, WKT -from_hex = bin_constructor(GEOSFunc('GEOSGeomFromHEX_buf')) -from_wkb = bin_constructor(GEOSFunc('GEOSGeomFromWKB_buf')) -from_wkt = geom_output(GEOSFunc('GEOSGeomFromWKT'), [c_char_p]) - -# Deprecated output routines -to_hex = bin_output(GEOSFunc('GEOSGeomToHEX_buf')) -to_wkb = bin_output(GEOSFunc('GEOSGeomToWKB_buf')) -to_wkt = string_from_geom(GEOSFunc('GEOSGeomToWKT')) - -# The GEOS geometry type, typeid, num_coordites and number of geometries -geos_normalize = int_from_geom(GEOSFunc('GEOSNormalize')) -geos_type = string_from_geom(GEOSFunc('GEOSGeomType')) -geos_typeid = int_from_geom(GEOSFunc('GEOSGeomTypeId')) -get_dims = int_from_geom(GEOSFunc('GEOSGeom_getDimensions'), zero=True) -get_num_coords = int_from_geom(GEOSFunc('GEOSGetNumCoordinates')) -get_num_geoms = int_from_geom(GEOSFunc('GEOSGetNumGeometries')) - -# Geometry creation factories -create_point = geom_output(GEOSFunc('GEOSGeom_createPoint'), [CS_PTR]) -create_linestring = geom_output(GEOSFunc('GEOSGeom_createLineString'), [CS_PTR]) -create_linearring = geom_output(GEOSFunc('GEOSGeom_createLinearRing'), [CS_PTR]) - -# Polygon and collection creation routines are special and will not -# have their argument types defined. -create_polygon = geom_output(GEOSFunc('GEOSGeom_createPolygon'), None) -create_collection = geom_output(GEOSFunc('GEOSGeom_createCollection'), None) - -# Ring routines -get_extring = geom_output(GEOSFunc('GEOSGetExteriorRing'), [GEOM_PTR]) -get_intring = geom_index(GEOSFunc('GEOSGetInteriorRingN')) -get_nrings = int_from_geom(GEOSFunc('GEOSGetNumInteriorRings')) - -# Collection Routines -get_geomn = geom_index(GEOSFunc('GEOSGetGeometryN')) - -# Cloning -geom_clone = GEOSFunc('GEOSGeom_clone') -geom_clone.argtypes = [GEOM_PTR] -geom_clone.restype = GEOM_PTR - -# Destruction routine. -destroy_geom = GEOSFunc('GEOSGeom_destroy') -destroy_geom.argtypes = [GEOM_PTR] -destroy_geom.restype = None - -# SRID routines -geos_get_srid = GEOSFunc('GEOSGetSRID') -geos_get_srid.argtypes = [GEOM_PTR] -geos_get_srid.restype = c_int - -geos_set_srid = GEOSFunc('GEOSSetSRID') -geos_set_srid.argtypes = [GEOM_PTR, c_int] -geos_set_srid.restype = None diff --git a/parts/django/django/contrib/gis/geos/prototypes/io.py b/parts/django/django/contrib/gis/geos/prototypes/io.py deleted file mode 100644 index 5c0c8b5..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/io.py +++ /dev/null @@ -1,242 +0,0 @@ -import threading -from ctypes import byref, c_char_p, c_int, c_char, c_size_t, Structure, POINTER -from django.contrib.gis.geos.base import GEOSBase -from django.contrib.gis.geos.libgeos import GEOM_PTR -from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string, check_sized_string -from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -### The WKB/WKT Reader/Writer structures and pointers ### -class WKTReader_st(Structure): pass -class WKTWriter_st(Structure): pass -class WKBReader_st(Structure): pass -class WKBWriter_st(Structure): pass - -WKT_READ_PTR = POINTER(WKTReader_st) -WKT_WRITE_PTR = POINTER(WKTWriter_st) -WKB_READ_PTR = POINTER(WKBReader_st) -WKB_WRITE_PTR = POINTER(WKBReader_st) - -### WKTReader routines ### -wkt_reader_create = GEOSFunc('GEOSWKTReader_create') -wkt_reader_create.restype = WKT_READ_PTR - -wkt_reader_destroy = GEOSFunc('GEOSWKTReader_destroy') -wkt_reader_destroy.argtypes = [WKT_READ_PTR] - -wkt_reader_read = GEOSFunc('GEOSWKTReader_read') -wkt_reader_read.argtypes = [WKT_READ_PTR, c_char_p] -wkt_reader_read.restype = GEOM_PTR -wkt_reader_read.errcheck = check_geom - -### WKTWriter routines ### -wkt_writer_create = GEOSFunc('GEOSWKTWriter_create') -wkt_writer_create.restype = WKT_WRITE_PTR - -wkt_writer_destroy = GEOSFunc('GEOSWKTWriter_destroy') -wkt_writer_destroy.argtypes = [WKT_WRITE_PTR] - -wkt_writer_write = GEOSFunc('GEOSWKTWriter_write') -wkt_writer_write.argtypes = [WKT_WRITE_PTR, GEOM_PTR] -wkt_writer_write.restype = geos_char_p -wkt_writer_write.errcheck = check_string - -### WKBReader routines ### -wkb_reader_create = GEOSFunc('GEOSWKBReader_create') -wkb_reader_create.restype = WKB_READ_PTR - -wkb_reader_destroy = GEOSFunc('GEOSWKBReader_destroy') -wkb_reader_destroy.argtypes = [WKB_READ_PTR] - -def wkb_read_func(func): - # Although the function definitions take `const unsigned char *` - # as their parameter, we use c_char_p here so the function may - # take Python strings directly as parameters. Inside Python there - # is not a difference between signed and unsigned characters, so - # it is not a problem. - func.argtypes = [WKB_READ_PTR, c_char_p, c_size_t] - func.restype = GEOM_PTR - func.errcheck = check_geom - return func - -wkb_reader_read = wkb_read_func(GEOSFunc('GEOSWKBReader_read')) -wkb_reader_read_hex = wkb_read_func(GEOSFunc('GEOSWKBReader_readHEX')) - -### WKBWriter routines ### -wkb_writer_create = GEOSFunc('GEOSWKBWriter_create') -wkb_writer_create.restype = WKB_WRITE_PTR - -wkb_writer_destroy = GEOSFunc('GEOSWKBWriter_destroy') -wkb_writer_destroy.argtypes = [WKB_WRITE_PTR] - -# WKB Writing prototypes. -def wkb_write_func(func): - func.argtypes = [WKB_WRITE_PTR, GEOM_PTR, POINTER(c_size_t)] - func.restype = c_uchar_p - func.errcheck = check_sized_string - return func - -wkb_writer_write = wkb_write_func(GEOSFunc('GEOSWKBWriter_write')) -wkb_writer_write_hex = wkb_write_func(GEOSFunc('GEOSWKBWriter_writeHEX')) - -# WKBWriter property getter/setter prototypes. -def wkb_writer_get(func, restype=c_int): - func.argtypes = [WKB_WRITE_PTR] - func.restype = restype - return func - -def wkb_writer_set(func, argtype=c_int): - func.argtypes = [WKB_WRITE_PTR, argtype] - return func - -wkb_writer_get_byteorder = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getByteOrder')) -wkb_writer_set_byteorder = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setByteOrder')) -wkb_writer_get_outdim = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getOutputDimension')) -wkb_writer_set_outdim = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setOutputDimension')) -wkb_writer_get_include_srid = wkb_writer_get(GEOSFunc('GEOSWKBWriter_getIncludeSRID'), restype=c_char) -wkb_writer_set_include_srid = wkb_writer_set(GEOSFunc('GEOSWKBWriter_setIncludeSRID'), argtype=c_char) - -### Base I/O Class ### -class IOBase(GEOSBase): - "Base class for GEOS I/O objects." - def __init__(self): - # Getting the pointer with the constructor. - self.ptr = self._constructor() - - def __del__(self): - # Cleaning up with the appropriate destructor. - if self._ptr: self._destructor(self._ptr) - -### Base WKB/WKT Reading and Writing objects ### - -# Non-public WKB/WKT reader classes for internal use because -# their `read` methods return _pointers_ instead of GEOSGeometry -# objects. -class _WKTReader(IOBase): - _constructor = wkt_reader_create - _destructor = wkt_reader_destroy - ptr_type = WKT_READ_PTR - - def read(self, wkt): - if not isinstance(wkt, basestring): raise TypeError - return wkt_reader_read(self.ptr, wkt) - -class _WKBReader(IOBase): - _constructor = wkb_reader_create - _destructor = wkb_reader_destroy - ptr_type = WKB_READ_PTR - - def read(self, wkb): - "Returns a _pointer_ to C GEOS Geometry object from the given WKB." - if isinstance(wkb, buffer): - wkb_s = str(wkb) - return wkb_reader_read(self.ptr, wkb_s, len(wkb_s)) - elif isinstance(wkb, basestring): - return wkb_reader_read_hex(self.ptr, wkb, len(wkb)) - else: - raise TypeError - -### WKB/WKT Writer Classes ### -class WKTWriter(IOBase): - _constructor = wkt_writer_create - _destructor = wkt_writer_destroy - ptr_type = WKT_WRITE_PTR - - def write(self, geom): - "Returns the WKT representation of the given geometry." - return wkt_writer_write(self.ptr, geom.ptr) - -class WKBWriter(IOBase): - _constructor = wkb_writer_create - _destructor = wkb_writer_destroy - ptr_type = WKB_WRITE_PTR - - def write(self, geom): - "Returns the WKB representation of the given geometry." - return buffer(wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t()))) - - def write_hex(self, geom): - "Returns the HEXEWKB representation of the given geometry." - return wkb_writer_write_hex(self.ptr, geom.ptr, byref(c_size_t())) - - ### WKBWriter Properties ### - - # Property for getting/setting the byteorder. - def _get_byteorder(self): - return wkb_writer_get_byteorder(self.ptr) - - def _set_byteorder(self, order): - if not order in (0, 1): raise ValueError('Byte order parameter must be 0 (Big Endian) or 1 (Little Endian).') - wkb_writer_set_byteorder(self.ptr, order) - - byteorder = property(_get_byteorder, _set_byteorder) - - # Property for getting/setting the output dimension. - def _get_outdim(self): - return wkb_writer_get_outdim(self.ptr) - - def _set_outdim(self, new_dim): - if not new_dim in (2, 3): raise ValueError('WKB output dimension must be 2 or 3') - wkb_writer_set_outdim(self.ptr, new_dim) - - outdim = property(_get_outdim, _set_outdim) - - # Property for getting/setting the include srid flag. - def _get_include_srid(self): - return bool(ord(wkb_writer_get_include_srid(self.ptr))) - - def _set_include_srid(self, include): - if bool(include): flag = chr(1) - else: flag = chr(0) - wkb_writer_set_include_srid(self.ptr, flag) - - srid = property(_get_include_srid, _set_include_srid) - -# `ThreadLocalIO` object holds instances of the WKT and WKB reader/writer -# objects that are local to the thread. The `GEOSGeometry` internals -# access these instances by calling the module-level functions, defined -# below. -class ThreadLocalIO(threading.local): - wkt_r = None - wkt_w = None - wkb_r = None - wkb_w = None - ewkb_w = None - ewkb_w3d = None - -thread_context = ThreadLocalIO() - -# These module-level routines return the I/O object that is local to the -# the thread. If the I/O object does not exist yet it will be initialized. -def wkt_r(): - if not thread_context.wkt_r: - thread_context.wkt_r = _WKTReader() - return thread_context.wkt_r - -def wkt_w(): - if not thread_context.wkt_w: - thread_context.wkt_w = WKTWriter() - return thread_context.wkt_w - -def wkb_r(): - if not thread_context.wkb_r: - thread_context.wkb_r = _WKBReader() - return thread_context.wkb_r - -def wkb_w(): - if not thread_context.wkb_w: - thread_context.wkb_w = WKBWriter() - return thread_context.wkb_w - -def ewkb_w(): - if not thread_context.ewkb_w: - thread_context.ewkb_w = WKBWriter() - thread_context.ewkb_w.srid = True - return thread_context.ewkb_w - -def ewkb_w3d(): - if not thread_context.ewkb_w3d: - thread_context.ewkb_w3d = WKBWriter() - thread_context.ewkb_w3d.srid = True - thread_context.ewkb_w3d.outdim = 3 - return thread_context.ewkb_w3d diff --git a/parts/django/django/contrib/gis/geos/prototypes/misc.py b/parts/django/django/contrib/gis/geos/prototypes/misc.py deleted file mode 100644 index 5b3b658..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/misc.py +++ /dev/null @@ -1,28 +0,0 @@ -""" - This module is for the miscellaneous GEOS routines, particularly the - ones that return the area, distance, and length. -""" -from ctypes import c_int, c_double, POINTER -from django.contrib.gis.geos.libgeos import GEOM_PTR -from django.contrib.gis.geos.prototypes.errcheck import check_dbl -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -### ctypes generator function ### -def dbl_from_geom(func, num_geom=1): - """ - Argument is a Geometry, return type is double that is passed - in by reference as the last argument. - """ - argtypes = [GEOM_PTR for i in xrange(num_geom)] - argtypes += [POINTER(c_double)] - func.argtypes = argtypes - func.restype = c_int # Status code returned - func.errcheck = check_dbl - return func - -### ctypes prototypes ### - -# Area, distance, and length prototypes. -geos_area = dbl_from_geom(GEOSFunc('GEOSArea')) -geos_distance = dbl_from_geom(GEOSFunc('GEOSDistance'), num_geom=2) -geos_length = dbl_from_geom(GEOSFunc('GEOSLength')) diff --git a/parts/django/django/contrib/gis/geos/prototypes/predicates.py b/parts/django/django/contrib/gis/geos/prototypes/predicates.py deleted file mode 100644 index bf69bb1..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/predicates.py +++ /dev/null @@ -1,44 +0,0 @@ -""" - This module houses the GEOS ctypes prototype functions for the - unary and binary predicate operations on geometries. -""" -from ctypes import c_char, c_char_p, c_double -from django.contrib.gis.geos.libgeos import GEOM_PTR -from django.contrib.gis.geos.prototypes.errcheck import check_predicate -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -## Binary & unary predicate functions ## -def binary_predicate(func, *args): - "For GEOS binary predicate functions." - argtypes = [GEOM_PTR, GEOM_PTR] - if args: argtypes += args - func.argtypes = argtypes - func.restype = c_char - func.errcheck = check_predicate - return func - -def unary_predicate(func): - "For GEOS unary predicate functions." - func.argtypes = [GEOM_PTR] - func.restype = c_char - func.errcheck = check_predicate - return func - -## Unary Predicates ## -geos_hasz = unary_predicate(GEOSFunc('GEOSHasZ')) -geos_isempty = unary_predicate(GEOSFunc('GEOSisEmpty')) -geos_isring = unary_predicate(GEOSFunc('GEOSisRing')) -geos_issimple = unary_predicate(GEOSFunc('GEOSisSimple')) -geos_isvalid = unary_predicate(GEOSFunc('GEOSisValid')) - -## Binary Predicates ## -geos_contains = binary_predicate(GEOSFunc('GEOSContains')) -geos_crosses = binary_predicate(GEOSFunc('GEOSCrosses')) -geos_disjoint = binary_predicate(GEOSFunc('GEOSDisjoint')) -geos_equals = binary_predicate(GEOSFunc('GEOSEquals')) -geos_equalsexact = binary_predicate(GEOSFunc('GEOSEqualsExact'), c_double) -geos_intersects = binary_predicate(GEOSFunc('GEOSIntersects')) -geos_overlaps = binary_predicate(GEOSFunc('GEOSOverlaps')) -geos_relatepattern = binary_predicate(GEOSFunc('GEOSRelatePattern'), c_char_p) -geos_touches = binary_predicate(GEOSFunc('GEOSTouches')) -geos_within = binary_predicate(GEOSFunc('GEOSWithin')) diff --git a/parts/django/django/contrib/gis/geos/prototypes/prepared.py b/parts/django/django/contrib/gis/geos/prototypes/prepared.py deleted file mode 100644 index 7342d7d..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/prepared.py +++ /dev/null @@ -1,25 +0,0 @@ -from ctypes import c_char -from django.contrib.gis.geos.libgeos import GEOM_PTR, PREPGEOM_PTR -from django.contrib.gis.geos.prototypes.errcheck import check_predicate -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -# Prepared geometry constructor and destructors. -geos_prepare = GEOSFunc('GEOSPrepare') -geos_prepare.argtypes = [GEOM_PTR] -geos_prepare.restype = PREPGEOM_PTR - -prepared_destroy = GEOSFunc('GEOSPreparedGeom_destroy') -prepared_destroy.argtpes = [PREPGEOM_PTR] -prepared_destroy.restype = None - -# Prepared geometry binary predicate support. -def prepared_predicate(func): - func.argtypes= [PREPGEOM_PTR, GEOM_PTR] - func.restype = c_char - func.errcheck = check_predicate - return func - -prepared_contains = prepared_predicate(GEOSFunc('GEOSPreparedContains')) -prepared_contains_properly = prepared_predicate(GEOSFunc('GEOSPreparedContainsProperly')) -prepared_covers = prepared_predicate(GEOSFunc('GEOSPreparedCovers')) -prepared_intersects = prepared_predicate(GEOSFunc('GEOSPreparedIntersects')) diff --git a/parts/django/django/contrib/gis/geos/prototypes/threadsafe.py b/parts/django/django/contrib/gis/geos/prototypes/threadsafe.py deleted file mode 100644 index 5888ed1..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/threadsafe.py +++ /dev/null @@ -1,90 +0,0 @@ -import threading -from django.contrib.gis.geos.libgeos import lgeos, notice_h, error_h, CONTEXT_PTR - -class GEOSContextHandle(object): - """ - Python object representing a GEOS context handle. - """ - def __init__(self): - # Initializing the context handler for this thread with - # the notice and error handler. - self.ptr = lgeos.initGEOS_r(notice_h, error_h) - - def __del__(self): - if self.ptr: lgeos.finishGEOS_r(self.ptr) - -# Defining a thread-local object and creating an instance -# to hold a reference to GEOSContextHandle for this thread. -class GEOSContext(threading.local): - handle = None - -thread_context = GEOSContext() - -def call_geos_threaded(cfunc, args): - """ - This module-level routine calls the specified GEOS C thread-safe - function with the context for this current thread. - """ - # If a context handle does not exist for this thread, initialize one. - if not thread_context.handle: - thread_context.handle = GEOSContextHandle() - # Call the threaded GEOS routine with pointer of the context handle - # as the first argument. - return cfunc(thread_context.handle.ptr, *args) - -class GEOSFunc(object): - """ - Class that serves as a wrapper for GEOS C Functions, and will - use thread-safe function variants when available. - """ - def __init__(self, func_name): - try: - # GEOS thread-safe function signatures end with '_r', and - # take an additional context handle parameter. - self.cfunc = getattr(lgeos, func_name + '_r') - self.threaded = True - except AttributeError: - # Otherwise, use usual function. - self.cfunc = getattr(lgeos, func_name) - self.threaded = False - - def __call__(self, *args): - if self.threaded: - return call_geos_threaded(self.cfunc, args) - else: - return self.cfunc(*args) - - def __str__(self): - return self.cfunc.__name__ - - # argtypes property - def _get_argtypes(self): - return self.cfunc.argtypes - - def _set_argtypes(self, argtypes): - if self.threaded: - new_argtypes = [CONTEXT_PTR] - new_argtypes.extend(argtypes) - self.cfunc.argtypes = new_argtypes - else: - self.cfunc.argtypes = argtypes - - argtypes = property(_get_argtypes, _set_argtypes) - - # restype property - def _get_restype(self): - return self.cfunc.restype - - def _set_restype(self, restype): - self.cfunc.restype = restype - - restype = property(_get_restype, _set_restype) - - # errcheck property - def _get_errcheck(self): - return self.cfunc.errcheck - - def _set_errcheck(self, errcheck): - self.cfunc.errcheck = errcheck - - errcheck = property(_get_errcheck, _set_errcheck) diff --git a/parts/django/django/contrib/gis/geos/prototypes/topology.py b/parts/django/django/contrib/gis/geos/prototypes/topology.py deleted file mode 100644 index 50817f9..0000000 --- a/parts/django/django/contrib/gis/geos/prototypes/topology.py +++ /dev/null @@ -1,51 +0,0 @@ -""" - This module houses the GEOS ctypes prototype functions for the - topological operations on geometries. -""" -__all__ = ['geos_boundary', 'geos_buffer', 'geos_centroid', 'geos_convexhull', - 'geos_difference', 'geos_envelope', 'geos_intersection', - 'geos_linemerge', 'geos_pointonsurface', 'geos_preservesimplify', - 'geos_simplify', 'geos_symdifference', 'geos_union', 'geos_relate'] - -from ctypes import c_char_p, c_double, c_int -from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE -from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string -from django.contrib.gis.geos.prototypes.geom import geos_char_p -from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc - -def topology(func, *args): - "For GEOS unary topology functions." - argtypes = [GEOM_PTR] - if args: argtypes += args - func.argtypes = argtypes - func.restype = GEOM_PTR - func.errcheck = check_geom - return func - -### Topology Routines ### -geos_boundary = topology(GEOSFunc('GEOSBoundary')) -geos_buffer = topology(GEOSFunc('GEOSBuffer'), c_double, c_int) -geos_centroid = topology(GEOSFunc('GEOSGetCentroid')) -geos_convexhull = topology(GEOSFunc('GEOSConvexHull')) -geos_difference = topology(GEOSFunc('GEOSDifference'), GEOM_PTR) -geos_envelope = topology(GEOSFunc('GEOSEnvelope')) -geos_intersection = topology(GEOSFunc('GEOSIntersection'), GEOM_PTR) -geos_linemerge = topology(GEOSFunc('GEOSLineMerge')) -geos_pointonsurface = topology(GEOSFunc('GEOSPointOnSurface')) -geos_preservesimplify = topology(GEOSFunc('GEOSTopologyPreserveSimplify'), c_double) -geos_simplify = topology(GEOSFunc('GEOSSimplify'), c_double) -geos_symdifference = topology(GEOSFunc('GEOSSymDifference'), GEOM_PTR) -geos_union = topology(GEOSFunc('GEOSUnion'), GEOM_PTR) - -# GEOSRelate returns a string, not a geometry. -geos_relate = GEOSFunc('GEOSRelate') -geos_relate.argtypes = [GEOM_PTR, GEOM_PTR] -geos_relate.restype = geos_char_p -geos_relate.errcheck = check_string - -# Routines only in GEOS 3.1+ -if GEOS_PREPARE: - geos_cascaded_union = GEOSFunc('GEOSUnionCascaded') - geos_cascaded_union.argtypes = [GEOM_PTR] - geos_cascaded_union.restype = GEOM_PTR - __all__.append('geos_cascaded_union') diff --git a/parts/django/django/contrib/gis/geos/tests/__init__.py b/parts/django/django/contrib/gis/geos/tests/__init__.py deleted file mode 100644 index 44c8e26..0000000 --- a/parts/django/django/contrib/gis/geos/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -GEOS Testing module. -""" -from unittest import TestSuite, TextTestRunner -import test_geos, test_io, test_geos_mutation, test_mutable_list - -test_suites = [ - test_geos.suite(), - test_io.suite(), - test_geos_mutation.suite(), - test_mutable_list.suite(), - ] - -def suite(): - "Builds a test suite for the GEOS tests." - s = TestSuite() - map(s.addTest, test_suites) - return s - -def run(verbosity=1): - "Runs the GEOS tests." - TextTestRunner(verbosity=verbosity).run(suite()) - -if __name__ == '__main__': - run(2) diff --git a/parts/django/django/contrib/gis/geos/tests/test_geos.py b/parts/django/django/contrib/gis/geos/tests/test_geos.py deleted file mode 100644 index 3cd021e..0000000 --- a/parts/django/django/contrib/gis/geos/tests/test_geos.py +++ /dev/null @@ -1,926 +0,0 @@ -import ctypes, random, unittest, sys -from django.contrib.gis.geos import * -from django.contrib.gis.geos.base import gdal, numpy, GEOSBase -from django.contrib.gis.geometry.test_data import TestDataMixin - -class GEOSTest(unittest.TestCase, TestDataMixin): - - @property - def null_srid(self): - """ - Returns the proper null SRID depending on the GEOS version. - See the comments in `test15_srid` for more details. - """ - info = geos_version_info() - if info['version'] == '3.0.0' and info['release_candidate']: - return -1 - else: - return None - - def test00_base(self): - "Tests out the GEOSBase class." - # Testing out GEOSBase class, which provides a `ptr` property - # that abstracts out access to underlying C pointers. - class FakeGeom1(GEOSBase): - pass - - # This one only accepts pointers to floats - c_float_p = ctypes.POINTER(ctypes.c_float) - class FakeGeom2(GEOSBase): - ptr_type = c_float_p - - # Default ptr_type is `c_void_p`. - fg1 = FakeGeom1() - # Default ptr_type is C float pointer - fg2 = FakeGeom2() - - # These assignments are OK -- None is allowed because - # it's equivalent to the NULL pointer. - fg1.ptr = ctypes.c_void_p() - fg1.ptr = None - fg2.ptr = c_float_p(ctypes.c_float(5.23)) - fg2.ptr = None - - # Because pointers have been set to NULL, an exception should be - # raised when we try to access it. Raising an exception is - # preferrable to a segmentation fault that commonly occurs when - # a C method is given a NULL memory reference. - for fg in (fg1, fg2): - # Equivalent to `fg.ptr` - self.assertRaises(GEOSException, fg._get_ptr) - - # Anything that is either not None or the acceptable pointer type will - # result in a TypeError when trying to assign it to the `ptr` property. - # Thus, memmory addresses (integers) and pointers of the incorrect type - # (in `bad_ptrs`) will not be allowed. - bad_ptrs = (5, ctypes.c_char_p('foobar')) - for bad_ptr in bad_ptrs: - # Equivalent to `fg.ptr = bad_ptr` - self.assertRaises(TypeError, fg1._set_ptr, bad_ptr) - self.assertRaises(TypeError, fg2._set_ptr, bad_ptr) - - def test01a_wkt(self): - "Testing WKT output." - for g in self.geometries.wkt_out: - geom = fromstr(g.wkt) - self.assertEqual(g.ewkt, geom.wkt) - - def test01b_hex(self): - "Testing HEX output." - for g in self.geometries.hex_wkt: - geom = fromstr(g.wkt) - self.assertEqual(g.hex, geom.hex) - - def test01b_hexewkb(self): - "Testing (HEX)EWKB output." - from binascii import a2b_hex - - # For testing HEX(EWKB). - ogc_hex = '01010000000000000000000000000000000000F03F' - # `SELECT ST_AsHEXEWKB(ST_GeomFromText('POINT(0 1)', 4326));` - hexewkb_2d = '0101000020E61000000000000000000000000000000000F03F' - # `SELECT ST_AsHEXEWKB(ST_GeomFromEWKT('SRID=4326;POINT(0 1 2)'));` - hexewkb_3d = '01010000A0E61000000000000000000000000000000000F03F0000000000000040' - - pnt_2d = Point(0, 1, srid=4326) - pnt_3d = Point(0, 1, 2, srid=4326) - - # OGC-compliant HEX will not have SRID nor Z value. - self.assertEqual(ogc_hex, pnt_2d.hex) - self.assertEqual(ogc_hex, pnt_3d.hex) - - # HEXEWKB should be appropriate for its dimension -- have to use an - # a WKBWriter w/dimension set accordingly, else GEOS will insert - # garbage into 3D coordinate if there is none. Also, GEOS has a - # a bug in versions prior to 3.1 that puts the X coordinate in - # place of Z; an exception should be raised on those versions. - self.assertEqual(hexewkb_2d, pnt_2d.hexewkb) - if GEOS_PREPARE: - self.assertEqual(hexewkb_3d, pnt_3d.hexewkb) - self.assertEqual(True, GEOSGeometry(hexewkb_3d).hasz) - else: - try: - hexewkb = pnt_3d.hexewkb - except GEOSException: - pass - else: - self.fail('Should have raised GEOSException.') - - # Same for EWKB. - self.assertEqual(buffer(a2b_hex(hexewkb_2d)), pnt_2d.ewkb) - if GEOS_PREPARE: - self.assertEqual(buffer(a2b_hex(hexewkb_3d)), pnt_3d.ewkb) - else: - try: - ewkb = pnt_3d.ewkb - except GEOSException: - pass - else: - self.fail('Should have raised GEOSException') - - # Redundant sanity check. - self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid) - - def test01c_kml(self): - "Testing KML output." - for tg in self.geometries.wkt_out: - geom = fromstr(tg.wkt) - kml = getattr(tg, 'kml', False) - if kml: self.assertEqual(kml, geom.kml) - - def test01d_errors(self): - "Testing the Error handlers." - # string-based - print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n" - for err in self.geometries.errors: - try: - g = fromstr(err.wkt) - except (GEOSException, ValueError): - pass - - # Bad WKB - self.assertRaises(GEOSException, GEOSGeometry, buffer('0')) - - print "\nEND - expecting GEOS_ERROR; safe to ignore.\n" - - class NotAGeometry(object): - pass - - # Some other object - self.assertRaises(TypeError, GEOSGeometry, NotAGeometry()) - # None - self.assertRaises(TypeError, GEOSGeometry, None) - - def test01e_wkb(self): - "Testing WKB output." - from binascii import b2a_hex - for g in self.geometries.hex_wkt: - geom = fromstr(g.wkt) - wkb = geom.wkb - self.assertEqual(b2a_hex(wkb).upper(), g.hex) - - def test01f_create_hex(self): - "Testing creation from HEX." - for g in self.geometries.hex_wkt: - geom_h = GEOSGeometry(g.hex) - # we need to do this so decimal places get normalised - geom_t = fromstr(g.wkt) - self.assertEqual(geom_t.wkt, geom_h.wkt) - - def test01g_create_wkb(self): - "Testing creation from WKB." - from binascii import a2b_hex - for g in self.geometries.hex_wkt: - wkb = buffer(a2b_hex(g.hex)) - geom_h = GEOSGeometry(wkb) - # we need to do this so decimal places get normalised - geom_t = fromstr(g.wkt) - self.assertEqual(geom_t.wkt, geom_h.wkt) - - def test01h_ewkt(self): - "Testing EWKT." - srid = 32140 - for p in self.geometries.polygons: - ewkt = 'SRID=%d;%s' % (srid, p.wkt) - poly = fromstr(ewkt) - self.assertEqual(srid, poly.srid) - self.assertEqual(srid, poly.shell.srid) - self.assertEqual(srid, fromstr(poly.ewkt).srid) # Checking export - - def test01i_json(self): - "Testing GeoJSON input/output (via GDAL)." - if not gdal or not gdal.GEOJSON: return - for g in self.geometries.json_geoms: - geom = GEOSGeometry(g.wkt) - if not hasattr(g, 'not_equal'): - self.assertEqual(g.json, geom.json) - self.assertEqual(g.json, geom.geojson) - self.assertEqual(GEOSGeometry(g.wkt), GEOSGeometry(geom.json)) - - def test01k_fromfile(self): - "Testing the fromfile() factory." - from StringIO import StringIO - ref_pnt = GEOSGeometry('POINT(5 23)') - - wkt_f = StringIO() - wkt_f.write(ref_pnt.wkt) - wkb_f = StringIO() - wkb_f.write(str(ref_pnt.wkb)) - - # Other tests use `fromfile()` on string filenames so those - # aren't tested here. - for fh in (wkt_f, wkb_f): - fh.seek(0) - pnt = fromfile(fh) - self.assertEqual(ref_pnt, pnt) - - def test01k_eq(self): - "Testing equivalence." - p = fromstr('POINT(5 23)') - self.assertEqual(p, p.wkt) - self.assertNotEqual(p, 'foo') - ls = fromstr('LINESTRING(0 0, 1 1, 5 5)') - self.assertEqual(ls, ls.wkt) - self.assertNotEqual(p, 'bar') - # Error shouldn't be raise on equivalence testing with - # an invalid type. - for g in (p, ls): - self.assertNotEqual(g, None) - self.assertNotEqual(g, {'foo' : 'bar'}) - self.assertNotEqual(g, False) - - def test02a_points(self): - "Testing Point objects." - prev = fromstr('POINT(0 0)') - for p in self.geometries.points: - # Creating the point from the WKT - pnt = fromstr(p.wkt) - self.assertEqual(pnt.geom_type, 'Point') - self.assertEqual(pnt.geom_typeid, 0) - self.assertEqual(p.x, pnt.x) - self.assertEqual(p.y, pnt.y) - self.assertEqual(True, pnt == fromstr(p.wkt)) - self.assertEqual(False, pnt == prev) - - # Making sure that the point's X, Y components are what we expect - self.assertAlmostEqual(p.x, pnt.tuple[0], 9) - self.assertAlmostEqual(p.y, pnt.tuple[1], 9) - - # Testing the third dimension, and getting the tuple arguments - if hasattr(p, 'z'): - self.assertEqual(True, pnt.hasz) - self.assertEqual(p.z, pnt.z) - self.assertEqual(p.z, pnt.tuple[2], 9) - tup_args = (p.x, p.y, p.z) - set_tup1 = (2.71, 3.14, 5.23) - set_tup2 = (5.23, 2.71, 3.14) - else: - self.assertEqual(False, pnt.hasz) - self.assertEqual(None, pnt.z) - tup_args = (p.x, p.y) - set_tup1 = (2.71, 3.14) - set_tup2 = (3.14, 2.71) - - # Centroid operation on point should be point itself - self.assertEqual(p.centroid, pnt.centroid.tuple) - - # Now testing the different constructors - pnt2 = Point(tup_args) # e.g., Point((1, 2)) - pnt3 = Point(*tup_args) # e.g., Point(1, 2) - self.assertEqual(True, pnt == pnt2) - self.assertEqual(True, pnt == pnt3) - - # Now testing setting the x and y - pnt.y = 3.14 - pnt.x = 2.71 - self.assertEqual(3.14, pnt.y) - self.assertEqual(2.71, pnt.x) - - # Setting via the tuple/coords property - pnt.tuple = set_tup1 - self.assertEqual(set_tup1, pnt.tuple) - pnt.coords = set_tup2 - self.assertEqual(set_tup2, pnt.coords) - - prev = pnt # setting the previous geometry - - def test02b_multipoints(self): - "Testing MultiPoint objects." - for mp in self.geometries.multipoints: - mpnt = fromstr(mp.wkt) - self.assertEqual(mpnt.geom_type, 'MultiPoint') - self.assertEqual(mpnt.geom_typeid, 4) - - self.assertAlmostEqual(mp.centroid[0], mpnt.centroid.tuple[0], 9) - self.assertAlmostEqual(mp.centroid[1], mpnt.centroid.tuple[1], 9) - - self.assertRaises(GEOSIndexError, mpnt.__getitem__, len(mpnt)) - self.assertEqual(mp.centroid, mpnt.centroid.tuple) - self.assertEqual(mp.coords, tuple(m.tuple for m in mpnt)) - for p in mpnt: - self.assertEqual(p.geom_type, 'Point') - self.assertEqual(p.geom_typeid, 0) - self.assertEqual(p.empty, False) - self.assertEqual(p.valid, True) - - def test03a_linestring(self): - "Testing LineString objects." - prev = fromstr('POINT(0 0)') - for l in self.geometries.linestrings: - ls = fromstr(l.wkt) - self.assertEqual(ls.geom_type, 'LineString') - self.assertEqual(ls.geom_typeid, 1) - self.assertEqual(ls.empty, False) - self.assertEqual(ls.ring, False) - if hasattr(l, 'centroid'): - self.assertEqual(l.centroid, ls.centroid.tuple) - if hasattr(l, 'tup'): - self.assertEqual(l.tup, ls.tuple) - - self.assertEqual(True, ls == fromstr(l.wkt)) - self.assertEqual(False, ls == prev) - self.assertRaises(GEOSIndexError, ls.__getitem__, len(ls)) - prev = ls - - # Creating a LineString from a tuple, list, and numpy array - self.assertEqual(ls, LineString(ls.tuple)) # tuple - self.assertEqual(ls, LineString(*ls.tuple)) # as individual arguments - self.assertEqual(ls, LineString([list(tup) for tup in ls.tuple])) # as list - self.assertEqual(ls.wkt, LineString(*tuple(Point(tup) for tup in ls.tuple)).wkt) # Point individual arguments - if numpy: self.assertEqual(ls, LineString(numpy.array(ls.tuple))) # as numpy array - - def test03b_multilinestring(self): - "Testing MultiLineString objects." - prev = fromstr('POINT(0 0)') - for l in self.geometries.multilinestrings: - ml = fromstr(l.wkt) - self.assertEqual(ml.geom_type, 'MultiLineString') - self.assertEqual(ml.geom_typeid, 5) - - self.assertAlmostEqual(l.centroid[0], ml.centroid.x, 9) - self.assertAlmostEqual(l.centroid[1], ml.centroid.y, 9) - - self.assertEqual(True, ml == fromstr(l.wkt)) - self.assertEqual(False, ml == prev) - prev = ml - - for ls in ml: - self.assertEqual(ls.geom_type, 'LineString') - self.assertEqual(ls.geom_typeid, 1) - self.assertEqual(ls.empty, False) - - self.assertRaises(GEOSIndexError, ml.__getitem__, len(ml)) - self.assertEqual(ml.wkt, MultiLineString(*tuple(s.clone() for s in ml)).wkt) - self.assertEqual(ml, MultiLineString(*tuple(LineString(s.tuple) for s in ml))) - - def test04_linearring(self): - "Testing LinearRing objects." - for rr in self.geometries.linearrings: - lr = fromstr(rr.wkt) - self.assertEqual(lr.geom_type, 'LinearRing') - self.assertEqual(lr.geom_typeid, 2) - self.assertEqual(rr.n_p, len(lr)) - self.assertEqual(True, lr.valid) - self.assertEqual(False, lr.empty) - - # Creating a LinearRing from a tuple, list, and numpy array - self.assertEqual(lr, LinearRing(lr.tuple)) - self.assertEqual(lr, LinearRing(*lr.tuple)) - self.assertEqual(lr, LinearRing([list(tup) for tup in lr.tuple])) - if numpy: self.assertEqual(lr, LinearRing(numpy.array(lr.tuple))) - - def test05a_polygons(self): - "Testing Polygon objects." - - # Testing `from_bbox` class method - bbox = (-180, -90, 180, 90) - p = Polygon.from_bbox( bbox ) - self.assertEqual(bbox, p.extent) - - prev = fromstr('POINT(0 0)') - for p in self.geometries.polygons: - # Creating the Polygon, testing its properties. - poly = fromstr(p.wkt) - self.assertEqual(poly.geom_type, 'Polygon') - self.assertEqual(poly.geom_typeid, 3) - self.assertEqual(poly.empty, False) - self.assertEqual(poly.ring, False) - self.assertEqual(p.n_i, poly.num_interior_rings) - self.assertEqual(p.n_i + 1, len(poly)) # Testing __len__ - self.assertEqual(p.n_p, poly.num_points) - - # Area & Centroid - self.assertAlmostEqual(p.area, poly.area, 9) - self.assertAlmostEqual(p.centroid[0], poly.centroid.tuple[0], 9) - self.assertAlmostEqual(p.centroid[1], poly.centroid.tuple[1], 9) - - # Testing the geometry equivalence - self.assertEqual(True, poly == fromstr(p.wkt)) - self.assertEqual(False, poly == prev) # Should not be equal to previous geometry - self.assertEqual(True, poly != prev) - - # Testing the exterior ring - ring = poly.exterior_ring - self.assertEqual(ring.geom_type, 'LinearRing') - self.assertEqual(ring.geom_typeid, 2) - if p.ext_ring_cs: - self.assertEqual(p.ext_ring_cs, ring.tuple) - self.assertEqual(p.ext_ring_cs, poly[0].tuple) # Testing __getitem__ - - # Testing __getitem__ and __setitem__ on invalid indices - self.assertRaises(GEOSIndexError, poly.__getitem__, len(poly)) - self.assertRaises(GEOSIndexError, poly.__setitem__, len(poly), False) - self.assertRaises(GEOSIndexError, poly.__getitem__, -1 * len(poly) - 1) - - # Testing __iter__ - for r in poly: - self.assertEqual(r.geom_type, 'LinearRing') - self.assertEqual(r.geom_typeid, 2) - - # Testing polygon construction. - self.assertRaises(TypeError, Polygon.__init__, 0, [1, 2, 3]) - self.assertRaises(TypeError, Polygon.__init__, 'foo') - - # Polygon(shell, (hole1, ... holeN)) - rings = tuple(r for r in poly) - self.assertEqual(poly, Polygon(rings[0], rings[1:])) - - # Polygon(shell_tuple, hole_tuple1, ... , hole_tupleN) - ring_tuples = tuple(r.tuple for r in poly) - self.assertEqual(poly, Polygon(*ring_tuples)) - - # Constructing with tuples of LinearRings. - self.assertEqual(poly.wkt, Polygon(*tuple(r for r in poly)).wkt) - self.assertEqual(poly.wkt, Polygon(*tuple(LinearRing(r.tuple) for r in poly)).wkt) - - def test05b_multipolygons(self): - "Testing MultiPolygon objects." - print "\nBEGIN - expecting GEOS_NOTICE; safe to ignore.\n" - prev = fromstr('POINT (0 0)') - for mp in self.geometries.multipolygons: - mpoly = fromstr(mp.wkt) - self.assertEqual(mpoly.geom_type, 'MultiPolygon') - self.assertEqual(mpoly.geom_typeid, 6) - self.assertEqual(mp.valid, mpoly.valid) - - if mp.valid: - self.assertEqual(mp.num_geom, mpoly.num_geom) - self.assertEqual(mp.n_p, mpoly.num_coords) - self.assertEqual(mp.num_geom, len(mpoly)) - self.assertRaises(GEOSIndexError, mpoly.__getitem__, len(mpoly)) - for p in mpoly: - self.assertEqual(p.geom_type, 'Polygon') - self.assertEqual(p.geom_typeid, 3) - self.assertEqual(p.valid, True) - self.assertEqual(mpoly.wkt, MultiPolygon(*tuple(poly.clone() for poly in mpoly)).wkt) - - print "\nEND - expecting GEOS_NOTICE; safe to ignore.\n" - - def test06a_memory_hijinks(self): - "Testing Geometry __del__() on rings and polygons." - #### Memory issues with rings and polygons - - # These tests are needed to ensure sanity with writable geometries. - - # Getting a polygon with interior rings, and pulling out the interior rings - poly = fromstr(self.geometries.polygons[1].wkt) - ring1 = poly[0] - ring2 = poly[1] - - # These deletes should be 'harmless' since they are done on child geometries - del ring1 - del ring2 - ring1 = poly[0] - ring2 = poly[1] - - # Deleting the polygon - del poly - - # Access to these rings is OK since they are clones. - s1, s2 = str(ring1), str(ring2) - - def test08_coord_seq(self): - "Testing Coordinate Sequence objects." - for p in self.geometries.polygons: - if p.ext_ring_cs: - # Constructing the polygon and getting the coordinate sequence - poly = fromstr(p.wkt) - cs = poly.exterior_ring.coord_seq - - self.assertEqual(p.ext_ring_cs, cs.tuple) # done in the Polygon test too. - self.assertEqual(len(p.ext_ring_cs), len(cs)) # Making sure __len__ works - - # Checks __getitem__ and __setitem__ - for i in xrange(len(p.ext_ring_cs)): - c1 = p.ext_ring_cs[i] # Expected value - c2 = cs[i] # Value from coordseq - self.assertEqual(c1, c2) - - # Constructing the test value to set the coordinate sequence with - if len(c1) == 2: tset = (5, 23) - else: tset = (5, 23, 8) - cs[i] = tset - - # Making sure every set point matches what we expect - for j in range(len(tset)): - cs[i] = tset - self.assertEqual(tset[j], cs[i][j]) - - def test09_relate_pattern(self): - "Testing relate() and relate_pattern()." - g = fromstr('POINT (0 0)') - self.assertRaises(GEOSException, g.relate_pattern, 0, 'invalid pattern, yo') - for rg in self.geometries.relate_geoms: - a = fromstr(rg.wkt_a) - b = fromstr(rg.wkt_b) - self.assertEqual(rg.result, a.relate_pattern(b, rg.pattern)) - self.assertEqual(rg.pattern, a.relate(b)) - - def test10_intersection(self): - "Testing intersects() and intersection()." - for i in xrange(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - i1 = fromstr(self.geometries.intersect_geoms[i].wkt) - self.assertEqual(True, a.intersects(b)) - i2 = a.intersection(b) - self.assertEqual(i1, i2) - self.assertEqual(i1, a & b) # __and__ is intersection operator - a &= b # testing __iand__ - self.assertEqual(i1, a) - - def test11_union(self): - "Testing union()." - for i in xrange(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - u1 = fromstr(self.geometries.union_geoms[i].wkt) - u2 = a.union(b) - self.assertEqual(u1, u2) - self.assertEqual(u1, a | b) # __or__ is union operator - a |= b # testing __ior__ - self.assertEqual(u1, a) - - def test12_difference(self): - "Testing difference()." - for i in xrange(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - d1 = fromstr(self.geometries.diff_geoms[i].wkt) - d2 = a.difference(b) - self.assertEqual(d1, d2) - self.assertEqual(d1, a - b) # __sub__ is difference operator - a -= b # testing __isub__ - self.assertEqual(d1, a) - - def test13_symdifference(self): - "Testing sym_difference()." - for i in xrange(len(self.geometries.topology_geoms)): - a = fromstr(self.geometries.topology_geoms[i].wkt_a) - b = fromstr(self.geometries.topology_geoms[i].wkt_b) - d1 = fromstr(self.geometries.sdiff_geoms[i].wkt) - d2 = a.sym_difference(b) - self.assertEqual(d1, d2) - self.assertEqual(d1, a ^ b) # __xor__ is symmetric difference operator - a ^= b # testing __ixor__ - self.assertEqual(d1, a) - - def test14_buffer(self): - "Testing buffer()." - for bg in self.geometries.buffer_geoms: - g = fromstr(bg.wkt) - - # The buffer we expect - exp_buf = fromstr(bg.buffer_wkt) - quadsegs = bg.quadsegs - width = bg.width - - # Can't use a floating-point for the number of quadsegs. - self.assertRaises(ctypes.ArgumentError, g.buffer, width, float(quadsegs)) - - # Constructing our buffer - buf = g.buffer(width, quadsegs) - self.assertEqual(exp_buf.num_coords, buf.num_coords) - self.assertEqual(len(exp_buf), len(buf)) - - # Now assuring that each point in the buffer is almost equal - for j in xrange(len(exp_buf)): - exp_ring = exp_buf[j] - buf_ring = buf[j] - self.assertEqual(len(exp_ring), len(buf_ring)) - for k in xrange(len(exp_ring)): - # Asserting the X, Y of each point are almost equal (due to floating point imprecision) - self.assertAlmostEqual(exp_ring[k][0], buf_ring[k][0], 9) - self.assertAlmostEqual(exp_ring[k][1], buf_ring[k][1], 9) - - def test15_srid(self): - "Testing the SRID property and keyword." - # Testing SRID keyword on Point - pnt = Point(5, 23, srid=4326) - self.assertEqual(4326, pnt.srid) - pnt.srid = 3084 - self.assertEqual(3084, pnt.srid) - self.assertRaises(ctypes.ArgumentError, pnt.set_srid, '4326') - - # Testing SRID keyword on fromstr(), and on Polygon rings. - poly = fromstr(self.geometries.polygons[1].wkt, srid=4269) - self.assertEqual(4269, poly.srid) - for ring in poly: self.assertEqual(4269, ring.srid) - poly.srid = 4326 - self.assertEqual(4326, poly.shell.srid) - - # Testing SRID keyword on GeometryCollection - gc = GeometryCollection(Point(5, 23), LineString((0, 0), (1.5, 1.5), (3, 3)), srid=32021) - self.assertEqual(32021, gc.srid) - for i in range(len(gc)): self.assertEqual(32021, gc[i].srid) - - # GEOS may get the SRID from HEXEWKB - # 'POINT(5 23)' at SRID=4326 in hex form -- obtained from PostGIS - # using `SELECT GeomFromText('POINT (5 23)', 4326);`. - hex = '0101000020E610000000000000000014400000000000003740' - p1 = fromstr(hex) - self.assertEqual(4326, p1.srid) - - # In GEOS 3.0.0rc1-4 when the EWKB and/or HEXEWKB is exported, - # the SRID information is lost and set to -1 -- this is not a - # problem on the 3.0.0 version (another reason to upgrade). - exp_srid = self.null_srid - - p2 = fromstr(p1.hex) - self.assertEqual(exp_srid, p2.srid) - p3 = fromstr(p1.hex, srid=-1) # -1 is intended. - self.assertEqual(-1, p3.srid) - - def test16_mutable_geometries(self): - "Testing the mutability of Polygons and Geometry Collections." - ### Testing the mutability of Polygons ### - for p in self.geometries.polygons: - poly = fromstr(p.wkt) - - # Should only be able to use __setitem__ with LinearRing geometries. - self.assertRaises(TypeError, poly.__setitem__, 0, LineString((1, 1), (2, 2))) - - # Constructing the new shell by adding 500 to every point in the old shell. - shell_tup = poly.shell.tuple - new_coords = [] - for point in shell_tup: new_coords.append((point[0] + 500., point[1] + 500.)) - new_shell = LinearRing(*tuple(new_coords)) - - # Assigning polygon's exterior ring w/the new shell - poly.exterior_ring = new_shell - s = str(new_shell) # new shell is still accessible - self.assertEqual(poly.exterior_ring, new_shell) - self.assertEqual(poly[0], new_shell) - - ### Testing the mutability of Geometry Collections - for tg in self.geometries.multipoints: - mp = fromstr(tg.wkt) - for i in range(len(mp)): - # Creating a random point. - pnt = mp[i] - new = Point(random.randint(1, 100), random.randint(1, 100)) - # Testing the assignment - mp[i] = new - s = str(new) # what was used for the assignment is still accessible - self.assertEqual(mp[i], new) - self.assertEqual(mp[i].wkt, new.wkt) - self.assertNotEqual(pnt, mp[i]) - - # MultiPolygons involve much more memory management because each - # Polygon w/in the collection has its own rings. - for tg in self.geometries.multipolygons: - mpoly = fromstr(tg.wkt) - for i in xrange(len(mpoly)): - poly = mpoly[i] - old_poly = mpoly[i] - # Offsetting the each ring in the polygon by 500. - for j in xrange(len(poly)): - r = poly[j] - for k in xrange(len(r)): r[k] = (r[k][0] + 500., r[k][1] + 500.) - poly[j] = r - - self.assertNotEqual(mpoly[i], poly) - # Testing the assignment - mpoly[i] = poly - s = str(poly) # Still accessible - self.assertEqual(mpoly[i], poly) - self.assertNotEqual(mpoly[i], old_poly) - - # Extreme (!!) __setitem__ -- no longer works, have to detect - # in the first object that __setitem__ is called in the subsequent - # objects -- maybe mpoly[0, 0, 0] = (3.14, 2.71)? - #mpoly[0][0][0] = (3.14, 2.71) - #self.assertEqual((3.14, 2.71), mpoly[0][0][0]) - # Doing it more slowly.. - #self.assertEqual((3.14, 2.71), mpoly[0].shell[0]) - #del mpoly - - def test17_threed(self): - "Testing three-dimensional geometries." - # Testing a 3D Point - pnt = Point(2, 3, 8) - self.assertEqual((2.,3.,8.), pnt.coords) - self.assertRaises(TypeError, pnt.set_coords, (1.,2.)) - pnt.coords = (1.,2.,3.) - self.assertEqual((1.,2.,3.), pnt.coords) - - # Testing a 3D LineString - ls = LineString((2., 3., 8.), (50., 250., -117.)) - self.assertEqual(((2.,3.,8.), (50.,250.,-117.)), ls.tuple) - self.assertRaises(TypeError, ls.__setitem__, 0, (1.,2.)) - ls[0] = (1.,2.,3.) - self.assertEqual((1.,2.,3.), ls[0]) - - def test18_distance(self): - "Testing the distance() function." - # Distance to self should be 0. - pnt = Point(0, 0) - self.assertEqual(0.0, pnt.distance(Point(0, 0))) - - # Distance should be 1 - self.assertEqual(1.0, pnt.distance(Point(0, 1))) - - # Distance should be ~ sqrt(2) - self.assertAlmostEqual(1.41421356237, pnt.distance(Point(1, 1)), 11) - - # Distances are from the closest vertex in each geometry -- - # should be 3 (distance from (2, 2) to (5, 2)). - ls1 = LineString((0, 0), (1, 1), (2, 2)) - ls2 = LineString((5, 2), (6, 1), (7, 0)) - self.assertEqual(3, ls1.distance(ls2)) - - def test19_length(self): - "Testing the length property." - # Points have 0 length. - pnt = Point(0, 0) - self.assertEqual(0.0, pnt.length) - - # Should be ~ sqrt(2) - ls = LineString((0, 0), (1, 1)) - self.assertAlmostEqual(1.41421356237, ls.length, 11) - - # Should be circumfrence of Polygon - poly = Polygon(LinearRing((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))) - self.assertEqual(4.0, poly.length) - - # Should be sum of each element's length in collection. - mpoly = MultiPolygon(poly.clone(), poly) - self.assertEqual(8.0, mpoly.length) - - def test20a_emptyCollections(self): - "Testing empty geometries and collections." - gc1 = GeometryCollection([]) - gc2 = fromstr('GEOMETRYCOLLECTION EMPTY') - pnt = fromstr('POINT EMPTY') - ls = fromstr('LINESTRING EMPTY') - poly = fromstr('POLYGON EMPTY') - mls = fromstr('MULTILINESTRING EMPTY') - mpoly1 = fromstr('MULTIPOLYGON EMPTY') - mpoly2 = MultiPolygon(()) - - for g in [gc1, gc2, pnt, ls, poly, mls, mpoly1, mpoly2]: - self.assertEqual(True, g.empty) - - # Testing len() and num_geom. - if isinstance(g, Polygon): - self.assertEqual(1, len(g)) # Has one empty linear ring - self.assertEqual(1, g.num_geom) - self.assertEqual(0, len(g[0])) - elif isinstance(g, (Point, LineString)): - self.assertEqual(1, g.num_geom) - self.assertEqual(0, len(g)) - else: - self.assertEqual(0, g.num_geom) - self.assertEqual(0, len(g)) - - # Testing __getitem__ (doesn't work on Point or Polygon) - if isinstance(g, Point): - self.assertRaises(GEOSIndexError, g.get_x) - elif isinstance(g, Polygon): - lr = g.shell - self.assertEqual('LINEARRING EMPTY', lr.wkt) - self.assertEqual(0, len(lr)) - self.assertEqual(True, lr.empty) - self.assertRaises(GEOSIndexError, lr.__getitem__, 0) - else: - self.assertRaises(GEOSIndexError, g.__getitem__, 0) - - def test20b_collections_of_collections(self): - "Testing GeometryCollection handling of other collections." - # Creating a GeometryCollection WKT string composed of other - # collections and polygons. - coll = [mp.wkt for mp in self.geometries.multipolygons if mp.valid] - coll.extend([mls.wkt for mls in self.geometries.multilinestrings]) - coll.extend([p.wkt for p in self.geometries.polygons]) - coll.extend([mp.wkt for mp in self.geometries.multipoints]) - gc_wkt = 'GEOMETRYCOLLECTION(%s)' % ','.join(coll) - - # Should construct ok from WKT - gc1 = GEOSGeometry(gc_wkt) - - # Should also construct ok from individual geometry arguments. - gc2 = GeometryCollection(*tuple(g for g in gc1)) - - # And, they should be equal. - self.assertEqual(gc1, gc2) - - def test21_test_gdal(self): - "Testing `ogr` and `srs` properties." - if not gdal.HAS_GDAL: return - g1 = fromstr('POINT(5 23)') - self.assertEqual(True, isinstance(g1.ogr, gdal.OGRGeometry)) - self.assertEqual(g1.srs, None) - - g2 = fromstr('LINESTRING(0 0, 5 5, 23 23)', srid=4326) - self.assertEqual(True, isinstance(g2.ogr, gdal.OGRGeometry)) - self.assertEqual(True, isinstance(g2.srs, gdal.SpatialReference)) - self.assertEqual(g2.hex, g2.ogr.hex) - self.assertEqual('WGS 84', g2.srs.name) - - def test22_copy(self): - "Testing use with the Python `copy` module." - import django.utils.copycompat as copy - poly = GEOSGeometry('POLYGON((0 0, 0 23, 23 23, 23 0, 0 0), (5 5, 5 10, 10 10, 10 5, 5 5))') - cpy1 = copy.copy(poly) - cpy2 = copy.deepcopy(poly) - self.assertNotEqual(poly._ptr, cpy1._ptr) - self.assertNotEqual(poly._ptr, cpy2._ptr) - - def test23_transform(self): - "Testing `transform` method." - if not gdal.HAS_GDAL: return - orig = GEOSGeometry('POINT (-104.609 38.255)', 4326) - trans = GEOSGeometry('POINT (992385.4472045 481455.4944650)', 2774) - - # Using a srid, a SpatialReference object, and a CoordTransform object - # for transformations. - t1, t2, t3 = orig.clone(), orig.clone(), orig.clone() - t1.transform(trans.srid) - t2.transform(gdal.SpatialReference('EPSG:2774')) - ct = gdal.CoordTransform(gdal.SpatialReference('WGS84'), gdal.SpatialReference(2774)) - t3.transform(ct) - - # Testing use of the `clone` keyword. - k1 = orig.clone() - k2 = k1.transform(trans.srid, clone=True) - self.assertEqual(k1, orig) - self.assertNotEqual(k1, k2) - - prec = 3 - for p in (t1, t2, t3, k2): - self.assertAlmostEqual(trans.x, p.x, prec) - self.assertAlmostEqual(trans.y, p.y, prec) - - def test24_extent(self): - "Testing `extent` method." - # The xmin, ymin, xmax, ymax of the MultiPoint should be returned. - mp = MultiPoint(Point(5, 23), Point(0, 0), Point(10, 50)) - self.assertEqual((0.0, 0.0, 10.0, 50.0), mp.extent) - pnt = Point(5.23, 17.8) - # Extent of points is just the point itself repeated. - self.assertEqual((5.23, 17.8, 5.23, 17.8), pnt.extent) - # Testing on the 'real world' Polygon. - poly = fromstr(self.geometries.polygons[3].wkt) - ring = poly.shell - x, y = ring.x, ring.y - xmin, ymin = min(x), min(y) - xmax, ymax = max(x), max(y) - self.assertEqual((xmin, ymin, xmax, ymax), poly.extent) - - def test25_pickle(self): - "Testing pickling and unpickling support." - # Using both pickle and cPickle -- just 'cause. - import pickle, cPickle - - # Creating a list of test geometries for pickling, - # and setting the SRID on some of them. - def get_geoms(lst, srid=None): - return [GEOSGeometry(tg.wkt, srid) for tg in lst] - tgeoms = get_geoms(self.geometries.points) - tgeoms.extend(get_geoms(self.geometries.multilinestrings, 4326)) - tgeoms.extend(get_geoms(self.geometries.polygons, 3084)) - tgeoms.extend(get_geoms(self.geometries.multipolygons, 900913)) - - # The SRID won't be exported in GEOS 3.0 release candidates. - no_srid = self.null_srid == -1 - for geom in tgeoms: - s1, s2 = cPickle.dumps(geom), pickle.dumps(geom) - g1, g2 = cPickle.loads(s1), pickle.loads(s2) - for tmpg in (g1, g2): - self.assertEqual(geom, tmpg) - if not no_srid: self.assertEqual(geom.srid, tmpg.srid) - - def test26_prepared(self): - "Testing PreparedGeometry support." - if not GEOS_PREPARE: return - # Creating a simple multipolygon and getting a prepared version. - mpoly = GEOSGeometry('MULTIPOLYGON(((0 0,0 5,5 5,5 0,0 0)),((5 5,5 10,10 10,10 5,5 5)))') - prep = mpoly.prepared - - # A set of test points. - pnts = [Point(5, 5), Point(7.5, 7.5), Point(2.5, 7.5)] - covers = [True, True, False] # No `covers` op for regular GEOS geoms. - for pnt, c in zip(pnts, covers): - # Results should be the same (but faster) - self.assertEqual(mpoly.contains(pnt), prep.contains(pnt)) - self.assertEqual(mpoly.intersects(pnt), prep.intersects(pnt)) - self.assertEqual(c, prep.covers(pnt)) - - def test26_line_merge(self): - "Testing line merge support" - ref_geoms = (fromstr('LINESTRING(1 1, 1 1, 3 3)'), - fromstr('MULTILINESTRING((1 1, 3 3), (3 3, 4 2))'), - ) - ref_merged = (fromstr('LINESTRING(1 1, 3 3)'), - fromstr('LINESTRING (1 1, 3 3, 4 2)'), - ) - for geom, merged in zip(ref_geoms, ref_merged): - self.assertEqual(merged, geom.merged) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(GEOSTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/geos/tests/test_geos_mutation.py b/parts/django/django/contrib/gis/geos/tests/test_geos_mutation.py deleted file mode 100644 index 28f484d..0000000 --- a/parts/django/django/contrib/gis/geos/tests/test_geos_mutation.py +++ /dev/null @@ -1,137 +0,0 @@ -# Copyright (c) 2008-2009 Aryeh Leib Taurog, all rights reserved. -# Modified from original contribution by Aryeh Leib Taurog, which was -# released under the New BSD license. -import unittest - -import django.utils.copycompat as copy - -from django.contrib.gis.geos import * -from django.contrib.gis.geos.error import GEOSIndexError - -def getItem(o,i): return o[i] -def delItem(o,i): del o[i] -def setItem(o,i,v): o[i] = v - -def api_get_distance(x): return x.distance(Point(-200,-200)) -def api_get_buffer(x): return x.buffer(10) -def api_get_geom_typeid(x): return x.geom_typeid -def api_get_num_coords(x): return x.num_coords -def api_get_centroid(x): return x.centroid -def api_get_empty(x): return x.empty -def api_get_valid(x): return x.valid -def api_get_simple(x): return x.simple -def api_get_ring(x): return x.ring -def api_get_boundary(x): return x.boundary -def api_get_convex_hull(x): return x.convex_hull -def api_get_extent(x): return x.extent -def api_get_area(x): return x.area -def api_get_length(x): return x.length - -geos_function_tests = [ val for name, val in vars().items() - if hasattr(val, '__call__') - and name.startswith('api_get_') ] - -class GEOSMutationTest(unittest.TestCase): - """ - Tests Pythonic Mutability of Python GEOS geometry wrappers - get/set/delitem on a slice, normal list methods - """ - - def test00_GEOSIndexException(self): - 'Testing Geometry GEOSIndexError' - p = Point(1,2) - for i in range(-2,2): p._checkindex(i) - self.assertRaises(GEOSIndexError, p._checkindex, 2) - self.assertRaises(GEOSIndexError, p._checkindex, -3) - - def test01_PointMutations(self): - 'Testing Point mutations' - for p in (Point(1,2,3), fromstr('POINT (1 2 3)')): - self.assertEqual(p._get_single_external(1), 2.0, 'Point _get_single_external') - - # _set_single - p._set_single(0,100) - self.assertEqual(p.coords, (100.0,2.0,3.0), 'Point _set_single') - - # _set_list - p._set_list(2,(50,3141)) - self.assertEqual(p.coords, (50.0,3141.0), 'Point _set_list') - - def test02_PointExceptions(self): - 'Testing Point exceptions' - self.assertRaises(TypeError, Point, range(1)) - self.assertRaises(TypeError, Point, range(4)) - - def test03_PointApi(self): - 'Testing Point API' - q = Point(4,5,3) - for p in (Point(1,2,3), fromstr('POINT (1 2 3)')): - p[0:2] = [4,5] - for f in geos_function_tests: - self.assertEqual(f(q), f(p), 'Point ' + f.__name__) - - def test04_LineStringMutations(self): - 'Testing LineString mutations' - for ls in (LineString((1,0),(4,1),(6,-1)), - fromstr('LINESTRING (1 0,4 1,6 -1)')): - self.assertEqual(ls._get_single_external(1), (4.0,1.0), 'LineString _get_single_external') - - # _set_single - ls._set_single(0,(-50,25)) - self.assertEqual(ls.coords, ((-50.0,25.0),(4.0,1.0),(6.0,-1.0)), 'LineString _set_single') - - # _set_list - ls._set_list(2, ((-50.0,25.0),(6.0,-1.0))) - self.assertEqual(ls.coords, ((-50.0,25.0),(6.0,-1.0)), 'LineString _set_list') - - lsa = LineString(ls.coords) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(ls), 'LineString ' + f.__name__) - - def test05_Polygon(self): - 'Testing Polygon mutations' - for pg in (Polygon(((1,0),(4,1),(6,-1),(8,10),(1,0)), - ((5,4),(6,4),(6,3),(5,4))), - fromstr('POLYGON ((1 0,4 1,6 -1,8 10,1 0),(5 4,6 4,6 3,5 4))')): - self.assertEqual(pg._get_single_external(0), - LinearRing((1,0),(4,1),(6,-1),(8,10),(1,0)), - 'Polygon _get_single_external(0)') - self.assertEqual(pg._get_single_external(1), - LinearRing((5,4),(6,4),(6,3),(5,4)), - 'Polygon _get_single_external(1)') - - # _set_list - pg._set_list(2, (((1,2),(10,0),(12,9),(-1,15),(1,2)), - ((4,2),(5,2),(5,3),(4,2)))) - self.assertEqual(pg.coords, - (((1.0,2.0),(10.0,0.0),(12.0,9.0),(-1.0,15.0),(1.0,2.0)), - ((4.0,2.0),(5.0,2.0),(5.0,3.0),(4.0,2.0))), - 'Polygon _set_list') - - lsa = Polygon(*pg.coords) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(pg), 'Polygon ' + f.__name__) - - def test06_Collection(self): - 'Testing Collection mutations' - for mp in (MultiPoint(*map(Point,((3,4),(-1,2),(5,-4),(2,8)))), - fromstr('MULTIPOINT (3 4,-1 2,5 -4,2 8)')): - self.assertEqual(mp._get_single_external(2), Point(5,-4), 'Collection _get_single_external') - - mp._set_list(3, map(Point,((5,5),(3,-2),(8,1)))) - self.assertEqual(mp.coords, ((5.0,5.0),(3.0,-2.0),(8.0,1.0)), 'Collection _set_list') - - lsa = MultiPoint(*map(Point,((5,5),(3,-2),(8,1)))) - for f in geos_function_tests: - self.assertEqual(f(lsa), f(mp), 'MultiPoint ' + f.__name__) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(GEOSMutationTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) - -if __name__ == '__main__': - run() diff --git a/parts/django/django/contrib/gis/geos/tests/test_io.py b/parts/django/django/contrib/gis/geos/tests/test_io.py deleted file mode 100644 index cc0f1ed..0000000 --- a/parts/django/django/contrib/gis/geos/tests/test_io.py +++ /dev/null @@ -1,112 +0,0 @@ -import binascii, ctypes, unittest -from django.contrib.gis.geos import GEOSGeometry, WKTReader, WKTWriter, WKBReader, WKBWriter, geos_version_info - -class GEOSIOTest(unittest.TestCase): - - def test01_wktreader(self): - # Creating a WKTReader instance - wkt_r = WKTReader() - wkt = 'POINT (5 23)' - - # read() should return a GEOSGeometry - ref = GEOSGeometry(wkt) - g1 = wkt_r.read(wkt) - g2 = wkt_r.read(unicode(wkt)) - - for geom in (g1, g2): - self.assertEqual(ref, geom) - - # Should only accept basestring objects. - self.assertRaises(TypeError, wkt_r.read, 1) - self.assertRaises(TypeError, wkt_r.read, buffer('foo')) - - def test02_wktwriter(self): - # Creating a WKTWriter instance, testing its ptr property. - wkt_w = WKTWriter() - self.assertRaises(TypeError, wkt_w._set_ptr, WKTReader.ptr_type()) - - ref = GEOSGeometry('POINT (5 23)') - ref_wkt = 'POINT (5.0000000000000000 23.0000000000000000)' - self.assertEqual(ref_wkt, wkt_w.write(ref)) - - def test03_wkbreader(self): - # Creating a WKBReader instance - wkb_r = WKBReader() - - hex = '000000000140140000000000004037000000000000' - wkb = buffer(binascii.a2b_hex(hex)) - ref = GEOSGeometry(hex) - - # read() should return a GEOSGeometry on either a hex string or - # a WKB buffer. - g1 = wkb_r.read(wkb) - g2 = wkb_r.read(hex) - for geom in (g1, g2): - self.assertEqual(ref, geom) - - bad_input = (1, 5.23, None, False) - for bad_wkb in bad_input: - self.assertRaises(TypeError, wkb_r.read, bad_wkb) - - def test04_wkbwriter(self): - wkb_w = WKBWriter() - - # Representations of 'POINT (5 23)' in hex -- one normal and - # the other with the byte order changed. - g = GEOSGeometry('POINT (5 23)') - hex1 = '010100000000000000000014400000000000003740' - wkb1 = buffer(binascii.a2b_hex(hex1)) - hex2 = '000000000140140000000000004037000000000000' - wkb2 = buffer(binascii.a2b_hex(hex2)) - - self.assertEqual(hex1, wkb_w.write_hex(g)) - self.assertEqual(wkb1, wkb_w.write(g)) - - # Ensuring bad byteorders are not accepted. - for bad_byteorder in (-1, 2, 523, 'foo', None): - # Equivalent of `wkb_w.byteorder = bad_byteorder` - self.assertRaises(ValueError, wkb_w._set_byteorder, bad_byteorder) - - # Setting the byteorder to 0 (for Big Endian) - wkb_w.byteorder = 0 - self.assertEqual(hex2, wkb_w.write_hex(g)) - self.assertEqual(wkb2, wkb_w.write(g)) - - # Back to Little Endian - wkb_w.byteorder = 1 - - # Now, trying out the 3D and SRID flags. - g = GEOSGeometry('POINT (5 23 17)') - g.srid = 4326 - - hex3d = '0101000080000000000000144000000000000037400000000000003140' - wkb3d = buffer(binascii.a2b_hex(hex3d)) - hex3d_srid = '01010000A0E6100000000000000000144000000000000037400000000000003140' - wkb3d_srid = buffer(binascii.a2b_hex(hex3d_srid)) - - # Ensuring bad output dimensions are not accepted - for bad_outdim in (-1, 0, 1, 4, 423, 'foo', None): - # Equivalent of `wkb_w.outdim = bad_outdim` - self.assertRaises(ValueError, wkb_w._set_outdim, bad_outdim) - - # These tests will fail on 3.0.0 because of a bug that was fixed in 3.1: - # http://trac.osgeo.org/geos/ticket/216 - if not geos_version_info()['version'].startswith('3.0.'): - # Now setting the output dimensions to be 3 - wkb_w.outdim = 3 - - self.assertEqual(hex3d, wkb_w.write_hex(g)) - self.assertEqual(wkb3d, wkb_w.write(g)) - - # Telling the WKBWriter to inlcude the srid in the representation. - wkb_w.srid = True - self.assertEqual(hex3d_srid, wkb_w.write_hex(g)) - self.assertEqual(wkb3d_srid, wkb_w.write(g)) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(GEOSIOTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/geos/tests/test_mutable_list.py b/parts/django/django/contrib/gis/geos/tests/test_mutable_list.py deleted file mode 100644 index ebbe8ff..0000000 --- a/parts/django/django/contrib/gis/geos/tests/test_mutable_list.py +++ /dev/null @@ -1,398 +0,0 @@ -# Copyright (c) 2008-2009 Aryeh Leib Taurog, http://www.aryehleib.com -# All rights reserved. -# -# Modified from original contribution by Aryeh Leib Taurog, which was -# released under the New BSD license. -import unittest -from django.contrib.gis.geos.mutable_list import ListMixin - -class UserListA(ListMixin): - _mytype = tuple - def __init__(self, i_list, *args, **kwargs): - self._list = self._mytype(i_list) - super(UserListA, self).__init__(*args, **kwargs) - - def __len__(self): return len(self._list) - - def __str__(self): return str(self._list) - - def __repr__(self): return repr(self._list) - - def _set_list(self, length, items): - # this would work: - # self._list = self._mytype(items) - # but then we wouldn't be testing length parameter - itemList = ['x'] * length - for i, v in enumerate(items): - itemList[i] = v - - self._list = self._mytype(itemList) - - def _get_single_external(self, index): - return self._list[index] - -class UserListB(UserListA): - _mytype = list - - def _set_single(self, index, value): - self._list[index] = value - -def nextRange(length): - nextRange.start += 100 - return range(nextRange.start, nextRange.start + length) - -nextRange.start = 0 - -class ListMixinTest(unittest.TestCase): - """ - Tests base class ListMixin by comparing a list clone which is - a ListMixin subclass with a real Python list. - """ - limit = 3 - listType = UserListA - - def lists_of_len(self, length=None): - if length is None: length = self.limit - pl = range(length) - return pl, self.listType(pl) - - def limits_plus(self, b): - return range(-self.limit - b, self.limit + b) - - def step_range(self): - return range(-1 - self.limit, 0) + range(1, 1 + self.limit) - - def test01_getslice(self): - 'Slice retrieval' - pl, ul = self.lists_of_len() - for i in self.limits_plus(1): - self.assertEqual(pl[i:], ul[i:], 'slice [%d:]' % (i)) - self.assertEqual(pl[:i], ul[:i], 'slice [:%d]' % (i)) - - for j in self.limits_plus(1): - self.assertEqual(pl[i:j], ul[i:j], 'slice [%d:%d]' % (i,j)) - for k in self.step_range(): - self.assertEqual(pl[i:j:k], ul[i:j:k], 'slice [%d:%d:%d]' % (i,j,k)) - - for k in self.step_range(): - self.assertEqual(pl[i::k], ul[i::k], 'slice [%d::%d]' % (i,k)) - self.assertEqual(pl[:i:k], ul[:i:k], 'slice [:%d:%d]' % (i,k)) - - for k in self.step_range(): - self.assertEqual(pl[::k], ul[::k], 'slice [::%d]' % (k)) - - def test02_setslice(self): - 'Slice assignment' - def setfcn(x,i,j,k,L): x[i:j:k] = range(L) - pl, ul = self.lists_of_len() - for slen in range(self.limit + 1): - ssl = nextRange(slen) - ul[:] = ssl - pl[:] = ssl - self.assertEqual(pl, ul[:], 'set slice [:]') - - for i in self.limits_plus(1): - ssl = nextRange(slen) - ul[i:] = ssl - pl[i:] = ssl - self.assertEqual(pl, ul[:], 'set slice [%d:]' % (i)) - - ssl = nextRange(slen) - ul[:i] = ssl - pl[:i] = ssl - self.assertEqual(pl, ul[:], 'set slice [:%d]' % (i)) - - for j in self.limits_plus(1): - ssl = nextRange(slen) - ul[i:j] = ssl - pl[i:j] = ssl - self.assertEqual(pl, ul[:], 'set slice [%d:%d]' % (i, j)) - - for k in self.step_range(): - ssl = nextRange( len(ul[i:j:k]) ) - ul[i:j:k] = ssl - pl[i:j:k] = ssl - self.assertEqual(pl, ul[:], 'set slice [%d:%d:%d]' % (i, j, k)) - - sliceLen = len(ul[i:j:k]) - self.assertRaises(ValueError, setfcn, ul, i, j, k, sliceLen + 1) - if sliceLen > 2: - self.assertRaises(ValueError, setfcn, ul, i, j, k, sliceLen - 1) - - for k in self.step_range(): - ssl = nextRange( len(ul[i::k]) ) - ul[i::k] = ssl - pl[i::k] = ssl - self.assertEqual(pl, ul[:], 'set slice [%d::%d]' % (i, k)) - - ssl = nextRange( len(ul[:i:k]) ) - ul[:i:k] = ssl - pl[:i:k] = ssl - self.assertEqual(pl, ul[:], 'set slice [:%d:%d]' % (i, k)) - - for k in self.step_range(): - ssl = nextRange(len(ul[::k])) - ul[::k] = ssl - pl[::k] = ssl - self.assertEqual(pl, ul[:], 'set slice [::%d]' % (k)) - - - def test03_delslice(self): - 'Delete slice' - for Len in range(self.limit): - pl, ul = self.lists_of_len(Len) - del pl[:] - del ul[:] - self.assertEqual(pl[:], ul[:], 'del slice [:]') - for i in range(-Len - 1, Len + 1): - pl, ul = self.lists_of_len(Len) - del pl[i:] - del ul[i:] - self.assertEqual(pl[:], ul[:], 'del slice [%d:]' % (i)) - pl, ul = self.lists_of_len(Len) - del pl[:i] - del ul[:i] - self.assertEqual(pl[:], ul[:], 'del slice [:%d]' % (i)) - for j in range(-Len - 1, Len + 1): - pl, ul = self.lists_of_len(Len) - del pl[i:j] - del ul[i:j] - self.assertEqual(pl[:], ul[:], 'del slice [%d:%d]' % (i,j)) - for k in range(-Len - 1,0) + range(1,Len): - pl, ul = self.lists_of_len(Len) - del pl[i:j:k] - del ul[i:j:k] - self.assertEqual(pl[:], ul[:], 'del slice [%d:%d:%d]' % (i,j,k)) - - for k in range(-Len - 1,0) + range(1,Len): - pl, ul = self.lists_of_len(Len) - del pl[:i:k] - del ul[:i:k] - self.assertEqual(pl[:], ul[:], 'del slice [:%d:%d]' % (i,k)) - - pl, ul = self.lists_of_len(Len) - del pl[i::k] - del ul[i::k] - self.assertEqual(pl[:], ul[:], 'del slice [%d::%d]' % (i,k)) - - for k in range(-Len - 1,0) + range(1,Len): - pl, ul = self.lists_of_len(Len) - del pl[::k] - del ul[::k] - self.assertEqual(pl[:], ul[:], 'del slice [::%d]' % (k)) - - def test04_get_set_del_single(self): - 'Get/set/delete single item' - pl, ul = self.lists_of_len() - for i in self.limits_plus(0): - self.assertEqual(pl[i], ul[i], 'get single item [%d]' % i) - - for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - pl[i] = 100 - ul[i] = 100 - self.assertEqual(pl[:], ul[:], 'set single item [%d]' % i) - - for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - del pl[i] - del ul[i] - self.assertEqual(pl[:], ul[:], 'del single item [%d]' % i) - - def test05_out_of_range_exceptions(self): - 'Out of range exceptions' - def setfcn(x, i): x[i] = 20 - def getfcn(x, i): return x[i] - def delfcn(x, i): del x[i] - pl, ul = self.lists_of_len() - for i in (-1 - self.limit, self.limit): - self.assertRaises(IndexError, setfcn, ul, i) # 'set index %d' % i) - self.assertRaises(IndexError, getfcn, ul, i) # 'get index %d' % i) - self.assertRaises(IndexError, delfcn, ul, i) # 'del index %d' % i) - - def test06_list_methods(self): - 'List methods' - pl, ul = self.lists_of_len() - pl.append(40) - ul.append(40) - self.assertEqual(pl[:], ul[:], 'append') - - pl.extend(range(50,55)) - ul.extend(range(50,55)) - self.assertEqual(pl[:], ul[:], 'extend') - - pl.reverse() - ul.reverse() - self.assertEqual(pl[:], ul[:], 'reverse') - - for i in self.limits_plus(1): - pl, ul = self.lists_of_len() - pl.insert(i,50) - ul.insert(i,50) - self.assertEqual(pl[:], ul[:], 'insert at %d' % i) - - for i in self.limits_plus(0): - pl, ul = self.lists_of_len() - self.assertEqual(pl.pop(i), ul.pop(i), 'popped value at %d' % i) - self.assertEqual(pl[:], ul[:], 'after pop at %d' % i) - - pl, ul = self.lists_of_len() - self.assertEqual(pl.pop(), ul.pop(i), 'popped value') - self.assertEqual(pl[:], ul[:], 'after pop') - - pl, ul = self.lists_of_len() - def popfcn(x, i): x.pop(i) - self.assertRaises(IndexError, popfcn, ul, self.limit) - self.assertRaises(IndexError, popfcn, ul, -1 - self.limit) - - pl, ul = self.lists_of_len() - for val in range(self.limit): - self.assertEqual(pl.index(val), ul.index(val), 'index of %d' % val) - - for val in self.limits_plus(2): - self.assertEqual(pl.count(val), ul.count(val), 'count %d' % val) - - for val in range(self.limit): - pl, ul = self.lists_of_len() - pl.remove(val) - ul.remove(val) - self.assertEqual(pl[:], ul[:], 'after remove val %d' % val) - - def indexfcn(x, v): return x.index(v) - def removefcn(x, v): return x.remove(v) - self.assertRaises(ValueError, indexfcn, ul, 40) - self.assertRaises(ValueError, removefcn, ul, 40) - - def test07_allowed_types(self): - 'Type-restricted list' - pl, ul = self.lists_of_len() - ul._allowed = (int, long) - ul[1] = 50 - ul[:2] = [60, 70, 80] - def setfcn(x, i, v): x[i] = v - self.assertRaises(TypeError, setfcn, ul, 2, 'hello') - self.assertRaises(TypeError, setfcn, ul, slice(0,3,2), ('hello','goodbye')) - - def test08_min_length(self): - 'Length limits' - pl, ul = self.lists_of_len() - ul._minlength = 1 - def delfcn(x,i): del x[:i] - def setfcn(x,i): x[:i] = [] - for i in range(self.limit - ul._minlength + 1, self.limit + 1): - self.assertRaises(ValueError, delfcn, ul, i) - self.assertRaises(ValueError, setfcn, ul, i) - del ul[:ul._minlength] - - ul._maxlength = 4 - for i in range(0, ul._maxlength - len(ul)): - ul.append(i) - self.assertRaises(ValueError, ul.append, 10) - - def test09_iterable_check(self): - 'Error on assigning non-iterable to slice' - pl, ul = self.lists_of_len(self.limit + 1) - def setfcn(x, i, v): x[i] = v - self.assertRaises(TypeError, setfcn, ul, slice(0,3,2), 2) - - def test10_checkindex(self): - 'Index check' - pl, ul = self.lists_of_len() - for i in self.limits_plus(0): - if i < 0: - self.assertEqual(ul._checkindex(i), i + self.limit, '_checkindex(neg index)') - else: - self.assertEqual(ul._checkindex(i), i, '_checkindex(pos index)') - - for i in (-self.limit - 1, self.limit): - self.assertRaises(IndexError, ul._checkindex, i) - - ul._IndexError = TypeError - self.assertRaises(TypeError, ul._checkindex, -self.limit - 1) - - def test_11_sorting(self): - 'Sorting' - pl, ul = self.lists_of_len() - pl.insert(0, pl.pop()) - ul.insert(0, ul.pop()) - pl.sort() - ul.sort() - self.assertEqual(pl[:], ul[:], 'sort') - mid = pl[len(pl) / 2] - pl.sort(key=lambda x: (mid-x)**2) - ul.sort(key=lambda x: (mid-x)**2) - self.assertEqual(pl[:], ul[:], 'sort w/ key') - - pl.insert(0, pl.pop()) - ul.insert(0, ul.pop()) - pl.sort(reverse=True) - ul.sort(reverse=True) - self.assertEqual(pl[:], ul[:], 'sort w/ reverse') - mid = pl[len(pl) / 2] - pl.sort(key=lambda x: (mid-x)**2) - ul.sort(key=lambda x: (mid-x)**2) - self.assertEqual(pl[:], ul[:], 'sort w/ key') - - def test_12_arithmetic(self): - 'Arithmetic' - pl, ul = self.lists_of_len() - al = range(10,14) - self.assertEqual(list(pl + al), list(ul + al), 'add') - self.assertEqual(type(ul), type(ul + al), 'type of add result') - self.assertEqual(list(al + pl), list(al + ul), 'radd') - self.assertEqual(type(al), type(al + ul), 'type of radd result') - objid = id(ul) - pl += al - ul += al - self.assertEqual(pl[:], ul[:], 'in-place add') - self.assertEqual(objid, id(ul), 'in-place add id') - - for n in (-1,0,1,3): - pl, ul = self.lists_of_len() - self.assertEqual(list(pl * n), list(ul * n), 'mul by %d' % n) - self.assertEqual(type(ul), type(ul * n), 'type of mul by %d result' % n) - self.assertEqual(list(n * pl), list(n * ul), 'rmul by %d' % n) - self.assertEqual(type(ul), type(n * ul), 'type of rmul by %d result' % n) - objid = id(ul) - pl *= n - ul *= n - self.assertEqual(pl[:], ul[:], 'in-place mul by %d' % n) - self.assertEqual(objid, id(ul), 'in-place mul by %d id' % n) - - pl, ul = self.lists_of_len() - self.assertEqual(pl, ul, 'cmp for equal') - self.assert_(pl >= ul, 'cmp for gte self') - self.assert_(pl <= ul, 'cmp for lte self') - self.assert_(ul >= pl, 'cmp for self gte') - self.assert_(ul <= pl, 'cmp for self lte') - - self.assert_(pl + [5] > ul, 'cmp') - self.assert_(pl + [5] >= ul, 'cmp') - self.assert_(pl < ul + [2], 'cmp') - self.assert_(pl <= ul + [2], 'cmp') - self.assert_(ul + [5] > pl, 'cmp') - self.assert_(ul + [5] >= pl, 'cmp') - self.assert_(ul < pl + [2], 'cmp') - self.assert_(ul <= pl + [2], 'cmp') - - pl[1] = 20 - self.assert_(pl > ul, 'cmp for gt self') - self.assert_(ul < pl, 'cmp for self lt') - pl[1] = -20 - self.assert_(pl < ul, 'cmp for lt self') - self.assert_(pl < ul, 'cmp for lt self') - -class ListMixinTestSingle(ListMixinTest): - listType = UserListB - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(ListMixinTest)) - s.addTest(unittest.makeSuite(ListMixinTestSingle)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) - -if __name__ == '__main__': - run() diff --git a/parts/django/django/contrib/gis/management/__init__.py b/parts/django/django/contrib/gis/management/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/management/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/management/base.py b/parts/django/django/contrib/gis/management/base.py deleted file mode 100644 index c998063..0000000 --- a/parts/django/django/contrib/gis/management/base.py +++ /dev/null @@ -1,15 +0,0 @@ -from django.core.management.base import BaseCommand, CommandError - -class ArgsCommand(BaseCommand): - """ - Command class for commands that take multiple arguments. - """ - args = '<arg arg ...>' - - def handle(self, *args, **options): - if not args: - raise CommandError('Must provide the following arguments: %s' % self.args) - return self.handle_args(*args, **options) - - def handle_args(self, *args, **options): - raise NotImplementedError() diff --git a/parts/django/django/contrib/gis/management/commands/__init__.py b/parts/django/django/contrib/gis/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/management/commands/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/management/commands/inspectdb.py b/parts/django/django/contrib/gis/management/commands/inspectdb.py deleted file mode 100644 index 937bb8e..0000000 --- a/parts/django/django/contrib/gis/management/commands/inspectdb.py +++ /dev/null @@ -1,32 +0,0 @@ -from optparse import make_option - -from django.core.management.base import CommandError -from django.core.management.commands.inspectdb import Command as InspectDBCommand - -class Command(InspectDBCommand): - db_module = 'django.contrib.gis.db' - gis_tables = {} - - def get_field_type(self, connection, table_name, row): - field_type, field_params, field_notes = super(Command, self).get_field_type(connection, table_name, row) - if field_type == 'GeometryField': - geo_col = row[0] - # Getting a more specific field type and any additional parameters - # from the `get_geometry_type` routine for the spatial backend. - field_type, geo_params = connection.introspection.get_geometry_type(table_name, geo_col) - field_params.update(geo_params) - # Adding the table name and column to the `gis_tables` dictionary, this - # allows us to track which tables need a GeoManager. - if table_name in self.gis_tables: - self.gis_tables[table_name].append(geo_col) - else: - self.gis_tables[table_name] = [geo_col] - return field_type, field_params, field_notes - - def get_meta(self, table_name): - meta_lines = super(Command, self).get_meta(table_name) - if table_name in self.gis_tables: - # If the table is a geographic one, then we need make - # GeoManager the default manager for the model. - meta_lines.insert(0, ' objects = models.GeoManager()') - return meta_lines diff --git a/parts/django/django/contrib/gis/management/commands/ogrinspect.py b/parts/django/django/contrib/gis/management/commands/ogrinspect.py deleted file mode 100644 index a495787..0000000 --- a/parts/django/django/contrib/gis/management/commands/ogrinspect.py +++ /dev/null @@ -1,122 +0,0 @@ -import os, sys -from optparse import make_option -from django.contrib.gis import gdal -from django.contrib.gis.management.base import ArgsCommand, CommandError - -def layer_option(option, opt, value, parser): - """ - Callback for `make_option` for the `ogrinspect` `layer_key` - keyword option which may be an integer or a string. - """ - try: - dest = int(value) - except ValueError: - dest = value - setattr(parser.values, option.dest, dest) - -def list_option(option, opt, value, parser): - """ - Callback for `make_option` for `ogrinspect` keywords that require - a string list. If the string is 'True'/'true' then the option - value will be a boolean instead. - """ - if value.lower() == 'true': - dest = True - else: - dest = [s for s in value.split(',')] - setattr(parser.values, option.dest, dest) - -class Command(ArgsCommand): - help = ('Inspects the given OGR-compatible data source (e.g., a shapefile) and outputs\n' - 'a GeoDjango model with the given model name. For example:\n' - ' ./manage.py ogrinspect zipcode.shp Zipcode') - args = '[data_source] [model_name]' - - option_list = ArgsCommand.option_list + ( - make_option('--blank', dest='blank', type='string', action='callback', - callback=list_option, default=False, - help='Use a comma separated list of OGR field names to add ' - 'the `blank=True` option to the field definition. Set with' - '`true` to apply to all applicable fields.'), - make_option('--decimal', dest='decimal', type='string', action='callback', - callback=list_option, default=False, - help='Use a comma separated list of OGR float fields to ' - 'generate `DecimalField` instead of the default ' - '`FloatField`. Set to `true` to apply to all OGR float fields.'), - make_option('--geom-name', dest='geom_name', type='string', default='geom', - help='Specifies the model name for the Geometry Field ' - '(defaults to `geom`)'), - make_option('--layer', dest='layer_key', type='string', action='callback', - callback=layer_option, default=0, - help='The key for specifying which layer in the OGR data ' - 'source to use. Defaults to 0 (the first layer). May be ' - 'an integer or a string identifier for the layer.'), - make_option('--multi-geom', action='store_true', dest='multi_geom', default=False, - help='Treat the geometry in the data source as a geometry collection.'), - make_option('--name-field', dest='name_field', - help='Specifies a field name to return for the `__unicode__` function.'), - make_option('--no-imports', action='store_false', dest='imports', default=True, - help='Do not include `from django.contrib.gis.db import models` ' - 'statement.'), - make_option('--null', dest='null', type='string', action='callback', - callback=list_option, default=False, - help='Use a comma separated list of OGR field names to add ' - 'the `null=True` option to the field definition. Set with' - '`true` to apply to all applicable fields.'), - make_option('--srid', dest='srid', - help='The SRID to use for the Geometry Field. If it can be ' - 'determined, the SRID of the data source is used.'), - make_option('--mapping', action='store_true', dest='mapping', - help='Generate mapping dictionary for use with `LayerMapping`.') - ) - - requires_model_validation = False - - def handle_args(self, *args, **options): - try: - data_source, model_name = args - except ValueError: - raise CommandError('Invalid arguments, must provide: %s' % self.args) - - if not gdal.HAS_GDAL: - raise CommandError('GDAL is required to inspect geospatial data sources.') - - # TODO: Support non file-based OGR datasources. - if not os.path.isfile(data_source): - raise CommandError('The given data source cannot be found: "%s"' % data_source) - - # Removing options with `None` values. - options = dict([(k, v) for k, v in options.items() if not v is None]) - - # Getting the OGR DataSource from the string parameter. - try: - ds = gdal.DataSource(data_source) - except gdal.OGRException, msg: - raise CommandError(msg) - - # Whether the user wants to generate the LayerMapping dictionary as well. - show_mapping = options.pop('mapping', False) - - # Popping the verbosity global option, as it's not accepted by `_ogrinspect`. - verbosity = options.pop('verbosity', False) - - # Returning the output of ogrinspect with the given arguments - # and options. - from django.contrib.gis.utils.ogrinspect import _ogrinspect, mapping - output = [s for s in _ogrinspect(ds, model_name, **options)] - if show_mapping: - # Constructing the keyword arguments for `mapping`, and - # calling it on the data source. - kwargs = {'geom_name' : options['geom_name'], - 'layer_key' : options['layer_key'], - 'multi_geom' : options['multi_geom'], - } - mapping_dict = mapping(ds, **kwargs) - # This extra legwork is so that the dictionary definition comes - # out in the same order as the fields in the model definition. - rev_mapping = dict([(v, k) for k, v in mapping_dict.items()]) - output.extend(['', '# Auto-generated `LayerMapping` dictionary for %s model' % model_name, - '%s_mapping = {' % model_name.lower()]) - output.extend([" '%s' : '%s'," % (rev_mapping[ogr_fld], ogr_fld) for ogr_fld in ds[options['layer_key']].fields]) - output.extend([" '%s' : '%s'," % (options['geom_name'], mapping_dict[options['geom_name']]), '}']) - return '\n'.join(output) diff --git a/parts/django/django/contrib/gis/maps/__init__.py b/parts/django/django/contrib/gis/maps/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/maps/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/maps/google/__init__.py b/parts/django/django/contrib/gis/maps/google/__init__.py deleted file mode 100644 index 9be689c..0000000 --- a/parts/django/django/contrib/gis/maps/google/__init__.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - This module houses the GoogleMap object, used for generating - the needed javascript to embed Google Maps in a Web page. - - Google(R) is a registered trademark of Google, Inc. of Mountain View, California. - - Example: - - * In the view: - return render_to_response('template.html', {'google' : GoogleMap(key="abcdefg")}) - - * In the template: - - <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> - {{ google.xhtml }} - <head> - <title>Google Maps via GeoDjango</title> - {{ google.style }} - {{ google.scripts }} - </head> - {{ google.body }} - <div id="{{ google.dom_id }}" style="width:600px;height:400px;"></div> - </body> - </html> - - Note: If you want to be more explicit in your templates, the following are - equivalent: - {{ google.body }} => "<body {{ google.onload }} {{ google.onunload }}>" - {{ google.xhtml }} => "<html xmlns="http://www.w3.org/1999/xhtml" {{ google.xmlns }}>" - {{ google.style }} => "<style>{{ google.vml_css }}</style>" - - Explanation: - - The `xhtml` property provides the correct XML namespace needed for - Google Maps to operate in IE using XHTML. Google Maps on IE uses - VML to draw polylines. Returns, by default: - <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml"> - - - The `style` property provides the correct style tag for the CSS - properties required by Google Maps on IE: - <style type="text/css">v\:* {behavior:url(#default#VML);}</style> - - - The `scripts` property provides the necessary <script> tags for - including the Google Maps javascript, as well as including the - generated javascript. - - - The `body` property provides the correct attributes for the - body tag to load the generated javascript. By default, returns: - <body onload="gmap_load()" onunload="GUnload()"> - - - The `dom_id` property returns the DOM id for the map. Defaults to "map". - - The following attributes may be set or customized in your local settings: - * GOOGLE_MAPS_API_KEY: String of your Google Maps API key. These are tied to - to a domain. May be obtained from http://www.google.com/apis/maps/ - * GOOGLE_MAPS_API_VERSION (optional): Defaults to using "2.x" - * GOOGLE_MAPS_URL (optional): Must have a substitution ('%s') for the API - version. -""" -from django.contrib.gis.maps.google.gmap import GoogleMap, GoogleMapSet -from django.contrib.gis.maps.google.overlays import GEvent, GIcon, GMarker, GPolygon, GPolyline -from django.contrib.gis.maps.google.zoom import GoogleZoom diff --git a/parts/django/django/contrib/gis/maps/google/gmap.py b/parts/django/django/contrib/gis/maps/google/gmap.py deleted file mode 100644 index cca5dc9..0000000 --- a/parts/django/django/contrib/gis/maps/google/gmap.py +++ /dev/null @@ -1,226 +0,0 @@ -from django.conf import settings -from django.contrib.gis import geos -from django.template.loader import render_to_string -from django.utils.safestring import mark_safe - -class GoogleMapException(Exception): pass -from django.contrib.gis.maps.google.overlays import GPolygon, GPolyline, GMarker, GIcon - -# The default Google Maps URL (for the API javascript) -# TODO: Internationalize for Japan, UK, etc. -GOOGLE_MAPS_URL='http://maps.google.com/maps?file=api&v=%s&key=' - -class GoogleMap(object): - "A class for generating Google Maps JavaScript." - - # String constants - onunload = mark_safe('onunload="GUnload()"') # Cleans up after Google Maps - vml_css = mark_safe('v\:* {behavior:url(#default#VML);}') # CSS for IE VML - xmlns = mark_safe('xmlns:v="urn:schemas-microsoft-com:vml"') # XML Namespace (for IE VML). - - def __init__(self, key=None, api_url=None, version=None, - center=None, zoom=None, dom_id='map', - kml_urls=[], polylines=None, polygons=None, markers=None, - template='gis/google/google-map.js', - js_module='geodjango', - extra_context={}): - - # The Google Maps API Key defined in the settings will be used - # if not passed in as a parameter. The use of an API key is - # _required_. - if not key: - try: - self.key = settings.GOOGLE_MAPS_API_KEY - except AttributeError: - raise GoogleMapException('Google Maps API Key not found (try adding GOOGLE_MAPS_API_KEY to your settings).') - else: - self.key = key - - # Getting the Google Maps API version, defaults to using the latest ("2.x"), - # this is not necessarily the most stable. - if not version: - self.version = getattr(settings, 'GOOGLE_MAPS_API_VERSION', '2.x') - else: - self.version = version - - # Can specify the API URL in the `api_url` keyword. - if not api_url: - self.api_url = mark_safe(getattr(settings, 'GOOGLE_MAPS_URL', GOOGLE_MAPS_URL) % self.version) - else: - self.api_url = api_url - - # Setting the DOM id of the map, the load function, the JavaScript - # template, and the KML URLs array. - self.dom_id = dom_id - self.extra_context = extra_context - self.js_module = js_module - self.template = template - self.kml_urls = kml_urls - - # Does the user want any GMarker, GPolygon, and/or GPolyline overlays? - overlay_info = [[GMarker, markers, 'markers'], - [GPolygon, polygons, 'polygons'], - [GPolyline, polylines, 'polylines']] - - for overlay_class, overlay_list, varname in overlay_info: - setattr(self, varname, []) - if overlay_list: - for overlay in overlay_list: - if isinstance(overlay, overlay_class): - getattr(self, varname).append(overlay) - else: - getattr(self, varname).append(overlay_class(overlay)) - - # If GMarker, GPolygons, and/or GPolylines are used the zoom will be - # automatically calculated via the Google Maps API. If both a zoom - # level and a center coordinate are provided with polygons/polylines, - # no automatic determination will occur. - self.calc_zoom = False - if self.polygons or self.polylines or self.markers: - if center is None or zoom is None: - self.calc_zoom = True - - # Defaults for the zoom level and center coordinates if the zoom - # is not automatically calculated. - if zoom is None: zoom = 4 - self.zoom = zoom - if center is None: center = (0, 0) - self.center = center - - def render(self): - """ - Generates the JavaScript necessary for displaying this Google Map. - """ - params = {'calc_zoom' : self.calc_zoom, - 'center' : self.center, - 'dom_id' : self.dom_id, - 'js_module' : self.js_module, - 'kml_urls' : self.kml_urls, - 'zoom' : self.zoom, - 'polygons' : self.polygons, - 'polylines' : self.polylines, - 'icons': self.icons, - 'markers' : self.markers, - } - params.update(self.extra_context) - return render_to_string(self.template, params) - - @property - def body(self): - "Returns HTML body tag for loading and unloading Google Maps javascript." - return mark_safe('<body %s %s>' % (self.onload, self.onunload)) - - @property - def onload(self): - "Returns the `onload` HTML <body> attribute." - return mark_safe('onload="%s.%s_load()"' % (self.js_module, self.dom_id)) - - @property - def api_script(self): - "Returns the <script> tag for the Google Maps API javascript." - return mark_safe('<script src="%s%s" type="text/javascript"></script>' % (self.api_url, self.key)) - - @property - def js(self): - "Returns only the generated Google Maps JavaScript (no <script> tags)." - return self.render() - - @property - def scripts(self): - "Returns all <script></script> tags required with Google Maps JavaScript." - return mark_safe('%s\n <script type="text/javascript">\n//<![CDATA[\n%s//]]>\n </script>' % (self.api_script, self.js)) - - @property - def style(self): - "Returns additional CSS styling needed for Google Maps on IE." - return mark_safe('<style type="text/css">%s</style>' % self.vml_css) - - @property - def xhtml(self): - "Returns XHTML information needed for IE VML overlays." - return mark_safe('<html xmlns="http://www.w3.org/1999/xhtml" %s>' % self.xmlns) - - @property - def icons(self): - "Returns a sequence of GIcon objects in this map." - return set([marker.icon for marker in self.markers if marker.icon]) - -class GoogleMapSet(GoogleMap): - - def __init__(self, *args, **kwargs): - """ - A class for generating sets of Google Maps that will be shown on the - same page together. - - Example: - gmapset = GoogleMapSet( GoogleMap( ... ), GoogleMap( ... ) ) - gmapset = GoogleMapSet( [ gmap1, gmap2] ) - """ - # The `google-multi.js` template is used instead of `google-single.js` - # by default. - template = kwargs.pop('template', 'gis/google/google-multi.js') - - # This is the template used to generate the GMap load JavaScript for - # each map in the set. - self.map_template = kwargs.pop('map_template', 'gis/google/google-single.js') - - # Running GoogleMap.__init__(), and resetting the template - # value with default obtained above. - super(GoogleMapSet, self).__init__(**kwargs) - self.template = template - - # If a tuple/list passed in as first element of args, then assume - if isinstance(args[0], (tuple, list)): - self.maps = args[0] - else: - self.maps = args - - # Generating DOM ids for each of the maps in the set. - self.dom_ids = ['map%d' % i for i in xrange(len(self.maps))] - - def load_map_js(self): - """ - Returns JavaScript containing all of the loading routines for each - map in this set. - """ - result = [] - for dom_id, gmap in zip(self.dom_ids, self.maps): - # Backup copies the GoogleMap DOM id and template attributes. - # They are overridden on each GoogleMap instance in the set so - # that only the loading JavaScript (and not the header variables) - # is used with the generated DOM ids. - tmp = (gmap.template, gmap.dom_id) - gmap.template = self.map_template - gmap.dom_id = dom_id - result.append(gmap.js) - # Restoring the backup values. - gmap.template, gmap.dom_id = tmp - return mark_safe(''.join(result)) - - def render(self): - """ - Generates the JavaScript for the collection of Google Maps in - this set. - """ - params = {'js_module' : self.js_module, - 'dom_ids' : self.dom_ids, - 'load_map_js' : self.load_map_js(), - 'icons' : self.icons, - } - params.update(self.extra_context) - return render_to_string(self.template, params) - - @property - def onload(self): - "Returns the `onload` HTML <body> attribute." - # Overloaded to use the `load` function defined in the - # `google-multi.js`, which calls the load routines for - # each one of the individual maps in the set. - return mark_safe('onload="%s.load()"' % self.js_module) - - @property - def icons(self): - "Returns a sequence of all icons in each map of the set." - icons = set() - for map in self.maps: icons |= map.icons - return icons diff --git a/parts/django/django/contrib/gis/maps/google/overlays.py b/parts/django/django/contrib/gis/maps/google/overlays.py deleted file mode 100644 index c2ebb3c..0000000 --- a/parts/django/django/contrib/gis/maps/google/overlays.py +++ /dev/null @@ -1,301 +0,0 @@ -from django.utils.safestring import mark_safe -from django.contrib.gis.geos import fromstr, Point, LineString, LinearRing, Polygon - -class GEvent(object): - """ - A Python wrapper for the Google GEvent object. - - Events can be attached to any object derived from GOverlayBase with the - add_event() call. - - For more information please see the Google Maps API Reference: - http://code.google.com/apis/maps/documentation/reference.html#GEvent - - Example: - - from django.shortcuts import render_to_response - from django.contrib.gis.maps.google import GoogleMap, GEvent, GPolyline - - def sample_request(request): - polyline = GPolyline('LINESTRING(101 26, 112 26, 102 31)') - event = GEvent('click', - 'function() { location.href = "http://www.google.com"}') - polyline.add_event(event) - return render_to_response('mytemplate.html', - {'google' : GoogleMap(polylines=[polyline])}) - """ - - def __init__(self, event, action): - """ - Initializes a GEvent object. - - Parameters: - - event: - string for the event, such as 'click'. The event must be a valid - event for the object in the Google Maps API. - There is no validation of the event type within Django. - - action: - string containing a Javascript function, such as - 'function() { location.href = "newurl";}' - The string must be a valid Javascript function. Again there is no - validation fo the function within Django. - """ - self.event = event - self.action = action - - def __unicode__(self): - "Returns the parameter part of a GEvent." - return mark_safe('"%s", %s' %(self.event, self.action)) - -class GOverlayBase(object): - def __init__(self): - self.events = [] - - def latlng_from_coords(self, coords): - "Generates a JavaScript array of GLatLng objects for the given coordinates." - return '[%s]' % ','.join(['new GLatLng(%s,%s)' % (y, x) for x, y in coords]) - - def add_event(self, event): - "Attaches a GEvent to the overlay object." - self.events.append(event) - - def __unicode__(self): - "The string representation is the JavaScript API call." - return mark_safe('%s(%s)' % (self.__class__.__name__, self.js_params)) - -class GPolygon(GOverlayBase): - """ - A Python wrapper for the Google GPolygon object. For more information - please see the Google Maps API Reference: - http://code.google.com/apis/maps/documentation/reference.html#GPolygon - """ - def __init__(self, poly, - stroke_color='#0000ff', stroke_weight=2, stroke_opacity=1, - fill_color='#0000ff', fill_opacity=0.4): - """ - The GPolygon object initializes on a GEOS Polygon or a parameter that - may be instantiated into GEOS Polygon. Please note that this will not - depict a Polygon's internal rings. - - Keyword Options: - - stroke_color: - The color of the polygon outline. Defaults to '#0000ff' (blue). - - stroke_weight: - The width of the polygon outline, in pixels. Defaults to 2. - - stroke_opacity: - The opacity of the polygon outline, between 0 and 1. Defaults to 1. - - fill_color: - The color of the polygon fill. Defaults to '#0000ff' (blue). - - fill_opacity: - The opacity of the polygon fill. Defaults to 0.4. - """ - if isinstance(poly, basestring): poly = fromstr(poly) - if isinstance(poly, (tuple, list)): poly = Polygon(poly) - if not isinstance(poly, Polygon): - raise TypeError('GPolygon may only initialize on GEOS Polygons.') - - # Getting the envelope of the input polygon (used for automatically - # determining the zoom level). - self.envelope = poly.envelope - - # Translating the coordinates into a JavaScript array of - # Google `GLatLng` objects. - self.points = self.latlng_from_coords(poly.shell.coords) - - # Stroke settings. - self.stroke_color, self.stroke_opacity, self.stroke_weight = stroke_color, stroke_opacity, stroke_weight - - # Fill settings. - self.fill_color, self.fill_opacity = fill_color, fill_opacity - - super(GPolygon, self).__init__() - - @property - def js_params(self): - return '%s, "%s", %s, %s, "%s", %s' % (self.points, self.stroke_color, self.stroke_weight, self.stroke_opacity, - self.fill_color, self.fill_opacity) - -class GPolyline(GOverlayBase): - """ - A Python wrapper for the Google GPolyline object. For more information - please see the Google Maps API Reference: - http://code.google.com/apis/maps/documentation/reference.html#GPolyline - """ - def __init__(self, geom, color='#0000ff', weight=2, opacity=1): - """ - The GPolyline object may be initialized on GEOS LineStirng, LinearRing, - and Polygon objects (internal rings not supported) or a parameter that - may instantiated into one of the above geometries. - - Keyword Options: - - color: - The color to use for the polyline. Defaults to '#0000ff' (blue). - - weight: - The width of the polyline, in pixels. Defaults to 2. - - opacity: - The opacity of the polyline, between 0 and 1. Defaults to 1. - """ - # If a GEOS geometry isn't passed in, try to contsruct one. - if isinstance(geom, basestring): geom = fromstr(geom) - if isinstance(geom, (tuple, list)): geom = Polygon(geom) - # Generating the lat/lng coordinate pairs. - if isinstance(geom, (LineString, LinearRing)): - self.latlngs = self.latlng_from_coords(geom.coords) - elif isinstance(geom, Polygon): - self.latlngs = self.latlng_from_coords(geom.shell.coords) - else: - raise TypeError('GPolyline may only initialize on GEOS LineString, LinearRing, and/or Polygon geometries.') - - # Getting the envelope for automatic zoom determination. - self.envelope = geom.envelope - self.color, self.weight, self.opacity = color, weight, opacity - super(GPolyline, self).__init__() - - @property - def js_params(self): - return '%s, "%s", %s, %s' % (self.latlngs, self.color, self.weight, self.opacity) - - -class GIcon(object): - """ - Creates a GIcon object to pass into a Gmarker object. - - The keyword arguments map to instance attributes of the same name. These, - in turn, correspond to a subset of the attributes of the official GIcon - javascript object: - - http://code.google.com/apis/maps/documentation/reference.html#GIcon - - Because a Google map often uses several different icons, a name field has - been added to the required arguments. - - Required Arguments: - varname: - A string which will become the basis for the js variable name of - the marker, for this reason, your code should assign a unique - name for each GIcon you instantiate, otherwise there will be - name space collisions in your javascript. - - Keyword Options: - image: - The url of the image to be used as the icon on the map defaults - to 'G_DEFAULT_ICON' - - iconsize: - a tuple representing the pixel size of the foreground (not the - shadow) image of the icon, in the format: (width, height) ex.: - - GIcon('fast_food', - image="/media/icon/star.png", - iconsize=(15,10)) - - Would indicate your custom icon was 15px wide and 10px height. - - shadow: - the url of the image of the icon's shadow - - shadowsize: - a tuple representing the pixel size of the shadow image, format is - the same as ``iconsize`` - - iconanchor: - a tuple representing the pixel coordinate relative to the top left - corner of the icon image at which this icon is anchored to the map. - In (x, y) format. x increases to the right in the Google Maps - coordinate system and y increases downwards in the Google Maps - coordinate system.) - - infowindowanchor: - The pixel coordinate relative to the top left corner of the icon - image at which the info window is anchored to this icon. - - """ - def __init__(self, varname, image=None, iconsize=None, - shadow=None, shadowsize=None, iconanchor=None, - infowindowanchor=None): - self.varname = varname - self.image = image - self.iconsize = iconsize - self.shadow = shadow - self.shadowsize = shadowsize - self.iconanchor = iconanchor - self.infowindowanchor = infowindowanchor - - def __cmp__(self, other): - return cmp(self.varname, other.varname) - - def __hash__(self): - # XOR with hash of GIcon type so that hash('varname') won't - # equal hash(GIcon('varname')). - return hash(self.__class__) ^ hash(self.varname) - -class GMarker(GOverlayBase): - """ - A Python wrapper for the Google GMarker object. For more information - please see the Google Maps API Reference: - http://code.google.com/apis/maps/documentation/reference.html#GMarker - - Example: - - from django.shortcuts import render_to_response - from django.contrib.gis.maps.google.overlays import GMarker, GEvent - - def sample_request(request): - marker = GMarker('POINT(101 26)') - event = GEvent('click', - 'function() { location.href = "http://www.google.com"}') - marker.add_event(event) - return render_to_response('mytemplate.html', - {'google' : GoogleMap(markers=[marker])}) - """ - def __init__(self, geom, title=None, draggable=False, icon=None): - """ - The GMarker object may initialize on GEOS Points or a parameter - that may be instantiated into a GEOS point. Keyword options map to - GMarkerOptions -- so far only the title option is supported. - - Keyword Options: - title: - Title option for GMarker, will be displayed as a tooltip. - - draggable: - Draggable option for GMarker, disabled by default. - """ - # If a GEOS geometry isn't passed in, try to construct one. - if isinstance(geom, basestring): geom = fromstr(geom) - if isinstance(geom, (tuple, list)): geom = Point(geom) - if isinstance(geom, Point): - self.latlng = self.latlng_from_coords(geom.coords) - else: - raise TypeError('GMarker may only initialize on GEOS Point geometry.') - # Getting the envelope for automatic zoom determination. - self.envelope = geom.envelope - # TODO: Add support for more GMarkerOptions - self.title = title - self.draggable = draggable - self.icon = icon - super(GMarker, self).__init__() - - def latlng_from_coords(self, coords): - return 'new GLatLng(%s,%s)' %(coords[1], coords[0]) - - def options(self): - result = [] - if self.title: result.append('title: "%s"' % self.title) - if self.icon: result.append('icon: %s' % self.icon.varname) - if self.draggable: result.append('draggable: true') - return '{%s}' % ','.join(result) - - @property - def js_params(self): - return '%s, %s' % (self.latlng, self.options()) diff --git a/parts/django/django/contrib/gis/maps/google/zoom.py b/parts/django/django/contrib/gis/maps/google/zoom.py deleted file mode 100644 index abc3fbf..0000000 --- a/parts/django/django/contrib/gis/maps/google/zoom.py +++ /dev/null @@ -1,161 +0,0 @@ -from django.contrib.gis.geos import GEOSGeometry, LinearRing, Polygon, Point -from django.contrib.gis.maps.google.gmap import GoogleMapException -from math import pi, sin, cos, log, exp, atan - -# Constants used for degree to radian conversion, and vice-versa. -DTOR = pi / 180. -RTOD = 180. / pi - -class GoogleZoom(object): - """ - GoogleZoom is a utility for performing operations related to the zoom - levels on Google Maps. - - This class is inspired by the OpenStreetMap Mapnik tile generation routine - `generate_tiles.py`, and the article "How Big Is the World" (Hack #16) in - "Google Maps Hacks" by Rich Gibson and Schuyler Erle. - - `generate_tiles.py` may be found at: - http://trac.openstreetmap.org/browser/applications/rendering/mapnik/generate_tiles.py - - "Google Maps Hacks" may be found at http://safari.oreilly.com/0596101619 - """ - - def __init__(self, num_zoom=19, tilesize=256): - "Initializes the Google Zoom object." - # Google's tilesize is 256x256, square tiles are assumed. - self._tilesize = tilesize - - # The number of zoom levels - self._nzoom = num_zoom - - # Initializing arrays to hold the parameters for each one of the - # zoom levels. - self._degpp = [] # Degrees per pixel - self._radpp = [] # Radians per pixel - self._npix = [] # 1/2 the number of pixels for a tile at the given zoom level - - # Incrementing through the zoom levels and populating the parameter arrays. - z = tilesize # The number of pixels per zoom level. - for i in xrange(num_zoom): - # Getting the degrees and radians per pixel, and the 1/2 the number of - # for every zoom level. - self._degpp.append(z / 360.) # degrees per pixel - self._radpp.append(z / (2 * pi)) # radians per pixl - self._npix.append(z / 2) # number of pixels to center of tile - - # Multiplying `z` by 2 for the next iteration. - z *= 2 - - def __len__(self): - "Returns the number of zoom levels." - return self._nzoom - - def get_lon_lat(self, lonlat): - "Unpacks longitude, latitude from GEOS Points and 2-tuples." - if isinstance(lonlat, Point): - lon, lat = lonlat.coords - else: - lon, lat = lonlat - return lon, lat - - def lonlat_to_pixel(self, lonlat, zoom): - "Converts a longitude, latitude coordinate pair for the given zoom level." - # Setting up, unpacking the longitude, latitude values and getting the - # number of pixels for the given zoom level. - lon, lat = self.get_lon_lat(lonlat) - npix = self._npix[zoom] - - # Calculating the pixel x coordinate by multiplying the longitude value - # with with the number of degrees/pixel at the given zoom level. - px_x = round(npix + (lon * self._degpp[zoom])) - - # Creating the factor, and ensuring that 1 or -1 is not passed in as the - # base to the logarithm. Here's why: - # if fac = -1, we'll get log(0) which is undefined; - # if fac = 1, our logarithm base will be divided by 0, also undefined. - fac = min(max(sin(DTOR * lat), -0.9999), 0.9999) - - # Calculating the pixel y coordinate. - px_y = round(npix + (0.5 * log((1 + fac)/(1 - fac)) * (-1.0 * self._radpp[zoom]))) - - # Returning the pixel x, y to the caller of the function. - return (px_x, px_y) - - def pixel_to_lonlat(self, px, zoom): - "Converts a pixel to a longitude, latitude pair at the given zoom level." - if len(px) != 2: - raise TypeError('Pixel should be a sequence of two elements.') - - # Getting the number of pixels for the given zoom level. - npix = self._npix[zoom] - - # Calculating the longitude value, using the degrees per pixel. - lon = (px[0] - npix) / self._degpp[zoom] - - # Calculating the latitude value. - lat = RTOD * ( 2 * atan(exp((px[1] - npix)/ (-1.0 * self._radpp[zoom]))) - 0.5 * pi) - - # Returning the longitude, latitude coordinate pair. - return (lon, lat) - - def tile(self, lonlat, zoom): - """ - Returns a Polygon corresponding to the region represented by a fictional - Google Tile for the given longitude/latitude pair and zoom level. This - tile is used to determine the size of a tile at the given point. - """ - # The given lonlat is the center of the tile. - delta = self._tilesize / 2 - - # Getting the pixel coordinates corresponding to the - # the longitude/latitude. - px = self.lonlat_to_pixel(lonlat, zoom) - - # Getting the lower-left and upper-right lat/lon coordinates - # for the bounding box of the tile. - ll = self.pixel_to_lonlat((px[0]-delta, px[1]-delta), zoom) - ur = self.pixel_to_lonlat((px[0]+delta, px[1]+delta), zoom) - - # Constructing the Polygon, representing the tile and returning. - return Polygon(LinearRing(ll, (ll[0], ur[1]), ur, (ur[0], ll[1]), ll), srid=4326) - - def get_zoom(self, geom): - "Returns the optimal Zoom level for the given geometry." - # Checking the input type. - if not isinstance(geom, GEOSGeometry) or geom.srid != 4326: - raise TypeError('get_zoom() expects a GEOS Geometry with an SRID of 4326.') - - # Getting the envelope for the geometry, and its associated width, height - # and centroid. - env = geom.envelope - env_w, env_h = self.get_width_height(env.extent) - center = env.centroid - - for z in xrange(self._nzoom): - # Getting the tile at the zoom level. - tile_w, tile_h = self.get_width_height(self.tile(center, z).extent) - - # When we span more than one tile, this is an approximately good - # zoom level. - if (env_w > tile_w) or (env_h > tile_h): - if z == 0: - raise GoogleMapException('Geometry width and height should not exceed that of the Earth.') - return z-1 - - # Otherwise, we've zoomed in to the max. - return self._nzoom-1 - - def get_width_height(self, extent): - """ - Returns the width and height for the given extent. - """ - # Getting the lower-left, upper-left, and upper-right - # coordinates from the extent. - ll = Point(extent[:2]) - ul = Point(extent[0], extent[3]) - ur = Point(extent[2:]) - # Calculating the width and height. - height = ll.distance(ul) - width = ul.distance(ur) - return width, height diff --git a/parts/django/django/contrib/gis/maps/openlayers/__init__.py b/parts/django/django/contrib/gis/maps/openlayers/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/maps/openlayers/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/measure.py b/parts/django/django/contrib/gis/measure.py deleted file mode 100644 index a60398b..0000000 --- a/parts/django/django/contrib/gis/measure.py +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2007, Robert Coup <robert.coup@onetrackmind.co.nz> -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of Distance nor the names of its contributors may be used -# to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -""" -Distance and Area objects to allow for sensible and convienient calculation -and conversions. - -Authors: Robert Coup, Justin Bronn - -Inspired by GeoPy (http://exogen.case.edu/projects/geopy/) -and Geoff Biggs' PhD work on dimensioned units for robotics. -""" -__all__ = ['A', 'Area', 'D', 'Distance'] -from decimal import Decimal - -class MeasureBase(object): - def default_units(self, kwargs): - """ - Return the unit value and the default units specified - from the given keyword arguments dictionary. - """ - val = 0.0 - for unit, value in kwargs.iteritems(): - if not isinstance(value, float): value = float(value) - if unit in self.UNITS: - val += self.UNITS[unit] * value - default_unit = unit - elif unit in self.ALIAS: - u = self.ALIAS[unit] - val += self.UNITS[u] * value - default_unit = u - else: - lower = unit.lower() - if lower in self.UNITS: - val += self.UNITS[lower] * value - default_unit = lower - elif lower in self.LALIAS: - u = self.LALIAS[lower] - val += self.UNITS[u] * value - default_unit = u - else: - raise AttributeError('Unknown unit type: %s' % unit) - return val, default_unit - - @classmethod - def unit_attname(cls, unit_str): - """ - Retrieves the unit attribute name for the given unit string. - For example, if the given unit string is 'metre', 'm' would be returned. - An exception is raised if an attribute cannot be found. - """ - lower = unit_str.lower() - if unit_str in cls.UNITS: - return unit_str - elif lower in cls.UNITS: - return lower - elif lower in cls.LALIAS: - return cls.LALIAS[lower] - else: - raise Exception('Could not find a unit keyword associated with "%s"' % unit_str) - -class Distance(MeasureBase): - UNITS = { - 'chain' : 20.1168, - 'chain_benoit' : 20.116782, - 'chain_sears' : 20.1167645, - 'british_chain_benoit' : 20.1167824944, - 'british_chain_sears' : 20.1167651216, - 'british_chain_sears_truncated' : 20.116756, - 'cm' : 0.01, - 'british_ft' : 0.304799471539, - 'british_yd' : 0.914398414616, - 'clarke_ft' : 0.3047972654, - 'clarke_link' : 0.201166195164, - 'fathom' : 1.8288, - 'ft': 0.3048, - 'german_m' : 1.0000135965, - 'gold_coast_ft' : 0.304799710181508, - 'indian_yd' : 0.914398530744, - 'inch' : 0.0254, - 'km': 1000.0, - 'link' : 0.201168, - 'link_benoit' : 0.20116782, - 'link_sears' : 0.20116765, - 'm': 1.0, - 'mi': 1609.344, - 'mm' : 0.001, - 'nm': 1852.0, - 'nm_uk' : 1853.184, - 'rod' : 5.0292, - 'sears_yd' : 0.91439841, - 'survey_ft' : 0.304800609601, - 'um' : 0.000001, - 'yd': 0.9144, - } - - # Unit aliases for `UNIT` terms encountered in Spatial Reference WKT. - ALIAS = { - 'centimeter' : 'cm', - 'foot' : 'ft', - 'inches' : 'inch', - 'kilometer' : 'km', - 'kilometre' : 'km', - 'meter' : 'm', - 'metre' : 'm', - 'micrometer' : 'um', - 'micrometre' : 'um', - 'millimeter' : 'mm', - 'millimetre' : 'mm', - 'mile' : 'mi', - 'yard' : 'yd', - 'British chain (Benoit 1895 B)' : 'british_chain_benoit', - 'British chain (Sears 1922)' : 'british_chain_sears', - 'British chain (Sears 1922 truncated)' : 'british_chain_sears_truncated', - 'British foot (Sears 1922)' : 'british_ft', - 'British foot' : 'british_ft', - 'British yard (Sears 1922)' : 'british_yd', - 'British yard' : 'british_yd', - "Clarke's Foot" : 'clarke_ft', - "Clarke's link" : 'clarke_link', - 'Chain (Benoit)' : 'chain_benoit', - 'Chain (Sears)' : 'chain_sears', - 'Foot (International)' : 'ft', - 'German legal metre' : 'german_m', - 'Gold Coast foot' : 'gold_coast_ft', - 'Indian yard' : 'indian_yd', - 'Link (Benoit)': 'link_benoit', - 'Link (Sears)': 'link_sears', - 'Nautical Mile' : 'nm', - 'Nautical Mile (UK)' : 'nm_uk', - 'US survey foot' : 'survey_ft', - 'U.S. Foot' : 'survey_ft', - 'Yard (Indian)' : 'indian_yd', - 'Yard (Sears)' : 'sears_yd' - } - LALIAS = dict([(k.lower(), v) for k, v in ALIAS.items()]) - - def __init__(self, default_unit=None, **kwargs): - # The base unit is in meters. - self.m, self._default_unit = self.default_units(kwargs) - if default_unit and isinstance(default_unit, str): - self._default_unit = default_unit - - def __getattr__(self, name): - if name in self.UNITS: - return self.m / self.UNITS[name] - else: - raise AttributeError('Unknown unit type: %s' % name) - - def __repr__(self): - return 'Distance(%s=%s)' % (self._default_unit, getattr(self, self._default_unit)) - - def __str__(self): - return '%s %s' % (getattr(self, self._default_unit), self._default_unit) - - def __cmp__(self, other): - if isinstance(other, Distance): - return cmp(self.m, other.m) - else: - return NotImplemented - - def __add__(self, other): - if isinstance(other, Distance): - return Distance(default_unit=self._default_unit, m=(self.m + other.m)) - else: - raise TypeError('Distance must be added with Distance') - - def __iadd__(self, other): - if isinstance(other, Distance): - self.m += other.m - return self - else: - raise TypeError('Distance must be added with Distance') - - def __sub__(self, other): - if isinstance(other, Distance): - return Distance(default_unit=self._default_unit, m=(self.m - other.m)) - else: - raise TypeError('Distance must be subtracted from Distance') - - def __isub__(self, other): - if isinstance(other, Distance): - self.m -= other.m - return self - else: - raise TypeError('Distance must be subtracted from Distance') - - def __mul__(self, other): - if isinstance(other, (int, float, long, Decimal)): - return Distance(default_unit=self._default_unit, m=(self.m * float(other))) - elif isinstance(other, Distance): - return Area(default_unit='sq_' + self._default_unit, sq_m=(self.m * other.m)) - else: - raise TypeError('Distance must be multiplied with number or Distance') - - def __imul__(self, other): - if isinstance(other, (int, float, long, Decimal)): - self.m *= float(other) - return self - else: - raise TypeError('Distance must be multiplied with number') - - def __rmul__(self, other): - return self * other - - def __div__(self, other): - if isinstance(other, (int, float, long, Decimal)): - return Distance(default_unit=self._default_unit, m=(self.m / float(other))) - else: - raise TypeError('Distance must be divided with number') - - def __idiv__(self, other): - if isinstance(other, (int, float, long, Decimal)): - self.m /= float(other) - return self - else: - raise TypeError('Distance must be divided with number') - - def __nonzero__(self): - return bool(self.m) - -class Area(MeasureBase): - # Getting the square units values and the alias dictionary. - UNITS = dict([('sq_%s' % k, v ** 2) for k, v in Distance.UNITS.items()]) - ALIAS = dict([(k, 'sq_%s' % v) for k, v in Distance.ALIAS.items()]) - LALIAS = dict([(k.lower(), v) for k, v in ALIAS.items()]) - - def __init__(self, default_unit=None, **kwargs): - self.sq_m, self._default_unit = self.default_units(kwargs) - if default_unit and isinstance(default_unit, str): - self._default_unit = default_unit - - def __getattr__(self, name): - if name in self.UNITS: - return self.sq_m / self.UNITS[name] - else: - raise AttributeError('Unknown unit type: ' + name) - - def __repr__(self): - return 'Area(%s=%s)' % (self._default_unit, getattr(self, self._default_unit)) - - def __str__(self): - return '%s %s' % (getattr(self, self._default_unit), self._default_unit) - - def __cmp__(self, other): - if isinstance(other, Area): - return cmp(self.sq_m, other.sq_m) - else: - return NotImplemented - - def __add__(self, other): - if isinstance(other, Area): - return Area(default_unit=self._default_unit, sq_m=(self.sq_m + other.sq_m)) - else: - raise TypeError('Area must be added with Area') - - def __iadd__(self, other): - if isinstance(other, Area): - self.sq_m += other.sq_m - return self - else: - raise TypeError('Area must be added with Area') - - def __sub__(self, other): - if isinstance(other, Area): - return Area(default_unit=self._default_unit, sq_m=(self.sq_m - other.sq_m)) - else: - raise TypeError('Area must be subtracted from Area') - - def __isub__(self, other): - if isinstance(other, Area): - self.sq_m -= other.sq_m - return self - else: - raise TypeError('Area must be subtracted from Area') - - def __mul__(self, other): - if isinstance(other, (int, float, long, Decimal)): - return Area(default_unit=self._default_unit, sq_m=(self.sq_m * float(other))) - else: - raise TypeError('Area must be multiplied with number') - - def __imul__(self, other): - if isinstance(other, (int, float, long, Decimal)): - self.sq_m *= float(other) - return self - else: - raise TypeError('Area must be multiplied with number') - - def __rmul__(self, other): - return self * other - - def __div__(self, other): - if isinstance(other, (int, float, long, Decimal)): - return Area(default_unit=self._default_unit, sq_m=(self.sq_m / float(other))) - else: - raise TypeError('Area must be divided with number') - - def __idiv__(self, other): - if isinstance(other, (int, float, long, Decimal)): - self.sq_m /= float(other) - return self - else: - raise TypeError('Area must be divided with number') - - def __nonzero__(self): - return bool(self.sq_m) - -# Shortcuts -D = Distance -A = Area diff --git a/parts/django/django/contrib/gis/models.py b/parts/django/django/contrib/gis/models.py deleted file mode 100644 index e379e82..0000000 --- a/parts/django/django/contrib/gis/models.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.db import connection - -if (hasattr(connection.ops, 'spatial_version') and - not connection.ops.mysql): - # Getting the `SpatialRefSys` and `GeometryColumns` - # models for the default spatial backend. These - # aliases are provided for backwards-compatibility. - SpatialRefSys = connection.ops.spatial_ref_sys() - GeometryColumns = connection.ops.geometry_columns() diff --git a/parts/django/django/contrib/gis/shortcuts.py b/parts/django/django/contrib/gis/shortcuts.py deleted file mode 100644 index a6fb892..0000000 --- a/parts/django/django/contrib/gis/shortcuts.py +++ /dev/null @@ -1,32 +0,0 @@ -import cStringIO, zipfile -from django.conf import settings -from django.http import HttpResponse -from django.template import loader - -def compress_kml(kml): - "Returns compressed KMZ from the given KML string." - kmz = cStringIO.StringIO() - zf = zipfile.ZipFile(kmz, 'a', zipfile.ZIP_DEFLATED) - zf.writestr('doc.kml', kml.encode(settings.DEFAULT_CHARSET)) - zf.close() - kmz.seek(0) - return kmz.read() - -def render_to_kml(*args, **kwargs): - "Renders the response as KML (using the correct MIME type)." - return HttpResponse(loader.render_to_string(*args, **kwargs), - mimetype='application/vnd.google-earth.kml+xml') - -def render_to_kmz(*args, **kwargs): - """ - Compresses the KML content and returns as KMZ (using the correct - MIME type). - """ - return HttpResponse(compress_kml(loader.render_to_string(*args, **kwargs)), - mimetype='application/vnd.google-earth.kmz') - - -def render_to_text(*args, **kwargs): - "Renders the response using the MIME type for plain text." - return HttpResponse(loader.render_to_string(*args, **kwargs), - mimetype='text/plain') diff --git a/parts/django/django/contrib/gis/sitemaps/__init__.py b/parts/django/django/contrib/gis/sitemaps/__init__.py deleted file mode 100644 index 9b6287f..0000000 --- a/parts/django/django/contrib/gis/sitemaps/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# Geo-enabled Sitemap classes. -from django.contrib.gis.sitemaps.georss import GeoRSSSitemap -from django.contrib.gis.sitemaps.kml import KMLSitemap, KMZSitemap - diff --git a/parts/django/django/contrib/gis/sitemaps/georss.py b/parts/django/django/contrib/gis/sitemaps/georss.py deleted file mode 100644 index f75cf80..0000000 --- a/parts/django/django/contrib/gis/sitemaps/georss.py +++ /dev/null @@ -1,53 +0,0 @@ -from django.core import urlresolvers -from django.contrib.sitemaps import Sitemap - -class GeoRSSSitemap(Sitemap): - """ - A minimal hook to produce sitemaps for GeoRSS feeds. - """ - def __init__(self, feed_dict, slug_dict=None): - """ - This sitemap object initializes on a feed dictionary (as would be passed - to `django.contrib.syndication.views.feed`) and a slug dictionary. - If the slug dictionary is not defined, then it's assumed the keys provide - the URL parameter to the feed. However, if you have a complex feed (e.g., - you override `get_object`, then you'll need to provide a slug dictionary. - The slug dictionary should have the same keys as the feed dictionary, but - each value in the slug dictionary should be a sequence of slugs that may - be used for valid feeds. For example, let's say we have a feed that - returns objects for a specific ZIP code in our feed dictionary: - - feed_dict = {'zipcode' : ZipFeed} - - Then we would use a slug dictionary with a list of the zip code slugs - corresponding to feeds you want listed in the sitemap: - - slug_dict = {'zipcode' : ['77002', '77054']} - """ - # Setting up. - self.feed_dict = feed_dict - self.locations = [] - if slug_dict is None: slug_dict = {} - # Getting the feed locations. - for section in feed_dict.keys(): - if slug_dict.get(section, False): - for slug in slug_dict[section]: - self.locations.append('%s/%s' % (section, slug)) - else: - self.locations.append(section) - - def get_urls(self, page=1, site=None): - """ - This method is overrridden so the appropriate `geo_format` attribute - is placed on each URL element. - """ - urls = Sitemap.get_urls(self, page=page, site=site) - for url in urls: url['geo_format'] = 'georss' - return urls - - def items(self): - return self.locations - - def location(self, obj): - return urlresolvers.reverse('django.contrib.syndication.views.feed', args=(obj,)) - diff --git a/parts/django/django/contrib/gis/sitemaps/kml.py b/parts/django/django/contrib/gis/sitemaps/kml.py deleted file mode 100644 index db30606..0000000 --- a/parts/django/django/contrib/gis/sitemaps/kml.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.core import urlresolvers -from django.contrib.sitemaps import Sitemap -from django.contrib.gis.db.models.fields import GeometryField -from django.db import models - -class KMLSitemap(Sitemap): - """ - A minimal hook to produce KML sitemaps. - """ - geo_format = 'kml' - - def __init__(self, locations=None): - # If no locations specified, then we try to build for - # every model in installed applications. - self.locations = self._build_kml_sources(locations) - - def _build_kml_sources(self, sources): - """ - Goes through the given sources and returns a 3-tuple of - the application label, module name, and field name of every - GeometryField encountered in the sources. - - If no sources are provided, then all models. - """ - kml_sources = [] - if sources is None: - sources = models.get_models() - for source in sources: - if isinstance(source, models.base.ModelBase): - for field in source._meta.fields: - if isinstance(field, GeometryField): - kml_sources.append((source._meta.app_label, - source._meta.module_name, - field.name)) - elif isinstance(source, (list, tuple)): - if len(source) != 3: - raise ValueError('Must specify a 3-tuple of (app_label, module_name, field_name).') - kml_sources.append(source) - else: - raise TypeError('KML Sources must be a model or a 3-tuple.') - return kml_sources - - def get_urls(self, page=1, site=None): - """ - This method is overrridden so the appropriate `geo_format` attribute - is placed on each URL element. - """ - urls = Sitemap.get_urls(self, page=page, site=site) - for url in urls: url['geo_format'] = self.geo_format - return urls - - def items(self): - return self.locations - - def location(self, obj): - return urlresolvers.reverse('django.contrib.gis.sitemaps.views.%s' % self.geo_format, - kwargs={'label' : obj[0], - 'model' : obj[1], - 'field_name': obj[2], - } - ) -class KMZSitemap(KMLSitemap): - geo_format = 'kmz' diff --git a/parts/django/django/contrib/gis/sitemaps/views.py b/parts/django/django/contrib/gis/sitemaps/views.py deleted file mode 100644 index 02a0fc0..0000000 --- a/parts/django/django/contrib/gis/sitemaps/views.py +++ /dev/null @@ -1,111 +0,0 @@ -from django.http import HttpResponse, Http404 -from django.template import loader -from django.contrib.sites.models import get_current_site -from django.core import urlresolvers -from django.core.paginator import EmptyPage, PageNotAnInteger -from django.contrib.gis.db.models.fields import GeometryField -from django.db import connections, DEFAULT_DB_ALIAS -from django.db.models import get_model -from django.utils.encoding import smart_str - -from django.contrib.gis.shortcuts import render_to_kml, render_to_kmz - -def index(request, sitemaps): - """ - This view generates a sitemap index that uses the proper view - for resolving geographic section sitemap URLs. - """ - current_site = get_current_site(request) - sites = [] - protocol = request.is_secure() and 'https' or 'http' - for section, site in sitemaps.items(): - if callable(site): - pages = site().paginator.num_pages - else: - pages = site.paginator.num_pages - sitemap_url = urlresolvers.reverse('django.contrib.gis.sitemaps.views.sitemap', kwargs={'section': section}) - sites.append('%s://%s%s' % (protocol, current_site.domain, sitemap_url)) - - if pages > 1: - for page in range(2, pages+1): - sites.append('%s://%s%s?p=%s' % (protocol, current_site.domain, sitemap_url, page)) - xml = loader.render_to_string('sitemap_index.xml', {'sitemaps': sites}) - return HttpResponse(xml, mimetype='application/xml') - -def sitemap(request, sitemaps, section=None): - """ - This view generates a sitemap with additional geographic - elements defined by Google. - """ - maps, urls = [], [] - if section is not None: - if section not in sitemaps: - raise Http404("No sitemap available for section: %r" % section) - maps.append(sitemaps[section]) - else: - maps = sitemaps.values() - - page = request.GET.get("p", 1) - current_site = get_current_site(request) - for site in maps: - try: - if callable(site): - urls.extend(site().get_urls(page=page, site=current_site)) - else: - urls.extend(site.get_urls(page=page, site=current_site)) - except EmptyPage: - raise Http404("Page %s empty" % page) - except PageNotAnInteger: - raise Http404("No page '%s'" % page) - xml = smart_str(loader.render_to_string('gis/sitemaps/geo_sitemap.xml', {'urlset': urls})) - return HttpResponse(xml, mimetype='application/xml') - -def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB_ALIAS): - """ - This view generates KML for the given app label, model, and field name. - - The model's default manager must be GeoManager, and the field name - must be that of a geographic field. - """ - placemarks = [] - klass = get_model(label, model) - if not klass: - raise Http404('You must supply a valid app label and module name. Got "%s.%s"' % (label, model)) - - if field_name: - try: - info = klass._meta.get_field_by_name(field_name) - if not isinstance(info[0], GeometryField): - raise Exception - except: - raise Http404('Invalid geometry field.') - - connection = connections[using] - - if connection.ops.postgis: - # PostGIS will take care of transformation. - placemarks = klass._default_manager.using(using).kml(field_name=field_name) - else: - # There's no KML method on Oracle or MySQL, so we use the `kml` - # attribute of the lazy geometry instead. - placemarks = [] - if connection.ops.oracle: - qs = klass._default_manager.using(using).transform(4326, field_name=field_name) - else: - qs = klass._default_manager.using(using).all() - for mod in qs: - setattr(mod, 'kml', getattr(mod, field_name).kml) - placemarks.append(mod) - - # Getting the render function and rendering to the correct. - if compress: - render = render_to_kmz - else: - render = render_to_kml - return render('gis/kml/placemarks.kml', {'places' : placemarks}) - -def kmz(request, label, model, field_name=None, using=DEFAULT_DB_ALIAS): - """ - This view returns KMZ for the given app label, model, and field name. - """ - return kml(request, label, model, field_name, compress=True, using=using) diff --git a/parts/django/django/contrib/gis/templates/gis/admin/openlayers.html b/parts/django/django/contrib/gis/templates/gis/admin/openlayers.html deleted file mode 100644 index 4292eb6..0000000 --- a/parts/django/django/contrib/gis/templates/gis/admin/openlayers.html +++ /dev/null @@ -1,37 +0,0 @@ -{% block extrastyle %} -<style type="text/css"> - #{{ id }}_map { width: {{ map_width }}px; height: {{ map_height }}px; } - #{{ id }}_map .aligned label { float:inherit; } - #{{ id }}_admin_map { position: relative; vertical-align: top; float: {{ LANGUAGE_BIDI|yesno:"right,left" }}; } - {% if not display_wkt %}#{{ id }} { display: none; }{% endif %} - .olControlEditingToolbar .olControlModifyFeatureItemActive { - background-image: url("{{ ADMIN_MEDIA_PREFIX }}img/gis/move_vertex_on.png"); - background-repeat: no-repeat; - } - .olControlEditingToolbar .olControlModifyFeatureItemInactive { - background-image: url("{{ ADMIN_MEDIA_PREFIX }}img/gis/move_vertex_off.png"); - background-repeat: no-repeat; - } -</style> -<!--[if IE]> -<style type="text/css"> - /* This fixes the mouse offset issues in IE. */ - #{{ id }}_admin_map { position: static; vertical-align: top; } - /* `font-size: 0` fixes the 1px border between tiles, but borks LayerSwitcher. - Thus, this is disabled until a better fix is found. - #{{ id }}_map { width: {{ map_width }}px; height: {{ map_height }}px; font-size: 0; } */ -</style> -<![endif]--> -{% endblock %} -<span id="{{ id }}_admin_map"> -<script type="text/javascript"> -//<![CDATA[ -{% block openlayers %}{% include "gis/admin/openlayers.js" %}{% endblock %} -//]]> -</script> -<div id="{{ id }}_map"{% if LANGUAGE_BIDI %} dir="ltr"{% endif %}></div> -<a href="javascript:{{ module }}.clearFeatures()">Delete all Features</a> -{% if display_wkt %}<p> WKT debugging window:</p>{% endif %} -<textarea id="{{ id }}" class="vWKTField required" cols="150" rows="10" name="{{ name }}">{{ wkt }}</textarea> -<script type="text/javascript">{% block init_function %}{{ module }}.init();{% endblock %}</script> -</span> diff --git a/parts/django/django/contrib/gis/templates/gis/admin/openlayers.js b/parts/django/django/contrib/gis/templates/gis/admin/openlayers.js deleted file mode 100644 index 4324693..0000000 --- a/parts/django/django/contrib/gis/templates/gis/admin/openlayers.js +++ /dev/null @@ -1,167 +0,0 @@ -{# Author: Justin Bronn, Travis Pinney & Dane Springmeyer #} -{% block vars %}var {{ module }} = {}; -{{ module }}.map = null; {{ module }}.controls = null; {{ module }}.panel = null; {{ module }}.re = new RegExp("^SRID=\d+;(.+)", "i"); {{ module }}.layers = {}; -{{ module }}.modifiable = {{ modifiable|yesno:"true,false" }}; -{{ module }}.wkt_f = new OpenLayers.Format.WKT(); -{{ module }}.is_collection = {{ is_collection|yesno:"true,false" }}; -{{ module }}.collection_type = '{{ collection_type }}'; -{{ module }}.is_linestring = {{ is_linestring|yesno:"true,false" }}; -{{ module }}.is_polygon = {{ is_polygon|yesno:"true,false" }}; -{{ module }}.is_point = {{ is_point|yesno:"true,false" }}; -{% endblock %} -{{ module }}.get_ewkt = function(feat){return 'SRID={{ srid }};' + {{ module }}.wkt_f.write(feat);} -{{ module }}.read_wkt = function(wkt){ - // OpenLayers cannot handle EWKT -- we make sure to strip it out. - // EWKT is only exposed to OL if there's a validation error in the admin. - var match = {{ module }}.re.exec(wkt); - if (match){wkt = match[1];} - return {{ module }}.wkt_f.read(wkt); -} -{{ module }}.write_wkt = function(feat){ - if ({{ module }}.is_collection){ {{ module }}.num_geom = feat.geometry.components.length;} - else { {{ module }}.num_geom = 1;} - document.getElementById('{{ id }}').value = {{ module }}.get_ewkt(feat); -} -{{ module }}.add_wkt = function(event){ - // This function will sync the contents of the `vector` layer with the - // WKT in the text field. - if ({{ module }}.is_collection){ - var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}()); - for (var i = 0; i < {{ module }}.layers.vector.features.length; i++){ - feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]); - } - {{ module }}.write_wkt(feat); - } else { - // Make sure to remove any previously added features. - if ({{ module }}.layers.vector.features.length > 1){ - old_feats = [{{ module }}.layers.vector.features[0]]; - {{ module }}.layers.vector.removeFeatures(old_feats); - {{ module }}.layers.vector.destroyFeatures(old_feats); - } - {{ module }}.write_wkt(event.feature); - } -} -{{ module }}.modify_wkt = function(event){ - if ({{ module }}.is_collection){ - if ({{ module }}.is_point){ - {{ module }}.add_wkt(event); - return; - } else { - // When modifying the selected components are added to the - // vector layer so we only increment to the `num_geom` value. - var feat = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.{{ geom_type }}()); - for (var i = 0; i < {{ module }}.num_geom; i++){ - feat.geometry.addComponents([{{ module }}.layers.vector.features[i].geometry]); - } - {{ module }}.write_wkt(feat); - } - } else { - {{ module }}.write_wkt(event.feature); - } -} -// Function to clear vector features and purge wkt from div -{{ module }}.deleteFeatures = function(){ - {{ module }}.layers.vector.removeFeatures({{ module }}.layers.vector.features); - {{ module }}.layers.vector.destroyFeatures(); -} -{{ module }}.clearFeatures = function (){ - {{ module }}.deleteFeatures(); - document.getElementById('{{ id }}').value = ''; - {{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }}); -} -// Add Select control -{{ module }}.addSelectControl = function(){ - var select = new OpenLayers.Control.SelectFeature({{ module }}.layers.vector, {'toggle' : true, 'clickout' : true}); - {{ module }}.map.addControl(select); - select.activate(); -} -{{ module }}.enableDrawing = function(){ {{ module }}.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();} -{{ module }}.enableEditing = function(){ {{ module }}.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();} -// Create an array of controls based on geometry type -{{ module }}.getControls = function(lyr){ - {{ module }}.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'}); - var nav = new OpenLayers.Control.Navigation(); - var draw_ctl; - if ({{ module }}.is_linestring){ - draw_ctl = new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}); - } else if ({{ module }}.is_polygon){ - draw_ctl = new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}); - } else if ({{ module }}.is_point){ - draw_ctl = new OpenLayers.Control.DrawFeature(lyr, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}); - } - if ({{ module }}.modifiable){ - var mod = new OpenLayers.Control.ModifyFeature(lyr, {'displayClass': 'olControlModifyFeature'}); - {{ module }}.controls = [nav, draw_ctl, mod]; - } else { - if(!lyr.features.length){ - {{ module }}.controls = [nav, draw_ctl]; - } else { - {{ module }}.controls = [nav]; - } - } -} -{{ module }}.init = function(){ - {% block map_options %}// The options hash, w/ zoom, resolution, and projection settings. - var options = { -{% autoescape off %}{% for item in map_options.items %} '{{ item.0 }}' : {{ item.1 }}{% if not forloop.last %},{% endif %} -{% endfor %}{% endautoescape %} };{% endblock %} - // The admin map for this geometry field. - {{ module }}.map = new OpenLayers.Map('{{ id }}_map', options); - // Base Layer - {{ module }}.layers.base = {% block base_layer %}new OpenLayers.Layer.WMS( "{{ wms_name }}", "{{ wms_url }}", {layers: '{{ wms_layer }}'} );{% endblock %} - {{ module }}.map.addLayer({{ module }}.layers.base); - {% block extra_layers %}{% endblock %} - {% if is_linestring %}OpenLayers.Feature.Vector.style["default"]["strokeWidth"] = 3; // Default too thin for linestrings. {% endif %} - {{ module }}.layers.vector = new OpenLayers.Layer.Vector(" {{ field_name }}"); - {{ module }}.map.addLayer({{ module }}.layers.vector); - // Read WKT from the text field. - var wkt = document.getElementById('{{ id }}').value; - if (wkt){ - // After reading into geometry, immediately write back to - // WKT <textarea> as EWKT (so that SRID is included). - var admin_geom = {{ module }}.read_wkt(wkt); - {{ module }}.write_wkt(admin_geom); - if ({{ module }}.is_collection){ - // If geometry collection, add each component individually so they may be - // edited individually. - for (var i = 0; i < {{ module }}.num_geom; i++){ - {{ module }}.layers.vector.addFeatures([new OpenLayers.Feature.Vector(admin_geom.geometry.components[i].clone())]); - } - } else { - {{ module }}.layers.vector.addFeatures([admin_geom]); - } - // Zooming to the bounds. - {{ module }}.map.zoomToExtent(admin_geom.geometry.getBounds()); - if ({{ module }}.is_point){ - {{ module }}.map.zoomTo({{ point_zoom }}); - } - } else { - {{ module }}.map.setCenter(new OpenLayers.LonLat({{ default_lon }}, {{ default_lat }}), {{ default_zoom }}); - } - // This allows editing of the geographic fields -- the modified WKT is - // written back to the content field (as EWKT, so that the ORM will know - // to transform back to original SRID). - {{ module }}.layers.vector.events.on({"featuremodified" : {{ module }}.modify_wkt}); - {{ module }}.layers.vector.events.on({"featureadded" : {{ module }}.add_wkt}); - {% block controls %} - // Map controls: - // Add geometry specific panel of toolbar controls - {{ module }}.getControls({{ module }}.layers.vector); - {{ module }}.panel.addControls({{ module }}.controls); - {{ module }}.map.addControl({{ module }}.panel); - {{ module }}.addSelectControl(); - // Then add optional visual controls - {% if mouse_position %}{{ module }}.map.addControl(new OpenLayers.Control.MousePosition());{% endif %} - {% if scale_text %}{{ module }}.map.addControl(new OpenLayers.Control.Scale());{% endif %} - {% if layerswitcher %}{{ module }}.map.addControl(new OpenLayers.Control.LayerSwitcher());{% endif %} - // Then add optional behavior controls - {% if not scrollable %}{{ module }}.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();{% endif %} - {% endblock %} - if (wkt){ - if ({{ module }}.modifiable){ - {{ module }}.enableEditing(); - } - } else { - {{ module }}.enableDrawing(); - } -} diff --git a/parts/django/django/contrib/gis/templates/gis/admin/osm.html b/parts/django/django/contrib/gis/templates/gis/admin/osm.html deleted file mode 100644 index b74b41f..0000000 --- a/parts/django/django/contrib/gis/templates/gis/admin/osm.html +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "gis/admin/openlayers.html" %} -{% block openlayers %}{% include "gis/admin/osm.js" %}{% endblock %}
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/templates/gis/admin/osm.js b/parts/django/django/contrib/gis/templates/gis/admin/osm.js deleted file mode 100644 index 2a1f59e..0000000 --- a/parts/django/django/contrib/gis/templates/gis/admin/osm.js +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "gis/admin/openlayers.js" %} -{% block base_layer %}new OpenLayers.Layer.OSM.Mapnik("OpenStreetMap (Mapnik)");{% endblock %} diff --git a/parts/django/django/contrib/gis/templates/gis/google/google-map.html b/parts/django/django/contrib/gis/templates/gis/google/google-map.html deleted file mode 100644 index fb60e44..0000000 --- a/parts/django/django/contrib/gis/templates/gis/google/google-map.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" {{ gmap.xmlns }}> -<head> - <title>{% block title %}Google Maps via GeoDjango{% endblock %}</title> - {{ gmap.style }} - {{ gmap.scripts }} -</head> -<body {{ gmap.onload }} {{ gmap.onunload }}> -{% if gmap.dom_ids %}{% for dom_id in gmap.dom_ids %}<div id="{{ dom_id }}" style="width:600px;height:400px;"></div>{% endfor %} -{% else %}<div id="{{ gmap.dom_id }}" style="width:600px;height:400px;"></div>{% endif %} -</body> -</html> diff --git a/parts/django/django/contrib/gis/templates/gis/google/google-map.js b/parts/django/django/contrib/gis/templates/gis/google/google-map.js deleted file mode 100644 index 06f11e3..0000000 --- a/parts/django/django/contrib/gis/templates/gis/google/google-map.js +++ /dev/null @@ -1,35 +0,0 @@ -{% autoescape off %} -{% block vars %}var geodjango = {};{% for icon in icons %} -var {{ icon.varname }} = new GIcon(G_DEFAULT_ICON); -{% if icon.image %}{{ icon.varname }}.image = "{{ icon.image }}";{% endif %} -{% if icon.shadow %}{{ icon.varname }}.shadow = "{{ icon.shadow }}";{% endif %} {% if icon.shadowsize %}{{ icon.varname }}.shadowSize = new GSize({{ icon.shadowsize.0 }}, {{ icon.shadowsize.1 }});{% endif %} -{% if icon.iconanchor %}{{ icon.varname }}.iconAnchor = new GPoint({{ icon.iconanchor.0 }}, {{ icon.iconanchor.1 }});{% endif %} {% if icon.iconsize %}{{ icon.varname }}.iconSize = new GSize({{ icon.iconsize.0 }}, {{ icon.iconsize.1 }});{% endif %} -{% if icon.infowindowanchor %}{{ icon.varname }}.infoWindowAnchor = new GPoint({{ icon.infowindowanchor.0 }}, {{ icon.infowindowanchor.1 }});{% endif %}{% endfor %} -{% endblock vars %}{% block functions %} -{% block load %}{{ js_module }}.{{ dom_id }}_load = function(){ - if (GBrowserIsCompatible()) { - {{ js_module }}.{{ dom_id }} = new GMap2(document.getElementById("{{ dom_id }}")); - {{ js_module }}.{{ dom_id }}.setCenter(new GLatLng({{ center.1 }}, {{ center.0 }}), {{ zoom }}); - {% block controls %}{{ js_module }}.{{ dom_id }}.setUIToDefault();{% endblock %} - {% if calc_zoom %}var bounds = new GLatLngBounds(); var tmp_bounds = new GLatLngBounds();{% endif %} - {% for kml_url in kml_urls %}{{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }} = new GGeoXml("{{ kml_url }}"); - {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_kml{{ forloop.counter }});{% endfor %} - {% for polygon in polygons %}{{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }} = new {{ polygon }}; - {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }}); - {% for event in polygon.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_poly{{ forloop.parentloop.counter }}, {{ event }});{% endfor %} - {% if calc_zoom %}tmp_bounds = {{ js_module }}.{{ dom_id }}_poly{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %} - {% for polyline in polylines %}{{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }} = new {{ polyline }}; - {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }}); - {% for event in polyline.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_polyline{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %} - {% if calc_zoom %}tmp_bounds = {{ js_module }}.{{ dom_id }}_polyline{{ forloop.counter }}.getBounds(); bounds.extend(tmp_bounds.getSouthWest()); bounds.extend(tmp_bounds.getNorthEast());{% endif %}{% endfor %} - {% for marker in markers %}{{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }} = new {{ marker }}; - {{ js_module }}.{{ dom_id }}.addOverlay({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }}); - {% for event in marker.events %}GEvent.addListener({{ js_module }}.{{ dom_id }}_marker{{ forloop.parentloop.counter }}, {{ event }}); {% endfor %} - {% if calc_zoom %}bounds.extend({{ js_module }}.{{ dom_id }}_marker{{ forloop.counter }}.getLatLng()); {% endif %}{% endfor %} - {% if calc_zoom %}{{ js_module }}.{{ dom_id }}.setCenter(bounds.getCenter(), {{ js_module }}.{{ dom_id }}.getBoundsZoomLevel(bounds));{% endif %} - {% block load_extra %}{% endblock %} - }else { - alert("Sorry, the Google Maps API is not compatible with this browser."); - } -} -{% endblock load %}{% endblock functions %}{% endautoescape %} diff --git a/parts/django/django/contrib/gis/templates/gis/google/google-multi.js b/parts/django/django/contrib/gis/templates/gis/google/google-multi.js deleted file mode 100644 index e3c7e8f..0000000 --- a/parts/django/django/contrib/gis/templates/gis/google/google-multi.js +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "gis/google/google-map.js" %} -{% block functions %} -{{ load_map_js }} -{{ js_module }}.load = function(){ - {% for dom_id in dom_ids %}{{ js_module }}.{{ dom_id }}_load(); - {% endfor %} -} -{% endblock %}
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/templates/gis/google/google-single.js b/parts/django/django/contrib/gis/templates/gis/google/google-single.js deleted file mode 100644 index b930e45..0000000 --- a/parts/django/django/contrib/gis/templates/gis/google/google-single.js +++ /dev/null @@ -1,2 +0,0 @@ -{% extends "gis/google/google-map.js" %} -{% block vars %}{# No vars here because used within GoogleMapSet #}{% endblock %}
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/templates/gis/kml/base.kml b/parts/django/django/contrib/gis/templates/gis/kml/base.kml deleted file mode 100644 index 374404c..0000000 --- a/parts/django/django/contrib/gis/templates/gis/kml/base.kml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<kml xmlns="http://earth.google.com/kml/{% block kml_version %}2.1{% endblock %}"> -<Document>{% block name %}{% endblock %} -{% block placemarks %}{% endblock %} -</Document> -</kml> diff --git a/parts/django/django/contrib/gis/templates/gis/kml/placemarks.kml b/parts/django/django/contrib/gis/templates/gis/kml/placemarks.kml deleted file mode 100644 index ea2ac19..0000000 --- a/parts/django/django/contrib/gis/templates/gis/kml/placemarks.kml +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "gis/kml/base.kml" %} -{% block placemarks %}{% for place in places %} - <Placemark> - <name>{% if place.name %}{{ place.name }}{% else %}{{ place }}{% endif %}</name> - <description>{% if place.description %}{{ place.description }}{% else %}{{ place }}{% endif %}</description> - {{ place.kml|safe }} - </Placemark>{% endfor %}{% endblock %} - diff --git a/parts/django/django/contrib/gis/templates/gis/sitemaps/geo_sitemap.xml b/parts/django/django/contrib/gis/templates/gis/sitemaps/geo_sitemap.xml deleted file mode 100644 index dbf858e..0000000 --- a/parts/django/django/contrib/gis/templates/gis/sitemaps/geo_sitemap.xml +++ /dev/null @@ -1,17 +0,0 @@ -{% autoescape off %}<?xml version="1.0" encoding="UTF-8"?> -<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:geo="http://www.google.com/geo/schemas/sitemap/1.0"> -{% spaceless %} -{% for url in urlset %} - <url> - <loc>{{ url.location|escape }}</loc> - {% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %} - {% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %} - {% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %} - {% if url.geo_format %}<geo:geo> - <geo:format>{{ url.geo_format }}</geo:format> - </geo:geo>{% endif %} - </url> -{% endfor %} -{% endspaceless %} -</urlset> -{% endautoescape %} diff --git a/parts/django/django/contrib/gis/tests/__init__.py b/parts/django/django/contrib/gis/tests/__init__.py deleted file mode 100644 index 138c291..0000000 --- a/parts/django/django/contrib/gis/tests/__init__.py +++ /dev/null @@ -1,141 +0,0 @@ -import unittest - -from django.conf import settings -from django.test.simple import build_suite, DjangoTestSuiteRunner - - -def run_tests(*args, **kwargs): - from django.test.simple import run_tests as base_run_tests - return base_run_tests(*args, **kwargs) - - -def run_gis_tests(test_labels, verbosity=1, interactive=True, failfast=False, extra_tests=None): - import warnings - warnings.warn( - 'The run_gis_tests() test runner has been deprecated in favor of GeoDjangoTestSuiteRunner.', - PendingDeprecationWarning - ) - test_runner = GeoDjangoTestSuiteRunner(verbosity=verbosity, interactive=interactive, failfast=failfast) - return test_runner.run_tests(test_labels, extra_tests=extra_tests) - - -def geo_apps(namespace=True, runtests=False): - """ - Returns a list of GeoDjango test applications that reside in - `django.contrib.gis.tests` that can be used with the current - database and the spatial libraries that are installed. - """ - from django.db import connection - from django.contrib.gis.geos import GEOS_PREPARE - from django.contrib.gis.gdal import HAS_GDAL - - apps = ['geoapp', 'relatedapp'] - - # No distance queries on MySQL. - if not connection.ops.mysql: - apps.append('distapp') - - # Test geography support with PostGIS 1.5+. - if connection.ops.postgis and connection.ops.geography: - apps.append('geogapp') - - # The following GeoDjango test apps depend on GDAL support. - if HAS_GDAL: - # 3D apps use LayerMapping, which uses GDAL. - if connection.ops.postgis and GEOS_PREPARE: - apps.append('geo3d') - - apps.append('layermap') - - if runtests: - return [('django.contrib.gis.tests', app) for app in apps] - elif namespace: - return ['django.contrib.gis.tests.%s' % app - for app in apps] - else: - return apps - - -def geodjango_suite(apps=True): - """ - Returns a TestSuite consisting only of GeoDjango tests that can be run. - """ - import sys - from django.db.models import get_app - - suite = unittest.TestSuite() - - # Adding the GEOS tests. - from django.contrib.gis.geos import tests as geos_tests - suite.addTest(geos_tests.suite()) - - # Adding the measurment tests. - from django.contrib.gis.tests import test_measure - suite.addTest(test_measure.suite()) - - # Adding GDAL tests, and any test suite that depends on GDAL, to the - # suite if GDAL is available. - from django.contrib.gis.gdal import HAS_GDAL - if HAS_GDAL: - from django.contrib.gis.gdal import tests as gdal_tests - suite.addTest(gdal_tests.suite()) - - from django.contrib.gis.tests import test_spatialrefsys, test_geoforms - suite.addTest(test_spatialrefsys.suite()) - suite.addTest(test_geoforms.suite()) - else: - sys.stderr.write('GDAL not available - no tests requiring GDAL will be run.\n') - - # Add GeoIP tests to the suite, if the library and data is available. - from django.contrib.gis.utils import HAS_GEOIP - if HAS_GEOIP and hasattr(settings, 'GEOIP_PATH'): - from django.contrib.gis.tests import test_geoip - suite.addTest(test_geoip.suite()) - - # Finally, adding the suites for each of the GeoDjango test apps. - if apps: - for app_name in geo_apps(namespace=False): - suite.addTest(build_suite(get_app(app_name))) - - return suite - - -class GeoDjangoTestSuiteRunner(DjangoTestSuiteRunner): - - def setup_test_environment(self, **kwargs): - super(GeoDjangoTestSuiteRunner, self).setup_test_environment(**kwargs) - - # Saving original values of INSTALLED_APPS, ROOT_URLCONF, and SITE_ID. - self.old_installed = getattr(settings, 'INSTALLED_APPS', None) - self.old_root_urlconf = getattr(settings, 'ROOT_URLCONF', '') - self.old_site_id = getattr(settings, 'SITE_ID', None) - - # Constructing the new INSTALLED_APPS, and including applications - # within the GeoDjango test namespace. - new_installed = ['django.contrib.sites', - 'django.contrib.sitemaps', - 'django.contrib.gis', - ] - - # Calling out to `geo_apps` to get GeoDjango applications supported - # for testing. - new_installed.extend(geo_apps()) - settings.INSTALLED_APPS = new_installed - - # SITE_ID needs to be set - settings.SITE_ID = 1 - - # ROOT_URLCONF needs to be set, else `AttributeErrors` are raised - # when TestCases are torn down that have `urls` defined. - settings.ROOT_URLCONF = '' - - - def teardown_test_environment(self, **kwargs): - super(GeoDjangoTestSuiteRunner, self).teardown_test_environment(**kwargs) - settings.INSTALLED_APPS = self.old_installed - settings.ROOT_URLCONF = self.old_root_urlconf - settings.SITE_ID = self.old_site_id - - - def build_suite(self, test_labels, extra_tests=None, **kwargs): - return geodjango_suite() diff --git a/parts/django/django/contrib/gis/tests/data/cities/cities.dbf b/parts/django/django/contrib/gis/tests/data/cities/cities.dbf Binary files differdeleted file mode 100644 index 8b27633..0000000 --- a/parts/django/django/contrib/gis/tests/data/cities/cities.dbf +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/cities/cities.prj b/parts/django/django/contrib/gis/tests/data/cities/cities.prj deleted file mode 100644 index a30c00a..0000000 --- a/parts/django/django/contrib/gis/tests/data/cities/cities.prj +++ /dev/null @@ -1 +0,0 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/data/cities/cities.shp b/parts/django/django/contrib/gis/tests/data/cities/cities.shp Binary files differdeleted file mode 100644 index 1c46ccc..0000000 --- a/parts/django/django/contrib/gis/tests/data/cities/cities.shp +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/cities/cities.shx b/parts/django/django/contrib/gis/tests/data/cities/cities.shx Binary files differdeleted file mode 100644 index 6be3fd6..0000000 --- a/parts/django/django/contrib/gis/tests/data/cities/cities.shx +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/counties/counties.dbf b/parts/django/django/contrib/gis/tests/data/counties/counties.dbf Binary files differdeleted file mode 100644 index ccdbb26..0000000 --- a/parts/django/django/contrib/gis/tests/data/counties/counties.dbf +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/counties/counties.shp b/parts/django/django/contrib/gis/tests/data/counties/counties.shp Binary files differdeleted file mode 100644 index 2e7dca5..0000000 --- a/parts/django/django/contrib/gis/tests/data/counties/counties.shp +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/counties/counties.shx b/parts/django/django/contrib/gis/tests/data/counties/counties.shx Binary files differdeleted file mode 100644 index 46ed3bb..0000000 --- a/parts/django/django/contrib/gis/tests/data/counties/counties.shx +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/geometries.json.gz b/parts/django/django/contrib/gis/tests/data/geometries.json.gz Binary files differdeleted file mode 100644 index 683dc83..0000000 --- a/parts/django/django/contrib/gis/tests/data/geometries.json.gz +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/interstates/interstates.dbf b/parts/django/django/contrib/gis/tests/data/interstates/interstates.dbf Binary files differdeleted file mode 100644 index a88d171..0000000 --- a/parts/django/django/contrib/gis/tests/data/interstates/interstates.dbf +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/interstates/interstates.prj b/parts/django/django/contrib/gis/tests/data/interstates/interstates.prj deleted file mode 100644 index a30c00a..0000000 --- a/parts/django/django/contrib/gis/tests/data/interstates/interstates.prj +++ /dev/null @@ -1 +0,0 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/data/interstates/interstates.shp b/parts/django/django/contrib/gis/tests/data/interstates/interstates.shp Binary files differdeleted file mode 100644 index 6d93de7..0000000 --- a/parts/django/django/contrib/gis/tests/data/interstates/interstates.shp +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/interstates/interstates.shx b/parts/django/django/contrib/gis/tests/data/interstates/interstates.shx Binary files differdeleted file mode 100644 index 7b9088a..0000000 --- a/parts/django/django/contrib/gis/tests/data/interstates/interstates.shx +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_point/test_point.dbf b/parts/django/django/contrib/gis/tests/data/test_point/test_point.dbf Binary files differdeleted file mode 100644 index b2b4eca..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_point/test_point.dbf +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_point/test_point.prj b/parts/django/django/contrib/gis/tests/data/test_point/test_point.prj deleted file mode 100644 index a30c00a..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_point/test_point.prj +++ /dev/null @@ -1 +0,0 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/data/test_point/test_point.shp b/parts/django/django/contrib/gis/tests/data/test_point/test_point.shp Binary files differdeleted file mode 100644 index 95e8b0a..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_point/test_point.shp +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_point/test_point.shx b/parts/django/django/contrib/gis/tests/data/test_point/test_point.shx Binary files differdeleted file mode 100644 index 087f3da..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_point/test_point.shx +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.dbf b/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.dbf Binary files differdeleted file mode 100644 index 7965bd6..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.dbf +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.prj b/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.prj deleted file mode 100644 index a30c00a..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.prj +++ /dev/null @@ -1 +0,0 @@ -GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shp b/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shp Binary files differdeleted file mode 100644 index b22930b..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shp +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shx b/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shx Binary files differdeleted file mode 100644 index c92f78b..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_poly/test_poly.shx +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.csv b/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.csv deleted file mode 100644 index dff648f..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.csv +++ /dev/null @@ -1,4 +0,0 @@ -POINT_X,POINT_Y,NUM -1.0,2.0,5 -5.0,23.0,17 -100.0,523.5,23 diff --git a/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.vrt b/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.vrt deleted file mode 100644 index 979c179..0000000 --- a/parts/django/django/contrib/gis/tests/data/test_vrt/test_vrt.vrt +++ /dev/null @@ -1,7 +0,0 @@ -<OGRVRTDataSource> -<OGRVRTLayer name="test_vrt"> -<SrcDataSource relativeToVRT="1">test_vrt.csv</SrcDataSource> -<GeometryType>wkbPoint25D</GeometryType> -<GeometryField encoding="PointFromColumns" x="POINT_X" y="POINT_Y" z="NUM"/> -</OGRVRTLayer> -</OGRVRTDataSource>
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/distapp/__init__.py b/parts/django/django/contrib/gis/tests/distapp/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/distapp/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/distapp/models.py b/parts/django/django/contrib/gis/tests/distapp/models.py deleted file mode 100644 index 76e7d3a..0000000 --- a/parts/django/django/contrib/gis/tests/distapp/models.py +++ /dev/null @@ -1,50 +0,0 @@ -from django.contrib.gis.db import models - -class SouthTexasCity(models.Model): - "City model on projected coordinate system for South Texas." - name = models.CharField(max_length=30) - point = models.PointField(srid=32140) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class SouthTexasCityFt(models.Model): - "Same City model as above, but U.S. survey feet are the units." - name = models.CharField(max_length=30) - point = models.PointField(srid=2278) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class AustraliaCity(models.Model): - "City model for Australia, using WGS84." - name = models.CharField(max_length=30) - point = models.PointField() - objects = models.GeoManager() - def __unicode__(self): return self.name - -class CensusZipcode(models.Model): - "Model for a few South Texas ZIP codes (in original Census NAD83)." - name = models.CharField(max_length=5) - poly = models.PolygonField(srid=4269) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class SouthTexasZipcode(models.Model): - "Model for a few South Texas ZIP codes." - name = models.CharField(max_length=5) - poly = models.PolygonField(srid=32140, null=True) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class Interstate(models.Model): - "Geodetic model for U.S. Interstates." - name = models.CharField(max_length=10) - path = models.LineStringField() - objects = models.GeoManager() - def __unicode__(self): return self.name - -class SouthTexasInterstate(models.Model): - "Projected model for South Texas Interstates." - name = models.CharField(max_length=10) - path = models.LineStringField(srid=32140) - objects = models.GeoManager() - def __unicode__(self): return self.name diff --git a/parts/django/django/contrib/gis/tests/distapp/tests.py b/parts/django/django/contrib/gis/tests/distapp/tests.py deleted file mode 100644 index 4f81a91..0000000 --- a/parts/django/django/contrib/gis/tests/distapp/tests.py +++ /dev/null @@ -1,358 +0,0 @@ -import os -from decimal import Decimal - -from django.db import connection -from django.db.models import Q -from django.contrib.gis.geos import GEOSGeometry, Point, LineString -from django.contrib.gis.measure import D # alias for Distance -from django.contrib.gis.tests.utils import oracle, postgis, spatialite, no_oracle, no_spatialite -from django.test import TestCase - -from models import AustraliaCity, Interstate, SouthTexasInterstate, \ - SouthTexasCity, SouthTexasCityFt, CensusZipcode, SouthTexasZipcode - -class DistanceTest(TestCase): - - # A point we are testing distances with -- using a WGS84 - # coordinate that'll be implicitly transormed to that to - # the coordinate system of the field, EPSG:32140 (Texas South Central - # w/units in meters) - stx_pnt = GEOSGeometry('POINT (-95.370401017314293 29.704867409475465)', 4326) - # Another one for Australia - au_pnt = GEOSGeometry('POINT (150.791 -34.4919)', 4326) - - def get_names(self, qs): - cities = [c.name for c in qs] - cities.sort() - return cities - - def test01_init(self): - "Test initialization of distance models." - self.assertEqual(9, SouthTexasCity.objects.count()) - self.assertEqual(9, SouthTexasCityFt.objects.count()) - self.assertEqual(11, AustraliaCity.objects.count()) - self.assertEqual(4, SouthTexasZipcode.objects.count()) - self.assertEqual(4, CensusZipcode.objects.count()) - self.assertEqual(1, Interstate.objects.count()) - self.assertEqual(1, SouthTexasInterstate.objects.count()) - - @no_spatialite - def test02_dwithin(self): - "Testing the `dwithin` lookup type." - # Distances -- all should be equal (except for the - # degree/meter pair in au_cities, that's somewhat - # approximate). - tx_dists = [(7000, 22965.83), D(km=7), D(mi=4.349)] - au_dists = [(0.5, 32000), D(km=32), D(mi=19.884)] - - # Expected cities for Australia and Texas. - tx_cities = ['Downtown Houston', 'Southside Place'] - au_cities = ['Mittagong', 'Shellharbour', 'Thirroul', 'Wollongong'] - - # Performing distance queries on two projected coordinate systems one - # with units in meters and the other in units of U.S. survey feet. - for dist in tx_dists: - if isinstance(dist, tuple): dist1, dist2 = dist - else: dist1 = dist2 = dist - qs1 = SouthTexasCity.objects.filter(point__dwithin=(self.stx_pnt, dist1)) - qs2 = SouthTexasCityFt.objects.filter(point__dwithin=(self.stx_pnt, dist2)) - for qs in qs1, qs2: - self.assertEqual(tx_cities, self.get_names(qs)) - - # Now performing the `dwithin` queries on a geodetic coordinate system. - for dist in au_dists: - if isinstance(dist, D) and not oracle: type_error = True - else: type_error = False - - if isinstance(dist, tuple): - if oracle: dist = dist[1] - else: dist = dist[0] - - # Creating the query set. - qs = AustraliaCity.objects.order_by('name') - if type_error: - # A ValueError should be raised on PostGIS when trying to pass - # Distance objects into a DWithin query using a geodetic field. - self.assertRaises(ValueError, AustraliaCity.objects.filter(point__dwithin=(self.au_pnt, dist)).count) - else: - self.assertEqual(au_cities, self.get_names(qs.filter(point__dwithin=(self.au_pnt, dist)))) - - def test03a_distance_method(self): - "Testing the `distance` GeoQuerySet method on projected coordinate systems." - # The point for La Grange, TX - lagrange = GEOSGeometry('POINT(-96.876369 29.905320)', 4326) - # Reference distances in feet and in meters. Got these values from - # using the provided raw SQL statements. - # SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 32140)) FROM distapp_southtexascity; - m_distances = [147075.069813, 139630.198056, 140888.552826, - 138809.684197, 158309.246259, 212183.594374, - 70870.188967, 165337.758878, 139196.085105] - # SELECT ST_Distance(point, ST_Transform(ST_GeomFromText('POINT(-96.876369 29.905320)', 4326), 2278)) FROM distapp_southtexascityft; - # Oracle 11 thinks this is not a projected coordinate system, so it's s - # not tested. - ft_distances = [482528.79154625, 458103.408123001, 462231.860397575, - 455411.438904354, 519386.252102563, 696139.009211594, - 232513.278304279, 542445.630586414, 456679.155883207] - - # Testing using different variations of parameters and using models - # with different projected coordinate systems. - dist1 = SouthTexasCity.objects.distance(lagrange, field_name='point') - dist2 = SouthTexasCity.objects.distance(lagrange) # Using GEOSGeometry parameter - if spatialite or oracle: - dist_qs = [dist1, dist2] - else: - dist3 = SouthTexasCityFt.objects.distance(lagrange.ewkt) # Using EWKT string parameter. - dist4 = SouthTexasCityFt.objects.distance(lagrange) - dist_qs = [dist1, dist2, dist3, dist4] - - # Original query done on PostGIS, have to adjust AlmostEqual tolerance - # for Oracle. - if oracle: tol = 2 - else: tol = 5 - - # Ensuring expected distances are returned for each distance queryset. - for qs in dist_qs: - for i, c in enumerate(qs): - self.assertAlmostEqual(m_distances[i], c.distance.m, tol) - self.assertAlmostEqual(ft_distances[i], c.distance.survey_ft, tol) - - @no_spatialite - def test03b_distance_method(self): - "Testing the `distance` GeoQuerySet method on geodetic coordnate systems." - if oracle: tol = 2 - else: tol = 5 - - # Testing geodetic distance calculation with a non-point geometry - # (a LineString of Wollongong and Shellharbour coords). - ls = LineString( ( (150.902, -34.4245), (150.87, -34.5789) ) ) - if oracle or connection.ops.geography: - # Reference query: - # SELECT ST_distance_sphere(point, ST_GeomFromText('LINESTRING(150.9020 -34.4245,150.8700 -34.5789)', 4326)) FROM distapp_australiacity ORDER BY name; - distances = [1120954.92533513, 140575.720018241, 640396.662906304, - 60580.9693849269, 972807.955955075, 568451.8357838, - 40435.4335201384, 0, 68272.3896586844, 12375.0643697706, 0] - qs = AustraliaCity.objects.distance(ls).order_by('name') - for city, distance in zip(qs, distances): - # Testing equivalence to within a meter. - self.assertAlmostEqual(distance, city.distance.m, 0) - else: - # PostGIS 1.4 and below is limited to disance queries only - # to/from point geometries, check for raising of ValueError. - self.assertRaises(ValueError, AustraliaCity.objects.distance, ls) - self.assertRaises(ValueError, AustraliaCity.objects.distance, ls.wkt) - - # Got the reference distances using the raw SQL statements: - # SELECT ST_distance_spheroid(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326), 'SPHEROID["WGS 84",6378137.0,298.257223563]') FROM distapp_australiacity WHERE (NOT (id = 11)); - # SELECT ST_distance_sphere(point, ST_GeomFromText('POINT(151.231341 -33.952685)', 4326)) FROM distapp_australiacity WHERE (NOT (id = 11)); st_distance_sphere - if connection.ops.postgis and connection.ops.proj_version_tuple() >= (4, 7, 0): - # PROJ.4 versions 4.7+ have updated datums, and thus different - # distance values. - spheroid_distances = [60504.0628957201, 77023.9489850262, 49154.8867574404, - 90847.4358768573, 217402.811919332, 709599.234564757, - 640011.483550888, 7772.00667991925, 1047861.78619339, - 1165126.55236034] - sphere_distances = [60580.9693849267, 77144.0435286473, 49199.4415344719, - 90804.7533823494, 217713.384600405, 709134.127242793, - 639828.157159169, 7786.82949717788, 1049204.06569028, - 1162623.7238134] - - else: - spheroid_distances = [60504.0628825298, 77023.948962654, 49154.8867507115, - 90847.435881812, 217402.811862568, 709599.234619957, - 640011.483583758, 7772.00667666425, 1047861.7859506, - 1165126.55237647] - sphere_distances = [60580.7612632291, 77143.7785056615, 49199.2725132184, - 90804.4414289463, 217712.63666124, 709131.691061906, - 639825.959074112, 7786.80274606706, 1049200.46122281, - 1162619.7297006] - - # Testing with spheroid distances first. - hillsdale = AustraliaCity.objects.get(name='Hillsdale') - qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point, spheroid=True) - for i, c in enumerate(qs): - self.assertAlmostEqual(spheroid_distances[i], c.distance.m, tol) - if postgis: - # PostGIS uses sphere-only distances by default, testing these as well. - qs = AustraliaCity.objects.exclude(id=hillsdale.id).distance(hillsdale.point) - for i, c in enumerate(qs): - self.assertAlmostEqual(sphere_distances[i], c.distance.m, tol) - - @no_oracle # Oracle already handles geographic distance calculation. - def test03c_distance_method(self): - "Testing the `distance` GeoQuerySet method used with `transform` on a geographic field." - # Normally you can't compute distances from a geometry field - # that is not a PointField (on PostGIS 1.4 and below). - if not connection.ops.geography: - self.assertRaises(ValueError, CensusZipcode.objects.distance, self.stx_pnt) - - # We'll be using a Polygon (created by buffering the centroid - # of 77005 to 100m) -- which aren't allowed in geographic distance - # queries normally, however our field has been transformed to - # a non-geographic system. - z = SouthTexasZipcode.objects.get(name='77005') - - # Reference query: - # SELECT ST_Distance(ST_Transform("distapp_censuszipcode"."poly", 32140), ST_GeomFromText('<buffer_wkt>', 32140)) FROM "distapp_censuszipcode"; - dists_m = [3553.30384972258, 1243.18391525602, 2186.15439472242] - - # Having our buffer in the SRID of the transformation and of the field - # -- should get the same results. The first buffer has no need for - # transformation SQL because it is the same SRID as what was given - # to `transform()`. The second buffer will need to be transformed, - # however. - buf1 = z.poly.centroid.buffer(100) - buf2 = buf1.transform(4269, clone=True) - ref_zips = ['77002', '77025', '77401'] - - for buf in [buf1, buf2]: - qs = CensusZipcode.objects.exclude(name='77005').transform(32140).distance(buf) - self.assertEqual(ref_zips, self.get_names(qs)) - for i, z in enumerate(qs): - self.assertAlmostEqual(z.distance.m, dists_m[i], 5) - - def test04_distance_lookups(self): - "Testing the `distance_lt`, `distance_gt`, `distance_lte`, and `distance_gte` lookup types." - # Retrieving the cities within a 20km 'donut' w/a 7km radius 'hole' - # (thus, Houston and Southside place will be excluded as tested in - # the `test02_dwithin` above). - qs1 = SouthTexasCity.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20))) - - # Can't determine the units on SpatiaLite from PROJ.4 string, and - # Oracle 11 incorrectly thinks it is not projected. - if spatialite or oracle: - dist_qs = (qs1,) - else: - qs2 = SouthTexasCityFt.objects.filter(point__distance_gte=(self.stx_pnt, D(km=7))).filter(point__distance_lte=(self.stx_pnt, D(km=20))) - dist_qs = (qs1, qs2) - - for qs in dist_qs: - cities = self.get_names(qs) - self.assertEqual(cities, ['Bellaire', 'Pearland', 'West University Place']) - - # Doing a distance query using Polygons instead of a Point. - z = SouthTexasZipcode.objects.get(name='77005') - qs = SouthTexasZipcode.objects.exclude(name='77005').filter(poly__distance_lte=(z.poly, D(m=275))) - self.assertEqual(['77025', '77401'], self.get_names(qs)) - # If we add a little more distance 77002 should be included. - qs = SouthTexasZipcode.objects.exclude(name='77005').filter(poly__distance_lte=(z.poly, D(m=300))) - self.assertEqual(['77002', '77025', '77401'], self.get_names(qs)) - - def test05_geodetic_distance_lookups(self): - "Testing distance lookups on geodetic coordinate systems." - # Line is from Canberra to Sydney. Query is for all other cities within - # a 100km of that line (which should exclude only Hobart & Adelaide). - line = GEOSGeometry('LINESTRING(144.9630 -37.8143,151.2607 -33.8870)', 4326) - dist_qs = AustraliaCity.objects.filter(point__distance_lte=(line, D(km=100))) - - if oracle or connection.ops.geography: - # Oracle and PostGIS 1.5 can do distance lookups on arbitrary geometries. - self.assertEqual(9, dist_qs.count()) - self.assertEqual(['Batemans Bay', 'Canberra', 'Hillsdale', - 'Melbourne', 'Mittagong', 'Shellharbour', - 'Sydney', 'Thirroul', 'Wollongong'], - self.get_names(dist_qs)) - else: - # PostGIS 1.4 and below only allows geodetic distance queries (utilizing - # ST_Distance_Sphere/ST_Distance_Spheroid) from Points to PointFields - # on geometry columns. - self.assertRaises(ValueError, dist_qs.count) - - # Ensured that a ValueError was raised, none of the rest of the test is - # support on this backend, so bail now. - if spatialite: return - - # Too many params (4 in this case) should raise a ValueError. - self.assertRaises(ValueError, len, - AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)', D(km=100), 'spheroid', '4'))) - - # Not enough params should raise a ValueError. - self.assertRaises(ValueError, len, - AustraliaCity.objects.filter(point__distance_lte=('POINT(5 23)',))) - - # Getting all cities w/in 550 miles of Hobart. - hobart = AustraliaCity.objects.get(name='Hobart') - qs = AustraliaCity.objects.exclude(name='Hobart').filter(point__distance_lte=(hobart.point, D(mi=550))) - cities = self.get_names(qs) - self.assertEqual(cities, ['Batemans Bay', 'Canberra', 'Melbourne']) - - # Cities that are either really close or really far from Wollongong -- - # and using different units of distance. - wollongong = AustraliaCity.objects.get(name='Wollongong') - d1, d2 = D(yd=19500), D(nm=400) # Yards (~17km) & Nautical miles. - - # Normal geodetic distance lookup (uses `distance_sphere` on PostGIS. - gq1 = Q(point__distance_lte=(wollongong.point, d1)) - gq2 = Q(point__distance_gte=(wollongong.point, d2)) - qs1 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq1 | gq2) - - # Geodetic distance lookup but telling GeoDjango to use `distance_spheroid` - # instead (we should get the same results b/c accuracy variance won't matter - # in this test case). - if postgis: - gq3 = Q(point__distance_lte=(wollongong.point, d1, 'spheroid')) - gq4 = Q(point__distance_gte=(wollongong.point, d2, 'spheroid')) - qs2 = AustraliaCity.objects.exclude(name='Wollongong').filter(gq3 | gq4) - querysets = [qs1, qs2] - else: - querysets = [qs1] - - for qs in querysets: - cities = self.get_names(qs) - self.assertEqual(cities, ['Adelaide', 'Hobart', 'Shellharbour', 'Thirroul']) - - def test06_area(self): - "Testing the `area` GeoQuerySet method." - # Reference queries: - # SELECT ST_Area(poly) FROM distapp_southtexaszipcode; - area_sq_m = [5437908.90234375, 10183031.4389648, 11254471.0073242, 9881708.91772461] - # Tolerance has to be lower for Oracle and differences - # with GEOS 3.0.0RC4 - tol = 2 - for i, z in enumerate(SouthTexasZipcode.objects.area()): - self.assertAlmostEqual(area_sq_m[i], z.area.sq_m, tol) - - def test07_length(self): - "Testing the `length` GeoQuerySet method." - # Reference query (should use `length_spheroid`). - # SELECT ST_length_spheroid(ST_GeomFromText('<wkt>', 4326) 'SPHEROID["WGS 84",6378137,298.257223563, AUTHORITY["EPSG","7030"]]'); - len_m1 = 473504.769553813 - len_m2 = 4617.668 - - if spatialite: - # Does not support geodetic coordinate systems. - self.assertRaises(ValueError, Interstate.objects.length) - else: - qs = Interstate.objects.length() - if oracle: tol = 2 - else: tol = 5 - self.assertAlmostEqual(len_m1, qs[0].length.m, tol) - - # Now doing length on a projected coordinate system. - i10 = SouthTexasInterstate.objects.length().get(name='I-10') - self.assertAlmostEqual(len_m2, i10.length.m, 2) - - @no_spatialite - def test08_perimeter(self): - "Testing the `perimeter` GeoQuerySet method." - # Reference query: - # SELECT ST_Perimeter(distapp_southtexaszipcode.poly) FROM distapp_southtexaszipcode; - perim_m = [18404.3550889361, 15627.2108551001, 20632.5588368978, 17094.5996143697] - if oracle: tol = 2 - else: tol = 7 - for i, z in enumerate(SouthTexasZipcode.objects.perimeter()): - self.assertAlmostEqual(perim_m[i], z.perimeter.m, tol) - - # Running on points; should return 0. - for i, c in enumerate(SouthTexasCity.objects.perimeter(model_att='perim')): - self.assertEqual(0, c.perim.m) - - def test09_measurement_null_fields(self): - "Testing the measurement GeoQuerySet methods on fields with NULL values." - # Creating SouthTexasZipcode w/NULL value. - SouthTexasZipcode.objects.create(name='78212') - # Performing distance/area queries against the NULL PolygonField, - # and ensuring the result of the operations is None. - htown = SouthTexasCity.objects.get(name='Downtown Houston') - z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212') - self.assertEqual(None, z.distance) - self.assertEqual(None, z.area) diff --git a/parts/django/django/contrib/gis/tests/geo3d/__init__.py b/parts/django/django/contrib/gis/tests/geo3d/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/geo3d/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/geo3d/models.py b/parts/django/django/contrib/gis/tests/geo3d/models.py deleted file mode 100644 index 3c4f77e..0000000 --- a/parts/django/django/contrib/gis/tests/geo3d/models.py +++ /dev/null @@ -1,69 +0,0 @@ -from django.contrib.gis.db import models - -class City3D(models.Model): - name = models.CharField(max_length=30) - point = models.PointField(dim=3) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class Interstate2D(models.Model): - name = models.CharField(max_length=30) - line = models.LineStringField(srid=4269) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class Interstate3D(models.Model): - name = models.CharField(max_length=30) - line = models.LineStringField(dim=3, srid=4269) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class InterstateProj2D(models.Model): - name = models.CharField(max_length=30) - line = models.LineStringField(srid=32140) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class InterstateProj3D(models.Model): - name = models.CharField(max_length=30) - line = models.LineStringField(dim=3, srid=32140) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class Polygon2D(models.Model): - name = models.CharField(max_length=30) - poly = models.PolygonField(srid=32140) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class Polygon3D(models.Model): - name = models.CharField(max_length=30) - poly = models.PolygonField(dim=3, srid=32140) - objects = models.GeoManager() - - def __unicode__(self): - return self.name - -class Point2D(models.Model): - point = models.PointField() - objects = models.GeoManager() - -class Point3D(models.Model): - point = models.PointField(dim=3) - objects = models.GeoManager() - -class MultiPoint3D(models.Model): - mpoint = models.MultiPointField(dim=3) - objects = models.GeoManager() diff --git a/parts/django/django/contrib/gis/tests/geo3d/tests.py b/parts/django/django/contrib/gis/tests/geo3d/tests.py deleted file mode 100644 index f57445c..0000000 --- a/parts/django/django/contrib/gis/tests/geo3d/tests.py +++ /dev/null @@ -1,231 +0,0 @@ -import os -import re -from django.utils.unittest import TestCase -from django.contrib.gis.db.models import Union, Extent3D -from django.contrib.gis.geos import GEOSGeometry, Point, Polygon -from django.contrib.gis.utils import LayerMapping, LayerMapError - -from models import City3D, Interstate2D, Interstate3D, \ - InterstateProj2D, InterstateProj3D, \ - Point2D, Point3D, MultiPoint3D, Polygon2D, Polygon3D - -data_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) -city_file = os.path.join(data_path, 'cities', 'cities.shp') -vrt_file = os.path.join(data_path, 'test_vrt', 'test_vrt.vrt') - -# The coordinates of each city, with Z values corresponding to their -# altitude in meters. -city_data = ( - ('Houston', (-95.363151, 29.763374, 18)), - ('Dallas', (-96.801611, 32.782057, 147)), - ('Oklahoma City', (-97.521157, 34.464642, 380)), - ('Wellington', (174.783117, -41.315268, 14)), - ('Pueblo', (-104.609252, 38.255001, 1433)), - ('Lawrence', (-95.235060, 38.971823, 251)), - ('Chicago', (-87.650175, 41.850385, 181)), - ('Victoria', (-123.305196, 48.462611, 15)), -) - -# Reference mapping of city name to its altitude (Z value). -city_dict = dict((name, coords) for name, coords in city_data) - -# 3D freeway data derived from the National Elevation Dataset: -# http://seamless.usgs.gov/products/9arc.php -interstate_data = ( - ('I-45', - 'LINESTRING(-95.3708481 29.7765870 11.339,-95.3694580 29.7787980 4.536,-95.3690305 29.7797359 9.762,-95.3691886 29.7812450 12.448,-95.3696447 29.7850144 10.457,-95.3702511 29.7868518 9.418,-95.3706724 29.7881286 14.858,-95.3711632 29.7896157 15.386,-95.3714525 29.7936267 13.168,-95.3717848 29.7955007 15.104,-95.3717719 29.7969804 16.516,-95.3717305 29.7982117 13.923,-95.3717254 29.8000778 14.385,-95.3719875 29.8013539 15.160,-95.3720575 29.8026785 15.544,-95.3721321 29.8040912 14.975,-95.3722074 29.8050998 15.688,-95.3722779 29.8060430 16.099,-95.3733818 29.8076750 15.197,-95.3741563 29.8103686 17.268,-95.3749458 29.8129927 19.857,-95.3763564 29.8144557 15.435)', - ( 11.339, 4.536, 9.762, 12.448, 10.457, 9.418, 14.858, - 15.386, 13.168, 15.104, 16.516, 13.923, 14.385, 15.16 , - 15.544, 14.975, 15.688, 16.099, 15.197, 17.268, 19.857, - 15.435), - ), - ) - -# Bounding box polygon for inner-loop of Houston (in projected coordinate -# system 32140), with elevation values from the National Elevation Dataset -# (see above). -bbox_wkt = 'POLYGON((941527.97 4225693.20,962596.48 4226349.75,963152.57 4209023.95,942051.75 4208366.38,941527.97 4225693.20))' -bbox_z = (21.71, 13.21, 9.12, 16.40, 21.71) -def gen_bbox(): - bbox_2d = GEOSGeometry(bbox_wkt, srid=32140) - bbox_3d = Polygon(tuple((x, y, z) for (x, y), z in zip(bbox_2d[0].coords, bbox_z)), srid=32140) - return bbox_2d, bbox_3d - -class Geo3DTest(TestCase): - """ - Only a subset of the PostGIS routines are 3D-enabled, and this TestCase - tries to test the features that can handle 3D and that are also - available within GeoDjango. For more information, see the PostGIS docs - on the routines that support 3D: - - http://postgis.refractions.net/documentation/manual-1.4/ch08.html#PostGIS_3D_Functions - """ - - def test01_3d(self): - "Test the creation of 3D models." - # 3D models for the rest of the tests will be populated in here. - # For each 3D data set create model (and 2D version if necessary), - # retrieve, and assert geometry is in 3D and contains the expected - # 3D values. - for name, pnt_data in city_data: - x, y, z = pnt_data - pnt = Point(x, y, z, srid=4326) - City3D.objects.create(name=name, point=pnt) - city = City3D.objects.get(name=name) - self.failUnless(city.point.hasz) - self.assertEqual(z, city.point.z) - - # Interstate (2D / 3D and Geographic/Projected variants) - for name, line, exp_z in interstate_data: - line_3d = GEOSGeometry(line, srid=4269) - # Using `hex` attribute because it omits 3D. - line_2d = GEOSGeometry(line_3d.hex, srid=4269) - - # Creating a geographic and projected version of the - # interstate in both 2D and 3D. - Interstate3D.objects.create(name=name, line=line_3d) - InterstateProj3D.objects.create(name=name, line=line_3d) - Interstate2D.objects.create(name=name, line=line_2d) - InterstateProj2D.objects.create(name=name, line=line_2d) - - # Retrieving and making sure it's 3D and has expected - # Z values -- shouldn't change because of coordinate system. - interstate = Interstate3D.objects.get(name=name) - interstate_proj = InterstateProj3D.objects.get(name=name) - for i in [interstate, interstate_proj]: - self.failUnless(i.line.hasz) - self.assertEqual(exp_z, tuple(i.line.z)) - - # Creating 3D Polygon. - bbox2d, bbox3d = gen_bbox() - Polygon2D.objects.create(name='2D BBox', poly=bbox2d) - Polygon3D.objects.create(name='3D BBox', poly=bbox3d) - p3d = Polygon3D.objects.get(name='3D BBox') - self.failUnless(p3d.poly.hasz) - self.assertEqual(bbox3d, p3d.poly) - - def test01a_3d_layermapping(self): - "Testing LayerMapping on 3D models." - from models import Point2D, Point3D - - point_mapping = {'point' : 'POINT'} - mpoint_mapping = {'mpoint' : 'MULTIPOINT'} - - # The VRT is 3D, but should still be able to map sans the Z. - lm = LayerMapping(Point2D, vrt_file, point_mapping, transform=False) - lm.save() - self.assertEqual(3, Point2D.objects.count()) - - # The city shapefile is 2D, and won't be able to fill the coordinates - # in the 3D model -- thus, a LayerMapError is raised. - self.assertRaises(LayerMapError, LayerMapping, - Point3D, city_file, point_mapping, transform=False) - - # 3D model should take 3D data just fine. - lm = LayerMapping(Point3D, vrt_file, point_mapping, transform=False) - lm.save() - self.assertEqual(3, Point3D.objects.count()) - - # Making sure LayerMapping.make_multi works right, by converting - # a Point25D into a MultiPoint25D. - lm = LayerMapping(MultiPoint3D, vrt_file, mpoint_mapping, transform=False) - lm.save() - self.assertEqual(3, MultiPoint3D.objects.count()) - - def test02a_kml(self): - "Test GeoQuerySet.kml() with Z values." - h = City3D.objects.kml(precision=6).get(name='Houston') - # KML should be 3D. - # `SELECT ST_AsKML(point, 6) FROM geo3d_city3d WHERE name = 'Houston';` - ref_kml_regex = re.compile(r'^<Point><coordinates>-95.363\d+,29.763\d+,18</coordinates></Point>$') - self.failUnless(ref_kml_regex.match(h.kml)) - - def test02b_geojson(self): - "Test GeoQuerySet.geojson() with Z values." - h = City3D.objects.geojson(precision=6).get(name='Houston') - # GeoJSON should be 3D - # `SELECT ST_AsGeoJSON(point, 6) FROM geo3d_city3d WHERE name='Houston';` - ref_json_regex = re.compile(r'^{"type":"Point","coordinates":\[-95.363151,29.763374,18(\.0+)?\]}$') - self.failUnless(ref_json_regex.match(h.geojson)) - - def test03a_union(self): - "Testing the Union aggregate of 3D models." - # PostGIS query that returned the reference EWKT for this test: - # `SELECT ST_AsText(ST_Union(point)) FROM geo3d_city3d;` - ref_ewkt = 'SRID=4326;MULTIPOINT(-123.305196 48.462611 15,-104.609252 38.255001 1433,-97.521157 34.464642 380,-96.801611 32.782057 147,-95.363151 29.763374 18,-95.23506 38.971823 251,-87.650175 41.850385 181,174.783117 -41.315268 14)' - ref_union = GEOSGeometry(ref_ewkt) - union = City3D.objects.aggregate(Union('point'))['point__union'] - self.failUnless(union.hasz) - self.assertEqual(ref_union, union) - - def test03b_extent(self): - "Testing the Extent3D aggregate for 3D models." - # `SELECT ST_Extent3D(point) FROM geo3d_city3d;` - ref_extent3d = (-123.305196, -41.315268, 14,174.783117, 48.462611, 1433) - extent1 = City3D.objects.aggregate(Extent3D('point'))['point__extent3d'] - extent2 = City3D.objects.extent3d() - - def check_extent3d(extent3d, tol=6): - for ref_val, ext_val in zip(ref_extent3d, extent3d): - self.assertAlmostEqual(ref_val, ext_val, tol) - - for e3d in [extent1, extent2]: - check_extent3d(e3d) - - def test04_perimeter(self): - "Testing GeoQuerySet.perimeter() on 3D fields." - # Reference query for values below: - # `SELECT ST_Perimeter3D(poly), ST_Perimeter2D(poly) FROM geo3d_polygon3d;` - ref_perim_3d = 76859.2620451 - ref_perim_2d = 76859.2577803 - tol = 6 - self.assertAlmostEqual(ref_perim_2d, - Polygon2D.objects.perimeter().get(name='2D BBox').perimeter.m, - tol) - self.assertAlmostEqual(ref_perim_3d, - Polygon3D.objects.perimeter().get(name='3D BBox').perimeter.m, - tol) - - def test05_length(self): - "Testing GeoQuerySet.length() on 3D fields." - # ST_Length_Spheroid Z-aware, and thus does not need to use - # a separate function internally. - # `SELECT ST_Length_Spheroid(line, 'SPHEROID["GRS 1980",6378137,298.257222101]') - # FROM geo3d_interstate[2d|3d];` - tol = 3 - ref_length_2d = 4368.1721949481 - ref_length_3d = 4368.62547052088 - self.assertAlmostEqual(ref_length_2d, - Interstate2D.objects.length().get(name='I-45').length.m, - tol) - self.assertAlmostEqual(ref_length_3d, - Interstate3D.objects.length().get(name='I-45').length.m, - tol) - - # Making sure `ST_Length3D` is used on for a projected - # and 3D model rather than `ST_Length`. - # `SELECT ST_Length(line) FROM geo3d_interstateproj2d;` - ref_length_2d = 4367.71564892392 - # `SELECT ST_Length3D(line) FROM geo3d_interstateproj3d;` - ref_length_3d = 4368.16897234101 - self.assertAlmostEqual(ref_length_2d, - InterstateProj2D.objects.length().get(name='I-45').length.m, - tol) - self.assertAlmostEqual(ref_length_3d, - InterstateProj3D.objects.length().get(name='I-45').length.m, - tol) - - def test06_scale(self): - "Testing GeoQuerySet.scale() on Z values." - # Mapping of City name to reference Z values. - zscales = (-3, 4, 23) - for zscale in zscales: - for city in City3D.objects.scale(1.0, 1.0, zscale): - self.assertEqual(city_dict[city.name][2] * zscale, city.scale.z) - - def test07_translate(self): - "Testing GeoQuerySet.translate() on Z values." - ztranslations = (5.23, 23, -17) - for ztrans in ztranslations: - for city in City3D.objects.translate(0, 0, ztrans): - self.assertEqual(city_dict[city.name][2] + ztrans, city.translate.z) diff --git a/parts/django/django/contrib/gis/tests/geo3d/views.py b/parts/django/django/contrib/gis/tests/geo3d/views.py deleted file mode 100644 index 60f00ef..0000000 --- a/parts/django/django/contrib/gis/tests/geo3d/views.py +++ /dev/null @@ -1 +0,0 @@ -# Create your views here. diff --git a/parts/django/django/contrib/gis/tests/geoapp/__init__.py b/parts/django/django/contrib/gis/tests/geoapp/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/geoapp/feeds.py b/parts/django/django/contrib/gis/tests/geoapp/feeds.py deleted file mode 100644 index 942b140..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/feeds.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.contrib.gis import feeds -from django.contrib.gis.tests.utils import mysql -from models import City, Country - -class TestGeoRSS1(feeds.Feed): - link = '/city/' - title = 'Test GeoDjango Cities' - - def items(self): - return City.objects.all() - - def item_link(self, item): - return '/city/%s/' % item.pk - - def item_geometry(self, item): - return item.point - -class TestGeoRSS2(TestGeoRSS1): - def geometry(self, obj): - # This should attach a <georss:box> element for the extent of - # of the cities in the database. This tuple came from - # calling `City.objects.extent()` -- we can't do that call here - # because `extent` is not implemented for MySQL/Oracle. - return (-123.30, -41.32, 174.78, 48.46) - - def item_geometry(self, item): - # Returning a simple tuple for the geometry. - return item.point.x, item.point.y - -class TestGeoAtom1(TestGeoRSS1): - feed_type = feeds.GeoAtom1Feed - -class TestGeoAtom2(TestGeoRSS2): - feed_type = feeds.GeoAtom1Feed - - def geometry(self, obj): - # This time we'll use a 2-tuple of coordinates for the box. - return ((-123.30, -41.32), (174.78, 48.46)) - -class TestW3CGeo1(TestGeoRSS1): - feed_type = feeds.W3CGeoFeed - -# The following feeds are invalid, and will raise exceptions. -class TestW3CGeo2(TestGeoRSS2): - feed_type = feeds.W3CGeoFeed - -class TestW3CGeo3(TestGeoRSS1): - feed_type = feeds.W3CGeoFeed - - def item_geometry(self, item): - from django.contrib.gis.geos import Polygon - return Polygon(((0, 0), (0, 1), (1, 1), (1, 0), (0, 0))) - -# The feed dictionary to use for URLs. -feed_dict = { - 'rss1' : TestGeoRSS1, - 'rss2' : TestGeoRSS2, - 'atom1' : TestGeoAtom1, - 'atom2' : TestGeoAtom2, - 'w3cgeo1' : TestW3CGeo1, - 'w3cgeo2' : TestW3CGeo2, - 'w3cgeo3' : TestW3CGeo3, -} diff --git a/parts/django/django/contrib/gis/tests/geoapp/fixtures/initial_data.json.gz b/parts/django/django/contrib/gis/tests/geoapp/fixtures/initial_data.json.gz Binary files differdeleted file mode 100644 index c695082..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/fixtures/initial_data.json.gz +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/geoapp/models.py b/parts/django/django/contrib/gis/tests/geoapp/models.py deleted file mode 100644 index 89027ee..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/models.py +++ /dev/null @@ -1,45 +0,0 @@ -from django.contrib.gis.db import models -from django.contrib.gis.tests.utils import mysql, spatialite - -# MySQL spatial indices can't handle NULL geometries. -null_flag = not mysql - -class Country(models.Model): - name = models.CharField(max_length=30) - mpoly = models.MultiPolygonField() # SRID, by default, is 4326 - objects = models.GeoManager() - def __unicode__(self): return self.name - -class City(models.Model): - name = models.CharField(max_length=30) - point = models.PointField() - objects = models.GeoManager() - def __unicode__(self): return self.name - -# This is an inherited model from City -class PennsylvaniaCity(City): - county = models.CharField(max_length=30) - objects = models.GeoManager() # TODO: This should be implicitly inherited. - -class State(models.Model): - name = models.CharField(max_length=30) - poly = models.PolygonField(null=null_flag) # Allowing NULL geometries here. - objects = models.GeoManager() - def __unicode__(self): return self.name - -class Track(models.Model): - name = models.CharField(max_length=30) - line = models.LineStringField() - objects = models.GeoManager() - def __unicode__(self): return self.name - -if not spatialite: - class Feature(models.Model): - name = models.CharField(max_length=20) - geom = models.GeometryField() - objects = models.GeoManager() - def __unicode__(self): return self.name - - class MinusOneSRID(models.Model): - geom = models.PointField(srid=-1) # Minus one SRID. - objects = models.GeoManager() diff --git a/parts/django/django/contrib/gis/tests/geoapp/sitemaps.py b/parts/django/django/contrib/gis/tests/geoapp/sitemaps.py deleted file mode 100644 index ca785f2..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/sitemaps.py +++ /dev/null @@ -1,8 +0,0 @@ -from django.contrib.gis.sitemaps import GeoRSSSitemap, KMLSitemap, KMZSitemap -from models import City, Country -from feeds import feed_dict - -sitemaps = {'kml' : KMLSitemap([City, Country]), - 'kmz' : KMZSitemap([City, Country]), - 'georss' : GeoRSSSitemap(feed_dict), - } diff --git a/parts/django/django/contrib/gis/tests/geoapp/test_feeds.py b/parts/django/django/contrib/gis/tests/geoapp/test_feeds.py deleted file mode 100644 index 7ec9a3c..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/test_feeds.py +++ /dev/null @@ -1,78 +0,0 @@ -from xml.dom import minidom -from django.test import TestCase - -from models import City - - -class GeoFeedTest(TestCase): - - urls = 'django.contrib.gis.tests.geoapp.urls' - - def assertChildNodes(self, elem, expected): - "Taken from regressiontests/syndication/tests.py." - actual = set([n.nodeName for n in elem.childNodes]) - expected = set(expected) - self.assertEqual(actual, expected) - - def test_geofeed_rss(self): - "Tests geographic feeds using GeoRSS over RSSv2." - # Uses `GEOSGeometry` in `item_geometry` - doc1 = minidom.parseString(self.client.get('/feeds/rss1/').content) - # Uses a 2-tuple in `item_geometry` - doc2 = minidom.parseString(self.client.get('/feeds/rss2/').content) - feed1, feed2 = doc1.firstChild, doc2.firstChild - - # Making sure the box got added to the second GeoRSS feed. - self.assertChildNodes(feed2.getElementsByTagName('channel')[0], - ['title', 'link', 'description', 'language', - 'lastBuildDate', 'item', 'georss:box', 'atom:link'] - ) - - # Incrementing through the feeds. - for feed in [feed1, feed2]: - # Ensuring the georss namespace was added to the <rss> element. - self.assertEqual(feed.getAttribute(u'xmlns:georss'), u'http://www.georss.org/georss') - chan = feed.getElementsByTagName('channel')[0] - items = chan.getElementsByTagName('item') - self.assertEqual(len(items), City.objects.count()) - - # Ensuring the georss element was added to each item in the feed. - for item in items: - self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'georss:point']) - - def test_geofeed_atom(self): - "Testing geographic feeds using GeoRSS over Atom." - doc1 = minidom.parseString(self.client.get('/feeds/atom1/').content) - doc2 = minidom.parseString(self.client.get('/feeds/atom2/').content) - feed1, feed2 = doc1.firstChild, doc2.firstChild - - # Making sure the box got added to the second GeoRSS feed. - self.assertChildNodes(feed2, ['title', 'link', 'id', 'updated', 'entry', 'georss:box']) - - for feed in [feed1, feed2]: - # Ensuring the georsss namespace was added to the <feed> element. - self.assertEqual(feed.getAttribute(u'xmlns:georss'), u'http://www.georss.org/georss') - entries = feed.getElementsByTagName('entry') - self.assertEqual(len(entries), City.objects.count()) - - # Ensuring the georss element was added to each entry in the feed. - for entry in entries: - self.assertChildNodes(entry, ['title', 'link', 'id', 'summary', 'georss:point']) - - def test_geofeed_w3c(self): - "Testing geographic feeds using W3C Geo." - doc = minidom.parseString(self.client.get('/feeds/w3cgeo1/').content) - feed = doc.firstChild - # Ensuring the geo namespace was added to the <feed> element. - self.assertEqual(feed.getAttribute(u'xmlns:geo'), u'http://www.w3.org/2003/01/geo/wgs84_pos#') - chan = feed.getElementsByTagName('channel')[0] - items = chan.getElementsByTagName('item') - self.assertEqual(len(items), City.objects.count()) - - # Ensuring the geo:lat and geo:lon element was added to each item in the feed. - for item in items: - self.assertChildNodes(item, ['title', 'link', 'description', 'guid', 'geo:lat', 'geo:lon']) - - # Boxes and Polygons aren't allowed in W3C Geo feeds. - self.assertRaises(ValueError, self.client.get, '/feeds/w3cgeo2/') # Box in <channel> - self.assertRaises(ValueError, self.client.get, '/feeds/w3cgeo3/') # Polygons in <entry> diff --git a/parts/django/django/contrib/gis/tests/geoapp/test_regress.py b/parts/django/django/contrib/gis/tests/geoapp/test_regress.py deleted file mode 100644 index 0295526..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/test_regress.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, unittest -from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis, no_spatialite -from django.contrib.gis.shortcuts import render_to_kmz -from models import City - -class GeoRegressionTests(unittest.TestCase): - - def test01_update(self): - "Testing GeoQuerySet.update(), see #10411." - pnt = City.objects.get(name='Pueblo').point - bak = pnt.clone() - pnt.y += 0.005 - pnt.x += 0.005 - - City.objects.filter(name='Pueblo').update(point=pnt) - self.assertEqual(pnt, City.objects.get(name='Pueblo').point) - City.objects.filter(name='Pueblo').update(point=bak) - self.assertEqual(bak, City.objects.get(name='Pueblo').point) - - def test02_kmz(self): - "Testing `render_to_kmz` with non-ASCII data, see #11624." - name = '\xc3\x85land Islands'.decode('iso-8859-1') - places = [{'name' : name, - 'description' : name, - 'kml' : '<Point><coordinates>5.0,23.0</coordinates></Point>' - }] - kmz = render_to_kmz('gis/kml/placemarks.kml', {'places' : places}) - - @no_spatialite - @no_mysql - def test03_extent(self): - "Testing `extent` on a table with a single point, see #11827." - pnt = City.objects.get(name='Pueblo').point - ref_ext = (pnt.x, pnt.y, pnt.x, pnt.y) - extent = City.objects.filter(name='Pueblo').extent() - for ref_val, val in zip(ref_ext, extent): - self.assertAlmostEqual(ref_val, val, 4) diff --git a/parts/django/django/contrib/gis/tests/geoapp/test_sitemaps.py b/parts/django/django/contrib/gis/tests/geoapp/test_sitemaps.py deleted file mode 100644 index c8c43f4..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/test_sitemaps.py +++ /dev/null @@ -1,86 +0,0 @@ -import cStringIO -from xml.dom import minidom -import zipfile -from django.test import TestCase - -from models import City, Country - - -class GeoSitemapTest(TestCase): - - urls = 'django.contrib.gis.tests.geoapp.urls' - - def assertChildNodes(self, elem, expected): - "Taken from regressiontests/syndication/tests.py." - actual = set([n.nodeName for n in elem.childNodes]) - expected = set(expected) - self.assertEqual(actual, expected) - - def test_geositemap_index(self): - "Tests geographic sitemap index." - # Getting the geo index. - doc = minidom.parseString(self.client.get('/sitemap.xml').content) - index = doc.firstChild - self.assertEqual(index.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9') - self.assertEqual(3, len(index.getElementsByTagName('sitemap'))) - - def test_geositemap_kml(self): - "Tests KML/KMZ geographic sitemaps." - for kml_type in ('kml', 'kmz'): - doc = minidom.parseString(self.client.get('/sitemaps/%s.xml' % kml_type).content) - - # Ensuring the right sitemaps namespaces are present. - urlset = doc.firstChild - self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9') - self.assertEqual(urlset.getAttribute(u'xmlns:geo'), u'http://www.google.com/geo/schemas/sitemap/1.0') - - urls = urlset.getElementsByTagName('url') - self.assertEqual(2, len(urls)) # Should only be 2 sitemaps. - for url in urls: - self.assertChildNodes(url, ['loc', 'geo:geo']) - # Making sure the 'geo:format' element was properly set. - geo_elem = url.getElementsByTagName('geo:geo')[0] - geo_format = geo_elem.getElementsByTagName('geo:format')[0] - self.assertEqual(kml_type, geo_format.childNodes[0].data) - - # Getting the relative URL since we don't have a real site. - kml_url = url.getElementsByTagName('loc')[0].childNodes[0].data.split('http://example.com')[1] - - if kml_type == 'kml': - kml_doc = minidom.parseString(self.client.get(kml_url).content) - elif kml_type == 'kmz': - # Have to decompress KMZ before parsing. - buf = cStringIO.StringIO(self.client.get(kml_url).content) - zf = zipfile.ZipFile(buf) - self.assertEqual(1, len(zf.filelist)) - self.assertEqual('doc.kml', zf.filelist[0].filename) - kml_doc = minidom.parseString(zf.read('doc.kml')) - - # Ensuring the correct number of placemarks are in the KML doc. - if 'city' in kml_url: - model = City - elif 'country' in kml_url: - model = Country - self.assertEqual(model.objects.count(), len(kml_doc.getElementsByTagName('Placemark'))) - - def test_geositemap_georss(self): - "Tests GeoRSS geographic sitemaps." - from feeds import feed_dict - - doc = minidom.parseString(self.client.get('/sitemaps/georss.xml').content) - - # Ensuring the right sitemaps namespaces are present. - urlset = doc.firstChild - self.assertEqual(urlset.getAttribute(u'xmlns'), u'http://www.sitemaps.org/schemas/sitemap/0.9') - self.assertEqual(urlset.getAttribute(u'xmlns:geo'), u'http://www.google.com/geo/schemas/sitemap/1.0') - - # Making sure the correct number of feed URLs were included. - urls = urlset.getElementsByTagName('url') - self.assertEqual(len(feed_dict), len(urls)) - - for url in urls: - self.assertChildNodes(url, ['loc', 'geo:geo']) - # Making sure the 'geo:format' element was properly set to 'georss'. - geo_elem = url.getElementsByTagName('geo:geo')[0] - geo_format = geo_elem.getElementsByTagName('geo:format')[0] - self.assertEqual('georss', geo_format.childNodes[0].data) diff --git a/parts/django/django/contrib/gis/tests/geoapp/tests.py b/parts/django/django/contrib/gis/tests/geoapp/tests.py deleted file mode 100644 index a2b81c6..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/tests.py +++ /dev/null @@ -1,735 +0,0 @@ -import re -from django.db import connection -from django.contrib.gis import gdal -from django.contrib.gis.geos import fromstr, GEOSGeometry, \ - Point, LineString, LinearRing, Polygon, GeometryCollection -from django.contrib.gis.measure import Distance -from django.contrib.gis.tests.utils import \ - no_mysql, no_oracle, no_spatialite, \ - mysql, oracle, postgis, spatialite -from django.test import TestCase - -from models import Country, City, PennsylvaniaCity, State, Track - -if not spatialite: - from models import Feature, MinusOneSRID - -class GeoModelTest(TestCase): - - def test01_fixtures(self): - "Testing geographic model initialization from fixtures." - # Ensuring that data was loaded from initial data fixtures. - self.assertEqual(2, Country.objects.count()) - self.assertEqual(8, City.objects.count()) - self.assertEqual(2, State.objects.count()) - - def test02_proxy(self): - "Testing Lazy-Geometry support (using the GeometryProxy)." - ## Testing on a Point - pnt = Point(0, 0) - nullcity = City(name='NullCity', point=pnt) - nullcity.save() - - # Making sure TypeError is thrown when trying to set with an - # incompatible type. - for bad in [5, 2.0, LineString((0, 0), (1, 1))]: - try: - nullcity.point = bad - except TypeError: - pass - else: - self.fail('Should throw a TypeError') - - # Now setting with a compatible GEOS Geometry, saving, and ensuring - # the save took, notice no SRID is explicitly set. - new = Point(5, 23) - nullcity.point = new - - # Ensuring that the SRID is automatically set to that of the - # field after assignment, but before saving. - self.assertEqual(4326, nullcity.point.srid) - nullcity.save() - - # Ensuring the point was saved correctly after saving - self.assertEqual(new, City.objects.get(name='NullCity').point) - - # Setting the X and Y of the Point - nullcity.point.x = 23 - nullcity.point.y = 5 - # Checking assignments pre & post-save. - self.assertNotEqual(Point(23, 5), City.objects.get(name='NullCity').point) - nullcity.save() - self.assertEqual(Point(23, 5), City.objects.get(name='NullCity').point) - nullcity.delete() - - ## Testing on a Polygon - shell = LinearRing((0, 0), (0, 100), (100, 100), (100, 0), (0, 0)) - inner = LinearRing((40, 40), (40, 60), (60, 60), (60, 40), (40, 40)) - - # Creating a State object using a built Polygon - ply = Polygon(shell, inner) - nullstate = State(name='NullState', poly=ply) - self.assertEqual(4326, nullstate.poly.srid) # SRID auto-set from None - nullstate.save() - - ns = State.objects.get(name='NullState') - self.assertEqual(ply, ns.poly) - - # Testing the `ogr` and `srs` lazy-geometry properties. - if gdal.HAS_GDAL: - self.assertEqual(True, isinstance(ns.poly.ogr, gdal.OGRGeometry)) - self.assertEqual(ns.poly.wkb, ns.poly.ogr.wkb) - self.assertEqual(True, isinstance(ns.poly.srs, gdal.SpatialReference)) - self.assertEqual('WGS 84', ns.poly.srs.name) - - # Changing the interior ring on the poly attribute. - new_inner = LinearRing((30, 30), (30, 70), (70, 70), (70, 30), (30, 30)) - ns.poly[1] = new_inner - ply[1] = new_inner - self.assertEqual(4326, ns.poly.srid) - ns.save() - self.assertEqual(ply, State.objects.get(name='NullState').poly) - ns.delete() - - def test03a_kml(self): - "Testing KML output from the database using GeoQuerySet.kml()." - # Only PostGIS supports KML serialization - if not postgis: - self.assertRaises(NotImplementedError, State.objects.all().kml, field_name='poly') - return - - # Should throw a TypeError when trying to obtain KML from a - # non-geometry field. - qs = City.objects.all() - self.assertRaises(TypeError, qs.kml, 'name') - - # The reference KML depends on the version of PostGIS used - # (the output stopped including altitude in 1.3.3). - if connection.ops.spatial_version >= (1, 3, 3): - ref_kml = '<Point><coordinates>-104.609252,38.255001</coordinates></Point>' - else: - ref_kml = '<Point><coordinates>-104.609252,38.255001,0</coordinates></Point>' - - # Ensuring the KML is as expected. - ptown1 = City.objects.kml(field_name='point', precision=9).get(name='Pueblo') - ptown2 = City.objects.kml(precision=9).get(name='Pueblo') - for ptown in [ptown1, ptown2]: - self.assertEqual(ref_kml, ptown.kml) - - def test03b_gml(self): - "Testing GML output from the database using GeoQuerySet.gml()." - if mysql or spatialite: - self.assertRaises(NotImplementedError, Country.objects.all().gml, field_name='mpoly') - return - - # Should throw a TypeError when tyring to obtain GML from a - # non-geometry field. - qs = City.objects.all() - self.assertRaises(TypeError, qs.gml, field_name='name') - ptown1 = City.objects.gml(field_name='point', precision=9).get(name='Pueblo') - ptown2 = City.objects.gml(precision=9).get(name='Pueblo') - - if oracle: - # No precision parameter for Oracle :-/ - gml_regex = re.compile(r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml"><gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ </gml:coordinates></gml:Point>') - for ptown in [ptown1, ptown2]: - self.failUnless(gml_regex.match(ptown.gml)) - else: - gml_regex = re.compile(r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>') - for ptown in [ptown1, ptown2]: - self.failUnless(gml_regex.match(ptown.gml)) - - def test03c_geojson(self): - "Testing GeoJSON output from the database using GeoQuerySet.geojson()." - # Only PostGIS 1.3.4+ supports GeoJSON. - if not connection.ops.geojson: - self.assertRaises(NotImplementedError, Country.objects.all().geojson, field_name='mpoly') - return - - if connection.ops.spatial_version >= (1, 4, 0): - pueblo_json = '{"type":"Point","coordinates":[-104.609252,38.255001]}' - houston_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"coordinates":[-95.363151,29.763374]}' - victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.305196,48.462611]}' - chicago_json = '{"type":"Point","crs":{"type":"name","properties":{"name":"EPSG:4326"}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' - else: - pueblo_json = '{"type":"Point","coordinates":[-104.60925200,38.25500100]}' - houston_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"coordinates":[-95.36315100,29.76337400]}' - victoria_json = '{"type":"Point","bbox":[-123.30519600,48.46261100,-123.30519600,48.46261100],"coordinates":[-123.30519600,48.46261100]}' - chicago_json = '{"type":"Point","crs":{"type":"EPSG","properties":{"EPSG":4326}},"bbox":[-87.65018,41.85039,-87.65018,41.85039],"coordinates":[-87.65018,41.85039]}' - - # Precision argument should only be an integer - self.assertRaises(TypeError, City.objects.geojson, precision='foo') - - # Reference queries and values. - # SELECT ST_AsGeoJson("geoapp_city"."point", 8, 0) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Pueblo'; - self.assertEqual(pueblo_json, City.objects.geojson().get(name='Pueblo').geojson) - - # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; - # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; - # This time we want to include the CRS by using the `crs` keyword. - self.assertEqual(houston_json, City.objects.geojson(crs=True, model_att='json').get(name='Houston').json) - - # 1.3.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 2) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Victoria'; - # 1.4.x: SELECT ST_AsGeoJson("geoapp_city"."point", 8, 1) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Houston'; - # This time we include the bounding box by using the `bbox` keyword. - self.assertEqual(victoria_json, City.objects.geojson(bbox=True).get(name='Victoria').geojson) - - # 1.(3|4).x: SELECT ST_AsGeoJson("geoapp_city"."point", 5, 3) FROM "geoapp_city" WHERE "geoapp_city"."name" = 'Chicago'; - # Finally, we set every available keyword. - self.assertEqual(chicago_json, City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson) - - def test03d_svg(self): - "Testing SVG output using GeoQuerySet.svg()." - if mysql or oracle: - self.assertRaises(NotImplementedError, City.objects.svg) - return - - self.assertRaises(TypeError, City.objects.svg, precision='foo') - # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo'; - svg1 = 'cx="-104.609252" cy="-38.255001"' - # Even though relative, only one point so it's practically the same except for - # the 'c' letter prefix on the x,y values. - svg2 = svg1.replace('c', '') - self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg) - self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg) - - @no_mysql - def test04_transform(self): - "Testing the transform() GeoManager method." - # Pre-transformed points for Houston and Pueblo. - htown = fromstr('POINT(1947516.83115183 6322297.06040572)', srid=3084) - ptown = fromstr('POINT(992363.390841912 481455.395105533)', srid=2774) - prec = 3 # Precision is low due to version variations in PROJ and GDAL. - - # Asserting the result of the transform operation with the values in - # the pre-transformed points. Oracle does not have the 3084 SRID. - if not oracle: - h = City.objects.transform(htown.srid).get(name='Houston') - self.assertEqual(3084, h.point.srid) - self.assertAlmostEqual(htown.x, h.point.x, prec) - self.assertAlmostEqual(htown.y, h.point.y, prec) - - p1 = City.objects.transform(ptown.srid, field_name='point').get(name='Pueblo') - p2 = City.objects.transform(srid=ptown.srid).get(name='Pueblo') - for p in [p1, p2]: - self.assertEqual(2774, p.point.srid) - self.assertAlmostEqual(ptown.x, p.point.x, prec) - self.assertAlmostEqual(ptown.y, p.point.y, prec) - - @no_mysql - @no_spatialite # SpatiaLite does not have an Extent function - def test05_extent(self): - "Testing the `extent` GeoQuerySet method." - # Reference query: - # `SELECT ST_extent(point) FROM geoapp_city WHERE (name='Houston' or name='Dallas');` - # => BOX(-96.8016128540039 29.7633724212646,-95.3631439208984 32.7820587158203) - expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820) - - qs = City.objects.filter(name__in=('Houston', 'Dallas')) - extent = qs.extent() - - for val, exp in zip(extent, expected): - self.assertAlmostEqual(exp, val, 4) - - # Only PostGIS has support for the MakeLine aggregate. - @no_mysql - @no_oracle - @no_spatialite - def test06_make_line(self): - "Testing the `make_line` GeoQuerySet method." - # Ensuring that a `TypeError` is raised on models without PointFields. - self.assertRaises(TypeError, State.objects.make_line) - self.assertRaises(TypeError, Country.objects.make_line) - # Reference query: - # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; - ref_line = GEOSGeometry('LINESTRING(-95.363151 29.763374,-96.801611 32.782057,-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326) - self.assertEqual(ref_line, City.objects.make_line()) - - @no_mysql - def test09_disjoint(self): - "Testing the `disjoint` lookup type." - ptown = City.objects.get(name='Pueblo') - qs1 = City.objects.filter(point__disjoint=ptown.point) - self.assertEqual(7, qs1.count()) - - qs2 = State.objects.filter(poly__disjoint=ptown.point) - self.assertEqual(1, qs2.count()) - self.assertEqual('Kansas', qs2[0].name) - - def test10_contains_contained(self): - "Testing the 'contained', 'contains', and 'bbcontains' lookup types." - # Getting Texas, yes we were a country -- once ;) - texas = Country.objects.get(name='Texas') - - # Seeing what cities are in Texas, should get Houston and Dallas, - # and Oklahoma City because 'contained' only checks on the - # _bounding box_ of the Geometries. - if not oracle: - qs = City.objects.filter(point__contained=texas.mpoly) - self.assertEqual(3, qs.count()) - cities = ['Houston', 'Dallas', 'Oklahoma City'] - for c in qs: self.assertEqual(True, c.name in cities) - - # Pulling out some cities. - houston = City.objects.get(name='Houston') - wellington = City.objects.get(name='Wellington') - pueblo = City.objects.get(name='Pueblo') - okcity = City.objects.get(name='Oklahoma City') - lawrence = City.objects.get(name='Lawrence') - - # Now testing contains on the countries using the points for - # Houston and Wellington. - tx = Country.objects.get(mpoly__contains=houston.point) # Query w/GEOSGeometry - nz = Country.objects.get(mpoly__contains=wellington.point.hex) # Query w/EWKBHEX - self.assertEqual('Texas', tx.name) - self.assertEqual('New Zealand', nz.name) - - # Spatialite 2.3 thinks that Lawrence is in Puerto Rico (a NULL geometry). - if not spatialite: - ks = State.objects.get(poly__contains=lawrence.point) - self.assertEqual('Kansas', ks.name) - - # Pueblo and Oklahoma City (even though OK City is within the bounding box of Texas) - # are not contained in Texas or New Zealand. - self.assertEqual(0, len(Country.objects.filter(mpoly__contains=pueblo.point))) # Query w/GEOSGeometry object - self.assertEqual((mysql and 1) or 0, - len(Country.objects.filter(mpoly__contains=okcity.point.wkt))) # Qeury w/WKT - - # OK City is contained w/in bounding box of Texas. - if not oracle: - qs = Country.objects.filter(mpoly__bbcontains=okcity.point) - self.assertEqual(1, len(qs)) - self.assertEqual('Texas', qs[0].name) - - @no_mysql - def test11_lookup_insert_transform(self): - "Testing automatic transform for lookups and inserts." - # San Antonio in 'WGS84' (SRID 4326) - sa_4326 = 'POINT (-98.493183 29.424170)' - wgs_pnt = fromstr(sa_4326, srid=4326) # Our reference point in WGS84 - - # Oracle doesn't have SRID 3084, using 41157. - if oracle: - # San Antonio in 'Texas 4205, Southern Zone (1983, meters)' (SRID 41157) - # Used the following Oracle SQL to get this value: - # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_CS.TRANSFORM(SDO_GEOMETRY('POINT (-98.493183 29.424170)', 4326), 41157)) FROM DUAL; - nad_wkt = 'POINT (300662.034646583 5416427.45974934)' - nad_srid = 41157 - else: - # San Antonio in 'NAD83(HARN) / Texas Centric Lambert Conformal' (SRID 3084) - nad_wkt = 'POINT (1645978.362408288754523 6276356.025927528738976)' # Used ogr.py in gdal 1.4.1 for this transform - nad_srid = 3084 - - # Constructing & querying with a point from a different SRID. Oracle - # `SDO_OVERLAPBDYINTERSECT` operates differently from - # `ST_Intersects`, so contains is used instead. - nad_pnt = fromstr(nad_wkt, srid=nad_srid) - if oracle: - tx = Country.objects.get(mpoly__contains=nad_pnt) - else: - tx = Country.objects.get(mpoly__intersects=nad_pnt) - self.assertEqual('Texas', tx.name) - - # Creating San Antonio. Remember the Alamo. - sa = City.objects.create(name='San Antonio', point=nad_pnt) - - # Now verifying that San Antonio was transformed correctly - sa = City.objects.get(name='San Antonio') - self.assertAlmostEqual(wgs_pnt.x, sa.point.x, 6) - self.assertAlmostEqual(wgs_pnt.y, sa.point.y, 6) - - # If the GeometryField SRID is -1, then we shouldn't perform any - # transformation if the SRID of the input geometry is different. - # SpatiaLite does not support missing SRID values. - if not spatialite: - m1 = MinusOneSRID(geom=Point(17, 23, srid=4326)) - m1.save() - self.assertEqual(-1, m1.geom.srid) - - @no_mysql - def test12_null_geometries(self): - "Testing NULL geometry support, and the `isnull` lookup type." - # Creating a state with a NULL boundary. - State.objects.create(name='Puerto Rico') - - # Querying for both NULL and Non-NULL values. - nullqs = State.objects.filter(poly__isnull=True) - validqs = State.objects.filter(poly__isnull=False) - - # Puerto Rico should be NULL (it's a commonwealth unincorporated territory) - self.assertEqual(1, len(nullqs)) - self.assertEqual('Puerto Rico', nullqs[0].name) - - # The valid states should be Colorado & Kansas - self.assertEqual(2, len(validqs)) - state_names = [s.name for s in validqs] - self.assertEqual(True, 'Colorado' in state_names) - self.assertEqual(True, 'Kansas' in state_names) - - # Saving another commonwealth w/a NULL geometry. - nmi = State.objects.create(name='Northern Mariana Islands', poly=None) - self.assertEqual(nmi.poly, None) - - # Assigning a geomery and saving -- then UPDATE back to NULL. - nmi.poly = 'POLYGON((0 0,1 0,1 1,1 0,0 0))' - nmi.save() - State.objects.filter(name='Northern Mariana Islands').update(poly=None) - self.assertEqual(None, State.objects.get(name='Northern Mariana Islands').poly) - - # Only PostGIS has `left` and `right` lookup types. - @no_mysql - @no_oracle - @no_spatialite - def test13_left_right(self): - "Testing the 'left' and 'right' lookup types." - # Left: A << B => true if xmax(A) < xmin(B) - # Right: A >> B => true if xmin(A) > xmax(B) - # See: BOX2D_left() and BOX2D_right() in lwgeom_box2dfloat4.c in PostGIS source. - - # Getting the borders for Colorado & Kansas - co_border = State.objects.get(name='Colorado').poly - ks_border = State.objects.get(name='Kansas').poly - - # Note: Wellington has an 'X' value of 174, so it will not be considered - # to the left of CO. - - # These cities should be strictly to the right of the CO border. - cities = ['Houston', 'Dallas', 'Oklahoma City', - 'Lawrence', 'Chicago', 'Wellington'] - qs = City.objects.filter(point__right=co_border) - self.assertEqual(6, len(qs)) - for c in qs: self.assertEqual(True, c.name in cities) - - # These cities should be strictly to the right of the KS border. - cities = ['Chicago', 'Wellington'] - qs = City.objects.filter(point__right=ks_border) - self.assertEqual(2, len(qs)) - for c in qs: self.assertEqual(True, c.name in cities) - - # Note: Wellington has an 'X' value of 174, so it will not be considered - # to the left of CO. - vic = City.objects.get(point__left=co_border) - self.assertEqual('Victoria', vic.name) - - cities = ['Pueblo', 'Victoria'] - qs = City.objects.filter(point__left=ks_border) - self.assertEqual(2, len(qs)) - for c in qs: self.assertEqual(True, c.name in cities) - - def test14_equals(self): - "Testing the 'same_as' and 'equals' lookup types." - pnt = fromstr('POINT (-95.363151 29.763374)', srid=4326) - c1 = City.objects.get(point=pnt) - c2 = City.objects.get(point__same_as=pnt) - c3 = City.objects.get(point__equals=pnt) - for c in [c1, c2, c3]: self.assertEqual('Houston', c.name) - - @no_mysql - def test15_relate(self): - "Testing the 'relate' lookup type." - # To make things more interesting, we will have our Texas reference point in - # different SRIDs. - pnt1 = fromstr('POINT (649287.0363174 4177429.4494686)', srid=2847) - pnt2 = fromstr('POINT(-98.4919715741052 29.4333344025053)', srid=4326) - - # Not passing in a geometry as first param shoud - # raise a type error when initializing the GeoQuerySet - self.assertRaises(ValueError, Country.objects.filter, mpoly__relate=(23, 'foo')) - - # Making sure the right exception is raised for the given - # bad arguments. - for bad_args, e in [((pnt1, 0), ValueError), ((pnt2, 'T*T***FF*', 0), ValueError)]: - qs = Country.objects.filter(mpoly__relate=bad_args) - self.assertRaises(e, qs.count) - - # Relate works differently for the different backends. - if postgis or spatialite: - contains_mask = 'T*T***FF*' - within_mask = 'T*F**F***' - intersects_mask = 'T********' - elif oracle: - contains_mask = 'contains' - within_mask = 'inside' - # TODO: This is not quite the same as the PostGIS mask above - intersects_mask = 'overlapbdyintersect' - - # Testing contains relation mask. - self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt1, contains_mask)).name) - self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, contains_mask)).name) - - # Testing within relation mask. - ks = State.objects.get(name='Kansas') - self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, within_mask)).name) - - # Testing intersection relation mask. - if not oracle: - self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt1, intersects_mask)).name) - self.assertEqual('Texas', Country.objects.get(mpoly__relate=(pnt2, intersects_mask)).name) - self.assertEqual('Lawrence', City.objects.get(point__relate=(ks.poly, intersects_mask)).name) - - def test16_createnull(self): - "Testing creating a model instance and the geometry being None" - c = City() - self.assertEqual(c.point, None) - - @no_mysql - def test17_unionagg(self): - "Testing the `unionagg` (aggregate union) GeoManager method." - tx = Country.objects.get(name='Texas').mpoly - # Houston, Dallas -- Oracle has different order. - union1 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') - union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374)') - qs = City.objects.filter(point__within=tx) - self.assertRaises(TypeError, qs.unionagg, 'name') - # Using `field_name` keyword argument in one query and specifying an - # order in the other (which should not be used because this is - # an aggregate method on a spatial column) - u1 = qs.unionagg(field_name='point') - u2 = qs.order_by('name').unionagg() - tol = 0.00001 - if oracle: - union = union2 - else: - union = union1 - self.assertEqual(True, union.equals_exact(u1, tol)) - self.assertEqual(True, union.equals_exact(u2, tol)) - qs = City.objects.filter(name='NotACity') - self.assertEqual(None, qs.unionagg(field_name='point')) - - @no_spatialite # SpatiaLite does not support abstract geometry columns - def test18_geometryfield(self): - "Testing the general GeometryField." - Feature(name='Point', geom=Point(1, 1)).save() - Feature(name='LineString', geom=LineString((0, 0), (1, 1), (5, 5))).save() - Feature(name='Polygon', geom=Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0)))).save() - Feature(name='GeometryCollection', - geom=GeometryCollection(Point(2, 2), LineString((0, 0), (2, 2)), - Polygon(LinearRing((0, 0), (0, 5), (5, 5), (5, 0), (0, 0))))).save() - - f_1 = Feature.objects.get(name='Point') - self.assertEqual(True, isinstance(f_1.geom, Point)) - self.assertEqual((1.0, 1.0), f_1.geom.tuple) - f_2 = Feature.objects.get(name='LineString') - self.assertEqual(True, isinstance(f_2.geom, LineString)) - self.assertEqual(((0.0, 0.0), (1.0, 1.0), (5.0, 5.0)), f_2.geom.tuple) - - f_3 = Feature.objects.get(name='Polygon') - self.assertEqual(True, isinstance(f_3.geom, Polygon)) - f_4 = Feature.objects.get(name='GeometryCollection') - self.assertEqual(True, isinstance(f_4.geom, GeometryCollection)) - self.assertEqual(f_3.geom, f_4.geom[2]) - - @no_mysql - def test19_centroid(self): - "Testing the `centroid` GeoQuerySet method." - qs = State.objects.exclude(poly__isnull=True).centroid() - if oracle: - tol = 0.1 - elif spatialite: - tol = 0.000001 - else: - tol = 0.000000001 - for s in qs: - self.assertEqual(True, s.poly.centroid.equals_exact(s.centroid, tol)) - - @no_mysql - def test20_pointonsurface(self): - "Testing the `point_on_surface` GeoQuerySet method." - # Reference values. - if oracle: - # SELECT SDO_UTIL.TO_WKTGEOMETRY(SDO_GEOM.SDO_POINTONSURFACE(GEOAPP_COUNTRY.MPOLY, 0.05)) FROM GEOAPP_COUNTRY; - ref = {'New Zealand' : fromstr('POINT (174.616364 -36.100861)', srid=4326), - 'Texas' : fromstr('POINT (-103.002434 36.500397)', srid=4326), - } - - elif postgis or spatialite: - # Using GEOSGeometry to compute the reference point on surface values - # -- since PostGIS also uses GEOS these should be the same. - ref = {'New Zealand' : Country.objects.get(name='New Zealand').mpoly.point_on_surface, - 'Texas' : Country.objects.get(name='Texas').mpoly.point_on_surface - } - - for c in Country.objects.point_on_surface(): - if spatialite: - # XXX This seems to be a WKT-translation-related precision issue? - tol = 0.00001 - else: - tol = 0.000000001 - self.assertEqual(True, ref[c.name].equals_exact(c.point_on_surface, tol)) - - @no_mysql - @no_oracle - def test21_scale(self): - "Testing the `scale` GeoQuerySet method." - xfac, yfac = 2, 3 - tol = 5 # XXX The low precision tolerance is for SpatiaLite - qs = Country.objects.scale(xfac, yfac, model_att='scaled') - for c in qs: - for p1, p2 in zip(c.mpoly, c.scaled): - for r1, r2 in zip(p1, p2): - for c1, c2 in zip(r1.coords, r2.coords): - self.assertAlmostEqual(c1[0] * xfac, c2[0], tol) - self.assertAlmostEqual(c1[1] * yfac, c2[1], tol) - - @no_mysql - @no_oracle - def test22_translate(self): - "Testing the `translate` GeoQuerySet method." - xfac, yfac = 5, -23 - qs = Country.objects.translate(xfac, yfac, model_att='translated') - for c in qs: - for p1, p2 in zip(c.mpoly, c.translated): - for r1, r2 in zip(p1, p2): - for c1, c2 in zip(r1.coords, r2.coords): - # XXX The low precision is for SpatiaLite - self.assertAlmostEqual(c1[0] + xfac, c2[0], 5) - self.assertAlmostEqual(c1[1] + yfac, c2[1], 5) - - @no_mysql - def test23_numgeom(self): - "Testing the `num_geom` GeoQuerySet method." - # Both 'countries' only have two geometries. - for c in Country.objects.num_geom(): self.assertEqual(2, c.num_geom) - for c in City.objects.filter(point__isnull=False).num_geom(): - # Oracle will return 1 for the number of geometries on non-collections, - # whereas PostGIS will return None. - if postgis: - self.assertEqual(None, c.num_geom) - else: - self.assertEqual(1, c.num_geom) - - @no_mysql - @no_spatialite # SpatiaLite can only count vertices in LineStrings - def test24_numpoints(self): - "Testing the `num_points` GeoQuerySet method." - for c in Country.objects.num_points(): - self.assertEqual(c.mpoly.num_points, c.num_points) - - if not oracle: - # Oracle cannot count vertices in Point geometries. - for c in City.objects.num_points(): self.assertEqual(1, c.num_points) - - @no_mysql - def test25_geoset(self): - "Testing the `difference`, `intersection`, `sym_difference`, and `union` GeoQuerySet methods." - geom = Point(5, 23) - tol = 1 - qs = Country.objects.all().difference(geom).sym_difference(geom).union(geom) - - # XXX For some reason SpatiaLite does something screwey with the Texas geometry here. Also, - # XXX it doesn't like the null intersection. - if spatialite: - qs = qs.exclude(name='Texas') - else: - qs = qs.intersection(geom) - - for c in qs: - if oracle: - # Should be able to execute the queries; however, they won't be the same - # as GEOS (because Oracle doesn't use GEOS internally like PostGIS or - # SpatiaLite). - pass - else: - self.assertEqual(c.mpoly.difference(geom), c.difference) - if not spatialite: - self.assertEqual(c.mpoly.intersection(geom), c.intersection) - self.assertEqual(c.mpoly.sym_difference(geom), c.sym_difference) - self.assertEqual(c.mpoly.union(geom), c.union) - - @no_mysql - def test26_inherited_geofields(self): - "Test GeoQuerySet methods on inherited Geometry fields." - # Creating a Pennsylvanian city. - mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)') - - # All transformation SQL will need to be performed on the - # _parent_ table. - qs = PennsylvaniaCity.objects.transform(32128) - - self.assertEqual(1, qs.count()) - for pc in qs: self.assertEqual(32128, pc.point.srid) - - @no_mysql - @no_oracle - @no_spatialite - def test27_snap_to_grid(self): - "Testing GeoQuerySet.snap_to_grid()." - # Let's try and break snap_to_grid() with bad combinations of arguments. - for bad_args in ((), range(3), range(5)): - self.assertRaises(ValueError, Country.objects.snap_to_grid, *bad_args) - for bad_args in (('1.0',), (1.0, None), tuple(map(unicode, range(4)))): - self.assertRaises(TypeError, Country.objects.snap_to_grid, *bad_args) - - # Boundary for San Marino, courtesy of Bjorn Sandvik of thematicmapping.org - # from the world borders dataset he provides. - wkt = ('MULTIPOLYGON(((12.41580 43.95795,12.45055 43.97972,12.45389 43.98167,' - '12.46250 43.98472,12.47167 43.98694,12.49278 43.98917,' - '12.50555 43.98861,12.51000 43.98694,12.51028 43.98277,' - '12.51167 43.94333,12.51056 43.93916,12.49639 43.92333,' - '12.49500 43.91472,12.48778 43.90583,12.47444 43.89722,' - '12.46472 43.89555,12.45917 43.89611,12.41639 43.90472,' - '12.41222 43.90610,12.40782 43.91366,12.40389 43.92667,' - '12.40500 43.94833,12.40889 43.95499,12.41580 43.95795)))') - sm = Country.objects.create(name='San Marino', mpoly=fromstr(wkt)) - - # Because floating-point arithmitic isn't exact, we set a tolerance - # to pass into GEOS `equals_exact`. - tol = 0.000000001 - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.1)) FROM "geoapp_country" WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr('MULTIPOLYGON(((12.4 44,12.5 44,12.5 43.9,12.4 43.9,12.4 44)))') - self.failUnless(ref.equals_exact(Country.objects.snap_to_grid(0.1).get(name='San Marino').snap_to_grid, tol)) - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.05, 0.23)) FROM "geoapp_country" WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr('MULTIPOLYGON(((12.4 43.93,12.45 43.93,12.5 43.93,12.45 43.93,12.4 43.93)))') - self.failUnless(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23).get(name='San Marino').snap_to_grid, tol)) - - # SELECT AsText(ST_SnapToGrid("geoapp_country"."mpoly", 0.5, 0.17, 0.05, 0.23)) FROM "geoapp_country" WHERE "geoapp_country"."name" = 'San Marino'; - ref = fromstr('MULTIPOLYGON(((12.4 43.87,12.45 43.87,12.45 44.1,12.5 44.1,12.5 43.87,12.45 43.87,12.4 43.87)))') - self.failUnless(ref.equals_exact(Country.objects.snap_to_grid(0.05, 0.23, 0.5, 0.17).get(name='San Marino').snap_to_grid, tol)) - - @no_mysql - @no_spatialite - def test28_reverse(self): - "Testing GeoQuerySet.reverse_geom()." - coords = [ (-95.363151, 29.763374), (-95.448601, 29.713803) ] - Track.objects.create(name='Foo', line=LineString(coords)) - t = Track.objects.reverse_geom().get(name='Foo') - coords.reverse() - self.assertEqual(tuple(coords), t.reverse_geom.coords) - if oracle: - self.assertRaises(TypeError, State.objects.reverse_geom) - - @no_mysql - @no_oracle - @no_spatialite - def test29_force_rhr(self): - "Testing GeoQuerySet.force_rhr()." - rings = ( ( (0, 0), (5, 0), (0, 5), (0, 0) ), - ( (1, 1), (1, 3), (3, 1), (1, 1) ), - ) - rhr_rings = ( ( (0, 0), (0, 5), (5, 0), (0, 0) ), - ( (1, 1), (3, 1), (1, 3), (1, 1) ), - ) - State.objects.create(name='Foo', poly=Polygon(*rings)) - s = State.objects.force_rhr().get(name='Foo') - self.assertEqual(rhr_rings, s.force_rhr.coords) - - @no_mysql - @no_oracle - @no_spatialite - def test29_force_rhr(self): - "Testing GeoQuerySet.geohash()." - if not connection.ops.geohash: return - # Reference query: - # SELECT ST_GeoHash(point) FROM geoapp_city WHERE name='Houston'; - # SELECT ST_GeoHash(point, 5) FROM geoapp_city WHERE name='Houston'; - ref_hash = '9vk1mfq8jx0c8e0386z6' - h1 = City.objects.geohash().get(name='Houston') - h2 = City.objects.geohash(precision=5).get(name='Houston') - self.assertEqual(ref_hash, h1.geohash) - self.assertEqual(ref_hash[:5], h2.geohash) - -from test_feeds import GeoFeedTest -from test_regress import GeoRegressionTests -from test_sitemaps import GeoSitemapTest diff --git a/parts/django/django/contrib/gis/tests/geoapp/urls.py b/parts/django/django/contrib/gis/tests/geoapp/urls.py deleted file mode 100644 index edaf280..0000000 --- a/parts/django/django/contrib/gis/tests/geoapp/urls.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.conf.urls.defaults import * -from feeds import feed_dict - -urlpatterns = patterns('', - (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feed_dict}), -) - -from sitemaps import sitemaps -urlpatterns += patterns('django.contrib.gis.sitemaps.views', - (r'^sitemap.xml$', 'index', {'sitemaps' : sitemaps}), - (r'^sitemaps/(?P<section>\w+)\.xml$', 'sitemap', {'sitemaps' : sitemaps}), - (r'^sitemaps/kml/(?P<label>\w+)/(?P<model>\w+)/(?P<field_name>\w+)\.kml$', 'kml'), - (r'^sitemaps/kml/(?P<label>\w+)/(?P<model>\w+)/(?P<field_name>\w+)\.kmz$', 'kmz'), -) diff --git a/parts/django/django/contrib/gis/tests/geogapp/__init__.py b/parts/django/django/contrib/gis/tests/geogapp/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/geogapp/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/geogapp/fixtures/initial_data.json b/parts/django/django/contrib/gis/tests/geogapp/fixtures/initial_data.json deleted file mode 100644 index 0664411..0000000 --- a/parts/django/django/contrib/gis/tests/geogapp/fixtures/initial_data.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "pk": 1, - "model": "geogapp.city", - "fields": { - "name": "Houston", - "point": "POINT (-95.363151 29.763374)" - } - }, - { - "pk": 2, - "model": "geogapp.city", - "fields": { - "name": "Dallas", - "point": "POINT (-96.801611 32.782057)" - } - }, - { - "pk": 3, - "model": "geogapp.city", - "fields": { - "name": "Oklahoma City", - "point": "POINT (-97.521157 34.464642)" - } - }, - { - "pk": 4, - "model": "geogapp.city", - "fields": { - "name": "Wellington", - "point": "POINT (174.783117 -41.315268)" - } - }, - { - "pk": 5, - "model": "geogapp.city", - "fields": { - "name": "Pueblo", - "point": "POINT (-104.609252 38.255001)" - } - }, - { - "pk": 6, - "model": "geogapp.city", - "fields": { - "name": "Lawrence", - "point": "POINT (-95.235060 38.971823)" - } - }, - { - "pk": 7, - "model": "geogapp.city", - "fields": { - "name": "Chicago", - "point": "POINT (-87.650175 41.850385)" - } - }, - { - "pk": 8, - "model": "geogapp.city", - "fields": { - "name": "Victoria", - "point": "POINT (-123.305196 48.462611)" - } - }, - { - "pk": 1, - "model": "geogapp.zipcode", - "fields" : { - "code" : "77002", - "poly" : "SRID=4269;POLYGON ((-95.365015 29.772327, -95.362415 29.772327, -95.360915 29.771827, -95.354615 29.771827, -95.351515 29.772527, -95.350915 29.765327, -95.351015 29.762436, -95.350115 29.760328, -95.347515 29.758528, -95.352315 29.753928, -95.356415 29.756328, -95.358215 29.754028, -95.360215 29.756328, -95.363415 29.757128, -95.364014 29.75638, -95.363415 29.753928, -95.360015 29.751828, -95.361815 29.749528, -95.362715 29.750028, -95.367516 29.744128, -95.369316 29.745128, -95.373916 29.744128, -95.380116 29.738028, -95.387916 29.727929, -95.388516 29.729629, -95.387916 29.732129, -95.382916 29.737428, -95.376616 29.742228, -95.372616 29.747228, -95.378601 29.750846, -95.378616 29.752028, -95.378616 29.754428, -95.376016 29.754528, -95.374616 29.759828, -95.373616 29.761128, -95.371916 29.763928, -95.372316 29.768727, -95.365884 29.76791, -95.366015 29.767127, -95.358715 29.765327, -95.358615 29.766327, -95.359115 29.767227, -95.360215 29.767027, -95.362783 29.768267, -95.365315 29.770527, -95.365015 29.772327))" - } - }, - { - "pk": 2, - "model": "geogapp.zipcode", - "fields" : { - "code" : "77005", - "poly" : "SRID=4269;POLYGON ((-95.447918 29.727275, -95.428017 29.728729, -95.421117 29.729029, -95.418617 29.727629, -95.418517 29.726429, -95.402117 29.726629, -95.402117 29.725729, -95.395316 29.725729, -95.391916 29.726229, -95.389716 29.725829, -95.396517 29.715429, -95.397517 29.715929, -95.400917 29.711429, -95.411417 29.715029, -95.418417 29.714729, -95.418317 29.70623, -95.440818 29.70593, -95.445018 29.70683, -95.446618 29.70763, -95.447418 29.71003, -95.447918 29.727275))" - } - }, - { - "pk": 3, - "model": "geogapp.zipcode", - "fields" : { - "code" : "77025", - "poly" : "SRID=4269;POLYGON ((-95.418317 29.70623, -95.414717 29.706129, -95.414617 29.70533, -95.418217 29.70533, -95.419817 29.69533, -95.419484 29.694196, -95.417166 29.690901, -95.414517 29.69433, -95.413317 29.69263, -95.412617 29.68973, -95.412817 29.68753, -95.414087 29.685055, -95.419165 29.685428, -95.421617 29.68513, -95.425717 29.67983, -95.425017 29.67923, -95.424517 29.67763, -95.427418 29.67763, -95.438018 29.664631, -95.436713 29.664411, -95.440118 29.662231, -95.439218 29.661031, -95.437718 29.660131, -95.435718 29.659731, -95.431818 29.660331, -95.441418 29.656631, -95.441318 29.656331, -95.441818 29.656131, -95.441718 29.659031, -95.441118 29.661031, -95.446718 29.656431, -95.446518 29.673431, -95.446918 29.69013, -95.447418 29.71003, -95.446618 29.70763, -95.445018 29.70683, -95.440818 29.70593, -95.418317 29.70623))" - } - }, - { - "pk": 4, - "model": "geogapp.zipcode", - "fields" : { - "code" : "77401", - "poly" : "SRID=4269;POLYGON ((-95.447918 29.727275, -95.447418 29.71003, -95.446918 29.69013, -95.454318 29.68893, -95.475819 29.68903, -95.475819 29.69113, -95.484419 29.69103, -95.484519 29.69903, -95.480419 29.70133, -95.480419 29.69833, -95.474119 29.69833, -95.474119 29.70453, -95.472719 29.71283, -95.468019 29.71293, -95.468219 29.720229, -95.464018 29.720229, -95.464118 29.724529, -95.463018 29.725929, -95.459818 29.726129, -95.459918 29.720329, -95.451418 29.720429, -95.451775 29.726303, -95.451318 29.727029, -95.447918 29.727275))" - } - } -]
\ No newline at end of file diff --git a/parts/django/django/contrib/gis/tests/geogapp/models.py b/parts/django/django/contrib/gis/tests/geogapp/models.py deleted file mode 100644 index 3696ba2..0000000 --- a/parts/django/django/contrib/gis/tests/geogapp/models.py +++ /dev/null @@ -1,20 +0,0 @@ -from django.contrib.gis.db import models - -class City(models.Model): - name = models.CharField(max_length=30) - point = models.PointField(geography=True) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class Zipcode(models.Model): - code = models.CharField(max_length=10) - poly = models.PolygonField(geography=True) - objects = models.GeoManager() - def __unicode__(self): return self.code - -class County(models.Model): - name = models.CharField(max_length=25) - state = models.CharField(max_length=20) - mpoly = models.MultiPolygonField(geography=True) - objects = models.GeoManager() - def __unicode__(self): return ' County, '.join([self.name, self.state]) diff --git a/parts/django/django/contrib/gis/tests/geogapp/tests.py b/parts/django/django/contrib/gis/tests/geogapp/tests.py deleted file mode 100644 index cb69ce9..0000000 --- a/parts/django/django/contrib/gis/tests/geogapp/tests.py +++ /dev/null @@ -1,87 +0,0 @@ -""" -Tests for geography support in PostGIS 1.5+ -""" -import os -from django.contrib.gis import gdal -from django.contrib.gis.measure import D -from django.test import TestCase -from models import City, County, Zipcode - -class GeographyTest(TestCase): - - def test01_fixture_load(self): - "Ensure geography features loaded properly." - self.assertEqual(8, City.objects.count()) - - def test02_distance_lookup(self): - "Testing GeoQuerySet distance lookup support on non-point geography fields." - z = Zipcode.objects.get(code='77002') - cities1 = list(City.objects - .filter(point__distance_lte=(z.poly, D(mi=500))) - .order_by('name') - .values_list('name', flat=True)) - cities2 = list(City.objects - .filter(point__dwithin=(z.poly, D(mi=500))) - .order_by('name') - .values_list('name', flat=True)) - for cities in [cities1, cities2]: - self.assertEqual(['Dallas', 'Houston', 'Oklahoma City'], cities) - - def test03_distance_method(self): - "Testing GeoQuerySet.distance() support on non-point geography fields." - # `GeoQuerySet.distance` is not allowed geometry fields. - htown = City.objects.get(name='Houston') - qs = Zipcode.objects.distance(htown.point) - - def test04_invalid_operators_functions(self): - "Ensuring exceptions are raised for operators & functions invalid on geography fields." - # Only a subset of the geometry functions & operator are available - # to PostGIS geography types. For more information, visit: - # http://postgis.refractions.net/documentation/manual-1.5/ch08.html#PostGIS_GeographyFunctions - z = Zipcode.objects.get(code='77002') - # ST_Within not available. - self.assertRaises(ValueError, City.objects.filter(point__within=z.poly).count) - # `@` operator not available. - self.assertRaises(ValueError, City.objects.filter(point__contained=z.poly).count) - - # Regression test for #14060, `~=` was never really implemented for PostGIS. - htown = City.objects.get(name='Houston') - self.assertRaises(ValueError, City.objects.get, point__exact=htown.point) - - def test05_geography_layermapping(self): - "Testing LayerMapping support on models with geography fields." - # There is a similar test in `layermap` that uses the same data set, - # but the County model here is a bit different. - if not gdal.HAS_GDAL: return - from django.contrib.gis.utils import LayerMapping - - # Getting the shapefile and mapping dictionary. - shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'data')) - co_shp = os.path.join(shp_path, 'counties', 'counties.shp') - co_mapping = {'name' : 'Name', - 'state' : 'State', - 'mpoly' : 'MULTIPOLYGON', - } - - # Reference county names, number of polygons, and state names. - names = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo'] - num_polys = [1, 2, 1, 19, 1] # Number of polygons for each. - st_names = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado'] - - lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269, unique='name') - lm.save(silent=True, strict=True) - - for c, name, num_poly, state in zip(County.objects.order_by('name'), names, num_polys, st_names): - self.assertEqual(4326, c.mpoly.srid) - self.assertEqual(num_poly, len(c.mpoly)) - self.assertEqual(name, c.name) - self.assertEqual(state, c.state) - - def test06_geography_area(self): - "Testing that Area calculations work on geography columns." - from django.contrib.gis.measure import A - # SELECT ST_Area(poly) FROM geogapp_zipcode WHERE code='77002'; - ref_area = 5439084.70637573 - tol = 5 - z = Zipcode.objects.area().get(code='77002') - self.assertAlmostEqual(z.area.sq_m, ref_area, tol) diff --git a/parts/django/django/contrib/gis/tests/layermap/__init__.py b/parts/django/django/contrib/gis/tests/layermap/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/layermap/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/layermap/models.py b/parts/django/django/contrib/gis/tests/layermap/models.py deleted file mode 100644 index 3a34d16..0000000 --- a/parts/django/django/contrib/gis/tests/layermap/models.py +++ /dev/null @@ -1,66 +0,0 @@ -from django.contrib.gis.db import models - -class State(models.Model): - name = models.CharField(max_length=20) - objects = models.GeoManager() - -class County(models.Model): - name = models.CharField(max_length=25) - state = models.ForeignKey(State) - mpoly = models.MultiPolygonField(srid=4269) # Multipolygon in NAD83 - objects = models.GeoManager() - -class CountyFeat(models.Model): - name = models.CharField(max_length=25) - poly = models.PolygonField(srid=4269) - objects = models.GeoManager() - -class City(models.Model): - name = models.CharField(max_length=25) - population = models.IntegerField() - density = models.DecimalField(max_digits=7, decimal_places=1) - dt = models.DateField() - point = models.PointField() - objects = models.GeoManager() - -class Interstate(models.Model): - name = models.CharField(max_length=20) - length = models.DecimalField(max_digits=6, decimal_places=2) - path = models.LineStringField() - objects = models.GeoManager() - -# Same as `City` above, but for testing model inheritance. -class CityBase(models.Model): - name = models.CharField(max_length=25) - population = models.IntegerField() - density = models.DecimalField(max_digits=7, decimal_places=1) - point = models.PointField() - objects = models.GeoManager() - -class ICity1(CityBase): - dt = models.DateField() - -class ICity2(ICity1): - dt_time = models.DateTimeField(auto_now=True) - -# Mapping dictionaries for the models above. -co_mapping = {'name' : 'Name', - 'state' : {'name' : 'State'}, # ForeignKey's use another mapping dictionary for the _related_ Model (State in this case). - 'mpoly' : 'MULTIPOLYGON', # Will convert POLYGON features into MULTIPOLYGONS. - } - -cofeat_mapping = {'name' : 'Name', - 'poly' : 'POLYGON', - } - -city_mapping = {'name' : 'Name', - 'population' : 'Population', - 'density' : 'Density', - 'dt' : 'Created', - 'point' : 'POINT', - } - -inter_mapping = {'name' : 'Name', - 'length' : 'Length', - 'path' : 'LINESTRING', - } diff --git a/parts/django/django/contrib/gis/tests/layermap/tests.py b/parts/django/django/contrib/gis/tests/layermap/tests.py deleted file mode 100644 index 6394b04..0000000 --- a/parts/django/django/contrib/gis/tests/layermap/tests.py +++ /dev/null @@ -1,268 +0,0 @@ -import os -import unittest -from decimal import Decimal - -from django.utils.copycompat import copy - -from django.contrib.gis.gdal import DataSource -from django.contrib.gis.tests.utils import mysql -from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey - -from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping - -shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data')) -city_shp = os.path.join(shp_path, 'cities', 'cities.shp') -co_shp = os.path.join(shp_path, 'counties', 'counties.shp') -inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp') - -# Dictionaries to hold what's expected in the county shapefile. -NAMES = ['Bexar', 'Galveston', 'Harris', 'Honolulu', 'Pueblo'] -NUMS = [1, 2, 1, 19, 1] # Number of polygons for each. -STATES = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado'] - -class LayerMapTest(unittest.TestCase): - - def test01_init(self): - "Testing LayerMapping initialization." - - # Model field that does not exist. - bad1 = copy(city_mapping) - bad1['foobar'] = 'FooField' - - # Shapefile field that does not exist. - bad2 = copy(city_mapping) - bad2['name'] = 'Nombre' - - # Nonexistent geographic field type. - bad3 = copy(city_mapping) - bad3['point'] = 'CURVE' - - # Incrementing through the bad mapping dictionaries and - # ensuring that a LayerMapError is raised. - for bad_map in (bad1, bad2, bad3): - try: - lm = LayerMapping(City, city_shp, bad_map) - except LayerMapError: - pass - else: - self.fail('Expected a LayerMapError.') - - # A LookupError should be thrown for bogus encodings. - try: - lm = LayerMapping(City, city_shp, city_mapping, encoding='foobar') - except LookupError: - pass - else: - self.fail('Expected a LookupError') - - def test02_simple_layermap(self): - "Test LayerMapping import of a simple point shapefile." - # Setting up for the LayerMapping. - lm = LayerMapping(City, city_shp, city_mapping) - lm.save() - - # There should be three cities in the shape file. - self.assertEqual(3, City.objects.count()) - - # Opening up the shapefile, and verifying the values in each - # of the features made it to the model. - ds = DataSource(city_shp) - layer = ds[0] - for feat in layer: - city = City.objects.get(name=feat['Name'].value) - self.assertEqual(feat['Population'].value, city.population) - self.assertEqual(Decimal(str(feat['Density'])), city.density) - self.assertEqual(feat['Created'].value, city.dt) - - # Comparing the geometries. - pnt1, pnt2 = feat.geom, city.point - self.assertAlmostEqual(pnt1.x, pnt2.x, 6) - self.assertAlmostEqual(pnt1.y, pnt2.y, 6) - - def test03_layermap_strict(self): - "Testing the `strict` keyword, and import of a LineString shapefile." - # When the `strict` keyword is set an error encountered will force - # the importation to stop. - try: - lm = LayerMapping(Interstate, inter_shp, inter_mapping) - lm.save(silent=True, strict=True) - except InvalidDecimal: - # No transactions for geoms on MySQL; delete added features. - if mysql: Interstate.objects.all().delete() - else: - self.fail('Should have failed on strict import with invalid decimal values.') - - # This LayerMapping should work b/c `strict` is not set. - lm = LayerMapping(Interstate, inter_shp, inter_mapping) - lm.save(silent=True) - - # Two interstate should have imported correctly. - self.assertEqual(2, Interstate.objects.count()) - - # Verifying the values in the layer w/the model. - ds = DataSource(inter_shp) - - # Only the first two features of this shapefile are valid. - valid_feats = ds[0][:2] - for feat in valid_feats: - istate = Interstate.objects.get(name=feat['Name'].value) - - if feat.fid == 0: - self.assertEqual(Decimal(str(feat['Length'])), istate.length) - elif feat.fid == 1: - # Everything but the first two decimal digits were truncated, - # because the Interstate model's `length` field has decimal_places=2. - self.assertAlmostEqual(feat.get('Length'), float(istate.length), 2) - - for p1, p2 in zip(feat.geom, istate.path): - self.assertAlmostEqual(p1[0], p2[0], 6) - self.assertAlmostEqual(p1[1], p2[1], 6) - - def county_helper(self, county_feat=True): - "Helper function for ensuring the integrity of the mapped County models." - for name, n, st in zip(NAMES, NUMS, STATES): - # Should only be one record b/c of `unique` keyword. - c = County.objects.get(name=name) - self.assertEqual(n, len(c.mpoly)) - self.assertEqual(st, c.state.name) # Checking ForeignKey mapping. - - # Multiple records because `unique` was not set. - if county_feat: - qs = CountyFeat.objects.filter(name=name) - self.assertEqual(n, qs.count()) - - def test04_layermap_unique_multigeometry_fk(self): - "Testing the `unique`, and `transform`, geometry collection conversion, and ForeignKey mappings." - # All the following should work. - try: - # Telling LayerMapping that we want no transformations performed on the data. - lm = LayerMapping(County, co_shp, co_mapping, transform=False) - - # Specifying the source spatial reference system via the `source_srs` keyword. - lm = LayerMapping(County, co_shp, co_mapping, source_srs=4269) - lm = LayerMapping(County, co_shp, co_mapping, source_srs='NAD83') - - # Unique may take tuple or string parameters. - for arg in ('name', ('name', 'mpoly')): - lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique=arg) - except: - self.fail('No exception should be raised for proper use of keywords.') - - # Testing invalid params for the `unique` keyword. - for e, arg in ((TypeError, 5.0), (ValueError, 'foobar'), (ValueError, ('name', 'mpolygon'))): - self.assertRaises(e, LayerMapping, County, co_shp, co_mapping, transform=False, unique=arg) - - # No source reference system defined in the shapefile, should raise an error. - if not mysql: - self.assertRaises(LayerMapError, LayerMapping, County, co_shp, co_mapping) - - # Passing in invalid ForeignKey mapping parameters -- must be a dictionary - # mapping for the model the ForeignKey points to. - bad_fk_map1 = copy(co_mapping); bad_fk_map1['state'] = 'name' - bad_fk_map2 = copy(co_mapping); bad_fk_map2['state'] = {'nombre' : 'State'} - self.assertRaises(TypeError, LayerMapping, County, co_shp, bad_fk_map1, transform=False) - self.assertRaises(LayerMapError, LayerMapping, County, co_shp, bad_fk_map2, transform=False) - - # There exist no State models for the ForeignKey mapping to work -- should raise - # a MissingForeignKey exception (this error would be ignored if the `strict` - # keyword is not set). - lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name') - self.assertRaises(MissingForeignKey, lm.save, silent=True, strict=True) - - # Now creating the state models so the ForeignKey mapping may work. - co, hi, tx = State(name='Colorado'), State(name='Hawaii'), State(name='Texas') - co.save(), hi.save(), tx.save() - - # If a mapping is specified as a collection, all OGR fields that - # are not collections will be converted into them. For example, - # a Point column would be converted to MultiPoint. Other things being done - # w/the keyword args: - # `transform=False`: Specifies that no transform is to be done; this - # has the effect of ignoring the spatial reference check (because the - # county shapefile does not have implicit spatial reference info). - # - # `unique='name'`: Creates models on the condition that they have - # unique county names; geometries from each feature however will be - # appended to the geometry collection of the unique model. Thus, - # all of the various islands in Honolulu county will be in in one - # database record with a MULTIPOLYGON type. - lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name') - lm.save(silent=True, strict=True) - - # A reference that doesn't use the unique keyword; a new database record will - # created for each polygon. - lm = LayerMapping(CountyFeat, co_shp, cofeat_mapping, transform=False) - lm.save(silent=True, strict=True) - - # The county helper is called to ensure integrity of County models. - self.county_helper() - - def test05_test_fid_range_step(self): - "Tests the `fid_range` keyword and the `step` keyword of .save()." - # Function for clearing out all the counties before testing. - def clear_counties(): County.objects.all().delete() - - # Initializing the LayerMapping object to use in these tests. - lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name') - - # Bad feature id ranges should raise a type error. - clear_counties() - bad_ranges = (5.0, 'foo', co_shp) - for bad in bad_ranges: - self.assertRaises(TypeError, lm.save, fid_range=bad) - - # Step keyword should not be allowed w/`fid_range`. - fr = (3, 5) # layer[3:5] - self.assertRaises(LayerMapError, lm.save, fid_range=fr, step=10) - lm.save(fid_range=fr) - - # Features IDs 3 & 4 are for Galveston County, Texas -- only - # one model is returned because the `unique` keyword was set. - qs = County.objects.all() - self.assertEqual(1, qs.count()) - self.assertEqual('Galveston', qs[0].name) - - # Features IDs 5 and beyond for Honolulu County, Hawaii, and - # FID 0 is for Pueblo County, Colorado. - clear_counties() - lm.save(fid_range=slice(5, None), silent=True, strict=True) # layer[5:] - lm.save(fid_range=slice(None, 1), silent=True, strict=True) # layer[:1] - - # Only Pueblo & Honolulu counties should be present because of - # the `unique` keyword. Have to set `order_by` on this QuerySet - # or else MySQL will return a different ordering than the other dbs. - qs = County.objects.order_by('name') - self.assertEqual(2, qs.count()) - hi, co = tuple(qs) - hi_idx, co_idx = tuple(map(NAMES.index, ('Honolulu', 'Pueblo'))) - self.assertEqual('Pueblo', co.name); self.assertEqual(NUMS[co_idx], len(co.mpoly)) - self.assertEqual('Honolulu', hi.name); self.assertEqual(NUMS[hi_idx], len(hi.mpoly)) - - # Testing the `step` keyword -- should get the same counties - # regardless of we use a step that divides equally, that is odd, - # or that is larger than the dataset. - for st in (4,7,1000): - clear_counties() - lm.save(step=st, strict=True) - self.county_helper(county_feat=False) - - def test06_model_inheritance(self): - "Tests LayerMapping on inherited models. See #12093." - icity_mapping = {'name' : 'Name', - 'population' : 'Population', - 'density' : 'Density', - 'point' : 'POINT', - 'dt' : 'Created', - } - - # Parent model has geometry field. - lm1 = LayerMapping(ICity1, city_shp, icity_mapping) - lm1.save() - - # Grandparent has geometry field. - lm2 = LayerMapping(ICity2, city_shp, icity_mapping) - lm2.save() - - self.assertEqual(6, ICity1.objects.count()) - self.assertEqual(3, ICity2.objects.count()) - diff --git a/parts/django/django/contrib/gis/tests/relatedapp/__init__.py b/parts/django/django/contrib/gis/tests/relatedapp/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/parts/django/django/contrib/gis/tests/relatedapp/__init__.py +++ /dev/null diff --git a/parts/django/django/contrib/gis/tests/relatedapp/models.py b/parts/django/django/contrib/gis/tests/relatedapp/models.py deleted file mode 100644 index 2e9a62b..0000000 --- a/parts/django/django/contrib/gis/tests/relatedapp/models.py +++ /dev/null @@ -1,49 +0,0 @@ -from django.contrib.gis.db import models -from django.contrib.localflavor.us.models import USStateField - -class Location(models.Model): - point = models.PointField() - objects = models.GeoManager() - def __unicode__(self): return self.point.wkt - -class City(models.Model): - name = models.CharField(max_length=50) - state = USStateField() - location = models.ForeignKey(Location) - objects = models.GeoManager() - def __unicode__(self): return self.name - -class AugmentedLocation(Location): - extra_text = models.TextField(blank=True) - objects = models.GeoManager() - -class DirectoryEntry(models.Model): - listing_text = models.CharField(max_length=50) - location = models.ForeignKey(AugmentedLocation) - objects = models.GeoManager() - -class Parcel(models.Model): - name = models.CharField(max_length=30) - city = models.ForeignKey(City) - center1 = models.PointField() - # Throwing a curveball w/`db_column` here. - center2 = models.PointField(srid=2276, db_column='mycenter') - border1 = models.PolygonField() - border2 = models.PolygonField(srid=2276) - objects = models.GeoManager() - def __unicode__(self): return self.name - -# These use the GeoManager but do not have any geographic fields. -class Author(models.Model): - name = models.CharField(max_length=100) - objects = models.GeoManager() - -class Article(models.Model): - title = models.CharField(max_length=100) - author = models.ForeignKey(Author, unique=True) - objects = models.GeoManager() - -class Book(models.Model): - title = models.CharField(max_length=100) - author = models.ForeignKey(Author, related_name='books', null=True) - objects = models.GeoManager() diff --git a/parts/django/django/contrib/gis/tests/relatedapp/tests.py b/parts/django/django/contrib/gis/tests/relatedapp/tests.py deleted file mode 100644 index c8aeb28..0000000 --- a/parts/django/django/contrib/gis/tests/relatedapp/tests.py +++ /dev/null @@ -1,284 +0,0 @@ -from django.test import TestCase - -from django.contrib.gis.geos import GEOSGeometry, Point, MultiPoint -from django.contrib.gis.db.models import Collect, Count, Extent, F, Union -from django.contrib.gis.geometry.backend import Geometry -from django.contrib.gis.tests.utils import mysql, oracle, no_mysql, no_oracle, no_spatialite - -from models import City, Location, DirectoryEntry, Parcel, Book, Author, Article - -class RelatedGeoModelTest(TestCase): - - def test02_select_related(self): - "Testing `select_related` on geographic models (see #7126)." - qs1 = City.objects.all() - qs2 = City.objects.select_related() - qs3 = City.objects.select_related('location') - - # Reference data for what's in the fixtures. - cities = ( - ('Aurora', 'TX', -97.516111, 33.058333), - ('Roswell', 'NM', -104.528056, 33.387222), - ('Kecksburg', 'PA', -79.460734, 40.18476), - ) - - for qs in (qs1, qs2, qs3): - for ref, c in zip(cities, qs): - nm, st, lon, lat = ref - self.assertEqual(nm, c.name) - self.assertEqual(st, c.state) - self.assertEqual(Point(lon, lat), c.location.point) - - @no_mysql - def test03_transform_related(self): - "Testing the `transform` GeoQuerySet method on related geographic models." - # All the transformations are to state plane coordinate systems using - # US Survey Feet (thus a tolerance of 0 implies error w/in 1 survey foot). - tol = 0 - - def check_pnt(ref, pnt): - self.assertAlmostEqual(ref.x, pnt.x, tol) - self.assertAlmostEqual(ref.y, pnt.y, tol) - self.assertEqual(ref.srid, pnt.srid) - - # Each city transformed to the SRID of their state plane coordinate system. - transformed = (('Kecksburg', 2272, 'POINT(1490553.98959621 314792.131023984)'), - ('Roswell', 2257, 'POINT(481902.189077221 868477.766629735)'), - ('Aurora', 2276, 'POINT(2269923.2484839 7069381.28722222)'), - ) - - for name, srid, wkt in transformed: - # Doing this implicitly sets `select_related` select the location. - # TODO: Fix why this breaks on Oracle. - qs = list(City.objects.filter(name=name).transform(srid, field_name='location__point')) - check_pnt(GEOSGeometry(wkt, srid), qs[0].location.point) - - @no_mysql - @no_spatialite - def test04a_related_extent_aggregate(self): - "Testing the `extent` GeoQuerySet aggregates on related geographic models." - # This combines the Extent and Union aggregates into one query - aggs = City.objects.aggregate(Extent('location__point')) - - # One for all locations, one that excludes New Mexico (Roswell). - all_extent = (-104.528056, 29.763374, -79.460734, 40.18476) - txpa_extent = (-97.516111, 29.763374, -79.460734, 40.18476) - e1 = City.objects.extent(field_name='location__point') - e2 = City.objects.exclude(state='NM').extent(field_name='location__point') - e3 = aggs['location__point__extent'] - - # The tolerance value is to four decimal places because of differences - # between the Oracle and PostGIS spatial backends on the extent calculation. - tol = 4 - for ref, e in [(all_extent, e1), (txpa_extent, e2), (all_extent, e3)]: - for ref_val, e_val in zip(ref, e): self.assertAlmostEqual(ref_val, e_val, tol) - - @no_mysql - def test04b_related_union_aggregate(self): - "Testing the `unionagg` GeoQuerySet aggregates on related geographic models." - # This combines the Extent and Union aggregates into one query - aggs = City.objects.aggregate(Union('location__point')) - - # These are the points that are components of the aggregate geographic - # union that is returned. Each point # corresponds to City PK. - p1 = Point(-104.528056, 33.387222) - p2 = Point(-97.516111, 33.058333) - p3 = Point(-79.460734, 40.18476) - p4 = Point(-96.801611, 32.782057) - p5 = Point(-95.363151, 29.763374) - - # Creating the reference union geometry depending on the spatial backend, - # as Oracle will have a different internal ordering of the component - # geometries than PostGIS. The second union aggregate is for a union - # query that includes limiting information in the WHERE clause (in other - # words a `.filter()` precedes the call to `.unionagg()`). - if oracle: - ref_u1 = MultiPoint(p4, p5, p3, p1, p2, srid=4326) - ref_u2 = MultiPoint(p3, p2, srid=4326) - else: - # Looks like PostGIS points by longitude value. - ref_u1 = MultiPoint(p1, p2, p4, p5, p3, srid=4326) - ref_u2 = MultiPoint(p2, p3, srid=4326) - - u1 = City.objects.unionagg(field_name='location__point') - u2 = City.objects.exclude(name__in=('Roswell', 'Houston', 'Dallas', 'Fort Worth')).unionagg(field_name='location__point') - u3 = aggs['location__point__union'] - - self.assertEqual(ref_u1, u1) - self.assertEqual(ref_u2, u2) - self.assertEqual(ref_u1, u3) - - def test05_select_related_fk_to_subclass(self): - "Testing that calling select_related on a query over a model with an FK to a model subclass works" - # Regression test for #9752. - l = list(DirectoryEntry.objects.all().select_related()) - - def test06_f_expressions(self): - "Testing F() expressions on GeometryFields." - # Constructing a dummy parcel border and getting the City instance for - # assigning the FK. - b1 = GEOSGeometry('POLYGON((-97.501205 33.052520,-97.501205 33.052576,-97.501150 33.052576,-97.501150 33.052520,-97.501205 33.052520))', srid=4326) - pcity = City.objects.get(name='Aurora') - - # First parcel has incorrect center point that is equal to the City; - # it also has a second border that is different from the first as a - # 100ft buffer around the City. - c1 = pcity.location.point - c2 = c1.transform(2276, clone=True) - b2 = c2.buffer(100) - p1 = Parcel.objects.create(name='P1', city=pcity, center1=c1, center2=c2, border1=b1, border2=b2) - - # Now creating a second Parcel where the borders are the same, just - # in different coordinate systems. The center points are also the - # the same (but in different coordinate systems), and this time they - # actually correspond to the centroid of the border. - c1 = b1.centroid - c2 = c1.transform(2276, clone=True) - p2 = Parcel.objects.create(name='P2', city=pcity, center1=c1, center2=c2, border1=b1, border2=b1) - - # Should return the second Parcel, which has the center within the - # border. - qs = Parcel.objects.filter(center1__within=F('border1')) - self.assertEqual(1, len(qs)) - self.assertEqual('P2', qs[0].name) - - if not mysql: - # This time center2 is in a different coordinate system and needs - # to be wrapped in transformation SQL. - qs = Parcel.objects.filter(center2__within=F('border1')) - self.assertEqual(1, len(qs)) - self.assertEqual('P2', qs[0].name) - - # Should return the first Parcel, which has the center point equal - # to the point in the City ForeignKey. - qs = Parcel.objects.filter(center1=F('city__location__point')) - self.assertEqual(1, len(qs)) - self.assertEqual('P1', qs[0].name) - - if not mysql: - # This time the city column should be wrapped in transformation SQL. - qs = Parcel.objects.filter(border2__contains=F('city__location__point')) - self.assertEqual(1, len(qs)) - self.assertEqual('P1', qs[0].name) - - def test07_values(self): - "Testing values() and values_list() and GeoQuerySets." - # GeoQuerySet and GeoValuesQuerySet, and GeoValuesListQuerySet respectively. - gqs = Location.objects.all() - gvqs = Location.objects.values() - gvlqs = Location.objects.values_list() - - # Incrementing through each of the models, dictionaries, and tuples - # returned by the different types of GeoQuerySets. - for m, d, t in zip(gqs, gvqs, gvlqs): - # The values should be Geometry objects and not raw strings returned - # by the spatial database. - self.failUnless(isinstance(d['point'], Geometry)) - self.failUnless(isinstance(t[1], Geometry)) - self.assertEqual(m.point, d['point']) - self.assertEqual(m.point, t[1]) - - def test08_defer_only(self): - "Testing defer() and only() on Geographic models." - qs = Location.objects.all() - def_qs = Location.objects.defer('point') - for loc, def_loc in zip(qs, def_qs): - self.assertEqual(loc.point, def_loc.point) - - def test09_pk_relations(self): - "Ensuring correct primary key column is selected across relations. See #10757." - # The expected ID values -- notice the last two location IDs - # are out of order. Dallas and Houston have location IDs that differ - # from their PKs -- this is done to ensure that the related location - # ID column is selected instead of ID column for the city. - city_ids = (1, 2, 3, 4, 5) - loc_ids = (1, 2, 3, 5, 4) - ids_qs = City.objects.order_by('id').values('id', 'location__id') - for val_dict, c_id, l_id in zip(ids_qs, city_ids, loc_ids): - self.assertEqual(val_dict['id'], c_id) - self.assertEqual(val_dict['location__id'], l_id) - - def test10_combine(self): - "Testing the combination of two GeoQuerySets. See #10807." - buf1 = City.objects.get(name='Aurora').location.point.buffer(0.1) - buf2 = City.objects.get(name='Kecksburg').location.point.buffer(0.1) - qs1 = City.objects.filter(location__point__within=buf1) - qs2 = City.objects.filter(location__point__within=buf2) - combined = qs1 | qs2 - names = [c.name for c in combined] - self.assertEqual(2, len(names)) - self.failUnless('Aurora' in names) - self.failUnless('Kecksburg' in names) - - def test11_geoquery_pickle(self): - "Ensuring GeoQuery objects are unpickled correctly. See #10839." - import pickle - from django.contrib.gis.db.models.sql import GeoQuery - qs = City.objects.all() - q_str = pickle.dumps(qs.query) - q = pickle.loads(q_str) - self.assertEqual(GeoQuery, q.__class__) - - # TODO: fix on Oracle -- get the following error because the SQL is ordered - # by a geometry object, which Oracle apparently doesn't like: - # ORA-22901: cannot compare nested table or VARRAY or LOB attributes of an object type - @no_oracle - def test12a_count(self): - "Testing `Count` aggregate use with the `GeoManager` on geo-fields." - # The City, 'Fort Worth' uses the same location as Dallas. - dallas = City.objects.get(name='Dallas') - - # Count annotation should be 2 for the Dallas location now. - loc = Location.objects.annotate(num_cities=Count('city')).get(id=dallas.location.id) - self.assertEqual(2, loc.num_cities) - - def test12b_count(self): - "Testing `Count` aggregate use with the `GeoManager` on non geo-fields. See #11087." - # Should only be one author (Trevor Paglen) returned by this query, and - # the annotation should have 3 for the number of books, see #11087. - # Also testing with a `GeoValuesQuerySet`, see #11489. - qs = Author.objects.annotate(num_books=Count('books')).filter(num_books__gt=1) - vqs = Author.objects.values('name').annotate(num_books=Count('books')).filter(num_books__gt=1) - self.assertEqual(1, len(qs)) - self.assertEqual(3, qs[0].num_books) - self.assertEqual(1, len(vqs)) - self.assertEqual(3, vqs[0]['num_books']) - - # TODO: The phantom model does appear on Oracle. - @no_oracle - def test13_select_related_null_fk(self): - "Testing `select_related` on a nullable ForeignKey via `GeoManager`. See #11381." - no_author = Book.objects.create(title='Without Author') - b = Book.objects.select_related('author').get(title='Without Author') - # Should be `None`, and not a 'dummy' model. - self.assertEqual(None, b.author) - - @no_mysql - @no_oracle - @no_spatialite - def test14_collect(self): - "Testing the `collect` GeoQuerySet method and `Collect` aggregate." - # Reference query: - # SELECT AsText(ST_Collect("relatedapp_location"."point")) FROM "relatedapp_city" LEFT OUTER JOIN - # "relatedapp_location" ON ("relatedapp_city"."location_id" = "relatedapp_location"."id") - # WHERE "relatedapp_city"."state" = 'TX'; - ref_geom = GEOSGeometry('MULTIPOINT(-97.516111 33.058333,-96.801611 32.782057,-95.363151 29.763374,-96.801611 32.782057)') - - c1 = City.objects.filter(state='TX').collect(field_name='location__point') - c2 = City.objects.filter(state='TX').aggregate(Collect('location__point'))['location__point__collect'] - - for coll in (c1, c2): - # Even though Dallas and Ft. Worth share same point, Collect doesn't - # consolidate -- that's why 4 points in MultiPoint. - self.assertEqual(4, len(coll)) - self.assertEqual(ref_geom, coll) - - def test15_invalid_select_related(self): - "Testing doing select_related on the related name manager of a unique FK. See #13934." - qs = Article.objects.select_related('author__article') - # This triggers TypeError when `get_default_columns` has no `local_only` - # keyword. The TypeError is swallowed if QuerySet is actually - # evaluated as list generation swallows TypeError in CPython. - sql = str(qs.query) - - # TODO: Related tests for KML, GML, and distance lookups. diff --git a/parts/django/django/contrib/gis/tests/test_geoforms.py b/parts/django/django/contrib/gis/tests/test_geoforms.py deleted file mode 100644 index aa6b25e..0000000 --- a/parts/django/django/contrib/gis/tests/test_geoforms.py +++ /dev/null @@ -1,65 +0,0 @@ -import unittest - -from django.forms import ValidationError -from django.contrib.gis import forms -from django.contrib.gis.geos import GEOSGeometry - -class GeometryFieldTest(unittest.TestCase): - - def test00_init(self): - "Testing GeometryField initialization with defaults." - fld = forms.GeometryField() - for bad_default in ('blah', 3, 'FoO', None, 0): - self.assertRaises(ValidationError, fld.clean, bad_default) - - def test01_srid(self): - "Testing GeometryField with a SRID set." - # Input that doesn't specify the SRID is assumed to be in the SRID - # of the input field. - fld = forms.GeometryField(srid=4326) - geom = fld.clean('POINT(5 23)') - self.assertEqual(4326, geom.srid) - # Making the field in a different SRID from that of the geometry, and - # asserting it transforms. - fld = forms.GeometryField(srid=32140) - tol = 0.0000001 - xform_geom = GEOSGeometry('POINT (951640.547328465 4219369.26171664)', srid=32140) - # The cleaned geometry should be transformed to 32140. - cleaned_geom = fld.clean('SRID=4326;POINT (-95.363151 29.763374)') - self.failUnless(xform_geom.equals_exact(cleaned_geom, tol)) - - def test02_null(self): - "Testing GeometryField's handling of null (None) geometries." - # Form fields, by default, are required (`required=True`) - fld = forms.GeometryField() - self.assertRaises(forms.ValidationError, fld.clean, None) - - # Still not allowed if `null=False`. - fld = forms.GeometryField(required=False, null=False) - self.assertRaises(forms.ValidationError, fld.clean, None) - - # This will clean None as a geometry (See #10660). - fld = forms.GeometryField(required=False) - self.assertEqual(None, fld.clean(None)) - - def test03_geom_type(self): - "Testing GeometryField's handling of different geometry types." - # By default, all geometry types are allowed. - fld = forms.GeometryField() - for wkt in ('POINT(5 23)', 'MULTIPOLYGON(((0 0, 0 1, 1 1, 1 0, 0 0)))', 'LINESTRING(0 0, 1 1)'): - self.assertEqual(GEOSGeometry(wkt), fld.clean(wkt)) - - pnt_fld = forms.GeometryField(geom_type='POINT') - self.assertEqual(GEOSGeometry('POINT(5 23)'), pnt_fld.clean('POINT(5 23)')) - self.assertRaises(forms.ValidationError, pnt_fld.clean, 'LINESTRING(0 0, 1 1)') - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(GeometryFieldTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) - -if __name__=="__main__": - run() diff --git a/parts/django/django/contrib/gis/tests/test_geoip.py b/parts/django/django/contrib/gis/tests/test_geoip.py deleted file mode 100644 index a9ab6a6..0000000 --- a/parts/django/django/contrib/gis/tests/test_geoip.py +++ /dev/null @@ -1,103 +0,0 @@ -import os, unittest -from django.db import settings -from django.contrib.gis.geos import GEOSGeometry -from django.contrib.gis.utils import GeoIP, GeoIPException - -# Note: Requires use of both the GeoIP country and city datasets. -# The GEOIP_DATA path should be the only setting set (the directory -# should contain links or the actual database files 'GeoIP.dat' and -# 'GeoLiteCity.dat'. -class GeoIPTest(unittest.TestCase): - - def test01_init(self): - "Testing GeoIP initialization." - g1 = GeoIP() # Everything inferred from GeoIP path - path = settings.GEOIP_PATH - g2 = GeoIP(path, 0) # Passing in data path explicitly. - g3 = GeoIP.open(path, 0) # MaxMind Python API syntax. - - for g in (g1, g2, g3): - self.assertEqual(True, bool(g._country)) - self.assertEqual(True, bool(g._city)) - - # Only passing in the location of one database. - city = os.path.join(path, 'GeoLiteCity.dat') - cntry = os.path.join(path, 'GeoIP.dat') - g4 = GeoIP(city, country='') - self.assertEqual(None, g4._country) - g5 = GeoIP(cntry, city='') - self.assertEqual(None, g5._city) - - # Improper parameters. - bad_params = (23, 'foo', 15.23) - for bad in bad_params: - self.assertRaises(GeoIPException, GeoIP, cache=bad) - if isinstance(bad, basestring): - e = GeoIPException - else: - e = TypeError - self.assertRaises(e, GeoIP, bad, 0) - - def test02_bad_query(self): - "Testing GeoIP query parameter checking." - cntry_g = GeoIP(city='<foo>') - # No city database available, these calls should fail. - self.assertRaises(GeoIPException, cntry_g.city, 'google.com') - self.assertRaises(GeoIPException, cntry_g.coords, 'yahoo.com') - - # Non-string query should raise TypeError - self.assertRaises(TypeError, cntry_g.country_code, 17) - self.assertRaises(TypeError, cntry_g.country_name, GeoIP) - - def test03_country(self): - "Testing GeoIP country querying methods." - g = GeoIP(city='<foo>') - - fqdn = 'www.google.com' - addr = '12.215.42.19' - - for query in (fqdn, addr): - for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name): - self.assertEqual('US', func(query)) - for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name): - self.assertEqual('United States', func(query)) - self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'}, - g.country(query)) - - def test04_city(self): - "Testing GeoIP city querying methods." - g = GeoIP(country='<foo>') - - addr = '130.80.29.3' - fqdn = 'chron.com' - for query in (fqdn, addr): - # Country queries should still work. - for func in (g.country_code, g.country_code_by_addr, g.country_code_by_name): - self.assertEqual('US', func(query)) - for func in (g.country_name, g.country_name_by_addr, g.country_name_by_name): - self.assertEqual('United States', func(query)) - self.assertEqual({'country_code' : 'US', 'country_name' : 'United States'}, - g.country(query)) - - # City information dictionary. - d = g.city(query) - self.assertEqual('USA', d['country_code3']) - self.assertEqual('Houston', d['city']) - self.assertEqual('TX', d['region']) - self.assertEqual(713, d['area_code']) - geom = g.geos(query) - self.failIf(not isinstance(geom, GEOSGeometry)) - lon, lat = (-95.3670, 29.7523) - lat_lon = g.lat_lon(query) - lat_lon = (lat_lon[1], lat_lon[0]) - for tup in (geom.tuple, g.coords(query), g.lon_lat(query), lat_lon): - self.assertAlmostEqual(lon, tup[0], 4) - self.assertAlmostEqual(lat, tup[1], 4) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(GeoIPTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/tests/test_measure.py b/parts/django/django/contrib/gis/tests/test_measure.py deleted file mode 100644 index 28d5048..0000000 --- a/parts/django/django/contrib/gis/tests/test_measure.py +++ /dev/null @@ -1,336 +0,0 @@ -""" -Distance and Area objects to allow for sensible and convienient calculation -and conversions. Here are some tests. -""" - -import unittest -from django.contrib.gis.measure import Distance, Area, D, A - -class DistanceTest(unittest.TestCase): - "Testing the Distance object" - - def testInit(self): - "Testing initialisation from valid units" - d = Distance(m=100) - self.assertEqual(d.m, 100) - - d1, d2, d3 = D(m=100), D(meter=100), D(metre=100) - for d in (d1, d2, d3): - self.assertEqual(d.m, 100) - - d = D(nm=100) - self.assertEqual(d.m, 185200) - - y1, y2, y3 = D(yd=100), D(yard=100), D(Yard=100) - for d in (y1, y2, y3): - self.assertEqual(d.yd, 100) - - mm1, mm2 = D(millimeter=1000), D(MiLLiMeTeR=1000) - for d in (mm1, mm2): - self.assertEqual(d.m, 1.0) - self.assertEqual(d.mm, 1000.0) - - - def testInitInvalid(self): - "Testing initialisation from invalid units" - self.assertRaises(AttributeError, D, banana=100) - - def testAccess(self): - "Testing access in different units" - d = D(m=100) - self.assertEqual(d.km, 0.1) - self.assertAlmostEqual(d.ft, 328.084, 3) - - def testAccessInvalid(self): - "Testing access in invalid units" - d = D(m=100) - self.failIf(hasattr(d, 'banana')) - - def testAddition(self): - "Test addition & subtraction" - d1 = D(m=100) - d2 = D(m=200) - - d3 = d1 + d2 - self.assertEqual(d3.m, 300) - d3 += d1 - self.assertEqual(d3.m, 400) - - d4 = d1 - d2 - self.assertEqual(d4.m, -100) - d4 -= d1 - self.assertEqual(d4.m, -200) - - try: - d5 = d1 + 1 - except TypeError, e: - pass - else: - self.fail('Distance + number should raise TypeError') - - try: - d5 = d1 - 1 - except TypeError, e: - pass - else: - self.fail('Distance - number should raise TypeError') - - try: - d1 += 1 - except TypeError, e: - pass - else: - self.fail('Distance += number should raise TypeError') - - try: - d1 -= 1 - except TypeError, e: - pass - else: - self.fail('Distance -= number should raise TypeError') - - def testMultiplication(self): - "Test multiplication & division" - d1 = D(m=100) - - d3 = d1 * 2 - self.assertEqual(d3.m, 200) - d3 = 2 * d1 - self.assertEqual(d3.m, 200) - d3 *= 5 - self.assertEqual(d3.m, 1000) - - d4 = d1 / 2 - self.assertEqual(d4.m, 50) - d4 /= 5 - self.assertEqual(d4.m, 10) - - a5 = d1 * D(m=10) - self.assert_(isinstance(a5, Area)) - self.assertEqual(a5.sq_m, 100*10) - - try: - d1 *= D(m=1) - except TypeError, e: - pass - else: - self.fail('Distance *= Distance should raise TypeError') - - try: - d5 = d1 / D(m=1) - except TypeError, e: - pass - else: - self.fail('Distance / Distance should raise TypeError') - - try: - d1 /= D(m=1) - except TypeError, e: - pass - else: - self.fail('Distance /= Distance should raise TypeError') - - def testUnitConversions(self): - "Testing default units during maths" - d1 = D(m=100) - d2 = D(km=1) - - d3 = d1 + d2 - self.assertEqual(d3._default_unit, 'm') - d4 = d2 + d1 - self.assertEqual(d4._default_unit, 'km') - d5 = d1 * 2 - self.assertEqual(d5._default_unit, 'm') - d6 = d1 / 2 - self.assertEqual(d6._default_unit, 'm') - - def testComparisons(self): - "Testing comparisons" - d1 = D(m=100) - d2 = D(km=1) - d3 = D(km=0) - - self.assert_(d2 > d1) - self.assert_(d1 == d1) - self.assert_(d1 < d2) - self.failIf(d3) - - def testUnitsStr(self): - "Testing conversion to strings" - d1 = D(m=100) - d2 = D(km=3.5) - - self.assertEqual(str(d1), '100.0 m') - self.assertEqual(str(d2), '3.5 km') - self.assertEqual(repr(d1), 'Distance(m=100.0)') - self.assertEqual(repr(d2), 'Distance(km=3.5)') - - def testUnitAttName(self): - "Testing the `unit_attname` class method" - unit_tuple = [('Yard', 'yd'), ('Nautical Mile', 'nm'), ('German legal metre', 'german_m'), - ('Indian yard', 'indian_yd'), ('Chain (Sears)', 'chain_sears'), ('Chain', 'chain')] - for nm, att in unit_tuple: - self.assertEqual(att, D.unit_attname(nm)) - -class AreaTest(unittest.TestCase): - "Testing the Area object" - - def testInit(self): - "Testing initialisation from valid units" - a = Area(sq_m=100) - self.assertEqual(a.sq_m, 100) - - a = A(sq_m=100) - self.assertEqual(a.sq_m, 100) - - a = A(sq_mi=100) - self.assertEqual(a.sq_m, 258998811.0336) - - def testInitInvaliA(self): - "Testing initialisation from invalid units" - self.assertRaises(AttributeError, A, banana=100) - - def testAccess(self): - "Testing access in different units" - a = A(sq_m=100) - self.assertEqual(a.sq_km, 0.0001) - self.assertAlmostEqual(a.sq_ft, 1076.391, 3) - - def testAccessInvaliA(self): - "Testing access in invalid units" - a = A(sq_m=100) - self.failIf(hasattr(a, 'banana')) - - def testAddition(self): - "Test addition & subtraction" - a1 = A(sq_m=100) - a2 = A(sq_m=200) - - a3 = a1 + a2 - self.assertEqual(a3.sq_m, 300) - a3 += a1 - self.assertEqual(a3.sq_m, 400) - - a4 = a1 - a2 - self.assertEqual(a4.sq_m, -100) - a4 -= a1 - self.assertEqual(a4.sq_m, -200) - - try: - a5 = a1 + 1 - except TypeError, e: - pass - else: - self.fail('Area + number should raise TypeError') - - try: - a5 = a1 - 1 - except TypeError, e: - pass - else: - self.fail('Area - number should raise TypeError') - - try: - a1 += 1 - except TypeError, e: - pass - else: - self.fail('Area += number should raise TypeError') - - try: - a1 -= 1 - except TypeError, e: - pass - else: - self.fail('Area -= number should raise TypeError') - - def testMultiplication(self): - "Test multiplication & division" - a1 = A(sq_m=100) - - a3 = a1 * 2 - self.assertEqual(a3.sq_m, 200) - a3 = 2 * a1 - self.assertEqual(a3.sq_m, 200) - a3 *= 5 - self.assertEqual(a3.sq_m, 1000) - - a4 = a1 / 2 - self.assertEqual(a4.sq_m, 50) - a4 /= 5 - self.assertEqual(a4.sq_m, 10) - - try: - a5 = a1 * A(sq_m=1) - except TypeError, e: - pass - else: - self.fail('Area * Area should raise TypeError') - - try: - a1 *= A(sq_m=1) - except TypeError, e: - pass - else: - self.fail('Area *= Area should raise TypeError') - - try: - a5 = a1 / A(sq_m=1) - except TypeError, e: - pass - else: - self.fail('Area / Area should raise TypeError') - - try: - a1 /= A(sq_m=1) - except TypeError, e: - pass - else: - self.fail('Area /= Area should raise TypeError') - - def testUnitConversions(self): - "Testing default units during maths" - a1 = A(sq_m=100) - a2 = A(sq_km=1) - - a3 = a1 + a2 - self.assertEqual(a3._default_unit, 'sq_m') - a4 = a2 + a1 - self.assertEqual(a4._default_unit, 'sq_km') - a5 = a1 * 2 - self.assertEqual(a5._default_unit, 'sq_m') - a6 = a1 / 2 - self.assertEqual(a6._default_unit, 'sq_m') - - def testComparisons(self): - "Testing comparisons" - a1 = A(sq_m=100) - a2 = A(sq_km=1) - a3 = A(sq_km=0) - - self.assert_(a2 > a1) - self.assert_(a1 == a1) - self.assert_(a1 < a2) - self.failIf(a3) - - def testUnitsStr(self): - "Testing conversion to strings" - a1 = A(sq_m=100) - a2 = A(sq_km=3.5) - - self.assertEqual(str(a1), '100.0 sq_m') - self.assertEqual(str(a2), '3.5 sq_km') - self.assertEqual(repr(a1), 'Area(sq_m=100.0)') - self.assertEqual(repr(a2), 'Area(sq_km=3.5)') - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(DistanceTest)) - s.addTest(unittest.makeSuite(AreaTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) - -if __name__=="__main__": - run() diff --git a/parts/django/django/contrib/gis/tests/test_spatialrefsys.py b/parts/django/django/contrib/gis/tests/test_spatialrefsys.py deleted file mode 100644 index a9fcbff..0000000 --- a/parts/django/django/contrib/gis/tests/test_spatialrefsys.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest - -from django.db import connection -from django.contrib.gis.tests.utils import mysql, no_mysql, oracle, postgis, spatialite - -test_srs = ({'srid' : 4326, - 'auth_name' : ('EPSG', True), - 'auth_srid' : 4326, - 'srtext' : 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', - 'srtext14' : 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', - 'proj4' : '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ', - 'spheroid' : 'WGS 84', 'name' : 'WGS 84', - 'geographic' : True, 'projected' : False, 'spatialite' : True, - 'ellipsoid' : (6378137.0, 6356752.3, 298.257223563), # From proj's "cs2cs -le" and Wikipedia (semi-minor only) - 'eprec' : (1, 1, 9), - }, - {'srid' : 32140, - 'auth_name' : ('EPSG', False), - 'auth_srid' : 32140, - 'srtext' : 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",30.28333333333333],PARAMETER["standard_parallel_2",28.38333333333333],PARAMETER["latitude_of_origin",27.83333333333333],PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],PARAMETER["false_northing",4000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","32140"]]', - 'srtext14': 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",30.28333333333333],PARAMETER["standard_parallel_2",28.38333333333333],PARAMETER["latitude_of_origin",27.83333333333333],PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],PARAMETER["false_northing",4000000],AUTHORITY["EPSG","32140"],AXIS["X",EAST],AXIS["Y",NORTH]]', - 'proj4' : '+proj=lcc +lat_1=30.28333333333333 +lat_2=28.38333333333333 +lat_0=27.83333333333333 +lon_0=-99 +x_0=600000 +y_0=4000000 +ellps=GRS80 +datum=NAD83 +units=m +no_defs ', - 'spheroid' : 'GRS 1980', 'name' : 'NAD83 / Texas South Central', - 'geographic' : False, 'projected' : True, 'spatialite' : False, - 'ellipsoid' : (6378137.0, 6356752.31414, 298.257222101), # From proj's "cs2cs -le" and Wikipedia (semi-minor only) - 'eprec' : (1, 5, 10), - }, - ) - -if oracle: - from django.contrib.gis.db.backends.oracle.models import SpatialRefSys -elif postgis: - from django.contrib.gis.db.backends.postgis.models import SpatialRefSys -elif spatialite: - from django.contrib.gis.db.backends.spatialite.models import SpatialRefSys - -class SpatialRefSysTest(unittest.TestCase): - - @no_mysql - def test01_retrieve(self): - "Testing retrieval of SpatialRefSys model objects." - for sd in test_srs: - srs = SpatialRefSys.objects.get(srid=sd['srid']) - self.assertEqual(sd['srid'], srs.srid) - - # Some of the authority names are borked on Oracle, e.g., SRID=32140. - # also, Oracle Spatial seems to add extraneous info to fields, hence the - # the testing with the 'startswith' flag. - auth_name, oracle_flag = sd['auth_name'] - if postgis or (oracle and oracle_flag): - self.assertEqual(True, srs.auth_name.startswith(auth_name)) - - self.assertEqual(sd['auth_srid'], srs.auth_srid) - - # No proj.4 and different srtext on oracle backends :( - if postgis: - if connection.ops.spatial_version >= (1, 4, 0): - srtext = sd['srtext14'] - else: - srtext = sd['srtext'] - self.assertEqual(srtext, srs.wkt) - self.assertEqual(sd['proj4'], srs.proj4text) - - @no_mysql - def test02_osr(self): - "Testing getting OSR objects from SpatialRefSys model objects." - for sd in test_srs: - sr = SpatialRefSys.objects.get(srid=sd['srid']) - self.assertEqual(True, sr.spheroid.startswith(sd['spheroid'])) - self.assertEqual(sd['geographic'], sr.geographic) - self.assertEqual(sd['projected'], sr.projected) - - if not (spatialite and not sd['spatialite']): - # Can't get 'NAD83 / Texas South Central' from PROJ.4 string - # on SpatiaLite - self.assertEqual(True, sr.name.startswith(sd['name'])) - - # Testing the SpatialReference object directly. - if postgis or spatialite: - srs = sr.srs - self.assertEqual(sd['proj4'], srs.proj4) - # No `srtext` field in the `spatial_ref_sys` table in SpatiaLite - if not spatialite: - if connection.ops.spatial_version >= (1, 4, 0): - srtext = sd['srtext14'] - else: - srtext = sd['srtext'] - self.assertEqual(srtext, srs.wkt) - - @no_mysql - def test03_ellipsoid(self): - "Testing the ellipsoid property." - for sd in test_srs: - # Getting the ellipsoid and precision parameters. - ellps1 = sd['ellipsoid'] - prec = sd['eprec'] - - # Getting our spatial reference and its ellipsoid - srs = SpatialRefSys.objects.get(srid=sd['srid']) - ellps2 = srs.ellipsoid - - for i in range(3): - param1 = ellps1[i] - param2 = ellps2[i] - self.assertAlmostEqual(ellps1[i], ellps2[i], prec[i]) - -def suite(): - s = unittest.TestSuite() - s.addTest(unittest.makeSuite(SpatialRefSysTest)) - return s - -def run(verbosity=2): - unittest.TextTestRunner(verbosity=verbosity).run(suite()) diff --git a/parts/django/django/contrib/gis/tests/utils.py b/parts/django/django/contrib/gis/tests/utils.py deleted file mode 100644 index b758fd0..0000000 --- a/parts/django/django/contrib/gis/tests/utils.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.conf import settings -from django.db import DEFAULT_DB_ALIAS - -# function that will pass a test. -def pass_test(*args): return - -def no_backend(test_func, backend): - "Use this decorator to disable test on specified backend." - if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].rsplit('.')[-1] == backend: - return pass_test - else: - return test_func - -# Decorators to disable entire test functions for specific -# spatial backends. -def no_oracle(func): return no_backend(func, 'oracle') -def no_postgis(func): return no_backend(func, 'postgis') -def no_mysql(func): return no_backend(func, 'mysql') -def no_spatialite(func): return no_backend(func, 'spatialite') - -# Shortcut booleans to omit only portions of tests. -_default_db = settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'].rsplit('.')[-1] -oracle = _default_db == 'oracle' -postgis = _default_db == 'postgis' -mysql = _default_db == 'mysql' -spatialite = _default_db == 'spatialite' diff --git a/parts/django/django/contrib/gis/utils/__init__.py b/parts/django/django/contrib/gis/utils/__init__.py deleted file mode 100644 index 1cff4d9..0000000 --- a/parts/django/django/contrib/gis/utils/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -""" - This module contains useful utilities for GeoDjango. -""" -# Importing the utilities that depend on GDAL, if available. -from django.contrib.gis.gdal import HAS_GDAL -if HAS_GDAL: - from django.contrib.gis.utils.ogrinfo import ogrinfo, sample - from django.contrib.gis.utils.ogrinspect import mapping, ogrinspect - from django.contrib.gis.utils.srs import add_postgis_srs, add_srs_entry - try: - # LayerMapping requires DJANGO_SETTINGS_MODULE to be set, - # so this needs to be in try/except. - from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError - except: - pass - -# Attempting to import the GeoIP class. -try: - from django.contrib.gis.utils.geoip import GeoIP, GeoIPException - HAS_GEOIP = True -except: - HAS_GEOIP = False - -from django.contrib.gis.utils.wkt import precision_wkt - diff --git a/parts/django/django/contrib/gis/utils/geoip.py b/parts/django/django/contrib/gis/utils/geoip.py deleted file mode 100644 index eedaef9..0000000 --- a/parts/django/django/contrib/gis/utils/geoip.py +++ /dev/null @@ -1,361 +0,0 @@ -""" - This module houses the GeoIP object, a ctypes wrapper for the MaxMind GeoIP(R) - C API (http://www.maxmind.com/app/c). This is an alternative to the GPL - licensed Python GeoIP interface provided by MaxMind. - - GeoIP(R) is a registered trademark of MaxMind, LLC of Boston, Massachusetts. - - For IP-based geolocation, this module requires the GeoLite Country and City - datasets, in binary format (CSV will not work!). The datasets may be - downloaded from MaxMind at http://www.maxmind.com/download/geoip/database/. - Grab GeoIP.dat.gz and GeoLiteCity.dat.gz, and unzip them in the directory - corresponding to settings.GEOIP_PATH. See the GeoIP docstring and examples - below for more details. - - TODO: Verify compatibility with Windows. - - Example: - - >>> from django.contrib.gis.utils import GeoIP - >>> g = GeoIP() - >>> g.country('google.com') - {'country_code': 'US', 'country_name': 'United States'} - >>> g.city('72.14.207.99') - {'area_code': 650, - 'city': 'Mountain View', - 'country_code': 'US', - 'country_code3': 'USA', - 'country_name': 'United States', - 'dma_code': 807, - 'latitude': 37.419200897216797, - 'longitude': -122.05740356445312, - 'postal_code': '94043', - 'region': 'CA'} - >>> g.lat_lon('salon.com') - (37.789798736572266, -122.39420318603516) - >>> g.lon_lat('uh.edu') - (-95.415199279785156, 29.77549934387207) - >>> g.geos('24.124.1.80').wkt - 'POINT (-95.2087020874023438 39.0392990112304688)' -""" -import os, re -from ctypes import c_char_p, c_float, c_int, Structure, CDLL, POINTER -from ctypes.util import find_library -from django.conf import settings -if not settings.configured: settings.configure() - -# Creating the settings dictionary with any settings, if needed. -GEOIP_SETTINGS = dict((key, getattr(settings, key)) - for key in ('GEOIP_PATH', 'GEOIP_LIBRARY_PATH', 'GEOIP_COUNTRY', 'GEOIP_CITY') - if hasattr(settings, key)) -lib_path = GEOIP_SETTINGS.get('GEOIP_LIBRARY_PATH', None) - -# GeoIP Exception class. -class GeoIPException(Exception): pass - -# The shared library for the GeoIP C API. May be downloaded -# from http://www.maxmind.com/download/geoip/api/c/ -if lib_path: - lib_name = None -else: - # TODO: Is this really the library name for Windows? - lib_name = 'GeoIP' - -# Getting the path to the GeoIP library. -if lib_name: lib_path = find_library(lib_name) -if lib_path is None: raise GeoIPException('Could not find the GeoIP library (tried "%s"). ' - 'Try setting GEOIP_LIBRARY_PATH in your settings.' % lib_name) -lgeoip = CDLL(lib_path) - -# Regular expressions for recognizing IP addresses and the GeoIP -# free database editions. -ipregex = re.compile(r'^(?P<w>\d\d?\d?)\.(?P<x>\d\d?\d?)\.(?P<y>\d\d?\d?)\.(?P<z>\d\d?\d?)$') -free_regex = re.compile(r'^GEO-\d{3}FREE') -lite_regex = re.compile(r'^GEO-\d{3}LITE') - -#### GeoIP C Structure definitions #### -class GeoIPRecord(Structure): - _fields_ = [('country_code', c_char_p), - ('country_code3', c_char_p), - ('country_name', c_char_p), - ('region', c_char_p), - ('city', c_char_p), - ('postal_code', c_char_p), - ('latitude', c_float), - ('longitude', c_float), - # TODO: In 1.4.6 this changed from `int dma_code;` to - # `union {int metro_code; int dma_code;};`. Change - # to a `ctypes.Union` in to accomodate in future when - # pre-1.4.6 versions are no longer distributed. - ('dma_code', c_int), - ('area_code', c_int), - # TODO: The following structure fields were added in 1.4.3 -- - # uncomment these fields when sure previous versions are no - # longer distributed by package maintainers. - #('charset', c_int), - #('continent_code', c_char_p), - ] -class GeoIPTag(Structure): pass - -#### ctypes function prototypes #### -RECTYPE = POINTER(GeoIPRecord) -DBTYPE = POINTER(GeoIPTag) - -# For retrieving records by name or address. -def record_output(func): - func.restype = RECTYPE - return func -rec_by_addr = record_output(lgeoip.GeoIP_record_by_addr) -rec_by_name = record_output(lgeoip.GeoIP_record_by_name) - -# For opening & closing GeoIP database files. -geoip_open = lgeoip.GeoIP_open -geoip_open.restype = DBTYPE -geoip_close = lgeoip.GeoIP_delete -geoip_close.argtypes = [DBTYPE] -geoip_close.restype = None - -# String output routines. -def string_output(func): - func.restype = c_char_p - return func -geoip_dbinfo = string_output(lgeoip.GeoIP_database_info) -cntry_code_by_addr = string_output(lgeoip.GeoIP_country_code_by_addr) -cntry_code_by_name = string_output(lgeoip.GeoIP_country_code_by_name) -cntry_name_by_addr = string_output(lgeoip.GeoIP_country_name_by_addr) -cntry_name_by_name = string_output(lgeoip.GeoIP_country_name_by_name) - -#### GeoIP class #### -class GeoIP(object): - # The flags for GeoIP memory caching. - # GEOIP_STANDARD - read database from filesystem, uses least memory. - # - # GEOIP_MEMORY_CACHE - load database into memory, faster performance - # but uses more memory - # - # GEOIP_CHECK_CACHE - check for updated database. If database has been updated, - # reload filehandle and/or memory cache. - # - # GEOIP_INDEX_CACHE - just cache - # the most frequently accessed index portion of the database, resulting - # in faster lookups than GEOIP_STANDARD, but less memory usage than - # GEOIP_MEMORY_CACHE - useful for larger databases such as - # GeoIP Organization and GeoIP City. Note, for GeoIP Country, Region - # and Netspeed databases, GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE - # - GEOIP_STANDARD = 0 - GEOIP_MEMORY_CACHE = 1 - GEOIP_CHECK_CACHE = 2 - GEOIP_INDEX_CACHE = 4 - cache_options = dict((opt, None) for opt in (0, 1, 2, 4)) - _city_file = '' - _country_file = '' - - # Initially, pointers to GeoIP file references are NULL. - _city = None - _country = None - - def __init__(self, path=None, cache=0, country=None, city=None): - """ - Initializes the GeoIP object, no parameters are required to use default - settings. Keyword arguments may be passed in to customize the locations - of the GeoIP data sets. - - * path: Base directory to where GeoIP data is located or the full path - to where the city or country data files (*.dat) are located. - Assumes that both the city and country data sets are located in - this directory; overrides the GEOIP_PATH settings attribute. - - * cache: The cache settings when opening up the GeoIP datasets, - and may be an integer in (0, 1, 2, 4) corresponding to - the GEOIP_STANDARD, GEOIP_MEMORY_CACHE, GEOIP_CHECK_CACHE, - and GEOIP_INDEX_CACHE `GeoIPOptions` C API settings, - respectively. Defaults to 0, meaning that the data is read - from the disk. - - * country: The name of the GeoIP country data file. Defaults to - 'GeoIP.dat'; overrides the GEOIP_COUNTRY settings attribute. - - * city: The name of the GeoIP city data file. Defaults to - 'GeoLiteCity.dat'; overrides the GEOIP_CITY settings attribute. - """ - # Checking the given cache option. - if cache in self.cache_options: - self._cache = self.cache_options[cache] - else: - raise GeoIPException('Invalid caching option: %s' % cache) - - # Getting the GeoIP data path. - if not path: - path = GEOIP_SETTINGS.get('GEOIP_PATH', None) - if not path: raise GeoIPException('GeoIP path must be provided via parameter or the GEOIP_PATH setting.') - if not isinstance(path, basestring): - raise TypeError('Invalid path type: %s' % type(path).__name__) - - if os.path.isdir(path): - # Constructing the GeoIP database filenames using the settings - # dictionary. If the database files for the GeoLite country - # and/or city datasets exist, then try and open them. - country_db = os.path.join(path, country or GEOIP_SETTINGS.get('GEOIP_COUNTRY', 'GeoIP.dat')) - if os.path.isfile(country_db): - self._country = geoip_open(country_db, cache) - self._country_file = country_db - - city_db = os.path.join(path, city or GEOIP_SETTINGS.get('GEOIP_CITY', 'GeoLiteCity.dat')) - if os.path.isfile(city_db): - self._city = geoip_open(city_db, cache) - self._city_file = city_db - elif os.path.isfile(path): - # Otherwise, some detective work will be needed to figure - # out whether the given database path is for the GeoIP country - # or city databases. - ptr = geoip_open(path, cache) - info = geoip_dbinfo(ptr) - if lite_regex.match(info): - # GeoLite City database detected. - self._city = ptr - self._city_file = path - elif free_regex.match(info): - # GeoIP Country database detected. - self._country = ptr - self._country_file = path - else: - raise GeoIPException('Unable to recognize database edition: %s' % info) - else: - raise GeoIPException('GeoIP path must be a valid file or directory.') - - def __del__(self): - # Cleaning any GeoIP file handles lying around. - if self._country: geoip_close(self._country) - if self._city: geoip_close(self._city) - - def _check_query(self, query, country=False, city=False, city_or_country=False): - "Helper routine for checking the query and database availability." - # Making sure a string was passed in for the query. - if not isinstance(query, basestring): - raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__) - - # Extra checks for the existence of country and city databases. - if city_or_country and not (self._country or self._city): - raise GeoIPException('Invalid GeoIP country and city data files.') - elif country and not self._country: - raise GeoIPException('Invalid GeoIP country data file: %s' % self._country_file) - elif city and not self._city: - raise GeoIPException('Invalid GeoIP city data file: %s' % self._city_file) - - def city(self, query): - """ - Returns a dictionary of city information for the given IP address or - Fully Qualified Domain Name (FQDN). Some information in the dictionary - may be undefined (None). - """ - self._check_query(query, city=True) - if ipregex.match(query): - # If an IP address was passed in - ptr = rec_by_addr(self._city, c_char_p(query)) - else: - # If a FQDN was passed in. - ptr = rec_by_name(self._city, c_char_p(query)) - - # Checking the pointer to the C structure, if valid pull out elements - # into a dicionary and return. - if bool(ptr): - record = ptr.contents - return dict((tup[0], getattr(record, tup[0])) for tup in record._fields_) - else: - return None - - def country_code(self, query): - "Returns the country code for the given IP Address or FQDN." - self._check_query(query, city_or_country=True) - if self._country: - if ipregex.match(query): return cntry_code_by_addr(self._country, query) - else: return cntry_code_by_name(self._country, query) - else: - return self.city(query)['country_code'] - - def country_name(self, query): - "Returns the country name for the given IP Address or FQDN." - self._check_query(query, city_or_country=True) - if self._country: - if ipregex.match(query): return cntry_name_by_addr(self._country, query) - else: return cntry_name_by_name(self._country, query) - else: - return self.city(query)['country_name'] - - def country(self, query): - """ - Returns a dictonary with with the country code and name when given an - IP address or a Fully Qualified Domain Name (FQDN). For example, both - '24.124.1.80' and 'djangoproject.com' are valid parameters. - """ - # Returning the country code and name - return {'country_code' : self.country_code(query), - 'country_name' : self.country_name(query), - } - - #### Coordinate retrieval routines #### - def coords(self, query, ordering=('longitude', 'latitude')): - cdict = self.city(query) - if cdict is None: return None - else: return tuple(cdict[o] for o in ordering) - - def lon_lat(self, query): - "Returns a tuple of the (longitude, latitude) for the given query." - return self.coords(query) - - def lat_lon(self, query): - "Returns a tuple of the (latitude, longitude) for the given query." - return self.coords(query, ('latitude', 'longitude')) - - def geos(self, query): - "Returns a GEOS Point object for the given query." - ll = self.lon_lat(query) - if ll: - from django.contrib.gis.geos import Point - return Point(ll, srid=4326) - else: - return None - - #### GeoIP Database Information Routines #### - def country_info(self): - "Returns information about the GeoIP country database." - if self._country is None: - ci = 'No GeoIP Country data in "%s"' % self._country_file - else: - ci = geoip_dbinfo(self._country) - return ci - country_info = property(country_info) - - def city_info(self): - "Retuns information about the GeoIP city database." - if self._city is None: - ci = 'No GeoIP City data in "%s"' % self._city_file - else: - ci = geoip_dbinfo(self._city) - return ci - city_info = property(city_info) - - def info(self): - "Returns information about all GeoIP databases in use." - return 'Country:\n\t%s\nCity:\n\t%s' % (self.country_info, self.city_info) - info = property(info) - - #### Methods for compatibility w/the GeoIP-Python API. #### - @classmethod - def open(cls, full_path, cache): - return GeoIP(full_path, cache) - - def _rec_by_arg(self, arg): - if self._city: - return self.city(arg) - else: - return self.country(arg) - region_by_addr = city - region_by_name = city - record_by_addr = _rec_by_arg - record_by_name = _rec_by_arg - country_code_by_addr = country_code - country_code_by_name = country_code - country_name_by_addr = country_name - country_name_by_name = country_name diff --git a/parts/django/django/contrib/gis/utils/layermapping.py b/parts/django/django/contrib/gis/utils/layermapping.py deleted file mode 100644 index cec1989..0000000 --- a/parts/django/django/contrib/gis/utils/layermapping.py +++ /dev/null @@ -1,602 +0,0 @@ -# LayerMapping -- A Django Model/OGR Layer Mapping Utility -""" - The LayerMapping class provides a way to map the contents of OGR - vector files (e.g. SHP files) to Geographic-enabled Django models. - - For more information, please consult the GeoDjango documentation: - http://geodjango.org/docs/layermapping.html -""" -import sys -from datetime import date, datetime -from decimal import Decimal -from django.core.exceptions import ObjectDoesNotExist -from django.db import connections, DEFAULT_DB_ALIAS -from django.contrib.gis.db.models import GeometryField -from django.contrib.gis.gdal import CoordTransform, DataSource, \ - OGRException, OGRGeometry, OGRGeomType, SpatialReference -from django.contrib.gis.gdal.field import \ - OFTDate, OFTDateTime, OFTInteger, OFTReal, OFTString, OFTTime -from django.db import models, transaction -from django.contrib.localflavor.us.models import USStateField - -# LayerMapping exceptions. -class LayerMapError(Exception): pass -class InvalidString(LayerMapError): pass -class InvalidDecimal(LayerMapError): pass -class InvalidInteger(LayerMapError): pass -class MissingForeignKey(LayerMapError): pass - -class LayerMapping(object): - "A class that maps OGR Layers to GeoDjango Models." - - # Acceptable 'base' types for a multi-geometry type. - MULTI_TYPES = {1 : OGRGeomType('MultiPoint'), - 2 : OGRGeomType('MultiLineString'), - 3 : OGRGeomType('MultiPolygon'), - OGRGeomType('Point25D').num : OGRGeomType('MultiPoint25D'), - OGRGeomType('LineString25D').num : OGRGeomType('MultiLineString25D'), - OGRGeomType('Polygon25D').num : OGRGeomType('MultiPolygon25D'), - } - - # Acceptable Django field types and corresponding acceptable OGR - # counterparts. - FIELD_TYPES = { - models.AutoField : OFTInteger, - models.IntegerField : (OFTInteger, OFTReal, OFTString), - models.FloatField : (OFTInteger, OFTReal), - models.DateField : OFTDate, - models.DateTimeField : OFTDateTime, - models.EmailField : OFTString, - models.TimeField : OFTTime, - models.DecimalField : (OFTInteger, OFTReal), - models.CharField : OFTString, - models.SlugField : OFTString, - models.TextField : OFTString, - models.URLField : OFTString, - USStateField : OFTString, - models.XMLField : OFTString, - models.SmallIntegerField : (OFTInteger, OFTReal, OFTString), - models.PositiveSmallIntegerField : (OFTInteger, OFTReal, OFTString), - } - - # The acceptable transaction modes. - TRANSACTION_MODES = {'autocommit' : transaction.autocommit, - 'commit_on_success' : transaction.commit_on_success, - } - - def __init__(self, model, data, mapping, layer=0, - source_srs=None, encoding=None, - transaction_mode='commit_on_success', - transform=True, unique=None, using=DEFAULT_DB_ALIAS): - """ - A LayerMapping object is initialized using the given Model (not an instance), - a DataSource (or string path to an OGR-supported data file), and a mapping - dictionary. See the module level docstring for more details and keyword - argument usage. - """ - # Getting the DataSource and the associated Layer. - if isinstance(data, basestring): - self.ds = DataSource(data) - else: - self.ds = data - self.layer = self.ds[layer] - - self.using = using - self.spatial_backend = connections[using].ops - - # Setting the mapping & model attributes. - self.mapping = mapping - self.model = model - - # Checking the layer -- intitialization of the object will fail if - # things don't check out before hand. - self.check_layer() - - # Getting the geometry column associated with the model (an - # exception will be raised if there is no geometry column). - if self.spatial_backend.mysql: - transform = False - else: - self.geo_field = self.geometry_field() - - # Checking the source spatial reference system, and getting - # the coordinate transformation object (unless the `transform` - # keyword is set to False) - if transform: - self.source_srs = self.check_srs(source_srs) - self.transform = self.coord_transform() - else: - self.transform = transform - - # Setting the encoding for OFTString fields, if specified. - if encoding: - # Making sure the encoding exists, if not a LookupError - # exception will be thrown. - from codecs import lookup - lookup(encoding) - self.encoding = encoding - else: - self.encoding = None - - if unique: - self.check_unique(unique) - transaction_mode = 'autocommit' # Has to be set to autocommit. - self.unique = unique - else: - self.unique = None - - # Setting the transaction decorator with the function in the - # transaction modes dictionary. - if transaction_mode in self.TRANSACTION_MODES: - self.transaction_decorator = self.TRANSACTION_MODES[transaction_mode] - self.transaction_mode = transaction_mode - else: - raise LayerMapError('Unrecognized transaction mode: %s' % transaction_mode) - - if using is None: - pass - - #### Checking routines used during initialization #### - def check_fid_range(self, fid_range): - "This checks the `fid_range` keyword." - if fid_range: - if isinstance(fid_range, (tuple, list)): - return slice(*fid_range) - elif isinstance(fid_range, slice): - return fid_range - else: - raise TypeError - else: - return None - - def check_layer(self): - """ - This checks the Layer metadata, and ensures that it is compatible - with the mapping information and model. Unlike previous revisions, - there is no need to increment through each feature in the Layer. - """ - # The geometry field of the model is set here. - # TODO: Support more than one geometry field / model. However, this - # depends on the GDAL Driver in use. - self.geom_field = False - self.fields = {} - - # Getting lists of the field names and the field types available in - # the OGR Layer. - ogr_fields = self.layer.fields - ogr_field_types = self.layer.field_types - - # Function for determining if the OGR mapping field is in the Layer. - def check_ogr_fld(ogr_map_fld): - try: - idx = ogr_fields.index(ogr_map_fld) - except ValueError: - raise LayerMapError('Given mapping OGR field "%s" not found in OGR Layer.' % ogr_map_fld) - return idx - - # No need to increment through each feature in the model, simply check - # the Layer metadata against what was given in the mapping dictionary. - for field_name, ogr_name in self.mapping.items(): - # Ensuring that a corresponding field exists in the model - # for the given field name in the mapping. - try: - model_field = self.model._meta.get_field(field_name) - except models.fields.FieldDoesNotExist: - raise LayerMapError('Given mapping field "%s" not in given Model fields.' % field_name) - - # Getting the string name for the Django field class (e.g., 'PointField'). - fld_name = model_field.__class__.__name__ - - if isinstance(model_field, GeometryField): - if self.geom_field: - raise LayerMapError('LayerMapping does not support more than one GeometryField per model.') - - # Getting the coordinate dimension of the geometry field. - coord_dim = model_field.dim - - try: - if coord_dim == 3: - gtype = OGRGeomType(ogr_name + '25D') - else: - gtype = OGRGeomType(ogr_name) - except OGRException: - raise LayerMapError('Invalid mapping for GeometryField "%s".' % field_name) - - # Making sure that the OGR Layer's Geometry is compatible. - ltype = self.layer.geom_type - if not (ltype.name.startswith(gtype.name) or self.make_multi(ltype, model_field)): - raise LayerMapError('Invalid mapping geometry; model has %s%s, ' - 'layer geometry type is %s.' % - (fld_name, (coord_dim == 3 and '(dim=3)') or '', ltype)) - - # Setting the `geom_field` attribute w/the name of the model field - # that is a Geometry. Also setting the coordinate dimension - # attribute. - self.geom_field = field_name - self.coord_dim = coord_dim - fields_val = model_field - elif isinstance(model_field, models.ForeignKey): - if isinstance(ogr_name, dict): - # Is every given related model mapping field in the Layer? - rel_model = model_field.rel.to - for rel_name, ogr_field in ogr_name.items(): - idx = check_ogr_fld(ogr_field) - try: - rel_field = rel_model._meta.get_field(rel_name) - except models.fields.FieldDoesNotExist: - raise LayerMapError('ForeignKey mapping field "%s" not in %s fields.' % - (rel_name, rel_model.__class__.__name__)) - fields_val = rel_model - else: - raise TypeError('ForeignKey mapping must be of dictionary type.') - else: - # Is the model field type supported by LayerMapping? - if not model_field.__class__ in self.FIELD_TYPES: - raise LayerMapError('Django field type "%s" has no OGR mapping (yet).' % fld_name) - - # Is the OGR field in the Layer? - idx = check_ogr_fld(ogr_name) - ogr_field = ogr_field_types[idx] - - # Can the OGR field type be mapped to the Django field type? - if not issubclass(ogr_field, self.FIELD_TYPES[model_field.__class__]): - raise LayerMapError('OGR field "%s" (of type %s) cannot be mapped to Django %s.' % - (ogr_field, ogr_field.__name__, fld_name)) - fields_val = model_field - - self.fields[field_name] = fields_val - - def check_srs(self, source_srs): - "Checks the compatibility of the given spatial reference object." - - if isinstance(source_srs, SpatialReference): - sr = source_srs - elif isinstance(source_srs, self.spatial_backend.spatial_ref_sys()): - sr = source_srs.srs - elif isinstance(source_srs, (int, basestring)): - sr = SpatialReference(source_srs) - else: - # Otherwise just pulling the SpatialReference from the layer - sr = self.layer.srs - - if not sr: - raise LayerMapError('No source reference system defined.') - else: - return sr - - def check_unique(self, unique): - "Checks the `unique` keyword parameter -- may be a sequence or string." - if isinstance(unique, (list, tuple)): - # List of fields to determine uniqueness with - for attr in unique: - if not attr in self.mapping: raise ValueError - elif isinstance(unique, basestring): - # Only a single field passed in. - if unique not in self.mapping: raise ValueError - else: - raise TypeError('Unique keyword argument must be set with a tuple, list, or string.') - - #### Keyword argument retrieval routines #### - def feature_kwargs(self, feat): - """ - Given an OGR Feature, this will return a dictionary of keyword arguments - for constructing the mapped model. - """ - # The keyword arguments for model construction. - kwargs = {} - - # Incrementing through each model field and OGR field in the - # dictionary mapping. - for field_name, ogr_name in self.mapping.items(): - model_field = self.fields[field_name] - - if isinstance(model_field, GeometryField): - # Verify OGR geometry. - val = self.verify_geom(feat.geom, model_field) - elif isinstance(model_field, models.base.ModelBase): - # The related _model_, not a field was passed in -- indicating - # another mapping for the related Model. - val = self.verify_fk(feat, model_field, ogr_name) - else: - # Otherwise, verify OGR Field type. - val = self.verify_ogr_field(feat[ogr_name], model_field) - - # Setting the keyword arguments for the field name with the - # value obtained above. - kwargs[field_name] = val - - return kwargs - - def unique_kwargs(self, kwargs): - """ - Given the feature keyword arguments (from `feature_kwargs`) this routine - will construct and return the uniqueness keyword arguments -- a subset - of the feature kwargs. - """ - if isinstance(self.unique, basestring): - return {self.unique : kwargs[self.unique]} - else: - return dict((fld, kwargs[fld]) for fld in self.unique) - - #### Verification routines used in constructing model keyword arguments. #### - def verify_ogr_field(self, ogr_field, model_field): - """ - Verifies if the OGR Field contents are acceptable to the Django - model field. If they are, the verified value is returned, - otherwise the proper exception is raised. - """ - if (isinstance(ogr_field, OFTString) and - isinstance(model_field, (models.CharField, models.TextField))): - if self.encoding: - # The encoding for OGR data sources may be specified here - # (e.g., 'cp437' for Census Bureau boundary files). - val = unicode(ogr_field.value, self.encoding) - else: - val = ogr_field.value - if len(val) > model_field.max_length: - raise InvalidString('%s model field maximum string length is %s, given %s characters.' % - (model_field.name, model_field.max_length, len(val))) - elif isinstance(ogr_field, OFTReal) and isinstance(model_field, models.DecimalField): - try: - # Creating an instance of the Decimal value to use. - d = Decimal(str(ogr_field.value)) - except: - raise InvalidDecimal('Could not construct decimal from: %s' % ogr_field.value) - - # Getting the decimal value as a tuple. - dtup = d.as_tuple() - digits = dtup[1] - d_idx = dtup[2] # index where the decimal is - - # Maximum amount of precision, or digits to the left of the decimal. - max_prec = model_field.max_digits - model_field.decimal_places - - # Getting the digits to the left of the decimal place for the - # given decimal. - if d_idx < 0: - n_prec = len(digits[:d_idx]) - else: - n_prec = len(digits) + d_idx - - # If we have more than the maximum digits allowed, then throw an - # InvalidDecimal exception. - if n_prec > max_prec: - raise InvalidDecimal('A DecimalField with max_digits %d, decimal_places %d must round to an absolute value less than 10^%d.' % - (model_field.max_digits, model_field.decimal_places, max_prec)) - val = d - elif isinstance(ogr_field, (OFTReal, OFTString)) and isinstance(model_field, models.IntegerField): - # Attempt to convert any OFTReal and OFTString value to an OFTInteger. - try: - val = int(ogr_field.value) - except: - raise InvalidInteger('Could not construct integer from: %s' % ogr_field.value) - else: - val = ogr_field.value - return val - - def verify_fk(self, feat, rel_model, rel_mapping): - """ - Given an OGR Feature, the related model and its dictionary mapping, - this routine will retrieve the related model for the ForeignKey - mapping. - """ - # TODO: It is expensive to retrieve a model for every record -- - # explore if an efficient mechanism exists for caching related - # ForeignKey models. - - # Constructing and verifying the related model keyword arguments. - fk_kwargs = {} - for field_name, ogr_name in rel_mapping.items(): - fk_kwargs[field_name] = self.verify_ogr_field(feat[ogr_name], rel_model._meta.get_field(field_name)) - - # Attempting to retrieve and return the related model. - try: - return rel_model.objects.get(**fk_kwargs) - except ObjectDoesNotExist: - raise MissingForeignKey('No ForeignKey %s model found with keyword arguments: %s' % (rel_model.__name__, fk_kwargs)) - - def verify_geom(self, geom, model_field): - """ - Verifies the geometry -- will construct and return a GeometryCollection - if necessary (for example if the model field is MultiPolygonField while - the mapped shapefile only contains Polygons). - """ - # Downgrade a 3D geom to a 2D one, if necessary. - if self.coord_dim != geom.coord_dim: - geom.coord_dim = self.coord_dim - - if self.make_multi(geom.geom_type, model_field): - # Constructing a multi-geometry type to contain the single geometry - multi_type = self.MULTI_TYPES[geom.geom_type.num] - g = OGRGeometry(multi_type) - g.add(geom) - else: - g = geom - - # Transforming the geometry with our Coordinate Transformation object, - # but only if the class variable `transform` is set w/a CoordTransform - # object. - if self.transform: g.transform(self.transform) - - # Returning the WKT of the geometry. - return g.wkt - - #### Other model methods #### - def coord_transform(self): - "Returns the coordinate transformation object." - SpatialRefSys = self.spatial_backend.spatial_ref_sys() - try: - # Getting the target spatial reference system - target_srs = SpatialRefSys.objects.get(srid=self.geo_field.srid).srs - - # Creating the CoordTransform object - return CoordTransform(self.source_srs, target_srs) - except Exception, msg: - raise LayerMapError('Could not translate between the data source and model geometry: %s' % msg) - - def geometry_field(self): - "Returns the GeometryField instance associated with the geographic column." - # Use the `get_field_by_name` on the model's options so that we - # get the correct field instance if there's model inheritance. - opts = self.model._meta - fld, model, direct, m2m = opts.get_field_by_name(self.geom_field) - return fld - - def make_multi(self, geom_type, model_field): - """ - Given the OGRGeomType for a geometry and its associated GeometryField, - determine whether the geometry should be turned into a GeometryCollection. - """ - return (geom_type.num in self.MULTI_TYPES and - model_field.__class__.__name__ == 'Multi%s' % geom_type.django) - - def save(self, verbose=False, fid_range=False, step=False, - progress=False, silent=False, stream=sys.stdout, strict=False): - """ - Saves the contents from the OGR DataSource Layer into the database - according to the mapping dictionary given at initialization. - - Keyword Parameters: - verbose: - If set, information will be printed subsequent to each model save - executed on the database. - - fid_range: - May be set with a slice or tuple of (begin, end) feature ID's to map - from the data source. In other words, this keyword enables the user - to selectively import a subset range of features in the geographic - data source. - - step: - If set with an integer, transactions will occur at every step - interval. For example, if step=1000, a commit would occur after - the 1,000th feature, the 2,000th feature etc. - - progress: - When this keyword is set, status information will be printed giving - the number of features processed and sucessfully saved. By default, - progress information will pe printed every 1000 features processed, - however, this default may be overridden by setting this keyword with an - integer for the desired interval. - - stream: - Status information will be written to this file handle. Defaults to - using `sys.stdout`, but any object with a `write` method is supported. - - silent: - By default, non-fatal error notifications are printed to stdout, but - this keyword may be set to disable these notifications. - - strict: - Execution of the model mapping will cease upon the first error - encountered. The default behavior is to attempt to continue. - """ - # Getting the default Feature ID range. - default_range = self.check_fid_range(fid_range) - - # Setting the progress interval, if requested. - if progress: - if progress is True or not isinstance(progress, int): - progress_interval = 1000 - else: - progress_interval = progress - - # Defining the 'real' save method, utilizing the transaction - # decorator created during initialization. - @self.transaction_decorator - def _save(feat_range=default_range, num_feat=0, num_saved=0): - if feat_range: - layer_iter = self.layer[feat_range] - else: - layer_iter = self.layer - - for feat in layer_iter: - num_feat += 1 - # Getting the keyword arguments - try: - kwargs = self.feature_kwargs(feat) - except LayerMapError, msg: - # Something borked the validation - if strict: raise - elif not silent: - stream.write('Ignoring Feature ID %s because: %s\n' % (feat.fid, msg)) - else: - # Constructing the model using the keyword args - is_update = False - if self.unique: - # If we want unique models on a particular field, handle the - # geometry appropriately. - try: - # Getting the keyword arguments and retrieving - # the unique model. - u_kwargs = self.unique_kwargs(kwargs) - m = self.model.objects.using(self.using).get(**u_kwargs) - is_update = True - - # Getting the geometry (in OGR form), creating - # one from the kwargs WKT, adding in additional - # geometries, and update the attribute with the - # just-updated geometry WKT. - geom = getattr(m, self.geom_field).ogr - new = OGRGeometry(kwargs[self.geom_field]) - for g in new: geom.add(g) - setattr(m, self.geom_field, geom.wkt) - except ObjectDoesNotExist: - # No unique model exists yet, create. - m = self.model(**kwargs) - else: - m = self.model(**kwargs) - - try: - # Attempting to save. - m.save(using=self.using) - num_saved += 1 - if verbose: stream.write('%s: %s\n' % (is_update and 'Updated' or 'Saved', m)) - except SystemExit: - raise - except Exception, msg: - if self.transaction_mode == 'autocommit': - # Rolling back the transaction so that other model saves - # will work. - transaction.rollback_unless_managed() - if strict: - # Bailing out if the `strict` keyword is set. - if not silent: - stream.write('Failed to save the feature (id: %s) into the model with the keyword arguments:\n' % feat.fid) - stream.write('%s\n' % kwargs) - raise - elif not silent: - stream.write('Failed to save %s:\n %s\nContinuing\n' % (kwargs, msg)) - - # Printing progress information, if requested. - if progress and num_feat % progress_interval == 0: - stream.write('Processed %d features, saved %d ...\n' % (num_feat, num_saved)) - - # Only used for status output purposes -- incremental saving uses the - # values returned here. - return num_saved, num_feat - - nfeat = self.layer.num_feat - if step and isinstance(step, int) and step < nfeat: - # Incremental saving is requested at the given interval (step) - if default_range: - raise LayerMapError('The `step` keyword may not be used in conjunction with the `fid_range` keyword.') - beg, num_feat, num_saved = (0, 0, 0) - indices = range(step, nfeat, step) - n_i = len(indices) - - for i, end in enumerate(indices): - # Constructing the slice to use for this step; the last slice is - # special (e.g, [100:] instead of [90:100]). - if i+1 == n_i: step_slice = slice(beg, None) - else: step_slice = slice(beg, end) - - try: - num_feat, num_saved = _save(step_slice, num_feat, num_saved) - beg = end - except: - stream.write('%s\nFailed to save slice: %s\n' % ('=-' * 20, step_slice)) - raise - else: - # Otherwise, just calling the previously defined _save() function. - _save() diff --git a/parts/django/django/contrib/gis/utils/ogrinfo.py b/parts/django/django/contrib/gis/utils/ogrinfo.py deleted file mode 100644 index 1e4c42d..0000000 --- a/parts/django/django/contrib/gis/utils/ogrinfo.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -This module includes some utility functions for inspecting the layout -of a GDAL data source -- the functionality is analogous to the output -produced by the `ogrinfo` utility. -""" - -from django.contrib.gis.gdal import DataSource -from django.contrib.gis.gdal.geometries import GEO_CLASSES - -def ogrinfo(data_source, num_features=10): - """ - Walks the available layers in the supplied `data_source`, displaying - the fields for the first `num_features` features. - """ - - # Checking the parameters. - if isinstance(data_source, str): - data_source = DataSource(data_source) - elif isinstance(data_source, DataSource): - pass - else: - raise Exception('Data source parameter must be a string or a DataSource object.') - - for i, layer in enumerate(data_source): - print "data source : %s" % data_source.name - print "==== layer %s" % i - print " shape type: %s" % GEO_CLASSES[layer.geom_type.num].__name__ - print " # features: %s" % len(layer) - print " srs: %s" % layer.srs - extent_tup = layer.extent.tuple - print " extent: %s - %s" % (extent_tup[0:2], extent_tup[2:4]) - print "Displaying the first %s features ====" % num_features - - width = max(*map(len,layer.fields)) - fmt = " %%%ss: %%s" % width - for j, feature in enumerate(layer[:num_features]): - print "=== Feature %s" % j - for fld_name in layer.fields: - type_name = feature[fld_name].type_name - output = fmt % (fld_name, type_name) - val = feature.get(fld_name) - if val: - if isinstance(val, str): - val_fmt = ' ("%s")' - else: - val_fmt = ' (%s)' - output += val_fmt % val - else: - output += ' (None)' - print output - -# For backwards compatibility. -sample = ogrinfo diff --git a/parts/django/django/contrib/gis/utils/ogrinspect.py b/parts/django/django/contrib/gis/utils/ogrinspect.py deleted file mode 100644 index 145bd22..0000000 --- a/parts/django/django/contrib/gis/utils/ogrinspect.py +++ /dev/null @@ -1,225 +0,0 @@ -""" -This module is for inspecting OGR data sources and generating either -models for GeoDjango and/or mapping dictionaries for use with the -`LayerMapping` utility. - -Author: Travis Pinney, Dane Springmeyer, & Justin Bronn -""" -from itertools import izip -# Requires GDAL to use. -from django.contrib.gis.gdal import DataSource -from django.contrib.gis.gdal.field import OFTDate, OFTDateTime, OFTInteger, OFTReal, OFTString, OFTTime - -def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): - """ - Given a DataSource, generates a dictionary that may be used - for invoking the LayerMapping utility. - - Keyword Arguments: - `geom_name` => The name of the geometry field to use for the model. - - `layer_key` => The key for specifying which layer in the DataSource to use; - defaults to 0 (the first layer). May be an integer index or a string - identifier for the layer. - - `multi_geom` => Boolean (default: False) - specify as multigeometry. - """ - if isinstance(data_source, basestring): - # Instantiating the DataSource from the string. - data_source = DataSource(data_source) - elif isinstance(data_source, DataSource): - pass - else: - raise TypeError('Data source parameter must be a string or a DataSource object.') - - # Creating the dictionary. - _mapping = {} - - # Generating the field name for each field in the layer. - for field in data_source[layer_key].fields: - mfield = field.lower() - if mfield[-1:] == '_': mfield += 'field' - _mapping[mfield] = field - gtype = data_source[layer_key].geom_type - if multi_geom and gtype.num in (1, 2, 3): prefix = 'MULTI' - else: prefix = '' - _mapping[geom_name] = prefix + str(gtype).upper() - return _mapping - -def ogrinspect(*args, **kwargs): - """ - Given a data source (either a string or a DataSource object) and a string - model name this function will generate a GeoDjango model. - - Usage: - - >>> from django.contrib.gis.utils import ogrinspect - >>> ogrinspect('/path/to/shapefile.shp','NewModel') - - ...will print model definition to stout - - or put this in a python script and use to redirect the output to a new - model like: - - $ python generate_model.py > myapp/models.py - - # generate_model.py - from django.contrib.gis.utils import ogrinspect - shp_file = 'data/mapping_hacks/world_borders.shp' - model_name = 'WorldBorders' - - print ogrinspect(shp_file, model_name, multi_geom=True, srid=4326, - geom_name='shapes', blank=True) - - Required Arguments - `datasource` => string or DataSource object to file pointer - - `model name` => string of name of new model class to create - - Optional Keyword Arguments - `geom_name` => For specifying the model name for the Geometry Field. - Otherwise will default to `geom` - - `layer_key` => The key for specifying which layer in the DataSource to use; - defaults to 0 (the first layer). May be an integer index or a string - identifier for the layer. - - `srid` => The SRID to use for the Geometry Field. If it can be determined, - the SRID of the datasource is used. - - `multi_geom` => Boolean (default: False) - specify as multigeometry. - - `name_field` => String - specifies a field name to return for the - `__unicode__` function (which will be generated if specified). - - `imports` => Boolean (default: True) - set to False to omit the - `from django.contrib.gis.db import models` code from the - autogenerated models thus avoiding duplicated imports when building - more than one model by batching ogrinspect() - - `decimal` => Boolean or sequence (default: False). When set to True - all generated model fields corresponding to the `OFTReal` type will - be `DecimalField` instead of `FloatField`. A sequence of specific - field names to generate as `DecimalField` may also be used. - - `blank` => Boolean or sequence (default: False). When set to True all - generated model fields will have `blank=True`. If the user wants to - give specific fields to have blank, then a list/tuple of OGR field - names may be used. - - `null` => Boolean (default: False) - When set to True all generated - model fields will have `null=True`. If the user wants to specify - give specific fields to have null, then a list/tuple of OGR field - names may be used. - - Note: This routine calls the _ogrinspect() helper to do the heavy lifting. - """ - return '\n'.join(s for s in _ogrinspect(*args, **kwargs)) - -def _ogrinspect(data_source, model_name, geom_name='geom', layer_key=0, srid=None, - multi_geom=False, name_field=None, imports=True, - decimal=False, blank=False, null=False): - """ - Helper routine for `ogrinspect` that generates GeoDjango models corresponding - to the given data source. See the `ogrinspect` docstring for more details. - """ - # Getting the DataSource - if isinstance(data_source, str): - data_source = DataSource(data_source) - elif isinstance(data_source, DataSource): - pass - else: - raise TypeError('Data source parameter must be a string or a DataSource object.') - - # Getting the layer corresponding to the layer key and getting - # a string listing of all OGR fields in the Layer. - layer = data_source[layer_key] - ogr_fields = layer.fields - - # Creating lists from the `null`, `blank`, and `decimal` - # keyword arguments. - def process_kwarg(kwarg): - if isinstance(kwarg, (list, tuple)): - return [s.lower() for s in kwarg] - elif kwarg: - return [s.lower() for s in ogr_fields] - else: - return [] - null_fields = process_kwarg(null) - blank_fields = process_kwarg(blank) - decimal_fields = process_kwarg(decimal) - - # Gets the `null` and `blank` keywords for the given field name. - def get_kwargs_str(field_name): - kwlist = [] - if field_name.lower() in null_fields: kwlist.append('null=True') - if field_name.lower() in blank_fields: kwlist.append('blank=True') - if kwlist: return ', ' + ', '.join(kwlist) - else: return '' - - # For those wishing to disable the imports. - if imports: - yield '# This is an auto-generated Django model module created by ogrinspect.' - yield 'from django.contrib.gis.db import models' - yield '' - - yield 'class %s(models.Model):' % model_name - - for field_name, width, precision, field_type in izip(ogr_fields, layer.field_widths, layer.field_precisions, layer.field_types): - # The model field name. - mfield = field_name.lower() - if mfield[-1:] == '_': mfield += 'field' - - # Getting the keyword args string. - kwargs_str = get_kwargs_str(field_name) - - if field_type is OFTReal: - # By default OFTReals are mapped to `FloatField`, however, they - # may also be mapped to `DecimalField` if specified in the - # `decimal` keyword. - if field_name.lower() in decimal_fields: - yield ' %s = models.DecimalField(max_digits=%d, decimal_places=%d%s)' % (mfield, width, precision, kwargs_str) - else: - yield ' %s = models.FloatField(%s)' % (mfield, kwargs_str[2:]) - elif field_type is OFTInteger: - yield ' %s = models.IntegerField(%s)' % (mfield, kwargs_str[2:]) - elif field_type is OFTString: - yield ' %s = models.CharField(max_length=%s%s)' % (mfield, width, kwargs_str) - elif field_type is OFTDate: - yield ' %s = models.DateField(%s)' % (mfield, kwargs_str[2:]) - elif field_type is OFTDateTime: - yield ' %s = models.DateTimeField(%s)' % (mfield, kwargs_str[2:]) - elif field_type is OFTDate: - yield ' %s = models.TimeField(%s)' % (mfield, kwargs_str[2:]) - else: - raise TypeError('Unknown field type %s in %s' % (field_type, mfield)) - - # TODO: Autodetection of multigeometry types (see #7218). - gtype = layer.geom_type - if multi_geom and gtype.num in (1, 2, 3): - geom_field = 'Multi%s' % gtype.django - else: - geom_field = gtype.django - - # Setting up the SRID keyword string. - if srid is None: - if layer.srs is None: - srid_str = 'srid=-1' - else: - srid = layer.srs.srid - if srid is None: - srid_str = 'srid=-1' - elif srid == 4326: - # WGS84 is already the default. - srid_str = '' - else: - srid_str = 'srid=%s' % srid - else: - srid_str = 'srid=%s' % srid - - yield ' %s = models.%s(%s)' % (geom_name, geom_field, srid_str) - yield ' objects = models.GeoManager()' - - if name_field: - yield '' - yield ' def __unicode__(self): return self.%s' % name_field diff --git a/parts/django/django/contrib/gis/utils/srs.py b/parts/django/django/contrib/gis/utils/srs.py deleted file mode 100644 index 989929e..0000000 --- a/parts/django/django/contrib/gis/utils/srs.py +++ /dev/null @@ -1,77 +0,0 @@ -from django.contrib.gis.gdal import SpatialReference -from django.db import connections, DEFAULT_DB_ALIAS - -def add_srs_entry(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None, - database=DEFAULT_DB_ALIAS): - """ - This function takes a GDAL SpatialReference system and adds its information - to the `spatial_ref_sys` table of the spatial backend. Doing this enables - database-level spatial transformations for the backend. Thus, this utility - is useful for adding spatial reference systems not included by default with - the backend -- for example, the so-called "Google Maps Mercator Projection" - is excluded in PostGIS 1.3 and below, and the following adds it to the - `spatial_ref_sys` table: - - >>> from django.contrib.gis.utils import add_srs_entry - >>> add_srs_entry(900913) - - Keyword Arguments: - auth_name: - This keyword may be customized with the value of the `auth_name` field. - Defaults to 'EPSG'. - - auth_srid: - This keyword may be customized with the value of the `auth_srid` field. - Defaults to the SRID determined by GDAL. - - ref_sys_name: - For SpatiaLite users only, sets the value of the the `ref_sys_name` field. - Defaults to the name determined by GDAL. - - database: - The name of the database connection to use; the default is the value - of `django.db.DEFAULT_DB_ALIAS` (at the time of this writing, it's value - is 'default'). - """ - connection = connections[database] - if not hasattr(connection.ops, 'spatial_version'): - raise Exception('The `add_srs_entry` utility only works ' - 'with spatial backends.') - if connection.ops.oracle or connection.ops.mysql: - raise Exception('This utility does not support the ' - 'Oracle or MySQL spatial backends.') - SpatialRefSys = connection.ops.spatial_ref_sys() - - # If argument is not a `SpatialReference` instance, use it as parameter - # to construct a `SpatialReference` instance. - if not isinstance(srs, SpatialReference): - srs = SpatialReference(srs) - - if srs.srid is None: - raise Exception('Spatial reference requires an SRID to be ' - 'compatible with the spatial backend.') - - # Initializing the keyword arguments dictionary for both PostGIS - # and SpatiaLite. - kwargs = {'srid' : srs.srid, - 'auth_name' : auth_name, - 'auth_srid' : auth_srid or srs.srid, - 'proj4text' : srs.proj4, - } - - # Backend-specific fields for the SpatialRefSys model. - if connection.ops.postgis: - kwargs['srtext'] = srs.wkt - if connection.ops.spatialite: - kwargs['ref_sys_name'] = ref_sys_name or srs.name - - # Creating the spatial_ref_sys model. - try: - # Try getting via SRID only, because using all kwargs may - # differ from exact wkt/proj in database. - sr = SpatialRefSys.objects.get(srid=srs.srid) - except SpatialRefSys.DoesNotExist: - sr = SpatialRefSys.objects.create(**kwargs) - -# Alias is for backwards-compatibility purposes. -add_postgis_srs = add_srs_entry diff --git a/parts/django/django/contrib/gis/utils/wkt.py b/parts/django/django/contrib/gis/utils/wkt.py deleted file mode 100644 index 4aecc62..0000000 --- a/parts/django/django/contrib/gis/utils/wkt.py +++ /dev/null @@ -1,55 +0,0 @@ -""" - Utilities for manipulating Geometry WKT. -""" - -def precision_wkt(geom, prec): - """ - Returns WKT text of the geometry according to the given precision (an - integer or a string). If the precision is an integer, then the decimal - places of coordinates WKT will be truncated to that number: - - >>> pnt = Point(5, 23) - >>> pnt.wkt - 'POINT (5.0000000000000000 23.0000000000000000)' - >>> precision(geom, 1) - 'POINT (5.0 23.0)' - - If the precision is a string, it must be valid Python format string - (e.g., '%20.7f') -- thus, you should know what you're doing. - """ - if isinstance(prec, int): - num_fmt = '%%.%df' % prec - elif isinstance(prec, basestring): - num_fmt = prec - else: - raise TypeError - - # TODO: Support 3D geometries. - coord_fmt = ' '.join([num_fmt, num_fmt]) - - def formatted_coords(coords): - return ','.join([coord_fmt % c[:2] for c in coords]) - - def formatted_poly(poly): - return ','.join(['(%s)' % formatted_coords(r) for r in poly]) - - def formatted_geom(g): - gtype = str(g.geom_type).upper() - yield '%s(' % gtype - if gtype == 'POINT': - yield formatted_coords((g.coords,)) - elif gtype in ('LINESTRING', 'LINEARRING'): - yield formatted_coords(g.coords) - elif gtype in ('POLYGON', 'MULTILINESTRING'): - yield formatted_poly(g) - elif gtype == 'MULTIPOINT': - yield formatted_coords(g.coords) - elif gtype == 'MULTIPOLYGON': - yield ','.join(['(%s)' % formatted_poly(p) for p in g]) - elif gtype == 'GEOMETRYCOLLECTION': - yield ','.join([''.join([wkt for wkt in formatted_geom(child)]) for child in g]) - else: - raise TypeError - yield ')' - - return ''.join([wkt for wkt in formatted_geom(geom)]) |