many changes :P

This commit is contained in:
kazu
2016-06-06 22:08:53 +02:00
parent db6b479d86
commit 6243165084
56 changed files with 4399 additions and 245 deletions

View File

@@ -4,7 +4,9 @@
#
#-------------------------------------------------
QT += core gui
QT += core gui opengl
CONFIG += c++11
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets svg
@@ -14,8 +16,10 @@ TEMPLATE = app
INCLUDEPATH += \
../
SOURCES += main.cpp\
MainWindow.cpp \
SOURCES += \
lib/gpc/gpc.cpp \
main.cpp \
MainWindow.cpp \
MainController.cpp \
mapview/tools/ToolSelector.cpp \
mapview/tools/Tool.cpp \
@@ -25,7 +29,9 @@ SOURCES += main.cpp\
params/ActionWidget.cpp \
params/ToolBox.cpp \
mapview/model/MapModel.cpp \
tree/MapTreeModel.cpp
tree/MapTreeModel.cpp \
mapview/3D/MapView3D.cpp
HEADERS += MainWindow.h \
mapview/Painter.h \
@@ -74,16 +80,33 @@ HEADERS += MainWindow.h \
mapview/model/MMFloorBeacon.h \
mapview/model/MMFloorAccessPoints.h \
mapview/model/MMFloorBeacons.h \
mapview/model/MMFloorUnderlay.h \
mapview/model/IHasFile.h \
mapview/elements/MV2DElementFloorUnderlay.h \
mapview/model/MMFloorUnderlayImage.h \
mapview/model/IHasParams.h
mapview/model/IHasParams.h \
mapview/model/MMFloorUnderlays.h \
mapview/elements/MV2DElementPOI.h \
mapview/model/MMFloorPOIs.h \
mapview/model/MMFloorPOI.h \
mapview/3D/MapView3D.h \
mapview/3D/MV3DElement.h \
mapview/3D/MV3DElementFloorObstacleWall.h \
mapview/3D/MV3DElementFloorObstaclePillar.h \
mapview/3D/MV3DElementAccessPoint.h \
mapview/3D/misc/Cube.h \
mapview/3D/MV3DElementFloorOutlinePolygon.h \
mapview/3D/MV3DElementFloorOutline.h \
mapview/3D/misc/Polygon.h \
mapview/grid/MapView3DGrid.h \
mapview/grid/MapModelGrid.h \
mapview/3DGrid/GridModel.h \
mapview/3DGrid/GridRenderer.h \
mapview/3DGrid/MyNode.h
FORMS += MainWindow.ui
SOURCES += \
/apps/android/workspace/Indoor/lib/tinyxml/tinyxml2.cpp
../Indoor/lib/tinyxml/tinyxml2.cpp
RESOURCES += \
res.qrc

View File

