diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py
index 866a852d49..fb686741c5 100644
--- a/django/contrib/gis/geos/geometry.py
+++ b/django/contrib/gis/geos/geometry.py
@@ -357,33 +357,49 @@ class GEOSGeometry(GEOSBase, ListMixin):
     #### Output Routines ####
     @property
     def ewkt(self):
-        "Returns the EWKT (WKT + SRID) of the Geometry."
+        """
+        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) of the Geometry."
+        "Returns the WKT (Well-Known Text) representation of this Geometry."
         return wkt_w.write(self)
 
     @property
     def hex(self):
         """
         Returns the HEX of the Geometry -- please note that the SRID is not
-        included in this representation, because the GEOS C library uses
-        -1 by default, even if the SRID is set.
+        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 HEXEWKB of this Geometry.  This is an extension of the WKB
+        specification that includes SRID and Z values taht are a part of this
+        geometry.
+        """
+        if self.hasz:
+            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: 
+        if gdal.GEOJSON:
             return self.ogr.json
         else:
             raise GEOSException('GeoJSON output only supported on GDAL 1.5+.')
@@ -391,9 +407,25 @@ class GEOSGeometry(GEOSBase, ListMixin):
 
     @property
     def wkb(self):
-        "Returns the WKB of the Geometry as a buffer."
+        """
+        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:
+            return ewkb_w3d.write(self)
+        else:
+            return ewkb_w.write(self)
+
     @property
     def kml(self):
         "Returns the KML representation of this Geometry."
@@ -617,7 +649,7 @@ GEOS_CLASSES = {0 : Point,
                 }
 
 # Similarly, import the GEOS I/O instances here to avoid conflicts.
-from django.contrib.gis.geos.io import wkt_r, wkt_w, wkb_r, wkb_w
+from django.contrib.gis.geos.io import wkt_r, wkt_w, wkb_r, wkb_w, ewkb_w, ewkb_w3d
 
 # If supported, import the PreparedGeometry class.
 if GEOS_PREPARE:
diff --git a/django/contrib/gis/geos/io.py b/django/contrib/gis/geos/io.py
index e5314c7911..2f895fbc2d 100644
--- a/django/contrib/gis/geos/io.py
+++ b/django/contrib/gis/geos/io.py
@@ -14,19 +14,19 @@ class IOBase(GEOSBase):
     "Base class for GEOS I/O objects."
     def __init__(self):
         # Getting the pointer with the constructor.
-        self.ptr = self.constructor()
+        self.ptr = self._constructor()
 
     def __del__(self):
         # Cleaning up with the appropriate destructor.
-        if self._ptr: self.destructor(self._ptr)
+        if self._ptr: self._destructor(self._ptr)
 
 ### WKT Reading and Writing objects ###
 
 # Non-public class for internal use because its `read` method returns
 # _pointers_ instead of a GEOSGeometry object.
 class _WKTReader(IOBase):
-    constructor = capi.wkt_reader_create
-    destructor = capi.wkt_reader_destroy
+    _constructor = capi.wkt_reader_create
+    _destructor = capi.wkt_reader_destroy
     ptr_type = capi.WKT_READ_PTR
 
     def read(self, wkt):
@@ -39,8 +39,8 @@ class WKTReader(_WKTReader):
         return GEOSGeometry(super(WKTReader, self).read(wkt))
 
 class WKTWriter(IOBase):
-    constructor = capi.wkt_writer_create
-    destructor = capi.wkt_writer_destroy
+    _constructor = capi.wkt_writer_create
+    _destructor = capi.wkt_writer_destroy
     ptr_type = capi.WKT_WRITE_PTR
 
     def write(self, geom):
@@ -51,8 +51,8 @@ class WKTWriter(IOBase):
 
 # Non-public class for the same reason as _WKTReader above.
 class _WKBReader(IOBase):
-    constructor = capi.wkb_reader_create
-    destructor = capi.wkb_reader_destroy
+    _constructor = capi.wkb_reader_create
+    _destructor = capi.wkb_reader_destroy
     ptr_type = capi.WKB_READ_PTR
 
     def read(self, wkb):
