kopia lustrzana https://github.com/f4exb/sdrangel
				
				
				
			
		
			
				
	
	
		
			197 wiersze
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			197 wiersze
		
	
	
		
			8.9 KiB
		
	
	
	
		
			C++
		
	
	
| ///////////////////////////////////////////////////////////////////////////////////
 | |
| // Copyright (C) 2021, 2023 Jon Beniston, M7RCE <jon@beniston.com>               //
 | |
| //                                                                               //
 | |
| // This program is free software; you can redistribute it and/or modify          //
 | |
| // it under the terms of the GNU General Public License as published by          //
 | |
| // the Free Software Foundation as version 3 of the License, or                  //
 | |
| // (at your option) any later version.                                           //
 | |
| //                                                                               //
 | |
| // This program is distributed in the hope that it will be useful,               //
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of                //
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  //
 | |
| // GNU General Public License V3 for more details.                               //
 | |
| //                                                                               //
 | |
| // You should have received a copy of the GNU General Public License             //
 | |
| // along with this program. If not, see <http://www.gnu.org/licenses/>.          //
 | |
| ///////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| #ifndef INCLUDE_OSMTEMPLATE_SERVER_H_
 | |
| #define INCLUDE_OSMTEMPLATE_SERVER_H_
 | |
| 
 | |
| #include <QTcpServer>
 | |
| #include <QTcpSocket>
 | |
| #include <QRegularExpression>
 | |
| #include <QDebug>
 | |
| 
 | |
| class OSMTemplateServer : public QTcpServer
 | |
