/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2023 Jon Beniston, M7RCE // // // // 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 . // /////////////////////////////////////////////////////////////////////////////////// #include "mapitem.h" MapItem::MapItem(const QObject *sourcePipe, const QString &group, MapSettings::MapItemSettings *itemSettings, SWGSDRangel::SWGMapItem *mapItem) : m_altitude(0.0) { m_sourcePipe = sourcePipe; m_group = group; m_itemSettings = itemSettings; m_name = *mapItem->getName(); m_hashKey = m_sourcePipe->objectName() + m_name; } void MapItem::update(SWGSDRangel::SWGMapItem *mapItem) { if (mapItem->getLabel()) { m_label = *mapItem->getLabel(); } else { m_label = ""; } m_latitude = mapItem->getLatitude(); m_longitude = mapItem->getLongitude(); m_altitude = mapItem->getAltitude(); } QGeoCoordinate MapItem::getCoordinates() { QGeoCoordinate coords; coords.setLatitude(m_latitude); coords.setLongitude(m_longitude); return coords; } void ObjectMapItem::update(SWGSDRangel::SWGMapItem *mapItem) { MapItem::update(mapItem); if (mapItem->getPositionDateTime()) { m_positionDateTime = QDateTime::fromString(*mapItem->getPositionDateTime(), Qt::ISODateWithMs); } else { m_positionDateTime = QDateTime(); } m_useHeadingPitchRoll = mapItem->getOrientation() == 1; m_heading = mapItem->getHeading(); m_pitch = mapItem->getPitch(); m_roll = mapItem->getRoll(); if (mapItem->getOrientationDateTime()) { m_orientationDateTime = QDateTime::fromString(*mapItem->getOrientationDateTime(), Qt::ISODateWithMs); } else { m_orientationDateTime = QDateTime(); } m_image = *mapItem->getImage(); m_imageRotation = mapItem->getImageRotation(); QString *text = mapItem->getText(); if (text != nullptr) { m_text = text->replace("\n", "
"); // Convert to HTML } else { m_text = ""; } if (mapItem->getModel()) { m_model = *mapItem->getModel(); } else { m_model = ""; } m_labelAltitudeOffset = mapItem->getLabelAltitudeOffset(); m_modelAltitudeOffset = mapItem->getModelAltitudeOffset(); m_altitudeReference = mapItem->getAltitudeReference(); m_fixedPosition = mapItem->getFixedPosition(); QList *animations = mapItem->getAnimations(); if (animations) { for (auto animation : *animations) { m_animations.append(new CesiumInterface::Animation(animation)); } } findFrequencies(); if (!m_fixedPosition) { updateTrack(mapItem->getTrack()); updatePredictedTrack(mapItem->getPredictedTrack()); } if (mapItem->getAvailableFrom()) { m_availableFrom = QDateTime::fromString(*mapItem->getAvailableFrom(), Qt::ISODateWithMs); } else { m_availableFrom = QDateTime(); } if (mapItem->getAvailableUntil()) { m_availableUntil = QDateTime::fromString(*mapItem->getAvailableUntil(), Qt::ISODateWithMs); } else { m_availableUntil = QDateTime(); } } void ImageMapItem::update(SWGSDRangel::SWGMapItem *mapItem) { MapItem::update(mapItem); m_image = "data:image/png;base64," + *mapItem->getImage(); m_imageZoomLevel = mapItem->getImageZoomLevel(); float east = mapItem->getImageTileEast(); float west = mapItem->getImageTileWest(); float north = mapItem->getImageTileNorth(); float south = mapItem->getImageTileSouth(); m_latitude = north - (north - south) / 2.0; m_longitude = east - (east - west) / 2.0; m_bounds = QGeoRectangle(QGeoCoordinate(north, west), QGeoCoordinate(south, east)); } void PolygonMapItem::update(SWGSDRangel::SWGMapItem *mapItem) { MapItem::update(mapItem); m_extrudedHeight = mapItem->getExtrudedHeight(); m_colorValid = mapItem->getColorValid(); m_color = mapItem->getColor(); m_altitudeReference = mapItem->getAltitudeReference(); m_deleted = *mapItem->getImage() == ""; qDeleteAll(m_points); m_points.clear(); QList *coords = mapItem->getCoordinates(); if (coords) { for (int i = 0; i < coords->size(); i++) { SWGSDRangel::SWGMapCoordinate* p = coords->at(i); QGeoCoordinate *c = new QGeoCoordinate(p->getLatitude(), p->getLongitude(), p->getAltitude()); m_points.append(c); } } // Calculate bounds m_polygon.clear(); qreal latMin = 90.0, latMax = -90.0, lonMin = 180.0, lonMax = -180.0; for (const auto p : m_points) { QGeoCoordinate coord = *p; latMin = std::min(latMin, coord.latitude()); latMax = std::max(latMax, coord.latitude()); lonMin = std::min(lonMin, coord.longitude()); lonMax = std::max(lonMax, coord.longitude()); m_polygon.push_back(QVariant::fromValue(coord)); } m_bounds = QGeoRectangle(QGeoCoordinate(latMax, lonMin), QGeoCoordinate(latMin, lonMax)); } void PolylineMapItem::update(SWGSDRangel::SWGMapItem *mapItem) { MapItem::update(mapItem); m_colorValid = mapItem->getColorValid(); m_color = mapItem->getColor(); m_altitudeReference = mapItem->getAltitudeReference(); m_deleted = *mapItem->getImage() == ""; qDeleteAll(m_points); m_points.clear(); QList *coords = mapItem->getCoordinates(); if (coords) { for (int i = 0; i < coords->size(); i++) { SWGSDRangel::SWGMapCoordinate* p = coords->at(i); QGeoCoordinate *c = new QGeoCoordinate(p->getLatitude(), p->getLongitude(), p->getAltitude()); m_points.append(c); } } // Calculate bounds m_polyline.clear(); qreal latMin = 90.0, latMax = -90.0, lonMin = 180.0, lonMax = -180.0; for (const auto p : m_points) { QGeoCoordinate coord = *p; latMin = std::min(latMin, coord.latitude()); latMax = std::max(latMax, coord.latitude()); lonMin = std::min(lonMin, coord.longitude()); lonMax = std::max(lonMax, coord.longitude()); m_polyline.push_back(QVariant::fromValue(coord)); } m_bounds = QGeoRectangle(QGeoCoordinate(latMax, lonMin), QGeoCoordinate(latMin, lonMax)); } // Look for a frequency in the text for this object void ObjectMapItem::findFrequencies() { m_frequencies.clear(); m_frequencyStrings.clear(); const QRegularExpression re("(([0-9]+(\\.[0-9]+)?) *([kMG])?Hz)"); QRegularExpressionMatchIterator itr = re.globalMatch(m_text); while (itr.hasNext()) { QRegularExpressionMatch match = itr.next(); QStringList capture = match.capturedTexts(); double frequency = capture[2].toDouble(); if (capture.length() == 5) { QChar unit = capture[4][0]; if (unit == 'k') { frequency *= 1000; } else if (unit == 'M') { frequency *= 1000000; } else if (unit == 'G') { frequency *= 1000000000; } } m_frequencies.append((qint64)frequency); m_frequencyStrings.append(capture[0]); } } void ObjectMapItem::updateTrack(QList *track) { if (track != nullptr) { qDeleteAll(m_takenTrackCoords); m_takenTrackCoords.clear(); qDeleteAll(m_takenTrackDateTimes); m_takenTrackDateTimes.clear(); m_takenTrack.clear(); m_takenTrack1.clear(); m_takenTrack2.clear(); for (int i = 0; i < track->size(); i++) { SWGSDRangel::SWGMapCoordinate* p = track->at(i); QGeoCoordinate *c = new QGeoCoordinate(p->getLatitude(), p->getLongitude(), p->getAltitude()); QDateTime *d = new QDateTime(QDateTime::fromString(*p->getDateTime(), Qt::ISODate)); m_takenTrackCoords.push_back(c); m_takenTrackDateTimes.push_back(d); m_takenTrack.push_back(QVariant::fromValue(*c)); } } else { // Automatically create a track if (m_takenTrackCoords.size() == 0) { QGeoCoordinate *c = new QGeoCoordinate(m_latitude, m_longitude, m_altitude); m_takenTrackCoords.push_back(c); if (m_positionDateTime.isValid()) { m_takenTrackDateTimes.push_back(new QDateTime(m_positionDateTime)); } else { m_takenTrackDateTimes.push_back(new QDateTime(QDateTime::currentDateTime())); } m_takenTrack.push_back(QVariant::fromValue(*c)); } else { QGeoCoordinate *prev = m_takenTrackCoords.last(); QDateTime *prevDateTime = m_takenTrackDateTimes.last(); if ((prev->latitude() != m_latitude) || (prev->longitude() != m_longitude) || (prev->altitude() != m_altitude) || (*prevDateTime != m_positionDateTime)) { QGeoCoordinate *c = new QGeoCoordinate(m_latitude, m_longitude, m_altitude); m_takenTrackCoords.push_back(c); if (m_positionDateTime.isValid()) { m_takenTrackDateTimes.push_back(new QDateTime(m_positionDateTime)); } else { m_takenTrackDateTimes.push_back(new QDateTime(QDateTime::currentDateTime())); } m_takenTrack.push_back(QVariant::fromValue(*c)); } } } } void ObjectMapItem::updatePredictedTrack(QList *track) { if (track != nullptr) { qDeleteAll(m_predictedTrackCoords); m_predictedTrackCoords.clear(); qDeleteAll(m_predictedTrackDateTimes); m_predictedTrackDateTimes.clear(); m_predictedTrack.clear(); m_predictedTrack1.clear(); m_predictedTrack2.clear(); for (int i = 0; i < track->size(); i++) { SWGSDRangel::SWGMapCoordinate* p = track->at(i); QGeoCoordinate *c = new QGeoCoordinate(p->getLatitude(), p->getLongitude(), p->getAltitude()); QDateTime *d = new QDateTime(QDateTime::fromString(*p->getDateTime(), Qt::ISODate)); m_predictedTrackCoords.push_back(c); m_predictedTrackDateTimes.push_back(d); m_predictedTrack.push_back(QVariant::fromValue(*c)); } } }