initial commit

This commit is contained in:
kazu
2016-05-24 16:55:19 +02:00
commit 13a89df8d6
77 changed files with 7454 additions and 0 deletions

93
IndoorMap.pro Normal file
View File

@@ -0,0 +1,93 @@
#-------------------------------------------------
#
# Project created by QtCreator 2016-03-27T13:14:56
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets svg
TARGET = IndoorMap
TEMPLATE = app
INCLUDEPATH += \
../
SOURCES += main.cpp\
MainWindow.cpp \
MainController.cpp \
mapview/tools/ToolSelector.cpp \
mapview/tools/Tool.cpp \
mapview/MapView2D.cpp \
params/ElementParamWidget.cpp \
params/LayerParamWidget.cpp \
params/ActionWidget.cpp \
params/ToolBox.cpp \
mapview/model/MapModel.cpp \
tree/MapTreeModel.cpp
HEADERS += MainWindow.h \
mapview/Painter.h \
mapview/Scaler.h \
mapview/tools/ToolSelector.h \
mapview/tools/Tool.h \
mapview/model/MapLayer.h \
mapview/model/MapModel.h \
mapview/tools/ToolMoveMap.h \
mapview/tools/Tools.h \
mapview/tools/ToolRuler.h \
mapview/tools/ToolMapZoom.h \
tree/MapTreeModel.h \
MainController.h \
mapview/tools/ToolMapGrid.h \
mapview/model/MapLayers.h \
mapview/MapView2D.h \
params/ElementParamWidget.h \
params/LayerParamWidget.h \
params/ActionWidget.h \
params/ToolBoxWidget.h \
UIHelper.h \
mapview/model/MapModelElement.h \
mapview/elements/MapViewElementHelper.h \
mapview/model/IHasAttributes.h \
mapview/model/IHasMAC.h \
mapview/model/IHasMaterial.h \
mapview/model/IHasName.h \
mapview/model/IHasObstacleType.h \
mapview/model/IHasPosition3D.h \
mapview/elements/MV2DElementFloorObstacleLine.h \
mapview/elements/MV2DElement.h \
mapview/elements/MV2DElementFloorOutlinePolygon.h \
mapview/elements/MV2DElementBeacon.h \
mapview/elements/MV2DElementAccessPoint.h \
mapview/elements/MV2DElementFloorObstacleCircle.h \
mapview/model/MMFloorObstacleCircle.h \
mapview/model/MMFloorObstacleLine.h \
mapview/model/MMFloorOutlinePolygon.h \
mapview/model/MMFloor.h \
mapview/model/MMFloors.h \
mapview/model/MMFloorObstacles.h \
mapview/model/MMFloorOutline.h \
mapview/model/MMRoot.h \
mapview/model/MMFloorAccessPoint.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
FORMS += MainWindow.ui
SOURCES += \
/apps/android/workspace/Indoor/lib/tinyxml/tinyxml2.cpp
RESOURCES += \
res.qrc
DISTFILES += \
res/icons/polygon.svg

103
MainController.cpp Normal file
View File

@@ -0,0 +1,103 @@
#include "MainController.h"
#include "MainWindow.h"
#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"
#include "mapview/tools/ToolRuler.h"
#include "mapview/tools/ToolMapGrid.h"
#include "params/ElementParamWidget.h"
#include "params/LayerParamWidget.h"
#include "params/ToolBoxWidget.h"
#include "params/ActionWidget.h"
#include "tree/MapTreeModel.h"
#include <QFileDialog>
#include <QTreeView>
MainController::MainController() {
mw = new MainWindow();
mw->resize(1000, 700);
MapView2D* mapView2D = mw->getMapView2D();
QTreeView* layerTree = mw->getTree();
mapModel = new MapModel();
//mapModel->load("/apps/android/workspace/IndoorApp/res/map.xml");
mapView2D->setModel(mapModel);
ToolMoveMap* moveMap = new ToolMoveMap();
ToolRuler* ruler = new ToolRuler();
ToolMapZoom* mapZoom = new ToolMapZoom();
ToolMapGrid* mapGrid = new ToolMapGrid();
ToolSelector* mapSelector = new ToolSelector();
mapView2D->getTools().enable(mapGrid);
mapView2D->getTools().enable(moveMap);
mapView2D->getTools().enable(mapZoom);
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()));
connect(mapModel, SIGNAL(aboutToReset()), this, SLOT(onMapModelAboutToReset()));
connect(mapModel, SIGNAL(reset()), this, SLOT(onMapModelReset()));
mapModel->load("/apps/map9.xml");
}
void MainController::layerSelected(QModelIndex idx) {
mw->getMapView2D()->layerChange();
MapLayer* ml = static_cast<MapLayer*>(idx.internalPointer());
mapModel->setSelectedLayer(ml);
mw->getMapView2D()->layerChange();
mw->getLayerParamWidget()->setElement(ml);
mw->getToolBoxWidget()->setSelectedLayer(ml);
}
void MainController::mapElementSelected(MapModelElement* el) {
mw->getElementParamWidget()->setElement(el);
}
void MainController::onMapModelAboutToReset() {
mw->getLayerParamWidget()->setElement(nullptr);
mw->getToolBoxWidget()->setSelectedLayer(nullptr);
mw->getMapView2D()->update();
}
void MainController::onMapModelReset() {
mw->getTree()->expandAll();
}
void MainController::onLoad() {
QString file = QFileDialog::getOpenFileName(mw, "open a map");
if (file != "") {
mapModel->load(file.toStdString());
}
}
void MainController::onSave() {
QString file = QFileDialog::getSaveFileName(mw, "save the map");
if (file != "") {
mapModel->save(file.toStdString());
}
}

46
MainController.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef MAINCONTROLLER_H
#define MAINCONTROLLER_H
#include <QObject>
#include <QModelIndex>
#include "MainWindow.h"
class MapTreeModel;
class MapModelElement;
class MapModel;
class MainController : public QObject {
Q_OBJECT
public:
explicit MainController();
void show() {mw->show();}
signals:
public slots:
/** MapLayer selection changed */
void layerSelected(QModelIndex idx);
/** MapElement selection has changed */
void mapElementSelected(MapModelElement* el);
void onLoad();
void onSave();
void onMapModelAboutToReset();
void onMapModelReset();
private:
MainWindow* mw;
MapTreeModel* mapTreeModel;
MapModel* mapModel;
};
#endif // MAINCONTROLLER_H

52
MainWindow.cpp Normal file
View File

@@ -0,0 +1,52 @@
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QGraphicsScene>
#include "mapview/MapView2D.h"
#include "mapview/model/MMFloorObstacleLine.h"
#include <Indoor/floorplan/v2/Floorplan.h>
#include "mapview/tools/ToolMoveMap.h"
#include "mapview/tools/ToolRuler.h"
#include "mapview/tools/ToolMapZoom.h"
#include "params/ElementParamWidget.h"
#include "params/LayerParamWidget.h"
#include "params/ActionWidget.h"
#include "params/ToolBoxWidget.h"
#include "tree/MapTreeModel.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
mapView2D = new MapView2D();
elementParamWidget = new ElementParamWidget();
layerParamWidget = new LayerParamWidget();
actionWidget = new ActionWidget();
toolBoxWidget = new ToolBoxWidget(mapView2D);
ui->layButtons->addWidget(toolBoxWidget);
ui->layMap->addWidget(mapView2D);
ui->layTree->addWidget(layerParamWidget);
ui->layTree->addWidget(elementParamWidget);
ui->layTree->addWidget(actionWidget);
}
MainWindow::~MainWindow() {
delete ui;
}
QTreeView* MainWindow::getTree() {
return ui->layerTree;
}

42
MainWindow.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MapView2D;
class QTreeView;
class ElementParamWidget;
class LayerParamWidget;
class ActionWidget;
class ToolBoxWidget;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
MapView2D* getMapView2D() {return mapView2D;}
ElementParamWidget* getElementParamWidget() {return elementParamWidget;}
LayerParamWidget* getLayerParamWidget() {return layerParamWidget;}
ToolBoxWidget* getToolBoxWidget() {return toolBoxWidget;}
ActionWidget* getActionWidget() {return actionWidget;}
QTreeView* getTree();
private:
Ui::MainWindow *ui;
MapView2D* mapView2D;
ElementParamWidget* elementParamWidget;
LayerParamWidget* layerParamWidget;
ActionWidget* actionWidget;
ToolBoxWidget* toolBoxWidget;
};
#endif // MAINWINDOW_H

45
MainWindow.ui Normal file
View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>777</width>
<height>407</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="layButtons"/>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="layMap"/>
</item>
<item row="0" column="2">
<layout class="QVBoxLayout" name="layTree">
<item>
<widget class="QTreeView" name="layerTree">
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

32
UIHelper.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef UIHELPER_H
#define UIHELPER_H
#include <QImage>
#include <QPainter>
#include <QtSvg/QSvgRenderer>
class UIHelper {
public:
// static QIcon getIcon(const std::string& name) {
// const std::string file = "://res/icons/" + name + "16.png";
// QPixmap img(file.c_str());
// return QIcon(img);
// }
static QIcon getIcon(const std::string& name) {
const int size = 32;
const QColor fill = Qt::transparent;
const std::string file = "://res/icons/" + name + ".svg";
QSvgRenderer renderer(QString(file.c_str()));
QPixmap pm(size, size);
pm.fill(fill);
QPainter painter(&pm);
renderer.render(&painter, pm.rect());
return QIcon(pm);
}
};
#endif // UIHELPER_H

16
main.cpp Normal file
View File

@@ -0,0 +1,16 @@
#include "MainController.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainController mc;
mc.show();
return a.exec();
}

90
mapview/MapView2D.cpp Normal file
View File

@@ -0,0 +1,90 @@
#include "MapView2D.h"
#include <QPainter>
#include <QOpenGLFunctions>
#include <QMouseEvent>
#include <QKeyEvent>
#include <iostream>
#include "model/MapModelElement.h"
#include "model/MapModel.h"
MapView2D::MapView2D(QWidget* parent) : QOpenGLWidget(parent) {
// openGL params
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSamples(1);
// format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
setFormat(format);
// receive mouse-move even when mouse is not down
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
// defaults
s.setScale(5);
}
void MapView2D::paintGL() {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClear(GL_COLOR_BUFFER_BIT);
QPainter qp(this);
Painter p(s, &qp, width(), height());
s.setScreenSize(width(), height());
// background tools
tools.paintBefore(this, p);
// render all visible elements
qp.setRenderHint( QPainter::Antialiasing, true );
for (MapModelElement* el : getModel()->getVisibleElements()) {el->getMV2D()->paint(p);}
qp.setRenderHint( QPainter::Antialiasing, false );
// foreground tools
tools.paintAfter(this, p);
}
void MapView2D::initializeGL() {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void MapView2D::resizeGL() {
// TODO ?
}
void MapView2D::keyPressEvent(QKeyEvent *e) {
tools.keyPressEvent(this, e);
update();
}
void MapView2D::wheelEvent(QWheelEvent* e) {
tools.wheelEvent(this, e);
update();
}
void MapView2D::mousePressEvent(QMouseEvent* e) {
tools.mousePressEvent(this, e);
update();
}
void MapView2D::mouseMoveEvent(QMouseEvent* e) {
tools.mouseMoveEvent(this, e);
update();
}
void MapView2D::mouseReleaseEvent(QMouseEvent* e) {
tools.mouseReleaseEvent(this, e);
update();
}

76
mapview/MapView2D.h Normal file
View File

@@ -0,0 +1,76 @@
#ifndef MAP2D_H
#define MAP2D_H
#include <QWidget>
#include <QOpenGLWidget>
#include "Scaler.h"
class MapModel;
#include "mapview/tools/Tools.h"
/**
* view to render (and edit) MapElements
*/
class MapView2D : public QOpenGLWidget {
Q_OBJECT
private:
/** scaling within the map */
Scaler s;
/** the currently active tool (if any) */
Tools tools;
/** the underlying data-model */
MapModel* model = nullptr;
public:
/** ctor */
MapView2D(QWidget* parent = nullptr);
void layerChange() {
update();
tools.layerChange(this);
}
public:
void paintGL();
void initializeGL();
void resizeGL();
Tools& getTools() {return tools;}
/** get the underlying data-model */
MapModel* getModel() {return model;}
/** set the underlying data-model */
void setModel(MapModel* mdl) {
this->model = mdl;
update();
}
/** get the underlying scaling device */
Scaler& getScaler() {return s;}
protected:
void mousePressEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e);
void mouseReleaseEvent(QMouseEvent* e);
void wheelEvent(QWheelEvent* e);
void keyPressEvent(QKeyEvent* e);
};
#endif // MAP2D_H

102
mapview/Painter.h Normal file
View File

@@ -0,0 +1,102 @@
#ifndef PAINTER_H
#define PAINTER_H
#include <QPainter>
#include <Indoor/geo/Point2.h>
#include <Indoor/geo/Point3.h>
#include "Scaler.h"
class Painter {
public:
Scaler& s;
QPainter* p;
int w;
int h;
public:
/** ctor */
Painter(Scaler& s, QPainter* p, int w, int h) : s(s), p(p), w(w), h(h) {
p->setPen(Qt::black);
p->setBrush(Qt::NoBrush);
}
int width() {return w;}
int height() {return h;}
void drawLine(const Point2 p1, const Point2 p2) {
p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
}
void drawLine(const Point3 p1, const Point3 p2) {
p->drawLine(s.xms(p1.x), s.yms(p1.y), s.xms(p2.x), s.yms(p2.y));
}
void drawCircle(const Point3 center) {
int r = 5;
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
}
void drawCircle(const Point2 center) {
int r = 5;
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
}
void drawCircle(const Point2 center, const float size_m) {
int r = s.ms(size_m);
p->drawEllipse(s.xms(center.x)-r, s.yms(center.y)-r, 2*r, 2*r);
}
void drawLine(const float x1, const float y1, const float x2, const float y2) {
p->drawLine(s.xms(x1), s.yms(y1), s.xms(x2), s.yms(y2));
}
void drawRect(const float x1, const float y1, const float x2, const float y2) {
float w = x2-x1;
float h = y1-y2;
p->drawRect(s.xms(x1), s.yms(y1), s.ms(w), s.ms(h));
}
void drawText(const Point2 pos, const std::string& text) {
p->drawText(s.xms(pos.x), s.xms(pos.y), text.c_str());
}
void drawPolygon(const std::vector<Point2>& points) {
std::vector<QPointF> vec;
for (const Point2 p : points) {
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
}
p->drawPolygon(vec.data(), vec.size());
}
void drawPolygon(const std::vector<Point3>& points) {
std::vector<QPointF> vec;
for (const Point3 p : points) {
vec.push_back(QPointF(s.xms(p.x), s.yms(p.y)));
}
p->drawPolygon(vec.data(), vec.size());
}
void setBrush(const QBrush& brush) { p->setBrush(brush); }
void setBrush(const Qt::BrushStyle& brush) { p->setBrush(brush); }
void setPen(const QPen& pen) {p->setPen(pen); }
void setPen(const QColor& pen) {p->setPen(pen); }
void setPen(const Qt::PenStyle& pen) {p->setPen(pen); }
template <typename Pen, typename Brush> void setPenBrush(const Pen& pen, const Brush& brush) {setPen(pen); setBrush(brush);}
const Scaler& getScaler() {return s;}
private:
};
#endif // PAINTER_H

104
mapview/Scaler.h Normal file
View File

@@ -0,0 +1,104 @@
#ifndef SCALER_H
#define SCALER_H
#include <Indoor/geo/Point3.h>
#include <QRectF>
struct Rect {
float x0;
float y0;
float x1;
float y1;
};
/**
* - scale between map- and screen-space.
* - inverts y-axis (for openGL)
*/
class Scaler {
private:
int w;
int h;
float _scale = 50;
float _snap = 0.1;
Point3 _offset;
public:
/** map->screen (no offset) */
float ms(const float m) const {return m*_scale;}
/** x map->screen */
float xms(const float x) const {return w/2+(x+_offset.x)*_scale;}
/** x map->screen */
float yms(const float y) const {return h/2-(y-_offset.y)*_scale;}
/** screen->map (no offset) */
float sm(const float s) const {return (s/_scale);}
/** x screen->map */
float xsm(const float x) const {return ((x-w/2)/_scale)-_offset.x;}
/** y screen->map */
float ysm(const float y) const {return ((h/2-y)/_scale)+_offset.y;}
void setScale(const float s) {_scale = s;}
float getScale() const {return _scale;}
void setOffset(Point3 p) {_offset = p;}
Point3 getOffset() const {return _offset;}
void addOffset(int px, int py) {_offset.x += sm(px); _offset.y += sm(py);}
float getLODstep() const {
float step = 0.01;
if (_scale <= 1000) {step = 0.1;}
if (_scale <= 500) {step = 0.5;}
if (_scale <= 100) {step = 1.0;}
if (_scale <= 50) {step = 5.0;}
if (_scale <= 10) {step = 10.0;}
if (_scale <= 1) {step = 100.0;}
return step;
}
/** get the currently visible map-region given the provided screen-size */
Rect getMapVisible(const int screenW, const int screenH) const {
Rect r;
r.x0 = xsm(0);
r.x1 = xsm(screenW);
r.y0 = ysm(screenH);
r.y1 = ysm(0);
return r;
}
/** get the currently visible map-region given the provided screen-size, SNAPED to the given grid-size */
Rect getMapVisible(const int screenW, const int screenH, const float mapGridSize) const {
Rect r = getMapVisible(screenW, screenH);
r.x0 = snapFloor(r.x0, mapGridSize);
r.y0 = snapFloor(r.y0, mapGridSize);
r.x1 = snapCeil(r.x1, mapGridSize);
r.y1 = snapCeil(r.y1, mapGridSize);
return r;
}
//Point2 getOffset() const {return _offset.xy();}
Point2 getCenter() const {return Point2(-_offset.x, _offset.y);}
void setScreenSize(const int w, const int h) {this->w = w; this->h = h;}
public:
static float snap(const float v, const float grid) { return std::round(v/grid)*grid; }
static Point2 snap(const Point2 p, const float grid) { return Point2(snap(p.x, grid), snap(p.y, grid)); }
static Point3 snap(const Point3 p, const float grid) { return Point3(snap(p.x, grid), snap(p.y, grid), snap(p.z, grid)); }
static float snapCeil(const float v, const float grid) { return std::ceil(v/grid) * grid; }
static float snapFloor(const float v, const float grid) { return std::floor(v/grid) * grid; }
//float snap(const float v) const { return v; }
};
#endif // SCALER_H

View File

@@ -0,0 +1,74 @@
#ifndef MV2DELEMENT_H
#define MV2DELEMENT_H
#include <QKeyEvent>
#include "../MapView2D.h"
#include "../Painter.h"
#include <Indoor/geo/BBox2.h>
#include <Indoor/geo/Line2.h>
/**
* represents one drawable, selectable, editable, ...
* element shown within the MapView2D
*/
class MV2DElement {
private:
bool _focused = false;
public:
/** dtor */
virtual ~MV2DElement() {;}
/** get the element's 2D bounding box */
virtual BBox2 getBoundingBox() const = 0;
/** get the element's minimal distance (nearest whatsoever) to the given point */
virtual float getMinDistanceXY(const Point2 p) const = 0;
/** repaint me */
virtual void paint(Painter& p) = 0;
/** got focus */
void focus() {
_focused = true;
onFocus();
}
/** lost focus */
void unfocus() {
_focused = false;
onUnfocus();
}
bool hasFocus() {return _focused;}
/** mouse pressed at the given point */
virtual void mousePressed(MapView2D* v, const Point2 p) = 0;
/** mouse moved to the given point */
virtual void mouseMove(MapView2D* v, const Point2 p) = 0;
/** mouse released */
virtual void mouseReleased(MapView2D* v, const Point2 p) = 0;
/** key pressed. return true when consumed. */
virtual bool keyPressEvent(MapView2D* v, QKeyEvent* e) = 0;
protected:
virtual void onFocus() = 0;
virtual void onUnfocus() = 0;
};
#endif // MV2DELEMENT_H

