osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthFeatures/OgrUtils

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003 * Copyright 2008-2010 Pelican Mapping
00004 * http://osgearth.org
00005 *
00006 * osgEarth is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public License
00017 * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 #ifndef OSGEARTHFEATURES_FEATURE_OGR_UTILS
00020 #define OSGEARTHFEATURES_FEATURE_OGR_UTILS 1
00021 
00022 #include <osgEarthFeatures/Feature>
00023 #include <osgEarthSymbology/Geometry>
00024 #include <osgEarth/StringUtils>
00025 #include <osg/Notify>
00026 #include <ogr_api.h>
00027 
00028 using namespace osgEarth;
00029 using namespace osgEarth::Features;
00030 using namespace osgEarth::Symbology;
00031 
00032 struct OgrUtils
00033 {
00034     static void
00035         populate( OGRGeometryH geomHandle, Symbology::Geometry* target, int numPoints )
00036     {
00037         for( int v = numPoints-1; v >= 0; v-- ) // reverse winding.. we like ccw
00038         {
00039             double x=0, y=0, z=0;
00040             OGR_G_GetPoint( geomHandle, v, &x, &y, &z );
00041             osg::Vec3d p( x, y, z );
00042             if ( target->size() == 0 || p != target->back() ) // remove dupes
00043                 target->push_back( p );
00044         }
00045     }
00046 
00047     static Symbology::Polygon*
00048         createPolygon( OGRGeometryH geomHandle )
00049     {
00050         Symbology::Polygon* output = 0L;
00051 
00052         int numParts = OGR_G_GetGeometryCount( geomHandle );
00053         if ( numParts == 0 )
00054         {
00055             int numPoints = OGR_G_GetPointCount( geomHandle );
00056             output = new Symbology::Polygon( numPoints );
00057             populate( geomHandle, output, numPoints );
00058             output->open();
00059         }
00060         else if ( numParts > 0 )
00061         {
00062             for( int p = 0; p < numParts; p++ )
00063             {
00064                 OGRGeometryH partRef = OGR_G_GetGeometryRef( geomHandle, p );
00065                 int numPoints = OGR_G_GetPointCount( partRef );
00066                 if ( p == 0 )
00067                 {
00068                     output = new Symbology::Polygon( numPoints );
00069                     populate( partRef, output, numPoints );
00070                     //output->open();
00071                     output->rewind( Symbology::Ring::ORIENTATION_CCW );
00072                 }
00073                 else
00074                 {
00075                     Symbology::Ring* hole = new Symbology::Ring( numPoints );
00076                     populate( partRef, hole, numPoints );
00077                     //hole->open();
00078                     hole->rewind( Symbology::Ring::ORIENTATION_CW );
00079                     output->getHoles().push_back( hole );
00080                 }
00081             }
00082         }
00083         return output;
00084     }
00085 
00086     static Symbology::Geometry*
00087         createGeometry( OGRGeometryH geomHandle )
00088     {
00089         Symbology::Geometry* output = 0L;
00090 
00091         OGRwkbGeometryType wkbType = OGR_G_GetGeometryType( geomHandle );        
00092 
00093         if (
00094             wkbType == wkbPolygon ||
00095             wkbType == wkbPolygon25D )
00096         {
00097             output = createPolygon( geomHandle );
00098         }
00099         else if (
00100             wkbType == wkbLineString ||
00101             wkbType == wkbLineString25D )
00102         {
00103             int numPoints = OGR_G_GetPointCount( geomHandle );
00104             output = new Symbology::LineString( numPoints );
00105             populate( geomHandle, output, numPoints );
00106         }
00107         else if (
00108             wkbType == wkbLinearRing )
00109         {
00110             int numPoints = OGR_G_GetPointCount( geomHandle );
00111             output = new Symbology::Ring( numPoints );
00112             populate( geomHandle, output, numPoints );
00113         }
00114         else if ( 
00115             wkbType == wkbPoint ||
00116             wkbType == wkbPoint25D )
00117         {
00118             int numPoints = OGR_G_GetPointCount( geomHandle );
00119             output = new Symbology::PointSet( numPoints );
00120             populate( geomHandle, output, numPoints );
00121         }
00122         else if (
00123             wkbType == wkbGeometryCollection ||
00124             wkbType == wkbGeometryCollection25D ||
00125             wkbType == wkbMultiPoint ||
00126             wkbType == wkbMultiPoint25D ||
00127             wkbType == wkbMultiLineString ||
00128             wkbType == wkbMultiLineString25D ||
00129             wkbType == wkbMultiPolygon ||
00130             wkbType == wkbMultiPolygon25D )
00131         {
00132             Symbology::MultiGeometry* multi = new Symbology::MultiGeometry();
00133 
00134             int numGeoms = OGR_G_GetGeometryCount( geomHandle );
00135             for( int n=0; n<numGeoms; n++ )
00136             {
00137                 OGRGeometryH subGeomRef = OGR_G_GetGeometryRef( geomHandle, n );
00138                 if ( subGeomRef )
00139                 {
00140                     Symbology::Geometry* geom = createGeometry( subGeomRef );
00141                     if ( geom ) multi->getComponents().push_back( geom );
00142                 }
00143             } 
00144 
00145             output = multi;
00146         }
00147 
00148         return output;
00149     }
00150 
00151     static OGRGeometryH
00152         encodePart( Geometry* geometry, OGRwkbGeometryType part_type )
00153     {
00154         OGRGeometryH part_handle = OGR_G_CreateGeometry( part_type );
00155 
00156         for( int v = geometry->size()-1; v >= 0; v-- )
00157         {
00158             osg::Vec3d p = (*geometry)[v];
00159             OGR_G_AddPoint( part_handle, p.x(), p.y(), p.z() );
00160         }
00161 
00162         return part_handle;
00163     }
00164 
00165 
00166     static OGRGeometryH
00167         encodeShape( Geometry* geometry, OGRwkbGeometryType shape_type, OGRwkbGeometryType part_type )
00168     {
00169         OGRGeometryH shape_handle = OGR_G_CreateGeometry( shape_type );
00170         if ( shape_handle )
00171         {
00172             GeometryIterator itr(geometry, true);
00173             while (itr.hasMore())
00174             {
00175                 Geometry* geom = itr.next();
00176                 OGRGeometryH part_handle = encodePart( geom, part_type );
00177                 if ( part_handle )
00178                 {
00179                     OGR_G_AddGeometryDirectly( shape_handle, part_handle );
00180                 }
00181             }
00182         }
00183         return shape_handle;
00184     }
00185 
00186     static OGRGeometryH createOgrGeometry(osgEarth::Symbology::Geometry* geometry, OGRwkbGeometryType requestedType = wkbUnknown)
00187     {
00188         if (!geometry) return NULL;
00189 
00190         if (requestedType == wkbUnknown)
00191         {
00192             osgEarth::Symbology::Geometry::Type geomType = geometry->getType();
00193             switch( geomType)
00194             {
00195             case osgEarth::Symbology::Geometry::TYPE_POLYGON:  
00196                 requestedType = wkbPolygon;
00197                 break;
00198             case osgEarth::Symbology::Geometry::TYPE_POINTSET:  
00199                 requestedType = wkbPoint;
00200                 break;
00201             case osgEarth::Symbology::Geometry::TYPE_LINESTRING:
00202                 requestedType = wkbLineString;
00203                 break;
00204             case osgEarth::Symbology::Geometry::TYPE_RING:
00205                 requestedType = wkbLinearRing;
00206                 break;            
00207             }
00208         }
00209 
00210         OGRwkbGeometryType shape_type =
00211             requestedType == wkbPolygon || requestedType == wkbMultiPolygon ? wkbPolygon :
00212             requestedType == wkbPolygon25D || requestedType == wkbMultiPolygon25D? wkbPolygon25D :
00213             requestedType == wkbLineString || requestedType == wkbMultiLineString? wkbMultiLineString :
00214             requestedType == wkbLineString25D || requestedType == wkbMultiLineString25D? wkbMultiLineString25D :
00215             requestedType == wkbPoint || requestedType == wkbMultiPoint? wkbMultiPoint :
00216             requestedType == wkbPoint25D || requestedType == wkbMultiPoint25D? wkbMultiPoint25D :
00217             wkbNone;
00218 
00219         OGRwkbGeometryType part_type =
00220             shape_type == wkbPolygon || shape_type == wkbPolygon25D? wkbLinearRing :
00221             shape_type == wkbMultiLineString? wkbLineString :
00222             shape_type == wkbMultiLineString25D? wkbLineString25D :
00223             shape_type == wkbMultiPoint? wkbPoint :
00224             shape_type == wkbMultiPoint25D? wkbPoint25D :
00225             wkbNone;
00226 
00227 
00228         osgEarth::Symbology::MultiGeometry* multi = dynamic_cast<MultiGeometry*>(geometry);
00229 
00230         if ( multi )
00231         {
00232             OGRGeometryH group_handle = OGR_G_CreateGeometry( requestedType );
00233             for (GeometryCollection::iterator itr = multi->getComponents().begin(); itr != multi->getComponents().end(); ++itr)
00234             {
00235                 OGRGeometryH shape_handle = encodeShape( itr->get(), shape_type, part_type );
00236                 if ( shape_handle )
00237                 {
00238                     if ( OGR_G_AddGeometryDirectly( group_handle, shape_handle ) != OGRERR_NONE )
00239                     {
00240                         OE_WARN << "OGR_G_AddGeometryDirectly failed!" << std::endl;
00241                     }
00242                 }
00243             }
00244 
00245             return group_handle;
00246         }
00247         else
00248         {
00249             OGRGeometryH shape_handle = encodeShape( geometry, shape_type, part_type );
00250             return shape_handle;
00251         }
00252     }
00253 
00254     static Symbology::Geometry*
00255         createGeometryFromWKT( const std::string& wkt )
00256     {       
00257         OGRwkbGeometryType type = 
00258             startsWith( wkt, "POINT" ) ? wkbPoint :
00259             startsWith( wkt, "LINESTRING" ) ? wkbLineString :
00260             startsWith( wkt, "POLYGON" ) ? wkbPolygon :
00261             startsWith( wkt, "MULTIPOINT" ) ? wkbMultiPoint :
00262             startsWith( wkt, "MULTILINESTRING" ) ? wkbMultiLineString :
00263             startsWith( wkt, "MULTIPOLYGON" ) ? wkbMultiPolygon :
00264             startsWith( wkt, "GEOMETRYCOLLECTION" ) ? wkbGeometryCollection :
00265             wkbNone;
00266 
00267         Symbology::Geometry* output = 0L;
00268         if ( type != wkbNone )
00269         {
00270             OGRGeometryH geom = OGR_G_CreateGeometry( type );
00271             if ( geom )
00272             {
00273                 char* ptr = (char*)wkt.c_str();
00274                 if ( OGRERR_NONE == OGR_G_ImportFromWkt( geom, &ptr ) )
00275                 {
00276                     output = createGeometry( geom );
00277                     OGR_G_DestroyGeometry( geom );
00278                 }
00279                 else
00280                 {
00281                     OE_NOTICE
00282                         << "OGR Feature Source: malformed WKT geometry" << std::endl;
00283                 }
00284             }
00285         }
00286         return output;
00287     }
00288 
00289     static Feature* createFeature( OGRFeatureH handle )
00290     {
00291         long fid = OGR_F_GetFID( handle );
00292 
00293         Feature* feature = new Feature( fid );
00294 
00295         OGRGeometryH geomRef = OGR_F_GetGeometryRef( handle );  
00296         if ( geomRef )
00297         {
00298             Symbology::Geometry* geom = OgrUtils::createGeometry( geomRef );
00299             feature->setGeometry( geom );
00300         }
00301 
00302         int numAttrs = OGR_F_GetFieldCount(handle); 
00303         for (int i = 0; i < numAttrs; ++i) 
00304         { 
00305             void* field_handle_ref = OGR_F_GetFieldDefnRef( handle, i ); 
00306 
00307             // get the field name and convert to lower case:
00308             const char* field_name = OGR_Fld_GetNameRef( field_handle_ref ); 
00309             std::string name = std::string( field_name ); 
00310             std::transform( name.begin(), name.end(), name.begin(), ::tolower ); 
00311 
00312             // get the field type and set the value appropriately
00313             OGRFieldType field_type = OGR_Fld_GetType( field_handle_ref );
00314             switch( field_type )
00315             {
00316                 case OFTInteger:
00317                     {
00318                         int value = OGR_F_GetFieldAsInteger( handle, i );
00319                         feature->set( name, value );
00320                     }
00321                     break;
00322                 case OFTReal:
00323                     {
00324                         double value = OGR_F_GetFieldAsDouble( handle, i );
00325                         feature->set( name, value );
00326                     }
00327                     break;
00328                 default:
00329                     {
00330                         const char* value = OGR_F_GetFieldAsString(handle, i);
00331                         feature->set( name, std::string(value) );
00332                     }
00333             }
00334                                  
00335             //const char* field_value= OGR_F_GetFieldAsString(handle, i); 
00336             //std::string value = std::string( field_value); 
00338             //feature->set(name, value);
00340         } 
00341 
00342         return feature;
00343     }
00344 
00345     static AttributeType getAttributeType( OGRFieldType type )
00346     {
00347         switch (type)
00348         {
00349         case OFTString: return ATTRTYPE_STRING;
00350         case OFTReal: return ATTRTYPE_DOUBLE;
00351         case OFTInteger: return ATTRTYPE_INT;
00352         default: return ATTRTYPE_UNSPECIFIED;
00353         };        
00354     }
00355 };
00356 
00357 
00358 #endif // OSGEARTHFEATURES_FEATURE_OGR_GEOM_UTILS
00359 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines