AttrRef addFloatAttr(AttrTable &self, const std::string &attrName, const size_t size, boost::python::list l) { std::vector<float> defaults = pyListValues<float>(l); return self.addFloatAttr(attrName, size, defaults); }
int OGRDODSDataSource::Open( const char * pszNewName ) { CPLAssert( nLayers == 0 ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Parse the URL into a base url, projection and constraint */ /* expression. */ /* -------------------------------------------------------------------- */ char *pszWrkURL = CPLStrdup( pszNewName + 5 ); char *pszFound; pszFound = strstr(pszWrkURL,"&"); if( pszFound ) { oConstraints = pszFound; *pszFound = '\0'; } pszFound = strstr(pszWrkURL,"?"); if( pszFound ) { oProjection = pszFound+1; *pszFound = '\0'; } // Trim common requests. int nLen = strlen(pszWrkURL); if( strcmp(pszWrkURL+nLen-4,".das") == 0 ) pszWrkURL[nLen-4] = '\0'; else if( strcmp(pszWrkURL+nLen-4,".dds") == 0 ) pszWrkURL[nLen-4] = '\0'; else if( strcmp(pszWrkURL+nLen-4,".asc") == 0 ) pszWrkURL[nLen-4] = '\0'; else if( strcmp(pszWrkURL+nLen-5,".dods") == 0 ) pszWrkURL[nLen-5] = '\0'; else if( strcmp(pszWrkURL+nLen-5,".html") == 0 ) pszWrkURL[nLen-5] = '\0'; oBaseURL = pszWrkURL; CPLFree( pszWrkURL ); /* -------------------------------------------------------------------- */ /* Do we want to override the .dodsrc file setting? Only do */ /* the putenv() if there isn't already a DODS_CONF in the */ /* environment. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "DODS_CONF", NULL ) != NULL && getenv("DODS_CONF") == NULL ) { static char szDODS_CONF[1000]; sprintf( szDODS_CONF, "DODS_CONF=%.980s", CPLGetConfigOption( "DODS_CONF", "" ) ); putenv( szDODS_CONF ); } /* -------------------------------------------------------------------- */ /* If we have a overridding AIS file location, apply it now. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "DODS_AIS_FILE", NULL ) != NULL ) { string oAISFile = CPLGetConfigOption( "DODS_AIS_FILE", "" ); RCReader::instance()->set_ais_database( oAISFile ); } /* -------------------------------------------------------------------- */ /* Connect to the server. */ /* -------------------------------------------------------------------- */ string version; try { poConnection = new AISConnect( oBaseURL ); version = poConnection->request_version(); } catch (Error &e) { CPLError(CE_Failure, CPLE_OpenFailed, "%s", e.get_error_message().c_str() ); return FALSE; } /* -------------------------------------------------------------------- */ /* We presume we only work with version 3 servers. */ /* -------------------------------------------------------------------- */ if (version.empty() || version.find("/3.") == string::npos) { CPLError( CE_Warning, CPLE_AppDefined, "I connected to the URL but could not get a DAP 3.x version string\n" "from the server. I will continue to connect but access may fail."); } /* -------------------------------------------------------------------- */ /* Fetch the DAS and DDS info about the server. */ /* -------------------------------------------------------------------- */ try { poConnection->request_das( oDAS ); poConnection->request_dds( *poDDS, oProjection + oConstraints ); } catch (Error &e) { CPLError(CE_Failure, CPLE_AppDefined, "Error fetching DAS or DDS:\n%s", e.get_error_message().c_str() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Do we have any ogr_layer_info attributes in the DAS? If so, */ /* use them to define the layers. */ /* -------------------------------------------------------------------- */ AttrTable::Attr_iter dv_i; #ifdef LIBDAP_39 AttrTable* poTable = oDAS.container(); if (poTable == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get container"); return FALSE; } #else AttrTable* poTable = &oDAS; #endif for( dv_i = poTable->attr_begin(); dv_i != poTable->attr_end(); dv_i++ ) { if( EQUALN(poTable->get_name(dv_i).c_str(),"ogr_layer_info",14) && poTable->is_container( dv_i ) ) { AttrTable *poAttr = poTable->get_attr_table( dv_i ); string target_container = poAttr->get_attr( "target_container" ); BaseType *poVar = poDDS->var( target_container.c_str() ); if( poVar == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Unable to find variable '%s' named in\n" "ogr_layer_info.target_container, skipping.", target_container.c_str() ); continue; } if( poVar->type() == dods_sequence_c ) AddLayer( new OGRDODSSequenceLayer(this, target_container.c_str(), poAttr) ); else if( poVar->type() == dods_grid_c || poVar->type() == dods_array_c ) AddLayer( new OGRDODSGridLayer(this,target_container.c_str(), poAttr) ); } } /* -------------------------------------------------------------------- */ /* Walk through the DODS variables looking for easily targetted */ /* ones. Eventually this will need to be driven by the AIS info. */ /* -------------------------------------------------------------------- */ if( nLayers == 0 ) { DDS::Vars_iter v_i; for( v_i = poDDS->var_begin(); v_i != poDDS->var_end(); v_i++ ) { BaseType *poVar = *v_i; if( poVar->type() == dods_sequence_c ) AddLayer( new OGRDODSSequenceLayer(this,poVar->name().c_str(), NULL) ); else if( poVar->type() == dods_grid_c || poVar->type() == dods_array_c ) AddLayer( new OGRDODSGridLayer(this,poVar->name().c_str(), NULL) ); } } return TRUE; }
OGRDODSGridLayer::OGRDODSGridLayer( OGRDODSDataSource *poDSIn, const char *pszTargetIn, AttrTable *poOGRLayerInfoIn ) : OGRDODSLayer( poDSIn, pszTargetIn, poOGRLayerInfoIn ), poTargetGrid(NULL), poTargetArray(NULL), nArrayRefCount(0), paoArrayRefs(NULL), nDimCount(0), paoDimensions(NULL), nMaxRawIndex(0) { /* -------------------------------------------------------------------- */ /* What is the layer name? */ /* -------------------------------------------------------------------- */ string oLayerName; const char *pszLayerName = pszTargetIn; if( poOGRLayerInfo != NULL ) { oLayerName = poOGRLayerInfo->get_attr( "layer_name" ); if( strlen(oLayerName.c_str()) > 0 ) pszLayerName = oLayerName.c_str(); } poFeatureDefn = new OGRFeatureDefn( pszLayerName ); poFeatureDefn->Reference(); /* -------------------------------------------------------------------- */ /* Fetch the target variable. */ /* -------------------------------------------------------------------- */ BaseType *poTargVar = poDS->poDDS->var( pszTargetIn ); if( poTargVar->type() == dods_grid_c ) { poTargetGrid = dynamic_cast<Grid *>( poTargVar ); poTargetArray = dynamic_cast<Array *>(poTargetGrid->array_var()); } else if( poTargVar->type() == dods_array_c ) { poTargetGrid = NULL; poTargetArray = dynamic_cast<Array *>( poTargVar ); } else { CPLAssert( false ); return; } /* -------------------------------------------------------------------- */ /* Count arrays in use. */ /* -------------------------------------------------------------------- */ AttrTable *poExtraContainers = NULL; nArrayRefCount = 1; // primary target. if( poOGRLayerInfo != NULL ) poExtraContainers = poOGRLayerInfo->find_container("extra_containers"); if( poExtraContainers != NULL ) { AttrTable::Attr_iter dv_i; for( dv_i = poExtraContainers->attr_begin(); dv_i != poExtraContainers->attr_end(); dv_i++ ) { nArrayRefCount++; } } /* -------------------------------------------------------------------- */ /* Collect extra_containers. */ /* -------------------------------------------------------------------- */ paoArrayRefs = new OGRDODSArrayRef[nArrayRefCount]; paoArrayRefs[0].pszName = CPLStrdup( pszTargetIn ); paoArrayRefs[0].poArray = poTargetArray; nArrayRefCount = 1; if( poExtraContainers != NULL ) { AttrTable::Attr_iter dv_i; for( dv_i = poExtraContainers->attr_begin(); dv_i != poExtraContainers->attr_end(); dv_i++ ) { const char *pszTargetName=poExtraContainers->get_attr(dv_i).c_str(); BaseType *poExtraTarget = poDS->poDDS->var( pszTargetName ); if( poExtraTarget == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Unable to find extra_container '%s', skipping.", pszTargetName ); continue; } if( poExtraTarget->type() == dods_array_c ) paoArrayRefs[nArrayRefCount].poArray = dynamic_cast<Array *>( poExtraTarget ); else if( poExtraTarget->type() == dods_grid_c ) { Grid *poGrid = dynamic_cast<Grid *>( poExtraTarget ); paoArrayRefs[nArrayRefCount].poArray = dynamic_cast<Array *>( poGrid->array_var() ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Target container '%s' is not grid or array, skipping.", pszTargetName ); continue; } paoArrayRefs[nArrayRefCount++].pszName = CPLStrdup(pszTargetName); } } /* -------------------------------------------------------------------- */ /* Collect dimension information. */ /* -------------------------------------------------------------------- */ int iDim; Array::Dim_iter iterDim; nDimCount = poTargetArray->dimensions(); paoDimensions = new OGRDODSDim[nDimCount]; nMaxRawIndex = 1; for( iterDim = poTargetArray->dim_begin(), iDim = 0; iterDim != poTargetArray->dim_end(); iterDim++, iDim++ ) { paoDimensions[iDim].pszDimName = CPLStrdup(poTargetArray->dimension_name(iterDim).c_str()); paoDimensions[iDim].nDimStart = poTargetArray->dimension_start(iterDim); paoDimensions[iDim].nDimEnd = poTargetArray->dimension_stop(iterDim); paoDimensions[iDim].nDimStride = poTargetArray->dimension_stride(iterDim); paoDimensions[iDim].poMap = NULL; paoDimensions[iDim].nDimEntries = (paoDimensions[iDim].nDimEnd + 1 - paoDimensions[iDim].nDimStart + paoDimensions[iDim].nDimStride - 1) / paoDimensions[iDim].nDimStride; nMaxRawIndex *= paoDimensions[iDim].nDimEntries; } /* -------------------------------------------------------------------- */ /* If we are working with a grid, collect the maps. */ /* -------------------------------------------------------------------- */ if( poTargetGrid != NULL ) { int iMap; Grid::Map_iter iterMap; for( iterMap = poTargetGrid->map_begin(), iMap = 0; iterMap != poTargetGrid->map_end(); iterMap++, iMap++ ) { paoDimensions[iMap].poMap = dynamic_cast<Array *>(*iterMap); } CPLAssert( iMap == nDimCount ); } /* -------------------------------------------------------------------- */ /* Setup field definitions. The first nDimCount will be the */ /* dimension attributes, and after that comes the actual target */ /* array. */ /* -------------------------------------------------------------------- */ for( iDim = 0; iDim < nDimCount; iDim++ ) { OGRFieldDefn oField( paoDimensions[iDim].pszDimName, OFTInteger ); if( EQUAL(oField.GetNameRef(), poTargetArray->name().c_str()) ) oField.SetName(CPLSPrintf("%s_i",paoDimensions[iDim].pszDimName)); if( paoDimensions[iDim].poMap != NULL ) { switch( paoDimensions[iDim].poMap->var()->type() ) { case dods_byte_c: case dods_int16_c: case dods_uint16_c: case dods_int32_c: case dods_uint32_c: oField.SetType( OFTInteger ); break; case dods_float32_c: case dods_float64_c: oField.SetType( OFTReal ); break; case dods_str_c: case dods_url_c: oField.SetType( OFTString ); break; default: // Ignore break; } } poFeatureDefn->AddFieldDefn( &oField ); } /* -------------------------------------------------------------------- */ /* Setup the array attributes themselves. */ /* -------------------------------------------------------------------- */ int iArray; for( iArray=0; iArray < nArrayRefCount; iArray++ ) { OGRDODSArrayRef *poRef = paoArrayRefs + iArray; OGRFieldDefn oArrayField( poRef->poArray->name().c_str(), OFTInteger ); switch( poRef->poArray->var()->type() ) { case dods_byte_c: case dods_int16_c: case dods_uint16_c: case dods_int32_c: case dods_uint32_c: oArrayField.SetType( OFTInteger ); break; case dods_float32_c: case dods_float64_c: oArrayField.SetType( OFTReal ); break; case dods_str_c: case dods_url_c: oArrayField.SetType( OFTString ); break; default: // Ignore break; } poFeatureDefn->AddFieldDefn( &oArrayField ); poRef->iFieldIndex = poFeatureDefn->GetFieldCount() - 1; } /* -------------------------------------------------------------------- */ /* X/Y/Z fields. */ /* -------------------------------------------------------------------- */ if( poOGRLayerInfo != NULL ) { AttrTable *poField = poOGRLayerInfo->find_container("x_field"); if( poField != NULL ) { oXField.Initialize( poField ); oXField.iFieldIndex = poFeatureDefn->GetFieldIndex( oXField.pszFieldName ); } poField = poOGRLayerInfo->find_container("y_field"); if( poField != NULL ) { oYField.Initialize( poField ); oYField.iFieldIndex = poFeatureDefn->GetFieldIndex( oYField.pszFieldName ); } poField = poOGRLayerInfo->find_container("z_field"); if( poField != NULL ) { oZField.Initialize( poField ); oZField.iFieldIndex = poFeatureDefn->GetFieldIndex( oZField.pszFieldName ); } } /* -------------------------------------------------------------------- */ /* If we have no layerinfo, then check if there are obvious x/y */ /* fields. */ /* -------------------------------------------------------------------- */ else { if( poFeatureDefn->GetFieldIndex( "lat" ) != -1 && poFeatureDefn->GetFieldIndex( "lon" ) != -1 ) { oXField.Initialize( "lon", "dds" ); oXField.iFieldIndex = poFeatureDefn->GetFieldIndex( "lon" ); oYField.Initialize( "lat", "dds" ); oYField.iFieldIndex = poFeatureDefn->GetFieldIndex( "lat" ); } else if( poFeatureDefn->GetFieldIndex( "latitude" ) != -1 && poFeatureDefn->GetFieldIndex( "longitude" ) != -1 ) { oXField.Initialize( "longitude", "dds" ); oXField.iFieldIndex = poFeatureDefn->GetFieldIndex( "longitude" ); oYField.Initialize( "latitude", "dds" ); oYField.iFieldIndex = poFeatureDefn->GetFieldIndex( "latitude" ); } } /* -------------------------------------------------------------------- */ /* Set the layer geometry type if we have point inputs. */ /* -------------------------------------------------------------------- */ if( oZField.iFieldIndex >= 0 ) poFeatureDefn->SetGeomType( wkbPoint25D ); else if( oXField.iFieldIndex >= 0 && oYField.iFieldIndex >= 0 ) poFeatureDefn->SetGeomType( wkbPoint ); else poFeatureDefn->SetGeomType( wkbNone ); }
int main() { size_t numItems = 10000000; AttrTable at; at.addVectorAttr("P", V3f(0.0)); at.addFloatAttr("float_attr", 1, std::vector<float>(1, 0.0)); at.addIntAttr("int_attr", 1, std::vector<int>(1, 0)); at.resize(numItems); // First we iterate explicitly over all points { boost::timer::auto_cpu_timer timer; AttrRef pRef = at.vectorAttrRef("P"); AttrRef floatRef = at.floatAttrRef("float_attr"); AttrRef intRef = at.intAttrRef("int_attr"); V3f pVal(0.0); float floatVal(0.0); int intVal(0); for (size_t i = 0, end = at.size(); i != end; ++i) { pVal += at.vectorAttr(pRef, i); floatVal += at.floatAttr(floatRef, i, 0); intVal += at.intAttr(intRef, i, 0); } timer.stop(); cout << "Time to iterate explicitly: "; timer.report(); } // Then, we introduce a global attribute map ParamMap params; params.intMap["int_attr"] = 1; params.floatMap["float_attr"] = 1.0; params.intMap["int_attr_2"] = 1; params.floatMap["float_attr_2"] = 1.0; { boost::timer::auto_cpu_timer timer; AttrRef pRef = at.vectorAttrRef("P"); AttrRef floatRef = at.floatAttrRef("float_attr"); AttrRef intRef = at.intAttrRef("int_attr"); AttrRef floatRef2 = at.floatAttrRef("float_attr_2"); AttrRef intRef2 = at.intAttrRef("int_attr_2"); V3f pVal(0.0); float floatVal(0.0), floatVal2(0.0); int intVal(0), intVal2(0); if (pRef.isValid()) { for (size_t i = 0, end = at.size(); i != end; ++i) { pVal += at.vectorAttr(pRef, i); } } else { pVal += params.vectorMap["P"] * at.size(); } if (floatRef.isValid()) { for (size_t i = 0, end = at.size(); i != end; ++i) { floatVal += at.floatAttr(floatRef, i, 0); } } else { floatVal += params.floatMap["float_attr"] * at.size(); } if (intRef.isValid()) { for (size_t i = 0, end = at.size(); i != end; ++i) { intVal += at.intAttr(intRef, i, 0); } } else { intVal += params.intMap["int_attr"] * at.size(); } if (floatRef2.isValid()) { for (size_t i = 0, end = at.size(); i != end; ++i) { floatVal2 += at.floatAttr(floatRef2, i, 0); } } else { floatVal2 += params.floatMap["float_attr_2"] * at.size(); } if (intRef2.isValid()) { for (size_t i = 0, end = at.size(); i != end; ++i) { intVal2 += at.intAttr(intRef2, i, 0); } } else { intVal2 += params.intMap["int_attr_2"] * at.size(); } timer.stop(); cout << "Time to iterate explicitly with param map: "; timer.report(); cout << pVal << " " << floatVal << " " << floatVal2 << " " << intVal << " " << intVal2 << endl; } // Lastly, we iterate using AttrVisitor { boost::timer::auto_cpu_timer timer; AttrVisitor visitor(at, params); Attr<V3f> p("P"); Attr<float> float1("float_attr"); Attr<float> float2("float_attr_2"); Attr<int> int1("int_attr"); Attr<int> int2("int_attr_2"); V3f pVal(0.0); float floatVal(0.0), floatVal2(0.0); int intVal(0), intVal2(0); for (AttrVisitor::const_iterator i = visitor.begin(), end = visitor.end(); i != end; ++i) { i.update(p); i.update(float1); i.update(float2); i.update(int1); i.update(int2); pVal += p.value(); floatVal += float1.value(); floatVal2 += float2.value(); intVal += int1.value(); intVal2 += int2.value(); } timer.stop(); cout << "Time to iterate using AttrVisitor: "; timer.report(); cout << pVal << " " << floatVal << " " << floatVal2 << " " << intVal << " " << intVal2 << endl; } }