initial version

This commit is contained in:
2016-01-21 11:10:55 +01:00
parent 8818a9b216
commit a7dc0cabbb
21 changed files with 1397 additions and 0 deletions

49
floorplan/Floor.h Executable file
View File

@@ -0,0 +1,49 @@
#ifndef FLOOR_H
#define FLOOR_H
#include <vector>
#include "../geo/Line2D.h"
/**
* represents one floor by describing all contained obstacles
*/
class Floor {
private:
/** all obstacles within the floor */
std::vector<Line2D> lines;
/** total width of the floor (in meter) */
double width_cm;
/** total depth of the floor (in meter) */
double depth_cm;
public:
/** ctor */
Floor(const float width_cm, const float depth_cm) : width_cm(width_cm), depth_cm(depth_cm) {;}
/** get all obstacles */
const std::vector<Line2D>& getObstacles() const {
return lines;
}
/** add a new obstacle to this floor */
void addObstacle(const Line2D& l ) {
lines.push_back(l);
}
/** get the floorplan's total width */
float getWidth_cm() const {return width_cm;}
/** get the floorplan's total depth */
float getDepth_cm() const {return depth_cm;}
};
#endif // FLOOR_H

138
floorplan/FloorplanFactorySVG.h Executable file
View File

@@ -0,0 +1,138 @@
#ifndef FLOORPLANFACTORYSVG_H
#define FLOORPLANFACTORYSVG_H
#include "Floor.h"
#include <string>
#include "../Exception.h"
#include <KLib/gfx/svg/SVGLoader.h>
/**
* load floorplans from SVG files
*/
class FloorplanFactorySVG {
/**
* helper class for SVG floorplans.
*
* converts between the SVG's scale and real-world scale
*/
class SVGScaler {
private:
/** the scaling factor to apply to the svg data */
const double scalingFactor;
public:
/** ctor */
SVGScaler(const double scalingFactor) : scalingFactor(scalingFactor) {
;
}
/** scale (x, y) into (_x, _y) */
void scale(const double x, const double y, double& _x, double& _y) const {
_x = x * scalingFactor;
_y = y * scalingFactor;
}
/** scale the given point into a new output point */
K::Point scale(const K::Point p) const {
K::Point ret;
scale (p.x, p.y, ret.x, ret.y);
return ret;
}
/** scale the given line into a new output line */
Line2D scale(const K::Line l) const {
Line2D ret;
scale (l.p1.x, l.p1.y, ret.p1.x, ret.p1.y);
scale (l.p2.x, l.p2.y, ret.p2.x, ret.p2.y);
return ret;
}
};
private:
K::SVGFile svg;
SVGScaler scaler;
double width;
double depth;
public:
/** ctor with svg filename and scaling factor */
FloorplanFactorySVG(const std::string& file, const float scaling) : scaler(scaling) {
// load the SVG
K::SVGLoader::load(K::File(file), &svg);
scaler.scale(svg.getWidth(), svg.getHeight(), width, depth);
}
/** get the width of the building */
float getWidth() const {return width;}
/** get the depth of the building */
float getDepth() const {return depth;}
/** get the floor identified by the given layer name */
Floor getFloor(const std::string layerName) {
// get the requested SVG layer
K::SVGComposite* sc = svg.getLayers();
K::SVGLayer* layer = sc->getContainedLayerNamed(layerName);
if (!layer) {throw Exception("SVG has no layer named '" + layerName + "'");}
// create and parse the new floor
Floor floor(width, depth);
load(layer, floor);
return floor;
}
private:
/** recursive loading/parsing of nested SVG elements */
void load(K::SVGElement* el, Floor& floor) {
switch (el->getType()) {
case SVGElementType::COMPOSITE: {
for (K::SVGElement* sub : ((K::SVGComposite*)el)->getChilds()) {
load(sub, floor);
}
break;
}
case SVGElementType::LAYER: {
K::SVGLayer* layer = (K::SVGLayer*) el;
for (K::SVGElement* sub : layer->getChilds()) {
load(sub, floor);
}
break;
}
case SVGElementType::PATH: {
for (const K::Line& line : ((K::SVGPath*)el)->getLines()) {
floor.addObstacle( scaler.scale(line) );
}
break;
}
case SVGElementType::TEXT: {
break;
}
default:
throw "should not happen!";
}
}
};
#endif // FLOORPLANFACTORYSVG_H