mirror of
https://github.com/django/django.git
synced 2025-03-31 19:46:42 +00:00
Applied DRY and centralized geometry input regular expressions; OGRGeometry
may now consume and output EWKT.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12302 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
f9f04a49e8
commit
25f47bbbb6
@ -39,7 +39,7 @@
|
|||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
# Python library requisites.
|
# Python library requisites.
|
||||||
import re, sys
|
import sys
|
||||||
from binascii import a2b_hex
|
from binascii import a2b_hex
|
||||||
from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p
|
from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p
|
||||||
|
|
||||||
@ -54,16 +54,14 @@ from django.contrib.gis.gdal.srs import SpatialReference, CoordTransform
|
|||||||
from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
|
from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
|
||||||
GEOJSON = capi.GEOJSON
|
GEOJSON = capi.GEOJSON
|
||||||
|
|
||||||
|
# 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:
|
# For more information, see the OGR C API source code:
|
||||||
# http://www.gdal.org/ogr/ogr__api_8h.html
|
# http://www.gdal.org/ogr/ogr__api_8h.html
|
||||||
#
|
#
|
||||||
# The OGR_G_* routines are relevant here.
|
# The OGR_G_* routines are relevant here.
|
||||||
|
|
||||||
# Regular expressions for recognizing HEXEWKB and WKT.
|
|
||||||
hex_regex = re.compile(r'^[0-9A-F]+$', re.I)
|
|
||||||
wkt_regex = re.compile(r'^(?P<type>POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+$', re.I)
|
|
||||||
json_regex = re.compile(r'^(\s+)?\{[\s\w,\[\]\{\}\-\."\':]+\}(\s+)?$')
|
|
||||||
|
|
||||||
#### OGRGeometry Class ####
|
#### OGRGeometry Class ####
|
||||||
class OGRGeometry(GDALBase):
|
class OGRGeometry(GDALBase):
|
||||||
"Generally encapsulates an OGR geometry."
|
"Generally encapsulates an OGR geometry."
|
||||||
@ -88,13 +86,16 @@ class OGRGeometry(GDALBase):
|
|||||||
wkt_m = wkt_regex.match(geom_input)
|
wkt_m = wkt_regex.match(geom_input)
|
||||||
json_m = json_regex.match(geom_input)
|
json_m = json_regex.match(geom_input)
|
||||||
if wkt_m:
|
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':
|
if wkt_m.group('type').upper() == 'LINEARRING':
|
||||||
# OGR_G_CreateFromWkt doesn't work with LINEARRING WKT.
|
# OGR_G_CreateFromWkt doesn't work with LINEARRING WKT.
|
||||||
# See http://trac.osgeo.org/gdal/ticket/1992.
|
# See http://trac.osgeo.org/gdal/ticket/1992.
|
||||||
g = capi.create_geom(OGRGeomType(wkt_m.group('type')).num)
|
g = capi.create_geom(OGRGeomType(wkt_m.group('type')).num)
|
||||||
capi.import_wkt(g, byref(c_char_p(geom_input)))
|
capi.import_wkt(g, byref(c_char_p(wkt_m.group('wkt'))))
|
||||||
else:
|
else:
|
||||||
g = capi.from_wkt(byref(c_char_p(geom_input)), None, byref(c_void_p()))
|
g = capi.from_wkt(byref(c_char_p(wkt_m.group('wkt'))), None, byref(c_void_p()))
|
||||||
elif json_m:
|
elif json_m:
|
||||||
if GEOJSON:
|
if GEOJSON:
|
||||||
g = capi.from_json(geom_input)
|
g = capi.from_json(geom_input)
|
||||||
@ -341,6 +342,15 @@ class OGRGeometry(GDALBase):
|
|||||||
"Returns the WKT representation of the Geometry."
|
"Returns the WKT representation of the Geometry."
|
||||||
return capi.to_wkt(self.ptr, byref(c_char_p()))
|
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 ####
|
#### Geometry Methods ####
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Clones this OGR Geometry."
|
"Clones this OGR Geometry."
|
||||||
|
@ -59,6 +59,17 @@ class OGRGeomTest(unittest.TestCase):
|
|||||||
geom = OGRGeometry(g.wkt)
|
geom = OGRGeometry(g.wkt)
|
||||||
self.assertEqual(g.wkt, geom.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):
|
def test01b_gml(self):
|
||||||
"Testing GML output."
|
"Testing GML output."
|
||||||
for g in wkt_out:
|
for g in wkt_out:
|
||||||
|
12
django/contrib/gis/geometry/regex.py
Normal file
12
django/contrib/gis/geometry/regex.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
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+)?$')
|
@ -25,11 +25,8 @@ from django.contrib.gis.geos import prototypes as capi
|
|||||||
# of their corresponding GEOS I/O class.
|
# 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
|
from django.contrib.gis.geos.prototypes.io import wkt_r, wkt_w, wkb_r, wkb_w, ewkb_w, ewkb_w3d
|
||||||
|
|
||||||
# Regular expression for recognizing HEXEWKB and WKT. A prophylactic measure
|
# For recognizing geometry input.
|
||||||
# to prevent potentially malicious input from reaching the underlying C
|
from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex
|
||||||
# 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+);)?(?P<wkt>(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+)$', re.I)
|
|
||||||
|
|
||||||
class GEOSGeometry(GEOSBase, ListMixin):
|
class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
"A class that, generally, encapsulates a GEOS geometry."
|
"A class that, generally, encapsulates a GEOS geometry."
|
||||||
@ -69,7 +66,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
|||||||
elif hex_regex.match(geo_input):
|
elif hex_regex.match(geo_input):
|
||||||
# Handling HEXEWKB input.
|
# Handling HEXEWKB input.
|
||||||
g = wkb_r().read(geo_input)
|
g = wkb_r().read(geo_input)
|
||||||
elif gdal.GEOJSON and gdal.geometries.json_regex.match(geo_input):
|
elif gdal.GEOJSON and json_regex.match(geo_input):
|
||||||
# Handling GeoJSON input.
|
# Handling GeoJSON input.
|
||||||
g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb)
|
g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb)
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user