Ticket #11948: 11948-3.diff

File 11948-3.diff, 7.9 KB (added by Claude Paroz, 7 years ago)

Docs included

  • django/contrib/gis/geos/geometry.py

    diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py
    index f411d5a..ed70f90 100644
    a b class GEOSGeometry(GEOSBase, ListMixin): 
    577577        "Return the envelope for this geometry (a polygon)."
    578578        return self._topology(capi.geos_envelope(self.ptr))
    579579
     580    def interpolate(self, distance):
     581        if not isinstance(self, (LineString, MultiLineString)):
     582            raise TypeError('interpolate only works on LineString and MultiLineString geometries')
     583        return self._topology(capi.geos_interpolate(self.ptr, distance))
     584
     585    def interpolate_normalized(self, distance):
     586        if not isinstance(self, (LineString, MultiLineString)):
     587            raise TypeError('interpolate only works on LineString and MultiLineString geometries')
     588        return self._topology(capi.geos_interpolate_normalized(self.ptr, distance))
     589
    580590    def intersection(self, other):
    581591        "Returns a Geometry representing the points shared by this Geometry and other."
    582592        return self._topology(capi.geos_intersection(self.ptr, other.ptr))
    class GEOSGeometry(GEOSBase, ListMixin): 
    586596        "Computes an interior point of this Geometry."
    587597        return self._topology(capi.geos_pointonsurface(self.ptr))
    588598
     599    def project(self, point):
     600        if not isinstance(point, Point):
     601            raise TypeError('locate_point argument must be a Point')
     602        if not isinstance(self, (LineString, MultiLineString)):
     603            raise TypeError('locate_point only works on LineString and MultiLineString geometries')
     604        return capi.geos_project(self.ptr, point.ptr)
     605
     606    def project_normalized(self, point):
     607        if not isinstance(point, Point):
     608            raise TypeError('locate_point argument must be a Point')
     609        if not isinstance(self, (LineString, MultiLineString)):
     610            raise TypeError('locate_point only works on LineString and MultiLineString geometries')
     611        return capi.geos_project_normalized(self.ptr, point.ptr)
     612
    589613    def relate(self, other):
    590614        "Returns the DE-9IM intersection matrix for this Geometry and the other."
    591615        return capi.geos_relate(self.ptr, other.ptr)
  • django/contrib/gis/geos/prototypes/topology.py

    diff --git a/django/contrib/gis/geos/prototypes/topology.py b/django/contrib/gis/geos/prototypes/topology.py
    index cc5734b..dfea3e9 100644
    a b __all__ = ['geos_boundary', 'geos_buffer', 'geos_centroid', 'geos_convexhull', 
    88           'geos_simplify', 'geos_symdifference', 'geos_union', 'geos_relate']
    99
    1010from ctypes import c_double, c_int
    11 from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE
    12 from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string
     11from django.contrib.gis.geos.libgeos import geos_version_info, GEOM_PTR, GEOS_PREPARE
     12from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_minus_one, check_string
    1313from django.contrib.gis.geos.prototypes.geom import geos_char_p
    1414from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
    1515
    16 def topology(func, *args):
     16def topology(func, *args, **kwargs):
    1717    "For GEOS unary topology functions."
    1818    argtypes = [GEOM_PTR]
    1919    if args: argtypes += args
    2020    func.argtypes = argtypes
    21     func.restype = GEOM_PTR
    22     func.errcheck = check_geom
     21    func.restype = kwargs.get('restype', GEOM_PTR)
     22    func.errcheck = kwargs.get('errcheck', check_geom)
    2323    return func
    2424
    2525### Topology Routines ###
    if GEOS_PREPARE: 
    4949    geos_cascaded_union.argtypes = [GEOM_PTR]
    5050    geos_cascaded_union.restype = GEOM_PTR
    5151    __all__.append('geos_cascaded_union')
     52
     53# Linear referencing routines
     54info = geos_version_info()
     55if info['version'] >= '3.2.0':
     56    geos_project = topology(GEOSFunc('GEOSProject'), GEOM_PTR,
     57        restype=c_double, errcheck=check_minus_one)
     58    geos_interpolate = topology(GEOSFunc('GEOSInterpolate'), c_double)
     59
     60    geos_project_normalized = topology(GEOSFunc('GEOSProjectNormalized'),
     61        GEOM_PTR, restype=c_double, errcheck=check_minus_one)
     62    geos_interpolate_normalized = topology(GEOSFunc('GEOSInterpolateNormalized'), c_double)
     63    __all__.extend(['geos_project', 'geos_interpolate',
     64        'geos_project_normalized', 'geos_interpolate_normalized'])
  • django/contrib/gis/geos/tests/test_geos.py

    diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py
    index ed38283..97f2a86 100644
    a b class GEOSTest(unittest.TestCase, TestDataMixin): 
    10171017
    10181018        print("\nEND - expecting GEOS_NOTICE; safe to ignore.\n")
    10191019
     1020    @unittest.skipUnless(geos_version_info()['version'] >= '3.2.0', "geos >= 3.2.0 is required")
     1021    def test_linearref(self):
     1022        "Testing linear referencing"
     1023
     1024        ls = fromstr('LINESTRING(0 0, 0 10, 10 10, 10 0)')
     1025        mls = fromstr('MULTILINESTRING((0 0, 0 10), (10 0, 10 10))')
     1026
     1027        self.assertEqual(ls.project(Point(0, 20)), 10.0)
     1028        self.assertEqual(ls.project(Point(7, 6)), 24)
     1029        self.assertEqual(ls.project_normalized(Point(0, 20)), 1.0/3)
     1030
     1031        self.assertEqual(ls.interpolate(10), Point(0, 10))
     1032        self.assertEqual(ls.interpolate(24), Point(10, 6))
     1033        self.assertEqual(ls.interpolate_normalized(1.0/3), Point(0, 10))
     1034
     1035        self.assertEqual(mls.project(Point(0, 20)), 10)
     1036        self.assertEqual(mls.project(Point(7, 6)), 16)
     1037
     1038        self.assertEqual(mls.interpolate(9), Point(0, 9))
     1039        self.assertEqual(mls.interpolate(17), Point(10, 7))
     1040
    10201041    def test_geos_version(self):
    10211042        "Testing the GEOS version regular expression."
    10221043        from django.contrib.gis.geos.libgeos import version_regex
  • docs/ref/contrib/gis/geos.txt

    diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt
    index 1b32265..0487472 100644
    a b quarter circle (defaults is 8). 
    402402Returns a :class:`GEOSGeometry` representing the points making up this
    403403geometry that do not make up other.
    404404
     405.. method:: GEOSGeometry.interpolate(distance)
     406.. method:: GEOSGeometry.interpolate_normalized(distance)
     407
     408.. versionadded:: 1.5
     409
     410Given a distance (float), returns the point (or closest point) within the
     411geometry (:class:`LineString` or :class:`MultiLineString`) at that distance.
     412The normalized version takes the distance as a float between 0 (origin) and 1
     413(endpoint).
     414
     415Reverse of :meth:`GEOSGeometry.project`.
     416
    405417.. method:: GEOSGeometry:intersection(other)
    406418
    407419Returns a :class:`GEOSGeometry` representing the points shared by this
    408420geometry and other.
    409421
     422.. method:: GEOSGeometry.project(point)
     423.. method:: GEOSGeometry.project_normalized(point)
     424
     425.. versionadded:: 1.5
     426
     427Returns the distance (float) from the origin of the geometry
     428(:class:`LineString` or :class:`MultiLineString`) to the point projected on the
     429geometry (that is to a point of the line the closest to the given point).
     430The normalized version returns the distance as a float between 0 (origin) and 1
     431(endpoint).
     432
     433Reverse of :meth:`GEOSGeometry.interpolate`.
     434
    410435.. method:: GEOSGeometry.relate(other)
    411436
    412437Returns the DE-9IM intersection matrix (a string) representing the
  • docs/releases/1.5.txt

    diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
    index 3e274b5..b4618e7 100644
    a b Django 1.5 also includes several smaller improvements worth noting: 
    102102* In the localflavor for Canada, "pq" was added to the acceptable codes for
    103103  Quebec. It's an old abbreviation.
    104104
     105* :class:`~django.contrib.gis.geos.LineString` and
     106  :class:`~django.contrib.gis.geos.MultiLineString` GEOS objects now support the
     107  :meth:`~django.contrib.gis.geos.GEOSGeometry.interpolate()` and
     108  :meth:`~django.contrib.gis.geos.GEOSGeometry.project()` methods
     109  (so-called linear referencing).
     110
    105111Backwards incompatible changes in 1.5
    106112=====================================
    107113
Back to Top