View File

@@ -0,0 +1,97 @@
#ifndef MV2DELEMENTACCESSPOINT_H
#define MV2DELEMENTACCESSPOINT_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementAccessPoint : public MV2DElement {
private:
bool sel = false;
Floorplan::AccessPoint* ap;
public:
/** ctor with the AP to render/edit */
MV2DElementAccessPoint(Floorplan::AccessPoint* ap) : ap(ap) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
bbox.add(Point2(ap->pos.x, ap->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(ap->pos.xy());
}
/** repaint me */
void paint(Painter& p) override {
if (sel) {
p.setPenBrush(Qt::black, CFG::SEL_COLOR);
p.drawCircle(ap->pos.xy());
} else if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawCircle(ap->pos.xy());
} else {
p.setPenBrush(Qt::gray, Qt::NoBrush);
p.drawCircle(ap->pos.xy());
}
// label
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());
}
}
/** 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);
ap->pos.x = p.x;
ap->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 // MV2DELEMENTACCESSPOINT_H

View File

@@ -0,0 +1,94 @@
#ifndef MV2DELEMENTBEACON_H
#define MV2DELEMENTBEACON_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementBeacon : public MV2DElement {
private:
bool sel = false;
Floorplan::Beacon* b;
public:
/** ctor with the Beacon to render/edit */
MV2DElementBeacon(Floorplan::Beacon* b) : b(b) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
bbox.add(Point2(b->pos.x, b->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(b->pos.xy());
}
/** repaint me */
void paint(Painter& p) override {
if (sel) {
p.setPenBrush(Qt::black, CFG::SEL_COLOR);
p.drawCircle(b->pos.xy());
} else if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawCircle(b->pos.xy());
} else {
p.setPenBrush(Qt::gray, Qt::NoBrush);
p.drawCircle(b->pos.xy());
}
// label
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());
}
}
virtual void onFocus() override {
;
}
virtual void onUnfocus() override {
sel = false;
}
/** 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);
b->pos.x = p.x;
b->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;
}
};
#endif // MV2DELEMENTBEACON_H

View File

@@ -0,0 +1,108 @@
#ifndef MV2DELEMENTFLOOROBSTACLECIRCLE_H
#define MV2DELEMENTFLOOROBSTACLECIRCLE_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementFloorObstacleCircle : public MV2DElement {
private:
int selPoint = -1;
Floorplan::FloorObstacleCircle* c;
public:
/** ctor */
MV2DElementFloorObstacleCircle(Floorplan::FloorObstacleCircle* c) : c(c) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
bbox.add(c->center);
bbox.grow(Point2(c->radius, c->radius));
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
float getMinDistanceXY(const Point2 p) const override {
return std::min(p.getDistance(getSelPoints()[0]), p.getDistance(getSelPoints()[1]));
}
/** repaint me */
void paint(Painter& p) override {
QPen pen = MapElementHelper::getPen(c->material, c->type, hasFocus());
p.setPenBrush(pen, Qt::NoBrush);
p.drawCircle(c->center, c->radius);
//QBrush brush = MapElementHelper::getBru(c->material, c->type, _focused);
// selected endpoints?
if (hasFocus()) {
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
if (selPoint == 0) {p.drawCircle(getSelPoints()[0]);}
if (selPoint == 1) {p.drawCircle(getSelPoints()[1]);}
}
// available endpoints
if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawCircle(getSelPoints()[0]);
p.drawCircle(getSelPoints()[1]);
}
}
std::vector<Point2> getSelPoints() const {
return {c->center, (c->center + Point2(c->radius,0))};
}
virtual void onFocus() override {
;
}
virtual void onUnfocus() override {
selPoint = -1;
}
/** 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 (selPoint == -1) {return;}
const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
if (selPoint == 0) {c->center = p;}
if (selPoint == 1) {c->radius = p.getDistance(c->center);}
}
/** mouse released */
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
const float l1 = _p.getDistance(getSelPoints()[0]);
const float l2 = _p.getDistance(getSelPoints()[1]);
if (l1 < l2 && l1 <= t) {selPoint = 0;}
else if (l2 < l1 && l2 <= t) {selPoint = 1;}
else {selPoint = -1;}
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
(void) e;
return false;
}
};
#endif // MV2DELEMENTFLOOROBSTACLECIRCLE_H

View File

@@ -0,0 +1,108 @@
#ifndef MV2DELEMENTFLOOROBSTACLELINE_H
#define MV2DELEMENTFLOOROBSTACLELINE_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementFloorObstacleLine : public MV2DElement {
private:
int selPoint = -1;
Floorplan::FloorObstacleLine* fo;
public:
/** ctor */
MV2DElementFloorObstacleLine(Floorplan::FloorObstacleLine* fo) : fo(fo) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
bbox.add(fo->from);
bbox.add(fo->to);
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
float getMinDistanceXY(const Point2 p) const override {
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
}
/** repaint me */
void paint(Painter& p) override {
// selected endpoints?
if (hasFocus()) {
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
if (selPoint == 0) {p.drawCircle(fo->from);}
if (selPoint == 1) {p.drawCircle(fo->to);}
}
// line
p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus()), Qt::NoBrush);
p.drawLine(fo->from, fo->to);
// available endpoints
if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawCircle(fo->from);
p.drawCircle(fo->to);
}
}
virtual void onFocus() override {
;
}
virtual void onUnfocus() override {
selPoint = -1; // clear selection
}
/** 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 (selPoint == -1) {return;}
const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
if (selPoint == 0) {fo->from.x = p.x; fo->from.y = p.y;}
if (selPoint == 1) {fo->to.x = p.x; fo->to.y = p.y;}
}
/** mouse released */
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
// (void) v;
// if (selPoint == -1) {return;}
// const Point3 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
// if (selPoint == 0) {fo.from.x = p.x; fo.from.y = p.y;}
// if (selPoint == 1) {fo.to.x = p.x; fo.to.y = p.y;}
// select a new point on mouse-release (more robust than on mouse-press)
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
const float l1 = _p.getDistance(fo->from);
const float l2 = _p.getDistance(fo->to);
if (l1 < l2 && l1 <= t) {selPoint = 0;}
else if (l2 < l1 && l2 <= t) {selPoint = 1;}
else {selPoint = -1;}
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
(void) e;
return false;
}
};
#endif // MV2DELEMENTFLOOROBSTACLELINE_H

View File

@@ -0,0 +1,152 @@
#ifndef MV2DELEMENTFLOOROUTLINEPOLYGON_H
#define MV2DELEMENTFLOOROUTLINEPOLYGON_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MV2DElementFloorOutlinePolygon : public MV2DElement {
private:
int selPoint = -1;
Floorplan::FloorOutlinePolygon& fo;
public:
/** ctor */
MV2DElementFloorOutlinePolygon(Floorplan::FloorOutlinePolygon& fo) : fo(fo) {;}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
BBox2 bbox;
for (const Point2 p : fo.poly.points) { bbox.add(p); }
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
float getMinDistanceXY(const Point2 p) const override {
float min = 999999;
for (int i = 0; i < (int)fo.poly.points.size()-1; ++i) {
const Point2 p1 = fo.poly.points[i];
const Point2 p2 = fo.poly.points[i+1];
const float dst = MapElementHelper::getLineDistanceXY(p1, p2, p);
if (dst < min) {min = dst;}
}
return min;
}
virtual void onFocus() override {
}
virtual void onUnfocus() override {
selPoint = -1; // clear selection
}
void paint(Painter& p) override {
QBrush brush;
// fill-style (depends on the mode)
switch (fo.method) {
case Floorplan::OutlineMethod::ADD:
brush.setStyle(Qt::BrushStyle::SolidPattern);
brush.setColor(QColor(0,0,0,24));
break;
case Floorplan::OutlineMethod::REMOVE:
brush.setStyle(Qt::BrushStyle::DiagCrossPattern);
brush.setColor(QColor(0,0,0));
break;
default:
brush.setStyle(Qt::BrushStyle::SolidPattern);
brush.setColor(QColor(255,0,0));
}
// outline + filled area
p.setPenBrush(Qt::black, brush);
p.drawPolygon(fo.poly.points);
// selected endpoints?
if (hasFocus() && selPoint != -1) {
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
p.drawCircle(fo.poly.points[selPoint]);
}
// available endpoints
if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
for (const Point2 pt : fo.poly.points) {
p.drawCircle(pt);
}
}
}
virtual void mousePressed(MapView2D* v, const Point2 p) override {
(void) v;
(void) p;
}
virtual void mouseMove(MapView2D* v, const Point2 _p) override {
(void) v;
if (selPoint == -1) {return;}
const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
fo.poly.points[selPoint].x = p.x;
fo.poly.points[selPoint].y = p.y;
}
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
(void) v;
// if (selPoint != -1) {
// const Point3 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
// fo.poly.points[selPoint].x = p.x;
// fo.poly.points[selPoint].y = p.y;
// }
// select a new point on mouse-release (more robust than on mouse-press)
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
auto comp = [&] (const Point2 a, const Point2 b) {return a.getDistance(_p) < b.getDistance(_p);};
auto it = std::min_element(fo.poly.points.begin(), fo.poly.points.end(), comp);
if (it == fo.poly.points.end()) {selPoint = -1;} // none found -> skip
else if ((*it).getDistance(_p) > t) {selPoint = -1;} // nearest distance is above threshold -> skip
else {selPoint = it - fo.poly.points.begin();}
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
if (e->key() == Qt::Key_Delete) {
// delete the currently selected vertex?
if (selPoint != -1) {
fo.poly.points.erase(fo.poly.points.begin() + selPoint);
selPoint = -1;
return true;
}
} else if (e->key() == Qt::Key_Plus && selPoint != -1) {
int idx1 = selPoint;
int idx2 = (selPoint + 1) % fo.poly.points.size();
int idxNew = idx2;
Point2 pNew = (fo.poly.points[idx1] + fo.poly.points[idx2]) / 2.0f;
fo.poly.points.insert(fo.poly.points.begin() + idxNew, pNew);
selPoint = idxNew;
return true;
}
// not consumed
return false;
}
};
#endif // MV2DELEMENTFLOOROUTLINEPOLYGON_H

View File

@@ -0,0 +1,136 @@
#ifndef MV2DELEMENTFLOORUNDERLAY_H
#define MV2DELEMENTFLOORUNDERLAY_H
#include "MV2DElement.h"
#include "MapViewElementHelper.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* display e.g. a PNG-file below the map [as reference]
*/
class MV2DElementFloorUnderlay : public MV2DElement {
private:
QImage img;
std::string tmpFile;
Floorplan::UnderlayImage* underlay;
BBox2 bbox;
int selPoint = -1;
public:
/** ctor */
MV2DElementFloorUnderlay(Floorplan::UnderlayImage* underlay) : underlay(underlay) {
missing();
}
void missing() {
//img = QImage(QSize(64, 64), QImage::Format_ARGB32);
//img.fill(0xFF000000);
img = QImage("://res/icons/cross.png");
}
/** get the element's 3D bounding box */
BBox2 getBoundingBox() const override {
return bbox;
}
/** get the element's minimal distance (nearest whatsoever) to the given point */
float getMinDistanceXY(const Point2 p) const override {
(void) p;
return CFG::SEL_THRESHOLD_SIZE_PX; // we do not know the distance from the image
}
virtual void onFocus() override {
}
virtual void onUnfocus() override {
selPoint = -1; // clear selection
}
void paint(Painter& p) override {
(void) p;
if (tmpFile != underlay->filename) {
img = QImage(underlay->filename.c_str());
if (img.size().width() == 0) {
missing();
}
tmpFile = underlay->filename;
}
// map coordinates
float mx1 = underlay->anchor.x;
float my1 = underlay->anchor.y;
float mw = img.width() * underlay->scaleX;
float mh = img.height() * underlay->scaleY;
float mx2 = mx1+mw;
float my2 = my1+mh;
// screen coordinates
float sx1 = p.s.xms(mx1);
float sy1 = p.s.yms(my1);
float sx2 = p.s.xms(mx2);
float sy2 = p.s.yms(my2);
float sw = abs(sx1-sx2);
float sh = abs(sy1-sy2);
bbox = BBox2();
bbox.add(Point2(mx1, my1));
bbox.add(Point2(mx2, my2));
p.p->drawImage(QRectF(sx1, sy1-sh, sw, sh), img, QRectF(0,0,img.width(),img.height()));
// selected endpoint(s)?
if (hasFocus()) {
p.setPenBrush(Qt::NoPen, CFG::SEL_COLOR);
if (selPoint == 0) {p.drawCircle(bbox.getMin());}
}
// just focused?
if (hasFocus()) {
p.setPenBrush(Qt::black, Qt::NoBrush);
p.drawRect(mx1,my1,mx2,my2);
p.drawCircle(bbox.getMin());
}
}
virtual void mousePressed(MapView2D* v, const Point2 p) override {
(void) v;
(void) p;
}
virtual void mouseMove(MapView2D* v, const Point2 _p) override {
(void) v;
if (selPoint == -1) {return;}
const Point2 p = Scaler::snap(_p, CFG::MOVE_SNAP_SIZE_M);
if (selPoint == 0) {underlay->anchor = p;}
}
virtual void mouseReleased(MapView2D* v, const Point2 _p) override {
// select a new point on mouse-release (more robust than on mouse-press)
const float t = v->getScaler().sm(CFG::SEL_THRESHOLD_SIZE_PX);
const float l1 = _p.getDistance(bbox.getMin());
if (l1 <= t) {selPoint = 0;}
else {selPoint = -1;}
}
virtual bool keyPressEvent(MapView2D* v, QKeyEvent *e) override {
(void) v;
(void) e;
return false;
}
};
#endif // MV2DELEMENTFLOORUNDERLAY_H

View File

@@ -0,0 +1,74 @@
#ifndef MAPELEMENTHELPER_H
#define MAPELEMENTHELPER_H
#include <Indoor/geo/Point2.h>
#include <Indoor/geo/Point3.h>
#include <Indoor/geo/Line2.h>
#include <QColor>
#include <QPen>
#include <QBrush>
#include <Indoor/floorplan/v2/Floorplan.h>
/** configuration */
namespace CFG {
const float MOVE_SNAP_SIZE_M = 0.1f; // in meter (= map-space)
const int SEL_THRESHOLD_SIZE_PX = 15; // in screen-pixels (-> should depend on the current zoom)
const QColor SEL_COLOR = Qt::blue;
}
/**
* contains some common helper-methods
*/
class MapElementHelper {
public:
/**
* get the minimal distance of dst to the line denoted by (p1, p2).
* this will generate line l perpendicular to (p1, p2)
* move l into dst
* and calculate the cut-point between l and (p1, p2)
*/
static float getLineDistanceXY(Point2 p1, Point2 p2, Point2 dst) {
// the line (p1, p2)
const Line2 line(p1, p2);
// 90 degree rotation L of the line (p1, p2)
const Point2 vec = (p1 - p2).perpendicular();
// the line L
const Line2 perb(dst-vec*100, dst+vec*100);
// calculate the cut betwen L and (p1,p2) (if any)
Point2 cut(0,0);
if (line.getSegmentIntersection(perb, cut)) {
// distance between cut-point and mouse
return cut.getDistance(dst);
} else {
// no cut detected
return 9999999;
}
}
static QPen getPen(Floorplan::Material mat, Floorplan::ObstacleType type, bool focus) {
using namespace Floorplan;
QPen pen; pen.setColor(Qt::darkGray);
if (focus) {pen.setColor(Qt::black);}
if (mat == Material::CONCRETE) {pen.setWidth(3);}
if (mat == Material::GLASS) {pen.setStyle(Qt::PenStyle::DotLine);}
if (type == ObstacleType::HANDRAIL) {pen.setStyle(Qt::PenStyle::DashLine);}
return pen;
}
};
#endif // MAPELEMENTHELPER_H

View File

@@ -0,0 +1,21 @@
#ifndef IHASATTRIBUTES_H
#define IHASATTRIBUTES_H
#include <string>
class IHasAttributes {
public:
/** 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 all attributes as map */
virtual const std::unordered_map<std::string, std::string> getAttributes() const = 0;
};
#endif // IHASATTRIBUTES_H

17
mapview/model/IHasFile.h Normal file
View File

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

15
mapview/model/IHasMAC.h Normal file
View File

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

View File

@@ -0,0 +1,15 @@
#ifndef IHASMATERIAL_H
#define IHASMATERIAL_H
#include <Indoor/floorplan/v2/Floorplan.h>
class IHasMaterial {
public:
virtual void setMaterial(const Floorplan::Material m) = 0;
virtual Floorplan::Material getMaterial() const = 0;
};
#endif // IHASMATERIAL_H

15
mapview/model/IHasName.h Normal file
View File

@@ -0,0 +1,15 @@
#ifndef IHASNAME_H
#define IHASNAME_H
#include <string>
class IHasName {
public:
virtual void setName(const std::string& name) = 0;
virtual const std::string& getName() const = 0;
};
#endif // IHASNAME_H

View File

@@ -0,0 +1,16 @@
#ifndef IHASOBSTACLETYPE_H
#define IHASOBSTACLETYPE_H
#include <Indoor/floorplan/v2/Floorplan.h>
class IHasObstacleType {
public:
virtual void setObstacleType(const Floorplan::ObstacleType t) = 0;
virtual Floorplan::ObstacleType getObatcleType() const = 0;
};
#endif // IHASOBSTACLETYPE_H

View File

@@ -0,0 +1,84 @@
#ifndef IHASPARAMS_H
#define IHASPARAMS_H
#include <Indoor/floorplan/v2/Floorplan.h>
#include <QVariant>
enum class ParamType {
INT,
FLOAT,
STRING,
FILE,
};
class ParamValue {
private:
union {
int _int;
float _float;
};
std::string _str;
public:
template <typename T> ParamValue(const T val) {
setValue(val);
}
void setValue(const std::string& val) {_str = val;}
void setValue(float val) {_float = val;}
void setValue(int val) {_int = val;}
std::string toString() const {return _str;}
float toFloat() const {return _float;}
int toInt() const {return _int;}
};
//union ParamValue {
// int _int;
// float _float;
// std::string _string;
// template <typename T> ParamValue(const T val) {
// setValue(val);
// }
// int toInt() const {return _int;}
// float toFloat() const {return _float;}
// const std::string& toString() const {return _string;}
// void setValue(const float val) {_float = val;}
// void setValue(const int val) {_int = val;}
// void setValue(const std::string& val) {_string = val;}
//};
struct Param {
std::string name;
ParamType type;
Param(const std::string& name, const ParamType type) : name(name), type(type) {;}
};
/** free parameters */
class IHasParams {
public:
/** get the number of parameters */
virtual int getNumParams() const = 0;
/** get the description of the idx-th parameter */
virtual Param getParamDesc(const int idx) const = 0;
/** get the idx-th param's value */
virtual ParamValue getParamValue(const int idx) const = 0;
/** set the idx-th param's value */
virtual void setParamValue(const int idx, const ParamValue& val) const = 0;
};
#endif // IHASPARAMS_H

