bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature &feature ) const { feature.setValid( false ); gdal::ogr_feature_unique_ptr fet; #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) if ( !QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers( mSource->mDriverName ) ) { OGRLayerH nextFeatureBelongingLayer; bool found = false; // First pass: try to read from the last feature, in the hope the dataset // returns them in increasing feature id number (and as we use a std::set // for mFilterFids, we get them in increasing number by the iterator) // Second pass: reset before reading for ( int passNumber = 0; passNumber < 2; passNumber++ ) { while ( fet.reset( GDALDatasetGetNextFeature( mConn->ds, &nextFeatureBelongingLayer, nullptr, nullptr, nullptr ) ), fet ) { if ( nextFeatureBelongingLayer == mOgrLayer ) { if ( OGR_F_GetFID( fet.get() ) == FID_TO_NUMBER( id ) ) { found = true; break; } } } if ( found || passNumber == 1 ) { break; } GDALDatasetResetReading( mConn->ds ); } if ( !found ) { return false; } } else #endif { fet.reset( OGR_L_GetFeature( mOgrLayer, FID_TO_NUMBER( id ) ) ); } if ( !fet ) { return false; } if ( !readFeature( std::move( fet ), feature ) ) return false; feature.setValid( true ); geometryToDestinationCrs( feature, mTransform ); return true; }
/*! \brief Read feature from OGR layer at given offset (level 1) This function implements random access on level 1. \param Map pointer to Map_info structure \param[out] line_p container used to store line points within \param[out] line_c container used to store line categories within \param offset given offset \return line type \return 0 dead line \return -2 no more features \return -1 out of memory */ int V1_read_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, off_t offset) { long FID; int type; OGRGeometryH hGeom; G_debug(4, "V1_read_line_ogr() offset = %lu offset_num = %lu", (long) offset, (long) Map->fInfo.ogr.offset_num); if (offset >= Map->fInfo.ogr.offset_num) return -2; if (line_p != NULL) Vect_reset_line(line_p); if (line_c != NULL) Vect_reset_cats(line_c); FID = Map->fInfo.ogr.offset[offset]; G_debug(4, " FID = %ld", FID); /* coordinates */ if (line_p != NULL) { /* Read feature to cache if necessary */ if (Map->fInfo.ogr.feature_cache_id != FID) { G_debug(4, "Read feature (FID = %ld) to cache", FID); if (Map->fInfo.ogr.feature_cache) { OGR_F_Destroy(Map->fInfo.ogr.feature_cache); } Map->fInfo.ogr.feature_cache = OGR_L_GetFeature(Map->fInfo.ogr.layer, FID); if (Map->fInfo.ogr.feature_cache == NULL) { G_fatal_error(_("Unable to get feature geometry, FID %ld"), FID); } Map->fInfo.ogr.feature_cache_id = FID; } hGeom = OGR_F_GetGeometryRef(Map->fInfo.ogr.feature_cache); if (hGeom == NULL) { G_fatal_error(_("Unable to get feature geometry, FID %ld"), FID); } type = read_line(Map, hGeom, offset + 1, line_p); } else { type = get_line_type(Map, FID); } /* category */ if (line_c != NULL) { Vect_cat_set(line_c, 1, (int) FID); } return type; }
bool getNextFeature() { if (m_current_feature) OGR_F_Destroy(m_current_feature); m_current_feature = OGR_L_GetFeature(m_layer, (long)m_index); if (!m_current_feature) return false; m_current_geometry = OGR_F_GetGeometryRef(m_current_feature); return true; }
bool QgsOgrFeatureIterator::fetchFeatureWithId( QgsFeatureId id, QgsFeature& feature ) const { feature.setValid( false ); OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( id ) ); if ( !fet ) { return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); return true; }
/*! \brief Recursively descend to feature and read the part \param Map pointer to Map_info structure \param hGeom OGR geometry \param offset given offset \param[out] Points container used to store line pointes within \return feature type \return -1 on error */ static int get_line_type(const struct Map_info *Map, long FID) { int eType; OGRFeatureH hFeat; OGRGeometryH hGeom; G_debug(4, "get_line_type() fid = %ld", FID); hFeat = OGR_L_GetFeature(Map->fInfo.ogr.layer, FID); if (hFeat == NULL) return -1; hGeom = OGR_F_GetGeometryRef(hFeat); if (hGeom == NULL) return -1; eType = wkbFlatten(OGR_G_GetGeometryType(hGeom)); OGR_F_Destroy(hFeat); G_debug(4, "OGR Geometry of type: %d", eType); switch (eType) { case wkbPoint: case wkbMultiPoint: return GV_POINT; break; case wkbLineString: case wkbMultiLineString: return GV_LINE; break; case wkbPolygon: case wkbMultiPolygon: case wkbGeometryCollection: return GV_BOUNDARY; break; default: G_warning(_("OGR feature type %d not supported"), eType); break; } return -1; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( !P->mRelevantFieldsForNextFeature ) ensureRelevantFields(); if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) 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; }
bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) { feature.setValid( false ); if ( mClosed ) return false; if ( mRequest.filterType() == QgsFeatureRequest::FilterFid ) { OGRFeatureH fet = OGR_L_GetFeature( ogrLayer, FID_TO_NUMBER( mRequest.filterFid() ) ); if ( !fet ) { close(); return false; } if ( readFeature( fet, feature ) ) OGR_F_Destroy( fet ); feature.setValid( true ); close(); // the feature has been read: we have finished here return true; } OGRFeatureH fet; while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) ) { if ( !readFeature( fet, feature ) ) continue; if ( !mRequest.filterRect().isNull() && !feature.constGeometry() ) continue; // we have a feature, end this cycle feature.setValid( true ); OGR_F_Destroy( fet ); return true; } // while close(); return false; }
/* OGRFeatureH OGR_L_GetFeature(OGRLayerH hLayer, long nFeatureId) {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"), {ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0), {ok, Feature} = lgeo_ogr:l_get_feature(Layer, 0). */ static ERL_NIF_TERM l_get_feature(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvLayer_t **layer; int index; ERL_NIF_TERM eterm; if(argc != 2) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[0], OGR_L_RESOURCE, (void**)&layer)) { return enif_make_badarg(env); } if (!enif_get_int(env, argv[1], &index)) { return enif_make_badarg(env); } OGRFeatureH feat = OGR_L_GetFeature((**layer).obj, index); if(feat == NULL) { return enif_make_atom(env, "undefined"); } EnvFeature_t **feature = \ enif_alloc_resource(OGR_F_RESOURCE, sizeof(EnvFeature_t*)); ErlNifEnv *feature_env = enif_alloc_env(); *feature = (EnvFeature_t*) enif_alloc(sizeof(EnvFeature_t)); (**feature).env = feature_env; (**feature).obj = feat; // Save copy of layer so is not garbage collected enif_make_copy(feature_env, argv[0]); eterm = enif_make_resource(env, feature); enif_release_resource(feature); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
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; }