static int _setExtent(S57_geo *geoData, OGRGeometryH geometry) { return_if_null(geoData); return_if_null(geometry); OGREnvelope envelope; OGR_G_GetEnvelope(geometry, &envelope); S57_setExt(geoData, envelope.MinX, envelope.MinY, envelope.MaxX, envelope.MaxY); return TRUE; }
bool QgsOgrFeatureIterator::nextFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( P->ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } // skip features without geometry if ( !OGR_F_GetGeometryRef( fet ) && !P->mFetchFeaturesWithoutGeom ) { OGR_F_Destroy( fet ); close(); return false; } readFeature( fet, feature ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; QgsRectangle selectionRect; while (( fet = OGR_L_GetNextFeature( P->ogrLayer ) ) ) { // skip features without geometry if ( !P->mFetchFeaturesWithoutGeom && !OGR_F_GetGeometryRef( fet ) ) { OGR_F_Destroy( fet ); continue; } readFeature( fet, feature ); if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) { //precise test for intersection with search rectangle //first make QgsRectangle from OGRPolygon OGREnvelope env; memset( &env, 0, sizeof( env ) ); if ( mSelectionRectangle ) OGR_G_GetEnvelope( mSelectionRectangle, &env ); if ( env.MinX != 0 || env.MinY != 0 || env.MaxX != 0 || env.MaxY != 0 ) //if envelope is invalid, skip the precise intersection test { selectionRect.set( env.MinX, env.MinY, env.MaxX, env.MaxY ); if ( !feature.geometry() || !feature.geometry()->intersects( selectionRect ) ) { OGR_F_Destroy( fet ); continue; } } } // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while QgsDebugMsg( "Feature is null" ); close(); return false; }
static CPLErr BlendMaskGenerator( #ifndef HAVE_GEOS CPL_UNUSED int nXOff, CPL_UNUSED int nYOff, CPL_UNUSED int nXSize, CPL_UNUSED int nYSize, CPL_UNUSED GByte *pabyPolyMask, CPL_UNUSED float *pafValidityMask, CPL_UNUSED OGRGeometryH hPolygon, CPL_UNUSED double dfBlendDist #else int nXOff, int nYOff, int nXSize, int nYSize, GByte *pabyPolyMask, float *pafValidityMask, OGRGeometryH hPolygon, double dfBlendDist #endif ) { #ifndef HAVE_GEOS CPLError( CE_Failure, CPLE_AppDefined, "Blend distance support not available without the GEOS library."); return CE_Failure; #else /* HAVE_GEOS */ /* -------------------------------------------------------------------- */ /* Convert the polygon into a collection of lines so that we */ /* measure distance from the edge even on the inside. */ /* -------------------------------------------------------------------- */ OGRGeometry *poLines = OGRGeometryFactory::forceToMultiLineString( ((OGRGeometry *) hPolygon)->clone() ); /* -------------------------------------------------------------------- */ /* Prepare a clipping polygon a bit bigger than the area of */ /* interest in the hopes of simplifying the cutline down to */ /* stuff that will be relavent for this area of interest. */ /* -------------------------------------------------------------------- */ CPLString osClipRectWKT; osClipRectWKT.Printf( "POLYGON((%g %g,%g %g,%g %g,%g %g,%g %g))", nXOff - (dfBlendDist+1), nYOff - (dfBlendDist+1), nXOff + nXSize + (dfBlendDist+1), nYOff - (dfBlendDist+1), nXOff + nXSize + (dfBlendDist+1), nYOff + nYSize + (dfBlendDist+1), nXOff - (dfBlendDist+1), nYOff + nYSize + (dfBlendDist+1), nXOff - (dfBlendDist+1), nYOff - (dfBlendDist+1) ); OGRPolygon *poClipRect = NULL; char *pszWKT = (char *) osClipRectWKT.c_str(); OGRGeometryFactory::createFromWkt( &pszWKT, NULL, (OGRGeometry**) (&poClipRect) ); if( poClipRect ) { /***** if it doesnt intersect the polym zero the mask and return *****/ if ( ! ((OGRGeometry *) hPolygon)->Intersects( poClipRect ) ) { memset( pafValidityMask, 0, sizeof(float) * nXSize * nYSize ); delete poLines; delete poClipRect; return CE_None; } /***** if it doesnt intersect the line at all just return *****/ else if ( ! ((OGRGeometry *) poLines)->Intersects( poClipRect ) ) { delete poLines; delete poClipRect; return CE_None; } OGRGeometry *poClippedLines = poLines->Intersection( poClipRect ); delete poLines; poLines = poClippedLines; delete poClipRect; } /* -------------------------------------------------------------------- */ /* Convert our polygon into GEOS format, and compute an */ /* envelope to accelerate later distance operations. */ /* -------------------------------------------------------------------- */ OGREnvelope sEnvelope; int iXMin, iYMin, iXMax, iYMax; GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext(); GEOSGeom poGEOSPoly; poGEOSPoly = poLines->exportToGEOS(hGEOSCtxt); OGR_G_GetEnvelope( hPolygon, &sEnvelope ); delete poLines; /***** this check was already done in the calling *****/ /***** function and should never be true *****/ /*if( sEnvelope.MinY - dfBlendDist > nYOff+nYSize || sEnvelope.MaxY + dfBlendDist < nYOff || sEnvelope.MinX - dfBlendDist > nXOff+nXSize || sEnvelope.MaxX + dfBlendDist < nXOff ) return CE_None; */ iXMin = MAX(0,(int) floor(sEnvelope.MinX - dfBlendDist - nXOff)); iXMax = MIN(nXSize, (int) ceil(sEnvelope.MaxX + dfBlendDist - nXOff)); iYMin = MAX(0,(int) floor(sEnvelope.MinY - dfBlendDist - nYOff)); iYMax = MIN(nYSize, (int) ceil(sEnvelope.MaxY + dfBlendDist - nYOff)); /* -------------------------------------------------------------------- */ /* Loop over potential area within blend line distance, */ /* processing each pixel. */ /* -------------------------------------------------------------------- */ int iY, iX; double dfLastDist; for( iY = 0; iY < nYSize; iY++ ) { dfLastDist = 0.0; for( iX = 0; iX < nXSize; iX++ ) { if( iX < iXMin || iX >= iXMax || iY < iYMin || iY > iYMax || dfLastDist > dfBlendDist + 1.5 ) { if( pabyPolyMask[iX + iY * nXSize] == 0 ) pafValidityMask[iX + iY * nXSize] = 0.0; dfLastDist -= 1.0; continue; } double dfDist, dfRatio; CPLString osPointWKT; GEOSGeom poGEOSPoint; osPointWKT.Printf( "POINT(%d.5 %d.5)", iX + nXOff, iY + nYOff ); poGEOSPoint = GEOSGeomFromWKT_r( hGEOSCtxt, osPointWKT ); GEOSDistance_r( hGEOSCtxt, poGEOSPoly, poGEOSPoint, &dfDist ); GEOSGeom_destroy_r( hGEOSCtxt, poGEOSPoint ); dfLastDist = dfDist; if( dfDist > dfBlendDist ) { if( pabyPolyMask[iX + iY * nXSize] == 0 ) pafValidityMask[iX + iY * nXSize] = 0.0; continue; } if( pabyPolyMask[iX + iY * nXSize] == 0 ) { /* outside */ dfRatio = 0.5 - (dfDist / dfBlendDist) * 0.5; } else { /* inside */ dfRatio = 0.5 + (dfDist / dfBlendDist) * 0.5; } pafValidityMask[iX + iY * nXSize] *= (float)dfRatio; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ GEOSGeom_destroy_r( hGEOSCtxt, poGEOSPoly ); OGRGeometry::freeGEOSContext( hGEOSCtxt ); return CE_None; #endif /* HAVE_GEOS */ }
CPLErr GDALWarpCutlineMasker( void *pMaskFuncArg, CPL_UNUSED int nBandCount, CPL_UNUSED GDALDataType eType, int nXOff, int nYOff, int nXSize, int nYSize, GByte ** /*ppImageData */, int bMaskIsFloat, void *pValidityMask ) { GDALWarpOptions *psWO = (GDALWarpOptions *) pMaskFuncArg; float *pafMask = (float *) pValidityMask; CPLErr eErr; GDALDriverH hMemDriver; if( nXSize < 1 || nYSize < 1 ) return CE_None; /* -------------------------------------------------------------------- */ /* Do some minimal checking. */ /* -------------------------------------------------------------------- */ if( !bMaskIsFloat ) { CPLAssert( FALSE ); return CE_Failure; } if( psWO == NULL || psWO->hCutline == NULL ) { CPLAssert( FALSE ); return CE_Failure; } hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWarpCutlineMasker needs MEM driver"); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Check the polygon. */ /* -------------------------------------------------------------------- */ OGRGeometryH hPolygon = (OGRGeometryH) psWO->hCutline; OGREnvelope sEnvelope; if( wkbFlatten(OGR_G_GetGeometryType(hPolygon)) != wkbPolygon && wkbFlatten(OGR_G_GetGeometryType(hPolygon)) != wkbMultiPolygon ) { CPLAssert( FALSE ); return CE_Failure; } OGR_G_GetEnvelope( hPolygon, &sEnvelope ); if( sEnvelope.MaxX + psWO->dfCutlineBlendDist < nXOff || sEnvelope.MinX - psWO->dfCutlineBlendDist > nXOff + nXSize || sEnvelope.MaxY + psWO->dfCutlineBlendDist < nYOff || sEnvelope.MinY - psWO->dfCutlineBlendDist > nYOff + nYSize ) { // We are far from the blend line - everything is masked to zero. // It would be nice to realize no work is required for this whole // chunk! memset( pafMask, 0, sizeof(float) * nXSize * nYSize ); return CE_None; } /* -------------------------------------------------------------------- */ /* Create a byte buffer into which we can burn the */ /* mask polygon and wrap it up as a memory dataset. */ /* -------------------------------------------------------------------- */ GByte *pabyPolyMask = (GByte *) CPLCalloc( nXSize, nYSize ); GDALDatasetH hMemDS; double adfGeoTransform[6] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 }; char szDataPointer[100]; char *apszOptions[] = { szDataPointer, NULL }; memset( szDataPointer, 0, sizeof(szDataPointer) ); sprintf( szDataPointer, "DATAPOINTER=" ); CPLPrintPointer( szDataPointer+strlen(szDataPointer), pabyPolyMask, sizeof(szDataPointer) - strlen(szDataPointer) ); hMemDS = GDALCreate( hMemDriver, "warp_temp", nXSize, nYSize, 0, GDT_Byte, NULL ); GDALAddBand( hMemDS, GDT_Byte, apszOptions ); GDALSetGeoTransform( hMemDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Burn the polygon into the mask with 1.0 values. */ /* -------------------------------------------------------------------- */ int nTargetBand = 1; double dfBurnValue = 255.0; int anXYOff[2]; char **papszRasterizeOptions = NULL; if( CSLFetchBoolean( psWO->papszWarpOptions, "CUTLINE_ALL_TOUCHED", FALSE )) papszRasterizeOptions = CSLSetNameValue( papszRasterizeOptions, "ALL_TOUCHED", "TRUE" ); anXYOff[0] = nXOff; anXYOff[1] = nYOff; eErr = GDALRasterizeGeometries( hMemDS, 1, &nTargetBand, 1, &hPolygon, CutlineTransformer, anXYOff, &dfBurnValue, papszRasterizeOptions, NULL, NULL ); CSLDestroy( papszRasterizeOptions ); // Close and ensure data flushed to underlying array. GDALClose( hMemDS ); /* -------------------------------------------------------------------- */ /* In the case with no blend distance, we just apply this as a */ /* mask, zeroing out everything outside the polygon. */ /* -------------------------------------------------------------------- */ if( psWO->dfCutlineBlendDist == 0.0 ) { int i; for( i = nXSize * nYSize - 1; i >= 0; i-- ) { if( pabyPolyMask[i] == 0 ) ((float *) pValidityMask)[i] = 0.0; } } else { eErr = BlendMaskGenerator( nXOff, nYOff, nXSize, nYSize, pabyPolyMask, (float *) pValidityMask, hPolygon, psWO->dfCutlineBlendDist ); } /* -------------------------------------------------------------------- */ /* Clean up. */ /* -------------------------------------------------------------------- */ CPLFree( pabyPolyMask ); return eErr; }
int main(int argc, const char **argv) { /* initialize apr_getopt_t */ apr_getopt_t *opt; const char *configfile=NULL; #ifndef USE_FORK apr_thread_t **threads; apr_threadattr_t *thread_attrs; #endif const char *tileset_name=NULL; const char *tileset_transfer_name=NULL; const char *grid_name = NULL; int *zooms = NULL;//[2]; double *extent = NULL;//[4]; int optch; int rv,n; const char *old = NULL; const char *optarg; apr_table_t *argdimensions; char *dimkey=NULL, *dimvalue=NULL,*key, *last, *optargcpy=NULL; int keyidx; int *metasizes = NULL;//[2]; int metax=-1,metay=-1; #ifdef USE_CLIPPERS const char *ogr_where = NULL; const char *ogr_layer = NULL; const char *ogr_sql = NULL; const char *ogr_datasource = NULL; #endif apr_initialize(); (void) signal(SIGINT,handle_sig_int); apr_pool_create(&ctx.pool,NULL); mapcache_context_init(&ctx); ctx.process_pool = ctx.pool; #ifndef USE_FORK apr_thread_mutex_create((apr_thread_mutex_t**)&ctx.threadlock,APR_THREAD_MUTEX_DEFAULT,ctx.pool); #else ctx.threadlock = NULL; #endif cfg = mapcache_configuration_create(ctx.pool); ctx.config = cfg; ctx.log= mapcache_context_seeding_log; apr_getopt_init(&opt, ctx.pool, argc, argv); seededtiles=seededtilestot=queuedtilestot=0; mapcache_gettimeofday(&starttime,NULL); lastlogtime=starttime; argdimensions = apr_table_make(ctx.pool,3); /* parse the all options based on opt_option[] */ while ((rv = apr_getopt_long(opt, seed_options, &optch, &optarg)) == APR_SUCCESS) { switch (optch) { case 'h': return usage(argv[0],NULL); break; case 'f': force = 1; break; case 'q': quiet = 1; break; case 'v': verbose = 1; break; case 'c': configfile = optarg; break; case 'g': grid_name = optarg; break; case 't': tileset_name = optarg; break; case 'x': tileset_transfer_name = optarg; break; case 'm': if(!strcmp(optarg,"delete")) { mode = MAPCACHE_CMD_DELETE; } else if(!strcmp(optarg,"transfer")){ mode = MAPCACHE_CMD_TRANSFER; } else if(strcmp(optarg,"seed")){ return usage(argv[0],"invalid mode, expecting \"seed\", \"delete\" or \"transfer\""); } else { mode = MAPCACHE_CMD_SEED; } break; case 'n': nthreads = (int)strtol(optarg, NULL, 10); break; case 'e': if ( MAPCACHE_SUCCESS != mapcache_util_extract_double_list(&ctx, (char*)optarg, ",", &extent, &n) || n != 4 || extent[0] >= extent[2] || extent[1] >= extent[3] ) { return usage(argv[0], "failed to parse extent, expecting comma separated 4 doubles"); } break; case 'z': if ( MAPCACHE_SUCCESS != mapcache_util_extract_int_list(&ctx, (char*)optarg, ",", &zooms, &n) || n != 2 || zooms[0] > zooms[1]) { return usage(argv[0], "failed to parse zooms, expecting comma separated 2 ints"); } else { minzoom = zooms[0]; maxzoom = zooms[1]; } break; case 'M': if ( MAPCACHE_SUCCESS != mapcache_util_extract_int_list(&ctx, (char*)optarg, ",", &metasizes, &n) || n != 2 || metasizes[0] <= 0 || metasizes[1] <=0) { return usage(argv[0], "failed to parse metasize, expecting comma separated 2 positive ints (e.g. -M 8,8"); } else { metax = metasizes[0]; metay = metasizes[1]; } break; case 'o': old = optarg; break; case 'D': optargcpy = apr_pstrdup(ctx.pool,optarg); keyidx = 0; for (key = apr_strtok(optargcpy, "=", &last); key != NULL; key = apr_strtok(NULL, "=", &last)) { if(keyidx == 0) { dimkey = key; } else { dimvalue = key; } keyidx++; } if(keyidx!=2 || !dimkey || !dimvalue || !*dimkey || !*dimvalue) { return usage(argv[0], "failed to parse dimension, expecting DIMNAME=DIMVALUE"); } apr_table_set(argdimensions,dimkey,dimvalue); break; #ifdef USE_CLIPPERS case 'd': ogr_datasource = optarg; break; case 's': ogr_sql = optarg; break; case 'l': ogr_layer = optarg; break; case 'w': ogr_where = optarg; break; #endif } } if (rv != APR_EOF) { return usage(argv[0],"bad options"); } if( ! configfile ) { return usage(argv[0],"config not specified"); } else { mapcache_configuration_parse(&ctx,configfile,cfg,0); if(ctx.get_error(&ctx)) return usage(argv[0],ctx.get_error_message(&ctx)); mapcache_configuration_post_config(&ctx,cfg); if(ctx.get_error(&ctx)) return usage(argv[0],ctx.get_error_message(&ctx)); } #ifdef USE_CLIPPERS if(extent && ogr_datasource) { return usage(argv[0], "cannot specify both extent and ogr-datasource"); } if( ogr_sql && ( ogr_where || ogr_layer )) { return usage(argv[0], "ogr-where or ogr_layer cannot be used in conjunction with ogr-sql"); } if(ogr_datasource) { OGRDataSourceH hDS = NULL; OGRLayerH layer = NULL; OGRRegisterAll(); hDS = OGROpen( ogr_datasource, FALSE, NULL ); if( hDS == NULL ) { printf( "OGR Open failed\n" ); exit( 1 ); } if(ogr_sql) { layer = OGR_DS_ExecuteSQL( hDS, ogr_sql, NULL, NULL); if(!layer) { return usage(argv[0],"aborting"); } } else { int nLayers = OGR_DS_GetLayerCount(hDS); if(nLayers>1 && !ogr_layer) { return usage(argv[0],"ogr datastore contains more than one layer. please specify which one to use with --ogr-layer"); } else { if(ogr_layer) { layer = OGR_DS_GetLayerByName(hDS,ogr_layer); } else { layer = OGR_DS_GetLayer(hDS,0); } if(!layer) { return usage(argv[0],"aborting"); } if(ogr_where) { if(OGRERR_NONE != OGR_L_SetAttributeFilter(layer, ogr_where)) { return usage(argv[0],"aborting"); } } } } if((nClippers=OGR_L_GetFeatureCount(layer, TRUE)) == 0) { return usage(argv[0],"no features in provided ogr parameters, cannot continue"); } initGEOS(notice, log_and_exit); clippers = (const GEOSPreparedGeometry**)malloc(nClippers*sizeof(GEOSPreparedGeometry*)); OGRFeatureH hFeature; GEOSWKTReader *geoswktreader = GEOSWKTReader_create(); OGR_L_ResetReading(layer); extent = apr_pcalloc(ctx.pool,4*sizeof(double)); int f=0; while( (hFeature = OGR_L_GetNextFeature(layer)) != NULL ) { OGRGeometryH geom = OGR_F_GetGeometryRef(hFeature); if(!geom || !OGR_G_IsValid(geom)) continue; char *wkt; OGR_G_ExportToWkt(geom,&wkt); GEOSGeometry *geosgeom = GEOSWKTReader_read(geoswktreader,wkt); free(wkt); clippers[f] = GEOSPrepare(geosgeom); //GEOSGeom_destroy(geosgeom); OGREnvelope ogr_extent; OGR_G_GetEnvelope (geom, &ogr_extent); if(f == 0) { extent[0] = ogr_extent.MinX; extent[1] = ogr_extent.MinY; extent[2] = ogr_extent.MaxX; extent[3] = ogr_extent.MaxY; } else { extent[0] = MAPCACHE_MIN(ogr_extent.MinX, extent[0]); extent[1] = MAPCACHE_MIN(ogr_extent.MinY, extent[1]); extent[2] = MAPCACHE_MAX(ogr_extent.MaxX, extent[2]); extent[3] = MAPCACHE_MAX(ogr_extent.MaxY, extent[3]); } OGR_F_Destroy( hFeature ); f++; } nClippers = f; } #endif if( ! tileset_name ) { return usage(argv[0],"tileset not specified"); } else { tileset = mapcache_configuration_get_tileset(cfg,tileset_name); if(!tileset) { return usage(argv[0], "tileset not found in configuration"); } if( ! grid_name ) { grid_link = APR_ARRAY_IDX(tileset->grid_links,0,mapcache_grid_link*); } else {