View File

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

56
mapview/model/MMFloor.h Normal file
View File

@@ -0,0 +1,56 @@
#ifndef MMFLOOR_H
#define MMFLOOR_H
#include "MapLayer.h"
#include "MMFloorOutline.h"
#include "MMFloorObstacles.h"
#include "MMFloorAccessPoints.h"
#include "MMFloorBeacons.h"
#include "MMFloorUnderlay.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* floor-layer containing one floor
* and its outline, obstacles, access-points, ...
*/
class MMFloor : public MapLayer, public IHasName {
private:
/** the underlying data-structure */
Floorplan::Floor* floor;
public:
/** ctor. existing floor */
MMFloor(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR), floor(floor) {
new MMFloorOutline(this, floor);
new MMFloorObstacles(this, floor);
new MMFloorAccessPoints(this, floor);
new MMFloorBeacons(this, floor);
new MMFloorUnderlay(this, floor);
}
/** ctor. new floor. */
MMFloor(MapLayer* parent) : MapLayer(parent), floor(nullptr) {
throw "not yet implemented";
}
/** get the underlying model */
Floorplan::Floor& getFloor() {return *floor;}
std::string getLayerName() const override {return floor->name;}
virtual void setName(const std::string& name) {this->floor->name = name;}
virtual const std::string& getName() const {return this->floor->name;}
};
#endif // MMFLOOR_H

View File

@@ -0,0 +1,42 @@
#ifndef MAPVIEWELEMENTACCESSPOINT_H
#define MAPVIEWELEMENTACCESSPOINT_H
#include "MapModelElement.h"
#include "IHasMAC.h"
#include "IHasName.h"
#include "../elements/MV2DElementAccessPoint.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorAccessPoint : public MapModelElement, public IHasMAC, public IHasName {
private:
Floorplan::Floor* floor;
Floorplan::AccessPoint* ap;
MV2DElementAccessPoint mv2d;
public:
MMFloorAccessPoint(MapLayer* parent, Floorplan::Floor* floor, Floorplan::AccessPoint* ap) :
MapModelElement(parent), floor(floor), ap(ap), mv2d(ap) {
}
virtual void setMAC(const std::string& mac) override {ap->mac = mac;}
virtual const std::string& getMAC() const override {return ap->mac;}
virtual void setName(const std::string& name) override {ap->name = name;}
virtual const std::string& getName() const override {return ap->name;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
void deleteMe() const override {
parent->removeElement(this);
floor->accesspoints.erase(std::remove(floor->accesspoints.begin(), floor->accesspoints.end(), ap), floor->accesspoints.end());
}
};
#endif // MAPVIEWELEMENTACCESSPOINT_H

View File

@@ -0,0 +1,45 @@
#ifndef MMFLOORACCESSPOINTS_H
#define MMFLOORACCESSPOINTS_H
#include "MapLayer.h"
#include "MMFloorAccessPoint.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer containing all of the map's floors
*/
class MMFloorAccessPoints : public MapLayer {
private:
Floorplan::Floor* floor;
public:
/** ctor with the underlying model */
MMFloorAccessPoints(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_ACCESS_POINTS), floor(floor) {
// add all APs
for (Floorplan::AccessPoint* ap : floor->accesspoints) {
new MMFloorAccessPoint(this, floor, ap);
}
}
std::string getLayerName() const override {return "APs";}
//TODO: check
void createAP(Floorplan::AccessPoint* ap) {
// add to underlying model
floor->accesspoints.push_back(ap);
// add to myself as element
elements.push_back(new MMFloorAccessPoint(this, floor, ap));
}
};
#endif // MMFLOORACCESSPOINTS_H

View File

@@ -0,0 +1,41 @@
#ifndef MAPVIEWELEMENTIBEACON_H
#define MAPVIEWELEMENTIBEACON_H
#include "MapModelElement.h"
#include "IHasMAC.h"
#include "IHasName.h"
#include "../elements/MV2DElementBeacon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorBeacon : public MapModelElement, public IHasMAC, public IHasName {
private:
Floorplan::Floor* floor;
Floorplan::Beacon* b;
MV2DElementBeacon mv2d;
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 void setName(const std::string& name) override {b->name = name;}
virtual const std::string& getName() const override {return b->name;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
void deleteMe() const override {
parent->removeElement(this);
floor->beacons.erase(std::remove(floor->beacons.begin(), floor->beacons.end(), b), floor->beacons.end());
}
};
#endif // MAPVIEWELEMENTIBEACON_H

View File

@@ -0,0 +1,44 @@
#ifndef MMFLOORBEACONS_H
#define MMFLOORBEACONS_H
#include "MapLayer.h"
#include "MMFloorBeacon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer containing all of the floor's beaconss
*/
class MMFloorBeacons : public MapLayer {
private:
Floorplan::Floor* floor;
public:
/** ctor with the underlying model */
MMFloorBeacons(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_BEACONS), floor(floor) {
// add all Beacons
for (Floorplan::Beacon* b : floor->beacons) {
new MMFloorBeacon(this, floor, b);
}
}
std::string getLayerName() const override {return "Beacons";}
//TODO: check
void createBeacon(Floorplan::Beacon* b) {
// add to underlying model
floor->beacons.push_back(b);
// add to myself as element
elements.push_back(new MMFloorBeacon(this, floor, b));
}
};
#endif // MMFLOORBEACONS_H

View File

@@ -0,0 +1,46 @@
#ifndef MAPMODELELEMENTFLOOROBSTACLECIRCLE_H
#define MAPMODELELEMENTFLOOROBSTACLECIRCLE_H
#include "MapModelElement.h"
#include "../elements/MapViewElementHelper.h"
#include "IHasMaterial.h"
#include "IHasObstacleType.h"
#include "../elements/MV2DElementFloorObstacleCircle.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorObstacleCircle : public MapModelElement, public IHasMaterial, public IHasObstacleType {
private:
Floorplan::Floor* mf;
Floorplan::FloorObstacleCircle* c;
MV2DElementFloorObstacleCircle mv2d;
public:
MMFloorObstacleCircle(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleCircle* c) :
MapModelElement(parent), mf(mf), c(c), mv2d(c) {
}
void setMaterial(const Floorplan::Material m) override {c->material = m;}
Floorplan::Material getMaterial() const override {return c->material;}
void setObstacleType(const Floorplan::ObstacleType t) override {c->type = t;}
Floorplan::ObstacleType getObatcleType() const override {return c->type;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
void deleteMe() const override {
parent->removeElement(this);
mf->obstacles.erase(std::remove(mf->obstacles.begin(), mf->obstacles.end(), c), mf->obstacles.end());
}
};
#endif // MAPMODELELEMENTFLOOROBSTACLECIRCLE_H

View File

@@ -0,0 +1,45 @@
#ifndef MAPELEMENTOBSTACLE_H
#define MAPELEMENTOBSTACLE_H
#include "MapModelElement.h"
#include "../elements/MapViewElementHelper.h"
#include "IHasMaterial.h"
#include "IHasObstacleType.h"
#include "../elements/MV2DElementFloorObstacleLine.h"
#include <Indoor/floorplan/v2/Floorplan.h>
class MMFloorObstacleLine : public MapModelElement, public IHasMaterial, public IHasObstacleType {
public:
Floorplan::Floor* mf;
Floorplan::FloorObstacleLine* fo;
MV2DElementFloorObstacleLine mv2d;
public:
MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) :
MapModelElement(parent), mf(mf), fo(fo), mv2d(fo) {
}
void setMaterial(const Floorplan::Material m) override {fo->material = m;}
Floorplan::Material getMaterial() const override {return fo->material;}
void setObstacleType(const Floorplan::ObstacleType t) override {fo->type = t;}
Floorplan::ObstacleType getObatcleType() const override {return fo->type;}
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
void deleteMe() const override {
parent->removeElement(this);
mf->obstacles.erase(std::remove(mf->obstacles.begin(), mf->obstacles.end(), fo), mf->obstacles.end());
}
};
#endif // MAPELEMENTOBSTACLE_H

View File

@@ -0,0 +1,63 @@
#ifndef MMFLOOROBSTACLES_H
#define MMFLOOROBSTACLES_H
#include "MapLayer.h"
#include "MMFloorObstacleCircle.h"
#include "MMFloorObstacleLine.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer that contains all of one floor's obstacles
*/
class MMFloorObstacles : public MapLayer {
Floorplan::Floor* floor;
public:
/** ctor with the floor */
MMFloorObstacles(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_OBSTACLES), floor(floor) {
// the obstacles
for (Floorplan::FloorObstacle* o : floor->obstacles) {
if (dynamic_cast<Floorplan::FloorObstacleLine*>(o)) {
elements.push_back(new MMFloorObstacleLine(this, floor, (Floorplan::FloorObstacleLine*)o));
} else if (dynamic_cast<Floorplan::FloorObstacleCircle*>(o)) {
elements.push_back(new MMFloorObstacleCircle(this, floor, (Floorplan::FloorObstacleCircle*)o));
}
}
}
/** get the corresponding floor from the underlying model */
Floorplan::Floor* getFloor() {return floor;}
//TODO: check
void createLine(Floorplan::FloorObstacleLine* obs) {
// add to underlying model
floor->obstacles.push_back(obs);
// add to myself as element
elements.push_back(new MMFloorObstacleLine(this, floor, obs));
}
//TODO: check
void createCircle(Floorplan::FloorObstacleCircle* obs) {
// add to underlying model
floor->obstacles.push_back(obs);
// add to myself as element
elements.push_back(new MMFloorObstacleCircle(this, floor, obs));
}
std::string getLayerName() const override {return "obstacles";}
};
#endif // MMFLOOROBSTACLES_H

View File

@@ -0,0 +1,52 @@
#ifndef MMFLOOROUTLINE_H
#define MMFLOOROUTLINE_H
#include "MapLayer.h"
#include "MMFloorOutlinePolygon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer containing all elements describing a floor's outline
*/
class MMFloorOutline : public MapLayer {
private:
/** the underlying model */
Floorplan::Floor* floor;
public:
/** ctor with the underlying model */
MMFloorOutline(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_GROUND), floor(floor) {
// the outline
for (Floorplan::FloorOutlinePolygon* poly : floor->outline) {
elements.push_back(new MMFloorOutlinePolygon(this, floor, poly));
}
}
/** get the corresponding floor from the underlying model */
Floorplan::Floor* getFloor() {return floor;}
//TODO: check
void create(Floorplan::FloorOutlinePolygon* poly) {
// add to underlying model
floor->outline.push_back(poly);
// add to myself as element
elements.push_back(new MMFloorOutlinePolygon(this, floor, poly));
}
std::string getLayerName() const override {return "outline";}
};
#endif // MMFLOOROUTLINE_H

View File

@@ -0,0 +1,53 @@
#ifndef MAPELEMENTFLOORGROUND_H
#define MAPELEMENTFLOORGROUND_H
#include "IHasName.h"
#include "MapModelElement.h"
#include "../elements/MV2DElementFloorOutlinePolygon.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* describes one polygon within a floor's outline
*/
class MMFloorOutlinePolygon : public MapModelElement, public IHasName {
private:
Floorplan::Floor* mf;
Floorplan::FloorOutlinePolygon* fo;
MV2DElementFloorOutlinePolygon mv2d;
public:
/** ctor */
MMFloorOutlinePolygon(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorOutlinePolygon* fo) : MapModelElement(parent), mf(mf), fo(fo), mv2d(*fo) {
;
}
Floorplan::FloorOutlinePolygon* getPolygon() {return fo;}
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;}
void deleteMe() const override {
// delete from the parent
parent->removeElement(this);
// delete from the underlying model
mf->outline.erase(std::remove(mf->outline.begin(), mf->outline.end(), fo), mf->outline.end());
}
};
#endif // MAPELEMENTFLOORGROUND_H

View File

@@ -0,0 +1,52 @@
#ifndef MMFLOORUNDERLAY_H
#define MMFLOORUNDERLAY_H
#include "MMFloorUnderlayImage.h"
#include "../elements/MV2DElementFloorUnderlay.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* add an external file as underlay (to copy it onto the map)
*/
class MMFloorUnderlay : public MapLayer {
private:
Floorplan::Floor* floor;
public:
/** ctor */
MMFloorUnderlay(MapLayer* parent, Floorplan::Floor* floor) : MapLayer(parent, MapLayerType::FLOOR_UNDERLAY), floor(floor) {
// the underlays
for (Floorplan::UnderlayImage* img : floor->underlays) {
elements.push_back(new MMFloorUnderlayImage(this, floor, img));
}
}
//TODO: check
void createImage(const Point2 center) {
Floorplan::UnderlayImage* elem = new Floorplan::UnderlayImage();
// add to underlying model
floor->underlays.push_back(elem);
// add to myself as element
MMFloorUnderlayImage* img = new MMFloorUnderlayImage(this, floor, elem);
elements.push_back(img);
img->setAnchor(center);
img->setScale(0.1, 0.1);
}
virtual std::string getLayerName() const override {return "underlay";}
};
#endif // MMFLOORUNDERLAY_H

View File

@@ -0,0 +1,78 @@
#ifndef MMFLOORUNDERLAYIMAGE_H
#define MMFLOORUNDERLAYIMAGE_H
#include "IHasFile.h"
#include "IHasParams.h"
#include "MapModelElement.h"
#include "../elements/MV2DElementFloorUnderlay.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* add an external image file as underlay (to copy it onto the map)
*/
class MMFloorUnderlayImage : public MapModelElement, public MapLayer, public IHasFile, public IHasParams {
private:
Floorplan::Floor* floor;
Floorplan::UnderlayImage* img;
MV2DElementFloorUnderlay mv2d;
std::string fileName;
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);
}
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;}
void deleteMe() const override {
;
}
int getNumParams() const override {return 3;}
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);
default: throw 1;
}
}
virtual ParamValue getParamValue(const int idx) const override {
switch(idx) {
case 0: return ParamValue(img->filename);
case 1: return ParamValue(img->scaleX);
case 2: return ParamValue(img->scaleY);
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();
default: throw 1;
}
}
};
#endif // MMFLOORUNDERLAYIMAGE_H

37
mapview/model/MMFloors.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef MMFLOORS_H
#define MMFLOORS_H
#include "MapLayer.h"
#include "MMFloor.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* layer containing all of the map's floors
*/
class MMFloors : public MapLayer {
private:
Floorplan::IndoorMap* map;
public:
/** ctor with the underlying model */
MMFloors(MapLayer* parent, Floorplan::IndoorMap* map) : MapLayer(parent, MapLayerType::FLOORS), map(map) {
// add all floors
for (Floorplan::Floor* floor : map->floors) {
new MMFloor(this, floor);
}
}
std::string getLayerName() const override {return "floors";}
/** get the underlying model */
Floorplan::IndoorMap* getMap() {return map;}
};
#endif // MMFLOORS_H

38
mapview/model/MMRoot.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef MMROOT_H
#define MMROOT_H
#include "MapLayer.h"
#include "MMFloors.h"
#include <Indoor/floorplan/v2/Floorplan.h>
/**
* floor-layer containing one floor
* and its outline, obstacles, access-points, ...
*/
class MMRoot : public MapLayer {
private:
/** the underlying data-structure */
Floorplan::IndoorMap* map;
public:
/** ctor. existing floor */
MMRoot(MapLayer* parent, Floorplan::IndoorMap* map) : MapLayer(parent), map(map) {
// all floors
new MMFloors(this, map);
}
/** get the underlying model */
Floorplan::IndoorMap* getMap() {return map;}
std::string getLayerName() const override {return "root";}
};
#endif // MMROOT_H

127
mapview/model/MapLayer.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef MAPLAYER_H
#define MAPLAYER_H
#include <string>
#include <vector>
#include <algorithm>
class MapModelElement;
enum class MapLayerType {
UNKNOWN,
ROOT,
FLOORS,
FLOOR,
FLOOR_GROUND,
FLOOR_OBSTACLES,
FLOOR_BEACONS,
FLOOR_ACCESS_POINTS,
FLOOR_UNDERLAY,
};
class MapLayer {
protected:
/** this layer's parent */
MapLayer* parent;
/** this layer's elements */
std::vector<MapModelElement*> elements;
/** this layer's sublayers */
std::vector<MapLayer*> sublayers;
/** this layer's type */
MapLayerType type;
/** whether this layer is visible */
bool visible;
public:
/** ctor */
MapLayer(MapLayer* parent) : parent(parent), type(MapLayerType::UNKNOWN), visible(true) {
if (parent) {parent->addSublayer(this);} // attach myself as child of my parent
}
/** ctor */
MapLayer(MapLayer* parent, MapLayerType type) : parent(parent), type(type), visible(true) {
if (parent) {parent->addSublayer(this);} // attach myself as child of my parent
}
/** dtor */
virtual ~MapLayer() {;}
/** get the layer's parent */
MapLayer* getParent() const {return parent;}
/** get the layer's name */
virtual std::string getLayerName() const = 0;
/** get the layer's type */
MapLayerType getLayerType() const {return type;}
/** get all elements within this layer */
const std::vector<MapModelElement*>& getElements() const {return elements;}
/** get all elements within this layer */
size_t getNumElements() const {return elements.size();}
/** remove the given element from the elements list */
void removeElement(const MapModelElement* elem) { elements.erase(std::remove(elements.begin(), elements.end(), elem), elements.end()); }
/** is this layer currently visible? */
bool isVisible() const {return visible;}
/** make this layer visible */
void setVisible(const bool visible) {this->visible = visible;}
/** get all sub-layers within this layer */
const std::vector<MapLayer*>& getSubLayers() const {return sublayers;}
/** helper method to get all elements and those of all sub-layers */
void getVisibleElementsRecursive(std::vector<MapModelElement*>& el) {
if (isVisible()) {
std::vector<MapModelElement*> local = getElements();
el.insert(el.end(), local.begin(), local.end());
for (MapLayer* sub : getSubLayers()) {
sub->getVisibleElementsRecursive(el);
}
}
}
protected:
/** add a new sublayer to this layer */
void addSublayer(MapLayer* ml) {
// sanity check before adding
if (std::find(sublayers.begin(), sublayers.end(), ml) != sublayers.end()) {throw "layer already present!";}
sublayers.push_back(ml);
}
};
class MapLayerRoot : public MapLayer {
public:
MapLayerRoot(MapLayer* parent) : MapLayer(parent, MapLayerType::ROOT) {;}
std::string getLayerName() const override {return "root";}
};
#endif // MAPLAYER_H

72
mapview/model/MapLayers.h Normal file
View File

