split line(old) and wall(new)
added new walling started working on windows
This commit is contained in:
@@ -70,7 +70,8 @@ SOURCES += \
|
||||
mapview/2D/MV2DElementStair.cpp \
|
||||
mapview/2D/MV2DElementElevator.cpp \
|
||||
mapview/2D/MV2DElementFloorObstacleCircle.cpp \
|
||||
mapview/3D/floorplan/FloorplanRendererModel.cpp
|
||||
mapview/3D/floorplan/FloorplanRendererModel.cpp \
|
||||
mapview/2D/MV2DElementFloorObstacleWall.cpp
|
||||
|
||||
|
||||
HEADERS += MainWindow.h \
|
||||
@@ -204,7 +205,10 @@ HEADERS += MainWindow.h \
|
||||
mapview/model/MMFloorObstacleObject.h \
|
||||
mapview/3D/MV3DElementFloorObstacleObject.h \
|
||||
mapview/2D/tools/ToolNewObject.h \
|
||||
mapview/2D/tools/ToolNewPillar.h
|
||||
mapview/2D/tools/ToolNewPillar.h \
|
||||
mapview/model/MMFloorObstacleWall.h \
|
||||
mapview/2D/MV2DElementFloorObstacleWall.h \
|
||||
mapview/2D/tools/ToolNewLine.h
|
||||
|
||||
|
||||
FORMS += MainWindow.ui
|
||||
|
||||
@@ -127,7 +127,7 @@ MainController::MainController() {
|
||||
|
||||
//mapModel->load("/apps/paper/maps/museum/map43_svg.xml");
|
||||
//mapModel->load("/apps/paper/maps/shl/SHL45_nm.xml");
|
||||
mapModel->load("/apps/paper/maps/test/polyMergeTest2.xml");
|
||||
mapModel->load("/apps/paper/maps/test/doors1.xml");
|
||||
|
||||
//mapModel->load("/mnt/sdcard/SHL41_nm.xml");
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
MV2DElementFloorObstacleLine::MV2DElementFloorObstacleLine(Floorplan::Floor* f, Floorplan::FloorObstacleLine* fo) : f(f), fo(fo) {
|
||||
;
|
||||
}
|
||||
@@ -22,18 +23,18 @@ ClickDist MV2DElementFloorObstacleLine::getMinDistanceXY(const Point2 p) const {
|
||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||
}
|
||||
|
||||
bool isConnected(const Point2 p, const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fo) {
|
||||
const float delta = 0.001;
|
||||
for (const Floorplan::FloorObstacle* fo1 : f->obstacles) {
|
||||
if (fo1 == fo) {continue;}
|
||||
const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(fo1);
|
||||
if (line) {
|
||||
if (line->from.eq(p, delta)) {return true;}
|
||||
if (line->to.eq(p, delta)) {return true;}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//bool isConnected(const Point2 p, const Floorplan::Floor* f, const Floorplan::FloorObstacleLine* fo) {
|
||||
// const float delta = 0.001;
|
||||
// for (const Floorplan::FloorObstacle* fo1 : f->obstacles) {
|
||||
// if (fo1 == fo) {continue;}
|
||||
// const Floorplan::FloorObstacleLine* line = dynamic_cast<const Floorplan::FloorObstacleLine*>(fo1);
|
||||
// if (line) {
|
||||
// if (line->from.eq(p, delta)) {return true;}
|
||||
// if (line->to.eq(p, delta)) {return true;}
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
|
||||
void MV2DElementFloorObstacleLine::paint(Painter& p) {
|
||||
|
||||
@@ -47,22 +48,22 @@ void MV2DElementFloorObstacleLine::paint(Painter& p) {
|
||||
// draw the wall itself
|
||||
p.drawLine(fo->from, fo->to);
|
||||
|
||||
const bool c1 = isConnected(fo->from, f, fo);
|
||||
const bool c2 = isConnected(fo->to, f, fo);
|
||||
// const bool c1 = isConnected(fo->from, f, fo);
|
||||
// const bool c2 = isConnected(fo->to, f, fo);
|
||||
|
||||
// wall conencted to other walls?
|
||||
if (c1 || c2) {
|
||||
// // wall conencted to other walls?
|
||||
// if (c1 || c2) {
|
||||
|
||||
// QPen change is costly!
|
||||
QPen pp = p.getPen();
|
||||
pp.setCapStyle(Qt::RoundCap);
|
||||
p.setPen(pp);
|
||||
// // QPen change is costly!
|
||||
// QPen pp = p.getPen();
|
||||
// pp.setCapStyle(Qt::RoundCap);
|
||||
// p.setPen(pp);
|
||||
|
||||
// indicate connection with other wall
|
||||
if (c1) {p.drawDot(fo->from);}
|
||||
if (c2) {p.drawDot(fo->to);}
|
||||
// // indicate connection with other wall
|
||||
// if (c1) {p.drawDot(fo->from);}
|
||||
// if (c2) {p.drawDot(fo->to);}
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
// length info
|
||||
if (hasFocus()) {
|
||||
@@ -91,9 +92,11 @@ std::vector<MoveableNode> MV2DElementFloorObstacleLine::getMoveableNodes() const
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
|
||||
(void) v;
|
||||
if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;}
|
||||
if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;}
|
||||
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleLine::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
@@ -101,5 +104,3 @@ void MV2DElementFloorObstacleLine::onNodeMoved(MapView2D* v, const int userIdx,
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
292
mapview/2D/MV2DElementFloorObstacleWall.cpp
Normal file
292
mapview/2D/MV2DElementFloorObstacleWall.cpp
Normal file
@@ -0,0 +1,292 @@
|
||||
#include "MV2DElementFloorObstacleWall.h"
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include "MapViewElementHelper.h"
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void drawDoorSwing(const Floorplan::FloorObstacleWall* wall, const Floorplan::FloorObstacleWallDoor* door, Painter& p, QPen& pen) {
|
||||
|
||||
const float len = door->width;
|
||||
//const Point2 dir = line->to - line->from;
|
||||
Point2 start = door->getStart(wall);
|
||||
Point2 end = door->getEnd(wall);
|
||||
|
||||
// opening indicator
|
||||
float open = (+M_PI * 0.5);
|
||||
if (door->inOut) {open = -open;}
|
||||
if (door->leftRight) {open = -open;}
|
||||
|
||||
const float angle1 = std::atan2(end.y - start.y, end.x - start.x);
|
||||
const float angle2 = angle1 + open;
|
||||
|
||||
if (std::isnan(angle1)) {return;}
|
||||
if (std::isnan(angle2)) {return;}
|
||||
|
||||
const Point2 pOpen = Point2( std::cos(angle2) * len, std::sin(angle2) * len ) + start;
|
||||
|
||||
pen.setWidth(2); p.setPen(pen);
|
||||
p.drawLine(start, end);
|
||||
|
||||
pen.setWidth(1); p.setPen(pen);
|
||||
p.drawLine(start, pOpen);
|
||||
p.drawArc(start, door->width, angle1, open);
|
||||
|
||||
}
|
||||
|
||||
void drawDoorRevolve(const Floorplan::FloorObstacleWallDoor* door, Painter& p, QPen& pen) {
|
||||
|
||||
// const float angle_rad = std::atan2(fo->to.y-fo->from.y, fo->to.x-fo->from.x);
|
||||
|
||||
// // arcs
|
||||
// const Point2 cen = (fo->from + fo->to) / 2;
|
||||
// const float rad = (fo->to - fo->from).length() / 2;
|
||||
// p.drawArc(cen, rad, (40-90)/180.0f*M_PI+angle_rad, 100/180.0f*M_PI);
|
||||
// p.drawArc(cen, rad, (180+40-90)/180.0f*M_PI+angle_rad, 100/180.0f*M_PI);
|
||||
|
||||
// const int funAngle = (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() / 50) % 360;
|
||||
|
||||
// // inner spinner
|
||||
// int numDoors = 3;
|
||||
// for (int i = 0; i < numDoors; ++i) {
|
||||
// const int deg = 360 * i / numDoors + angle_rad*180.0f/M_PI + funAngle;
|
||||
// const float sx = std::cos(deg / 180.0f * M_PI);
|
||||
// const float sy = std::sin(deg / 180.0f * M_PI);
|
||||
// const Point2 dst = cen + Point2(sx,sy) * rad;
|
||||
// p.drawLine(cen, dst);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
void drawDoor(const Floorplan::FloorObstacleWall* line, const Floorplan::FloorObstacleWallDoor* door, Painter& p) {
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(QColor(0.5,0.5,0.5));
|
||||
pen.setStyle(Qt::PenStyle::DotLine);
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
|
||||
if (Floorplan::DoorType::SWING == door->type) {
|
||||
drawDoorSwing(line, door, p, pen);
|
||||
} else if (Floorplan::DoorType::REVOLVING == door->type) {
|
||||
drawDoorRevolve(door, p, pen);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void drawWindow(const Floorplan::FloorObstacleWall* wall, const Floorplan::FloorObstacleWallWindow* win, Painter& p) {
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(QColor(0.5,0.5,0.5));
|
||||
pen.setWidth(3);
|
||||
pen.setStyle(Qt::PenStyle::DotLine);
|
||||
p.setPenBrush(pen, Qt::NoBrush);
|
||||
|
||||
const Point2 p1 = win->getStart(wall);
|
||||
const Point2 p2 = win->getEnd(wall);
|
||||
|
||||
p.drawLine(p1, p2);
|
||||
|
||||
}
|
||||
|
||||
bool isConnected(const Point2 p, const Floorplan::Floor* f, const Floorplan::FloorObstacleWall* fo) {
|
||||
const float delta = 0.001;
|
||||
for (const Floorplan::FloorObstacle* fo1 : f->obstacles) {
|
||||
if (fo1 == fo) {continue;}
|
||||
const Floorplan::FloorObstacleWall* wall = dynamic_cast<const Floorplan::FloorObstacleWall*>(fo1);
|
||||
if (wall) {
|
||||
if (wall->from.eq(p, delta)) {return true;}
|
||||
if (wall->to.eq(p, delta)) {return true;}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MV2DElementFloorObstacleWall::MV2DElementFloorObstacleWall(Floorplan::Floor* f, Floorplan::FloorObstacleWall* fo) : f(f), fo(fo) {
|
||||
;
|
||||
}
|
||||
|
||||
BBox2 MV2DElementFloorObstacleWall::getBoundingBox() const {
|
||||
BBox2 bbox;
|
||||
bbox.add(fo->from);
|
||||
bbox.add(fo->to);
|
||||
return bbox;
|
||||
}
|
||||
|
||||
ClickDist MV2DElementFloorObstacleWall::getMinDistanceXY(const Point2 p) const {
|
||||
return MapElementHelper::getLineDistanceXY(fo->from, fo->to, p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MV2DElementFloorObstacleWall::paint(Painter& p) {
|
||||
|
||||
// convert wall's thickness from meter to pixels
|
||||
const float thickness_px = p.s.ms(fo->thickness_m);
|
||||
|
||||
// see notes within MapElementHelper!
|
||||
// lines only get thicker, but not longer!
|
||||
p.setPenBrush(MapElementHelper::getPen(fo->material, fo->type, hasFocus(), thickness_px), Qt::NoBrush);
|
||||
|
||||
// draw the wall itself
|
||||
|
||||
// sort all doors by position on the line
|
||||
std::vector<Floorplan::FloorObstacleWallDoor*> doors = fo->doors;
|
||||
auto comp = [] (const Floorplan::FloorObstacleWallDoor* d1, const Floorplan::FloorObstacleWallDoor* d2) {
|
||||
return d1->atLinePos < d2->atLinePos;
|
||||
};
|
||||
std::sort(doors.begin(), doors.end(), comp);
|
||||
|
||||
std::vector<Point2> pts;
|
||||
pts.push_back(fo->from);
|
||||
for (const Floorplan::FloorObstacleWallDoor* door : doors) {
|
||||
pts.push_back(door->getStart(fo));
|
||||
pts.push_back(door->getEnd(fo));
|
||||
}
|
||||
pts.push_back(fo->to);
|
||||
|
||||
for (size_t i = 0; i < pts.size(); i+=2) {
|
||||
p.drawLine(pts[i], pts[i+1]);
|
||||
}
|
||||
//p.drawLine(fo->from, fo->to);
|
||||
|
||||
const bool c1 = isConnected(fo->from, f, fo);
|
||||
const bool c2 = isConnected(fo->to, f, fo);
|
||||
|
||||
// wall conencted to other walls?
|
||||
if (c1 || c2) {
|
||||
|
||||
// QPen change is costly!
|
||||
QPen pp = p.getPen();
|
||||
pp.setCapStyle(Qt::RoundCap);
|
||||
p.setPen(pp);
|
||||
|
||||
// indicate connection with other wall
|
||||
if (c1) {p.drawDot(fo->from);}
|
||||
if (c2) {p.drawDot(fo->to);}
|
||||
|
||||
}
|
||||
|
||||
for (const Floorplan::FloorObstacleWallDoor* door : fo->doors) {
|
||||
drawDoor(fo, door, p);
|
||||
}
|
||||
|
||||
for (const Floorplan::FloorObstacleWallWindow* window : fo->windows) {
|
||||
drawWindow(fo, window, p);
|
||||
}
|
||||
|
||||
// length info
|
||||
if (hasFocus()) {
|
||||
|
||||
// obstacle length
|
||||
p.setPenBrush(Qt::black, Qt::NoBrush);
|
||||
p.drawLength(fo->from, fo->to, fo->from.getDistance(fo->to), thickness_px/2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleWall::onFocus() {
|
||||
;
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleWall::onUnfocus() {
|
||||
selectedUserIdx = -1; // clear selection
|
||||
}
|
||||
|
||||
std::vector<MoveableNode> MV2DElementFloorObstacleWall::getMoveableNodes() const {
|
||||
|
||||
std::vector<MoveableNode> nodes;
|
||||
nodes.push_back(MoveableNode(0, fo->from));
|
||||
nodes.push_back(MoveableNode(1, fo->to));
|
||||
|
||||
int cnt = 0;
|
||||
for (const Floorplan::FloorObstacleWallDoor* door : fo->doors) {
|
||||
const Point2 pos = fo->from + (fo->to - fo->from) * door->atLinePos;
|
||||
nodes.push_back(MoveableNode(cnt+1000, pos));
|
||||
++cnt;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (const Floorplan::FloorObstacleWallWindow* win : fo->windows) {
|
||||
const Point2 pos = fo->from + (fo->to - fo->from) * win->atLinePos;
|
||||
nodes.push_back(MoveableNode(cnt+2000, pos));
|
||||
++cnt;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
void MV2DElementFloorObstacleWall::onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
|
||||
(void) v;
|
||||
if (userIdx == 0) {fo->from.x = newPos.x; fo->from.y = newPos.y;}
|
||||
if (userIdx == 1) {fo->to.x = newPos.x; fo->to.y = newPos.y;}
|
||||
|
||||
Point2 perp = (fo->from - fo->to).perpendicular() * 100;
|
||||
Line2 l1(newPos-perp, newPos+perp);
|
||||
Line2 l2(fo->from, fo->to);
|
||||
|
||||
Point2 p;
|
||||
float u = 0;
|
||||
bool isects = intersects(l2, l1, true, p, &u);
|
||||
if (u < 0.1) {u = 0.1;}
|
||||
if (u > 0.9) {u = 0.9;}
|
||||
|
||||
if (userIdx >= 1000 && userIdx < 2000) {
|
||||
|
||||
Floorplan::FloorObstacleWallDoor* door = fo->doors[userIdx-1000];
|
||||
|
||||
if (isects) {
|
||||
door->atLinePos = u;
|
||||
}
|
||||
|
||||
} else if (userIdx >= 2000 && userIdx < 3000) {
|
||||
|
||||
Floorplan::FloorObstacleWallWindow* win = fo->windows[userIdx-2000];
|
||||
|
||||
if (isects) {
|
||||
win->atLinePos = u;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MV2DElementFloorObstacleWall::onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos) {
|
||||
(void) userIdx;
|
||||
(void) newPos;
|
||||
emit v->onElementChange(this);
|
||||
}
|
||||
|
||||
|
||||
bool MV2DElementFloorObstacleWall::keyPressEvent(MapView2D* v, QKeyEvent* e) {
|
||||
|
||||
if (e->key() == Qt::Key_D) {
|
||||
Floorplan::FloorObstacleWallDoor* door = new Floorplan::FloorObstacleWallDoor(Floorplan::DoorType::SWING, Floorplan::Material::WOOD, 0.5, 1.0, 2.1);
|
||||
fo->doors.push_back(door);
|
||||
return true;
|
||||
} else if (e->key() == Qt::Key_W) {
|
||||
Floorplan::FloorObstacleWallWindow* win = new Floorplan::FloorObstacleWallWindow(Floorplan::WindowType::UNKNOWN, Floorplan::Material::WOOD, 0.5, 0.5, 1.0, 1.0);
|
||||
fo->windows.push_back(win);
|
||||
return true;
|
||||
} else if (e->key() == Qt::Key_Delete && getSelectedNode() >= 1000) {
|
||||
const int idx = getSelectedNode() - 1000;
|
||||
fo->doors.erase(fo->doors.begin()+idx);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
45
mapview/2D/MV2DElementFloorObstacleWall.h
Normal file
45
mapview/2D/MV2DElementFloorObstacleWall.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef MV2DELEMENTFLOOROBSTACLEWALL_H
|
||||
#define MV2DELEMENTFLOOROBSTACLEWALL_H
|
||||
|
||||
|
||||
#include "MV2DElement.h"
|
||||
#include "HasMoveableNodes.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
class MV2DElementFloorObstacleWall : public MV2DElement, public HasMoveableNodes {
|
||||
|
||||
private:
|
||||
|
||||
Floorplan::Floor* f;
|
||||
Floorplan::FloorObstacleWall* fo;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
MV2DElementFloorObstacleWall(Floorplan::Floor* f, Floorplan::FloorObstacleWall* fo);
|
||||
|
||||
/** get the element's 3D bounding box */
|
||||
BBox2 getBoundingBox() const override;
|
||||
|
||||
/** get the element's minimal distance (nearest whatsoever) to the given point */
|
||||
ClickDist getMinDistanceXY(const Point2 p) const override;
|
||||
|
||||
/** repaint me */
|
||||
void paint(Painter& p) override;
|
||||
|
||||
void onFocus() override;
|
||||
|
||||
void onUnfocus() override;
|
||||
|
||||
virtual std::vector<MoveableNode> getMoveableNodes() const override;
|
||||
|
||||
void onNodeMove(MapView2D* v, const int userIdx, const Point2 newPos) override;
|
||||
|
||||
void onNodeMoved(MapView2D* v, const int userIdx, const Point2 newPos);
|
||||
|
||||
bool keyPressEvent(MapView2D* v, QKeyEvent* e) override;
|
||||
|
||||
};
|
||||
|
||||
#endif // MV2DELEMENTFLOOROBSTACLEWALL_H
|
||||
83
mapview/2D/tools/ToolNewLine.h
Normal file
83
mapview/2D/tools/ToolNewLine.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef TOOLNEWLINE_H
|
||||
#define TOOLNEWLINE_H
|
||||
|
||||
#include "ToolNewElement.h"
|
||||
#include "../../model/MMFloorObstacles.h"
|
||||
#include "../../model/MMFloorObstacleLine.h"
|
||||
|
||||
/** old walls, based on lines */
|
||||
class ToolNewLine : public ToolNewElement<Floorplan::FloorObstacleLine, MMFloorObstacleLine> {
|
||||
|
||||
private:
|
||||
|
||||
/** currently edited line node (has 2) */
|
||||
int idx = 0;
|
||||
|
||||
public:
|
||||
|
||||
ToolNewLine(Tools& tools, MapLayer* layer) : ToolNewElement(tools, layer) {
|
||||
;
|
||||
}
|
||||
|
||||
void becomesActive() override {
|
||||
//create(); // start adding an new element
|
||||
}
|
||||
|
||||
void becomesInactive() override {
|
||||
deleteCurrent(); // delete the currently pending and not yet finished wall element
|
||||
}
|
||||
|
||||
const std::string getName() const override {
|
||||
return "new Line";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** mouse is currently moved */
|
||||
void moving(const Point2 mapPoint) override {
|
||||
|
||||
// live-moving of the ending point
|
||||
if (idx == 1) { foEL->to = mapPoint; }
|
||||
|
||||
}
|
||||
|
||||
/** next point */
|
||||
void leftMouse(const Point2 mapPoint) override {
|
||||
|
||||
// 1st click (where to start the line)
|
||||
if (idx == 0) {
|
||||
createEmptyElement();
|
||||
foEL->from = mapPoint; foEL->to = mapPoint;
|
||||
++idx;
|
||||
|
||||
// 2nd click (wehere the line ends)
|
||||
} else if (idx == 1) {
|
||||
finalizeCurrent();
|
||||
idx = 0;
|
||||
if (!addAnother) {disableMe();}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rightMouse(const Point2 mapPoint) override {
|
||||
|
||||
(void) mapPoint;
|
||||
finalizeCurrent();
|
||||
disableMe();
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void createEmptyElement() {
|
||||
|
||||
foEL = new Floorplan::FloorObstacleLine(Floorplan::ObstacleType::WALL, Floorplan::Material::DRYWALL, Point2(0, 0), Point2(0, 0));
|
||||
MMFloorObstacles* obs = (MMFloorObstacles*)layer;
|
||||
mmEL = obs->createLine(foEL);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLNEWLINE_H
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
#include "ToolNewElement.h"
|
||||
#include "../../model/MMFloorObstacles.h"
|
||||
#include "../../model/MMFloorObstacleLine.h"
|
||||
#include "../../model/MMFloorObstacleWall.h"
|
||||
|
||||
class ToolNewWall : public ToolNewElement<Floorplan::FloorObstacleLine, MMFloorObstacleLine> {
|
||||
/** new walls */
|
||||
class ToolNewWall : public ToolNewElement<Floorplan::FloorObstacleWall, MMFloorObstacleWall> {
|
||||
|
||||
private:
|
||||
|
||||
@@ -71,9 +72,9 @@ private:
|
||||
|
||||
void createEmptyElement() {
|
||||
|
||||
foEL = new Floorplan::FloorObstacleLine(Floorplan::ObstacleType::WALL, Floorplan::Material::DRYWALL, Point2(0, 0), Point2(0, 0));
|
||||
foEL = new Floorplan::FloorObstacleWall(Floorplan::ObstacleType::WALL, Floorplan::Material::DRYWALL, Point2(0, 0), Point2(0, 0));
|
||||
MMFloorObstacles* obs = (MMFloorObstacles*)layer;
|
||||
mmEL = obs->createLine(foEL);
|
||||
mmEL = obs->createWall(foEL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include "IHasParams.h"
|
||||
|
||||
#include "../2D/MV2DElementFloorObstacleLine.h"
|
||||
//#include "../3D/MV3DElementFloorObstacleWall.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
@@ -21,13 +20,12 @@ public:
|
||||
Floorplan::Floor* mf;
|
||||
Floorplan::FloorObstacleLine* fo;
|
||||
MV2DElementFloorObstacleLine mv2d;
|
||||
//MV3DElementFloorObstacleWall mv3d;
|
||||
|
||||
public:
|
||||
|
||||
MMFloorObstacleLine(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleLine* fo) :
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(mf, fo) {//, mv3d(mf,fo) {
|
||||
|
||||
MapModelElement(parent), mf(mf), fo(fo), mv2d(mf, fo) {
|
||||
;
|
||||
}
|
||||
|
||||
void setMaterial(const Floorplan::Material m) override {fo->material = m;}
|
||||
@@ -37,44 +35,41 @@ public:
|
||||
Floorplan::ObstacleType getObatcleType() const override {return fo->type;}
|
||||
|
||||
MV2DElement* getMV2D() const override {return (MV2DElement*) &mv2d;}
|
||||
//MV3DElement* getMV3D() const override {return (MV3DElement*) &mv3d;}
|
||||
|
||||
void deleteMe() const override {
|
||||
parent->removeElement(this);
|
||||
mf->obstacles.erase(std::remove(mf->obstacles.begin(), mf->obstacles.end(), fo), mf->obstacles.end());
|
||||
}
|
||||
|
||||
|
||||
virtual int getNumParams() const override {
|
||||
int getNumParams() const override {
|
||||
return 3;
|
||||
}
|
||||
|
||||
virtual Param getParamDesc(const int idx) const override {
|
||||
switch(idx) {
|
||||
case 0: return Param("thickness (m)", ParamType::FLOAT);
|
||||
case 1: return Param("height (m)", ParamType::FLOAT);
|
||||
case 2: return Param("length", ParamType::FLOAT, true);
|
||||
case 0: return Param("thickness (m)", ParamType::FLOAT);
|
||||
case 1: return Param("height (m)", ParamType::FLOAT);
|
||||
case 2: return Param("length", ParamType::FLOAT, true);
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
|
||||
virtual ParamValue getParamValue(const int idx) const override {
|
||||
switch(idx) {
|
||||
case 0: return fo->thickness_m;
|
||||
case 1: return fo->height_m;
|
||||
case 2: return fo->from.getDistance(fo->to);
|
||||
case 0: return fo->thickness_m;
|
||||
case 1: return fo->height_m;
|
||||
case 2: return fo->from.getDistance(fo->to);
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
|
||||
virtual void setParamValue(const int idx, const ParamValue& val) override {
|
||||
switch(idx) {
|
||||
case 0: fo->thickness_m = val.toFloat(); break;
|
||||
case 1: fo->height_m = val.toFloat(); break;
|
||||
case 2: break;
|
||||
case 0: fo->thickness_m = val.toFloat(); return;
|
||||
case 1: fo->height_m = val.toFloat(); return;
|
||||
case 2: return;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // MAPELEMENTOBSTACLE_H
|
||||
|
||||
116
mapview/model/MMFloorObstacleWall.h
Normal file
116
mapview/model/MMFloorObstacleWall.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#ifndef MMFLOOROBSTACLEWALL_H
|
||||
#define MMFLOOROBSTACLEWALL_H
|
||||
|
||||
|
||||
#include "MapModelElement.h"
|
||||
#include "../2D/MapViewElementHelper.h"
|
||||
|
||||
#include "IHasMaterial.h"
|
||||
#include "IHasObstacleType.h"
|
||||
#include "IHasParams.h"
|
||||
|
||||
#include "../2D/MV2DElementFloorObstacleWall.h"
|
||||
|
||||
#include <Indoor/floorplan/v2/Floorplan.h>
|
||||
|
||||
class MMFloorObstacleWall : public MapModelElement, public IHasMaterial, public IHasObstacleType, public IHasParams {
|
||||
|
||||
public:
|
||||
|
||||
Floorplan::Floor* mf;
|
||||
Floorplan::FloorObstacleWall* wall;
|
||||
MV2DElementFloorObstacleWall mv2d;
|
||||
|
||||
public:
|
||||
|
||||
MMFloorObstacleWall(MapLayer* parent, Floorplan::Floor* mf, Floorplan::FloorObstacleWall* wall) :
|
||||
MapModelElement(parent), mf(mf), wall(wall), mv2d(mf, wall) {
|
||||
;
|
||||
}
|
||||
|
||||
void setMaterial(const Floorplan::Material m) override {wall->material = m;}
|
||||
Floorplan::Material getMaterial() const override {return wall->material;}
|
||||
|
||||
void setObstacleType(const Floorplan::ObstacleType t) override {wall->type = t;}
|
||||
Floorplan::ObstacleType getObatcleType() const override {return wall->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(), wall), mf->obstacles.end());
|
||||
}
|
||||
|
||||
int getType() const {
|
||||
const int idx = mv2d.getSelectedNode();
|
||||
if (idx < 1000) {return 0;} // line
|
||||
if (idx < 2000) {return 1;} // door
|
||||
return 2; // window
|
||||
}
|
||||
|
||||
Floorplan::FloorObstacleWallDoor* getCurDoor() const {
|
||||
const int idx = mv2d.getSelectedNode()-1000;
|
||||
return wall->doors[idx];
|
||||
}
|
||||
|
||||
int getNumParams() const override {
|
||||
switch(getType()) {
|
||||
case 0: return 3;
|
||||
case 1: return 4;
|
||||
case 2: return 0;
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
|
||||
virtual Param getParamDesc(const int idx) const override {
|
||||
switch(getType()) {
|
||||
case 0: switch(idx) {
|
||||
case 0: return Param("thickness (m)", ParamType::FLOAT);
|
||||
case 1: return Param("height (m)", ParamType::FLOAT);
|
||||
case 2: return Param("length", ParamType::FLOAT, true);
|
||||
}
|
||||
case 1: switch(idx) {
|
||||
case 0: return Param("width (m)", ParamType::FLOAT);
|
||||
case 1: return Param("height (m)", ParamType::FLOAT);
|
||||
case 2: return Param("left/right", ParamType::BOOL);
|
||||
case 3: return Param("in/out", ParamType::BOOL);
|
||||
}
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
|
||||
virtual ParamValue getParamValue(const int idx) const override {
|
||||
switch(getType()) {
|
||||
case 0: switch(idx) {
|
||||
case 0: return wall->thickness_m;
|
||||
case 1: return wall->height_m;
|
||||
case 2: return wall->from.getDistance(wall->to);
|
||||
}
|
||||
case 1: switch(idx) {
|
||||
case 0: return getCurDoor()->width;
|
||||
case 1: return getCurDoor()->height;
|
||||
case 2: return getCurDoor()->leftRight;
|
||||
case 3: return getCurDoor()->inOut;
|
||||
}
|
||||
}
|
||||
throw 1;
|
||||
}
|
||||
|
||||
virtual void setParamValue(const int idx, const ParamValue& val) override {
|
||||
switch(getType()) {
|
||||
case 0: switch(idx) {
|
||||
case 0: wall->thickness_m = val.toFloat(); return;
|
||||
case 1: wall->height_m = val.toFloat(); return;
|
||||
case 2: return;
|
||||
}
|
||||
case 1: switch(idx) {
|
||||
case 0: getCurDoor()->width = val.toFloat(); return;
|
||||
case 1: getCurDoor()->height = val.toFloat(); return;
|
||||
case 2: getCurDoor()->leftRight = val.toBool(); return;
|
||||
case 3: getCurDoor()->inOut = val.toBool(); return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MMFLOOROBSTACLEWALL_H
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "MapLayer.h"
|
||||
#include "MMFloorObstacleCircle.h"
|
||||
#include "MMFloorObstacleLine.h"
|
||||
#include "MMFloorObstacleWall.h"
|
||||
#include "MMFloorObstacleDoor.h"
|
||||
#include "MMFloorObstacleObject.h"
|
||||
|
||||
@@ -25,12 +26,14 @@ public:
|
||||
for (Floorplan::FloorObstacle* o : floor->obstacles) {
|
||||
if (dynamic_cast<Floorplan::FloorObstacleLine*>(o)) {
|
||||
addElement(new MMFloorObstacleLine(this, floor, (Floorplan::FloorObstacleLine*)o));
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleWall*>(o)) {
|
||||
addElement(new MMFloorObstacleWall(this, floor, (Floorplan::FloorObstacleWall*)o));
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleCircle*>(o)) {
|
||||
addElement(new MMFloorObstacleCircle(this, floor, (Floorplan::FloorObstacleCircle*)o));
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleDoor*>(o)) {
|
||||
addElement(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
||||
addElement(new MMFloorObstacleDoor(this, floor, (Floorplan::FloorObstacleDoor*)o));
|
||||
} else if (dynamic_cast<Floorplan::FloorObstacleObject*>(o)) {
|
||||
addElement(new MMFloorObstacleObject(this, floor, (Floorplan::FloorObstacleObject*)o));
|
||||
addElement(new MMFloorObstacleObject(this, floor, (Floorplan::FloorObstacleObject*)o));
|
||||
} else {
|
||||
throw new Exception("todo: not yet implemented obstacle type");
|
||||
}
|
||||
@@ -50,6 +53,21 @@ public:
|
||||
/** get the corresponding floor from the underlying model */
|
||||
Floorplan::Floor* getFloor() {return floor;}
|
||||
|
||||
|
||||
//TODO: check
|
||||
MMFloorObstacleWall* createWall(Floorplan::FloorObstacleWall* obs) {
|
||||
|
||||
// add to underlying model
|
||||
floor->obstacles.push_back(obs);
|
||||
|
||||
// add to myself as element
|
||||
MMFloorObstacleWall* mm = new MMFloorObstacleWall(this, floor, obs);
|
||||
addElement(mm);
|
||||
return mm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//TODO: check
|
||||
MMFloorObstacleDoor* createDoor(Floorplan::FloorObstacleDoor* obs) {
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "../mapview/2D/tools/ToolSelector.h"
|
||||
#include "../mapview/2D/tools/ToolNewElement.h"
|
||||
#include "../mapview/2D/tools/ToolNewWall.h"
|
||||
#include "../mapview/2D/tools/ToolNewLine.h"
|
||||
#include "../mapview/2D/tools/ToolNewDoor.h"
|
||||
#include "../mapview/2D/tools/ToolNewStair.h"
|
||||
#include "../mapview/2D/tools/ToolNewElevator.h"
|
||||
@@ -81,6 +82,11 @@ ToolBoxWidget::ToolBoxWidget(MapView2D* view, QWidget *parent) : QWidget(parent)
|
||||
lay->addWidget(btnWall, r++, 0, 1,1,Qt::AlignTop);
|
||||
connect(btnWall, SIGNAL(clicked(bool)), this, SLOT(onNewWall()));
|
||||
|
||||
btnLine = new QPushButton(UIHelper::getIcon("line"), "");
|
||||
btnLine->setMinimumSize(s,s);
|
||||
lay->addWidget(btnLine, r++, 0, 1,1,Qt::AlignTop);
|
||||
connect(btnLine, SIGNAL(clicked(bool)), this, SLOT(onNewLine()));
|
||||
|
||||
btnPillar = new QPushButton(UIHelper::getIcon("pillar"), "");
|
||||
btnPillar->setMinimumSize(s,s);
|
||||
lay->addWidget(btnPillar, r++, 0, 1,1,Qt::AlignTop);
|
||||
@@ -184,6 +190,7 @@ void ToolBoxWidget::onMainToolChanged() {
|
||||
|
||||
btnGround->setStyleSheet( dynamic_cast<ToolNewOutline*>(t) ? styleSel : styleNor );
|
||||
|
||||
btnLine->setStyleSheet( dynamic_cast<ToolNewLine*>(t) ? styleSel : styleNor );
|
||||
btnDoor->setStyleSheet( dynamic_cast<ToolNewDoor*>(t) ? styleSel : styleNor );
|
||||
btnWall->setStyleSheet( dynamic_cast<ToolNewWall*>(t) ? styleSel : styleNor );
|
||||
btnObject->setStyleSheet( dynamic_cast<ToolNewObject*>(t) ? styleSel : styleNor );
|
||||
@@ -206,6 +213,7 @@ void ToolBoxWidget::setSelectedLayer(MapLayer *ml) {
|
||||
|
||||
btnGround->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_GROUND));
|
||||
|
||||
btnLine->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
||||
btnWall->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
||||
btnPillar->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
||||
btnDoor->setEnabled(ml && (ml->getLayerType() == MapLayerType::FLOOR_OBSTACLES));
|
||||
@@ -258,6 +266,10 @@ void ToolBoxWidget::onMeasure() {
|
||||
view->getTools().setMain(new ToolMeasure(view->getTools()));
|
||||
}
|
||||
|
||||
void ToolBoxWidget::onNewLine() {
|
||||
view->getTools().setMain(new ToolNewLine(view->getTools(), curLayer));
|
||||
}
|
||||
|
||||
void ToolBoxWidget::onNewWall() {
|
||||
view->getTools().setMain(new ToolNewWall(view->getTools(), curLayer));
|
||||
}
|
||||
@@ -277,105 +289,36 @@ void ToolBoxWidget::onNewPillar() {
|
||||
|
||||
|
||||
void ToolBoxWidget::onNewStair() {
|
||||
|
||||
view->getTools().setMain(new ToolNewStair(view->getTools(), curLayer));
|
||||
|
||||
|
||||
// const Point2 center = view->getScaler().getCenter();
|
||||
|
||||
// Floorplan::StairFreeform* stair = new Floorplan::StairFreeform();
|
||||
// Floorplan::StairPart part(Point3(center.x-3, center.y, 0), Point3(center.x+3, center.y, 3), 3);
|
||||
// stair->parts.push_back( part );
|
||||
|
||||
// MMFloorStairs* stairs = (MMFloorStairs*)curLayer;
|
||||
// stairs->create(stair);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ToolBoxWidget::onNewElevator() {
|
||||
|
||||
// const Point2 center = view->getScaler().getCenter();
|
||||
|
||||
// Floorplan::Elevator* elevator = new Floorplan::Elevator(center);
|
||||
|
||||
// MMFloorElevators* elevators = (MMFloorElevators*)curLayer;
|
||||
// elevators->create(elevator);
|
||||
|
||||
view->getTools().setMain(new ToolNewElevator(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
view->getTools().setMain(new ToolNewAccessPoint(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
view->getTools().setMain(new ToolNewBeacon(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
void ToolBoxWidget::onNewFingerprintLocation() {
|
||||
|
||||
// const Point2 center = view->getScaler().getCenter();
|
||||
// Floorplan::FingerprintLocation* fpl = new Floorplan::FingerprintLocation("noname", center, 0);
|
||||
|
||||
// MMFloorFingerprints* fps = (MMFloorFingerprints*) curLayer;
|
||||
// fps->create(fpl);
|
||||
|
||||
view->getTools().setMain(new ToolNewFingerprint(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ToolBoxWidget::onNewPOI() {
|
||||
|
||||
// const Point2 center = view->getScaler().getCenter();
|
||||
// Floorplan::POI* poi = new Floorplan::POI(
|
||||
// Floorplan::POIType::ROOM, "noname", Point2(center.x, center.y)
|
||||
// );
|
||||
|
||||
// MMFloorPOIs* pois = (MMFloorPOIs*) curLayer;
|
||||
// pois->createPOI(poi);
|
||||
|
||||
view->getTools().setMain(new ToolNewPOI(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
void ToolBoxWidget::onNewGTP() {
|
||||
|
||||
// const Point2 center = view->getScaler().getCenter();
|
||||
// Floorplan::GroundTruthPoint* gtp = new Floorplan::GroundTruthPoint(
|
||||
// 0, Point3(center.x, center.y, 0)
|
||||
// );
|
||||
|
||||
// MMFloorGroundTruthPoints* gtps = (MMFloorGroundTruthPoints*) curLayer;
|
||||
// gtps->createGroundTruthPoint(gtp);
|
||||
|
||||
view->getTools().setMain(new ToolNewGroundTruth(view->getTools(), curLayer));
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ToolBoxWidget::onNewEarthReg() {
|
||||
|
||||
const Point2 center = view->getScaler().getCenter();
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
QPushButton* btnMeasure;
|
||||
|
||||
QPushButton* btnGround;
|
||||
QPushButton* btnLine;
|
||||
QPushButton* btnWall;
|
||||
QPushButton* btnPillar;
|
||||
QPushButton* btnDoor;
|
||||
@@ -63,6 +64,7 @@ private slots:
|
||||
|
||||
void onNewGround();
|
||||
void onNewWall();
|
||||
void onNewLine();
|
||||
void onNewPillar();
|
||||
void onNewDoor();
|
||||
void onNewObject();
|
||||
|
||||
1
res.qrc
1
res.qrc
@@ -28,5 +28,6 @@
|
||||
<file>res/icons/save.svg</file>
|
||||
<file>res/icons/load.svg</file>
|
||||
<file>res/icons/objects.svg</file>
|
||||
<file>res/icons/line.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
80
res/icons/line.svg
Normal file
80
res/icons/line.svg
Normal file
@@ -0,0 +1,80 @@
|
||||
<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 8.4666659 8.4666669"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.1 r"
|
||||
sodipodi:docname="line.svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9195959"
|
||||
inkscape:cx="21.899183"
|
||||
inkscape:cy="14.697118"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1019"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4485"
|
||||
empspacing="4" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<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,-288.53332)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 2.1166666,294.88332 4.2333333,-4.23333"
|
||||
id="path4491"
|
||||
inkscape:connector-curvature="0" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path4489"
|
||||
cx="6.3499999"
|
||||
cy="290.64999"
|
||||
r="1.0583333" />
|
||||
<circle
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:0.52916667;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path4487"
|
||||
cx="2.1166666"
|
||||
cy="294.88333"
|
||||
r="1.0583333" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
Reference in New Issue
Block a user