Skip to content

Commit 6272274

Browse files
committedJul 12, 2013
Merge pull request #717 from Oslandia/issue7244
geometry: don't check for cut edges and validate the split geometries instead (fixes #7244)
2 parents cafc367 + 5256b80 commit 6272274

File tree

2 files changed

+132
-16
lines changed

2 files changed

+132
-16
lines changed
 

‎src/core/qgsgeometry.cpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5401,22 +5401,6 @@ int QgsGeometry::splitPolygonGeometry( GEOSGeometry* splitLine, QList<QgsGeometr
54015401
return 2; //an error occured during noding
54025402
}
54035403

5404-
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
5405-
((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=1)))
5406-
GEOSGeometry *cutEdges = GEOSPolygonizer_getCutEdges( &nodedGeometry, 1 );
5407-
if ( cutEdges )
5408-
{
5409-
if ( numberOfGeometries( cutEdges ) > 0 )
5410-
{
5411-
GEOSGeom_destroy( cutEdges );
5412-
GEOSGeom_destroy( nodedGeometry );
5413-
return 3;
5414-
}
5415-
5416-
GEOSGeom_destroy( cutEdges );
5417-
}
5418-
#endif
5419-
54205404
GEOSGeometry *polygons = GEOSPolygonize( &nodedGeometry, 1 );
54215405
if ( !polygons || numberOfGeometries( polygons ) == 0 )
54225406
{
@@ -5486,6 +5470,14 @@ int QgsGeometry::splitPolygonGeometry( GEOSGeometry* splitLine, QList<QgsGeometr
54865470
mDirtyWkb = true;
54875471
}
54885472

5473+
for ( int i = 1; i < testedGeometries.size(); ++i )
5474+
{
5475+
if ( GEOSisValid( testedGeometries[i] ) != 1 )
5476+
{
5477+
return 3;
5478+
}
5479+
}
5480+
54895481
for ( int i = 1; i < testedGeometries.size(); ++i )
54905482
{
54915483
newGeometries << fromGeosGeom( testedGeometries[i] );

‎tests/src/python/test_qgsissue7244.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsSpatialiteProvider
3+
4+
.. note:: This program is free software; you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation; either version 2 of the License, or
7+
(at your option) any later version.
8+
"""
9+
__author__ = 'Vincent Mora'
10+
__date__ = '09/07/2013'
11+
__copyright__ = 'Copyright 2013, The QGIS Project'
12+
# This will get replaced with a git SHA1 when you do a git archive
13+
__revision__ = '$Format:%H$'
14+
15+
import os
16+
import random
17+
18+
from qgis.core import *
19+
from qgis.gui import *
20+
21+
from utilities import (getQgisTestApp,
22+
TestCase,
23+
unittest
24+
)
25+
26+
from pyspatialite import dbapi2 as sqlite3
27+
28+
# Convenience instances in case you may need them
29+
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
30+
31+
32+
def die(error_message):
33+
raise Exception(error_message)
34+
35+
class TestQgsSpatialiteProvider(TestCase):
36+
37+
@classmethod
38+
def setUpClass(cls):
39+
"""Run before all tests"""
40+
# create test db
41+
if os.path.exists("test.sqlite") :
42+
os.remove("test.sqlite")
43+
con = sqlite3.connect("test.sqlite")
44+
cur = con.cursor()
45+
sql = "SELECT InitSpatialMetadata()"
46+
cur.execute(sql)
47+
48+
# simple table with primary key
49+
sql = "CREATE TABLE test_mpg (id SERIAL PRIMARY KEY, name STRING NOT NULL)"
50+
cur.execute(sql)
51+
sql = "SELECT AddGeometryColumn('test_mpg', 'geometry', 4326, 'MULTIPOLYGON', 'XY')"
52+
cur.execute(sql)
53+
sql = "INSERT INTO test_mpg (name, geometry) "
54+
sql += "VALUES ('multipolygon with 8 squares', GeomFromText('MULTIPOLYGON("
55+
for i in range(0,4,2):
56+
for j in range (0,4,2):
57+
sql += "(("
58+
sql += str(i) + " " + str(j) + ","
59+
sql += str(i+1) + " " + str(j) + ","
60+
sql += str(i+1) + " " + str(j+1) + ","
61+
sql += str(i) + " " + str(j+1) + ","
62+
sql += str(i) + " " + str(j)
63+
sql += ")),"
64+
sql = sql[:-1] # remove last comma
65+
sql += ")', 4326))"
66+
cur.execute(sql)
67+
68+
sql = "CREATE TABLE test_pg (id SERIAL PRIMARY KEY, name STRING NOT NULL)"
69+
cur.execute(sql)
70+
sql = "SELECT AddGeometryColumn('test_pg', 'geometry', 4326, 'POLYGON', 'XY')"
71+
cur.execute(sql)
72+
sql = "INSERT INTO test_pg (name, geometry) "
73+
sql += "VALUES ('polygon with interior ring', GeomFromText('POLYGON((0 0,3 0,3 3,0 3,0 0),(1 1,1 2,2 2,2 1,1 1))', 4326))"
74+
cur.execute(sql)
75+
con.commit()
76+
con.close()
77+
78+
@classmethod
79+
def tearDownClass(cls):
80+
"""Run after all tests"""
81+
# for the time beeing, keep the file to check with qgis
82+
#if os.path.exists("test.sqlite") :
83+
# os.remove("test.sqlite")
84+
pass
85+
86+
def setUp(self):
87+
"""Run before each test."""
88+
pass
89+
90+
def tearDown(self):
91+
"""Run after each test."""
92+
pass
93+
94+
def test_SplitMultipolygon(self):
95+
"""Split multipolygon"""
96+
layer = QgsVectorLayer("dbname=test.sqlite table=test_mpg (geometry)", "test_mpg", "spatialite")
97+
assert(layer.isValid())
98+
assert(layer.hasGeometryType())
99+
layer.featureCount() == 1 or die("wrong number of features")
100+
layer.startEditing()
101+
layer.splitFeatures([QgsPoint(0.5, -0.5), QgsPoint(0.5, 1.5)], 0)==0 or die("error in split of one polygon of multipolygon")
102+
layer.splitFeatures([QgsPoint(2.5, -0.5), QgsPoint(2.5, 4)], 0)==0 or die("error in split of two polygons of multipolygon at a time")
103+
layer.commitChanges() or die("this commit should work")
104+
layer.featureCount() == 7 or die("wrong number of features after 2 split")
105+
106+
def test_SplitTruToCreateCutEdge(self):
107+
"""Try to creat a cut edge"""
108+
layer = QgsVectorLayer("dbname=test.sqlite table=test_pg (geometry)", "test_pg", "spatialite")
109+
assert(layer.isValid())
110+
assert(layer.hasGeometryType())
111+
layer.featureCount() == 1 or die("wrong number of features")
112+
layer.startEditing()
113+
layer.splitFeatures([QgsPoint(1.5, -0.5), QgsPoint(1.5, 1.5)], 0)==0 or die("error when trying to create an invalid polygon in split")
114+
layer.commitChanges() or die("this commit should work")
115+
layer.featureCount() == 1 or die("wrong number of features, polygon should be unafected by cut")
116+
117+
118+
119+
120+
121+
if __name__ == '__main__':
122+
unittest.main()
123+
124+

0 commit comments

Comments
 (0)
Please sign in to comment.