@@ -4,6 +4,7 @@
#include "mapview/model/MapModel.h"
#include "mapview/model/MapModelElement.h"
#include "mapview/tools/ToolSelector.h"
#include "mapview/tools/ToolMoveMap.h"
#include "mapview/tools/ToolMapZoom.h"
@@ -26,11 +27,17 @@ MainController::MainController() {
mw->resize(1000, 700);
MapView2D* mapView2D = mw->getMapView2D();
MapView3D* mapView3D = mw->getMapView3D();
QTreeView* layerTree = mw->getTree();
// model setup
mapModel = new MapModel();
//mapModel->load("/apps/android/workspace/IndoorApp/res/map.xml");
mapView2D->setModel(mapModel);
mapView3D->setModel(mapModel);
mapTreeModel = new MapTreeModel(mapModel);
layerTree->setModel(mapTreeModel);
ToolMoveMap* moveMap = new ToolMoveMap();
ToolRuler* ruler = new ToolRuler();
@@ -44,19 +51,32 @@ MainController::MainController() {
mapView2D->getTools().enable(mapSelector);
mapView2D->getTools().enable(ruler);
mapTreeModel = new MapTreeModel(mapModel);
layerTree->setModel(mapTreeModel);
connect(layerTree, SIGNAL(clicked(QModelIndex)), this, SLOT(layerSelected(QModelIndex)));
connect(mapSelector, SIGNAL(onMapElementSelected(MapModelElement*)), this, SLOT(mapElementSelected(MapModelElement*)));
connect(mw->getActionWidget(), SIGNAL(onLoad()), this, SLOT(onLoad()));
connect(mw->getActionWidget(), SIGNAL(onSave()), this, SLOT(onSave()));
// model events
connect(mapModel, SIGNAL(aboutToReset()), this, SLOT(onMapModelAboutToReset()));
connect(mapModel, SIGNAL(reset()), this, SLOT(onMapModelReset()));
mapModel->load("/apps/map9.xml");
// load/save
connect(mw->getActionWidget(), SIGNAL(onLoad()), this, SLOT(onLoad()));
connect(mw->getActionWidget(), SIGNAL(onSave()), this, SLOT(onSave()));
// 3D view change
connect(mw->getShow3DFloorplan(), SIGNAL(triggered(bool)), this, SLOT(onShow3DFloorplan()));
connect(mw->getShow3DGrid(), SIGNAL(triggered(bool)), this, SLOT(onShow3DGrid()));
mapModel->load("../IndoorMap/maps/SHL9.xml");
}
void MainController::onShow3DFloorplan() {
mw->getMapView3D()->showFloorplan();
}
void MainController::onShow3DGrid() {
mw->getMapView3D()->showGrid();
}
void MainController::layerSelected(QModelIndex idx) {

View File

@@ -34,6 +34,11 @@ public slots:
void onMapModelAboutToReset();
void onMapModelReset();
private slots:
void onShow3DFloorplan();
void onShow3DGrid();
private:

View File

@@ -9,6 +9,8 @@
#include <Indoor/floorplan/v2/Floorplan.h>
#include "mapview/3D/MapView3D.h"
#include "mapview/tools/ToolMoveMap.h"
#include "mapview/tools/ToolRuler.h"
#include "mapview/tools/ToolMapZoom.h"
@@ -24,9 +26,12 @@
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
mapView2D = new MapView2D();
mapView3D = new MapView3D();
elementParamWidget = new ElementParamWidget();
layerParamWidget = new LayerParamWidget();
actionWidget = new ActionWidget();
@@ -35,18 +40,29 @@ MainWindow::MainWindow(QWidget *parent) :
ui->layButtons->addWidget(toolBoxWidget);
ui->layMap->addWidget(mapView2D);
ui->layMap->addWidget(mapView3D);
ui->layTree->addWidget(layerParamWidget);
ui->layTree->addWidget(elementParamWidget);
ui->layTree->addWidget(actionWidget);
}
MainWindow::~MainWindow() {
delete ui;
}
QAction* MainWindow::getShow3DFloorplan() {
return ui->actShow3DFloorplan;
}
QAction* MainWindow::getShow3DGrid() {
return ui->actShow3DGrid;
}
QTreeView* MainWindow::getTree() {
return ui->layerTree;
}

View File

@@ -3,6 +3,7 @@
#include <QMainWindow>
class MapView2D;
class MapView3D;
class QTreeView;
class ElementParamWidget;
class LayerParamWidget;
@@ -22,16 +23,22 @@ public:
~MainWindow();
MapView2D* getMapView2D() {return mapView2D;}
MapView3D* getMapView3D() {return mapView3D;}
ElementParamWidget* getElementParamWidget() {return elementParamWidget;}
LayerParamWidget* getLayerParamWidget() {return layerParamWidget;}
ToolBoxWidget* getToolBoxWidget() {return toolBoxWidget;}
ActionWidget* getActionWidget() {return actionWidget;}
QAction* getShow3DFloorplan();
QAction* getShow3DGrid();
QTreeView* getTree();
private:
Ui::MainWindow *ui;
MapView2D* mapView2D;
MapView3D* mapView3D;
ElementParamWidget* elementParamWidget;
LayerParamWidget* layerParamWidget;
ActionWidget* actionWidget;

View File

@@ -27,7 +27,7 @@
<widget class="QTreeView" name="layerTree">
<property name="maximumSize">
<size>
<width>200</width>
<width>250</width>
<height>16777215</height>
</size>
</property>
@@ -38,6 +38,46 @@
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>777</width>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuView">
<property name="title">
<string>View</string>
</property>
<widget class="QMenu" name="menu3D">
<property name="title">
<string>3D</string>
</property>
<addaction name="actShow3DFloorplan"/>
<addaction name="actShow3DGrid"/>
</widget>
<addaction name="action2D"/>
<addaction name="menu3D"/>
</widget>
<addaction name="menuView"/>
</widget>
<action name="action2D">
<property name="text">
<string>2D</string>
</property>
</action>
<action name="actShow3DFloorplan">
<property name="text">
<string>Floorplan</string>
</property>
</action>
<action name="actShow3DGrid">
<property name="text">
<string>Grid</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>

2472
lib/gpc/gpc.cpp Executable file

File diff suppressed because it is too large Load Diff

133
lib/gpc/gpc.h Executable file
View File

@@ -0,0 +1,133 @@
/*
===========================================================================
Project: Generic Polygon Clipper
A new algorithm for calculating the difference, intersection,
exclusive-or or union of arbitrary polygon sets.
File: gpc.h
Author: Alan Murta (email: gpc@cs.man.ac.uk)
Version: 2.32
Date: 17th December 2004
Copyright: (C) Advanced Interfaces Group,
University of Manchester.
This software is free for non-commercial use. It may be copied,
modified, and redistributed provided that this copyright notice
is preserved on all copies. The intellectual property rights of
the algorithms used reside with the University of Manchester
Advanced Interfaces Group.
You may not use this software, in whole or in part, in support
of any commercial product without the express consent of the
author.
There is no warranty or other guarantee of fitness of this
software for any purpose. It is provided solely "as is".
===========================================================================
*/
#ifndef __gpc_h
#define __gpc_h
#include <stdio.h>
/*
===========================================================================
Constants
===========================================================================
*/
/* Increase GPC_EPSILON to encourage merging of near coincident edges */
#define GPC_EPSILON (DBL_EPSILON)
#define GPC_VERSION "2.32"
/*
===========================================================================
Public Data Types
===========================================================================
*/
typedef enum /* Set operation type */
{
GPC_DIFF, /* Difference */
GPC_INT, /* Intersection */
GPC_XOR, /* Exclusive or */
GPC_UNION /* Union */
} gpc_op;
typedef struct /* Polygon vertex structure */
{
double x; /* Vertex x component */
double y; /* vertex y component */
} gpc_vertex;
typedef struct /* Vertex list structure */
{
int num_vertices; /* Number of vertices in list */
gpc_vertex *vertex; /* Vertex array pointer */
} gpc_vertex_list;
typedef struct /* Polygon set structure */
{
int num_contours; /* Number of contours in polygon */
int *hole; /* Hole / external contour flags */
gpc_vertex_list *contour; /* Contour array pointer */
} gpc_polygon;
typedef struct /* Tristrip set structure */
{
int num_strips; /* Number of tristrips */
gpc_vertex_list *strip; /* Tristrip array pointer */
} gpc_tristrip;
/*
===========================================================================
Public Function Prototypes
===========================================================================
*/
void gpc_read_polygon (FILE *infile_ptr,
int read_hole_flags,
gpc_polygon *polygon);
void gpc_write_polygon (FILE *outfile_ptr,
int write_hole_flags,
gpc_polygon *polygon);
void gpc_add_contour (gpc_polygon *polygon,
gpc_vertex_list *contour,
int hole);
void gpc_polygon_clip (gpc_op set_operation,
gpc_polygon *subject_polygon,
gpc_polygon *clip_polygon,
gpc_polygon *result_polygon);
void gpc_tristrip_clip (gpc_op set_operation,
gpc_polygon *subject_polygon,
gpc_polygon *clip_polygon,
gpc_tristrip *result_tristrip);
void gpc_polygon_to_tristrip (gpc_polygon *polygon,
gpc_tristrip *tristrip);
void gpc_free_polygon (gpc_polygon *polygon);
void gpc_free_tristrip (gpc_tristrip *tristrip);
#endif
/*
===========================================================================
End of file: gpc.h
===========================================================================
*/

25
mapview/3D/MV3DElement.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef MV3DELEMENT_H
#define MV3DELEMENT_H
#include "MapView3D.h"
/**
* represents one drawable
* element shown within the MapView3D
*/
class MV3DElement {
public:
/** dtor */
virtual ~MV3DElement() {;}
public:
/** repaint me */
virtual void paintGL() = 0;
};
#endif // MV3DELEMENT_H

View File

@@ -0,0 +1,34 @@
#ifndef MV3DELEMENTACCESSPOINT_H
#define MV3DELEMENTACCESSPOINT_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "misc/Cube.h"
#include "MV3DElement.h"
class MV3DElementAccessPoint : public MV3DElement {
Floorplan::Floor* f;
Floorplan::AccessPoint* ap;
public:
/** ctor */
MV3DElementAccessPoint(Floorplan::Floor* f, Floorplan::AccessPoint* ap) : f(f), ap(ap) {
;
}
protected:
/** repaint me */
void paintGL() override {
Cube cube(ap->getPos(f), 0.5);
cube.paintGL();
}
};
#endif // MV3DELEMENTACCESSPOINT_H

View File

@@ -0,0 +1,4 @@
#ifndef MV3DELEMENTFLOOROBSTACLEPILLAR_H
#define MV3DELEMENTFLOOROBSTACLEPILLAR_H
#endif // MV3DELEMENTFLOOROBSTACLEPILLAR_H

View File

@@ -0,0 +1,86 @@
#ifndef MV3DELEMENTFLOOROBSTACLEWALL_H
#define MV3DELEMENTFLOOROBSTACLEWALL_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "MV3DElement.h"
class MV3DElementFloorObstacleWall : public MV3DElement {
Floorplan::Floor* f;
Floorplan::FloorObstacleLine* fo;
public:
/** ctor */
MV3DElementFloorObstacleWall(Floorplan::Floor* f, Floorplan::FloorObstacleLine* fo) : f(f), fo(fo) {
;
}
protected:
Point3 cross(Point3 u, Point3 v) {
float x = u.y*v.z - u.z*v.y;
float y = u.z*v.x - u.x*v.z;
float z = u.x*v.y - u.y*v.x;
return Point3(x,y,z);
}
/** repaint me */
void paintGL() override {
float y1 = f->atHeight;
float y2 = y1+f->height;
Point3 p1 = Point3(fo->from.x, y1, fo->from.y);
Point3 p2 = Point3(fo->to.x, y1, fo->to.y);
Point3 p3 = Point3(fo->to.x, y2, fo->to.y);
Point3 p4 = Point3(fo->from.x, y2, fo->from.y);
Point3 v1 = p2-p1;
Point3 v2 = p3-p1;
Point3 n = cross(v1, v2);
n/=n.length();
// align normals to virtual viewport
Point3 view(99,99,99);
if ((view-n).length() > (view+n).length()) {n = -n;}
if (fo->type == Floorplan::ObstacleType::WALL) {
// fill the wall
glColor3f(0.75, 0.75, 0.75);
glDisable(GL_CULL_FACE);
glBegin(GL_QUADS);
glNormal3f(n.x, n.y, n.z);
glVertex3f(p1.x, p1.y, p1.z);
glVertex3f(p2.x, p2.y, p2.z);
glVertex3f(p3.x, p3.y, p3.z);
glVertex3f(p4.x, p4.y, p4.z);
glEnd();
glEnable(GL_CULL_FACE);
}
glColor3f(0,0,0);
// glDisable(GL_LIGHTING);
// glBegin(GL_LINE_STRIP);
// glVertex3f(p1.x, p1.y, p1.z);
// glVertex3f(p2.x, p2.y, p2.z);
// glVertex3f(p3.x, p3.y, p3.z);
// glVertex3f(p4.x, p4.y, p4.z);
// glVertex3f(p1.x, p1.y, p1.z);
// glEnd();
// glEnable(GL_LIGHTING);
}
};
#endif // MV3DELEMENTFLOOROBSTACLEWALL_H

View File

@@ -0,0 +1,71 @@
#ifndef MV3DELEMENTFLOOROUTLINE_H
#define MV3DELEMENTFLOOROUTLINE_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "misc/Cube.h"
#include "MV3DElement.h"
#include "../../lib/gpc/gpc.h"
#include "misc/Polygon.h"
class MV3DElementFloorOutline : public MV3DElement {
Floorplan::Floor* f;
Floorplan::FloorOutline* out;
public:
/** ctor */
MV3DElementFloorOutline(Floorplan::Floor* f, Floorplan::FloorOutline* out) : f(f), out(out) {
;
}
protected:
/** repaint me */
void paintGL() override {
std::vector<gpc_polygon> add;
std::vector<gpc_polygon> rem;
std::vector<Floorplan::FloorOutlinePolygon*> polys = *out;
Polygon pol;
for (Floorplan::FloorOutlinePolygon* poly : polys) {
switch (poly->method) {
case Floorplan::OutlineMethod::ADD: pol.add(poly->poly); break;
case Floorplan::OutlineMethod::REMOVE: pol.remove(poly->poly); break;
default: throw 1;
}
}
std::vector<std::vector<Point3>> trias = pol.get(f->atHeight);
glColor3f(0.2, 0.2, 0.2);
glDisable(GL_CULL_FACE);
for (const std::vector<Point3>& tria : trias) {
glBegin(GL_TRIANGLE_STRIP);
for (const Point3& p3 : tria) {
glVertex3f(p3.x, p3.z, p3.y);
}
glEnd();
}
glEnable(GL_CULL_FACE);
}
};
#endif // MV3DELEMENTFLOOROUTLINE_H

View File

@@ -0,0 +1,53 @@
#ifndef MV3DELEMENTFLOOROUTLINEPOLYGON_H
#define MV3DELEMENTFLOOROUTLINEPOLYGON_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "misc/Cube.h"
#include "MV3DElement.h"
class MV3DElementFloorOutlinePolygon : public MV3DElement {
Floorplan::Floor* f;
Floorplan::FloorOutlinePolygon* poly;
public:
/** ctor */
MV3DElementFloorOutlinePolygon(Floorplan::Floor* f, Floorplan::FloorOutlinePolygon* poly) : f(f), poly(poly) {
;
}
protected:
/** repaint me */
void paintGL() override {
glDisable(GL_CULL_FACE);
switch (poly->method) {
case Floorplan::OutlineMethod::ADD:
glColor3f(1,1,1);
break;
case Floorplan::OutlineMethod::REMOVE:
glColor3f(0.2, 0.2, 0.2);
break;
}
glBegin(GL_POLYGON);
glNormal3f(0,1,0);
for (Point2 p2 : poly->poly.points) {
Point3 p3(p2.x, p2.y, f->atHeight);
glVertex3f(p3.x, p3.z, p3.y);
}
glEnd();
glEnable(GL_CULL_FACE);
}
};
#endif // MV3DELEMENTFLOOROUTLINEPOLYGON_H

194
mapview/3D/MapView3D.cpp Normal file
View File

@@ -0,0 +1,194 @@
#include "MapView3D.h"
#include "../model/MapModelElement.h"
#include "../model/MapModel.h"
#include "../3DGrid/GridModel.h"
#include "../3DGrid/GridRenderer.h"
MapView3D::MapView3D(QWidget *parent) : QGLWidget(parent) {
rot.x = 45;
rot.y = 0;
rot.z = 45;
center.x = 0;
center.y = 0;
center.z = 0;
scale.x = 0.05f;
scale.y = 0.05f;
scale.z = 0.05f;
}
void MapView3D::initializeGL() {
//setFormat(QGLFormat(QGL::SampleBuffers));
QGLWidget::initializeGL();
// culling, lighting, depth-test, ...
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glEnable(GL_MULTISAMPLE);
// glEnable(GL_LINE_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
GLfloat light0_position [] = {+5, 5, +5, 1};
GLfloat light1_position [] = {-5, 5, -5, 1};
glLightfv ( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv ( GL_LIGHT1, GL_POSITION, light1_position );
GLfloat light_diffuse []={ 0.7, 0.7, 0.7, 1.0 };
glLightfv ( GL_LIGHT0, GL_DIFFUSE, light_diffuse );
glLightfv ( GL_LIGHT1, GL_DIFFUSE, light_diffuse );
// otherwise scaling the scene kills lighting normals!
glEnable(GL_NORMALIZE);
// allow using glColor3(r,g,b)
glEnable(GL_COLOR_MATERIAL);
// GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
// GLfloat mat_shininess[] = { 50.0 };
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
// glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
// background color
qglClearColor(Qt::white);
}
void MapView3D::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 3) scale
glScalef(scale.x, scale.y, scale.z);
// 2) rotate around center
glRotatef(rot.x, 1.0, 0.0, 0.0);
glRotatef(rot.z, 0.0, 1.0, 0.0);
glRotatef(rot.y, 0.0, 0.0, 1.0);
// 1) post translate (mouse moving)
glTranslatef(center.x, center.z, center.y);
// 0) swap the y axis
//glScalef(+1, -1, +1);
// // 1) translate into center
// glTranslatef(tra.x, tra.y, tra.z);
draw();
}
void MapView3D::resizeGL(int width, int height) {
//int side = qMin(width, height);
//glViewport((width - side) / 2, (height - side) / 2, side, side);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef QT_OPENGL_ES_1
//glOrthof(-2, +2, -2, +2, 1.0, 15.0);
#else
//glOrtho(-2, +2, -2, +2, 1.0, 25.0);
//glFrustum(-1,1, -1,1, 0.1,20);
viewport.size.x = 2.0f;
viewport.size.y = 2.0f * height / width;
const float w = viewport.size.x;
const float h = viewport.size.y;
glOrtho(-w, +w, -h, +h, -20, +20);
//glFrustum(+w, -w, -h, +h, -20, +20);
#endif
glMatrixMode(GL_MODELVIEW);
}
void MapView3D::mousePressEvent(QMouseEvent* e) {
mouse.btn = e->button();
mouse.x = e->x();
mouse.y = e->y();
update();
}
void MapView3D::mouseMoveEvent(QMouseEvent* e) {
float dx = mouse.x - e->x();
float dy = mouse.y - e->y();
if (mouse.btn == 1) {
rot.z -= dx/2.0f; // upward
rot.x -= dy/2.0f;
} else if (mouse.btn == 4) {
Point3 vec(-dx / width() * 2 * viewport.size.x, 0, dy / height() * 2 * viewport.size.y);
vec = vec.rot(rot.x/180*M_PI, rot.y/180*M_PI, rot.z/180*M_PI);
vec /= scale;
center += vec;
}
mouse.x = e->x();
mouse.y = e->y();
update();
}
void MapView3D::mouseReleaseEvent(QMouseEvent* e) {
update();
}
void MapView3D::wheelEvent(QWheelEvent* e) {
float f = e->delta() / 120.0f;
scale *= (f > 0) ? (2) : (0.5);
update();
}
void MapView3D::showFloorplan() {
if (gridModel) {delete gridModel; gridModel = nullptr;}
update();
}
void MapView3D::showGrid() {
if (gridModel) {delete gridModel; gridModel = nullptr;}
GridModel* gm = new GridModel();
Floorplan::IndoorMap* im = getModel()->getMap();
gm->rebuild(im);
this->gridModel = gm;
update();
}
void MapView3D::draw() {
if (gridModel) {
// show grid
GridRenderer renderer(gridModel->getGrid());
renderer.paintGL();
} else {
// show floorplan
for (MapModelElement* el : getModel()->getVisibleElements()) {
if (el->getMV3D()) {el->getMV3D()->paintGL();}
}
}
}

