int kml2tessellate_rec ( GeometryPtr poKmlGeometry, int *pnTessellate ) { LineStringPtr poKmlLineString; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; size_t nGeom; size_t i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); if ( poKmlLineString->has_tessellate ( ) ) { *pnTessellate = poKmlLineString->get_tessellate ( ); return TRUE; } break; case kmldom::Type_LinearRing: break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); if ( poKmlPolygon->has_tessellate ( ) ) { *pnTessellate = poKmlPolygon->get_tessellate ( ); return TRUE; } break; case kmldom::Type_MultiGeometry: poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); for ( i = 0; i < nGeom; i++ ) { if ( kml2tessellate_rec ( poKmlMultiGeometry-> get_geometry_array_at ( i ), pnTessellate ) ) return TRUE; } break; default: break; } return FALSE; }
void ogr2tessellate_rec ( int nTessellate, GeometryPtr poKmlGeometry ) { LineStringPtr poKmlLineString; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; size_t nGeom; size_t i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); poKmlLineString->set_tessellate ( nTessellate ); break; case kmldom::Type_LinearRing: break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); poKmlPolygon->set_tessellate ( nTessellate ); break; case kmldom::Type_MultiGeometry: poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); for ( i = 0; i < nGeom; i++ ) { ogr2tessellate_rec ( nTessellate, poKmlMultiGeometry-> get_geometry_array_at ( i ) ); } break; default: break; } }
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; }
/** * @brief KmlExport::exportToKML Triggers logfile export to KML. */ bool KmlExport::exportToKML() { bool ret = open(); if (!ret) { qDebug () << "Logfile failed to open during KML export"; return false; } // Parses logfile and generates KML document ret = preparseLogFile(); if (!ret) { qDebug () << "Logfile preparsing failed"; return false; } // Call parser. parseLogFile(); // Add track to <Document> document->add_feature(trackFolder); // Add timespans to <Document> document->add_feature(timestampFolder); // Add ground track to <Document> { LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(false); // Do not extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_CLAMPTOGROUND); linestring->set_coordinates(wallAxes[0]); MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry(); multiGeometry->add_geometry(linestring); PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(multiGeometry); placemark->set_styleurl("#ts_2_tb"); placemark->set_name("Ground track"); document->add_feature(placemark); } // Add wall axes to <Document> FolderPtr folder = factory->CreateFolder(); for (int i=0; i<numberOfWallAxes; i++) { LineStringPtr linestring = factory->CreateLineString(); linestring->set_extrude(false); // Do not extrude to ground linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE); linestring->set_coordinates(wallAxes[i]); MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry(); multiGeometry->add_geometry(linestring); PlacemarkPtr placemark = factory->CreatePlacemark(); placemark->set_geometry(multiGeometry); placemark->set_styleurl("#ts_1_tb"); folder->add_feature(placemark); folder->set_name("Wall axes"); } document->add_feature(folder); // Create <kml> and give it <Document>. KmlPtr kml = factory->CreateKml(); kml->set_feature(document); // kml takes ownership. // Serialize to XML std::string kml_data = kmldom::SerializePretty(kml); // Save to file if (QFileInfo(outputFileName).suffix().toLower() == "kmz") { if (!kmlengine::KmzFile::WriteKmz(outputFileName.toStdString().c_str(), kml_data)) { qDebug() << "KMZ write failed: " << outputFileName; QMessageBox::critical(new QWidget(),"KMZ write failed", "Failed to write KMZ file."); return false; } } else if (QFileInfo(outputFileName).suffix().toLower() == "kml") { if (!kmlbase::File::WriteStringToFile(kml_data, outputFileName.toStdString())) { qDebug() << "KML write failed: " << outputFileName; QMessageBox::critical(new QWidget(),"KML write failed", "Failed to write KML file."); return false; } } else { qDebug() << "Write failed. Invalid file name:" << outputFileName; QMessageBox::critical(new QWidget(),"Write failed", "Failed to write file. Invalid filename"); return false; } return true; }
int kml2altitudemode_rec ( GeometryPtr poKmlGeometry, int *pnAltitudeMode, int *pbIsGX ) { PointPtr poKmlPoint; LineStringPtr poKmlLineString; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; size_t nGeom; size_t i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: poKmlPoint = AsPoint ( poKmlGeometry ); if ( poKmlPoint->has_altitudemode ( ) ) { *pnAltitudeMode = poKmlPoint->get_altitudemode ( ); return TRUE; } else if ( poKmlPoint->has_gx_altitudemode ( ) ) { *pnAltitudeMode = poKmlPoint->get_gx_altitudemode ( ); *pbIsGX = TRUE; return TRUE; } break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); if ( poKmlLineString->has_altitudemode ( ) ) { *pnAltitudeMode = poKmlLineString->get_altitudemode ( ); return TRUE; } else if ( poKmlLineString->has_gx_altitudemode ( ) ) { *pnAltitudeMode = poKmlLineString->get_gx_altitudemode ( ); *pbIsGX = TRUE; return TRUE; } break; case kmldom::Type_LinearRing: break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); if ( poKmlPolygon->has_altitudemode ( ) ) { *pnAltitudeMode = poKmlPolygon->get_altitudemode ( ); return TRUE; } else if ( poKmlPolygon->has_gx_altitudemode ( ) ) { *pnAltitudeMode = poKmlPolygon->get_gx_altitudemode ( ); *pbIsGX = TRUE; return TRUE; } break; case kmldom::Type_MultiGeometry: poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); for ( i = 0; i < nGeom; i++ ) { if ( kml2altitudemode_rec ( poKmlMultiGeometry-> get_geometry_array_at ( i ), pnAltitudeMode, pbIsGX ) ) return TRUE; } break; default: break; } return FALSE; }
void ogr2altitudemode_rec ( GeometryPtr poKmlGeometry, int iAltitudeMode, int isGX ) { PointPtr poKmlPoint; LineStringPtr poKmlLineString; PolygonPtr poKmlPolygon; MultiGeometryPtr poKmlMultiGeometry; size_t nGeom; size_t i; switch ( poKmlGeometry->Type ( ) ) { case kmldom::Type_Point: poKmlPoint = AsPoint ( poKmlGeometry ); if ( !isGX ) poKmlPoint->set_altitudemode ( iAltitudeMode ); else poKmlPoint->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_LineString: poKmlLineString = AsLineString ( poKmlGeometry ); if ( !isGX ) poKmlLineString->set_altitudemode ( iAltitudeMode ); else poKmlLineString->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_LinearRing: break; case kmldom::Type_Polygon: poKmlPolygon = AsPolygon ( poKmlGeometry ); if ( !isGX ) poKmlPolygon->set_altitudemode ( iAltitudeMode ); else poKmlPolygon->set_gx_altitudemode ( iAltitudeMode ); break; case kmldom::Type_MultiGeometry: poKmlMultiGeometry = AsMultiGeometry ( poKmlGeometry ); nGeom = poKmlMultiGeometry->get_geometry_array_size ( ); for ( i = 0; i < nGeom; i++ ) { ogr2altitudemode_rec ( poKmlMultiGeometry-> get_geometry_array_at ( i ), iAltitudeMode, isGX ); } break; default: break; } }