@@ -0,0 +1,72 @@
#ifndef MAPLAYERFLOOR_H
#define MAPLAYERFLOOR_H
#include "MapLayer.h"
#include <Indoor/floorplan/v2/Floorplan.h>
#include "../model/MMFloorObstacleLine.h"
#include "../model/MMFloorObstacleCircle.h"
#include "../model/MMFloorOutlinePolygon.h"
#include "../model/MMFloorBeacon.h"
/*
class MapLayerFloorOutlineAdd : public TypedMapLayer {
private:
Floorplan::Floor& floor;
public:
MapLayerFloorOutlineAdd(MapLayer* parent, Floorplan::Floor& floor) : TypedMapLayer(parent, MapLayerType::FLOOR_GROUND_ADD), floor(floor) {;}
std::string getLayerName() const override {return "add";}
Floorplan::Floor& getFloor() {return floor;}
std::vector<MapModelElement*> getElements() const override {
std::vector<MapModelElement*> vec;
for (Floorplan::FloorOutlinePolygon& p : floor.outline.add) {vec.push_back(new MapViewElementFloorOutlinePolygon(floor, p, MapViewElementFloorOutlinePolygon::Type::ADD));}
return vec;
}
void create(const Floorplan::FloorOutlinePolygon& poly) {
floor.outline.add.push_back(poly);
}
virtual size_t getNumElements() const override {return floor.outline.add.size();}
};
class MapLayerFloorOutlineRemove : public TypedMapLayer {
private:
Floorplan::Floor& floor;
public:
MapLayerFloorOutlineRemove(MapLayer* parent, Floorplan::Floor& floor) : TypedMapLayer(parent, MapLayerType::FLOOR_GROUND_REMOVE), floor(floor) {;}
std::string getLayerName() const override {return "remove";}
Floorplan::Floor& getFloor() {return floor;}
std::vector<MapModelElement*> getElements() const override {
std::vector<MapModelElement*> vec;
for (Floorplan::FloorOutlinePolygon& p : floor.outline.remove) {vec.push_back(new MapViewElementFloorOutlinePolygon(floor, p, MapViewElementFloorOutlinePolygon::Type::REMOVE));}
return vec;
}
void create(const Floorplan::FloorOutlinePolygon& poly) {
floor.outline.remove.push_back(poly);
}
virtual size_t getNumElements() const override {return floor.outline.remove.size();}
};
class MapLayerFloorOutlinePolygon : public TypedMapLayer {
private:
Floorplan::Floor& floor;
public:
MapLayerFloorOutlinePolygon(MapLayer* parent, Floorplan::Floor& floor) : TypedMapLayer(parent, MapLayerType::FLOOR_GROUND), floor(floor) {
new MapLayerFloorOutlineAdd(this, floor);
new MapLayerFloorOutlineRemove(this, floor);
}
std::string getLayerName() const override {return "ground";}
Floorplan::Floor& getFloor() {return floor;}
};
*/
#endif // MAPLAYERFLOOR_H

View File

112
mapview/model/MapModel.h Normal file
View File

@@ -0,0 +1,112 @@
#ifndef MAPMODEL_H
#define MAPMODEL_H
#include <QObject>
#include "MapLayer.h"
#include "MapModelElement.h"
#include "MMRoot.h"
#include <Indoor/floorplan/v2/Floorplan.h>
#include <Indoor/floorplan/v2/FloorplanReader.h>
#include <Indoor/floorplan/v2/FloorplanWriter.h>
class MapModel : public QObject {
Q_OBJECT
private:
///** wrapper-classes for all elements */
//std::vector<MapModelElement*> selElements;
/** the map's root-layer containing all other layers */
MapLayer* root = nullptr;
/** the currently selected layer (if any) */
MapLayer* selLayer = nullptr;
/** the loaded floorplan */
Floorplan::IndoorMap* im;
public:
/** ctor */
MapModel() {
root = new MapLayerRoot(nullptr);
}
virtual ~MapModel() {
cleanup();
}
void cleanup() {
selLayer = nullptr;
//selElements.clear();
if (root) {delete root; root = nullptr;}
}
void load(const std::string& file) {
emit aboutToReset();
cleanup();
// load the indoor-map using the given XML-file
im = Floorplan::Reader::readFromFile(file);
root = new MMRoot(nullptr, im);
emit reset();
}
void save(const std::string& file) {
Floorplan::Writer::writeToFile(im, file);
}
/** get the map's root-layer containing all other layers */
MapLayer* getRootLayer() { return root; }
/** get all elements within the currently selected layer */
std::vector<MapModelElement*> getSelectedLayerElements() {
//return selElements;
//return (selLayer) ? (selLayer->getElementsRecursive()) : (std::vector<MapModelElement*>());
std::vector<MapModelElement*> elements;
root->getVisibleElementsRecursive(elements);
return elements;
}
/** get all currently visible elements */
std::vector<MapModelElement*> getVisibleElements() {
return getSelectedLayerElements();
}
/** set the currently selected layer */
void setSelectedLayer(MapLayer* ml) {
//selElements.clear();
//for (MapModelElement* el : ml->getElementsRecursive()) {selElements.push_back(el);}
selLayer = ml;
}
/** get the currently selected layer */
MapLayer* getSelectedLayer() const {
return selLayer;
}
void reselect() {
setSelectedLayer(selLayer);
emit reset();
}
signals:
void aboutToReset();
void reset();
};
#endif // MAPMODEL_H

View File

@@ -0,0 +1,34 @@
#ifndef MAPMODELELEMENT_H
#define MAPMODELELEMENT_H
#include "MapLayer.h"
class MV2DElement;
class MapModelElement {
protected:
MapLayer* parent;
public:
/** ctor */
MapModelElement(MapLayer* parent) : parent(parent) {;}
/** dtor */
virtual ~MapModelElement() {;}
/** get the 2D interaction class for this element */
virtual MV2DElement* getMV2D() const = 0;
/** delete this element from the model */
virtual void deleteMe() const = 0;
/** get the parent element */
MapLayer* getParent() const {return parent;}
};
#endif // MAPMODELELEMENT_H

0
mapview/tools/Tool.cpp Normal file
View File

35
mapview/tools/Tool.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef TOOL_H
#define TOOL_H
#include <QKeyEvent>
#include <QMouseEvent>
#include <QObject>
#include "../Painter.h"
class MapView2D;
class Tool : public QObject {
Q_OBJECT
public:
virtual ~Tool() {;}
virtual void mousePressEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; }
virtual void mouseMoveEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; }
virtual void mouseReleaseEvent(MapView2D* m, QMouseEvent* e) { (void) m; (void) e; }
virtual void wheelEvent(MapView2D* m, QWheelEvent* e) { (void) m; (void) e; }
virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) { (void) m; (void) e; }
virtual void paintBefore(MapView2D* m, Painter& p) { (void) m; (void) p; }
virtual void paintAfter(MapView2D* m, Painter& p) { (void) m; (void) p; }
virtual void layerChange(MapView2D* m) { (void) m; }
};
#endif // TOOL_H

View File

@@ -0,0 +1,71 @@
#ifndef TOOLMAPGRID_H
#define TOOLMAPGRID_H
#include "Tool.h"
class ToolMapGrid : public Tool {
public:
void paintBefore(MapView2D* m, Painter& p) override {
(void) m;
static const QColor cB(250,250,250);
static const QColor cN(235,235,235);
static const QColor c0(128,128,128);
int w = p.width();
int h = p.height();
// grid-size
const float step = p.getScaler().getLODstep();
const float sStep = step/5;
// map-region visible on the screen
const Rect r = p.getScaler().getMapVisible(w, h, step);
// x-lines
for (float x = r.x0; x < r.x1; x += step) {
// major-lines (without center)
if (std::abs(x) > 0.001) {
p.setPenBrush(cN, Qt::NoBrush);
p.drawLine(x, r.y0, x, r.y1);
}
// minor-lines
p.setPenBrush(cB, Qt::NoBrush);
for (float x1 = x+sStep; x1 < x+step; x1 += sStep) {
p.drawLine(x1, r.y0, x1, r.y1);
}
}
// y-lines
for (float y = r.y0; y < r.y1; y += step) {
// major-lines (without center)
if (std::abs(y) > 0.001) {
p.setPenBrush(cN, Qt::NoBrush);
p.drawLine(r.x0, y, r.x1, y);
}
// minor-lines
p.setPenBrush(cB, Qt::NoBrush);
for (float y1 = y+sStep; y1 < y+step; y1 += sStep) {
p.drawLine(r.x0, y1, r.x1, y1);
}
}
// thick center lines
p.setPenBrush(c0, Qt::NoBrush);
p.drawLine(0, r.y0, 0, r.y1);
p.drawLine(r.x0, 0, r.x1, 0);
}
};
#endif // TOOLMAPGRID_H

View File

@@ -0,0 +1,28 @@
#ifndef TOOLMAPZOOM_H
#define TOOLMAPZOOM_H
#include "Tool.h"
#include "../MapView2D.h"
class ToolMapZoom : public Tool {
public:
virtual void wheelEvent(MapView2D* m, QWheelEvent* e) override {
Scaler& s = m->getScaler();
if (e->delta() < 0) {
s.setScale(s.getScale() * 0.5);
} else {
s.setScale(s.getScale() / 0.5);
}
if (s.getScale() > 1000) {s.setScale(1000);}
if (s.getScale() < 5) {s.setScale(5);}
}
};
#endif // TOOLMAPZOOM_H

View File

@@ -0,0 +1,49 @@
#ifndef TOOLMOVEMAP_H
#define TOOLMOVEMAP_H
#include "Tool.h"
#include "../MapView2D.h"
/**
*
*/
class ToolMoveMap : public Tool {
private:
bool mouseIsDown = false;
Point3 startOffset;
int sx;
int sy;
virtual void mousePressEvent(MapView2D* m, QMouseEvent* e) override {
if (e->button() == Qt::MouseButton::MidButton) {
mouseIsDown = true;
this->sx = e->x();
this->sy = e->y();
this->startOffset = m->getScaler().getOffset();
}
}
virtual void mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
if (!mouseIsDown) {return;}
m->getScaler().setOffset(startOffset);
m->getScaler().addOffset(e->x()-sx, e->y()-sy);
}
virtual void mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
(void) m;
(void) e;
mouseIsDown = false;
}
virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) override {
(void) m;
(void) e;
// TODO: move on arrow keys?
}
};
#endif // TOOLMOVEMAP_H

140
mapview/tools/ToolRuler.h Normal file
View File

@@ -0,0 +1,140 @@
#ifndef TOOLRULER_H
#define TOOLRULER_H
#include "Tool.h"
class ToolRuler : public Tool {
private:
int mouseX;
int mouseY;
const bool fullSize = true;
const int rs = 40; // ruler size
const int tsMajor = 20; // major-tick size
const int tsMinor = 5; // minor-tick size
public:
virtual void mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
(void) m;
this->mouseX = e->x();
this->mouseY = e->y();
}
virtual void paintBefore(MapView2D* m, Painter& p) override {
(void) m;
// mouse-indicator within the image?
if (fullSize) {
const int w = p.width();
const int h = p.height();
p.setPenBrush(Qt::lightGray, Qt::NoBrush);
p.p->drawLine(rs, mouseY, w, mouseY);
p.p->drawLine(mouseX, rs, mouseX, h);
}
}
virtual void paintAfter(MapView2D* m, Painter& p) override {
(void) m;
static const QColor c1(240,240,240);
static const QColor c2(200,200,200);
const int w = p.width();
const int h = p.height();
// ruler step-size depending on the current zoom level
const float step = p.getScaler().getLODstep();
const float sStep = step / 10.0f;
// the visible map-rect
const Rect r = p.getScaler().getMapVisible(w, h, step);
QRect rx(rs,0,w-1-rs,rs);
QRect ry(0,rs,rs,h-1-rs);
// background
{
// samller font
QFont f = p.p->font(); f.setPointSize(8);
p.p->setFont(f);
// outline
p.setPen(Qt::darkGray);
// x-axis
QLinearGradient gx(0,0,0,rs); gx.setColorAt(0, c1); gx.setColorAt(1, c2); p.setBrush(gx);
p.p->drawRect(rx);
// y-axis
QLinearGradient gy(0,0,rs,0); gy.setColorAt(0, c2); gy.setColorAt(1, c1); p.setBrush(gy);
p.p->drawRect(ry);
}
// mouse-indicator
p.setPenBrush(Qt::darkGray, Qt::NoBrush);
p.p->drawLine(0, mouseY, rs, mouseY);
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) {
// major-lines
const float yMajor = p.s.yms(y);
//if (yMajor < 0 || yMajor > h) {continue;} // stop at the end
p.p->drawLine(0,yMajor, tsMajor,yMajor);
// minor-lines
for (float y1 = y+sStep; y1 < y+step; y1 += sStep) {
const float yMinor = p.s.yms(y1);
p.p->drawLine(0,yMinor, tsMinor,yMinor);
}
// text-label
std::sprintf(buf, "%.1f", y);
p.p->drawText(6, yMajor-2, buf);
}
// x-axis
p.p->setClipRect(rx);
for (float x = r.x0; x <= r.x1; x += step) {
// major-lines
const float xMajor = p.s.xms(x);
//if (xMajor < 0 || xMajor > w) {continue;} // stop at the end
p.p->drawLine(xMajor,0, xMajor,tsMajor);
// minor-lines
for (float x1 = x+sStep; x1 < x+step; x1 += sStep) {
const float xMinor = p.s.xms(x1);
p.p->drawLine(xMinor,0, xMinor,tsMinor);
}
// text-label
std::sprintf(buf, "%.1f", x);
p.p->drawText(xMajor+2, 18, buf);
}
p.p->setClipping(false);
}
};
#endif // TOOLRULER_H

View File

View File

@@ -0,0 +1,163 @@
#ifndef TOOLSELECTOR_H
#define TOOLSELECTOR_H
#include "Tool.h"
#include "../model/MapModelElement.h"
#include "../MapView2D.h"
#include "../model/MapModel.h"
class ToolSelector : public Tool {
Q_OBJECT
private:
/** the currently focused MapElement (if any) */
MapModelElement* focused = nullptr;
/** whether the mouse-button is currently pressed */
bool mouseIsDown = false;
public:
virtual ~ToolSelector() {;}
virtual void mousePressEvent(MapView2D* m, QMouseEvent* e) override {
if (e->button() != Qt::MouseButton::LeftButton) {return;}
mouseIsDown = true;
const Scaler& s = m->getScaler();
Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
//Point3 p3(s.xsm(e->x()), s.ysm(e->y()), 0);
const float g = m->getScaler().sm(10); // increase each BBox by 10 px (needed mainly for hor/ver lines)
// get all elements with bounding-box matchings
std::vector<MapModelElement*> possible;
for (MapModelElement* el : m->getModel()->getSelectedLayerElements()) {
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?
}
// among those, find the best-matching one (smallest distance to an intersection)
auto lambda = [&] (const MapModelElement* el1, const MapModelElement* el2) {return el1->getMV2D()->getMinDistanceXY(p2) < el2->getMV2D()->getMinDistanceXY(p2);};
auto it = std::min_element(possible.begin(), possible.end(), lambda);
MapModelElement* el = (it == possible.end()) ? (nullptr) : (*it);
// focus changed? -> unfocus the old one (if any)
if (setFocused(el)) {
;
} else {
// focus kept. provide the currently focused element with events
if (focused) {focused->getMV2D()->mousePressed(m, p2);}
}
}
/** needed eg. when the focused element gets invalid (switching visible layers) */
void layerChange(MapView2D* m) override {
(void) m;
setFocused(nullptr);
}
private:
/**
* @brief change the currently focused element. throws an event.
* @param el the to-be-focused element or null
* @return true if the focused element has changed. false otherwise
*/
bool setFocused(MapModelElement* el) {
// whether the focus has changed or not
const bool focusChanged = (focused != el);
if (focusChanged) {
// unfocus the old one (if any)
if (focused) {focused->getMV2D()->unfocus();}
// set the currently focused object (if any)
focused = el;
// focus the new one (if any)
if (focused) {focused->getMV2D()->focus();}
emit onMapElementSelected(el);
}
// done
return focusChanged;
}
virtual void mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
const Scaler& s = m->getScaler();
Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
// mouse pressed?
if (mouseIsDown) {
// provide the focused element with the mouse event?
if (focused) {focused->getMV2D()->mouseMove(m, p2); return;}
}
}
virtual void mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
const Scaler& s = m->getScaler();
Point2 p2(s.xsm(e->x()), s.ysm(e->y()));
// provide the focused element with the mouse event?
if (focused) {focused->getMV2D()->mouseReleased(m, p2);}
mouseIsDown = false;
}
virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) override {
(void) m;
if (focused) {
// pass it to the element which may consume this event
if (focused->getMV2D()->keyPressEvent(m, e)) {return;}
// not consumed -> additional options
// ESCAPE -> unfocus
if (e->key() == Qt::Key_Escape) {setFocused(nullptr);}
// DELETE -> delete
if (e->key() == Qt::Key_Delete) {
focused->deleteMe();
setFocused(nullptr);
}
}
}
signals:
/** map element was selected */
void onMapElementSelected(MapModelElement* el);
};
#endif // TOOLSELECTOR_H

59
mapview/tools/Tools.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef TOOLS_H
#define TOOLS_H
#include <vector>
#include "Tool.h"
/**
* combine several tools under the interface for one tool
*/
class Tools : public Tool {
private:
std::vector<Tool*> tools;
public:
/** add this tool */
void enable(Tool* t) {tools.push_back(t);}
/** remove this tool */
void disable(Tool* t) {tools.erase(std::remove(tools.begin(), tools.end(), t));}
virtual void mousePressEvent(MapView2D* m, QMouseEvent* e) override {
for (Tool* t : tools) {t->mousePressEvent(m, e);}
}
virtual void mouseMoveEvent(MapView2D* m, QMouseEvent* e) override {
for (Tool* t : tools) {t->mouseMoveEvent(m, e);}
}
virtual void mouseReleaseEvent(MapView2D* m, QMouseEvent* e) override {
for (Tool* t : tools) {t->mouseReleaseEvent(m, e);}
}
virtual void wheelEvent(MapView2D* m, QWheelEvent* e) override {
for (Tool* t : tools) {t->wheelEvent(m, e);}
}
virtual void keyPressEvent(MapView2D* m, QKeyEvent* e) override {
for (Tool* t : tools) {t->keyPressEvent(m, e);}
}
virtual void paintBefore(MapView2D* m, Painter& p) override {
for (Tool* t : tools) {t->paintBefore(m, p);}
}
virtual void paintAfter(MapView2D* m, Painter& p) override {
for (Tool* t : tools) {t->paintAfter(m, p);}
}
virtual void layerChange(MapView2D* m) override {
for (Tool* t : tools) {t->layerChange(m);}
}
};
#endif // TOOLS_H

23
params/ActionWidget.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "ActionWidget.h"
#include <QPushButton>
#include <QHBoxLayout>
ActionWidget::ActionWidget(QWidget *parent) : QGroupBox(parent) {
setTitle("actions");
QHBoxLayout* lay = new QHBoxLayout(this);
QPushButton* btnLoad = new QPushButton("load");
lay->addWidget(btnLoad);
QPushButton* btnSave = new QPushButton("save");
lay->addWidget(btnSave);
connect(btnLoad, SIGNAL(clicked(bool)), this, SIGNAL(onLoad()));
connect(btnSave, SIGNAL(clicked(bool)), this, SIGNAL(onSave()));
}

24
params/ActionWidget.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef ACTIONWIDGET_H
#define ACTIONWIDGET_H
#include <QGroupBox>
class ActionWidget : public QGroupBox {
Q_OBJECT
public:
explicit ActionWidget(QWidget *parent = 0);
signals:
void onLoad();
void onSave();
public slots:
};
#endif // ACTIONWIDGET_H

View File