72
mapview/3D/MapView3D.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef MAPVIEW3D_H
#define MAPVIEW3D_H
#include <QtWidgets>
#include <QtOpenGL>
#include <Indoor/geo/Point3.h>
class MapModel;
class GridModel;
class MapView3D : public QGLWidget {
Q_OBJECT
public:
MapView3D(QWidget* parent = 0);
/** set the underlying data-model */
void setModel(MapModel* mdl) {
this->model = mdl;
update();
}
/** get the underlying data-model */
MapModel* getModel() {return model;}
/** show 3D rendered floorplan */
void showFloorplan();
/** show 3D rendered grid derived from the floorplan */
void showGrid();
private:
/** the underlying data-model */
MapModel* model = nullptr;
GridModel* gridModel = nullptr;
Point3 rot;
Point3 center;
Point3 scale;
struct Mouse {
int btn;
float x;
float y;
} mouse;
struct Viewport {
Point2 size;
} viewport;
protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);
void mousePressEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e);
void wheelEvent(QWheelEvent* e);
private:
void draw();
};
#endif // MAPVIEW3D_H

82
mapview/3D/misc/Cube.h Normal file
View File

@@ -0,0 +1,82 @@
#ifndef CUBE_H
#define CUBE_H
#include <Indoor/geo/Point3.h>
#include <QtOpenGL>
class Cube {
private:
Point3 pos;
float size;
public:
Cube(Point3 pos, float size) : pos(pos), size(size) {
}
void paintGL() {
float s = size;
glPushMatrix();
glTranslatef(pos.x, pos.z, pos.y);
glColor3f(0,0,1);
glBegin(GL_QUADS);
// bottom
glNormal3f(0,-1,0);
glVertex3f(+s, -s, -s);
glVertex3f(+s, -s, +s);
glVertex3f(-s, -s, +s);
glVertex3f(-s, -s, -s);
// top
glNormal3f(0,+1,0);
glVertex3f(-s, +s, -s);
glVertex3f(-s, +s, +s);
glVertex3f(+s, +s, +s);
glVertex3f(+s, +s, -s);
// left
glNormal3f(-1,0,0);
glVertex3f(-s, -s, -s);
glVertex3f(-s, -s, +s);
glVertex3f(-s, +s, +s);
glVertex3f(-s, +s, -s);
// right
glNormal3f(+1,0,0);
glVertex3f(+s, +s, -s);
glVertex3f(+s, +s, +s);
glVertex3f(+s, -s, +s);
glVertex3f(+s, -s, -s);
// front
glNormal3f(0,0,+1);
glVertex3f(+s, +s, +s);
glVertex3f(-s, +s, +s);
glVertex3f(-s, -s, +s);
glVertex3f(+s, -s, +s);
// rear
glNormal3f(0,0,-1);
glVertex3f(+s, -s, -s);
glVertex3f(-s, -s, -s);
glVertex3f(-s, +s, -s);
glVertex3f(+s, +s, -s);
glEnd();
glPopMatrix();
}
};
#endif // CUBE_H

109
mapview/3D/misc/Polygon.h Normal file
View File

@@ -0,0 +1,109 @@
#ifndef POLYGON_H
#define POLYGON_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include "../../../lib/gpc/gpc.h"
class Polygon {
struct GPCPolygon : gpc_polygon {
GPCPolygon() {
// contour = (gpc_vertex_list*) calloc(0, 1024);
// contour->num_vertices = 0;
// contour->vertex = (gpc_vertex*) calloc(0, 1024);
// hole = (int*) calloc(0, 1024);
num_contours = 0;
contour = nullptr;
hole = nullptr;
}
~GPCPolygon() {
if (contour) {
gpc_free_polygon(this);
//free(contour->vertex); contour->vertex = nullptr;
}
free(contour); contour = nullptr;
free(hole); hole = nullptr;
}
GPCPolygon& operator = (const GPCPolygon& o) = delete;
GPCPolygon& operator = (GPCPolygon& o) {
this->contour = o.contour;
this->hole = o.hole;
this->num_contours = o.num_contours;
o.contour = nullptr;
o.hole = nullptr;
return *this;
}
};
private:
GPCPolygon state;
public:
void add(const Floorplan::Polygon2& poly) {
GPCPolygon cur = toGPC(poly);
//GPCPolygon out;
gpc_polygon_clip(GPC_UNION, &state, &cur, &state);
//state = out;
}
void remove(const Floorplan::Polygon2& poly) {
GPCPolygon cur = toGPC(poly);
//GPCPolygon out;
gpc_polygon_clip(GPC_DIFF, &state, &cur, &state);
//state = out;
}
std::vector<std::vector<Point3>> get(float z) {
gpc_tristrip res;
res.num_strips = 0;
res.strip = nullptr;
//res.strip = (gpc_vertex_list*) malloc(1024);
gpc_polygon_to_tristrip(&state, &res);
std::vector<std::vector<Point3>> trias;
for (int i = 0; i < res.num_strips; ++i) {
gpc_vertex_list lst = res.strip[i];
std::vector<Point3> tria;
for (int j = 0; j < lst.num_vertices; ++j) {
gpc_vertex& vert = lst.vertex[j];
Point3 p3(vert.x, vert.y, z);
tria.push_back(p3);
}
trias.push_back(tria);
}
gpc_free_tristrip(&res);
return std::move(trias);
}
private:
GPCPolygon toGPC(Floorplan::Polygon2 poly) {
std::vector<gpc_vertex> verts;
for (Point2 p2 : poly.points) {
gpc_vertex vert; vert.x = p2.x; vert.y = p2.y;
verts.push_back(vert);
}
GPCPolygon gpol;
gpc_vertex_list list;
list.num_vertices = verts.size();
list.vertex = verts.data();
gpc_add_contour(&gpol, &list, 0);
return gpol;
}
};
#endif // POLYGON_H

