Fixed #28960 -- Added GEOSGeometry.buffer_with_style().
This commit is contained in:
parent
2162f0983d
commit
6d794fb762
1
AUTHORS
1
AUTHORS
|
@ -752,6 +752,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
|
Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
|
||||||
Stanislas Guerra <stan@slashdev.me>
|
Stanislas Guerra <stan@slashdev.me>
|
||||||
Stanislaus Madueke
|
Stanislaus Madueke
|
||||||
|
Stanislav Karpov <work@stkrp.ru>
|
||||||
starrynight <cmorgh@gmail.com>
|
starrynight <cmorgh@gmail.com>
|
||||||
Stefane Fermgier <sf@fermigier.com>
|
Stefane Fermgier <sf@fermigier.com>
|
||||||
Stefano Rivera <stefano@rivera.za.net>
|
Stefano Rivera <stefano@rivera.za.net>
|
||||||
|
|
|
@ -499,6 +499,18 @@ class GEOSGeometryBase(GEOSBase):
|
||||||
"""
|
"""
|
||||||
return self._topology(capi.geos_buffer(self.ptr, width, quadsegs))
|
return self._topology(capi.geos_buffer(self.ptr, width, quadsegs))
|
||||||
|
|
||||||
|
def buffer_with_style(self, width, quadsegs=8, end_cap_style=1, join_style=1, mitre_limit=5.0):
|
||||||
|
"""
|
||||||
|
Same as buffer() but allows customizing the style of the buffer.
|
||||||
|
|
||||||
|
End cap style can be round (1), flat (2), or square (3).
|
||||||
|
Join style can be round (1), mitre (2), or bevel (3).
|
||||||
|
Mitre ratio limit only affects mitered join style.
|
||||||
|
"""
|
||||||
|
return self._topology(
|
||||||
|
capi.geos_bufferwithstyle(self.ptr, width, quadsegs, end_cap_style, join_style, mitre_limit),
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def centroid(self):
|
def centroid(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -21,6 +21,7 @@ class Topology(GEOSFuncFactory):
|
||||||
# Topology Routines
|
# Topology Routines
|
||||||
geos_boundary = Topology('GEOSBoundary')
|
geos_boundary = Topology('GEOSBoundary')
|
||||||
geos_buffer = Topology('GEOSBuffer', argtypes=[GEOM_PTR, c_double, c_int])
|
geos_buffer = Topology('GEOSBuffer', argtypes=[GEOM_PTR, c_double, c_int])
|
||||||
|
geos_bufferwithstyle = Topology('GEOSBufferWithStyle', argtypes=[GEOM_PTR, c_double, c_int, c_int, c_int, c_double])
|
||||||
geos_centroid = Topology('GEOSGetCentroid')
|
geos_centroid = Topology('GEOSGetCentroid')
|
||||||
geos_convexhull = Topology('GEOSConvexHull')
|
geos_convexhull = Topology('GEOSConvexHull')
|
||||||
geos_difference = Topology('GEOSDifference', argtypes=[GEOM_PTR, GEOM_PTR])
|
geos_difference = Topology('GEOSDifference', argtypes=[GEOM_PTR, GEOM_PTR])
|
||||||
|
|
|
@ -496,6 +496,16 @@ Topological Methods
|
||||||
optional ``quadsegs`` keyword sets the number of segments used to
|
optional ``quadsegs`` keyword sets the number of segments used to
|
||||||
approximate a quarter circle (defaults is 8).
|
approximate a quarter circle (defaults is 8).
|
||||||
|
|
||||||
|
.. method:: GEOSGeometry.buffer_with_style(width, quadsegs=8, end_cap_style=1, join_style=1, mitre_limit=5.0)
|
||||||
|
|
||||||
|
.. versionadded:: 2.1
|
||||||
|
|
||||||
|
Same as :meth:`buffer`, but allows customizing the style of the buffer.
|
||||||
|
|
||||||
|
* ``end_cap_style`` can be round (``1``), flat (``2``), or square (``3``).
|
||||||
|
* ``join_style`` can be round (``1``), mitre (``2``), or bevel (``3``).
|
||||||
|
* Mitre ratio limit (``mitre_limit``) only affects mitered join style.
|
||||||
|
|
||||||
.. method:: GEOSGeometry.difference(other)
|
.. method:: GEOSGeometry.difference(other)
|
||||||
|
|
||||||
Returns a :class:`GEOSGeometry` representing the points making up this
|
Returns a :class:`GEOSGeometry` representing the points making up this
|
||||||
|
|
|
@ -70,7 +70,9 @@ Minor features
|
||||||
:mod:`django.contrib.gis`
|
:mod:`django.contrib.gis`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* The new :meth:`.GEOSGeometry.buffer_with_style` method is a version of
|
||||||
|
:meth:`~.GEOSGeometry.buffer` that allows customizing the style of the
|
||||||
|
buffer.
|
||||||
|
|
||||||
:mod:`django.contrib.messages`
|
:mod:`django.contrib.messages`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -407,6 +407,7 @@ minified
|
||||||
minify
|
minify
|
||||||
mis
|
mis
|
||||||
misconfiguration
|
misconfiguration
|
||||||
|
mitre
|
||||||
mixin
|
mixin
|
||||||
mixins
|
mixins
|
||||||
modelforms
|
modelforms
|
||||||
|
|
|
@ -78,6 +78,24 @@
|
||||||
"width": 2.0, "quadsegs": 8
|
"width": 2.0, "quadsegs": 8
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"buffer_with_style_geoms": [
|
||||||
|
{"wkt": "POINT (0 0)",
|
||||||
|
"buffer_wkt": "POLYGON EMPTY",
|
||||||
|
"width": 5.0, "end_cap_style": 2, "join_style": 2
|
||||||
|
},
|
||||||
|
{"wkt": "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))",
|
||||||
|
"buffer_wkt": "POLYGON ((-2 -2, -2 12, 12 12, 12 -2, -2 -2))",
|
||||||
|
"width": 2.0, "end_cap_style": 2, "join_style": 2
|
||||||
|
},
|
||||||
|
{"wkt": "LINESTRING (0 0, 10 0)",
|
||||||
|
"buffer_wkt": "POLYGON ((10 2, 10 -2, 0 -2, 0 2, 10 2))",
|
||||||
|
"width": 2.0, "end_cap_style": 2, "join_style": 2
|
||||||
|
},
|
||||||
|
{"wkt": "LINESTRING (0 0, 10 0, 10 10, 0 10)",
|
||||||
|
"buffer_wkt": "POLYGON ((8 2, 8 8, 0 8, 0 12, 12 12, 12 -2, 0 -2, 0 2, 8 2))",
|
||||||
|
"width": 2.0, "end_cap_style": 2, "join_style": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
"relate_geoms": [
|
"relate_geoms": [
|
||||||
{"wkt_a": "MULTIPOINT(80 70, 20 20, 200 170, 140 120)",
|
{"wkt_a": "MULTIPOINT(80 70, 20 20, 200 170, 140 120)",
|
||||||
"wkt_b": "MULTIPOINT(80 170, 140 120, 200 80, 80 70)",
|
"wkt_b": "MULTIPOINT(80 170, 140 120, 200 80, 80 70)",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import ctypes
|
import ctypes
|
||||||
|
import itertools
|
||||||
import json
|
import json
|
||||||
import pickle
|
import pickle
|
||||||
import random
|
import random
|
||||||
|
@ -650,21 +651,56 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
|
||||||
self.assertEqual(d1, a)
|
self.assertEqual(d1, a)
|
||||||
|
|
||||||
def test_buffer(self):
|
def test_buffer(self):
|
||||||
"Testing buffer()."
|
bg = self.geometries.buffer_geoms[0]
|
||||||
for bg in self.geometries.buffer_geoms:
|
g = fromstr(bg.wkt)
|
||||||
|
|
||||||
|
# Can't use a floating-point for the number of quadsegs.
|
||||||
|
with self.assertRaises(ctypes.ArgumentError):
|
||||||
|
g.buffer(bg.width, quadsegs=1.1)
|
||||||
|
|
||||||
|
self._test_buffer(self.geometries.buffer_geoms, 'buffer')
|
||||||
|
|
||||||
|
def test_buffer_with_style(self):
|
||||||
|
bg = self.geometries.buffer_with_style_geoms[0]
|
||||||
|
g = fromstr(bg.wkt)
|
||||||
|
|
||||||
|
# Can't use a floating-point for the number of quadsegs.
|
||||||
|
with self.assertRaises(ctypes.ArgumentError):
|
||||||
|
g.buffer_with_style(bg.width, quadsegs=1.1)
|
||||||
|
|
||||||
|
# Can't use a floating-point for the end cap style.
|
||||||
|
with self.assertRaises(ctypes.ArgumentError):
|
||||||
|
g.buffer_with_style(bg.width, end_cap_style=1.2)
|
||||||
|
# Can't use a end cap style that is not in the enum.
|
||||||
|
with self.assertRaises(GEOSException):
|
||||||
|
g.buffer_with_style(bg.width, end_cap_style=55)
|
||||||
|
|
||||||
|
# Can't use a floating-point for the join style.
|
||||||
|
with self.assertRaises(ctypes.ArgumentError):
|
||||||
|
g.buffer_with_style(bg.width, join_style=1.3)
|
||||||
|
# Can't use a join style that is not in the enum.
|
||||||
|
with self.assertRaises(GEOSException):
|
||||||
|
g.buffer_with_style(bg.width, join_style=66)
|
||||||
|
|
||||||
|
self._test_buffer(
|
||||||
|
itertools.chain(self.geometries.buffer_geoms, self.geometries.buffer_with_style_geoms),
|
||||||
|
'buffer_with_style',
|
||||||
|
)
|
||||||
|
|
||||||
|
def _test_buffer(self, geometries, buffer_method_name):
|
||||||
|
for bg in geometries:
|
||||||
g = fromstr(bg.wkt)
|
g = fromstr(bg.wkt)
|
||||||
|
|
||||||
# The buffer we expect
|
# The buffer we expect
|
||||||
exp_buf = fromstr(bg.buffer_wkt)
|
exp_buf = fromstr(bg.buffer_wkt)
|
||||||
quadsegs = bg.quadsegs
|
|
||||||
width = bg.width
|
|
||||||
|
|
||||||
# Can't use a floating-point for the number of quadsegs.
|
|
||||||
with self.assertRaises(ctypes.ArgumentError):
|
|
||||||
g.buffer(width, float(quadsegs))
|
|
||||||
|
|
||||||
# Constructing our buffer
|
# Constructing our buffer
|
||||||
buf = g.buffer(width, quadsegs)
|
buf_kwargs = {
|
||||||
|
kwarg_name: getattr(bg, kwarg_name)
|
||||||
|
for kwarg_name in ('width', 'quadsegs', 'end_cap_style', 'join_style', 'mitre_limit')
|
||||||
|
if hasattr(bg, kwarg_name)
|
||||||
|
}
|
||||||
|
buf = getattr(g, buffer_method_name)(**buf_kwargs)
|
||||||
self.assertEqual(exp_buf.num_coords, buf.num_coords)
|
self.assertEqual(exp_buf.num_coords, buf.num_coords)
|
||||||
self.assertEqual(len(exp_buf), len(buf))
|
self.assertEqual(len(exp_buf), len(buf))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue