Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/webapi-mapfeatures #826

Merged
merged 43 commits into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1c1b928
Add new MapActionsController and imageAction
KOKAProduktion Jul 14, 2021
32f1f3c
Clone WebMapController logic to MapActionsController
KOKAProduktion Jul 14, 2021
50d0c6f
Merge branch 'feature/webapi' into feature/webapi-marble-tiled-output
KOKAProduktion Jul 14, 2021
332e848
Add missing image retrieval params
KOKAProduktion Jul 14, 2021
5539560
Remove copyright note from marble output
KOKAProduktion Jul 15, 2021
c6fbabe
Disable dynamic/live features
KOKAProduktion Jul 16, 2021
9ab4234
Merge commit master into feature/webapi-marble-tiled-output
KOKAProduktion Sep 29, 2021
155b7cb
Add constrainDistance flag to showRectStreamlined
KOKAProduktion Sep 30, 2021
3d91611
Implement basic map features retrieval (draft)
KOKAProduktion Oct 4, 2021
61d3ebc
Merge remote-tracking branch 'origin/master' into feature/webapi-marb…
KOKAProduktion Oct 4, 2021
c89da64
Merge branch 'feature/webapi-marble-tiled-output' into feature/webapi…
KOKAProduktion Oct 4, 2021
0960811
Don't constrain map distance on imageAction
KOKAProduktion Oct 5, 2021
eedb5ca
Add image attributions to image response and success code
KOKAProduktion Oct 5, 2021
6b63860
Add simple OL implementation
KOKAProduktion Oct 5, 2021
34e6283
Merge remote-tracking branch 'origin/master' into feature/webapi-marb…
KOKAProduktion Oct 14, 2021
7de26a0
Complement previous commit
KOKAProduktion Oct 14, 2021
4c0939f
Merge branch 'feature/webapi-marble-tiled-output' into feature/webapi…
KOKAProduktion Oct 14, 2021
f94269f
Implement map features retrieval by rect
KOKAProduktion Oct 14, 2021
e417194
Merge remote-tracking branch 'origin/master' into feature/webapi-marb…
KOKAProduktion Oct 19, 2021
c07a658
Merge remote-tracking branch 'origin/master' into feature/webapi-mapf…
KOKAProduktion Oct 19, 2021
d7ecd79
Add detailFactor to MapActionsController calls
KOKAProduktion Oct 19, 2021
ae22eef
Extend MapActionsController::features result
KOKAProduktion Oct 19, 2021
bcd605f
Complement API contract on NDB, VOR and Markers
KOKAProduktion Oct 19, 2021
a155597
Merge remote-tracking branch 'origin/master' into feature/webapi-mapf…
KOKAProduktion Oct 29, 2021
6144c2a
Merge remote-tracking branch 'origin/master' into feature/webapi-marb…
KOKAProduktion Oct 29, 2021
762dc69
Merge remote-tracking branch 'origin/master' into feature/webapi-mapf…
KOKAProduktion Dec 13, 2021
3a615a8
Merge remote-tracking branch 'origin/master' into feature/webapi-marb…
KOKAProduktion Dec 13, 2021
b3330c5
Adapt renamed methods of MapPaintWidget
KOKAProduktion Dec 13, 2021
27cd181
Adapt renamed methods of MapPaintWidget
KOKAProduktion Dec 13, 2021
3968661
Add degree unit argument to get*ByRect conversions
KOKAProduktion Dec 13, 2021
734e132
Adapt MapQuery changes
KOKAProduktion Dec 13, 2021
9ea0429
Add map object id's to map features action result
KOKAProduktion Dec 16, 2021
54c769a
Implement beasic get map feature by id action
KOKAProduktion Dec 16, 2021
cc4ec71
Merge branch 'feature/webapi-marble-tiled-output' into feature/webapi…
KOKAProduktion Dec 16, 2021
77b3eaa
Add waypoints to map features result
KOKAProduktion Jan 3, 2022
02356fb
Add wind direction and speed to sim info response
KOKAProduktion Mar 7, 2022
a01462f
Merge remote-tracking branch 'origin/master' into feature/webapi-mapf…
KOKAProduktion Mar 7, 2022
f9bdd7b
Fix merge issues/adapt changes
KOKAProduktion Mar 7, 2022
0d902e3
Update OL build
KOKAProduktion Mar 7, 2022
87e1650
Create initial ol-map plugin
KOKAProduktion Mar 8, 2022
b4fe9b2
Implement airport quicksearch via map toolbar
KOKAProduktion Mar 8, 2022
b37d8fc
Turn off aircraft following when quicksearching an airport
KOKAProduktion Mar 8, 2022
ac5e247
Trap main UI to respect ol-map plugin active state
KOKAProduktion Mar 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 222 additions & 2 deletions src/webapi/mapactionscontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,240 @@
#include "mapactionscontroller.h"
#include "abstractlnmactionscontroller.h"

#include <navapp.h>

#include "mapgui/mappaintwidget.h"
#include "mapgui/mapwidget.h"
#include "navapp.h"

#include <QDebug>
#include <QBuffer>
#include <QPixmap>

MapActionsController::MapActionsController(QObject *parent, bool verboseParam, AbstractInfoBuilder* infoBuilder) :
AbstractLnmActionsController(parent, verboseParam, infoBuilder)
AbstractLnmActionsController(parent, verboseParam, infoBuilder), parentWidget((QWidget *)parent) // WARNING: Uncertain cast (QWidget *) QObject
{
qDebug() << Q_FUNC_INFO;
init();
}

WebApiResponse MapActionsController::imageAction(WebApiRequest request){

WebApiResponse response = getResponse();

response.body = "Not implemented";
atools::geo::Rect rect(
request.parameters.value("leftlon").toFloat(),
request.parameters.value("toplat").toFloat(),
request.parameters.value("rightlon").toFloat(),
request.parameters.value("bottomlat").toFloat()
);

MapPixmap map = getPixmapRect(100,100,rect);

if(map.isValid())
{
// ===========================================================================
// Write pixmap as image
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);

map.pixmap.save(&buffer, "PNG", 80);

response.body = bytes;
}

response.headers.replace("Content-Type", "image/png");

return response;

}
MapActionsController::~MapActionsController()
{
qDebug() << Q_FUNC_INFO;
deInit();
}

void MapActionsController::init()
{
qDebug() << Q_FUNC_INFO;

deInit();

// Create a map widget clone with the desired resolution
mapPaintWidget = new MapPaintWidget(parentWidget, false /* no real widget - hidden */);

// Activate painting
mapPaintWidget->setActive();
}

void MapActionsController::deInit()
{
qDebug() << Q_FUNC_INFO;

delete mapPaintWidget;
mapPaintWidget = nullptr;
}

MapPixmap MapActionsController::getPixmap(int width, int height)
{
if(verbose)
qDebug() << Q_FUNC_INFO << width << "x" << height;

return getPixmapPosDistance(width, height, atools::geo::EMPTY_POS,
static_cast<float>(NavApp::getMapWidget()->distance()), QLatin1String(""));
}

MapPixmap MapActionsController::getPixmapObject(int width, int height, web::ObjectType type, const QString& ident,
float distanceKm)
{
if(verbose)
qDebug() << Q_FUNC_INFO << width << "x" << height << "type" << type << "ident" << ident << "distanceKm" <<
distanceKm;

MapPixmap mapPixmap;
switch(type)
{
case web::USER_AIRCRAFT: {
mapPixmap = getPixmapPosDistance(width, height, NavApp::getUserAircraftPos(), distanceKm, QLatin1String(""), tr("No user aircraft"));
break;
}

case web::ROUTE: {
mapPixmap = getPixmapRect(width, height, NavApp::getRouteRect(), tr("No flight plan"));
break;
}

case web::AIRPORT: {
mapPixmap = getPixmapPosDistance(width, height, NavApp::getAirportPos(ident), distanceKm, QLatin1String(""), tr("Airport %1 not found").arg(ident));
break;
}
}
return mapPixmap;
}