View File

@@ -0,0 +1,38 @@
#ifndef GRIDMODEL_H
#define GRIDMODEL_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include <Indoor/grid/Grid.h>
#include <Indoor/grid/factory/v2/GridFactory.h>
#include "MyNode.h"
/**
* used for 3D grid rendering
*/
class GridModel {
private:
int gridSize_cm = 40;
Grid<MyNode> grid;
Floorplan::IndoorMap* im;
public:
GridModel() : grid(gridSize_cm) {
;
}
Grid<MyNode>* getGrid() {return &grid;}
void rebuild(Floorplan::IndoorMap* im) {
GridFactory<MyNode> fac(grid);
fac.build(im);
int i = 0;(void) i;
}
};
#endif // GRIDMODEL_H

View File

@@ -0,0 +1,40 @@
#ifndef GRIDRENDERER_H
#define GRIDRENDERER_H
#include "../3D/MV3DElement.h"
#include "MyNode.h"
#include <Indoor/grid/Grid.h>
class GridRenderer : public MV3DElement {
private:
Grid<MyNode>* grid;
public:
GridRenderer(Grid<MyNode>* grid) : grid(grid) {
;
}
virtual void paintGL() override {
glDisable(GL_LIGHTING);
glColor3f(0,0,0);
glPointSize(0.1f);
glBegin(GL_POINTS);
for (MyNode& n : *grid) {
glVertex3f(n.x_cm/100.0f, n.z_cm/100.0f*5, n.y_cm/100.0f);
}
glEnd();
glEnable(GL_LIGHTING);
}
};
#endif // GRIDRENDERER_H

10
mapview/3DGrid/MyNode.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef MYNODE_H
#define MYNODE_H
#include <Indoor/grid/Grid.h>
struct MyNode : public GridNode, public GridPoint {
MyNode(float x, float y, float z) : GridPoint(x,y,z) {;}
};
#endif // MYNODE_H

View File

@@ -44,7 +44,9 @@ void MapView2D::paintGL() {
// render all visible elements
qp.setRenderHint( QPainter::Antialiasing, true );
for (MapModelElement* el : getModel()->getVisibleElements()) {el->getMV2D()->paint(p);}
for (MapModelElement* el : getModel()->getVisibleElements()) {
if (el->getMV2D()) {el->getMV2D()->paint(p);}
}
qp.setRenderHint( QPainter::Antialiasing, false );
// foreground tools

View File

@@ -46,8 +46,13 @@ public:
}
// label
p.setPenBrush(Qt::black, Qt::NoBrush);
if (p.getScaler().getScale() >= 25) {
p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, ap->mac.c_str());
const std::string str = ap->name + " (" + ap->name + ")";
p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str());
} else if (p.getScaler().getScale() >= 10) {
const std::string str = ap->name;
p.p->drawText(p.getScaler().xms(ap->pos.x) + 10, p.getScaler().yms(ap->pos.y) + 5, str.c_str());
}
}

View File

@@ -45,8 +45,13 @@ public:
}
// label
p.setPenBrush(Qt::black, Qt::NoBrush);
if (p.getScaler().getScale() >= 25) {
p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, b->mac.c_str());
const std::string str = b->name + " (" + b->mac + ")";
p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str());
} else if (p.getScaler().getScale() >= 10) {
const std::string str = b->name;
p.p->drawText(p.getScaler().xms(b->pos.x) + 10, p.getScaler().yms(b->pos.y) + 5, str.c_str());
}
}

View File

@@ -87,7 +87,10 @@ public:
bbox.add(Point2(mx2, my2));
float opacity = p.p->opacity();
p.p->setOpacity(0.65f);
p.p->drawImage(QRectF(sx1, sy1-sh, sw, sh), img, QRectF(0,0,img.width(),img.height()));
p.p->setOpacity(opacity);
// selected endpoint(s)?
if (hasFocus()) {
@@ -125,9 +128,19 @@ public:
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
(void) e;
const float s = (e->modifiers() & Qt::ShiftModifier) ? (1.0f) : (0.1f);
if (e->key() == Qt::Key_Up) {underlay->anchor += Point2(0, +s); return true;}
if (e->key() == Qt::Key_Down) {underlay->anchor += Point2(0, -s); return true;}
if (e->key() == Qt::Key_Left) {underlay->anchor += Point2(-s, 0); return true;}
if (e->key() == Qt::Key_Right) {underlay->anchor += Point2(+s, 0); return true;}
return false;
}

View File

@@ -0,0 +1,99 @@
#ifndef MV2DELEMENTPOI_H
#define MV2DELEMENTPOI_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementPOI : public MV2DElement {
private:
bool sel = false;
Floorplan::POI* poi;
public:
/** ctor with the AP to render/edit */
MV2DElementPOI(Floorplan::POI* poi) : poi(poi) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
bbox.add(Point2(poi->pos.x, poi->pos.y));
bbox.grow(Point2(0.1, 0.1));
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
float getMinDistanceXY(const Point2 p) const override {
return p.getDistance(poi->pos);
}
/** repaint me */
void paint(Painter& p) override {
if (sel) {
p.setPenBrush(Qt::black, CFG::SEL_COLOR);
p.drawCircle(poi->pos);
} else if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawCircle(poi->pos);
} else {
p.setPenBrush(Qt::gray, Qt::NoBrush);
p.drawCircle(poi->pos);
}
// label
p.setPenBrush(Qt::black, Qt::NoBrush);
if (p.getScaler().getScale() >= 10) {
const std::string str = poi->name;
p.p->drawText(p.getScaler().xms(poi->pos.x) + 10, p.getScaler().yms(poi->pos.y) + 5, str.c_str());
}
}
/** mouse pressed at the given point */
virtual void mousePressed(MapView2D* v, const Point2 p) override {
(void) v;
(void) p;
}
/** mouse moved to the given point */
virtual void mouseMove(MapView2D* v, const Point2 _p) override {
(void) v;
if (sel) {
const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
poi->pos.x = p.x;
poi->pos.y = p.y;
}
}
/** mouse released */
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
(void) v;
(void) _p;
sel = true;
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
(void) e;
return false;
}
virtual void onFocus() override {
}
virtual void onUnfocus() override {
sel = false;
}
};
#endif // MV2DELEMENTPOI_H

View File

@@ -1,21 +1,21 @@
#ifndef IHASATTRIBUTES_H
#define IHASATTRIBUTES_H
#include <string>
//#include <string>
class IHasAttributes {
//class IHasAttributes {
public:
//public:
/** set the value for the given key */
virtual void setAttribute(const std::string& key, const std::string& val) = 0;
// /** set the value for the given key */
// virtual void setAttribute(const std::string& key, const std::string& val) = 0;
/** get the value for the given key */
virtual const std::string& getAttribute(const std::string& key) const = 0;
// /** get the value for the given key */
// virtual const std::string& getAttribute(const std::string& key) const = 0;
/** get all attributes as map */
virtual const std::unordered_map<std::string, std::string> getAttributes() const = 0;
// /** get all attributes as map */
// virtual const std::unordered_map<std::string, std::string> getAttributes() const = 0;
};
//};
#endif // IHASATTRIBUTES_H

View File

@@ -1,17 +1,17 @@
#ifndef IHASFILE_H
#define IHASFILE_H
#include <string>
//#include <string>
class IHasFile {
//class IHasFile {
public:
//public:
virtual void setFileName(const std::string& file) = 0;
// virtual void setFileName(const std::string& file) = 0;
virtual const std::string& getFileName() const = 0;
// virtual const std::string& getFileName() const = 0;
};
//};
#endif // IHASFILE_H

View File

@@ -1,15 +1,15 @@
#ifndef IHASMAC_H
#define IHASMAC_H
#include <string>
//#include <string>
class IHasMAC {
public:
//class IHasMAC {
//public:
virtual void setMAC(const std::string& mac) = 0;
// virtual void setMAC(const std::string& mac) = 0;
virtual const std::string& getMAC() const = 0;
// virtual const std::string& getMAC() const = 0;
};
//};
#endif // IHASMAC_H

View File

