Skip to content
Browse files

Add parallel_offset method and back port some of functools for Python…

… 2.4.
  • Loading branch information...
1 parent 9959eff commit 54706fb47adac6a2ec48ed2f845598de10f9d239 @sgillies sgillies committed
Showing with 91 additions and 11 deletions.
  1. +1 −1 setup.py
  2. +78 −0 shapely/ftools.py
  3. +1 −1 shapely/geometry/base.py
  4. +3 −3 shapely/geometry/linestring.py
  5. +5 −3 shapely/geos.py
  6. +2 −2 shapely/impl.py
  7. +1 −1 shapely/tests/cascaded_union.txt
View
2 setup.py
@@ -17,7 +17,7 @@
setup_args = dict(
metadata_version = '1.2',
name = 'Shapely',
- version = '1.2.7',
+ version = '1.2.8',
requires_python = '>=2.5,<3',
requires_external = 'libgeos_c (>=3.1)',
description = 'Geometric objects, predicates, and operations',
View
78 shapely/ftools.py
@@ -0,0 +1,78 @@
+# Backport some of functools from Python 2.5 standard library for Shapely
+# on Python 2.4
+#
+# Python module wrapper for _functools C module
+# to allow utilities written in Python to be added
+# to the functools module.
+# Written by Nick Coghlan <ncoghlan at gmail.com>
+# Copyright (C) 2006 Python Software Foundation.
+# See C source code for _functools credits/copyright
+#
+# _functools module written and maintained
+# by Hye-Shik Chang <perky@FreeBSD.org>
+# with adaptations by Raymond Hettinger <python@rcn.com>
+# Copyright (c) 2004, 2005, 2006 Python Software Foundation.
+# All rights reserved.
+
+def _partial(func, *args, **keywords):
+ def newfunc(*fargs, **fkeywords):
+ newkeywords = keywords.copy()
+ newkeywords.update(fkeywords)
+ return func(
+ *(args + fargs), **newkeywords)
+ newfunc.func = func
+ newfunc.args = args
+ newfunc.keywords = keywords
+ return newfunc
+
+# update_wrapper() and wraps() are tools to help write
+# wrapper functions that can handle naive introspection
+
+WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__doc__')
+WRAPPER_UPDATES = ('__dict__',)
+def _update_wrapper(wrapper,
+ wrapped,
+ assigned = WRAPPER_ASSIGNMENTS,
+ updated = WRAPPER_UPDATES):
+ """Update a wrapper function to look like the wrapped function
+
+ wrapper is the function to be updated
+ wrapped is the original function
+ assigned is a tuple naming the attributes assigned directly
+ from the wrapped function to the wrapper function (defaults to
+ functools.WRAPPER_ASSIGNMENTS)
+ updated is a tuple naming the attributes of the wrapper that
+ are updated with the corresponding attribute from the wrapped
+ function (defaults to functools.WRAPPER_UPDATES)
+ """
+ for attr in assigned:
+ setattr(wrapper, attr, getattr(wrapped, attr))
+ for attr in updated:
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
+ # Return the wrapper so this can be used as a decorator via partial()
+ return wrapper
+
+def _wraps(wrapped,
+ assigned = WRAPPER_ASSIGNMENTS,
+ updated = WRAPPER_UPDATES):
+ """Decorator factory to apply update_wrapper() to a wrapper function
+
+ Returns a decorator that invokes update_wrapper() with the decorated
+ function as the wrapper argument and the arguments to wraps() as the
+ remaining arguments. Default arguments are as for update_wrapper().
+ This is a convenience function to simplify applying partial() to
+ update_wrapper().
+ """
+ return _partial(_update_wrapper, wrapped=wrapped,
+ assigned=assigned, updated=updated)
+
+# Use stdlib's functools if available
+try:
+ from functools import partial, update_wrapper, wraps
+ have_functools = 1
+except ImportError:
+ partial = _partial
+ update_wrapper = _update_wrapper
+ wraps = _wraps
+ have_functools = 0
+
View
2 shapely/geometry/base.py
@@ -1,11 +1,11 @@
"""Base geometry class and utilities
"""
-from functools import wraps
import sys
import warnings
from shapely.coords import CoordinateSequence
+from shapely.ftools import wraps
from shapely.geos import lgeos
from shapely.impl import DefaultImplementation, delegated
from shapely import wkb, wkt
View
6 shapely/geometry/linestring.py
@@ -80,7 +80,7 @@ def xy(self):
"""
return self.coords.xy
- def semi_perimeter(
+ def parallel_offset(
self, distance, side,
resolution=16, join_style=1, mitre_limit=1.0):
@@ -100,10 +100,10 @@ def semi_perimeter(
When two line segments meet at a sharp angle, a miter join will extend
far beyond the original geometry. To prevent unreasonable geometry, the
mitre limit allows controlling the maximum length of the join corner.
- Corners with a ratio which exceed the limit will be beveled. """
+ Corners with a ratio which exceed the limit will be beveled."""
try:
- return geom_factory(self.impl['semi_perimeter'](
+ return geom_factory(self.impl['parallel_offset'](
self, distance, resolution, join_style, mitre_limit,
bool(side=='left')))
except WindowsError:
View
8 shapely/geos.py
@@ -3,7 +3,6 @@
"""
import atexit
-import functools
import logging
import os
import sys
@@ -13,8 +12,11 @@
from ctypes import cdll, CDLL, PyDLL, CFUNCTYPE, c_char_p, c_void_p, string_at
from ctypes.util import find_library
+import ftools
from ctypes_declarations import prototype
+
+
# Begin by creating a do-nothing handler and adding to this module's logger.
class NullHandler(logging.Handler):
def emit(self, record):
@@ -267,7 +269,7 @@ def __init__(self, dll):
for key in filter(lambda x: not x.endswith('_r'), keys):
if key + '_r' in keys:
reentr_func = getattr(self._lgeos, key + '_r')
- attr = functools.partial(reentr_func, self.geos_handle)
+ attr = ftools.partial(reentr_func, self.geos_handle)
attr.__name__ = reentr_func.__name__
setattr(self, key, attr)
else:
@@ -349,7 +351,7 @@ class LGEOS16LR(LGEOS16):
def __init__(self, dll):
super(LGEOS16LR, self).__init__(dll)
- self.methods['semi_perimeter'] = self.GEOSSingleSidedBuffer
+ self.methods['parallel_offset'] = self.GEOSSingleSidedBuffer
self.methods['project'] = self.GEOSProject
self.methods['project_normalized'] = self.GEOSProjectNormalized
self.methods['interpolate'] = self.GEOSInterpolate
View
4 shapely/impl.py
@@ -11,7 +11,7 @@
Shapely 1.2 includes a GEOS backend and it is the default.
"""
-from functools import wraps
+from ftools import wraps
from shapely.coords import BoundsOp
from shapely.geos import lgeos
@@ -98,7 +98,7 @@ def __repr__(self):
}
IMPL16LR = {
- 'semi_perimeter': (UnaryTopologicalOp, 'semi_perimeter'),
+ 'parallel_offset': (UnaryTopologicalOp, 'parallel_offset'),
'project_normalized': (ProjectOp, 'project_normalized'),
'project': (ProjectOp, 'project'),
'interpolate_normalized': (InterpolateOp, 'interpolate_normalized'),
View
2 shapely/tests/cascaded_union.txt
@@ -1,7 +1,7 @@
Cascaded Union
==============
- >>> from functools import partial
+ >>> from shapely.ftools import partial
>>> import random
>>> from shapely.geometry import Point
>>> from shapely.ops import cascaded_union

0 comments on commit 54706fb

Please sign in to comment.
Something went wrong with that request. Please try again.