@@ -0,0 +1,226 @@
#include "ElementParamWidget.h"
#include "../mapview/model/MapModelElement.h"
#include "../mapview/model/MMFloorObstacleLine.h"
#include "../mapview/model/MMFloorOutlinePolygon.h"
#include "../mapview/model/IHasMAC.h"
#include "../mapview/model/IHasFile.h"
#include <Indoor/floorplan/v2/Floorplan.h>
#include <QLabel>
#include <QComboBox>
#include <QGridLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QFileDialog>
QComboBox* getMaterials() {
using namespace Floorplan;
QComboBox* cmbMaterial = new QComboBox();
for (int i = 0; i < (int)Material::_END; ++i) {
switch ((Material)i) {
case Material::CONCRETE: cmbMaterial->addItem("Concrete", i); break;
case Material::UNKNOWN: cmbMaterial->addItem("Unknown ", i); break;
case Material::DRYWALL: cmbMaterial->addItem("Drywall", i); break;
case Material::WOOD: cmbMaterial->addItem("Wood", i); break;
case Material::GLASS: cmbMaterial->addItem("Glass", i); break;
case Material::_END: throw 1;
}
}
return cmbMaterial;
}
QComboBox* getObstacleTypes() {
using namespace Floorplan;
QComboBox* cmb = new QComboBox();
for (int i = 0; i < (int)ObstacleType::_END; ++i) {
switch ((ObstacleType)i) {
case ObstacleType::DOOR: cmb->addItem("Door", i); break;
case ObstacleType::UNKNOWN: cmb->addItem("Unknown ", i); break;
case ObstacleType::WALL: cmb->addItem("Wall", i); break;
case ObstacleType::WINDOW: cmb->addItem("Window", i); break;
case ObstacleType::HANDRAIL:cmb->addItem("Handrail", i); break;
case ObstacleType::PILLAR: cmb->addItem("Pillar", i); break;
case ObstacleType::_END: throw 1;
}
}
return cmb;
}
QComboBox* getOutlineMethods() {
using namespace Floorplan;
QComboBox* cmb = new QComboBox();
for (int i = 0; i < (int)OutlineMethod::_END; ++i) {
switch ((OutlineMethod)i) {
case OutlineMethod::ADD: cmb->addItem("add", i); break;
case OutlineMethod::REMOVE: cmb->addItem("remove ", i); break;
case OutlineMethod::_END: throw 1;
}
}
return cmb;
}
ElementParamWidget::ElementParamWidget(QWidget *parent) : QGroupBox(parent) {
setMinimumSize(100, 100);
setMaximumWidth(200);
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;
// start empty
setElement(nullptr);
}
void ElementParamWidget::setElement(MapModelElement* el) {
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("?");
}
// 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());}
}
// 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());}
}
// 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());}
}
// 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());}
}
}
void ElementParamWidget::onMaterialChange() {
IHasMaterial* el = dynamic_cast<IHasMaterial*>(this->curElement);
if (el) {el->setMaterial( (Floorplan::Material) material.cmb->currentData().toInt() );}
}
void ElementParamWidget::onObstacleTypeChange() {
IHasObstacleType* el = dynamic_cast<IHasObstacleType*>(this->curElement);
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::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::onSelectFileName() {
QString res = QFileDialog::getOpenFileName(this);
dynamic_cast<IHasFile*>(curElement)->setFileName(res.toStdString());
fileName.lbl->setText(res);
}

View File

@@ -0,0 +1,76 @@
#ifndef PARAMWIDGET_H
#define PARAMWIDGET_H
#include <QGroupBox>
#include "../mapview/model/MapModelElement.h"
class QLabel;
class QComboBox;
class QLineEdit;
class QPushButton;
class ElementParamWidget : public QGroupBox {
Q_OBJECT
public:
explicit ElementParamWidget(QWidget *parent = 0);
private:
QLabel* lblDetails;
MapModelElement* curElement = nullptr;
struct {
QComboBox* cmb;
QLabel* lbl;
} material;
struct {
QComboBox* cmb;
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:
/** set the to-be-edited element */
void setElement(MapModelElement* el);
private slots:
void onMaterialChange();
void onObstacleTypeChange();
void onNameChange();
void onMACChanged();
void onOutlineMethodChange();
void onSelectFileName();
};
#endif // PARAMWIDGET_H

106
params/LayerParamWidget.cpp Normal file
View File

@@ -0,0 +1,106 @@
#include "LayerParamWidget.h"
#include <QGridLayout>
#include <QLineEdit>
#include <QLabel>
#include "mapview/model/MMFloor.h"
LayerParamWidget::LayerParamWidget(QWidget *parent) : QGroupBox(parent) {
setMinimumSize(100, 100);
setMaximumWidth(200);
setTitle("MapLayer Parameters");
QGridLayout* lay = new QGridLayout(this);
int r = 0;
selected.lbl = new QLabel("selected");
selected.info = new QLabel();
lay->addWidget(selected.lbl, r, 0);
lay->addWidget(selected.info, r, 1);
++r;
name.lbl = new QLabel("name");
name.txt = new QLineEdit();
lay->addWidget(name.lbl, r, 0);
lay->addWidget(name.txt, r, 1);
connect(name.txt, SIGNAL(textChanged(QString)), this, SLOT(onNameChanged()));
++r;
atHeight.lbl = new QLabel("at height");
atHeight.txt = new QLineEdit();
lay->addWidget(atHeight.lbl, r, 0);
lay->addWidget(atHeight.txt, r, 1);
connect(atHeight.txt, SIGNAL(textChanged(QString)), this, SLOT(onAtHeightChanged()));
++r;
height.lbl = new QLabel("height");
height.txt = new QLineEdit();
lay->addWidget(height.lbl, r, 0);
lay->addWidget(height.txt, r, 1);
connect(height.txt, SIGNAL(textChanged(QString)), this, SLOT(onHeightChanged()));
++r;
// start empty
setElement(nullptr);
}
void LayerParamWidget::setElement(MapLayer* l) {
this->curElement = l;
if (l) {
std::string info = l->getLayerName() + " (" + std::to_string(l->getNumElements()) + " elements)";
selected.info->setText(info.c_str());
} else {
selected.info->setText("-");
}
{
MMFloor* floor = dynamic_cast<MMFloor*>(l);
atHeight.lbl->setVisible(floor);
atHeight.txt->setVisible(floor);
height.lbl->setVisible(floor);
height.txt->setVisible(floor);
if (floor) {
std::string _atHeight = std::to_string(floor->getFloor().atHeight);
atHeight.txt->setText( _atHeight.c_str() );
std::string _height = std::to_string(floor->getFloor().height);
height.txt->setText( _height.c_str() );
}
}
// has name
{
IHasName* elem = dynamic_cast<IHasName*>(l);
name.lbl->setVisible(elem);
name.txt->setVisible(elem);
if (elem) {name.txt->setText(elem->getName().c_str());}
}
}
void LayerParamWidget::onAtHeightChanged() {
MMFloor* floor = dynamic_cast<MMFloor*>(curElement);
try {
if (floor) {floor->getFloor().atHeight = std::stof(atHeight.txt->text().toStdString());}
} catch (...) {;}
}
void LayerParamWidget::onHeightChanged() {
MMFloor* floor = dynamic_cast<MMFloor*>(curElement);
try {
if (floor) {floor->getFloor().height = std::stof(height.txt->text().toStdString());}
} catch (...) {;}
}
void LayerParamWidget::onNameChanged() {
dynamic_cast<IHasName*>(curElement)->setName(name.txt->text().toStdString());
}

61
params/LayerParamWidget.h Normal file
View File

@@ -0,0 +1,61 @@
#ifndef LAYERPARAMWIDGET_H
#define LAYERPARAMWIDGET_H
#include <QGroupBox>
class MapLayer;
class QLabel;
class QLineEdit;
class QComboBox;
class LayerParamWidget : public QGroupBox {
Q_OBJECT
public:
explicit LayerParamWidget(QWidget *parent = 0);
private:
MapLayer* curElement = nullptr;
struct {
QLabel* info;
QLabel* lbl;
} selected;
struct {
QLineEdit* txt;
QLabel* lbl;
} name;
struct {
QLineEdit* txt;
QLabel* lbl;
} atHeight;
struct {
QLineEdit* txt;
QLabel* lbl;
} height;
signals:
public slots:
/** set the to-be-edited element */
void setElement(MapLayer* l);
private slots:
void onAtHeightChanged();
void onHeightChanged();
void onNameChanged();
};
#endif // LAYERPARAMWIDGET_H

174
params/ToolBox.cpp Normal file
View File

@@ -0,0 +1,174 @@
#include "ToolBoxWidget.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QPushButton>
#include <QPixmap>
#include "../mapview/model/MapLayers.h"
#include "../mapview/MapView2D.h"
#include "../mapview/model/MapModel.h"
#include "../mapview/model/MMFloorAccessPoint.h"
#include "../mapview/model/MMFloorBeacon.h"
#include "../UIHelper.h"
ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent), view(view) {
const int s = 32;
setMaximumWidth(48);
setMinimumWidth(48);
QGridLayout* lay = new QGridLayout(this);
int r = 0;
// OBSTACLES
btnGround = new QPushButton(UIHelper::getIcon("floor"), "");
btnGround->setMinimumSize(s,s);
lay->addWidget(btnGround, r++, 0, 1,1,Qt::AlignTop);
connect(btnGround, SIGNAL(clicked(bool)), this, SLOT(onNewGround()));
btnWall = new QPushButton(UIHelper::getIcon("wall"), "");
btnWall->setMinimumSize(s,s);
lay->addWidget(btnWall, r++, 0, 1,1,Qt::AlignTop);
connect(btnWall, SIGNAL(clicked(bool)), this, SLOT(onNewWall()));
btnPillar = new QPushButton(UIHelper::getIcon("pillar"), "");
btnPillar->setMinimumSize(s,s);
lay->addWidget(btnPillar, r++, 0, 1,1,Qt::AlignTop);
connect(btnPillar, SIGNAL(clicked(bool)), this, SLOT(onNewPillar()));
// TRANSMITTERS
btnWifi = new QPushButton(UIHelper::getIcon("wifi"), "");
btnWifi->setMinimumSize(s,s);
lay->addWidget(btnWifi, r++, 0, 1,1,Qt::AlignTop);
connect(btnWifi, SIGNAL(clicked(bool)), this, SLOT(onNewAccessPoint()));
btnBeacon = new QPushButton(UIHelper::getIcon("beacon"), "");
btnBeacon->setMinimumSize(s,s);
lay->addWidget(btnBeacon, r++, 0, 1,1,Qt::AlignTop);
connect(btnBeacon, SIGNAL(clicked(bool)), this, SLOT(onNewBeacon()));
// IMAGES
btnImage = new QPushButton(UIHelper::getIcon("image"), "");
btnImage->setMinimumSize(s,s);
lay->addWidget(btnImage, r++, 0, 1,1,Qt::AlignTop);
connect(btnImage, SIGNAL(clicked(bool)), this, SLOT(onNewImage()));
// FILL
lay->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), r, 0);
// start empty
setSelectedLayer(nullptr);
}
void ToolBoxWidget::setSelectedLayer(MapLayer *ml) {
this->curLayer = ml;
btnGround->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_GROUND));
btnWall->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
btnPillar->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
btnWifi->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_ACCESS_POINTS));
btnBeacon->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_BEACONS));
btnImage->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_UNDERLAY));
}
void ToolBoxWidget::onNewGround() {
const Point2 center = view->getScaler().getCenter();
float s = view->getScaler().sm(50);
Floorplan::FloorOutlinePolygon* poly = new Floorplan::FloorOutlinePolygon();
poly->name = "new";
poly->poly.points.push_back(Point2(center.x-s, center.y-s));
poly->poly.points.push_back(Point2(center.x+s, center.y-s));
poly->poly.points.push_back(Point2(center.x, center.y+s));
MMFloorOutline* ml = (MMFloorOutline*)curLayer;
ml->create(poly);
view->getModel()->reselect();
}
void ToolBoxWidget::onNewWall() {
const Point2 center = view->getScaler().getCenter();
float s = view->getScaler().sm(50);
Floorplan::FloorObstacleLine* wall = new Floorplan::FloorObstacleLine(
Floorplan::ObstacleType::WALL,
Floorplan::Material::DRYWALL,
Point2(center.x-s, center.y),
Point2(center.x+s, center.y)
);
MMFloorObstacles* obs = (MMFloorObstacles*)curLayer;
obs->createLine(wall);
view->getModel()->reselect();
}
void ToolBoxWidget::onNewPillar() {
const Point2 center = view->getScaler().getCenter();
float s = view->getScaler().sm(50);
Floorplan::FloorObstacleCircle* pillar = new Floorplan::FloorObstacleCircle(
Floorplan::ObstacleType::PILLAR,
Floorplan::Material::DRYWALL,
Point2(center.x-s, center.y),
s
);
MMFloorObstacles* obs = (MMFloorObstacles*)curLayer;
obs->createCircle(pillar);
view->getModel()->reselect();
}
void ToolBoxWidget::onNewAccessPoint() {
const Point2 center = view->getScaler().getCenter();
Floorplan::AccessPoint* ap = new Floorplan::AccessPoint(
"noname", "00:00:00:00:00:00", Point3(center.x, center.y, 0)
);
MMFloorAccessPoints* aps = (MMFloorAccessPoints*) curLayer;
aps->createAP(ap);
}
void ToolBoxWidget::onNewBeacon() {
const Point2 center = view->getScaler().getCenter();
Floorplan::Beacon* b = new Floorplan::Beacon(
"noname", "00:00:00:00:00:00", Point3(center.x, center.y, 0)
);
MMFloorBeacons* beacons = (MMFloorBeacons*) curLayer;
beacons->createBeacon(b);
}
void ToolBoxWidget::onNewImage() {
const Point2 center = view->getScaler().getCenter();
MMFloorUnderlay* underlay = (MMFloorUnderlay*) curLayer;
underlay->createImage(center);
}

53
params/ToolBoxWidget.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef TOOLBOX_H
#define TOOLBOX_H
#include <QWidget>
class MapLayer;
class QPushButton;
class MapView2D;
class ToolBoxWidget : public QWidget {
Q_OBJECT
public:
explicit ToolBoxWidget(MapView2D* view, QWidget *parent = 0);
signals:
public slots:
/** set the currently selected map layer */
void setSelectedLayer(MapLayer* ml);
private:
MapView2D* view;
MapLayer* curLayer;
QPushButton* btnGround;
QPushButton* btnWall;
QPushButton* btnPillar;
QPushButton* btnWifi;
QPushButton* btnBeacon;
QPushButton* btnImage;
private slots:
void onNewGround();
void onNewWall();
void onNewPillar();
void onNewAccessPoint();
void onNewBeacon();
void onNewImage();
};
#endif // TOOLBOX_H

13
res.qrc Normal file
View File

@@ -0,0 +1,13 @@
<RCC>
<qresource prefix="/">
<file>res/icons/polygon32.png</file>
<file>res/icons/polygon16.png</file>
<file>res/icons/floor.svg</file>
<file>res/icons/wall.svg</file>
<file>res/icons/pillar.svg</file>
<file>res/icons/wifi.svg</file>
<file>res/icons/beacon.svg</file>
<file>res/icons/image.svg</file>
<file>res/icons/cross.png</file>
</qresource>
</RCC>

770
res/icons/beacon.svg Normal file
View File