@@ -2,13 +2,16 @@
#define IHASPARAMS_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include <QVariant>
#include <Indoor/geo/Point2.h>
#include <Indoor/geo/Point3.h>
enum class ParamType {
INT,
FLOAT,
STRING,
FILE,
POINT2,
POINT3,
};
class ParamValue {
@@ -17,6 +20,7 @@ private:
union {
int _int;
float _float;
float _arr[3];
};
std::string _str;
@@ -29,7 +33,11 @@ public:
void setValue(const std::string& val) {_str = val;}
void setValue(float val) {_float = val;}
void setValue(int val) {_int = val;}
void setValue(Point2 p) {_arr[0] = p.x; _arr[1] = p.y;}
void setValue(Point3 p) {_arr[0] = p.x; _arr[1] = p.y; _arr[2] = p.z;}
Point2 toPoint2() const {return Point2(_arr[0], _arr[1]);}
Point3 toPoint3() const {return Point3(_arr[0], _arr[1], _arr[2]);}
std::string toString() const {return _str;}
float toFloat() const {return _float;}
int toInt() const {return _int;}

View File

@@ -1,19 +1,18 @@
#ifndef IHASPOSITION3D_H
#define IHASPOSITION3D_H
//#include <Indoor/geo/Point3.h>
#include <Indoor/geo/Point3.h>
//class IHasPosition3D {
class IHasPosition3D {
//public:
public:
// /** set the element's 3D position */
// virtual void setPosition3D(const Point3& p) = 0;
/** set the element's 3D position */
virtual void setPosition3D(const Point3& p) = 0;
// /** get the element's 3D position */
// virtual Point3 getPosition3D() const = 0;
/** get the element's 3D position */
virtual Point3 getPosition3D() const = 0;
};
//};
#endif // IHASPOSITION3D_H

View File

@@ -6,7 +6,10 @@
#include "MMFloorObstacles.h"
#include "MMFloorAccessPoints.h"
#include "MMFloorBeacons.h"
#include "MMFloorUnderlay.h"
#include "MMFloorUnderlays.h"
#include "MMFloorPOIs.h"
#include "IHasParams.h"
#include <Indoor/floorplan/v2/Floorplan.h>
@@ -16,7 +19,7 @@
* floor-layer containing one floor
* and its outline, obstacles, access-points, ...
*/
class MMFloor : public MapLayer, public IHasName {
class MMFloor : public MapLayer, public IHasParams {
private:
@@ -28,11 +31,13 @@ public:
/** ctor. existing floor */
MMFloor(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR), floor(floor) {
new MMFloorOutline(this, floor);
new MMFloorUnderlays(this, floor);
elements.push_back(new MMFloorOutline(this, floor));
new MMFloorObstacles(this, floor);
new MMFloorAccessPoints(this, floor);
new MMFloorBeacons(this, floor);
new MMFloorUnderlay(this, floor);
new MMFloorPOIs(this, floor);
}
@@ -47,9 +52,29 @@ public:
std::string getLayerName() const override {return floor->name;}
virtual int getNumParams() const override {
return 1;
}
virtual void setName(const std::string& name) {this->floor->name = name;}
virtual const std::string& getName() const {return this->floor->name;}
virtual Param getParamDesc(const int idx) const override {
switch(idx) {
case 0: return Param("anem", ParamType::STRING);
}
throw 1;
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return floor->name;
}
throw 1;
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch(idx) {
case 0: floor->name = val.toString(); break;
}
}
};

View File

@@ -2,35 +2,61 @@
#define MAPVIEWELEMENTACCESSPOINT_H
#include "MapModelElement.h"
#include "IHasMAC.h"
#include "IHasName.h"
#include "IHasParams.h"
#include "../elements/MV2DElementAccessPoint.h"
#include "../3D/MV3DElementAccessPoint.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorAccessPoint : public MapModelElement, public IHasMAC, public IHasName {
class MMFloorAccessPoint : public MapModelElement, public IHasParams {
private:
Floorplan::Floor* floor;
Floorplan::AccessPoint* ap;
MV2DElementAccessPoint mv2d;
MV3DElementAccessPoint mv3d;
public:
MMFloorAccessPoint(MapLayer* parent, Floorplan::Floor* floor, Floorplan::AccessPoint* ap) :
MapModelElement(parent), floor(floor), ap(ap), mv2d(ap) {
MapModelElement(parent), floor(floor), ap(ap), mv2d(ap), mv3d(floor, ap) {
}
virtual void setMAC(const std::string& mac) override {ap->mac = mac;}
virtual const std::string& getMAC() const override {return ap->mac;}
virtual int getNumParams() const override {
return 3;
}
virtual void setName(const std::string& name) override {ap->name = name;}
virtual const std::string& getName() const override {return ap->name;}
virtual Param getParamDesc(const int idx) const override {
switch(idx) {
case 0: return Param("name", ParamType::STRING);
case 1: return Param("MAC", ParamType::STRING);
case 2: return Param("Position", ParamType::POINT3);
}
throw 1;
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return ap->name;
case 1: return ap->mac;
case 2: return ap->pos;
}
throw 1;
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch(idx) {
case 0: ap->name = val.toString(); break;
case 1: ap->mac = val.toString(); break;
case 2: ap->pos = val.toPoint3(); break;
}
}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
void deleteMe() const override {
parent->removeElement(this);

View File

@@ -22,7 +22,7 @@ public:
// add all APs
for (Floorplan::AccessPoint* ap : floor->accesspoints) {
new MMFloorAccessPoint(this, floor, ap);
elements.push_back(new MMFloorAccessPoint(this, floor, ap));
}
}

View File

@@ -2,14 +2,13 @@
#define MAPVIEWELEMENTIBEACON_H
#include "MapModelElement.h"
#include "IHasMAC.h"
#include "IHasName.h"
#include "IHasParams.h"
#include "../elements/MV2DElementBeacon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorBeacon : public MapModelElement, public IHasMAC, public IHasName {
class MMFloorBeacon : public MapModelElement, public IHasParams {
private:
@@ -20,14 +19,38 @@ private:
public:
MMFloorBeacon(MapLayer* parent, Floorplan::Floor* floor, Floorplan::Beacon* b) : MapModelElement(parent), floor(floor), b(b), mv2d(b) {
;
}
virtual void setMAC(const std::string& mac) override {b->mac = mac;}
virtual const std::string& getMAC() const override {return b->mac;}
virtual int getNumParams() const override {
return 3;
}
virtual void setName(const std::string& name) override {b->name = name;}
virtual const std::string& getName() const override {return b->name;}
virtual Param getParamDesc(const int idx) const override {
switch(idx) {
case 0: return Param("name", ParamType::STRING);
case 1: return Param("MAC", ParamType::STRING);
case 2: return Param("Position", ParamType::POINT3);
}
throw 1;
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return b->name;
case 1: return b->mac;
case 2: return b->pos;
}
throw 1;
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch(idx) {
case 0: b->name = val.toString(); break;
case 1: b->mac = val.toString(); break;
case 2: b->pos = val.toPoint3(); break;
}
}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}

View File

@@ -22,7 +22,7 @@ public:
// add all Beacons
for (Floorplan::Beacon* b : floor->beacons) {
new MMFloorBeacon(this, floor, b);
elements.push_back(new MMFloorBeacon(this, floor, b));
}
}

View File

