|
13 | 13 | __revision__ = '$Format:%H$'
|
14 | 14 |
|
15 | 15 | import os
|
| 16 | + |
| 17 | +from PyQt4.QtCore import QVariant |
| 18 | + |
16 | 19 | from qgis.core import (QgsGeometry,
|
17 | 20 | QgsVectorLayer,
|
18 | 21 | QgsFeature,
|
|
23 | 26 | TestCase,
|
24 | 27 | unittest,
|
25 | 28 | expectedFailure,
|
26 |
| - unitTestDataPath) |
| 29 | + unitTestDataPath, |
| 30 | + writeShape) |
27 | 31 | # Convenience instances in case you may need them
|
28 | 32 | # not used in this test
|
29 | 33 |
|
@@ -241,6 +245,107 @@ def testSimplifyIssue4189(self):
|
241 | 245 | myMinimumLength = len('POLYGON(())')
|
242 | 246 | assert myEndLength > myMinimumLength, myMessage
|
243 | 247 |
|
| 248 | + def testClipping(self): |
| 249 | + """Test that we can clip geometries using other geometries.""" |
| 250 | + """Check we can write a vector file.""" |
| 251 | + myMemoryLayer = QgsVectorLayer( |
| 252 | + ('LineString?crs=epsg:4326&field=name:string(20)&index=yes'), |
| 253 | + 'clip-in', |
| 254 | + 'memory') |
| 255 | + |
| 256 | + assert myMemoryLayer is not None, 'Provider not initialised' |
| 257 | + myProvider = myMemoryLayer.dataProvider() |
| 258 | + assert myProvider is not None |
| 259 | + |
| 260 | + myFeature1 = QgsFeature() |
| 261 | + myFeature1.setGeometry(QgsGeometry.fromPolyline([ |
| 262 | + QgsPoint(10,10), |
| 263 | + QgsPoint(20,10), |
| 264 | + QgsPoint(30,10), |
| 265 | + QgsPoint(40,10), |
| 266 | + ] |
| 267 | + )) |
| 268 | + myFeature1.setAttributeMap({0 : QVariant('Johny')}) |
| 269 | + |
| 270 | + myFeature2 = QgsFeature() |
| 271 | + myFeature2.setGeometry(QgsGeometry.fromPolyline([ |
| 272 | + QgsPoint(10,10), |
| 273 | + QgsPoint(20,20), |
| 274 | + QgsPoint(30,30), |
| 275 | + QgsPoint(40,40), |
| 276 | + ] |
| 277 | + )) |
| 278 | + myFeature2.setAttributeMap({0 : QVariant('Be')}) |
| 279 | + |
| 280 | + myFeature3 = QgsFeature() |
| 281 | + myFeature3.setGeometry(QgsGeometry.fromPolyline([ |
| 282 | + QgsPoint(10,10), |
| 283 | + QgsPoint(10,20), |
| 284 | + QgsPoint(10,30), |
| 285 | + QgsPoint(10,40), |
| 286 | + ] |
| 287 | + )) |
| 288 | + |
| 289 | + myFeature3.setAttributeMap({0 : QVariant('Good')}) |
| 290 | + |
| 291 | + myResult, myFeatures = myProvider.addFeatures( |
| 292 | + [myFeature1, myFeature2, myFeature3]) |
| 293 | + assert myResult == True |
| 294 | + assert len(myFeatures) == 3 |
| 295 | + |
| 296 | + myClipPolygon = QgsGeometry.fromPolygon([[ |
| 297 | + QgsPoint(20,20), |
| 298 | + QgsPoint(20,30), |
| 299 | + QgsPoint(30,30), |
| 300 | + QgsPoint(30,20), |
| 301 | + QgsPoint(20,20), |
| 302 | + ]] |
| 303 | + ) |
| 304 | + print 'Clip: %s' % myClipPolygon.exportToWkt() |
| 305 | + writeShape(myMemoryLayer, 'clipGeometryBefore.shp') |
| 306 | + myProvider.rewind() |
| 307 | + myProvider.select(myProvider.attributeIndexes()) |
| 308 | + myFeatures = [] |
| 309 | + myFeature = QgsFeature() |
| 310 | + while myProvider.nextFeature(myFeature): |
| 311 | + myGeometry = myFeature.geometry() |
| 312 | + if myGeometry.intersects(myClipPolygon): |
| 313 | + # Adds nodes where the clip and the line intersec |
| 314 | + myCombinedGeometry = myGeometry.combine(myClipPolygon) |
| 315 | + # Gives you the areas inside the clip |
| 316 | + mySymmetricalGeometry = myGeometry.symDifference( |
| 317 | + myCombinedGeometry) |
| 318 | + # Gives you areas outside the clip area |
| 319 | + myDifferenceGeometry = myCombinedGeometry.difference( |
| 320 | + myClipPolygon) |
| 321 | + #print 'Original: %s' % myGeometry.exportToWkt() |
| 322 | + #print 'Combined: %s' % myCombinedGeometry.exportToWkt() |
| 323 | + #print 'Difference: %s' % myDifferenceGeometry.exportToWkt() |
| 324 | + print 'Symmetrical: %s' % mySymmetricalGeometry.exportToWkt() |
| 325 | + |
| 326 | + myExpectedWkt = 'LINESTRING(20.0 20.0, 30.0 30.0)' |
| 327 | + # There should only be one feature that intersects this clip |
| 328 | + # poly so this assertion should work. |
| 329 | + self.assertEqual(myExpectedWkt, |
| 330 | + mySymmetricalGeometry.exportToWkt()) |
| 331 | + |
| 332 | + myNewFeature = QgsFeature() |
| 333 | + myNewFeature.setAttributeMap(myFeature.attributeMap()) |
| 334 | + myNewFeature.setGeometry(mySymmetricalGeometry) |
| 335 | + myFeatures.append(myNewFeature) |
| 336 | + |
| 337 | + myNewMemoryLayer = QgsVectorLayer( |
| 338 | + ('LineString?crs=epsg:4326&field=name:string(20)&index=yes'), |
| 339 | + 'clip-out', |
| 340 | + 'memory') |
| 341 | + myNewProvider = myNewMemoryLayer.dataProvider() |
| 342 | + myResult, myFeatures = myNewProvider.addFeatures(myFeatures) |
| 343 | + self.assertTrue(myResult) |
| 344 | + self.assertEqual(len(myFeatures), 1) |
| 345 | + myNewMemoryLayer.commitChanges() |
| 346 | + |
| 347 | + writeShape(myNewMemoryLayer, 'clipGeometryAfter.shp') |
| 348 | + |
244 | 349 | if __name__ == '__main__':
|
245 | 350 | unittest.main()
|
246 | 351 |
|
0 commit comments