MapPixmap MapActionsController::getPixmapPosDistance(int width, int height, atools::geo::Pos pos, float distanceKm,
const QString& mapCommand, const QString& errorCase)
{
if(verbose)
qDebug() << Q_FUNC_INFO << width << "x" << height << pos << "distanceKm" << distanceKm << "cmd" << mapCommand;

if(!pos.isValid())
{
if(errorCase == QLatin1String(""))
{
// Use current map position
pos.setLonX(static_cast<float>(NavApp::getMapWidget()->centerLongitude()));
pos.setLatY(static_cast<float>(NavApp::getMapWidget()->centerLatitude()));
}
else
{
qWarning() << Q_FUNC_INFO << errorCase;
MapPixmap mappixmap;
mappixmap.error = errorCase;
return mappixmap;
}
}

if(mapPaintWidget != nullptr)
{
// Copy all map settings
mapPaintWidget->copySettings(*NavApp::getMapWidget());

// Do not center world rectangle when resizing map widget
mapPaintWidget->setKeepWorldRect(false);

// Jump to position without zooming for sharp map
mapPaintWidget->showPosNotAdjusted(pos, distanceKm);

if(!mapCommand.isEmpty())
{
// Move or zoom map by command
if(mapCommand == QLatin1String("left"))
mapPaintWidget->moveLeft(Marble::Instant);
else if(mapCommand == QLatin1String("right"))
mapPaintWidget->moveRight(Marble::Instant);
else if(mapCommand == QLatin1String("up"))
mapPaintWidget->moveUp(Marble::Instant);
else if(mapCommand == QLatin1String("down"))
mapPaintWidget->moveDown(Marble::Instant);
else if(mapCommand == QLatin1String("in"))
mapPaintWidget->zoomIn(Marble::Instant);
else if(mapCommand == QLatin1String("out"))
mapPaintWidget->zoomOut(Marble::Instant);
else
{
qWarning() << Q_FUNC_INFO << "Invalid map command" << mapCommand;
return MapPixmap();
}
}

// Jump to next sharp level
mapPaintWidget->zoomIn(Marble::Instant);
mapPaintWidget->zoomOut(Marble::Instant);

MapPixmap mappixmap;

// The actual zoom distance
mappixmap.correctedDistanceKm = static_cast<float>(mapPaintWidget->distance());

if(mapCommand == QLatin1String("in") || mapCommand == QLatin1String("out"))
// Requested is equal to result when zooming
mappixmap.requestedDistanceKm = mappixmap.correctedDistanceKm;
else
// What was requested
mappixmap.requestedDistanceKm = distanceKm;

// Fill result object
mappixmap.pixmap = mapPaintWidget->getPixmap(width, height);
Comment on lines +295 to +296
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#848 Hi @albar965, I've started using MapPaintWidget::getPixmap() here but as far as i can see this hasn't been merged yet. Still won't exclude that I may have introduced the issue on the #772 and #776 PR's...

Should I check or investigate further?

Cheers

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the merge the problem? Or reverting a change?
And there is still the issue with getIls().

I can simply release it the next days. It's an alpha/development version. People can expect issues. 🙂

Alex

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, i don't think merging would solve the issue. At least I haven't run into it yet so i didn't fix anything in this PR. So maybe we shouldn't merge before we solve it, trying to avoid adding issues :)

Not retrieving ILS yet on this PR, I'm only that far for now:

        const QList<map::MapAirport> airports;
        const QList<map::MapNdb> ndbs;
        const QList<map::MapVor> vors;
        const QList<map::MapMarker> markers;
        const QList<map::MapWaypoint> waypoints;

Cheers

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah, i don't think merging would solve the issue. At least I haven't run into it yet so i didn't fix anything in this PR. So maybe we shouldn't merge before we solve it, trying to avoid adding issues :)

Not retrieving ILS yet on this PR, I'm only that far for now:

