File indexing completed on 2023-05-30 09:06:29
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 #include <QCoreApplication> 0007 #include <QFile> 0008 #include <QFileInfo> 0009 #include <QTextStream> 0010 #include <QTime> 0011 #include <QDebug> 0012 0013 #include "geodata/data/GeoDataLineString.h" 0014 #include "geodata/data/GeoDataLinearRing.h" 0015 #include "geodata/data/GeoDataDocument.h" 0016 #include "geodata/data/GeoDataPlacemark.h" 0017 #include "geodata/data/GeoDataMultiGeometry.h" 0018 #include "geodata/data/GeoDataStyle.h" 0019 #include "geodata/data/GeoDataStyleMap.h" 0020 #include "geodata/data/GeoDataLineStyle.h" 0021 #include "geodata/data/GeoDataData.h" 0022 #include "geodata/data/GeoDataExtendedData.h" 0023 #include "geodata/writer/GeoWriter.h" 0024 #include "geodata/handlers/kml/KmlElementDictionary.h" 0025 #include "MarbleColors.h" 0026 0027 using namespace Marble; 0028 0029 int usage() 0030 { 0031 qDebug() << "Usage: [options] poly2kml input.poly output.kml"; 0032 qDebug() << "\tOptions store additional metadata in output.kml:"; 0033 qDebug() << "\t--version aVersion"; 0034 qDebug() << "\t--name aName"; 0035 qDebug() << "\t--date aDate"; 0036 qDebug() << "\t--payload aFilename"; 0037 return 1; 0038 } 0039 0040 QColor randomColor() 0041 { 0042 QVector<QColor> colors = QVector<QColor>() << Oxygen::aluminumGray4 << Oxygen::brickRed4; 0043 colors << Oxygen::hotOrange4 << Oxygen::forestGreen4 << Oxygen::hotOrange4; 0044 colors << Oxygen::seaBlue2 << Oxygen::skyBlue4 << Oxygen::sunYellow6; 0045 return colors.at( qrand() % colors.size() ); 0046 } 0047 0048 void parseBoundingBox( const QFileInfo &file, const QString &name, 0049 const QString &version, const QString &date, 0050 const QString &transport, const QString &payload, 0051 GeoDataDocument* document ) 0052 { 0053 GeoDataPlacemark* placemark = new GeoDataPlacemark; 0054 GeoDataMultiGeometry *geometry = new GeoDataMultiGeometry; 0055 QFile input( file.absoluteFilePath() ); 0056 QString country = "Unknown"; 0057 if ( input.open( QFile::ReadOnly ) ) { 0058 QTextStream stream( &input ); 0059 country = stream.readLine(); 0060 float lat( 0.0 ), lon( 0.0 ); 0061 GeoDataLinearRing *box = new GeoDataLinearRing; 0062 while ( !stream.atEnd() ) { 0063 bool inside = true; 0064 QString line = stream.readLine().trimmed(); 0065 QStringList entries = line.split( QLatin1Char( ' ' ), QString::SkipEmptyParts ); 0066 if ( entries.size() == 1 ) { 0067 if (entries.first() == QLatin1String("END") && inside) { 0068 inside = false; 0069 if (!box->isEmpty()) { 0070 geometry->append(box); 0071 box = new GeoDataLinearRing; 0072 } 0073 } else if (entries.first() == QLatin1String("END") && !inside) { 0074 qDebug() << "END not expected here"; 0075 } else if ( entries.first().startsWith( QLatin1String( "!" ) ) ) { 0076 qDebug() << "Warning: Negative polygons not supported, skipping"; 0077 } else { 0078 //int number = entries.first().toInt(); 0079 inside = true; 0080 } 0081 } else if ( entries.size() == 2 ) { 0082 lon = entries.first().toDouble(); 0083 lat = entries.last().toDouble(); 0084 GeoDataCoordinates point( lon, lat, 0.0, GeoDataCoordinates::Degree ); 0085 *box << point; 0086 } else { 0087 qDebug() << "Warning: Ignoring line in" << file.absoluteFilePath() 0088 << "with" << entries.size() << "fields:" << line; 0089 } 0090 } 0091 } 0092 0093 GeoDataStyle::Ptr style(new GeoDataStyle); 0094 GeoDataLineStyle lineStyle; 0095 QColor color = randomColor(); 0096 color.setAlpha( 200 ); 0097 lineStyle.setColor( color ); 0098 lineStyle.setWidth( 4 ); 0099 style->setLineStyle(lineStyle); 0100 style->setId("border"); 0101 0102 GeoDataStyleMap styleMap; 0103 styleMap.setId("map-border"); 0104 styleMap.insert("normal", QLatin1Char('#') + style->id()); 0105 document->addStyleMap(styleMap); 0106 document->addStyle(style); 0107 0108 placemark->setStyleUrl(QLatin1Char('#') + styleMap.id()); 0109 0110 placemark->setName( name ); 0111 if ( !version.isEmpty() ) { 0112 placemark->extendedData().addValue( GeoDataData( "version", version ) ); 0113 } 0114 if ( !date.isEmpty() ) { 0115 placemark->extendedData().addValue( GeoDataData( "date", date ) ); 0116 } 0117 if ( !transport.isEmpty() ) { 0118 placemark->extendedData().addValue( GeoDataData( "transport", transport ) ); 0119 } 0120 if ( !payload.isEmpty() ) { 0121 placemark->extendedData().addValue( GeoDataData( "payload", payload ) ); 0122 } 0123 placemark->setGeometry(geometry); 0124 document->append(placemark); 0125 } 0126 0127 int save( GeoDataDocument* document, const QFileInfo &filename ) 0128 { 0129 GeoWriter writer; 0130 writer.setDocumentType( kml::kmlTag_nameSpaceOgc22 ); 0131 0132 QFile file( filename.absoluteFilePath() ); 0133 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) 0134 { 0135 qDebug() << "Cannot write to " << file.fileName(); 0136 return usage(); 0137 } 0138 0139 if ( !writer.write( &file, document ) ) { 0140 qDebug() << "Can not write to " << file.fileName(); 0141 } 0142 file.close(); 0143 return 0; 0144 } 0145 0146 int main( int argc, char* argv[] ) 0147 { 0148 QCoreApplication app( argc, argv ); 0149 if ( argc < 3 ) { 0150 usage(); 0151 return 0; 0152 } 0153 0154 QString inputFile = argv[argc-2]; 0155 QString outputFile = argv[argc-1]; 0156 QString name; 0157 QString version; 0158 QString date; 0159 QString transport; 0160 QString payload; 0161 for ( int i=1; i<argc-2; ++i ) { 0162 QString arg( argv[i] ); 0163 if (arg == QLatin1String("--name")) { 0164 name = argv[++i]; 0165 } else if (arg == QLatin1String("--version")) { 0166 version = argv[++i]; 0167 } else if (arg == QLatin1String("--date")) { 0168 date = argv[++i]; 0169 } else if (arg == QLatin1String("--transport")) { 0170 transport = argv[++i]; 0171 } else if (arg == QLatin1String("--payload")) { 0172 payload = argv[++i]; 0173 } else { 0174 usage(); 0175 return 1; 0176 } 0177 } 0178 0179 qsrand( QTime::currentTime().msec() ); 0180 QFileInfo input( inputFile ); 0181 if ( !input.exists() || !input.isFile() ) { 0182 qDebug() << "Invalid input file"; 0183 return usage(); 0184 } 0185 0186 GeoDataDocument document; 0187 parseBoundingBox( input, name, version, date, transport, payload, &document ); 0188 return save( &document, QFileInfo( outputFile ) ); 0189 }