22.01.2016, 10:06, Kai Muehlbauer kirjoitti:


To quickly check if there is an improvement I used the python shapely package. Converting the outer loop geometry to an shapely prepared geometry and calling 'contains()' with the inner loop geometries to find those fully contained geometries I get an improvement of nearly 40% to the former ogr only code.

As Even pointed out, there is only OGRPreparedGeometryIntersects() (GEOSPreparedIntersects) exposed within ogrgeometry.cpp. In my use case I would need GEOSPreparedContains to mimic the shapely behaviour.

I made a small test with the attached diff, which prepares the geometries of the input layer.

The input layer had two polygons (boundaries of two Finnish municipalities) and the method layer had 3091 points, all in either one of the polygons.

The improvement is ~15%.

I think the prepared geometries could be used by default easily. Prepared contains test would need addition of the respective GEOS method.

Ari


Next thing is that the ogr SWIG python bindings do not wrap those available OGRPrepared-functions.

I'm no expert when it comes to c/c++-python interaction to create a patch to have this functionality within python ogr/gdal. So hoping for help in this matter, I'm asking for suggestions how to get the GEOSPreparedGeometry stuff called from OGR.

Cheers,
Kai
_______________________________________________
gdal-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/gdal-dev

Index: ogr/ogrsf_frmts/generic/ogrlayer.cpp
===================================================================
--- ogr/ogrsf_frmts/generic/ogrlayer.cpp	(revision 33064)
+++ ogr/ogrsf_frmts/generic/ogrlayer.cpp	(working copy)
@@ -2033,6 +2033,7 @@
     double progress_ticker = 0;
     int bSkipFailures = CPLTestBool(CSLFetchNameValueDef(papszOptions, "SKIP_FAILURES", "NO"));
     int bPromoteToMulti = CPLTestBool(CSLFetchNameValueDef(papszOptions, "PROMOTE_TO_MULTI", "NO"));
+    int bUsePreparedGeometries = CPLTestBool(CSLFetchNameValueDef(papszOptions, "USE_PREPARED_GEOMETRIES", "NO"));
 
     // check for GEOS
     if (!OGRGeometryFactory::haveGEOS()) {
@@ -2093,10 +2094,23 @@
             continue;
         }
 
+        // 
+        OGRPreparedGeometry* x_prepared_geom = NULL;
+        if (bUsePreparedGeometries) x_prepared_geom = OGRCreatePreparedGeometry(x_geom);
+
         pLayerMethod->ResetReading();
         while (OGRFeature *y = pLayerMethod->GetNextFeature()) {
             OGRGeometry *y_geom = y->GetGeometryRef();
             if (!y_geom) {delete y; continue;}
+
+            if (bUsePreparedGeometries &&
+                !((x_prepared_geom && OGRPreparedGeometryIntersects(x_prepared_geom, y_geom)) ||
+                  x_geom->Intersects(y_geom)))
+            {
+                delete y;
+                continue;
+            }
+
             OGRGeometry* poIntersection = x_geom->Intersection(y_geom);
             if( poIntersection == NULL || poIntersection->IsEmpty() ||
                 (x_geom->getDimension() == 2 &&
@@ -2119,6 +2133,7 @@
                 delete z;
                 if (ret != OGRERR_NONE) {
                     if (!bSkipFailures) {
+                        OGRDestroyPreparedGeometry(x_prepared_geom);
                         delete x; 
                         goto done;
                     } else {
@@ -2129,6 +2144,7 @@
             }
         }
 
+        OGRDestroyPreparedGeometry(x_prepared_geom);
         delete x;
     }
     if (pfnProgress && !pfnProgress(1.0, "", pProgressArg)) {
_______________________________________________
gdal-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/gdal-dev

Reply via email to