@@ -0,0 +1,770 @@
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ns1="http://sozi.baierouge.fr"
id="svg7413"
sodipodi:docname="smarTB arch v2.svg"
viewBox="0 0 29.562 19.343"
version="1.1"
inkscape:version="0.48.1 r9760"
>
<defs
id="defs7415"
>
<linearGradient
id="linearGradient5302-8"
inkscape:collect="always"
>
<stop
id="stop5304"
style="stop-color:rgb(136, 138, 133)"
offset="0"
/>
<stop
id="stop5306"
style="stop-color:rgb(211, 215, 207);stop-opacity:0"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient14881"
>
<stop
id="stop14883"
style="stop-color:#877c32"
offset="0"
/>
<stop
id="stop14893"
style="stop-color:#ffd716"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient7622"
>
<stop
id="stop7624"
style="stop-color:white"
offset="0"
/>
<stop
id="stop7626"
style="stop-color:white;stop-opacity:0"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient3506"
>
<stop
id="stop3508"
style="stop-color:#3c3c3c"
offset="0"
/>
<stop
id="stop3510"
style="stop-color:#3c3c3c;stop-opacity:.22745"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient6215"
>
<stop
id="stop6217"
style="stop-color:#cfb900"
offset="0"
/>
<stop
id="stop6219"
style="stop-color:#e2d44d"
offset="0.21"
/>
<stop
id="stop6221"
style="stop-color:#9a8b00"
offset="0.84"
/>
<stop
id="stop6223"
style="stop-color:#cfb900"
offset="1"
/>
</linearGradient
>
<radialGradient
id="radialGradient5328"
xlink:href="#linearGradient5302-8"
gradientUnits="userSpaceOnUse"
cy="15.259"
cx="27.577"
gradientTransform="matrix(1.4785 0 0 1.4785 -13.195 -7.3291)"
r="3.8335"
inkscape:collect="always"
/>
<radialGradient
id="radialGradient5330"
xlink:href="#linearGradient5302-8"
gradientUnits="userSpaceOnUse"
cy="15.048"
cx="27.577"
gradientTransform="matrix(1.3418 0 0 1.3418 -9.426 -5.2229)"
r="3.8335"
inkscape:collect="always"
/>
<radialGradient
id="radialGradient5332"
gradientUnits="userSpaceOnUse"
cy="44.75"
cx="21.5"
gradientTransform="matrix(1.4601 0 0 .11765 -7.106 31.198)"
r="17"
inkscape:collect="always"
>
<stop
id="stop14995"
style="stop-color:black"
offset="0"
/>
<stop
id="stop14997"
style="stop-color:black;stop-opacity:0"
offset="1"
/>
</radialGradient
>
<radialGradient
id="radialGradient5334"
gradientUnits="userSpaceOnUse"
cy="14.525"
cx="10.78"
gradientTransform="matrix(2.7925 .12351 -.032071 .72512 -18.856 8.6275)"
r="23"
inkscape:collect="always"
>
<stop
id="stop14983"
style="stop-color:#628430"
offset="0"
/>
<stop
id="stop14985"
style="stop-color:#364d17"
offset="1"
/>
</radialGradient
>
<radialGradient
id="radialGradient5336"
xlink:href="#linearGradient7622"
gradientUnits="userSpaceOnUse"
cy="12.336"
cx="6.509"
gradientTransform="matrix(2.0637 -.0048795 .0019461 .82308 -6.9477 9.5473)"
r="21.999"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5338"
y2="31.347"
xlink:href="#linearGradient7622"
gradientUnits="userSpaceOnUse"
x2="18.968"
gradientTransform="matrix(.53081 0 0 .75859 -34.068 -8.2971)"
y1="20.166"
x1="16.965"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5340"
y2="19.5"
xlink:href="#linearGradient14881"
gradientUnits="userSpaceOnUse"
x2="27"
gradientTransform="matrix(0 -.33333 1 0 -12.043 28)"
y1="19.5"
x1="24"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5342"
y2="19.5"
xlink:href="#linearGradient14881"
gradientUnits="userSpaceOnUse"
x2="4.3284"
gradientTransform="matrix(.33333 0 0 1 2.2901 9)"
y1="19.5"
x1="8"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5344"
y2="19.5"
xlink:href="#linearGradient14881"
gradientUnits="userSpaceOnUse"
x2="4.3284"
gradientTransform="matrix(-.33333 0 0 1 14.623 8.7923)"
y1="19.5"
x1="8"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5346"
y2="31.347"
gradientUnits="userSpaceOnUse"
x2="18.968"
gradientTransform="matrix(.26246 0 0 .32273 -22.852 9.5051)"
y1="20.166"
x1="16.965"
inkscape:collect="always"
>
<stop
id="stop14863"
style="stop-color:white"
offset="0"
/>
<stop
id="stop14865"
style="stop-color:white;stop-opacity:0"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient5348"
y2="19.5"
xlink:href="#linearGradient6215"
gradientUnits="userSpaceOnUse"
x2="27"
gradientTransform="matrix(-.18719 0 0 .28079 -11.485 10.589)"
y1="19.5"
x1="24"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5350"
y2="19.5"
xlink:href="#linearGradient6215"
gradientUnits="userSpaceOnUse"
x2="4.3284"
gradientTransform="matrix(0 .18719 -.28079 0 -14.855 14.145)"
y1="19.5"
x1="8"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5352"
y2="11.5"
xlink:href="#linearGradient6215"
gradientUnits="userSpaceOnUse"
x2="4.7127"
gradientTransform="matrix(0 .18719 -.28079 0 -14.855 16.673)"
y1="11.5"
x1="12.647"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5354"
y2="19.5"
xlink:href="#linearGradient6215"
gradientUnits="userSpaceOnUse"
x2="4.3284"
gradientTransform="matrix(.18719 0 0 .28079 -22.249 10.589)"
y1="19.5"
x1="8"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5356"
y2="19.5"
xlink:href="#linearGradient14881"
gradientUnits="userSpaceOnUse"
x2="4.3284"
gradientTransform="matrix(0 -.33333 1 0 -12.043 33.667)"
y1="19.5"
x1="8"
inkscape:collect="always"
/>
<radialGradient
id="radialGradient5358"
gradientUnits="userSpaceOnUse"
cy="-36.857"
cx="21.333"
gradientTransform="matrix(.86667 -1.922e-7 1.664e-7 .75005 -8.4222 9.6446)"
r="8"
inkscape:collect="always"
>
<stop
id="stop9129"
style="stop-color:#f0f0f0"
offset="0"
/>
<stop
id="stop9131"
style="stop-color:#a9a9a9"
offset="1"
/>
</radialGradient
>
<linearGradient
id="linearGradient5360"
y2="9.1187"
xlink:href="#linearGradient3506"
gradientUnits="userSpaceOnUse"
x2="20.405"
gradientTransform="matrix(.64540 0 0 .42550 -3.4019 -23.059)"
y1="6.9878"
x1="20.405"
inkscape:collect="always"
/>
<linearGradient
id="linearGradient5362"
y2="9.1187"
xlink:href="#linearGradient3506"
gradientUnits="userSpaceOnUse"
x2="20.405"
gradientTransform="matrix(.64540 0 0 .42550 -.90190 -23.059)"
y1="6.9878"
x1="20.405"
inkscape:collect="always"
/>
</defs
>
<sodipodi:namedview
id="namedview7417"
fit-margin-left="0"
inkscape:zoom="8.0000002"
borderopacity="1.0"
inkscape:current-layer="layer1"
inkscape:cx="29.19243"
inkscape:cy="-3.0269165"
inkscape:window-maximized="1"
showgrid="false"
fit-margin-right="0"
units="px"
inkscape:document-units="in"
bordercolor="#666666"
inkscape:window-x="0"
inkscape:window-y="24"
fit-margin-bottom="0"
inkscape:window-width="1440"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
pagecolor="#ffffff"
inkscape:window-height="823"
fit-margin-top="0"
/>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(-807.72 -736.2)"
>
<g
id="g6941"
style="enable-background:new"
inkscape:export-ydpi="200"
inkscape:export-filename="/home/baptiste/Images/Mesh ecosud topologie.png"
transform="matrix(.63449 0 0 .63449 570.41 585.32)"
inkscape:export-xdpi="200"
/>
<g
id="g4758"
transform="translate(1.25 58.5)"
/>
<g
id="g5144"
inkscape:export-ydpi="1000"
inkscape:export-xdpi="1000"
inkscape:export-filename="/home/baptiste/Images/Projets/SmarTB/smarTB arch.png"
transform="translate(79.432 90.278)"
>
<g
id="g5146"
style="enable-background:new"
transform="matrix(0 -1 1 0 847.93 743.58)"
inkscape:r_cy="true"
inkscape:r_cx="true"
>
<g
id="g5148"
transform="matrix(.44966 -.22409 .22409 .44966 75.597 -117.31)"
>
<path
id="path5150"
sodipodi:rx="3.3335035"
sodipodi:ry="3.3335035"
style="color:#000000;stroke:url(#radialGradient5328);stroke-miterlimit:10;stroke-width:1.5866;fill:none"
sodipodi:type="arc"
d="m30.911 18.605a3.3335 3.3335 0 1 1 -6.667 0 3.3335 3.3335 0 1 1 6.667 0z"
transform="matrix(0 -1.7738 -1.7738 0 57 70.164)"
sodipodi:cy="18.604561"
sodipodi:cx="27.577164"
inkscape:r_cy="true"
inkscape:r_cx="true"
/>
<path
id="path5152"
sodipodi:rx="3.3335035"
sodipodi:ry="3.3335035"
style="color:#000000;stroke:url(#radialGradient5330);stroke-miterlimit:10;stroke-width:.81150;fill:none"
sodipodi:type="arc"
d="m30.911 18.605a3.3335 3.3335 0 1 1 -6.667 0 3.3335 3.3335 0 1 1 6.667 0z"
transform="matrix(0 -3.4678 -3.4678 0 88.518 116.88)"
sodipodi:cy="18.604561"
sodipodi:cx="27.577164"
inkscape:r_cy="true"
inkscape:r_cx="true"
/>
</g
>
</g
>
<g
id="g5154"
transform="translate(-59,28.5)"
>
<path
id="path5156"
sodipodi:nodetypes="cczcccc"
style="stroke-linejoin:round;fill-rule:evenodd;stroke:#2e3436;stroke-width:.52833;fill:#2e3436"
inkscape:connector-curvature="0"
d="m793.69 626.37-0.28284 4.1423s0.14906 0.16096 0.30384 0.16265c0.15478 0.002 0.29784-0.15586 0.29784-0.15586l-0.31176-4.1491v-2.0894l-0.007 2.0894z"
/>
<path
id="path5158"
d="m797.68 630.65-4.1423-0.28284s-0.16096 0.14905-0.16265 0.30384c-0.002 0.15478 0.15586 0.29784 0.15586 0.29784l4.1491-0.31176h2.0894l-2.0894-0.007z"
sodipodi:nodetypes="cczcccc"
style="stroke-linejoin:round;fill-rule:evenodd;stroke:#2e3436;stroke-width:.52833;fill:#2e3436"
inkscape:connector-curvature="0"
/>
<g
id="g5160"
transform="matrix(.40772 0 0 .40772 794.56 621.08)"
>
<path
id="path5162"
style="opacity:.3;color:#000000;display:block;fill:url(#radialGradient5332)"
inkscape:connector-curvature="0"
d="m49.107 36.463a24.822 2 0 0 1 -49.643 0 24.822 2 0 1 1 49.643 0z"
/>
<path
id="path5164"
d="m46.5 35.5c-19.549 0-33.623-0.02218-45 0.000005v-20h45z"
sodipodi:nodetypes="ccccc"
style="stroke-linejoin:round;color:#000000;stroke:#28390d;stroke-width:.89721;display:block;fill:url(#radialGradient5334)"
inkscape:connector-curvature="0"
/>
<path
id="path5166"
d="m45.5 34.502c-17.946 0-33.678-0.01023-42.995-0.0039-0.0042-0.001-0.0039-17.998-0.0039-17.998h42.999c-0.004 8.3386 0 18.002 0 18.002z"
sodipodi:nodetypes="cccccc"
style="opacity:.4;color:#000000;stroke:url(#radialGradient5336);display:block;fill:none"
inkscape:connector-curvature="0"
/>
<rect
id="rect5168"
style="color:#000000;stroke:#2e3436;display:block;fill:#555753"
rx=".94194"
transform="rotate(-90)"
ry=".94194"
width="10.056"
y="5.4603"
x="-30.528"
height="5.93"
/>
<rect
id="rect5170"
style="opacity:.17045;color:#000000;stroke:url(#linearGradient5338);display:block;fill:none"
transform="rotate(-90)"
rx="0"
ry="0"
height="3.882"
width="8.016"
y="6.4676"
x="-29.583"
/>
<path
id="path5172"
sodipodi:nodetypes="cccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5340)"
inkscape:connector-curvature="0"
d="m6.9567 19v1h1v-1zm2 0v1h1v-1z"
/>
<path
id="path5174"
style="color:#000000;display:block;fill:url(#linearGradient5342)"
inkscape:connector-curvature="0"
d="m3.9567 22v1h1v-1h-1zm0 2v1h1v-1h-1zm0 2v1h1v-1h-1zm0 2v1h1v-1h-1z"
/>
<path
id="path5176"
style="color:#000000;display:block;fill:url(#linearGradient5344)"
inkscape:connector-curvature="0"
d="m11.957 21.792v1h1v-1h-1zm0 2v1h1v-1h-1zm0 2v1h1v-1h-1zm0 2v1h1v-1h-1z"
/>
<g
id="g5178"
transform="matrix(3.323 0 0 3.323 91.632 -32.316)"
>
<path
id="path5180"
sodipodi:nodetypes="cccccc"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:none"
inkscape:connector-curvature="0"
d="m-21.172 16.064-0.83359 0.29834v0.52648 2.8254l-2.7155 0.01273v-0.58894"
/>
<rect
id="rect5182"
style="color:#000000;stroke:#2e3436;stroke-width:.28079;display:block;fill:#555753"
rx=".26449"
ry=".26449"
height="2.2268"
width="4.5082"
y="15.504"
x="-20.899"
/>
<rect
id="rect5184"
style="opacity:.17045;color:#000000;stroke:url(#linearGradient5346);stroke-width:.28079;display:block;fill:none"
rx="0"
ry="0"
height="1.6515"
width="3.9636"
y="15.786"
x="-20.634"
/>
<path
id="path5186"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:none"
inkscape:connector-curvature="0"
d="m-21.172 16.626-0.83798 0.29834"
/>
<path
id="path5188"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:#98a332"
inkscape:connector-curvature="0"
d="m-21.172 17.187-0.84236 0.42118"
/>
<path
id="path5190"
sodipodi:nodetypes="ccccccccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5348)"
inkscape:connector-curvature="0"
d="m-16.274 15.924v0.28079h0.29641v-0.28079zm0 0.56158v0.28079h0.29641v-0.28079zm0 0.56158v0.28079h0.29641v-0.28079z"
/>
<path
id="path5192"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5350)"
inkscape:connector-curvature="0"
d="m-20.47 15.081v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641zm0.56158 0v0.29641h0.28079v-0.29641z"
/>
<path
id="path5194"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:none"
inkscape:connector-curvature="0"
d="m-20.342 18.103 0.29782 1.0499h0.546l-0.29782-1.0499"
/>
<path
id="path5196"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:none"
inkscape:connector-curvature="0"
d="m-19.219 18.103 0.29782 1.0499h0.546l-0.29782-1.0499"
/>
<path
id="path5198"
style="color:#000000;stroke:#305526;stroke-width:.14039;display:block;fill:none"
inkscape:connector-curvature="0"
d="m-18.096 18.131 0.29782 1.0218h0.54601l-0.29782-1.0218"
/>
<path
id="path5200"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5352)"
inkscape:connector-curvature="0"
d="m-20.47 17.852v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851zm0.56158 0v0.31851h0.28079v-0.31851z"
/>
<path
id="path5202"
sodipodi:nodetypes="ccccccccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5354)"
inkscape:connector-curvature="0"
d="m-21.313 15.924v0.28079h0.29641v-0.28079zm0 0.56158v0.28079h0.29641v-0.28079zm0 0.56158v0.28079h0.29641v-0.28079z"
/>
</g
>
<path
id="path5204"
sodipodi:nodetypes="cccccccccc"
style="color:#000000;display:block;fill:url(#linearGradient5356)"
inkscape:connector-curvature="0"
d="m6.9567 31v1h1v-1zm2 0v1h1v-1z"
/>
</g
>
<g
id="g5206"
transform="matrix(1.3548 0 0 1.3548 763.23 683.41)"
>
<g
id="g5208"
transform="matrix(0 -.47816 .47816 0 29.162 -32.888)"
>
<rect
id="rect5210"
style="fill:#ffffff"
rx=".625"
ry=".625"
height="4.8971"
width="6.3732"
y="15.653"
x="7.8712"
/>
<rect
id="rect5212"
style="stroke:#555753;stroke-width:.56467;fill:url(#radialGradient5358)"
rx=".56471"
ry=".56471"
transform="scale(1,-1)"
width="7"
y="-21.5"
x="7.5"
height="7"
/>
<rect
id="rect5214"
style="opacity:.88172;fill:url(#linearGradient5360)"
transform="scale(1,-1)"
height="1"
width="1.5"
y="-20"
x="9"
/>
<rect
id="rect5216"
style="opacity:.88172;fill:url(#linearGradient5362)"
transform="scale(1,-1)"
height="1"
width="1.5"
y="-20"
x="11.5"
/>
</g
>
</g
>
</g
>
</g
>
</g
>
<metadata
>
<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
>
<dc:title
>Wireless sensor</dc:title
>
<dc:date
>2011-07-29T10:27:30</dc:date
>
<dc:description
>A wireless sensor clipart influenced by Tango project guidelines</dc:description
>
<dc:source
>https://openclipart.org/detail/152365/wireless-sensor-by-b.gaultier</dc:source
>
<dc:creator
>
<cc:Agent
>
<dc:title
>b.gaultier</dc:title
>
</cc:Agent
>
</dc:creator
>
<dc:subject
>
<rdf:Bag
>
<rdf:li
>electronic</rdf:li
>
<rdf:li
>sensor</rdf:li
>
<rdf:li
>tango</rdf:li
>
<rdf:li
>wireless</rdf:li
>
<rdf:li
>wireless sensor</rdf:li
>
</rdf:Bag
>
</dc:subject
>
</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: 23 KiB

BIN
res/icons/cross.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

1070
res/icons/floor.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 34 KiB

81
res/icons/image.svg Normal file
View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--part of the matt icon theme by sixsixfive released under CC0 (https://creativecommons.org/publicdomain/zero/1.0/) on openclipart-->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 128 128">
<defs id="0">
<linearGradient id="L">
<stop id="h" stop-opacity="0"/>
<stop offset="0.5" id="i"/>
<stop id="j" offset="1" stop-opacity="0.169"/>
</linearGradient>
<linearGradient id="M">
<stop id="k" stop-opacity="0"/>
<stop id="l" offset="0.5"/>
<stop offset="1" id="m" stop-opacity="0"/>
</linearGradient>
<linearGradient id="N">
<stop id="n"/>
<stop offset="1" id="o" stop-opacity="0.579"/>
</linearGradient>
<linearGradient id="O">
<stop id="p" stop-color="#8bb300"/>
<stop offset="1" id="q" stop-color="#99c500"/>
</linearGradient>
<linearGradient id="P">
<stop id="r" stop-color="#eee"/>
<stop offset="1" id="s" stop-color="#d2d2d2"/>
</linearGradient>
<linearGradient id="Q">
<stop id="t"/>
<stop offset="1" id="u" stop-opacity="0.536"/>
</linearGradient>
<linearGradient id="R">
<stop id="v"/>
<stop offset="1" id="w" stop-color="#ddd" stop-opacity="0"/>
</linearGradient>
<filter id="S" x="-0.147" width="1.294" y="-0.145" height="1.29">
<feGaussianBlur stdDeviation="1.81881" id="x"/>
</filter>
<filter id="T">
<feGaussianBlur stdDeviation="2.58594" id="y"/>
</filter>
<radialGradient xlink:href="#Q" id="U" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.97467889,0,0.43910718)" cx="89.51" cy="22.254" r="18.279"/>
<radialGradient xlink:href="#O" r="31.14" cy="35.807" cx="179.26" gradientTransform="matrix(1,0,0,0.13401545,-131.35837,66.507196)" gradientUnits="userSpaceOnUse" id="V"/>
<radialGradient xlink:href="#N" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1,0,0,0.64123902,0,22.551491)" r="33.797" cy="62.859" cx="64.2" id="W"/>
<filter id="X">
<feGaussianBlur stdDeviation="0.2529" id="z"/>
</filter>
<linearGradient xlink:href="#R" y2="25.1" x2="86.82" y1="14.793" x1="98.33" gradientTransform="matrix(0.96714879,0,0,0.96714879,1.5886796,3.2231964)" gradientUnits="userSpaceOnUse" id="Y"/>
<radialGradient xlink:href="#P" r="44.42" cy="100.32" cx="81.79" gradientTransform="matrix(2.0026052,-1.5970314,1.7773333,2.2286954,-278.10308,27.013826)" gradientUnits="userSpaceOnUse" id="Z"/>
<linearGradient xlink:href="#L" gradientTransform="translate(-0.42906965,0.17162786)" gradientUnits="userSpaceOnUse" y2="49.07" x2="98.13" y1="41.456" x1="90.12" id="a"/>
<filter id="b">
<feGaussianBlur stdDeviation="0.2599" id="10"/>
</filter>
<linearGradient xlink:href="#M" gradientTransform="translate(-60.345531,36.057221)" y2="48.958" x2="97.88" y1="41.3" x1="90.16" gradientUnits="userSpaceOnUse" id="c"/>
<linearGradient xlink:href="#P" gradientUnits="userSpaceOnUse" y2="50.42" x2="91.72" y1="31.16" x1="104.33" id="d"/>
<linearGradient xlink:href="#P" gradientUnits="userSpaceOnUse" y2="68.34" x2="36.483" y1="89.57" x1="25.99" id="e"/>
<filter id="f">
<feGaussianBlur stdDeviation="0.34584" id="11"/>
</filter>
</defs>
<path d="m 20.09375,4.1185004 0,117.9999996 88.84375,0 0,-86.15625 -0.59375,-0.625 c 0.21045,0.144391 0.41688,0.302162 0.625,0.4375 L 78.09375,4.1497504 c 0.05654,0.079597 0.09993,0.1703021 0.15625,0.25 l -0.25,-0.28125 -57.90625,0 z" id="1" transform="matrix(0.96714879,0,0,0.97126149,1.5886796,2.6954315)" opacity="0.809" filter="url(#T)"/>
<path d="m 21.022325,5.8526322 0,114.1235578 85.925125,0 0,-83.325913 -29.921165,-30.7976448 -56.00396,0 z" id="2" fill="url(#Z)"/>
<path id="3" d="m 81.698039,28.309502 0.135161,-8.351 C 81.901124,13.359407 80.956142,8.4107397 77.785779,3.9471419 L 80.362343,3.9159389 107.86271,29.53084 c -4.06802,-2.645393 -9.621189,-0.791242 -16.861906,-1.025606 l -9.302765,-0.195732 z" transform="matrix(1.016085,0,0,1.112241,-3.7922382,2.9647584)" opacity="0.505" fill="url(#U)" filter="url(#S)"/>
<path d="m 82.748319,29.121681 0.130721,-8.07666 c 0.06569,-6.382306 -2.691577,-10.83607 -5.75779,-15.1530328 l 29.86674,30.5881668 c -3.93438,-2.558489 -8.23966,-6.942507 -15.242513,-7.169171 l -8.997158,-0.189303 z" id="4" fill="#eee"/>
<path id="5" d="m 82.748319,29.121681 0.130721,-8.07666 c 0.06569,-6.382306 -2.691577,-10.83607 -5.75779,-15.1530328 l 29.86674,30.5881668 c -3.93438,-2.558489 -8.23966,-6.942507 -15.242513,-7.169171 l -8.997158,-0.189303 z" fill="url(#Y)"/>
<path id="6" d="m 32.34375,41.1875 c -1.076646,0 -1.9375,0.860854 -1.9375,1.9375 l 0.789179,34.65625 6.117071,6.118657 58.75,0.631343 c 1.076646,0 1.9375,-0.860854 1.9375,-1.9375 L 97.368657,49.125 89.370242,41.818843 32.34375,41.1875 z" fill="url(#W)" filter="url(#X)"/>
<rect id="7" width="26.652" height="42.516" x="52.03" y="41.28" transform="matrix(2.0986114,0,0,0.88510731,-75.645463,4.7769901)" filter="url(#f)"/>
<rect transform="matrix(2.1905454,0,0,0.83797185,-82.955778,8.7656631)" y="41.28" x="52.03" height="42.516" width="26.652" id="8" filter="url(#f)"/>
<rect id="9" width="26.652" height="42.516" x="52.03" y="41.28" transform="matrix(2.0066774,0,0,0.82618798,-65.211739,15.098658)" filter="url(#f)"/>
<rect transform="matrix(2.1721586,0,0,0.76137672,-73.685188,17.719957)" y="41.28" x="52.03" height="42.516" width="26.652" id="A" filter="url(#f)"/>
<path d="m 32.34375,41.1875 c -1.076646,0 -1.9375,0.860854 -1.9375,1.9375 l 0,34.65625 6.90625,6.75 58.75,0 c 1.076646,0 1.9375,-0.860854 1.9375,-1.9375 L 98.048358,49.101925 90.085781,41.323994 32.34375,41.1875 z" id="B" fill="#eee"/>
<path d="M 33.0625 43.84375 L 33.0625 80.375 L 34.59375 81.875 L 95.34375 81.875 L 95.34375 46.53125 L 92.5625 43.84375 L 33.0625 43.84375 z " id="C" fill="#6193cf"/>
<path d="M 47.53125 43.84375 L 36.9375 46.5625 L 36.46875 46.46875 L 36.75 46.625 L 36.375 46.71875 L 36.96875 46.75 L 37.09375 46.9375 L 38.4375 81.875 L 48.65625 81.875 L 37.21875 47.09375 L 60.84375 81.875 L 79.34375 81.875 L 37.28125 46.9375 L 95.34375 78.375 L 95.34375 59.4375 L 37.78125 46.75 L 95.34375 48.40625 L 95.34375 46.53125 L 92.5625 43.84375 L 47.53125 43.84375 z M 36.53125 46.90625 L 33.0625 53.15625 L 33.0625 62 L 36.53125 46.90625 z " id="D" fill="#7ca6d7"/>
<path d="m 33.04788,43.858213 0,7.84375 c 1.05358,0.726143 2.34487,1.15625 3.75,1.15625 3.51981,0 6.375,-2.682059 6.375,-6 0,-1.090212 -0.3052,-2.118572 -0.84375,-3 l -9.28125,0 z" id="E" fill="#ffeb55"/>
<path d="M 55.46875 73.53125 C 48.50349 73.48457 41.0516 73.995119 33.0625 75.53125 L 33.0625 80.375 L 34.59375 81.875 L 95.34375 81.875 L 95.34375 76.34375 C 83.78958 76.33405 70.77338 73.633828 55.46875 73.53125 z " id="F" fill="url(#V)"/>
<path d="m 89.674152,41.523199 7.912589,7.633977" id="G" opacity="0.717" fill="none" filter="url(#b)" stroke="url(#a)"/>
<path id="H" d="m 29.757691,77.408792 7.912589,7.633977" opacity="0.575" fill="none" filter="url(#b)" stroke="url(#c)"/>
<path d="m 89.67563,40.948711 9.02517,8.64112 1.024133,-1.152149 -9.473229,-8.449096 -0.576074,0.960125 z" id="I" fill="url(#d)"/>
<path d="m 29.536537,77.039758 8.938689,8.55005 -8.79295,-0.291479 -0.145739,-8.258571 z" id="J" stroke-opacity="0.908" fill="url(#e)" stroke-linejoin="round" stroke-linecap="round" stroke-width="3"/>
<text x="63.743" y="109.94" id="K" fill="#555" font-family="Jigsaw Trouserdrop" text-anchor="middle" text-align="center" line-height="125%" font-size="40"><tspan id="g" x="63.743" y="109.94" font-family="Liberation Sans" text-align="center" line-height="125%" font-weight="bold" font-size="18">IMAGE</tspan>
</text>
</svg>