@@ -71,8 +71,8 @@ class WKBReader(_WKBReader):
         return GEOSGeometry(super(WKBReader, self).read(wkb))
 
 class WKBWriter(IOBase):
-    constructor = capi.wkb_writer_create
-    destructor = capi.wkb_writer_destroy
+    _constructor = capi.wkb_writer_create
+    _destructor = capi.wkb_writer_destroy
     ptr_type = capi.WKB_WRITE_PTR
 
     def write(self, geom):
@@ -121,3 +121,10 @@ wkt_r = _WKTReader()
 wkt_w = WKTWriter()
 wkb_r = _WKBReader()
 wkb_w = WKBWriter()
+
+# These instances are for writing EWKB in 2D and 3D.
+ewkb_w = WKBWriter()
+ewkb_w.srid = True
+ewkb_w3d = WKBWriter()
+ewkb_w3d.srid = True
+ewkb_w3d.outdim = 3
diff --git a/django/contrib/gis/geos/prototypes/geom.py b/django/contrib/gis/geos/prototypes/geom.py
index a177f0df9f..e3f2417cd2 100644
--- a/django/contrib/gis/geos/prototypes/geom.py
+++ b/django/contrib/gis/geos/prototypes/geom.py
@@ -62,17 +62,16 @@ def string_from_geom(func):
 
 ### ctypes prototypes ###
 
-# Deprecated creation routines from WKB, HEX, WKT
+# Deprecated creation and output routines from WKB, HEX, WKT
 from_hex = bin_constructor(lgeos.GEOSGeomFromHEX_buf)
 from_wkb = bin_constructor(lgeos.GEOSGeomFromWKB_buf)
 from_wkt = geom_output(lgeos.GEOSGeomFromWKT, [c_char_p])
 
-# Output routines
 to_hex = bin_output(lgeos.GEOSGeomToHEX_buf)
 to_wkb = bin_output(lgeos.GEOSGeomToWKB_buf)
 to_wkt = string_from_geom(lgeos.GEOSGeomToWKT)
 
-# The GEOS geometry type, typeid, num_coordites and number of geometries
+# The GEOS geometry type, typeid, num_coordinates and number of geometries
 geos_normalize = int_from_geom(lgeos.GEOSNormalize)
 geos_type = string_from_geom(lgeos.GEOSGeomType)
 geos_typeid = int_from_geom(lgeos.GEOSGeomTypeId)
diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py
index 070ccf6d5f..85f983733d 100644
--- a/django/contrib/gis/geos/tests/test_geos.py
+++ b/django/contrib/gis/geos/tests/test_geos.py
@@ -71,6 +71,31 @@ class GEOSTest(unittest.TestCase):
             geom = fromstr(g.wkt)
             self.assertEqual(g.hex, geom.hex)
 
+    def test01b_hexewkb(self):
+        "Testing (HEX)EWKB output."
+        from binascii import a2b_hex
+
+        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.
+        self.assertEqual(hexewkb_2d, pnt_2d.hexewkb)
+        self.assertEqual(hexewkb_3d, pnt_3d.hexewkb)
+
+        # Same for EWKB.
+        self.assertEqual(buffer(a2b_hex(hexewkb_2d)), pnt_2d.ewkb)
+        self.assertEqual(buffer(a2b_hex(hexewkb_3d)), pnt_3d.ewkb)
+        
+        # Redundant sanity check.
+        self.assertEqual(True, GEOSGeometry(hexewkb_3d).hasz)
+        self.assertEqual(4326, GEOSGeometry(hexewkb_2d).srid)
+
     def test01c_kml(self):
         "Testing KML output."
         for tg in wkt_out:
diff --git a/django/contrib/gis/tests/geometries.py b/django/contrib/gis/tests/geometries.py
index 950ffdb0e5..701741316d 100644
--- a/django/contrib/gis/tests/geometries.py
+++ b/django/contrib/gis/tests/geometries.py
@@ -171,3 +171,10 @@ json_geoms = (TestGeom('POINT(100 0)', json='{ "type": "Point", "coordinates": [
                        not_equal=True,
                        ),
               )
+
+# 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'