@@ -302,27 +302,146 @@ void QgsOgrFeatureIterator::notifyLoadedFeature( OGRFeatureH fet, QgsFeature& fe
302
302
* *
303
303
***************************************************************************/
304
304
305
+ #include < ogr_geometry.h>
306
+
305
307
// ! Provides a specialized FeatureIterator for enable map2pixel simplification of the geometries
306
308
QgsOgrSimplifiedFeatureIterator::QgsOgrSimplifiedFeatureIterator ( QgsOgrProvider* p, const QgsFeatureRequest& request ) : QgsOgrFeatureIterator( p, request )
307
309
{
310
+ mPointBufferCount = 512 ;
311
+ mPointBufferPtr = (OGRRawPoint*)malloc ( mPointBufferCount * sizeof (OGRRawPoint) );
308
312
}
309
313
QgsOgrSimplifiedFeatureIterator::~QgsOgrSimplifiedFeatureIterator ( )
310
314
{
315
+ if ( mPointBufferPtr )
316
+ {
317
+ OGRFree ( mPointBufferPtr );
318
+ mPointBufferPtr = NULL ;
319
+ }
320
+ }
321
+
322
+ // ! Returns a point buffer of the specified size
323
+ OGRRawPoint* QgsOgrSimplifiedFeatureIterator::mallocPoints ( int numPoints )
324
+ {
325
+ if ( mPointBufferPtr && mPointBufferCount < numPoints )
326
+ {
327
+ OGRFree ( mPointBufferPtr );
328
+ mPointBufferPtr = NULL ;
329
+ }
330
+ if ( mPointBufferPtr ==NULL )
331
+ {
332
+ mPointBufferCount = numPoints;
333
+ mPointBufferPtr = (OGRRawPoint*)malloc ( mPointBufferCount * sizeof (OGRRawPoint) );
334
+ }
335
+ return mPointBufferPtr ;
336
+ }
337
+
338
+ // ! Simplify the OGR-geometry using the specified tolerance
339
+ bool QgsOgrSimplifiedFeatureIterator::simplifyOgrGeometry ( const QgsFeatureRequest& request, OGRGeometry* geometry, bool isaLinearRing )
340
+ {
341
+ OGRwkbGeometryType wkbGeometryType = wkbFlatten ( geometry->getGeometryType () );
342
+
343
+ // Simplify the geometry rewriting temporally its WKB-stream for saving calloc's.
344
+ if (wkbGeometryType==wkbLineString)
345
+ {
346
+ OGRLineString* lineString = (OGRLineString*)geometry;
347
+
348
+ OGREnvelope env;
349
+ geometry->getEnvelope (&env );
350
+ QgsRectangle envelope ( env.MinX , env.MinY , env.MaxX , env.MaxY );
351
+
352
+ // Can replace the geometry by its BBOX ?
353
+ if ( request.canbeGeneralizedByMapBoundingBox ( envelope ) )
354
+ {
355
+ OGRRawPoint* points = NULL ;
356
+ int numPoints = 0 ;
357
+
358
+ double x1 = envelope.xMinimum ();
359
+ double y1 = envelope.yMinimum ();
360
+ double x2 = envelope.xMaximum ();
361
+ double y2 = envelope.yMaximum ();
362
+
363
+ if ( isaLinearRing )
364
+ {
365
+ numPoints = 5 ;
366
+ points = mallocPoints ( numPoints );
367
+ points[0 ].x = x1; points[0 ].y = y1 ;
368
+ points[1 ].x = x2; points[1 ].y = y1 ;
369
+ points[2 ].x = x2; points[2 ].y = y2;
370
+ points[3 ].x = x1; points[3 ].y = y2;
371
+ points[4 ].x = x1; points[4 ].y = y1 ;
372
+ }
373
+ else
374
+ {
375
+ numPoints = 2 ;
376
+ points = mallocPoints ( numPoints );
377
+ points[0 ].x = x1; points[0 ].y = y1 ;
378
+ points[1 ].x = x2; points[1 ].y = y2;
379
+ }
380
+ lineString->setPoints ( numPoints, points );
381
+ lineString->flattenTo2D ();
382
+ return true ;
383
+ }
384
+ else
385
+ {
386
+ QGis::GeometryType geometryType = isaLinearRing ? QGis::Polygon : QGis::Line;
387
+
388
+ int numPoints = lineString->getNumPoints ();
389
+ int numSimplifiedPoints = 0 ;
390
+
391
+ OGRRawPoint* points = mallocPoints ( numPoints );
392
+ double * xptr = (double *)points;
393
+ double * yptr = xptr+1 ;
394
+ lineString->getPoints ( points );
395
+
396
+ if ( request.simplifyGeometry ( geometryType, envelope, xptr, 16 , yptr, 16 , numPoints, numSimplifiedPoints ) )
397
+ {
398
+ lineString->setPoints (numSimplifiedPoints, points);
399
+ lineString->flattenTo2D ();
400
+ }
401
+ return numSimplifiedPoints!=numPoints;
402
+ }
403
+ }
404
+ else
405
+ if (wkbGeometryType==wkbPolygon)
406
+ {
407
+ OGRPolygon* polygon = (OGRPolygon*)geometry;
408
+ bool result = simplifyOgrGeometry ( request, polygon->getExteriorRing (), true );
409
+
410
+ for (int i = 0 , numInteriorRings = polygon->getNumInteriorRings (); i < numInteriorRings; ++i)
411
+ {
412
+ result |= simplifyOgrGeometry ( request, polygon->getInteriorRing (i), true );
413
+ }
414
+ if ( result ) polygon->flattenTo2D ();
415
+ return result;
416
+ }
417
+ else
418
+ if (wkbGeometryType==wkbMultiLineString || wkbGeometryType==wkbMultiPolygon)
419
+ {
420
+ OGRGeometryCollection* collection = (OGRGeometryCollection*)geometry;
421
+ bool result = false ;
422
+
423
+ for (int i = 0 , numGeometries = collection->getNumGeometries (); i < numGeometries; ++i)
424
+ {
425
+ result |= simplifyOgrGeometry ( request, collection->getGeometryRef (i), wkbGeometryType==wkbMultiPolygon );
426
+ }
427
+ if ( result ) collection->flattenTo2D ();
428
+ return result;
429
+ }
430
+ return false ;
311
431
}
312
432
313
433
// ! notify the OGRFeatureH was readed of the data provider
314
434
void QgsOgrSimplifiedFeatureIterator::notifyReadedFeature ( OGRFeatureH fet, OGRGeometryH geom, QgsFeature& feature )
315
435
{
316
- /* TODO: ### ahuarte47!
317
436
if ( mRequest .flags () & QgsFeatureRequest::SimplifyGeometries )
318
437
{
319
- OGRwkbGeometryType wkbType = OGR_G_GetGeometryType( geom );
320
- OGRwkbGeometryType wkbGeometryType = QgsOgrProvider::ogrWkbSingleFlatten( wkbType );
438
+ OGRwkbGeometryType wkbType = QgsOgrProvider::ogrWkbSingleFlatten ( OGR_G_GetGeometryType (geom) );
321
439
322
- if (wkbGeometryType ==wkbLineString || wkbGeometryType ==wkbPolygon)
440
+ if (wkbType ==wkbLineString || wkbType ==wkbPolygon)
323
441
{
442
+ simplifyOgrGeometry ( mRequest , (OGRGeometry*)geom, wkbType==wkbPolygon );
324
443
}
325
- }*/
444
+ }
326
445
QgsOgrFeatureIterator::notifyReadedFeature ( fet, geom, feature );
327
446
}
328
447
0 commit comments