After

Width:  |  Height:  |  Size: 7.4 KiB

753
res/icons/pillar.svg Normal file
View File

@@ -0,0 +1,753 @@
<?xml version="1.0"?>
<svg
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:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:ns1="http://sozi.baierouge.fr"
id="svg3382"
viewBox="0 0 300.18 644.05"
version="1.1"
>
<defs
id="defs3384"
>
<radialGradient
id="radialGradient4328"
gradientUnits="userSpaceOnUse"
cy="209.49"
cx="203.65"
gradientTransform="matrix(1.1806 0 0 1.2225 -36.777 -46.607)"
r="27.577"
>
<stop
id="stop4241"
stop-color="#FFF"
offset="0"
/>
<stop
id="stop4243"
stop-color="#CCC"
offset="1"
/>
</radialGradient
>
<filter
id="filter4319"
width="1.2128"
y="-.10638"
x="-.10638"
height="1.2128"
color-interpolation-filters="sRGB"
>
<feGaussianBlur
id="feGaussianBlur4321"
stdDeviation="2.9560062"
/>
</filter
>
<clipPath
id="clipPath4178"
clipPathUnits="userSpaceOnUse"
>
<path
id="path4180"
opacity=".51439"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
fill="#333"
d="m472.23 56.05c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-11.873-33.84-29.875-34.563-14.494-0.58199-28.334 10.403-28.562 25.625-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 19.624 7.6077 18.837 21.128-0.97088 16.669-16.998 22.229-33.398 21.05-19.664-1.4133 39.81 10.246 41.407-9.1113 1.8071-21.901-20.989-16.617 0.70342-15.68 1.584 0.0676-13.519-39.38-13.423-40.962l0.0625-4.0201c0.10086-1.624-10.875-1.3411-12.501-1.4044z"
/>
</clipPath
>
<filter
id="filter10847"
color-interpolation-filters="sRGB"
>
<feGaussianBlur
id="feGaussianBlur10849"
stdDeviation="2.7227669"
/>
</filter
>
<clipPath
id="clipPath4174"
clipPathUnits="userSpaceOnUse"
>
<path
id="path4176"
opacity=".51439"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
fill="#333"
d="m469.17 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-11.873-33.84-29.875-34.562-14.494-0.58199-28.334 10.403-28.562 25.625-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 19.624 7.6077 18.837 21.128-0.97088 16.669-16.998 22.229-33.398 21.05-19.664-1.4133 39.81 10.246 41.407-9.1113 1.8071-21.901-20.989-16.617 0.70342-15.68 1.584 0.0676-13.519-39.38-13.423-40.962l0.0625-4.0201c0.10086-1.624-10.875-1.3411-12.501-1.4044z"
/>
</clipPath
>
<filter
id="filter10867"
color-interpolation-filters="sRGB"
>
<feGaussianBlur
id="feGaussianBlur10869"
stdDeviation="2.2608041"
/>
</filter
>
<clipPath
id="clipPath4170"
clipPathUnits="userSpaceOnUse"
>
<path
id="path4172"
opacity=".51439"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
fill="#333"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-11.873-33.84-29.875-34.562-14.494-0.58199-28.334 10.403-28.562 25.625-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 19.624 7.6077 18.837 21.128-0.97088 16.669-16.998 22.229-33.398 21.05-19.664-1.4133 39.81 10.246 41.407-9.1113 1.8071-21.901-20.989-16.617 0.70342-15.68 1.584 0.0676-13.519-39.38-13.423-40.962l0.0625-4.0201c0.10086-1.624-10.875-1.3411-12.501-1.4044z"
/>
</clipPath
>
<filter
id="filter3996"
width="1.0907"
y="-.92139"
x="-.045325"
height="2.8428"
color-interpolation-filters="sRGB"
>
<feGaussianBlur
id="feGaussianBlur3998"
stdDeviation="3.1496171"
/>
</filter
>
<filter
id="filter4113"
width="1.0937"
y="-85.061"
x="-.046834"
height="171.12"
color-interpolation-filters="sRGB"
>
<feGaussianBlur
id="feGaussianBlur4115"
stdDeviation="2.5589068"
/>
</filter
>
<linearGradient
id="linearGradient4101"
y2="721.54"
xlink:href="#linearGradient4024"
gradientUnits="userSpaceOnUse"
x2="201.71"
gradientTransform="matrix(-1 0 0 -1 570.66 991.98)"
y1="704.86"
x1="201.71"
/>
<linearGradient
id="linearGradient4024"
>
<stop
id="stop4026"
stop-color="#CCC"
offset="0"
/>
<stop
id="stop4034"
stop-color="#f1f1f1"
offset=".2394"
/>
<stop
id="stop4032"
stop-color="#f2f2f2"
offset=".64835"
/>
<stop
id="stop4028"
stop-color="#dbdbdb"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient4099"
y2="702.22"
xlink:href="#linearGradient3865"
gradientUnits="userSpaceOnUse"
x2="282.26"
gradientTransform="matrix(1 0 0 .625 -569.48 -732.6)"
y1="702.22"
x1="116.21"
/>
<linearGradient
id="linearGradient3865"
>
<stop
id="stop3867"
stop-color="#e6e6e6"
offset="0"
/>
<stop
id="stop3873"
stop-color="#f2f2f2"
offset=".5"
/>
<stop
id="stop3869"
stop-color="#e6e6e6"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient4030"
y2="721.54"
xlink:href="#linearGradient4024"
gradientUnits="userSpaceOnUse"
x2="201.71"
gradientTransform="translate(172.19 46.759)"
y1="704.86"
x1="201.71"
/>
<linearGradient
id="linearGradient4011"
y2="702.22"
xlink:href="#linearGradient3865"
gradientUnits="userSpaceOnUse"
x2="282.26"
gradientTransform="matrix(1 0 0 .625 172.19 306.14)"
y1="702.22"
x1="116.21"
/>
<linearGradient
id="linearGradient4091"
y2="471.14"
xlink:href="#linearGradient3811"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(-576.62 46.759)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3811"
>
<stop
id="stop3813"
stop-color="#b3b3b3"
offset="0"
/>
<stop
id="stop3815"
stop-color="#e6e6e6"
offset=".56701"
/>
<stop
id="stop3817"
stop-color="#e6e6e6"
offset=".84064"
/>
<stop
id="stop3819"
stop-color="#b3b3b3"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient4093"
y2="471.14"
xlink:href="#linearGradient3821"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(-546 46.759)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3821"
>
<stop
id="stop3823"
stop-color="#b3b3b3"
offset="0"
/>
<stop
id="stop3825"
stop-color="#e6e6e6"
offset=".43083"
/>
<stop
id="stop3827"
stop-color="#e6e6e6"
offset=".74779"
/>
<stop
id="stop3829"
stop-color="#b3b3b3"
offset="1"
/>
</linearGradient
>
<linearGradient
id="linearGradient4238"
y2="471.14"
xlink:href="#linearGradient3821"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(196.86 46.759)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient4241"
y2="471.14"
xlink:href="#linearGradient3811"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(166.24 46.759)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3809"
y2="471.14"
xlink:href="#linearGradient3811"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(-8.3462)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3857"
y2="471.14"
xlink:href="#linearGradient3821"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(22.271)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3855"
y2="471.14"
xlink:href="#linearGradient3811"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(-402.03)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3852"
y2="471.14"
xlink:href="#linearGradient3821"
gradientUnits="userSpaceOnUse"
x2="152.88"
gradientTransform="translate(-371.41)"
y1="471.14"
x1="165.43"
/>
<linearGradient
id="linearGradient3380"
y2="471.14"
xlink:href="#linearGradient3865"
gradientUnits="userSpaceOnUse"
y1="471.14"
gradientTransform="translate(172.19 46.759)"
x2="264.79"
x1="133.68"
/>
</defs
>
<g
id="layer1"
transform="translate(-221.34 -158.91)"
>
<rect
id="rect2985"
fill-rule="evenodd"
rx="0"
ry="0"
height="441.07"
width="131.11"
y="297.37"
x="305.87"
fill="url(#linearGradient3380)"
/>
<g
id="g3859"
fill-rule="evenodd"
transform="translate(174.59 46.759)"
>
<rect
id="rect3757"
rx="3.1024"
ry="10.645"
height="441.07"
width="12.504"
y="250.61"
x="144.66"
fill="url(#linearGradient3809)"
/>
<rect
id="rect3773"
rx="3.1024"
ry="10.645"
height="441.07"
width="12.504"
y="250.61"
x="175.28"
fill="url(#linearGradient3857)"
/>
<rect
id="rect3831"
ry="10.645"
rx="3.1024"
transform="scale(-1,1)"
height="441.07"
width="12.504"
y="250.61"
x="-249.02"
fill="url(#linearGradient3855)"
/>
<rect
id="rect3833"
ry="10.645"
rx="3.1024"
transform="scale(-1,1)"
height="441.07"
width="12.504"
y="250.61"
x="-218.4"
fill="url(#linearGradient3852)"
/>
</g
>
<rect
id="rect4133"
fill-rule="evenodd"
height="34.57"
width="220.04"
y="768.39"
x="261.66"
fill="#f2f2f2"
/>
<rect
id="rect4173"
fill-rule="evenodd"
rx="3.1024"
ry="10.645"
height="441.07"
width="12.504"
y="297.37"
x="319.25"
fill="url(#linearGradient4241)"
/>
<rect
id="rect4175"
fill-rule="evenodd"
rx="3.1024"
ry="10.645"
height="441.07"
width="12.504"
y="297.37"
x="349.87"
fill="url(#linearGradient4238)"
/>
<rect
id="rect4177"
ry="10.645"
fill-rule="evenodd"
rx="3.1024"
transform="scale(-1,1)"
height="441.07"
width="12.504"
y="297.37"
x="-423.61"
fill="url(#linearGradient4091)"
/>
<rect
id="rect4179"
ry="10.645"
fill-rule="evenodd"
rx="3.1024"
transform="scale(-1,1)"
height="441.07"
width="12.504"
y="297.37"
x="-392.99"
fill="url(#linearGradient4093)"
/>
<rect
id="rect10747"
transform="scale(-1,1)"
fill-rule="evenodd"
rx="3.1024"
ry="10.645"
height="441.07"
width="12.504"
y="297.37"
x="-423.61"
fill="url(#linearGradient4091)"
/>
<path
id="path4117"
d="m305.62 738.51 131.13-0.0722"
filter="url(#filter4113)"
stroke="#000"
stroke-width="1px"
fill="none"
/>
<rect
id="rect4003"
fill-rule="evenodd"
ry="6.5891"
height="13.178"
width="166.05"
y="738.44"
x="288.41"
fill="url(#linearGradient4011)"
/>
<path
id="rect4013"
d="m298.12 751.62h146.61s-5.5 6.1177 0.375 11.137c5.875 5.0189 9.342 5.6366 9.342 5.6366l-166.05-0.00001s0.485-0.64878 7.9096-5.6374 1.8125-11.136 1.8125-11.136z"
fill="url(#linearGradient4030)"
fill-rule="evenodd"
/>
<path
id="path4103"
d="m305.87 300.37 131.13-0.0722"
filter="url(#filter4113)"
stroke="#000"
stroke-width="1px"
fill="none"
/>
<rect
id="rect4095"
transform="scale(-1)"
fill-rule="evenodd"
ry="6.5891"
height="13.178"
width="166.05"
y="-300.3"
x="-453.27"
fill="url(#linearGradient4099)"
/>
<path
id="path4097"
d="m444.73 287.12h-146.61s5.5-6.1177-0.375-11.137c-5.875-5.0189-9.342-5.6366-9.342-5.6366l166.05 0.00001s-0.485 0.64878-7.9096 5.6374-1.8125 11.136-1.8125 11.136z"
fill="url(#linearGradient4101)"
fill-rule="evenodd"
/>
<path
id="path4332"
d="m306.62 275.71 131.13-0.0722"
filter="url(#filter4113)"
stroke="#000"
stroke-width="1px"
fill="none"
/>
<path
id="rect4221"
d="m226.21 212.96 14.159-31.822 38.532-18.096 176.32 1.3038 38.604 16.139 22.546 40.558-6.4918 29.859-17.492 24.612-235.94 0.30278-28.285-30.495z"
fill="#e6e6e6"
fill-rule="evenodd"
/>
<path
id="path3985"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m457.07 52.487c-25.4-1.097-140.26-1.613-162.83-0.298 2.1188 1.0912-2.0799 7.4488-2.5298 5.1085 17.65 0.1962 141.9 0.12749 163.59 1.0644 4.5318-0.18264 5.3142-5.6141 1.7718-5.8742z"
transform="matrix(1.0536 0 0 .60052 -24.475 135.78)"
filter="url(#filter3996)"
fill="#BBB"
/>
<g
id="g4182"
transform="matrix(1.2991 0 0 1.2991 -238.81 66.092)"
>
<path
id="path3127"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-27.346-29.622-29.994-29.622-13.226 0-28.216 5.4627-28.444 20.685-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156 1.584 0.0676 3.0919-1.2924 3.1875-2.875l0.0625-1c0.10085-1.624-1.3116-3.1867-2.9375-3.25z"
clip-path="url(#clipPath4178)"
transform="matrix(1.0536 0 0 1.0536 -89.357 12.436)"
filter="url(#filter10847)"
fill="#BBB"
/>
<path
id="path4121"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-28.823-33.561-30.671-33.561-14.506 0-27.539 9.401-27.767 24.623-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156 1.584 0.0676 0.12584-1.2924 0.22146-2.875l0.0625-1c0.10085-1.624 1.6544-3.1867 0.0285-3.25z"
clip-path="url(#clipPath4174)"
transform="matrix(1.0536 0 0 1.0536 -86.127 12.456)"
filter="url(#filter10867)"
fill="#BBB"
/>
<path
id="path4125"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-11.873-33.84-29.875-34.562-14.494-0.58199-28.334 10.403-28.562 25.625-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312a3.0625 3.0625 0 0 0 -2.375 3.5625l0.1875 1a3.0625 3.0625 0 0 0 3.625 2.4375c1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156a3.0625 3.0625 0 0 0 3.1875 -2.875l0.0625-1a3.0625 3.0625 0 0 0 -2.9375 -3.25z"
clip-path="url(#clipPath4170)"
transform="matrix(1.0536 0 0 1.0536 -87.665 12.456)"
fill="#f2f2f2"
/>
</g
>
<g
id="g4187"
transform="matrix(-1.2991 0 0 1.2991 981.67 66.092)"
>
<path
id="path4189"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-27.346-29.622-29.994-29.622-13.226 0-28.216 5.4627-28.444 20.685-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156 1.584 0.0676 3.0919-1.2924 3.1875-2.875l0.0625-1c0.10085-1.624-1.3116-3.1867-2.9375-3.25z"
clip-path="url(#clipPath4178)"
transform="matrix(1.0536 0 0 1.0536 -89.357 12.436)"
filter="url(#filter10847)"
fill="#BBB"
/>
<path
id="path4191"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-28.823-33.561-30.671-33.561-14.506 0-27.539 9.401-27.767 24.623-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312-1.546 0.3275-2.6673 2.0094-2.375 3.5625l0.1875 1c0.29786 1.5936 2.0368 2.7629 3.625 2.4375 1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156 1.584 0.0676 0.12584-1.2924 0.22146-2.875l0.0625-1c0.10085-1.624 1.6544-3.1867 0.0285-3.25z"
clip-path="url(#clipPath4174)"
transform="matrix(1.0536 0 0 1.0536 -86.127 12.456)"
filter="url(#filter10867)"
fill="#BBB"
/>
<path
id="path4193"
style="block-progression:tb;color:#000000;text-transform:none;text-indent:0"
d="m470.62 56.031c-25.407-1.0974-48.956 17.774-51.094 43.688-1.9119 23.171 15.045 45.318 38.875 47.031 20.196 1.4516 39.472-13.408 40.688-34.281 1.0078-17.303-11.873-33.84-29.875-34.562-14.494-0.58199-28.334 10.403-28.562 25.625-0.17655 11.787 8.9789 23.032 21.531 22.75 9.1862-0.20623 18.06-7.6345 17.219-17.656-0.28271-3.3674-1.8434-6.5281-4.2812-8.8438-2.4453-2.3228-6.0679-3.8198-9.9375-3.0312a3.0625 3.0625 0 0 0 -2.375 3.5625l0.1875 1a3.0625 3.0625 0 0 0 3.625 2.4375c1.4246-0.29032 2.5071 0.12559 3.625 1.1875 1.0945 1.0397 1.9052 2.7803 2.0312 4.2812 0.45617 5.4336-4.781 9.8147-10.25 9.9375-8.1309 0.18253-14.37-7.4976-14.25-15.531 0.16316-10.893 10.433-19.024 21.156-18.594 13.743 0.55183 23.819 13.48 23.031 27-0.97088 16.669-16.663 28.772-33.062 27.594-19.664-1.4133-33.847-19.955-32.25-39.312 1.8071-21.901 21.964-38.093 43.656-37.156a3.0625 3.0625 0 0 0 3.1875 -2.875l0.0625-1a3.0625 3.0625 0 0 0 -2.9375 -3.25z"
clip-path="url(#clipPath4170)"
transform="matrix(1.0536 0 0 1.0536 -87.665 12.456)"
fill="#f2f2f2"
/>
</g
>
<rect
id="rect3951"
fill-rule="evenodd"
height="9.618"
width="169.74"
y="158.96"
x="288.14"
fill="#f2f2f2"
/>
<g
id="g4323"
fill-rule="evenodd"
transform="translate(-47.728 20.121)"
>
<path
id="path4247"
fill="#999"
d="m419.16 174.38c-19.4 0-35.125 15.725-35.125 35.125s15.725 35.125 35.125 35.125 35.125-15.725 35.125-35.125-15.725-35.125-35.125-35.125zm0 12.5c12.497 0 22.625 10.128 22.625 22.625s-10.128 22.625-22.625 22.625-22.625-10.128-22.625-22.625 10.128-22.625 22.625-22.625z"
/>
<path
id="path4252"
d="m231.22 209.49c0 15.23-12.347 27.577-27.577 27.577s-27.577-12.347-27.577-27.577 12.347-27.577 27.577-27.577 27.577 12.347 27.577 27.577z"
fill="url(#radialGradient4328)"
transform="matrix(.83864 0 0 .83864 248.37 33.803)"
/>
<path
id="path4259"
filter="url(#filter4319)"
d="m419.16 176.16c-18.446 0-33.344 14.898-33.344 33.344s14.898 33.344 33.344 33.344 33.344-14.898 33.344-33.344-14.898-33.344-33.344-33.344zm0 8.9375c13.451 0 24.406 10.955 24.406 24.406s-10.955 24.406-24.406 24.406-24.406-10.955-24.406-24.406 10.955-24.406 24.406-24.406z"
fill="#FFF"
/>
</g
>
</g
>
<metadata
>
<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
>
<dc:title
>Antique pillar</dc:title
>
<dc:date
>2013-05-08T10:46:42</dc:date
>
<dc:description
>antique, pillar</dc:description
>
<dc:source
>https://openclipart.org/detail/177883/antique-pillar-by-lfidnl-177883</dc:source
>
<dc:creator
>
<cc:Agent
>
<dc:title
>LFIdnl</dc:title
>
</cc:Agent
>
</dc:creator
>
<dc:subject
>
<rdf:Bag
>
<rdf:li
>antique</rdf:li
>
<rdf:li
>pillar</rdf:li
>
</rdf:Bag
>
</dc:subject
>
</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: 27 KiB

