File indexing completed on 2024-04-28 04:41:02

0001 /*
0002     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <overpassquery.h>
0008 #include <overpassquerymanager.h>
0009 #include <io.h>
0010 
0011 #include <QCommandLineParser>
0012 #include <QCoreApplication>
0013 #include <QDebug>
0014 #include <QFile>
0015 #include <QJsonDocument>
0016 #include <QtPlugin>
0017 
0018 #include <iostream>
0019 
0020 Q_IMPORT_PLUGIN(OSM_XmlIOPlugin)
0021 
0022 #define S(x) QStringLiteral(x)
0023 
0024 int main(int argc, char **argv)
0025 {
0026     QCoreApplication app(argc, argv);
0027     QCommandLineParser parser;
0028     parser.setApplicationDescription(S("overpassql-cli"));
0029     parser.addHelpOption();
0030     QCommandLineOption queryOption({ S("q"), S("query") }, S("Overpass QL query to run"), S("query-string"));
0031     parser.addOption(queryOption);
0032     QCommandLineOption queryFileOption({ S("f"), S("query-file") }, S("File to read Overpass QL query from"), S("query-file"));
0033     parser.addOption(queryFileOption);
0034     QCommandLineOption bboxOption({ S("b"), S("bbox") }, S("Query bounding box"), S("x,y,w,h"));
0035     parser.addOption(bboxOption);
0036     QCommandLineOption tileSizeOption({ S("t"), S("tile-size") }, S("Query tile size"), S("w,h"));
0037     parser.addOption(tileSizeOption);
0038     QCommandLineOption minTileSizeOption({ S("m"), S("minimum-tile-size") }, S("Minimum query tile size"), S("w,h"));
0039     parser.addOption(minTileSizeOption);
0040     QCommandLineOption outFileOption( { S("o"), S("output") }, S("Output file name"), S("out"));
0041     parser.addOption(outFileOption);
0042     parser.process(app);
0043 
0044     OSM::OverpassQueryManager mgr;
0045     OSM::OverpassQuery query;
0046 
0047     if (parser.isSet(queryFileOption)) {
0048         QFile f(parser.value(queryFileOption));
0049         if (!f.open(QFile::ReadOnly)) {
0050             std::cerr << "failed to read query file: " << qPrintable(f.errorString()) << std::endl;
0051             return 1;
0052         }
0053         query.setQuery(QString::fromUtf8(f.readAll()));
0054     } else {
0055         query.setQuery(parser.value(queryOption));
0056     }
0057 
0058     if (parser.isSet(bboxOption)) {
0059         const auto s = parser.value(bboxOption).split(QLatin1Char(','));
0060         if (s.size() != 4) {
0061             std::cerr << "invalid bbox format" << std::endl;
0062             return 1;
0063         }
0064         QRectF bbox(s[0].toDouble(), s[1].toDouble(), s[2].toDouble(), s[3].toDouble());
0065         query.setBoundingBox(bbox);
0066     }
0067 
0068     if (parser.isSet(tileSizeOption)) {
0069         const auto s = parser.value(tileSizeOption).split(QLatin1Char(','));
0070         if (s.size() != 2) {
0071             std::cerr << "invalid tile size format" << std::endl;
0072             return 1;
0073         }
0074         QSizeF tileSize(s[0].toDouble(), s[1].toDouble());
0075         query.setTileSize(tileSize);
0076     }
0077     if (parser.isSet(minTileSizeOption)) {
0078         const auto s = parser.value(minTileSizeOption).split(QLatin1Char(','));
0079         if (s.size() != 2) {
0080             std::cerr << "invalid minimum tile size format" << std::endl;
0081             return 1;
0082         }
0083         QSizeF minTileSize(s[0].toDouble(), s[1].toDouble());
0084         query.setMinimumTileSize(minTileSize);
0085     }
0086 
0087     QObject::connect(&query, &OSM::OverpassQuery::finished, &app, [&]() {
0088         if (query.error() != OSM::OverpassQuery::NoError) {
0089             std::cerr << "query error" << std::endl;
0090             app.exit(1);
0091         }
0092 
0093         const auto outFileName = parser.value(outFileOption);
0094         QFile outFile(outFileName);
0095         std::unique_ptr<OSM::AbstractWriter> writer;
0096         if (!outFileName.isEmpty() && outFile.open(QFile::WriteOnly)) {
0097             writer = OSM::IO::writerForFileName(outFile.fileName());
0098         } else if (outFile.open(stdout, QFile::WriteOnly)) {
0099             writer = OSM::IO::writerForMimeType(u"application/vnd.openstreetmap.data+xml");
0100         }
0101         if (!writer) {
0102             std::cerr << "unsupported output file format" << std::endl;
0103             app.exit(1);
0104         }
0105         writer->write(query.result(), &outFile);
0106 
0107         app.quit();
0108     });
0109     mgr.execute(&query);
0110 
0111     return app.exec();
0112 }