mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
gis: Added beginnings of django.contrib.gis.
Changed ManyToManyField to provide get_internal_type() -> 'NoField'. GIS fields use NoField? and new _post_create_sql for AddGeometryColumn. git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@4674 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5514d87319
commit
5edcbdc826
71
django/contrib/gis/__init__.py
Normal file
71
django/contrib/gis/__init__.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
from geos import geomFromWKT, geomToWKT
|
||||||
|
from decimal import Decimal
|
||||||
|
from django.db import models
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
|
|
||||||
|
class GeoQuerySet(QuerySet):
|
||||||
|
# The list of valid query terms
|
||||||
|
# override the local QUERY_TERMS in the namespace
|
||||||
|
# not sure how to do that locals() hackery
|
||||||
|
# possibly in the init change its locals() variables
|
||||||
|
# not sure if that will work
|
||||||
|
|
||||||
|
QUERY_TERMS = (
|
||||||
|
'exact', 'iexact', 'contains', 'icontains', 'overlaps',
|
||||||
|
'gt', 'gte', 'lt', 'lte', 'in',
|
||||||
|
'startswith', 'istartswith', 'endswith', 'iendswith',
|
||||||
|
'range', 'year', 'month', 'day', 'isnull', 'search',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def dprint(arg):
|
||||||
|
import re
|
||||||
|
import inspect
|
||||||
|
print re.match("^\s*dprint\(\s*(.+)\s*\)", inspect.stack()[1][4][0]).group(1) + ": " + repr(arg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class GeometryManager(models.Manager):
|
||||||
|
#def filter(self, *args, **kwargs):
|
||||||
|
# super(Manager, self).filter(*args, **kwargs)
|
||||||
|
# return self.get_query_set().filter(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_query_set(self):
|
||||||
|
return GeoQuerySet(self.model)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BoundingBox:
|
||||||
|
|
||||||
|
def _geom(self):
|
||||||
|
return geomToWKT(self._g)
|
||||||
|
|
||||||
|
geom = property(_geom)
|
||||||
|
|
||||||
|
def _area(self):
|
||||||
|
return self._g.area()
|
||||||
|
|
||||||
|
area = property(_area)
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, ne, sw):
|
||||||
|
"""
|
||||||
|
Create a bounding box using two points
|
||||||
|
This points come from a JSON request, so they are strings
|
||||||
|
"""
|
||||||
|
ne = [Decimal(i.strip(' ')) for i in ne[1:-1].split(',')]
|
||||||
|
sw = [Decimal(i.strip(' ')) for i in sw[1:-1].split(',')]
|
||||||
|
ne_lat = ne[0]
|
||||||
|
ne_lng = ne[1]
|
||||||
|
sw_lat = sw[0]
|
||||||
|
sw_lng = sw[1]
|
||||||
|
bb = 'POLYGON(('
|
||||||
|
bb += str(ne_lng) + " " + str(ne_lat) + ","
|
||||||
|
bb += str(ne_lng) + " " + str(sw_lat) + ","
|
||||||
|
bb += str(sw_lng) + " " + str(sw_lat) + ","
|
||||||
|
bb += str(sw_lng) + " " + str(ne_lat) + ","
|
||||||
|
bb += str(ne_lng) + " " + str(ne_lat)
|
||||||
|
bb += '))'
|
||||||
|
self._g = geomFromWKT(bb)
|
0
django/contrib/gis/db/__init__.py
Normal file
0
django/contrib/gis/db/__init__.py
Normal file
0
django/contrib/gis/db/models/__init__.py
Normal file
0
django/contrib/gis/db/models/__init__.py
Normal file
72
django/contrib/gis/db/models/fields/__init__.py
Normal file
72
django/contrib/gis/db/models/fields/__init__.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from django.db import models
|
||||||
|
from django.db.models.fields import Field
|
||||||
|
#from GeoTypes import Point
|
||||||
|
|
||||||
|
# Creates the SQL to add the model to the database. Defaults to using an
|
||||||
|
# SRID of 4326 (WGS84 Datum -- 'normal' lat/lon coordinates)
|
||||||
|
def _add_geom(geom, srid, style, model, field, dim=2):
|
||||||
|
from django.db import backend
|
||||||
|
|
||||||
|
# Constructing the AddGeometryColumn(...) command -- the style
|
||||||
|
# object is passed in from the management module and is used
|
||||||
|
# to syntax highlight the command for 'sqlall'
|
||||||
|
sql = style.SQL_KEYWORD('SELECT ') + \
|
||||||
|
style.SQL_TABLE('AddGeometryColumn') + "('" + \
|
||||||
|
style.SQL_TABLE(model) + "', '" + \
|
||||||
|
style.SQL_FIELD(field) + "', " + \
|
||||||
|
style.SQL_FIELD(str(srid)) + ", '" + \
|
||||||
|
style.SQL_KEYWORD(geom) + "', " + \
|
||||||
|
style.SQL_KEYWORD(str(dim)) + \
|
||||||
|
');'
|
||||||
|
return sql
|
||||||
|
|
||||||
|
class GeometryField(Field):
|
||||||
|
"""The base GIS field -- maps to an OpenGIS Geometry type."""
|
||||||
|
|
||||||
|
_geom = 'GEOMETRY'
|
||||||
|
_srid = 4326
|
||||||
|
|
||||||
|
def _post_create_sql(self, *args, **kwargs):
|
||||||
|
"""Returns SQL that will be executed after the model has been created. Geometry
|
||||||
|
columns must be added after creation with the PostGIS AddGeometryColumn() function."""
|
||||||
|
return _add_geom(self._geom, self._srid, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_db_prep_lookup(self, lookup_type, value):
|
||||||
|
"Returns field's value prepared for database lookup."
|
||||||
|
if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'month', 'day', 'search', 'overlaps'):
|
||||||
|
return [value]
|
||||||
|
elif lookup_type in ('range', 'in'):
|
||||||
|
return value
|
||||||
|
elif lookup_type in ('contains', 'icontains'):
|
||||||
|
return ["%%%s%%" % prep_for_like_query(value)]
|
||||||
|
elif lookup_type == 'iexact':
|
||||||
|
return [prep_for_like_query(value)]
|
||||||
|
elif lookup_type in ('startswith', 'istartswith'):
|
||||||
|
return ["%s%%" % prep_for_like_query(value)]
|
||||||
|
elif lookup_type in ('endswith', 'iendswith'):
|
||||||
|
return ["%%%s" % prep_for_like_query(value)]
|
||||||
|
elif lookup_type == 'isnull':
|
||||||
|
return []
|
||||||
|
elif lookup_type == 'year':
|
||||||
|
try:
|
||||||
|
value = int(value)
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError("The __year lookup type requires an integer argument")
|
||||||
|
return ['%s-01-01 00:00:00' % value, '%s-12-31 23:59:59.999999' % value]
|
||||||
|
raise TypeError("Field has invalid lookup: %s" % lookup_type)
|
||||||
|
|
||||||
|
def get_db_prep_save(self, value):
|
||||||
|
return 'SRID=%d;%s' % (self._srid, value)
|
||||||
|
|
||||||
|
|
||||||
|
class PointField(GeometryField):
|
||||||
|
_geom = 'POINT'
|
||||||
|
|
||||||
|
class PolygonField(GeometryField):
|
||||||
|
_geom = 'POLYGON'
|
||||||
|
|
||||||
|
class MultiPolygonField(GeometryField):
|
||||||
|
_geom = 'MULTIPOLYGON'
|
||||||
|
|
||||||
|
class GeometryManager(models.Manager):
|
||||||
|
pass
|
@ -386,6 +386,10 @@ def get_custom_sql_for_model(model):
|
|||||||
output.append(statement + ";")
|
output.append(statement + ";")
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
|
for f in opts.fields:
|
||||||
|
if hasattr(f, '_post_create_sql'):
|
||||||
|
output.append(f._post_create_sql(style, model._meta.db_table, f.column))
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def get_custom_sql(app):
|
def get_custom_sql(app):
|
||||||
|
@ -11,7 +11,6 @@ DATA_TYPES = {
|
|||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'int',
|
'IntegerField': 'int',
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'ManyToManyField': None,
|
|
||||||
'NullBooleanField': 'bit',
|
'NullBooleanField': 'bit',
|
||||||
'OneToOneField': 'int',
|
'OneToOneField': 'int',
|
||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
@ -22,4 +21,5 @@ DATA_TYPES = {
|
|||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
|
'NoField': None,
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ DATA_TYPES = {
|
|||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'ManyToManyField': None,
|
|
||||||
'NullBooleanField': 'bool',
|
'NullBooleanField': 'bool',
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
@ -26,4 +25,5 @@ DATA_TYPES = {
|
|||||||
'TextField': 'longtext',
|
'TextField': 'longtext',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
|
'NoField': None,
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ DATA_TYPES = {
|
|||||||
'ImageField': 'varchar2(100)',
|
'ImageField': 'varchar2(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'ManyToManyField': None,
|
|
||||||
'NullBooleanField': 'integer',
|
'NullBooleanField': 'integer',
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
@ -22,4 +21,5 @@ DATA_TYPES = {
|
|||||||
'TextField': 'long',
|
'TextField': 'long',
|
||||||
'TimeField': 'timestamp',
|
'TimeField': 'timestamp',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
|
'NoField': None,
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ DATA_TYPES = {
|
|||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
'IPAddressField': 'inet',
|
'IPAddressField': 'inet',
|
||||||
'ManyToManyField': None,
|
|
||||||
'NullBooleanField': 'boolean',
|
'NullBooleanField': 'boolean',
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
@ -26,4 +25,5 @@ DATA_TYPES = {
|
|||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
|
'NoField': None,
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ DATA_TYPES = {
|
|||||||
'ImageField': 'varchar(100)',
|
'ImageField': 'varchar(100)',
|
||||||
'IntegerField': 'integer',
|
'IntegerField': 'integer',
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'ManyToManyField': None,
|
|
||||||
'NullBooleanField': 'bool',
|
'NullBooleanField': 'bool',
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PhoneNumberField': 'varchar(20)',
|
'PhoneNumberField': 'varchar(20)',
|
||||||
@ -25,4 +24,5 @@ DATA_TYPES = {
|
|||||||
'TextField': 'text',
|
'TextField': 'text',
|
||||||
'TimeField': 'time',
|
'TimeField': 'time',
|
||||||
'USStateField': 'varchar(2)',
|
'USStateField': 'varchar(2)',
|
||||||
|
'NoField': None,
|
||||||
}
|
}
|
||||||
|
@ -644,6 +644,9 @@ class ManyToManyField(RelatedField, Field):
|
|||||||
msg = gettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.')
|
msg = gettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.')
|
||||||
self.help_text = string_concat(self.help_text, ' ', msg)
|
self.help_text = string_concat(self.help_text, ' ', msg)
|
||||||
|
|
||||||
|
def get_internal_type(self):
|
||||||
|
return "NoField"
|
||||||
|
|
||||||
def get_manipulator_field_objs(self):
|
def get_manipulator_field_objs(self):
|
||||||
if self.rel.raw_id_admin:
|
if self.rel.raw_id_admin:
|
||||||
return [oldforms.RawIdAdminField]
|
return [oldforms.RawIdAdminField]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user