Happens during paint in the marble widget.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll investigate

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Take your time.

mappixmap.pos = mapPaintWidget->getCurrentViewCenterPos();

return mappixmap;
}
else
{
qWarning() << Q_FUNC_INFO << "mapPaintWidget is null";
return MapPixmap();
}
}

MapPixmap MapActionsController::getPixmapRect(int width, int height, atools::geo::Rect rect, const QString& errorCase)
{
if(verbose)
qDebug() << Q_FUNC_INFO << width << "x" << height << rect;

if(rect.isValid())
{
if(mapPaintWidget != nullptr)
{
// Copy all map settings
mapPaintWidget->copySettings(*NavApp::getMapWidget());

// Do not center world rectangle when resizing
mapPaintWidget->setKeepWorldRect(false);

mapPaintWidget->showRectStreamlined(rect);

MapPixmap mapPixmap;

// No distance requested. Therefore requested is equal to actual
mapPixmap.correctedDistanceKm = mapPixmap.requestedDistanceKm = static_cast<float>(mapPaintWidget->distance());
mapPixmap.pixmap = mapPaintWidget->getPixmap(width, height);
mapPixmap.pos = mapPaintWidget->getCurrentViewCenterPos();

return mapPixmap;
}
else
{
qWarning() << Q_FUNC_INFO << "mapPaintWidget is null";
return MapPixmap();
}
}
else
{
qWarning() << Q_FUNC_INFO << errorCase;
MapPixmap mapPixmap;
mapPixmap.error = errorCase;
return mapPixmap;
}
}
37 changes: 37 additions & 0 deletions src/webapi/mapactionscontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@
#define MAPACTIONSCONTROLLER_H

#include "webapi/abstractlnmactionscontroller.h"
#include "web/webmapcontroller.h"

#include "web/webflags.h"

#include "geo/rect.h"
#include <QPixmap>

class QPixmap;
class MapPaintWidget;
/**
* @brief Map actions controller implementation.
*/
Expand All @@ -33,6 +41,35 @@ class MapActionsController :
* @brief get map image
*/
Q_INVOKABLE WebApiResponse imageAction(WebApiRequest request);

explicit MapActionsController(QWidget *parent, bool verboseParam);
virtual ~MapActionsController() override;

MapActionsController(const MapActionsController& other) = delete;
MapActionsController& operator=(const MapActionsController& other) = delete;

protected:

/* Create or delete the map paint widget */
void init();
void deInit();

/* Get pixmap with given width and height from current position. */
MapPixmap getPixmap(int width, int height);

/* Get pixmap with given width and height for a map object like an airport, the user aircraft or a route. */
MapPixmap getPixmapObject(int width, int height, web::ObjectType type, const QString& ident, float distanceKm);

/* Get map at given position and distance. Command can be used to zoom in/out or scroll from the given position:
* "in", "out", "left", "right", "up" and "down". */
MapPixmap getPixmapPosDistance(int width, int height, atools::geo::Pos pos, float distanceKm, const QString& mapCommand, const QString& errorCase = QLatin1String(""));

/* Zoom to rectangel on map. */
MapPixmap getPixmapRect(int width, int height, atools::geo::Rect rect, const QString& errorCase = tr("Invalid rectangle"));

MapPaintWidget *mapPaintWidget = nullptr;
QWidget *parentWidget;
bool verbose = false;
};

#endif // MAPACTIONSCONTROLLER_H
8 changes: 4 additions & 4 deletions web/webapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,28 @@ paths:
description: Top latitude
schema:
type: number
default: 11.4
default: 10
- name: bottomlat
required: true
in: query
description: Bottom latitude
schema:
type: number
default: 11.5
default: 15
- name: leftlon
required: true
in: query
description: Left longitude
schema:
type: number
default: 44.1
default: 40
- name: rightlon
required: true
in: query
description: Right longitude
schema:
type: number
default: 44.2
default: 45
responses:
200:
description: Resulting map image
Expand Down