bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( P->fields().count() ); feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups bool fetchGeom = !( mRequest.flags() & QgsFeatureRequest::NoGeometry ); bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect; bool geometryTypeFilter = P->mOgrGeometryTypeFilter != wkbUnknown; if ( fetchGeom || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { // get the wkb representation unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) ); } if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) ) || ( geometryTypeFilter && ( !feature.geometry() || wkbFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != wkbFlatten( P->mOgrGeometryTypeFilter ) ) ) ) { OGR_F_Destroy( fet ); return false; } } if ( !fetchGeom ) { feature.setGeometry( 0 ); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < P->mAttributeFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } return true; }
/* OGR_G_ExportToWkb (OGRGeometryH, OGRwkbByteOrder, unsigned char *) {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), {ok, Geometry} = lgeo_ogr:f_get_geometry_ref(Feature), {ok, Wkb} = lgeo_ogr:g_export_to_wkb(Geometry). */ static ERL_NIF_TERM g_export_to_wkb(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvGeometry_t **geom; ERL_NIF_TERM eterm; if (argc != 1) { return enif_make_badarg(env); } if (!enif_get_resource(env, argv[0], OGR_G_RESOURCE, (void**)&geom)) { return enif_make_badarg(env); } int size = OGR_G_WkbSize((**geom).obj); unsigned char *wkb = malloc(sizeof(char)*(size)); OGRErr eErr = OGR_G_ExportToWkb((**geom).obj, (OGRwkbByteOrder)(( htonl( 1 ) == 1 ) ? 0 : 1), wkb); if (eErr != OGRERR_NONE) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, eErr)); } ErlNifBinary bin = {.size = size, .data = wkb}; eterm = enif_make_binary(env, &bin); OGRFree(wkb); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( mSource->mFields.count() ); feature.setFields( &mSource->mFields ); // allow name-based attribute lookups bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect; bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown; if ( mFetchGeometry || useIntersect || geometryTypeFilter ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { if ( mGeometrySimplifier ) mGeometrySimplifier->simplifyGeometry( geom ); // get the wkb representation int memorySize = OGR_G_WkbSize( geom ); unsigned char *wkb = new unsigned char[memorySize]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); QgsGeometry* geometry = feature.geometry(); if ( !geometry ) feature.setGeometryAndOwnership( wkb, memorySize ); else geometry->fromWkb( wkb, memorySize ); } if (( useIntersect && ( !feature.geometry() || !feature.geometry()->intersects( mRequest.filterRect() ) ) ) || ( geometryTypeFilter && ( !feature.geometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry()->wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) ) { OGR_F_Destroy( fet ); return false; } } if ( !mFetchGeometry ) { feature.setGeometry( 0 ); } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < mSource->mFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } return true; }
void QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) { feature.setFeatureId( OGR_F_GetFID( fet ) ); feature.initAttributes( P->fields().count() ); feature.setFields( &P->mAttributeFields ); // allow name-based attribute lookups // fetch geometry if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ) { OGRGeometryH geom = OGR_F_GetGeometryRef( fet ); if ( geom ) { // get the wkb representation unsigned char *wkb = new unsigned char[OGR_G_WkbSize( geom )]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); feature.setGeometryAndOwnership( wkb, OGR_G_WkbSize( geom ) ); } else { feature.setGeometry( 0 ); } } // fetch attributes if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ) { const QgsAttributeList& attrs = mRequest.subsetOfAttributes(); for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it ) { getFeatureAttribute( fet, feature, *it ); } } else { // all attributes for ( int idx = 0; idx < P->mAttributeFields.count(); ++idx ) { getFeatureAttribute( fet, feature, idx ); } } }
QgsGeometry QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom ) { if ( !geom ) return QgsGeometry(); // get the wkb representation int memorySize = OGR_G_WkbSize( geom ); unsigned char *wkb = new unsigned char[memorySize]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); QgsGeometry g; g.fromWkb( wkb, memorySize ); return g; }
QgsGeometry QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom ) { if ( !geom ) return QgsGeometry(); // get the wkb representation int memorySize = OGR_G_WkbSize( geom ); unsigned char *wkb = new unsigned char[memorySize]; OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb ); // Read original geometry type uint32_t origGeomType; memcpy( &origGeomType, wkb + 1, sizeof( uint32_t ) ); bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 ); bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 ); // PolyhedralSurface and TINs are not supported, map them to multipolygons... if ( origGeomType % 1000 == 16 ) // is TIN, TINZ, TINM or TINZM { // TIN has the same wkb layout as a multipolygon, just need to overwrite the geom types... int nDims = 2 + hasZ + hasM; uint32_t newMultiType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::MultiPolygon, hasZ, hasM ) ); uint32_t newSingleType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::Polygon, hasZ, hasM ) ); unsigned char *wkbptr = wkb; // Endianness wkbptr += 1; // Overwrite geom type memcpy( wkbptr, &newMultiType, sizeof( uint32_t ) ); wkbptr += 4; // Geom count uint32_t numGeoms; memcpy( &numGeoms, wkb + 5, sizeof( uint32_t ) ); wkbptr += 4; // For each part, overwrite the geometry type to polygon (Z|M) for ( uint32_t i = 0; i < numGeoms; ++i ) { // Endianness wkbptr += 1; // Overwrite geom type memcpy( wkbptr, &newSingleType, sizeof( uint32_t ) ); wkbptr += sizeof( uint32_t ); // skip coordinates uint32_t nRings; memcpy( &nRings, wkbptr, sizeof( uint32_t ) ); wkbptr += sizeof( uint32_t ); for ( uint32_t j = 0; j < nRings; ++j ) { uint32_t nPoints; memcpy( &nPoints, wkbptr, sizeof( uint32_t ) ); wkbptr += sizeof( uint32_t ) + sizeof( double ) * nDims * nPoints; } } } else if ( origGeomType % 1000 == 15 ) // PolyhedralSurface, PolyhedralSurfaceZ, PolyhedralSurfaceM or PolyhedralSurfaceZM { // PolyhedralSurface has the same wkb layout as a MultiPolygon, just need to overwrite the geom type... uint32_t newType = static_cast<uint32_t>( QgsWkbTypes::zmType( QgsWkbTypes::MultiPolygon, hasZ, hasM ) ); // Overwrite geom type memcpy( wkb + 1, &newType, sizeof( uint32_t ) ); } QgsGeometry g; g.fromWkb( wkb, memorySize ); return g; }