Fixed #25663 -- Added checking of the number of points for LinearRing and LineString.

This commit is contained in:
Sergey Fedoseev 2015-11-05 13:25:44 +05:00 committed by Tim Graham
parent 7a452c5ce2
commit 1e35dd1a05
2 changed files with 31 additions and 12 deletions

View File

@ -36,16 +36,24 @@ class LineString(ProjectInterpolateMixin, GEOSGeometry):
# Getting the number of coords and the number of dimensions -- which # Getting the number of coords and the number of dimensions -- which
# must stay the same, e.g., no LineString((1, 2), (1, 2, 3)). # must stay the same, e.g., no LineString((1, 2), (1, 2, 3)).
ncoords = len(coords) ncoords = len(coords)
if coords: if ncoords < self._minlength:
ndim = len(coords[0]) raise TypeError(
else: '%s requires at least %d points, got %s.' % (
raise TypeError('Cannot initialize on empty sequence.') self.__class__.__name__,
self._checkdim(ndim) self._minlength,
ncoords,
)
)
ndim = None
# Incrementing through each of the coordinates and verifying # Incrementing through each of the coordinates and verifying
for i in range(1, ncoords): for coord in coords:
if not isinstance(coords[i], (tuple, list, Point)): if not isinstance(coord, (tuple, list, Point)):
raise TypeError('each coordinate should be a sequence (list or tuple)') raise TypeError('Each coordinate should be a sequence (list or tuple)')
if len(coords[i]) != ndim:
if ndim is None:
ndim = len(coord)
self._checkdim(ndim)
elif len(coord) != ndim:
raise TypeError('Dimension mismatch.') raise TypeError('Dimension mismatch.')
numpy_coords = False numpy_coords = False
elif numpy and isinstance(coords, numpy.ndarray): elif numpy and isinstance(coords, numpy.ndarray):

View File

@ -3,7 +3,6 @@ from __future__ import unicode_literals
import ctypes import ctypes
import json import json
import random import random
import unittest
from binascii import a2b_hex, b2a_hex from binascii import a2b_hex, b2a_hex
from io import BytesIO from io import BytesIO
from unittest import skipUnless from unittest import skipUnless
@ -19,7 +18,7 @@ from django.contrib.gis.geos.base import GEOSBase
from django.contrib.gis.shortcuts import numpy from django.contrib.gis.shortcuts import numpy
from django.template import Context from django.template import Context
from django.template.engine import Engine from django.template.engine import Engine
from django.test import ignore_warnings, mock from django.test import SimpleTestCase, ignore_warnings, mock
from django.utils import six from django.utils import six
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
@ -29,7 +28,7 @@ from ..test_data import TestDataMixin
@skipUnless(HAS_GEOS, "Geos is required.") @skipUnless(HAS_GEOS, "Geos is required.")
class GEOSTest(unittest.TestCase, TestDataMixin): class GEOSTest(SimpleTestCase, TestDataMixin):
def test_base(self): def test_base(self):
"Tests out the GEOSBase class." "Tests out the GEOSBase class."
@ -326,6 +325,12 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
if numpy: if numpy:
self.assertEqual(ls, LineString(numpy.array(ls.tuple))) # as numpy array self.assertEqual(ls, LineString(numpy.array(ls.tuple))) # as numpy array
with self.assertRaisesMessage(TypeError, 'Each coordinate should be a sequence (list or tuple)'):
LineString((0, 0))
with self.assertRaisesMessage(TypeError, 'LineString requires at least 2 points, got 1.'):
LineString([(0, 0)])
def test_multilinestring(self): def test_multilinestring(self):
"Testing MultiLineString objects." "Testing MultiLineString objects."
prev = fromstr('POINT(0 0)') prev = fromstr('POINT(0 0)')
@ -369,6 +374,12 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
if numpy: if numpy:
self.assertEqual(lr, LinearRing(numpy.array(lr.tuple))) self.assertEqual(lr, LinearRing(numpy.array(lr.tuple)))
with self.assertRaisesMessage(TypeError, 'LinearRing requires at least 4 points, got 3.'):
LinearRing((0, 0), (1, 1), (0, 0))
with self.assertRaisesMessage(TypeError, 'LinearRing requires at least 4 points, got 1.'):
LinearRing([(0, 0)])
def test_polygons_from_bbox(self): def test_polygons_from_bbox(self):
"Testing `from_bbox` class method." "Testing `from_bbox` class method."
bbox = (-180, -90, 180, 90) bbox = (-180, -90, 180, 90)