233
res/icons/polygon.svg Normal file
View File

@@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="polygone.svg"
inkscape:export-filename="C:\Users\Danilo\Desktop\polygon.png"
inkscape:export-xdpi="320"
inkscape:export-ydpi="320">
<defs
id="defs4">
<linearGradient
id="linearGradient3892">
<stop
id="stop3894"
offset="0"
style="stop-color:#294bd4;stop-opacity:0.17857143;" />
<stop
id="stop3896"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3892"
id="linearGradient3890"
x1="1.4782338"
y1="28.013315"
x2="62.164814"
y2="28.013315"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.9195959"
inkscape:cx="8.0824225"
inkscape:cy="34.133293"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="737"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-988.36218)">
<path
style="fill:url(#linearGradient3890);stroke:#1c80f6;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
d="M 5.42957,44.302025 1.9782338,20.812517 8.0812203,9.1992238 28.284271,3.1383098 42.426406,12.355951 54.548237,13.997449 61.664814,32.438502 57.326157,52.888322 39.017142,43.796949 20.118051,51.599326 22.761856,46.465813 5.555839,44.428295"
id="path3054"
inkscape:connector-curvature="0"
transform="translate(0,988.36218)"
sodipodi:nodetypes="cccccccccccc" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,14.247038,1034.1719)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-2"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,16.014805,1028.7424)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-3"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,-0.40017389,1026.8483)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-24"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,-3.9357078,1003.7411)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-6"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,1.367593,992.37683)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-66"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,21.696913,985.81084)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-29"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,35.839048,995.02848)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-0"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,47.708341,996.9225)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-4"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,55.158216,1015.6103)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-9"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,50.48626,1035.4346)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
<path
sodipodi:type="arc"
style="fill:#10e0e7;fill-opacity:1;stroke:#000000;stroke-width:1.64271903;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.70000005;stroke-opacity:0.87134507;stroke-dasharray:none;stroke-dashoffset:0"
id="path5211-8-4-31"
sodipodi:cx="12.753176"
sodipodi:cy="14.313122"
sodipodi:rx="3.7249374"
sodipodi:ry="4.7350903"
d="m 9.758726,11.496811 a 3.7249374,4.7350903 0 1 1 -0.00986,0.01703"
transform="matrix(0.51652697,0,0,0.40633473,32.682322,1026.9745)"
sodipodi:start="3.7785777"
sodipodi:end="10.057297"
sodipodi:open="true" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
res/icons/polygon16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

BIN
res/icons/polygon32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

117
res/icons/wall.svg Normal file
View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg 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:svg="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:ns1="http://sozi.baierouge.fr" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg2" viewBox="0 0 271.02 309.62" version="1.1" inkscape:version="0.91 r13725">
<g id="g3542" transform="translate(-25.674 -14.91)">
<g id="g7986" transform="matrix(-.11758 .20365 .20365 .11758 482.75 214.33)">
<rect id="use5590-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="704.27" x="971.47"/>
<rect id="use5592-0" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="784.5" x="1087.5"/>
<rect id="use5606-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="543.82" x="971.47"/>
<rect id="use5608-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="624.05" x="1087.5"/>
<rect id="use5610-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="704.27" x="1203.5"/>
<rect id="use5612-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="784.5" x="1319.5"/>
<rect id="use5622-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="383.36" x="971.47"/>
<rect id="use5624-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="463.59" x="1087.5"/>
<rect id="use5626-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="543.82" x="1203.5"/>
<rect id="use5628-7" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="624.05" x="1319.5"/>
<rect id="use5630-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="704.27" x="1435.5"/>
<rect id="use5632-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="784.5" x="1551.5"/>
<rect id="use5638-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="222.9" x="971.47"/>
<rect id="use5640-7" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="303.13" x="1087.5"/>
<rect id="use5642-6" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="383.36" x="1203.5"/>
<rect id="use5644-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="463.59" x="1319.5"/>
<rect id="use5646-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="543.82" x="1435.5"/>
<rect id="use5648-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="624.05" x="1551.5"/>
<rect id="use5650-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="704.27" x="1667.5"/>
<rect id="use5652-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="784.5" x="1783.5"/>
<rect id="use5654-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="62.446" x="971.47"/>
<rect id="use5656-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="142.67" x="1087.5"/>
<rect id="use5658-6" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="222.9" x="1203.5"/>
<rect id="use5660-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="303.13" x="1319.5"/>
<rect id="use5662-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="383.36" x="1435.5"/>
<rect id="use5664-7" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="463.59" x="1551.5"/>
<rect id="use5666-6" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="543.82" x="1667.5"/>
<rect id="use5668-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="624.05" x="1783.5"/>
<rect id="use5670-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="704.27" x="1899.5"/>
<rect id="use5674-9" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="62.446" x="1203.5"/>
<rect id="use5676-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="142.67" x="1319.5"/>
<rect id="use5678-7" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="222.9" x="1435.5"/>
<rect id="use5680-9" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="303.13" x="1551.5"/>
<rect id="use5682-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="383.36" x="1667.5"/>
<rect id="use5684-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="463.59" x="1783.5"/>
<rect id="use5686-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="543.82" x="1899.5"/>
<rect id="use5694-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="62.446" x="1435.5"/>
<rect id="use5696-2" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="142.67" x="1551.5"/>
<rect id="use5698-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="222.9" x="1667.5"/>
<rect id="use5700-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="303.13" x="1783.5"/>
<rect id="use5702-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="383.36" x="1899.5"/>
<rect id="use5714-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="62.446" x="1667.5"/>
<rect id="use5716-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="142.67" x="1783.5"/>
<rect id="use5718-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="222.9" x="1899.5"/>
<rect id="use5734-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="223.08" y="62.446" x="1899.5"/>
<rect id="use5554-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.45" y="784.81" x="2015.1"/>
<rect id="use5554-5-8" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="624.07" x="2015.1"/>
<rect id="use5554-5-4" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="463.62" x="2015.1"/>
<rect id="use5554-5-4-0" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="303.37" x="2015.1"/>
<rect id="use5554-5-4-7" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="142.62" x="2015.1"/>
<rect id="use5554-5-6" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.45" y="784.65" x="971.5"/>
<rect id="use5554-5-8-3" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="623.91" x="971.47"/>
<rect id="use5554-5-4-6" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="463.46" x="971.47"/>
<rect id="use5554-5-4-0-1" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="303.21" x="971.47"/>
<rect id="use5554-5-4-7-5" style="fill:#cc0000" transform="matrix(.10991 -.99394 .86603 0.5 0 0)" height="74.286" width="107.48" y="142.46" x="971.47"/>
</g>
<g id="g3460">
<rect id="use5554-5-42" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.809" y="-333.6" x="316.94"/>
<rect id="use5554-5-8-0" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-371.4" x="316.94"/>
<rect id="use5554-5-4-9" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-409.13" x="316.94"/>
<rect id="use5554-5-4-0-7" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-446.81" x="316.94"/>
<rect id="use5554-5-4-7-3" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-484.61" x="316.94"/>
<rect id="use5554-5-42-5" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.809" y="-314.79" x="316.96"/>
<rect id="use5554-5-8-0-7" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-352.59" x="316.95"/>
<rect id="use5554-5-4-9-5" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-390.32" x="316.95"/>
<rect id="use5554-5-4-0-7-4" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-428" x="316.95"/>
<rect id="use5554-5-4-7-3-1" style="fill:#8f0000" transform="matrix(.86307 -.50509 0 -1 0 0)" height="17.469" width="26.816" y="-465.8" x="316.95"/>
</g>
<g id="g3266" transform="matrix(-1 0 0 1 322.45 0)">
<path id="use5636-5-2" style="fill:#ff0000" d="m25.753 123.67 48.039-21.076 23.142 13.561-48.039 21.076z"/>
<path id="use5636-5-2-07" style="fill:#ff0000" d="m75.714 101.75 48.036-21.08 23.15 13.561-48.044 21.079z"/>
<path id="use5636-5-2-7" style="fill:#ff0000" d="m125.68 79.844 48.039-21.076 23.143 13.561-48.039 21.076z"/>
<path id="use5636-5-2-3" style="fill:#ff0000" d="m175.63 57.906 48.04-21.076 23.15 13.562-48.04 21.076z"/>
<path id="use5636-5-2-9" style="fill:#ff0000" d="m225.59 35.986 48.039-21.076 23.143 13.561-48.039 21.076z"/>
</g>
</g>
<metadata>
<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>
<dc:title>wall 2</dc:title>
<dc:date>2013-01-21T11:03:01</dc:date>
<dc:description/>
<dc:source>https://openclipart.org/detail/174369/wall-2-by-jarda-174369</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>jarda</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>brick</rdf:li>
<rdf:li>bricks</rdf:li>
<rdf:li>wall</rdf:li>
</rdf:Bag>
</dc:subject>
</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: 12 KiB

126
res/icons/wifi.svg Normal file
View File

@@ -0,0 +1,126 @@
<?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="svg4427"
inkscape:version="0.91pre3 r13670"
viewBox="0 0 614.15501 507.70723"
version="1.1"
sodipodi:docname="_svgclean2.svg"
>
<sodipodi:namedview
id="base"
bordercolor="#666666"
inkscape:pageshadow="2"
inkscape:window-y="0"
pagecolor="#ffffff"
inkscape:zoom="0.35"
inkscape:window-width="799"
inkscape:window-maximized="0"
inkscape:window-x="0"
showgrid="false"
borderopacity="1.0"
inkscape:current-layer="layer1"
inkscape:cx="319.22"
inkscape:cy="256.67216"
inkscape:window-height="645"
inkscape:pageopacity="0.0"
inkscape:document-units="px"
/>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
transform="translate(-55.78 -281.36)"
>
<path
id="path4391"
d="m362.47 399.37c-80.452 0.30312-160.77 30.425-222.31 90.281l55.906 55.281c92.256-89.611 240.75-90.142 333.66-1.1562l55.781-55.813c-62.02-59.38-142.59-88.89-223.04-88.59zm-166.41 145.56-0.125 0.0937z"
sodipodi:nodetypes="cccccccccc"
style="color:#000000;fill:#000000"
inkscape:connector-curvature="0"
/>
<path
id="path4395"
d="m362.37 281.37c-110.95 0.41801-221.72 41.957-306.59 124.5l55.469 54.844c138.94-134.56 362.26-135.24 502.03-1.375l56.656-55.781c-85.52-81.9-196.62-122.6-307.57-122.19zm-251.12 179.34-0.5625 0.53125z"
sodipodi:nodetypes="sccccsccc"
style="color:#000000;fill:#000000"
inkscape:connector-curvature="0"
/>
<path
id="path4381"
d="m362.34 516.87c-50.088 0.18872-100.12 18.953-138.44 56.219l53.438 52.812c47.181-45.821 123.11-46.068 170.62-0.5625l53.219-53.312c-38.607-36.975-88.756-55.345-138.84-55.156zm-85 109.03-0.063 0.0625z"
sodipodi:nodetypes="cccccccccc"
style="color:#000000;fill:#000000"
inkscape:connector-curvature="0"
/>
<path
id="path4411"
sodipodi:rx="78.5"
sodipodi:ry="78.5"
style="color:#000000;fill:#000000"
sodipodi:type="arc"
d="m780.99 634.37a78.5 78.5 0 0 1 -0.0574 -110.96 78.5 78.5 0 0 1 110.96 -0.17211 78.5 78.5 0 0 1 0.28684 110.96 78.5 78.5 0 0 1 -110.96 0.40159l55.28-55.74z"
transform="translate(-473.55,131.71)"
sodipodi:cy="578.86218"
sodipodi:cx="836.5"
sodipodi:end="2.3520582"
sodipodi:start="2.3561945"
/>
</g
>
<metadata
id="metadata9"
>
<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: 3.9 KiB

0
tree/MapTreeModel.cpp Normal file
View File

120
tree/MapTreeModel.h Normal file
View File

@@ -0,0 +1,120 @@
#ifndef MAPTREE_H
#define MAPTREE_H
#include <QAbstractItemModel>
#include "../mapview/model/MapModel.h"
// http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
class MapTreeModel : public QAbstractItemModel {
Q_OBJECT
private:
MapModel* mdl;
public:
/** ctor */
MapTreeModel(MapModel* mdl) : mdl(mdl) {
connect(mdl, SIGNAL(reset()), this, SLOT(onMapModelReset()));
}
virtual ~MapTreeModel() {;}
virtual QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override {
MapLayer* _parent = nullptr;
if (!parent.isValid()) {
_parent = mdl->getRootLayer();
} else {
_parent = static_cast<MapLayer*>(parent.internalPointer());
}
return createIndex(row, column, _parent->getSubLayers().at(row));
}
virtual QModelIndex parent(const QModelIndex& child) const override {
MapLayer* _child = static_cast<MapLayer*>(child.internalPointer());
if (!_child) {return QModelIndex();}
return createIndex(0,0,_child->getParent());
}
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override {
// if (parent.column() > 0) {
// return 0;
// }
MapLayer* _parent = nullptr;
if (!parent.isValid()) { // root
_parent = mdl->getRootLayer();
} else { // deeper layer
_parent = static_cast<MapLayer*>(parent.internalPointer());
}
return _parent->getSubLayers().size();
}
virtual int columnCount(const QModelIndex& parent) const override {
if (!parent.isValid()) {
return 1; // root
} else {
return 1; // TODO
}
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override {
MapLayer* _elem = static_cast<MapLayer*>(index.internalPointer());
if (index.column() == 0) {
if (role == Qt::DisplayRole) {return _elem->getLayerName().c_str();}
if (role == Qt::CheckStateRole) {return _elem->isVisible() ? Qt::Checked : Qt::Unchecked;}
}
return QVariant();
}
Qt::ItemFlags flags(const QModelIndex &index) const override {
(void) index;
// each item is selectable, enable, and has an editable checkbox
int flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
return (Qt::ItemFlags) flags;
}
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override {
// checking / unchecking a layer (visibility)
if (role == Qt::CheckStateRole) {
MapLayer* _elem = static_cast<MapLayer*>(index.internalPointer());
_elem->setVisible( value != 0 );
return true;
}
return false;
}
public slots:
/** the underlying map-model has changed */
void onMapModelReset() {
//emit dataChanged(QModelIndex(), QModelIndex(-1));
//emit modelReset(QPrivateSignal());
endResetModel();
}
};
#endif // MAPTREE_H