Permalink
Browse files

Merged the gis branch into trunk.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8219 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent d0f57e7 commit 79e68c225b926302ebb29c808dda8afa49856f5c @jbronn jbronn committed Aug 5, 2008
Showing with 14,939 additions and 0 deletions.
  1. BIN django/contrib/admin/media/img/gis/move_vertex_off.png
  2. BIN django/contrib/admin/media/img/gis/move_vertex_on.png
  3. 0 django/contrib/gis/__init__.py
  4. +12 −0 django/contrib/gis/admin/__init__.py
  5. +128 −0 django/contrib/gis/admin/options.py
  6. +92 −0 django/contrib/gis/admin/widgets.py
  7. 0 django/contrib/gis/db/__init__.py
  8. +18 −0 django/contrib/gis/db/backend/__init__.py
  9. +14 −0 django/contrib/gis/db/backend/adaptor.py
  10. +29 −0 django/contrib/gis/db/backend/base.py
  11. +13 −0 django/contrib/gis/db/backend/mysql/__init__.py
  12. +5 −0 django/contrib/gis/db/backend/mysql/creation.py
  13. +53 −0 django/contrib/gis/db/backend/mysql/field.py
  14. +59 −0 django/contrib/gis/db/backend/mysql/query.py
  15. +31 −0 django/contrib/gis/db/backend/oracle/__init__.py
  16. +5 −0 django/contrib/gis/db/backend/oracle/adaptor.py
  17. +8 −0 django/contrib/gis/db/backend/oracle/creation.py
  18. +103 −0 django/contrib/gis/db/backend/oracle/field.py
  19. +49 −0 django/contrib/gis/db/backend/oracle/models.py
  20. +154 −0 django/contrib/gis/db/backend/oracle/query.py
  21. +42 −0 django/contrib/gis/db/backend/postgis/__init__.py
  22. +33 −0 django/contrib/gis/db/backend/postgis/adaptor.py
  23. +224 −0 django/contrib/gis/db/backend/postgis/creation.py
  24. +95 −0 django/contrib/gis/db/backend/postgis/field.py
  25. +54 −0 django/contrib/gis/db/backend/postgis/management.py
  26. +58 −0 django/contrib/gis/db/backend/postgis/models.py
  27. +287 −0 django/contrib/gis/db/backend/postgis/query.py
  28. +52 −0 django/contrib/gis/db/backend/util.py
  29. +17 −0 django/contrib/gis/db/models/__init__.py
  30. +214 −0 django/contrib/gis/db/models/fields/__init__.py
  31. +82 −0 django/contrib/gis/db/models/manager.py
  32. +11 −0 django/contrib/gis/db/models/mixin.py
  33. +62 −0 django/contrib/gis/db/models/proxy.py
  34. +617 −0 django/contrib/gis/db/models/query.py
  35. +2 −0 django/contrib/gis/db/models/sql/__init__.py
  36. +327 −0 django/contrib/gis/db/models/sql/query.py
  37. +64 −0 django/contrib/gis/db/models/sql/where.py
  38. +1 −0 django/contrib/gis/forms/__init__.py
  39. +37 −0 django/contrib/gis/forms/fields.py
  40. +28 −0 django/contrib/gis/gdal/LICENSE
  41. +51 −0 django/contrib/gis/gdal/__init__.py
  42. +138 −0 django/contrib/gis/gdal/datasource.py
  43. +66 −0 django/contrib/gis/gdal/driver.py
  44. +134 −0 django/contrib/gis/gdal/envelope.py
  45. +41 −0 django/contrib/gis/gdal/error.py
  46. +115 −0 django/contrib/gis/gdal/feature.py
  47. +179 −0 django/contrib/gis/gdal/field.py
  48. +643 −0 django/contrib/gis/gdal/geometries.py
  49. +73 −0 django/contrib/gis/gdal/geomtype.py
  50. +187 −0 django/contrib/gis/gdal/layer.py
  51. +83 −0 django/contrib/gis/gdal/libgdal.py
  52. 0 django/contrib/gis/gdal/prototypes/__init__.py
  53. +68 −0 django/contrib/gis/gdal/prototypes/ds.py
  54. +125 −0 django/contrib/gis/gdal/prototypes/errcheck.py
  55. +116 −0 django/contrib/gis/gdal/prototypes/generation.py
  56. +109 −0 django/contrib/gis/gdal/prototypes/geom.py
  57. +71 −0 django/contrib/gis/gdal/prototypes/srs.py
  58. +360 −0 django/contrib/gis/gdal/srs.py
  59. +27 −0 django/contrib/gis/geos/LICENSE
  60. +69 −0 django/contrib/gis/geos/__init__.py
  61. +608 −0 django/contrib/gis/geos/base.py
  62. +105 −0 django/contrib/gis/geos/collections.py
  63. +164 −0 django/contrib/gis/geos/coordseq.py
  64. +20 −0 django/contrib/gis/geos/error.py
  65. +391 −0 django/contrib/gis/geos/geometries.py
  66. +126 −0 django/contrib/gis/geos/libgeos.py
  67. +33 −0 django/contrib/gis/geos/prototypes/__init__.py
  68. +82 −0 django/contrib/gis/geos/prototypes/coordseq.py
  69. +76 −0 django/contrib/gis/geos/prototypes/errcheck.py
  70. +111 −0 django/contrib/gis/geos/prototypes/geom.py
  71. +27 −0 django/contrib/gis/geos/prototypes/misc.py
  72. +43 −0 django/contrib/gis/geos/prototypes/predicates.py
  73. +35 −0 django/contrib/gis/geos/prototypes/topology.py
  74. 0 django/contrib/gis/management/__init__.py
  75. +15 −0 django/contrib/gis/management/base.py
  76. 0 django/contrib/gis/management/commands/__init__.py
  77. +190 −0 django/contrib/gis/management/commands/inspectdb.py
  78. +119 −0 django/contrib/gis/management/commands/ogrinspect.py
  79. 0 django/contrib/gis/maps/__init__.py
  80. +61 −0 django/contrib/gis/maps/google/__init__.py
  81. +138 −0 django/contrib/gis/maps/google/gmap.py
  82. +220 −0 django/contrib/gis/maps/google/overlays.py
  83. +164 −0 django/contrib/gis/maps/google/zoom.py
  84. 0 django/contrib/gis/maps/openlayers/__init__.py
  85. +329 −0 django/contrib/gis/measure.py
  86. +284 −0 django/contrib/gis/models.py
  87. +29 −0 django/contrib/gis/oldforms/__init__.py
  88. +12 −0 django/contrib/gis/shortcuts.py
  89. +55 −0 django/contrib/gis/sitemaps.py
  90. +37 −0 django/contrib/gis/templates/gis/admin/openlayers.html
  91. +157 −0 django/contrib/gis/templates/gis/admin/openlayers.js
  92. +2 −0 django/contrib/gis/templates/gis/admin/osm.html
  93. +2 −0 django/contrib/gis/templates/gis/admin/osm.js
  94. +34 −0 django/contrib/gis/templates/gis/google/js/google-map.js
  95. +6 −0 django/contrib/gis/templates/gis/kml/base.kml
  96. +8 −0 django/contrib/gis/templates/gis/kml/placemarks.kml
  97. +148 −0 django/contrib/gis/tests/__init__.py
  98. BIN django/contrib/gis/tests/data/test_point/test_point.dbf
  99. +1 −0 django/contrib/gis/tests/data/test_point/test_point.prj
  100. BIN django/contrib/gis/tests/data/test_point/test_point.shp
  101. BIN django/contrib/gis/tests/data/test_point/test_point.shx
  102. BIN django/contrib/gis/tests/data/test_poly/test_poly.dbf
  103. +1 −0 django/contrib/gis/tests/data/test_poly/test_poly.prj
  104. BIN django/contrib/gis/tests/data/test_poly/test_poly.shp
  105. BIN django/contrib/gis/tests/data/test_poly/test_poly.shx
  106. +4 −0 django/contrib/gis/tests/data/test_vrt/test_vrt.csv
  107. +7 −0 django/contrib/gis/tests/data/test_vrt/test_vrt.vrt
  108. 0 django/contrib/gis/tests/distapp/__init__.py
  109. +33 −0 django/contrib/gis/tests/distapp/data.py
  110. +42 −0 django/contrib/gis/tests/distapp/models.py
  111. +296 −0 django/contrib/gis/tests/distapp/tests.py
  112. 0 django/contrib/gis/tests/geoapp/__init__.py
  113. +33 −0 django/contrib/gis/tests/geoapp/models.py
  114. +8 −0 django/contrib/gis/tests/geoapp/sql/city.mysql.sql
  115. +8 −0 django/contrib/gis/tests/geoapp/sql/city.oracle.sql
  116. +8 −0 django/contrib/gis/tests/geoapp/sql/city.postgresql_psycopg2.sql
  117. +1 −0 django/contrib/gis/tests/geoapp/sql/co.wkt
  118. +4 −0 django/contrib/gis/tests/geoapp/sql/country.mysql.sql
  119. +4 −0 django/contrib/gis/tests/geoapp/sql/country.postgresql_psycopg2.sql
  120. +1 −0 django/contrib/gis/tests/geoapp/sql/ks.wkt
  121. +1 −0 django/contrib/gis/tests/geoapp/sql/nz.wkt
  122. +5 −0 django/contrib/gis/tests/geoapp/sql/state.mysql.sql
  123. +5 −0 django/contrib/gis/tests/geoapp/sql/state.postgresql_psycopg2.sql
  124. +1 −0 django/contrib/gis/tests/geoapp/sql/tx.wkt
  125. +564 −0 django/contrib/gis/tests/geoapp/tests.py
  126. +179 −0 django/contrib/gis/tests/geoapp/tests_mysql.py
  127. +157 −0 django/contrib/gis/tests/geometries.py
  128. 0 django/contrib/gis/tests/layermap/__init__.py
  129. BIN django/contrib/gis/tests/layermap/cities/cities.dbf
  130. +1 −0 django/contrib/gis/tests/layermap/cities/cities.prj
  131. BIN django/contrib/gis/tests/layermap/cities/cities.shp
  132. BIN django/contrib/gis/tests/layermap/cities/cities.shx
  133. BIN django/contrib/gis/tests/layermap/counties/counties.dbf
  134. BIN django/contrib/gis/tests/layermap/counties/counties.shp
  135. BIN django/contrib/gis/tests/layermap/counties/counties.shx
  136. BIN django/contrib/gis/tests/layermap/interstates/interstates.dbf
  137. +1 −0 django/contrib/gis/tests/layermap/interstates/interstates.prj
  138. BIN django/contrib/gis/tests/layermap/interstates/interstates.shp
  139. BIN django/contrib/gis/tests/layermap/interstates/interstates.shx
  140. +52 −0 django/contrib/gis/tests/layermap/models.py
  141. +249 −0 django/contrib/gis/tests/layermap/tests.py
  142. 0 django/contrib/gis/tests/relatedapp/__init__.py
  143. +12 −0 django/contrib/gis/tests/relatedapp/models.py
  144. +98 −0 django/contrib/gis/tests/relatedapp/tests.py
  145. +1 −0 django/contrib/gis/tests/relatedapp/tests_mysql.py
  146. +28 −0 django/contrib/gis/tests/test_gdal.py
  147. +40 −0 django/contrib/gis/tests/test_gdal_driver.py
  148. +181 −0 django/contrib/gis/tests/test_gdal_ds.py
  149. +45 −0 django/contrib/gis/tests/test_gdal_envelope.py
  150. +403 −0 django/contrib/gis/tests/test_gdal_geom.py
  151. +169 −0 django/contrib/gis/tests/test_gdal_srs.py
  152. +104 −0 django/contrib/gis/tests/test_geoip.py
  153. +775 −0 django/contrib/gis/tests/test_geos.py
  154. +333 −0 django/contrib/gis/tests/test_measure.py
  155. +90 −0 django/contrib/gis/tests/test_spatialrefsys.py
  156. +22 −0 django/contrib/gis/tests/utils.py
  157. +25 −0 django/contrib/gis/utils/__init__.py
  158. +344 −0 django/contrib/gis/utils/geoip.py
  159. +677 −0 django/contrib/gis/utils/layermapping.py
  160. +53 −0 django/contrib/gis/utils/ogrinfo.py
  161. +225 −0 django/contrib/gis/utils/ogrinspect.py
  162. +27 −0 django/contrib/gis/utils/srs.py
  163. +55 −0 django/contrib/gis/utils/wkt.py
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
No changes.
@@ -0,0 +1,12 @@
+# Getting the normal admin routines, classes, and `site` instance.
+from django.contrib.admin import autodiscover, site, 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
@@ -0,0 +1,128 @@
+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
+ admin_media_prefix = settings.ADMIN_MEDIA_PREFIX
+ map_width = 600
+ map_height = 400
+ map_srid = 4326
+ map_template = 'gis/admin/openlayers.html'
+ openlayers_url = 'http://openlayers.org/api/2.6/OpenLayers.js'
+ 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):
+ # 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 in ('MULTIPOINT', 'MULTILINESTRING', 'MULTIPOLYGON', 'GEOMETRYCOLLECTION')
+ if is_collection:
+ if db_field._geom == 'GEOMETRYCOLLECTION': collection_type = 'Any'
+ else: collection_type = OGRGeomType(db_field._geom.replace('MULTI', ''))
+ else:
+ collection_type = 'None'
+
+ class OLMap(self.widget):
+ template = self.map_template
+ geom_type = db_field._geom
+ params = {'admin_media_prefix' : self.admin_media_prefix,
+ '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),
+ 'field_name' : db_field.name,
+ 'is_collection' : is_collection,
+ 'scrollable' : self.scrollable,
+ 'layerswitcher' : self.layerswitcher,
+ 'collection_type' : collection_type,
+ 'is_linestring' : db_field._geom in ('LINESTRING', 'MULTILINESTRING'),
+ 'is_polygon' : db_field._geom in ('POLYGON', 'MULTIPOLYGON'),
+ 'is_point' : db_field._geom 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,
+ '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
+
+# Using the Beta OSM in the admin requires the following:
+# (1) The Google Maps Mercator projection needs to be added
+# to your `spatial_ref_sys` table. You'll need at least GDAL 1.5:
+# >>> from django.contrib.gis.gdal import SpatialReference
+# >>> from django.contrib.gis.utils import add_postgis_srs
+# >>> add_postgis_srs(SpatialReference(900913)) # Adding the Google Projection
+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
+ units = 'm'
@@ -0,0 +1,92 @@
+from django.contrib.gis.gdal import OGRException
+from django.contrib.gis.geos import GEOSGeometry, GEOSException
+from django.forms.widgets import Textarea
+from django.template.loader import render_to_string
+
+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
+ # interfaace 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 ID of
+ # the GeometryField (passed in via the `attrs` keyword).
+ self.params['module'] = 'geodjango_%s' % self.params['field_name']
+
+ if value:
+ # Transforming the geometry to the projection used on the
+ # OpenLayers map.
+ srid = self.params['srid']
+ if value.srid != srid:
+ try:
+ value.transform(srid)
+ wkt = value.wkt
+ except OGRException:
+ wkt = ''
+ else:
+ wkt = value.wkt
+
+ # Setting the parameter WKT with that of the transformed
+ # geometry.
+ self.params['wkt'] = wkt
+
+ return render_to_string(self.template, self.params)
+
+ 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
No changes.
@@ -0,0 +1,18 @@
+"""
+ This module provides the backend for spatial SQL construction with Django.
+
+ Specifically, this module will import the correct routines and modules
+ needed for GeoDjango to interface with the spatial database.
+"""
+from django.conf import settings
+from django.contrib.gis.db.backend.util import gqn
+
+# Retrieving the necessary settings from the backend.
+if settings.DATABASE_ENGINE == 'postgresql_psycopg2':
+ from django.contrib.gis.db.backend.postgis import create_spatial_db, get_geo_where_clause, SpatialBackend
+elif settings.DATABASE_ENGINE == 'oracle':
+ from django.contrib.gis.db.backend.oracle import create_spatial_db, get_geo_where_clause, SpatialBackend
+elif settings.DATABASE_ENGINE == 'mysql':
+ from django.contrib.gis.db.backend.mysql import create_spatial_db, get_geo_where_clause, SpatialBackend
+else:
+ raise NotImplementedError('No Geographic Backend exists for %s' % settings.DATABASE_ENGINE)
@@ -0,0 +1,14 @@
+class WKTAdaptor(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
@@ -0,0 +1,29 @@
+"""
+ This module holds the base `SpatialBackend` object, which is
+ instantiated by each spatial backend with the features it has.
+"""
+# TODO: Create a `Geometry` protocol and allow user to use
+# different Geometry objects -- for now we just use GEOSGeometry.
+from django.contrib.gis.geos import GEOSGeometry, GEOSException
+
+class BaseSpatialBackend(object):
+ Geometry = GEOSGeometry
+ GeometryException = GEOSException
+
+ def __init__(self, **kwargs):
+ kwargs.setdefault('distance_functions', {})
+ kwargs.setdefault('limited_where', {})
+ for k, v in kwargs.iteritems(): setattr(self, k, v)
+
+ def __getattr__(self, name):
+ """
+ All attributes of the spatial backend return False by default.
+ """
+ try:
+ return self.__dict__[name]
+ except KeyError:
+ return False
+
+
+
+
@@ -0,0 +1,13 @@
+__all__ = ['create_spatial_db', 'get_geo_where_clause', 'SpatialBackend']
+
+from django.contrib.gis.db.backend.base import BaseSpatialBackend
+from django.contrib.gis.db.backend.adaptor import WKTAdaptor
+from django.contrib.gis.db.backend.mysql.creation import create_spatial_db
+from django.contrib.gis.db.backend.mysql.field import MySQLGeoField
+from django.contrib.gis.db.backend.mysql.query import *
+
+SpatialBackend = BaseSpatialBackend(name='mysql', mysql=True,
+ gis_terms=MYSQL_GIS_TERMS,
+ select=GEOM_SELECT,
+ Adaptor=WKTAdaptor,
+ Field=MySQLGeoField)
@@ -0,0 +1,5 @@
+from django.test.utils import create_test_db
+
+def create_spatial_db(test=True, verbosity=1, autoclobber=False):
+ if not test: raise NotImplementedError('This uses `create_test_db` from test/utils.py')
+ create_test_db(verbosity, autoclobber)
@@ -0,0 +1,53 @@
+from django.db import connection
+from django.db.models.fields import Field # Django base Field class
+from django.contrib.gis.db.backend.mysql.query import GEOM_FROM_TEXT
+
+# Quotename & geographic quotename, respectively.
+qn = connection.ops.quote_name
+
+class MySQLGeoField(Field):
+ """
+ The backend-specific geographic field for MySQL.
+ """
+
+ def _geom_index(self, style, db_table):
+ """
+ Creates a spatial index for the geometry column. If MyISAM tables are
+ used an R-Tree index is created, otherwise a B-Tree index is created.
+ Thus, for best spatial performance, you should use MyISAM tables
+ (which do not support transactions). For more information, see Ch.
+ 16.6.1 of the MySQL 5.0 documentation.
+ """
+
+ # Getting the index name.
+ idx_name = '%s_%s_id' % (db_table, self.column)
+
+ sql = 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(self.column)) + ');'
+ return sql
+
+ def _post_create_sql(self, style, db_table):
+ """
+ Returns SQL that will be executed after the model has been
+ created.
+ """
+ # Getting the geometric index for this Geometry column.
+ if self._index:
+ return (self._geom_index(style, db_table),)
+ else:
+ return ()
+
+ def db_type(self):
+ "The OpenGIS name is returned for the MySQL database column type."
+ return self._geom
+
+ def get_placeholder(self, value):
+ """
+ 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.
+ """
+ return '%s(%%s)' % GEOM_FROM_TEXT
Oops, something went wrong.

0 comments on commit 79e68c2

Please sign in to comment.