static OGRGeometry *kml2geom_rec ( GeometryPtr poKmlGeometry, OGRSpatialReference *poOgrSRS) { /***** ogr geom vars *****/ OGRPoint *poOgrPoint; OGRLineString *poOgrLineString; OGRLinearRing *poOgrLinearRing; OGRPolygon *poOgrPolygon; OGRGeometryCollection *poOgrMultiGeometry; OGRGeometry *poOgrGeometry = NULL; OGRGeometry *poOgrTmpGeometry = NULL; /***** libkml geom vars *****/ CoordinatesPtr poKmlCoordinates; PointPtr poKmlPoint; LineStringPtr poKmlLineString; LinearRingPtr poKmlLinearRing; OuterBoundaryIsPtr poKmlOuterRing; InnerBoundaryIsPtr poKmlInnerRing; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; GxTrackPtr poKmlGxTrack; GxMultiTrackPtr poKmlGxMultiTrack; GeometryPtr poKmlTmpGeometry; Vec3 oKmlVec; size_t nRings, nCoords, nGeom, i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: poKmlPoint = AsPoint ( poKmlGeometry ); if ( poKmlPoint->has_coordinates ( ) ) { poKmlCoordinates = poKmlPoint->get_coordinates ( ); nCoords = poKmlCoordinates->get_coordinates_array_size ( ); if (nCoords > 0) { oKmlVec = poKmlCoordinates->get_coordinates_array_at ( 0 ); if ( oKmlVec.has_altitude ( ) ) poOgrPoint = new OGRPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ), oKmlVec.get_altitude ( ) ); else poOgrPoint = new OGRPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ) ); poOgrGeometry = poOgrPoint; } else { poOgrGeometry = new OGRPoint(); } } else { poOgrGeometry = new OGRPoint(); } break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); poOgrLineString = new OGRLineString ( ); if ( poKmlLineString->has_coordinates ( ) ) { poKmlCoordinates = poKmlLineString->get_coordinates ( ); nCoords = poKmlCoordinates->get_coordinates_array_size ( ); for ( i = 0; i < nCoords; i++ ) { oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i ); if ( oKmlVec.has_altitude ( ) ) poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ), oKmlVec.get_altitude ( ) ); else poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ) ); } } poOgrGeometry = poOgrLineString; break; case kmldom::Type_LinearRing: poKmlLinearRing = AsLinearRing ( poKmlGeometry ); poOgrLinearRing = new OGRLinearRing ( ); if ( poKmlLinearRing->has_coordinates ( ) ) { poKmlCoordinates = poKmlLinearRing->get_coordinates ( ); nCoords = poKmlCoordinates->get_coordinates_array_size ( ); for ( i = 0; i < nCoords; i++ ) { oKmlVec = poKmlCoordinates->get_coordinates_array_at ( i ); if ( oKmlVec.has_altitude ( ) ) poOgrLinearRing-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ), oKmlVec.get_altitude ( ) ); else poOgrLinearRing-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ) ); } } poOgrGeometry = poOgrLinearRing; break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); poOgrPolygon = new OGRPolygon ( ); if ( poKmlPolygon->has_outerboundaryis ( ) ) { poKmlOuterRing = poKmlPolygon->get_outerboundaryis ( ); poKmlLinearRing = poKmlOuterRing->get_linearring ( ); if (poKmlLinearRing) { poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS ); poOgrPolygon-> addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry ); } } nRings = poKmlPolygon->get_innerboundaryis_array_size ( ); for ( i = 0; i < nRings; i++ ) { poKmlInnerRing = poKmlPolygon->get_innerboundaryis_array_at ( i ); poKmlLinearRing = poKmlInnerRing->get_linearring ( ); if (poKmlLinearRing) { poOgrTmpGeometry = kml2geom_rec ( poKmlLinearRing, poOgrSRS ); poOgrPolygon-> addRingDirectly ( ( OGRLinearRing * ) poOgrTmpGeometry ); } } poOgrGeometry = poOgrPolygon; break; case kmldom::Type_MultiGeometry: { poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); // Detect subgeometry type to instantiate appropriate // multi geometry type. kmldom::KmlDomType type = kmldom::Type_Unknown; for ( i = 0; i < nGeom; i++ ) { poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i ); if (type == kmldom::Type_Unknown) type = poKmlTmpGeometry->Type(); else if (type != poKmlTmpGeometry->Type()) { type = kmldom::Type_Unknown; break; } } if (type == kmldom::Type_Point) poOgrMultiGeometry = new OGRMultiPoint(); else if (type == kmldom::Type_LineString) poOgrMultiGeometry = new OGRMultiLineString(); else if (type == kmldom::Type_Polygon) poOgrMultiGeometry = new OGRMultiPolygon(); else poOgrMultiGeometry = new OGRGeometryCollection (); for ( i = 0; i < nGeom; i++ ) { poKmlTmpGeometry = poKmlMultiGeometry->get_geometry_array_at ( i ); poOgrTmpGeometry = kml2geom_rec ( poKmlTmpGeometry, poOgrSRS ); poOgrMultiGeometry->addGeometryDirectly ( poOgrTmpGeometry ); } poOgrGeometry = poOgrMultiGeometry; break; } case kmldom::Type_GxTrack: poKmlGxTrack = AsGxTrack ( poKmlGeometry ); nCoords = poKmlGxTrack->get_gx_coord_array_size(); poOgrLineString = new OGRLineString ( ); for ( i = 0; i < nCoords; i++ ) { oKmlVec = poKmlGxTrack->get_gx_coord_array_at ( i ); if ( oKmlVec.has_altitude ( ) ) poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ), oKmlVec.get_altitude ( ) ); else poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ) ); } poOgrGeometry = poOgrLineString; break; case kmldom::Type_GxMultiTrack: { poKmlGxMultiTrack = AsGxMultiTrack ( poKmlGeometry ); nGeom = poKmlGxMultiTrack->get_gx_track_array_size ( ); poOgrMultiGeometry = new OGRMultiLineString(); for( size_t j = 0; j < nGeom; j++ ) { poKmlGxTrack = poKmlGxMultiTrack->get_gx_track_array_at ( j ); nCoords = poKmlGxTrack->get_gx_coord_array_size(); poOgrLineString = new OGRLineString ( ); for ( i = 0; i < nCoords; i++ ) { oKmlVec = poKmlGxTrack->get_gx_coord_array_at ( i ); if ( oKmlVec.has_altitude ( ) ) poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ), oKmlVec.get_altitude ( ) ); else poOgrLineString-> addPoint ( oKmlVec.get_longitude ( ), oKmlVec.get_latitude ( ) ); } poOgrMultiGeometry->addGeometryDirectly(poOgrLineString); } poOgrGeometry = poOgrMultiGeometry; break; } default: break; } if (poOgrGeometry) poOgrGeometry->assignSpatialReference(poOgrSRS); return poOgrGeometry; }