@@ -8,6 +8,7 @@
#include "IHasObstacleType.h"
#include "../elements/MV2DElementFloorObstacleLine.h"
#include "../3D/MV3DElementFloorObstacleWall.h"
#include <Indoor/floorplan/v2/Floorplan.h>
@@ -19,11 +20,12 @@ public:
Floorplan::Floor* mf;
Floorplan::FloorObstacleLine* fo;
MV2DElementFloorObstacleLine mv2d;
MV3DElementFloorObstacleWall mv3d;
public:
MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) :
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo), mv3d(mf,fo) {
}
@@ -34,6 +36,7 @@ public:
Floorplan::ObstacleType getObatcleType() const override {return fo->type;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
void deleteMe() const override {
parent->removeElement(this);

View File

@@ -3,6 +3,7 @@
#include "MapLayer.h"
#include "MMFloorOutlinePolygon.h"
#include "../3D/MV3DElementFloorOutline.h"
#include <Indoor/floorplan/v2/Floorplan.h>
@@ -10,17 +11,20 @@
/**
* layer containing all elements describing a floor's outline
*/
class MMFloorOutline : public MapLayer {
class MMFloorOutline : public MapLayer, public MapModelElement {
private:
/** the underlying model */
Floorplan::Floor* floor;
MV3DElementFloorOutline mv3d;
public:
/** ctor with the underlying model */
MMFloorOutline(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_GROUND), floor(floor) {
MMFloorOutline(MapLayer* parent, Floorplan::Floor* floor) :
MapLayer(parent, MapLayerType::FLOOR_GROUND), MapModelElement(parent), floor(floor), mv3d(floor, &floor->outline) {
// the outline
for (Floorplan::FloorOutlinePolygon* poly : floor->outline) {
@@ -29,6 +33,8 @@ public:
}
MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
/** get the corresponding floor from the underlying model */
Floorplan::Floor* getFloor() {return floor;}

View File

@@ -1,10 +1,11 @@
#ifndef MAPELEMENTFLOORGROUND_H
#define MAPELEMENTFLOORGROUND_H
#include "IHasName.h"
#include "IHasParams.h"
#include "MapModelElement.h"
#include "../elements/MV2DElementFloorOutlinePolygon.h"
#include "../3D/MV3DElementFloorOutlinePolygon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
@@ -12,18 +13,20 @@
/**
* describes one polygon within a floor's outline
*/
class MMFloorOutlinePolygon : public MapModelElement, public IHasName {
class MMFloorOutlinePolygon : public MapModelElement, public IHasParams {
private:
Floorplan::Floor* mf;
Floorplan::FloorOutlinePolygon* fo;
MV2DElementFloorOutlinePolygon mv2d;
MV3DElementFloorOutlinePolygon mv3d;
public:
/** ctor */
MMFloorOutlinePolygon(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorOutlinePolygon* fo) : MapModelElement(parent), mf(mf), fo(fo), mv2d(*fo) {
MMFloorOutlinePolygon(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorOutlinePolygon* fo) :
MapModelElement(parent), mf(mf), fo(fo), mv2d(*fo), mv3d(mf, fo) {
;
}
@@ -32,10 +35,32 @@ public:
Floorplan::OutlineMethod getMethod() const {return fo->method;}
void setMethod(const Floorplan::OutlineMethod m) {this->fo->method = m;}
void setName(const std::string& name) override {fo->name = name;}
const std::string& getName() const override {return fo->name;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
virtual int getNumParams() const override {
return 1;
}
virtual Param getParamDesc(const int idx) const override {
switch(idx) {
case 0: return Param("anem", ParamType::STRING);
}
throw 1;
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return fo->name;
}
throw 1;
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch(idx) {
case 0: fo->name = val.toString(); break;
}
}
void deleteMe() const override {

View File

@@ -0,0 +1,65 @@
#ifndef MMFLOORPOI_H
#define MMFLOORPOI_H
#include "MapModelElement.h"
#include "IHasParams.h"
#include "../elements/MV2DElementPOI.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorPOI : public MapModelElement, public IHasParams {
private:
Floorplan::Floor* floor;
Floorplan::POI* poi;
MV2DElementPOI mv2d;
public:
MMFloorPOI(MapLayer* parent, Floorplan::Floor* floor, Floorplan::POI* poi) : MapModelElement(parent), floor(floor), poi(poi), mv2d(poi) {
;
}
virtual int getNumParams() const override {
return 3;
}
virtual Param getParamDesc(const int idx) const override {
switch(idx) {
case 0: return Param("name", ParamType::STRING);
case 1: return Param("type", ParamType::INT);
case 2: return Param("position", ParamType::POINT2);
}
throw 1;
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return poi->name;
case 1: return (int) poi->type;
case 2: return poi->pos;
}
throw 1;
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch(idx) {
case 0: poi->name = val.toString(); break;
case 1: poi->type = (Floorplan::POIType) val.toInt(); break;
case 2: poi->pos = val.toPoint2(); break;
}
}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
void deleteMe() const override {
parent->removeElement(this);
floor->pois.erase(std::remove(floor->pois.begin(), floor->pois.end(), poi), floor->pois.end());
}
};
#endif // MMFLOORPOI_H

View File

@@ -0,0 +1,46 @@
#ifndef MMFLOORPOIS_H
#define MMFLOORPOIS_H
#include "MapLayer.h"
#include "MMFloorPOI.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer that contains all of one floor's POIs
*/
class MMFloorPOIs : public MapLayer {
Floorplan::Floor* floor;
public:
/** ctor with the floor */
MMFloorPOIs(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_POIS), floor(floor) {
// the POIs
for (Floorplan::POI* poi : floor->pois) {
elements.push_back(new MMFloorPOI(this, floor, poi));
}
}
/** get the corresponding floor from the underlying model */
Floorplan::Floor* getFloor() {return floor;}
//TODO: check
void createPOI(Floorplan::POI* poi) {
// add to underlying model
floor->pois.push_back(poi);
// add to myself as element
elements.push_back(new MMFloorPOI(this, floor, poi));
}
std::string getLayerName() const override {return "POIs";}
};
#endif // MMFLOORPOIS_H

View File

@@ -2,7 +2,6 @@
#define MMFLOORUNDERLAYIMAGE_H
#include "IHasFile.h"
#include "IHasParams.h"
#include "MapModelElement.h"
@@ -12,7 +11,7 @@
/**
* add an external image file as underlay (to copy it onto the map)
*/
class MMFloorUnderlayImage : public MapModelElement, public MapLayer, public IHasFile, public IHasParams {
class MMFloorUnderlayImage : public MapModelElement, public IHasParams {
private:
@@ -24,19 +23,15 @@ private:
public:
/** ctor */
MMFloorUnderlayImage(MapLayer* parent, Floorplan::Floor* floor, Floorplan::UnderlayImage* img) : MapModelElement(parent), MapLayer(parent, MapLayerType::FLOOR_UNDERLAY), floor(floor), img(img), mv2d(img) {
setFileName(img->filename);
MMFloorUnderlayImage(MapLayer* parent, Floorplan::Floor* floor, Floorplan::UnderlayImage* img) : MapModelElement(parent), floor(floor), img(img), mv2d(img) {
;
}
virtual void setFileName(const std::string& file) {img->filename = file;}
virtual const std::string& getFileName() const {return img->filename;}
void setAnchor(const Point2 anchor) {img->anchor = anchor;}
Point2 getAnchor() const {return img->anchor;}
void setScale(const float x, const float y) {img->scaleX = x; img->scaleY = y;}
virtual std::string getLayerName() const override {return "underlay";}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
@@ -44,13 +39,14 @@ public:
;
}
int getNumParams() const override {return 3;}
int getNumParams() const override {return 4;}
virtual Param getParamDesc(const int idx) const override {
switch (idx) {
case 0: return Param("file", ParamType::FILE);
case 1: return Param("scale X", ParamType::FLOAT);
case 2: return Param("scale Y", ParamType::FLOAT);
case 3: return Param("Anchor", ParamType::POINT2);
default: throw 1;
}
}
@@ -60,15 +56,17 @@ public:
case 0: return ParamValue(img->filename);
case 1: return ParamValue(img->scaleX);
case 2: return ParamValue(img->scaleY);
case 3: return ParamValue(img->anchor);
default: throw 1;
}
}
virtual void setParamValue(const int idx, const ParamValue& val) const override {
switch (idx) {
case 0: img->filename = val.toString();
case 1: img->scaleX = val.toFloat();
case 2: img->scaleY = val.toFloat();
case 0: img->filename = val.toString(); break;
case 1: img->scaleX = val.toFloat(); break;
case 2: img->scaleY = val.toFloat(); break;
case 3: img->anchor = val.toPoint2(); break;
default: throw 1;
}
}

View File

@@ -10,7 +10,7 @@
/**
* add an external file as underlay (to copy it onto the map)
*/
class MMFloorUnderlay : public MapLayer {
class MMFloorUnderlays : public MapLayer {
private:
@@ -19,7 +19,7 @@ private:
public:
/** ctor */
MMFloorUnderlay(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_UNDERLAY), floor(floor) {
MMFloorUnderlays(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_UNDERLAYS), floor(floor) {
// the underlays
for (Floorplan::UnderlayImage* img : floor->underlays) {

View File

@@ -17,7 +17,8 @@ enum class MapLayerType {
FLOOR_OBSTACLES,
FLOOR_BEACONS,
FLOOR_ACCESS_POINTS,
FLOOR_UNDERLAY,
FLOOR_UNDERLAYS,
FLOOR_POIS,
};

View File

@@ -68,6 +68,11 @@ public:
}
/** get the constructed map */
Floorplan::IndoorMap* getMap() const {
return im;
}
/** get the map's root-layer containing all other layers */
MapLayer* getRootLayer() { return root; }

View File

@@ -5,6 +5,7 @@
#include "MapLayer.h"
class MV2DElement;
class MV3DElement;
class MapModelElement {
@@ -21,10 +22,13 @@ public:
virtual ~MapModelElement() {;}
/** get the 2D interaction class for this element */
virtual MV2DElement* getMV2D() const = 0;
virtual MV2DElement* getMV2D() const {return nullptr;}
/** get the 3D interaction class for this element */
virtual MV3DElement* getMV3D() const {return nullptr;}
/** delete this element from the model */
virtual void deleteMe() const = 0;
virtual void deleteMe() const {;}
/** get the parent element */
MapLayer* getParent() const {return parent;}

View File

@@ -5,12 +5,23 @@
class ToolMapGrid : public Tool {
private:
bool show = true;
public:
virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) {
(void) m;
if (e->key() == Qt::Key_NumberSign) { show = !show; }
}
void paintBefore(MapView2D* m, Painter& p) override {
(void) m;
if (!show) {return;}
static const QColor cB(250,250,250);
static const QColor cN(235,235,235);
static const QColor c0(128,128,128);

View File

@@ -86,11 +86,9 @@ public:
p.p->drawLine(mouseX, 0, mouseX, rs);
p.setPenBrush(Qt::black, Qt::NoBrush);
char buf[128];
// y-axis
p.p->setClipRect(ry);
for (float y = r.y0; y <= r.y1; y += step) {
@@ -131,6 +129,7 @@ public:
p.p->drawText(xMajor+2, 18, buf);
}
p.p->setClipping(false);
}

View File

@@ -39,6 +39,7 @@ public:
// get all elements with bounding-box matchings
std::vector<MapModelElement*> possible;
for (MapModelElement* el : m->getModel()->getSelectedLayerElements()) {
if (!el->getMV2D()) {continue;}
BBox2 bbox = el->getMV2D()->getBoundingBox(); // elements 3D bbox
bbox.grow(Point2(g, g)); // grow a little (needed for straight lines)
if (bbox.contains(p2)) {possible.push_back(el);} // intersection?

View File

@@ -6,6 +6,7 @@
#include "../mapview/model/IHasMAC.h"
#include "../mapview/model/IHasFile.h"
#include "../mapview/model/IHasParams.h"
#include <Indoor/floorplan/v2/Floorplan.h>
@@ -65,62 +66,13 @@ QComboBox* getOutlineMethods() {
ElementParamWidget::ElementParamWidget(QWidget *parent) : QGroupBox(parent) {
this->lay = new QGridLayout(this);
setMinimumSize(100, 100);
setMaximumWidth(200);
setMaximumWidth(250);
setTitle("MapElement Parameters");
QGridLayout* lay = new QGridLayout(this);
int r = 0;
lblDetails = new QLabel();
lay->addWidget(new QLabel("selected"),r,0);
lay->addWidget(lblDetails,r,1);
++r;
name.txt = new QLineEdit();
name.lbl = new QLabel("name");
lay->addWidget(name.lbl,r,0);
lay->addWidget(name.txt,r,1);
connect(name.txt , SIGNAL(textChanged(QString)), this, SLOT(onNameChange()));
++r;
mac.lbl = new QLabel("MAC");
mac.txt = new QLineEdit();
lay->addWidget(mac.lbl, r, 0);
lay->addWidget(mac.txt, r, 1);
connect(mac.txt, SIGNAL(textChanged(QString)), this, SLOT(onMACChanged()));
++r;
obstacleType.cmb = getObstacleTypes();
obstacleType.lbl = new QLabel("type");
lay->addWidget(obstacleType.lbl,r,0);
lay->addWidget(obstacleType.cmb,r,1);
connect(obstacleType.cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(onObstacleTypeChange()));
++r;
material.cmb = getMaterials();
material.lbl = new QLabel("material");
lay->addWidget(material.lbl,r,0);
lay->addWidget(material.cmb,r,1);
connect(material.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onMaterialChange()));
++r;
fileName.txt = new QLabel();
fileName.lbl = new QLabel("file");
fileName.btn = new QPushButton("op");
lay->addWidget(fileName.lbl,r,0);
lay->addWidget(fileName.txt,r,1);
lay->addWidget(fileName.btn,r,2);
connect(fileName.btn , SIGNAL(clicked(bool)), this, SLOT(onSelectFileName()));
++r;
outlineMethod.cmb = getOutlineMethods();
outlineMethod.lbl = new QLabel("outline");
lay->addWidget(outlineMethod.lbl,r,0);
lay->addWidget(outlineMethod.cmb,r,1);
connect(outlineMethod.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onOutlineMethodChange()));
++r;
QGridLayout* lay = new QGridLayout();
// start empty
setElement(nullptr);
@@ -129,68 +81,176 @@ ElementParamWidget::ElementParamWidget(QWidget *parent) : QGroupBox(parent) {
void ElementParamWidget::setElement(MapModelElement* el) {
while ( QWidget* w = this->findChild<QWidget*>() ) {delete w;}
delete this->layout();
this->lay = new QGridLayout();
this->setLayout(lay);
int r = 0;
this->curElement = el;
if (el == nullptr) {
lblDetails->setText("-");
} else if (dynamic_cast<MMFloorObstacleLine*>(el)) {
MMFloorObstacleLine* obs = dynamic_cast<MMFloorObstacleLine*>(el);
lblDetails->setText("Obstacle");
} else if (dynamic_cast<MMFloorOutlinePolygon*>(el)) {
MMFloorOutlinePolygon* poly = dynamic_cast<MMFloorOutlinePolygon*>(el);
std::string txt = "Polygon (" + std::to_string(poly->getPolygon()->poly.points.size()) + " Points)";
lblDetails->setText(txt.c_str());
} else {
lblDetails->setText("?");
}
// if (el == nullptr) {
// lblDetails->setText("-");
// } else if (dynamic_cast<MMFloorObstacleLine*>(el)) {
// MMFloorObstacleLine* obs = dynamic_cast<MMFloorObstacleLine*>(el);
// lblDetails->setText("Obstacle");
// } else if (dynamic_cast<MMFloorOutlinePolygon*>(el)) {
// MMFloorOutlinePolygon* poly = dynamic_cast<MMFloorOutlinePolygon*>(el);
// std::string txt = "Polygon (" + std::to_string(poly->getPolygon()->poly.points.size()) + " Points)";
// lblDetails->setText(txt.c_str());
// } else {
// lblDetails->setText("?");
// }
// material? -> select in combo-box
{
IHasMaterial* elem = dynamic_cast<IHasMaterial*>(el);
material.cmb->setVisible(elem != nullptr);
material.lbl->setVisible(elem != nullptr);
if (elem) {material.cmb->setCurrentIndex((int)elem->getMaterial());}
if (elem) {
material.cmb = getMaterials();
material.lbl = new QLabel("material");
lay->addWidget(material.lbl,r,0);
lay->addWidget(material.cmb,r,1);
connect(material.cmb , SIGNAL(currentIndexChanged(int)), this, SLOT(onMaterialChange()));
material.cmb->setCurrentIndex((int)elem->getMaterial());
++r;
}
}
// obstacle-type? -> select in combo-box
{
IHasObstacleType* elem = dynamic_cast<IHasObstacleType*>(el);
obstacleType.cmb->setVisible(elem != nullptr);
obstacleType.lbl->setVisible(elem != nullptr);
if (elem) {obstacleType.cmb->setCurrentIndex((int)elem->getObatcleType());}
if (elem) {
obstacleType.cmb = getObstacleTypes();
obstacleType.lbl = new QLabel("type");
lay->addWidget(obstacleType.lbl,r,0);
lay->addWidget(obstacleType.cmb,r,1);
connect(obstacleType.cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(onObstacleTypeChange()));
obstacleType.cmb->setCurrentIndex((int)elem->getObatcleType());
++r;
}
}
// has name?
{
IHasName* elem = dynamic_cast<IHasName*>(el);
name.txt->setVisible(elem != nullptr);
name.lbl->setVisible(elem != nullptr);
if (elem) {name.txt->setText(elem->getName().c_str());}
}
// has MAC?
{
IHasMAC* elem = dynamic_cast<IHasMAC*>(el);
mac.lbl->setVisible(elem);
mac.txt->setVisible(elem);
if (elem) {mac.txt->setText(elem->getMAC().c_str());}
}
// has outline method?
{
MMFloorOutlinePolygon* elem = dynamic_cast<MMFloorOutlinePolygon*>(el);
outlineMethod.cmb->setVisible(elem);
outlineMethod.lbl->setVisible(elem);
if (elem) {outlineMethod.cmb->setCurrentIndex((int)elem->getMethod());}
if (elem) {
QComboBox* cmb = getOutlineMethods();
QLabel* lbl = new QLabel("outline");
lay->addWidget(lbl,r,0);
lay->addWidget(cmb,r,1);
cmb->setCurrentIndex((int)elem->getMethod());
connect(cmb, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [elem, cmb] (int idx) {
elem->setMethod( (Floorplan::OutlineMethod) cmb->currentData().toInt() );
});
++r;
}
}
// has File
{
IHasFile* elem = dynamic_cast<IHasFile*>(el);
fileName.lbl->setVisible(elem);
fileName.txt->setVisible(elem);
fileName.btn->setVisible(elem);
if (elem) {fileName.txt->setText(elem->getFileName().c_str());}
IHasParams* elem = dynamic_cast<IHasParams*>(el);
if (elem) {
for(int i = 0; i < elem->getNumParams(); ++i) {
const Param param = elem->getParamDesc(i);
const ParamValue value = elem->getParamValue(i);
lay->addWidget(new QLabel(param.name.c_str()),r,0);
switch(param.type) {
case ParamType::FLOAT: {
const std::string str = std::to_string(value.toFloat());
QLineEdit* le = new QLineEdit( str.c_str() );
connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
const float val = std::stof(str.toStdString());
elem->setParamValue(i, ParamValue(val));
});
lay->addWidget(le,r,1);
break;
}
case ParamType::INT: {
const std::string str = std::to_string(value.toInt());
QLineEdit* le = new QLineEdit( str.c_str() );
connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
const int val = std::stoi(str.toStdString());
elem->setParamValue(i, ParamValue(val));
});
lay->addWidget(le,r,1);
break;
}
case ParamType::STRING: {
const std::string str = value.toString();
QLineEdit* le = new QLineEdit( str.c_str() );
connect(le, &QLineEdit::textChanged, [i,elem] (const QString& str) {
elem->setParamValue(i, ParamValue(str.toStdString()));
});
lay->addWidget(le,r,1);
break;
}
case ParamType::FILE: {
const std::string str = value.toString();
QLabel* lblFile = new QLabel(str.c_str());
QPushButton* btn = new QPushButton("<");
btn->setMaximumSize(32,32);
connect(btn, &QPushButton::clicked, [i,elem,lblFile] (const bool checked) {
QString res = QFileDialog::getOpenFileName();
elem->setParamValue(i, ParamValue(res.toStdString()));
lblFile->setText(res);
});
lay->addWidget(lblFile,r,1);
lay->addWidget(btn,r,2);
break;
}
case ParamType::POINT2: {
const Point2 p2 = value.toPoint2();
QWidget* subWidget = new QWidget();
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
QLineEdit* txtX = new QLineEdit(QString::number(p2.x));
QLineEdit* txtY = new QLineEdit(QString::number(p2.y));
laySub->addWidget(txtX,0,0);
laySub->addWidget(txtY,0,1);
lay->addWidget(subWidget,r,1);
auto onChange = [i,elem,txtX,txtY] (const QString& str) {
elem->setParamValue(i, ParamValue( Point2(txtX->text().toFloat(), txtY->text().toFloat()) ));
};
connect(txtX, &QLineEdit::textChanged, onChange);
connect(txtY, &QLineEdit::textChanged, onChange);
break;
}
case ParamType::POINT3: {
const Point3 p3 = value.toPoint3();
QWidget* subWidget = new QWidget();
QGridLayout* laySub = new QGridLayout(subWidget); laySub->setMargin(0);
QLineEdit* txtX = new QLineEdit(QString::number(p3.x));
QLineEdit* txtY = new QLineEdit(QString::number(p3.y));
QLineEdit* txtZ = new QLineEdit(QString::number(p3.z));
laySub->addWidget(txtX,0,0);
laySub->addWidget(txtY,0,1);
laySub->addWidget(txtZ,0,2);
lay->addWidget(subWidget,r,1);
auto onChange = [i,elem,txtX,txtY,txtZ] (const QString& str) {
elem->setParamValue(i, ParamValue( Point3(txtX->text().toFloat(), txtY->text().toFloat(), txtZ->text().toFloat()) ));
};
connect(txtX, &QLineEdit::textChanged, onChange);
connect(txtY, &QLineEdit::textChanged, onChange);
connect(txtZ, &QLineEdit::textChanged, onChange);
break;
}
}
++r;
}
}
}
}
@@ -205,22 +265,22 @@ void ElementParamWidget::onObstacleTypeChange() {
if (el) {el->setObstacleType((Floorplan::ObstacleType) obstacleType.cmb->currentData().toInt() );}
}
void ElementParamWidget::onNameChange() {
IHasName* el = dynamic_cast<IHasName*>(this->curElement);
if (el) {el->setName(name.txt->text().toStdString());}
}
//void ElementParamWidget::onNameChange() {
// IHasName* el = dynamic_cast<IHasName*>(this->curElement);
// if (el) {el->setName(name.txt->text().toStdString());}
//}
void ElementParamWidget::onOutlineMethodChange() {
MMFloorOutlinePolygon* el = dynamic_cast<MMFloorOutlinePolygon*>(this->curElement);
if (el) {el->setMethod( (Floorplan::OutlineMethod) outlineMethod.cmb->currentData().toInt() );}
}
//void ElementParamWidget::onOutlineMethodChange() {
// MMFloorOutlinePolygon* el = dynamic_cast<MMFloorOutlinePolygon*>(this->curElement);
// if (el) {el->setMethod( (Floorplan::OutlineMethod) outlineMethod.cmb->currentData().toInt() );}
//}
void ElementParamWidget::onMACChanged() {
dynamic_cast<IHasMAC*>(curElement)->setMAC(mac.txt->text().toStdString());
}
//void ElementParamWidget::onMACChanged() {
// dynamic_cast<IHasMAC*>(curElement)->setMAC(mac.txt->text().toStdString());
//}
void ElementParamWidget::onSelectFileName() {
QString res = QFileDialog::getOpenFileName(this);
dynamic_cast<IHasFile*>(curElement)->setFileName(res.toStdString());
fileName.lbl->setText(res);
}
//void ElementParamWidget::onSelectFileName() {
// QString res = QFileDialog::getOpenFileName(this);
// dynamic_cast<IHasFile*>(curElement)->setFileName(res.toStdString());
// fileName.txt->setText(res);
//}

View File

@@ -8,6 +8,7 @@ class QLabel;
class QComboBox;
class QLineEdit;
class QPushButton;
class QGridLayout;
class ElementParamWidget : public QGroupBox {
@@ -21,8 +22,11 @@ public:
private:
QGridLayout* lay;
QLabel* lblDetails;
MapModelElement* curElement = nullptr;
int r = 0;
struct {
QComboBox* cmb;
@@ -34,27 +38,6 @@ private:
QLabel* lbl;
} obstacleType;
struct {
QLineEdit* txt;
QLabel* lbl;
} name;
struct {
QLineEdit* txt;
QLabel* lbl;
} mac;
struct {
QLabel* txt;
QPushButton* btn;
QLabel* lbl;
} fileName;
struct {
QComboBox* cmb;
QLabel* lbl;
} outlineMethod;
signals:
public slots:
@@ -66,10 +49,6 @@ private slots:
void onMaterialChange();
void onObstacleTypeChange();
void onNameChange();
void onMACChanged();
void onOutlineMethodChange();
void onSelectFileName();
};

View File

@@ -4,12 +4,13 @@
#include <QLineEdit>
#include <QLabel>
#include "mapview/model/IHasName.h"
#include "mapview/model/MMFloor.h"
LayerParamWidget::LayerParamWidget(QWidget *parent) : QGroupBox(parent) {
setMinimumSize(100, 100);
setMaximumWidth(200);
setMaximumWidth(250);
setTitle("MapLayer Parameters");
QGridLayout* lay = new QGridLayout(this);

View File

@@ -22,7 +22,7 @@ ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent)
setMinimumWidth(48);
QGridLayout* lay = new QGridLayout(this);
int r = 0;
// OBSTACLES
btnGround = new QPushButton(UIHelper::getIcon("floor"), "");
@@ -57,6 +57,11 @@ ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent)
lay->addWidget(btnImage, r++, 0, 1,1,Qt::AlignTop);
connect(btnImage, SIGNAL(clicked(bool)), this, SLOT(onNewImage()));
// POI
btnPOI = new QPushButton(UIHelper::getIcon("poi"), "");
btnPOI->setMinimumSize(s,s);
lay->addWidget(btnPOI, r++, 0, 1,1,Qt::AlignTop);
connect(btnPOI, SIGNAL(clicked(bool)), this, SLOT(onNewPOI()));
// FILL
lay->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), r, 0);
@@ -77,8 +82,9 @@ void ToolBoxWidget::setSelectedLayer(MapLayer *ml) {
btnWifi->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_ACCESS_POINTS));
btnBeacon->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_BEACONS));
btnPOI->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_POIS));
btnImage->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_UNDERLAY));
btnImage->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_UNDERLAYS));
}
@@ -164,11 +170,23 @@ void ToolBoxWidget::onNewBeacon() {
}
void ToolBoxWidget::onNewPOI() {
const Point2 center = view->getScaler().getCenter();
Floorplan::POI* poi = new Floorplan::POI(
Floorplan::POIType::ROOM, "noname", Point2(center.x, center.y)
);
MMFloorPOIs* pois = (MMFloorPOIs*) curLayer;
pois->createPOI(poi);
}
void ToolBoxWidget::onNewImage() {
const Point2 center = view->getScaler().getCenter();
MMFloorUnderlay* underlay = (MMFloorUnderlay*) curLayer;
underlay->createImage(center);
MMFloorUnderlays* underlays = (MMFloorUnderlays*) curLayer;
underlays->createImage(center);
}