| {
 | |
|     Q_OBJECT
 | |
| private:
 | |
|     QString m_thunderforestAPIKey;
 | |
|     QString m_maptilerAPIKey;
 | |
|     quint16 m_tileServerPort;
 | |
|     bool m_overlay;
 | |
| 
 | |
| public:
 | |
|     // port - port to listen on / is listening on. Use 0 for any free port.
 | |
|     OSMTemplateServer(const QString &thunderforestAPIKey, const QString &maptilerAPIKey, quint16 tileServerPort, quint16 &port, QObject* parent = 0) :
 | |
|         QTcpServer(parent),
 | |
|         m_thunderforestAPIKey(thunderforestAPIKey),
 | |
|         m_maptilerAPIKey(maptilerAPIKey),
 | |
|         m_tileServerPort(tileServerPort),
 | |
|         m_overlay(false)
 | |
|     {
 | |
|         listen(QHostAddress::Any, port);
 | |
|         port = serverPort();
 | |
|     }
 | |
| 
 | |
|     void incomingConnection(qintptr socket) override
 | |
|     {
 | |
|         QTcpSocket* s = new QTcpSocket(this);
 | |
|         connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
 | |
|         connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
 | |
|         s->setSocketDescriptor(socket);
 | |
|         //addPendingConnection(socket);
 | |
|     }
 | |
| 
 | |
|     void setThunderforestAPIKey(const QString& thunderforestAPIKey)
 | |
|     {
 | |
|         m_thunderforestAPIKey = thunderforestAPIKey;
 | |
|     }
 | |
| 
 | |
|     void setMaptilerAPIKey(const QString& maptilerAPIKey)
 | |
|     {
 | |
|         m_maptilerAPIKey = maptilerAPIKey;
 | |
|     }
 | |
| 
 | |
|     void setEnableOverlay(bool enableOverlay)
 | |
|     {
 | |
|         m_overlay = enableOverlay;
 | |
|     }
 | |
| 
 | |
| private slots:
 | |
|     void readClient()
 | |
|     {
 | |
|         QTcpSocket* socket = (QTcpSocket*)sender();
 | |
|         if (socket->canReadLine())
 | |
|         {
 | |
|             QString line = socket->readLine();
 | |
|             qDebug() << "HTTP Request: " << line;
 | |
|             QStringList tokens = QString(line).split(QRegularExpression("[ \r\n][ \r\n]*"));
 | |
|             if (tokens[0] == "GET")
 | |
|             {
 | |
|                 bool hires = tokens[1].contains("hires");
 | |
|                 QString hiresURL = hires ? "@2x" : "";
 | |
|                 QString xml, url;
 | |
|                 if ((tokens[1] == "/street") || (tokens[1] == "/street-hires"))
 | |
|                 {
 | |
|                     if (m_overlay) {
 | |
|                         url = QString("http://127.0.0.1:%1/street/%z/%x/%y.png").arg(m_tileServerPort);
 | |
|                     } else {
 | |
|                         url = "https://tile.openstreetmap.org/%z/%x/%y.png";
 | |
|                     }
 | |
|                     xml = QString("\
 | |
|                         {\
 | |
|                             \"UrlTemplate\" : \"%1\",\
 | |
|                             \"ImageFormat\" : \"png\",\
 | |
|                             \"QImageFormat\" : \"Indexed8\",\
 | |
|                             \"ID\" : \"wmf-intl-1x\",\
 | |
|                             \"MaximumZoomLevel\" : 19,\
 | |
|                             \"MapCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>\",\
 | |
|                             \"DataCopyRight\" : \"\"\
 | |
|                         }").arg(url);
 | |
|                 }
 | |
|                 else if (tokens[1] == "/satellite")
 | |
|                 {
 | |
|                     if (m_overlay) {
 | |
|                         url = QString("http://127.0.0.1:%1/satellite/%z/%x/%y.jpg").arg(m_tileServerPort);
 | |
|                     } else {
 | |
|                         url = QString("https://api.maptiler.com/tiles/satellite-v2/%z/%x/%y%1.jpg?key=%2").arg(hiresURL).arg(m_maptilerAPIKey);
 | |
|                     }
 | |
|                     xml = QString("\
 | |
|                     {\
 | |
|                         \"Enabled\" : true,\
 | |
|                         \"UrlTemplate\" : \"%1\",\
 | |
|                         \"ImageFormat\" : \"jpg\",\
 | |
|                         \"QImageFormat\" : \"RGB888\",\
 | |
|                         \"ID\" : \"usgs-l7\",\
 | |
|                         \"MaximumZoomLevel\" : 22,\
 | |
|                         \"MapCopyRight\" : \"<a href='http://maptiler.com/'>Maptiler</a>\",\
 | |
|                         \"DataCopyRight\" : \"\"\
 | |
|                     }").arg(url);
 | |
|                 }
 | |
|                 else if (tokens[1].contains("transit"))
 | |
|                 {
 | |
|                     QStringList map({"/night-transit", "/night-transit-hires", "/transit", "/transit-hires"});
 | |
|                     QStringList mapId({"thf-nighttransit", "thf-nighttransit-hires", "thf-transit", "thf-transit-hires"});
 | |
|                     QStringList mapUrl({"dark_nolabels", "dark_nolabels", "light_nolabels", "light_nolabels"});
 | |
| 
 | |
|                     // Use CartoDB maps without labels for aviation maps
 | |
|                     int idx = map.indexOf(tokens[1]);
 | |
|                     if (m_overlay) {
 | |
|                         url = QString("http://127.0.0.1:%1/%2/%z/%x/%y.png").arg(m_tileServerPort).arg(mapUrl[idx]);
 | |
|                     } else {
 | |
|                         url = QString("http://1.basemaps.cartocdn.com/%2/%z/%x/%y.png%1").arg(hiresURL).arg(mapUrl[idx]);
 | |
|                     }
 | |
|                     xml = QString("\
 | |
|                     {\
 | |
|                         \"UrlTemplate\" : \"%1\",\
 | |
|                         \"ImageFormat\" : \"png\",\
 | |
|                         \"QImageFormat\" : \"Indexed8\",\
 | |
|                         \"ID\" : \"%2\",\
 | |
|                         \"MaximumZoomLevel\" : 20,\
 | |
|                         \"MapCopyRight\" : \"<a href='https://carto.com'>CartoDB</a>\",\
 | |
|                         \"DataCopyRight\" : \"\"\
 | |
|                     }").arg(url).arg(mapId[idx]);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     QStringList map({"/cycle", "/cycle-hires", "/hiking", "/hiking-hires", "/night-transit", "/night-transit-hires", "/terrain", "/terrain-hires", "/transit", "/transit-hires"});
 | |
|                     QStringList mapId({"thf-cycle", "thf-cycle-hires", "thf-hike", "thf-hike-hires", "thf-nighttransit", "thf-nighttransit-hires", "thf-landsc", "thf-landsc-hires", "thf-transit", "thf-transit-hires"});
 | |
|                     QStringList mapUrl({"cycle", "cycle", "outdoors", "outdoors", "transport-dark", "transport-dark", "landscape", "landscape", "transport", "transport"});
 | |
| 
 | |
|                     int idx = map.indexOf(tokens[1]);
 | |
|                     if (idx != -1)
 | |
|                     {
 | |
|                         if (m_overlay) {
 | |
|                             url = QString("http://127.0.0.1:%1/%2/%z/%x/%y.png").arg(m_tileServerPort).arg(mapUrl[idx]);
 | |
|                         } else {
 | |
|                             url = QString("http://a.tile.thunderforest.com/%1/%z/%x/%y%3.png?apikey=%2").arg(mapUrl[idx]).arg(m_thunderforestAPIKey).arg(hiresURL);
 | |
|                         }
 | |
|                         xml = QString("\
 | |
|                         {\
 | |
|                             \"UrlTemplate\" : \"%1\",\
 | |
|                             \"ImageFormat\" : \"png\",\
 | |
|                             \"QImageFormat\" : \"Indexed8\",\
 | |
|                             \"ID\" : \"%2\",\
 | |
|                             \"MaximumZoomLevel\" : 20,\
 | |
|                             \"MapCopyRight\" : \"<a href='http://www.thunderforest.com/'>Thunderforest</a>\",\
 | |
|                             \"DataCopyRight\" : \"<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\"\
 | |
|                         }").arg(url).arg(mapId[idx]);
 | |
|                     }
 | |
|                 }
 | |
|                 QTextStream os(socket);
 | |
|                 os.setAutoDetectUnicode(true);
 | |
|                 os << "HTTP/1.0 200 Ok\r\n"
 | |
|                     "Content-Type: text/html; charset=\"utf-8\"\r\n"
 | |
|                     "\r\n"
 | |
|                     << xml << "\n";
 | |
|                 socket->close();
 | |
| 
 | |
|                 if (socket->state() == QTcpSocket::UnconnectedState) {
 | |
|                     delete socket;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void discardClient()
 | |
|     {
 | |
|         QTcpSocket* socket = (QTcpSocket*)sender();
 | |
|         socket->deleteLater();
 | |
|     }
 | |
| 
 | |
| };
 | |
| 
 | |
| #endif
 |