FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { TileKey key = *query.tileKey(); int z = key.getLevelOfDetail(); int tileX = key.getTileX(); int tileY = key.getTileY(); unsigned int numRows, numCols; key.getProfile()->getNumTiles(key.getLevelOfDetail(), numCols, numRows); tileY = numRows - tileY - 1; //Get the image sqlite3_stmt* select = NULL; std::string queryStr = "SELECT tile_data from tiles where zoom_level = ? AND tile_column = ? AND tile_row = ?"; int rc = sqlite3_prepare_v2( _database, queryStr.c_str(), -1, &select, 0L ); if ( rc != SQLITE_OK ) { OE_WARN << LC << "Failed to prepare SQL: " << queryStr << "; " << sqlite3_errmsg(_database) << std::endl; return NULL; } bool valid = true; sqlite3_bind_int( select, 1, z ); sqlite3_bind_int( select, 2, tileX ); sqlite3_bind_int( select, 3, tileY ); rc = sqlite3_step( select ); FeatureList features; if ( rc == SQLITE_ROW) { // the pointer returned from _blob gets freed internally by sqlite, supposedly const char* data = (const char*)sqlite3_column_blob( select, 0 ); int dataLen = sqlite3_column_bytes( select, 0 ); std::string dataBuffer( data, dataLen ); std::stringstream in(dataBuffer); MVT::read(in, key, features); } else { OE_DEBUG << LC << "SQL QUERY failed for " << queryStr << ": " << std::endl; valid = false; } sqlite3_finalize( select ); // apply filters before returning. applyFilters( features ); if (!features.empty()) { //OE_NOTICE << "Returning " << features.size() << " features" << std::endl; return new FeatureListCursor(features); } return 0; }
void CollectionFilterState::push( const FeatureList& input ) { for( FeatureList::const_iterator i = input.begin(); i != input.end(); i++ ) if ( i->get()->hasShapeData() ) features.push_back( i->get() ); }
FilterContext ScaleFilter::push( FeatureList& input, FilterContext& cx ) { for( FeatureList::iterator i = input.begin(); i != input.end(); ++i ) { Feature* input = i->get(); if ( input && input->getGeometry() ) { Bounds envelope = input->getGeometry()->getBounds(); // now scale and shift everything GeometryIterator scale_iter( input->getGeometry() ); while( scale_iter.hasMore() ) { Geometry* geom = scale_iter.next(); for( osg::Vec3dArray::iterator v = geom->begin(); v != geom->end(); v++ ) { double xr = (v->x() - envelope.xMin()) / envelope.width(); v->x() += (xr - 0.5) * _scale; double yr = (v->y() - envelope.yMin()) / envelope.height(); v->y() += (yr - 0.5) * _scale; } } } } return cx; }
FilterContext ScriptFilter::push( FeatureList& input, FilterContext& context ) { if ( !isSupported() ) { OE_WARN << "ScriptFilter support not enabled" << std::endl; return context; } if (!_engine.valid()) { OE_WARN << "No scripting engine\n"; return context; } bool ok = true; for( FeatureList::iterator i = input.begin(); i != input.end(); ) { if ( push( i->get(), context ) ) { ++i; } else { i = input.erase(i); } } return context; }
ReaderWriter::FeatureList ReaderWriter::featureAsString(ReaderWriter::Features feature) { typedef struct { ReaderWriter::Features feature; const char *s; } FeatureStringList; FeatureStringList list[] = { { FEATURE_READ_OBJECT, "readObject" }, { FEATURE_READ_IMAGE, "readImage" }, { FEATURE_READ_HEIGHT_FIELD, "readHeightField" }, { FEATURE_READ_NODE, "readNode" }, { FEATURE_READ_SHADER, "readShader" }, { FEATURE_WRITE_OBJECT, "writeObject" }, { FEATURE_WRITE_IMAGE, "writeImage" }, { FEATURE_WRITE_HEIGHT_FIELD, "writeHeightField" }, { FEATURE_WRITE_NODE, "writeNode" }, { FEATURE_WRITE_SHADER, "writeShader" }, { FEATURE_NONE,0 } }; FeatureList result; for(FeatureStringList *p=list; p->feature != 0; p++) { if ((feature & p->feature) != 0) result.push_back(p->s); } return result; }
FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { FeatureCursor* result = 0L; std::string url = createURL( query ); // check the blacklist: if ( Registry::instance()->isBlacklisted(url) ) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url); // read the data: ReadResult r = uri.readString( _dbOptions.get() ); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible const std::string& mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); dataOK = getFeatures( buffer, mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //If we have any filters, process them here before the cursor is created if (!_options.filters().empty()) { // preprocess the features using the filter list: if ( features.size() > 0 ) { FilterContext cx; cx.setProfile( getFeatureProfile() ); for( FeatureFilterList::const_iterator i = _options.filters().begin(); i != _options.filters().end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( features, cx ); } } } //result = new FeatureListCursor(features); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }
FeatureList BufferFilter::process( Feature* input, FilterEnv* env ) { FeatureList output; GeoShapeList& shapes = input->getShapes(); GeoShapeList new_shapes; double b = getDistance(); if ( env->getInputSRS()->isGeographic() ) { // for geo, convert from meters to degrees //TODO: we SHOULD do this for each and every feature buffer segment, but // for how this is a shortcut approximation. double bc = b/1.4142; osg::Vec2d vec( bc, bc ); //vec.normalize(); GeoPoint c = input->getExtent().getCentroid(); osg::Vec2d p0( c.x(), c.y() ); osg::Vec2d p1; Units::convertLinearToAngularVector( vec, Units::METERS, Units::DEGREES, p0, p1 ); b = (p1-p0).length(); } for( GeoShapeList::iterator i = shapes.begin(); i != shapes.end(); i++ ) { GeoPartList new_parts; GeoShape& shape = *i; if ( shape.getShapeType() == GeoShape::TYPE_POLYGON ) { GeoShape new_shape( GeoShape::TYPE_POLYGON, shape.getSRS() ); bufferPolygons( shape, b, new_shape.getParts() ); new_shapes.push_back( new_shape ); } else if ( shape.getShapeType() == GeoShape::TYPE_LINE ) { if ( getConvertToPolygon() ) { GeoShape new_shape( GeoShape::TYPE_POLYGON, shape.getSRS() ); bufferLinesToPolygons( shape, b, new_shape ); new_shapes.push_back( new_shape ); } else { GeoShape new_shape( GeoShape::TYPE_LINE, shape.getSRS() ); bufferLinesToLines( shape, b, new_shape ); new_shapes.push_back( new_shape ); } } } if ( new_shapes.size() > 0 ) input->getShapes().swap( new_shapes ); output.push_back( input ); return output; }
// reads a chunk of features into a memory cache; do this for performance // and to avoid needing the OGR Mutex every time void FeatureCursorOGR::readChunk() { if ( !_resultSetHandle ) return; OGR_SCOPED_LOCK; while( _queue.size() < _chunkSize && !_resultSetEndReached ) { FeatureList filterList; while( filterList.size() < _chunkSize && !_resultSetEndReached ) { OGRFeatureH handle = OGR_L_GetNextFeature( _resultSetHandle ); if ( handle ) { osg::ref_ptr<Feature> feature = OgrUtils::createFeature( handle, _profile.get() ); if (feature.valid() && !_source->isBlacklisted( feature->getFID() ) && validateGeometry( feature->getGeometry() )) { filterList.push_back( feature.release() ); } OGR_F_Destroy( handle ); } else { _resultSetEndReached = true; } } // preprocess the features using the filter list: if ( !_filters.empty() ) { FilterContext cx; cx.setProfile( _profile.get() ); if (_query.bounds().isSet()) { cx.extent() = GeoExtent(_profile->getSRS(), _query.bounds().get()); } else { cx.extent() = _profile->getExtent(); } for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( filterList, cx ); } } for(FeatureList::const_iterator i = filterList.begin(); i != filterList.end(); ++i) { _queue.push( i->get() ); } } }
/* Build Object */ ClassStatement* buildObject() { FeatureList* methods = new FeatureList(); methods->add(new FeatureOption(new FormalDeclare(new Id(new string("vtable")), new Type(new string("Int64"))))); methods->add(new FeatureOption(new Feature(new Id(new string("abort")), new ListFormalDeclare(), new Type(new string("Object")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("type_name")), new ListFormalDeclare(), new Type(new string("SELF_TYPE")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("copy")), new ListFormalDeclare(), new Type(new string("SELF_TYPE")), new ExprList()))); return new ClassStatement(new Type(new string("Object")), nullptr, methods); }
void ImageOverlay::init() { OpenThreads::ScopedLock< OpenThreads::Mutex > lock(_mutex); if (_root->getNumChildren() > 0) { _root->removeChildren(0, _root->getNumChildren()); } if ( !_clampCallback.valid() ) { _clampCallback = new TerrainCallbackAdapter<ImageOverlay>(this); } if ( getMapNode() ) { const SpatialReference* mapSRS = getMapNode()->getMapSRS(); // calculate a bounding polytope in world space (for mesh clamping): osg::ref_ptr<Feature> f = new Feature( new Polygon(), mapSRS->getGeodeticSRS() ); Geometry* g = f->getGeometry(); g->push_back( osg::Vec3d(_lowerLeft.x(), _lowerLeft.y(), 0) ); g->push_back( osg::Vec3d(_lowerRight.x(), _lowerRight.y(), 0) ); g->push_back( osg::Vec3d(_upperRight.x(), _upperRight.y(), 0) ); g->push_back( osg::Vec3d(_upperLeft.x(), _upperLeft.y(), 0) ); f->getWorldBoundingPolytope( getMapNode()->getMapSRS(), _boundingPolytope ); FeatureList features; if (!mapSRS->isGeographic()) { f->splitAcrossDateLine(features); } else { features.push_back( f ); } for (FeatureList::iterator itr = features.begin(); itr != features.end(); ++itr) { _root->addChild(createNode(itr->get(), features.size() > 1)); } _dirty = false; // Set the annotation up for auto-clamping. We always need to auto-clamp a draped image // so that the mesh roughly conforms with the surface, otherwise the draping routine // might clip it. Style style; style.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN; applyStyle( style ); setLightingIfNotSet( false ); getMapNode()->getTerrain()->addTerrainCallback( _clampCallback.get() ); clamp( getMapNode()->getTerrain()->getGraph(), getMapNode()->getTerrain() ); } }
osg::Node* GeometryCompiler::compile(Feature* feature, const Style& style, const FilterContext& context) { FeatureList workingSet; workingSet.push_back(feature); return compile(workingSet, style, context); }
void AltitudeFilter::pushAndDontClamp( FeatureList& features, FilterContext& cx ) { NumericExpression scaleExpr; if ( _altitude.valid() && _altitude->verticalScale().isSet() ) scaleExpr = *_altitude->verticalScale(); NumericExpression offsetExpr; if ( _altitude.valid() && _altitude->verticalOffset().isSet() ) offsetExpr = *_altitude->verticalOffset(); for( FeatureList::iterator i = features.begin(); i != features.end(); ++i ) { Feature* feature = i->get(); // run a symbol script if present. if ( _altitude.valid() && _altitude->script().isSet() ) { StringExpression temp( _altitude->script().get() ); feature->eval( temp, &cx ); } double minHAT = DBL_MAX; double maxHAT = -DBL_MAX; double scaleZ = 1.0; if ( _altitude.valid() && _altitude->verticalScale().isSet() ) scaleZ = feature->eval( scaleExpr, &cx ); double offsetZ = 0.0; if ( _altitude.valid() && _altitude->verticalOffset().isSet() ) offsetZ = feature->eval( offsetExpr, &cx ); GeometryIterator gi( feature->getGeometry() ); while( gi.hasMore() ) { Geometry* geom = gi.next(); for( Geometry::iterator g = geom->begin(); g != geom->end(); ++g ) { g->z() *= scaleZ; g->z() += offsetZ; if ( g->z() < minHAT ) minHAT = g->z(); if ( g->z() > maxHAT ) maxHAT = g->z(); } } if ( minHAT != DBL_MAX ) { feature->set( "__min_hat", minHAT ); feature->set( "__max_hat", maxHAT ); } } }
virtual void traverse( FeatureTile* tile) { if (tile->getFeatures().size() > 0) { //Actually load up the features FeatureList features; for (FeatureIDList::const_iterator i = tile->getFeatures().begin(); i != tile->getFeatures().end(); i++) { Feature* f = _features->getFeature( *i ); if (f) { //Reproject the feature to the dest SRS if it's not already if (!f->getSRS()->isEquivalentTo( _srs ) ) { f->transform( _srs ); } features.push_back( f ); } else { OE_NOTICE << "couldn't get feature " << *i << std::endl; } } //Need to do the cropping again since these are brand new features coming from the feature source. CropFilter cropFilter(_cropMethod); FilterContext context(0); context.extent() = tile->getExtent(); cropFilter.push( features, context ); std::string contents = Feature::featuresToGeoJSON( features ); std::stringstream buf; int x = tile->getKey().getTileX(); unsigned int numRows, numCols; tile->getKey().getProfile()->getNumTiles(tile->getKey().getLevelOfDetail(), numCols, numRows); int y = numRows - tile->getKey().getTileY() - 1; buf << _dest << "/" << tile->getKey().getLevelOfDetail() << "/" << x << "/" << y << ".json"; std::string filename = buf.str(); //OE_NOTICE << "Writing " << features.size() << " features to " << filename << std::endl; if ( !osgDB::fileExists( osgDB::getFilePath(filename) ) ) osgEarth::makeDirectoryForFile( filename ); std::fstream output( filename.c_str(), std::ios_base::out ); if ( output.is_open() ) { output << contents; output.flush(); output.close(); } } tile->traverse( this ); }
ClassStatement* buildConvert() { FeatureList* methods = new FeatureList(); const char * const types[] = { "Int", "Int64", "Int32", "Int8", "Float" }; for(string type : types) { methods->add(buildConvertFunc(type)); } return new ClassStatement(new Type(new string("Convert")), new Type(new string("Object")), methods, true); }
virtual FilterContext push( FeatureList& input, FilterContext& context ) { for (FeatureList::iterator itr = input.begin(); itr != input.end(); itr++) { //Change the value of the attribute if (_key.isSet() && _value.isSet()) { itr->get()->set(*_key, std::string(*_value)); } } return context; }
FilterContext ClampFilter::push( FeatureList& features, const FilterContext& cx ) { const Session* session = cx.getSession(); if ( !session ) { OE_WARN << LC << "No session - session is required for elevation clamping" << std::endl; return cx; } // the map against which we'll be doing elevation clamping MapFrame mapf = session->createMapFrame( Map::ELEVATION_LAYERS ); const SpatialReference* mapSRS = mapf.getProfile()->getSRS(); const SpatialReference* featureSRS = cx.profile()->getSRS(); bool isGeocentric = session->getMapInfo().isGeocentric(); // establish an elevation query interface based on the features' SRS. ElevationQuery eq( mapf ); for( FeatureList::iterator i = features.begin(); i != features.end(); ++i ) { Feature* feature = i->get(); GeometryIterator gi( feature->getGeometry() ); while( gi.hasMore() ) { Geometry* geom = gi.next(); if ( isGeocentric ) { // convert to map coords: cx.toWorld( geom ); mapSRS->transformFromECEF( geom ); // populate the elevations: eq.getElevations( geom, mapSRS ); // convert back to geocentric: mapSRS->transformToECEF( geom ); cx.toLocal( geom ); } else { // clamps the entire array to the highest available resolution. eq.getElevations( geom, featureSRS ); } } } return cx; }
void FeatureCursorCDBV::Read_Data_Directly(void) { FeatureList preProcessList; OGR_SCOPED_LOCK; OGR_L_ResetReading(_layerHandle); OGRFeatureH feat_handle; OGRLayer * thislayer = (OGRLayer *)_layerHandle; int totalCount = thislayer->GetFeatureCount(); int fcount = -1; while ((feat_handle = OGR_L_GetNextFeature(_layerHandle)) != NULL) { ++fcount; if (feat_handle) { osg::ref_ptr<Feature> f = OgrUtils::createFeature(feat_handle, _profile.get()); if (f.valid() && !_source->isBlacklisted(f->getFID())) { if (isGeometryValid(f->getGeometry())) { _queue.push(f); if (_filters.size() > 0) { preProcessList.push_back(f.release()); } } else { OE_DEBUG << LC << "Skipping feature with invalid geometry: " << f->getGeoJSON() << std::endl; } } OGR_F_Destroy(feat_handle); } } // preprocess the features using the filter list: if (preProcessList.size() > 0) { FilterContext cx; cx.setProfile(_profile.get()); for (FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { FeatureFilter* filter = i->get(); cx = filter->push(preProcessList, cx); } } }
virtual void traverse( FeatureTile* tile) { if (_added && _cropMethod != CropFilter::METHOD_CROPPING) return; bool traverse = true; GeoExtent featureExtent(_feature->getSRS(), _feature->getGeometry()->getBounds()); if (featureExtent.intersects( tile->getExtent())) { //If the node contains the feature, and it doesn't contain the max number of features add it. If it's already full then //split it. if (tile->getKey().getLevelOfDetail() >= (unsigned int)_firstLevel && (tile->getFeatures().size() < (unsigned int)_maxFeatures || tile->getKey().getLevelOfDetail() == _maxLevel || tile->getKey().getLevelOfDetail() == _levelAdded)) { if (_levelAdded < 0 || _levelAdded == tile->getKey().getLevelOfDetail()) { osg::ref_ptr< Feature > clone = new Feature( *_feature, osg::CopyOp::DEEP_COPY_ALL ); FeatureList features; features.push_back( clone ); CropFilter cropFilter(_cropMethod); FilterContext context(0); context.extent() = tile->getExtent(); cropFilter.push( features, context ); if (!features.empty() && clone->getGeometry() && clone->getGeometry()->isValid()) { //tile->getFeatures().push_back( clone ); tile->getFeatures().push_back( clone->getFID() ); _added = true; _levelAdded = tile->getKey().getLevelOfDetail(); _numAdded++; traverse = false; } } if (traverse || _cropMethod == CropFilter::METHOD_CROPPING) { tile->traverse( this ); } } else { tile->split(); tile->traverse( this ); } } }
FeatureCursor* FeatureListSource::createFeatureCursor( const Symbology::Query& query ) { //Create a copy of all of the features before returning the cursor. //The processing filters in osgEarth can modify the features as they are operating and we don't want our original data destroyed. FeatureList cursorFeatures; for (FeatureList::iterator itr = _features.begin(); itr != _features.end(); ++itr) { Feature* feature = new osgEarth::Features::Feature(*(itr->get()), osg::CopyOp::DEEP_COPY_ALL); cursorFeatures.push_back( feature ); } return new FeatureListCursor( cursorFeatures ); }
//clustering: // troll the external model for geodes. for each geode, create a geode in the target // model. then, for each geometry in that geode, replicate it once for each instance of // the model in the feature batch and transform the actual verts to a local offset // relative to the tile centroid. Finally, reassemble all the geodes and optimize. // hopefully stateset sharing etc will work out. we may need to strip out LODs too. bool SubstituteModelFilter::cluster(const FeatureList& features, const MarkerSymbol* symbol, Session* session, osg::Group* attachPoint, FilterContext& cx ) { MarkerToFeatures markerToFeatures; MarkerFactory factory( session); for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { Feature* f = i->get(); osg::ref_ptr< osg::Node > model = factory.getOrCreateNode( f, symbol ); //Try to find the existing entry if (model.valid()) { MarkerToFeatures::iterator itr = markerToFeatures.find( model.get() ); if (itr == markerToFeatures.end()) { markerToFeatures[ model.get() ].push_back( f ); } else { itr->second.push_back( f ); } } } /* OE_NOTICE << "Sorted models into " << markerToFeatures.size() << " buckets" << std::endl; for (MarkerToFeatures::iterator i = markerToFeatures.begin(); i != markerToFeatures.end(); ++i) { OE_NOTICE << " Bucket has " << i->second.size() << " features" << std::endl; } */ //For each model, cluster the features that use that model for (MarkerToFeatures::iterator i = markerToFeatures.begin(); i != markerToFeatures.end(); ++i) { osg::Node* clone = dynamic_cast<osg::Node*>( i->first->clone( osg::CopyOp::DEEP_COPY_ALL ) ); // ..and apply the clustering to the copy. ClusterVisitor cv( i->second, _modelMatrix, this, cx ); clone->accept( cv ); attachPoint->addChild( clone ); } return true; }
FeatureNode::FeatureNode(const FeatureList& features, const Style& style, const GeometryCompilerOptions& options, StyleSheet* styleSheet): AnnotationNode(), _options ( options ), _needsRebuild ( true ), _styleSheet ( styleSheet ), _clampDirty ( false ), _index ( 0 ) { _features.insert( _features.end(), features.begin(), features.end() ); setStyle( style ); }
FeatureNode::FeatureNode(MapNode* mapNode, FeatureList& features, const Style& style, const GeometryCompilerOptions& options, StyleSheet* styleSheet): AnnotationNode(), _options ( options ), _needsRebuild ( true ), _styleSheet ( styleSheet ) { _features.insert( _features.end(), features.begin(), features.end() ); FeatureNode::setMapNode( mapNode ); setStyle( style ); }
ClassStatement* buildIO() { FeatureList* methods = new FeatureList(); ListFormalDeclare* outStringList = new ListFormalDeclare(); ListFormalDeclare* outIntList = new ListFormalDeclare(); outStringList->add(new FormalDeclare(new Id(new string("x")), new Type(new string("String")), nullptr)); outIntList->add(new FormalDeclare(new Id(new string("x")), new Type(new string("Int")), nullptr)); methods->add(new FeatureOption(new Feature(new Id(new string("out_string")), outStringList, new Type(new string("SELF_TYPE")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("out_int")),outIntList, new Type(new string("SELF_TYPE")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("in_string")), new ListFormalDeclare(), new Type(new string("String")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("in_int")), new ListFormalDeclare(), new Type(new string("Int")), new ExprList()))); return new ClassStatement(new Type(new string("IO")), new Type(new string("Object")), methods); }
FilterContext TransformFilter::push( FeatureList& input, FilterContext& incx ) { _bbox = osg::BoundingBoxd(); // first transform all the points into the output SRS, collecting a bounding box as we go: bool ok = true; for( FeatureList::iterator i = input.begin(); i != input.end(); i++ ) if ( !push( i->get(), incx ) ) ok = false; FilterContext outcx( incx ); outcx.isGeocentric() = _makeGeocentric; if ( _outputSRS.valid() ) { if ( incx.extent()->isValid() ) outcx.profile() = new FeatureProfile( incx.extent()->transform( _outputSRS.get() ) ); else outcx.profile() = new FeatureProfile( incx.profile()->getExtent().transform( _outputSRS.get() ) ); } // set the reference frame to shift data to the centroid. This will // prevent floating point precision errors in the openGL pipeline for // properly gridded data. if ( _bbox.valid() && _localize ) { // create a suitable reference frame: osg::Matrixd localizer; if ( _makeGeocentric ) { localizer = createGeocentricInvRefFrame( _bbox.center(), _outputSRS.get() ); localizer.invert( localizer ); } else { localizer = osg::Matrixd::translate( -_bbox.center() ); } // localize the geometry relative to the reference frame. for( FeatureList::iterator i = input.begin(); i != input.end(); i++ ) { localizeGeometry( i->get(), localizer ); } outcx.setReferenceFrame( localizer ); } return outcx; }
FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { FeatureCursor* result = 0L; std::string url = createURL( query ); if (url.empty()) return 0; // check the blacklist: if ( Registry::instance()->isBlacklisted(url) ) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url); // read the data: ReadResult r = uri.readString( _dbOptions.get() ); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible std::string mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); //If the mimetype is empty then try to set it from the format specification if (mimeType.empty()) { if (_options.format().value() == "json") mimeType = "json"; else if (_options.format().value().compare("gml") == 0) mimeType = "text/xml"; } dataOK = getFeatures( buffer, mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //result = new FeatureListCursor(features); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }
ClassStatement* buildString() { FeatureList* methods = new FeatureList(); ListFormalDeclare* concatParam = new ListFormalDeclare(); ListFormalDeclare* substrParam = new ListFormalDeclare(); concatParam->add(new FormalDeclare(new Id(new string("s")), new Type(new string("String")), nullptr)); substrParam->add(new FormalDeclare(new Id(new string("i")), new Type(new string("Int")), nullptr)); substrParam->add(new FormalDeclare(new Id(new string("l")), new Type(new string("Int")), nullptr)); methods->add(new FeatureOption(new FormalDeclare(new Id(new string("theString")), new Type(new string("Bool"))))); methods->add(new FeatureOption(new Feature(new Id(new string("length")), new ListFormalDeclare(), new Type(new string("Int")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("concat")), concatParam, new Type(new string("String")), new ExprList()))); methods->add(new FeatureOption(new Feature(new Id(new string("substr")), substrParam, new Type(new string("String")), new ExprList()))); return new ClassStatement(new Type(new string("String")), new Type(new string("Object")), methods, true); }
FilterContext ResampleFilter::push( FeatureList& input, FilterContext& context ) { if ( !isSupported() ) { OE_WARN << "ResampleFilter support not enabled" << std::endl; return context; } bool ok = true; for( FeatureList::iterator i = input.begin(); i != input.end(); ++i ) if ( !push( i->get(), context ) ) ok = false; return context; }
FeatureNode::FeatureNode(MapNode* mapNode, FeatureList& features, const Style& style, const GeometryCompilerOptions& options, StyleSheet* styleSheet): AnnotationNode( mapNode ), _style ( style ), _options ( options ), _needsRebuild (true), _clusterCulling(true), _clusterCullingCallback(0), _styleSheet( styleSheet ) { _features.insert( _features.end(), features.begin(), features.end() ); build(); }
osg::Vec3dArray* createBoundary( const SpatialReference* srs, ProgressCallback* progress ) { if ( _failed ) return 0L; if ( _features.valid() ) { if ( _features->getFeatureProfile() ) { osg::ref_ptr<FeatureCursor> cursor = _features->createFeatureCursor(); if ( cursor ) { if ( cursor->hasMore() ) { Feature* f = cursor->nextFeature(); if ( f && f->getGeometry() ) { // Init a filter to tranform feature in desired SRS if (!srs->isEquivalentTo(_features->getFeatureProfile()->getSRS())) { FilterContext cx; cx.profile() = new FeatureProfile(_features->getFeatureProfile()->getExtent()); //cx.isGeocentric() = _features->getFeatureProfile()->getSRS()->isGeographic(); TransformFilter xform( srs ); FeatureList featureList; featureList.push_back(f); cx = xform.push(featureList, cx); } return f->getGeometry()->toVec3dArray(); } } } } else { OE_WARN << LC << "Failed to create boundary; feature source has no SRS" << std::endl; _failed = true; } } else { OE_WARN << LC << "Unable to create boundary; invalid feature source" << std::endl; _failed = true; } return 0L; }
void FeatureCursor::fill( FeatureList& list ) { while( hasMore() ) { list.push_back( nextFeature() ); } }