View File

@@ -26,6 +26,7 @@ private:
MapView2D* view;
MapLayer* curLayer;
int r = 0;
QPushButton* btnGround;
QPushButton* btnWall;
@@ -33,6 +34,7 @@ private:
QPushButton* btnWifi;
QPushButton* btnBeacon;
QPushButton* btnPOI;
QPushButton* btnImage;
@@ -44,6 +46,7 @@ private slots:
void onNewAccessPoint();
void onNewBeacon();
void onNewPOI();
void onNewImage();

View File

@@ -9,5 +9,6 @@
<file>res/icons/beacon.svg</file>
<file>res/icons/image.svg</file>
<file>res/icons/cross.png</file>
<file>res/icons/poi.svg</file>
</qresource>
</RCC>

189
res/icons/poi.svg Normal file
View File

@@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.w3.org/2000/svg"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
id="svg4206"
sodipodi:docname="_svgclean2.svg"
viewBox="0 0 313.57 499.87"
version="1.1"
inkscape:version="0.48.3.1 r9886"
>
<defs
id="defs4208"
>
<radialGradient
id="radialGradient3916"
gradientUnits="userSpaceOnUse"
cy="315.54"
cx="258.26"
gradientTransform="matrix(-.8861 .30979 -.33003 -.94397 705.84 424.5)"
r="156.79"
inkscape:collect="always"
>
<stop
id="stop3767"
style="stop-color:#63798f"
offset="0"
/>
<stop
id="stop3769"
style="stop-color:#95b8d9"
offset="1"
/>
</radialGradient
>
<linearGradient
id="linearGradient3918"
y2="206.65"
gradientUnits="userSpaceOnUse"
x2="372.86"
y1="426.65"
x1="263.21"
inkscape:collect="always"
>
<stop
id="stop3757"
style="stop-color:#4d5e6e"
offset="0"
/>
<stop
id="stop3759"
style="stop-color:#95b8d9"
offset="1"
/>
</linearGradient
>
<filter
id="filter3852"
width="1.2618"
y="-1.44"
x="-.13091"
height="3.88"
color-interpolation-filters="sRGB"
inkscape:collect="always"
>
<feGaussianBlur
id="feGaussianBlur3854"
stdDeviation="12"
inkscape:collect="always"
/>
</filter
>
</defs
>
<sodipodi:namedview
id="base"
bordercolor="#666666"
inkscape:pageshadow="2"
inkscape:window-y="0"
pagecolor="#ffffff"
inkscape:window-maximized="0"
inkscape:zoom="0.35"
inkscape:window-x="0"
inkscape:window-height="645"
showgrid="false"
borderopacity="1.0"
inkscape:current-layer="layer1"
inkscape:cx="156.78568"
inkscape:cy="249.93782"
inkscape:window-width="674"
inkscape:pageopacity="0.0"
inkscape:document-units="px"
/>
<g
id="layer1"
inkscape:label="Calque 1"
inkscape:groupmode="layer"
transform="translate(-218.21 -282.43)"
>
<g
id="g4259"
>
<g
id="g3856"
transform="translate(55,141.14)"
>
<path
id="path3858"
d="m266.67 442.36 53.333 160 53.333-160z"
style="fill:#4d5e6e"
inkscape:connector-curvature="0"
/>
<path
id="path3860"
sodipodi:rx="134.28572"
sodipodi:ry="134.28572"
style="stroke:url(#linearGradient3918);stroke-width:45;fill:url(#radialGradient3916)"
sodipodi:type="arc"
d="m462.86 289.51c0 74.164-60.122 134.29-134.29 134.29-74.164 0-134.29-60.122-134.29-134.29 0-74.164 60.122-134.29 134.29-134.29 74.164 0 134.29 60.122 134.29 134.29z"
transform="translate(-8.5714,8.5714)"
sodipodi:cy="289.50504"
sodipodi:cx="328.57144"
/>
</g
>
<path
id="path3866"
style="opacity:.85357;filter:url(#filter3852);fill:#000000"
inkscape:connector-curvature="0"
d="m275 733.5h220l-120 20z"
/>
</g
>
</g
>
<metadata
id="metadata19"
>
<rdf:RDF
>
<cc:Work
>
<dc:format
>image/svg+xml</dc:format
>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage"
/>
<cc:license
rdf:resource="http://creativecommons.org/licenses/publicdomain/"
/>
<dc:publisher
>
<cc:Agent
rdf:about="http://openclipart.org/"
>
<dc:title
>Openclipart</dc:title
>
</cc:Agent
>
</dc:publisher
>
</cc:Work
>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/"
>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution"
/>
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks"
/>
</cc:License
>
</rdf:RDF
>
</metadata
>
</svg
>

After

Width:  |  Height:  |  Size: 4.7 KiB