589 lines
19 KiB
C++
589 lines
19 KiB
C++
/*
|
||
* © Copyright 2014 – Urheberrechtshinweis
|
||
* Alle Rechte vorbehalten / All Rights Reserved
|
||
*
|
||
* Programmcode ist urheberrechtlich geschuetzt.
|
||
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
|
||
* Einige Aenderungen beigetragen von Toni Fetzer
|
||
* Keine Verwendung ohne explizite Genehmigung.
|
||
* (vgl. § 106 ff UrhG / § 97 UrhG)
|
||
*/
|
||
|
||
#ifndef FLOORPLANREADER_H
|
||
#define FLOORPLANREADER_H
|
||
|
||
#include <iostream>
|
||
|
||
#include "Floorplan.h"
|
||
#include "FloorplanLINT.h"
|
||
|
||
#include "../../misc/Debug.h"
|
||
#include "../../Assertions.h"
|
||
#include "../../lib/tinyxml/tinyxml2.h"
|
||
|
||
namespace Floorplan {
|
||
|
||
using XMLAttr = tinyxml2::XMLAttribute;
|
||
using XMLElem = tinyxml2::XMLElement;
|
||
using XMLNode = tinyxml2::XMLNode;
|
||
|
||
/**
|
||
* read an IndoorMaps from XML-data
|
||
*/
|
||
class Reader {
|
||
|
||
private:
|
||
|
||
static constexpr const char* name = "FPReader";
|
||
|
||
public:
|
||
|
||
/** read an IndoorMap from the given XML-file */
|
||
static IndoorMap* readFromFile(const std::string& file) {
|
||
Log::add(name, "reading floorplan from file: " + file);
|
||
setlocale(LC_NUMERIC, "C");
|
||
tinyxml2::XMLDocument doc;
|
||
const tinyxml2::XMLError res = doc.LoadFile(file.c_str());
|
||
if (res != tinyxml2::XMLError::XML_SUCCESS) {
|
||
throw Exception(
|
||
std::string() + "error while loading XML " + file + "\n" +
|
||
((doc.GetErrorStr1()) ? (doc.GetErrorStr1()) : ("")) + "\n" +
|
||
((doc.GetErrorStr2()) ? (doc.GetErrorStr2()) : ("")));
|
||
}
|
||
IndoorMap* map = parse(doc);
|
||
return map;
|
||
}
|
||
|
||
/** read an IndoorMap from the given XMl-string */
|
||
static IndoorMap* readFromString(const std::string& str) {
|
||
Log::add(name, "reading floorplan from string");
|
||
setlocale(LC_NUMERIC, "C");
|
||
tinyxml2::XMLDocument doc;
|
||
const tinyxml2::XMLError res = doc.Parse(str.c_str(), str.length());
|
||
if (res != tinyxml2::XMLError::XML_SUCCESS) {
|
||
throw Exception(
|
||
std::string() + "error while parsing XML\n" +
|
||
((doc.GetErrorStr1()) ? (doc.GetErrorStr1()) : ("")) + "\n" +
|
||
((doc.GetErrorStr2()) ? (doc.GetErrorStr2()) : (""))
|
||
);
|
||
}
|
||
IndoorMap* map = parse(doc);
|
||
return map;
|
||
}
|
||
|
||
private:
|
||
|
||
#define FOREACH_NODE(out, in) for( const XMLElem* out = in->FirstChildElement(); out; out = out->NextSiblingElement() )
|
||
|
||
static void assertNode(const std::string& node, const XMLElem* el) {
|
||
std::string err = std::string("unexpected node '") + el->Name() + "' expected '" + node + "'";
|
||
Assert::equal(node, std::string(el->Name()), err);
|
||
}
|
||
|
||
/** parse the complete document */
|
||
static IndoorMap* parse(tinyxml2::XMLDocument& doc) {
|
||
return parseMap(doc.FirstChildElement());
|
||
}
|
||
|
||
/** parse the <map> node */
|
||
static IndoorMap* parseMap(const XMLElem* el) {
|
||
Log::add(name, "parsing the map");
|
||
IndoorMap* map = new IndoorMap();
|
||
map->width = el->FloatAttribute("width");
|
||
map->depth = el->FloatAttribute("depth");
|
||
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("floors") == n->Name()) {map->floors = parseFloors(n);}
|
||
if (std::string("earthReg") == n->Name()) {map->earthReg = parseEarthReg(n);}
|
||
}
|
||
return map;
|
||
}
|
||
|
||
/** parse the <earthReg> node */
|
||
static EarthRegistration parseEarthReg(const XMLElem* el) {
|
||
EarthRegistration reg;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("correspondences") == n->Name()) {
|
||
FOREACH_NODE(n2, n) {
|
||
if (std::string("point") == n2->Name()) {
|
||
Floorplan::EarthPosMapPos* pos = new Floorplan::EarthPosMapPos();
|
||
pos->posOnMap_m.x = n2->FloatAttribute("mx");
|
||
pos->posOnMap_m.y = n2->FloatAttribute("my");
|
||
pos->posOnMap_m.z = n2->FloatAttribute("mz");
|
||
pos->posOnEarth.lat = n2->FloatAttribute("lat");
|
||
pos->posOnEarth.lon = n2->FloatAttribute("lon");
|
||
pos->posOnEarth.height = n2->FloatAttribute("alt");
|
||
reg.correspondences.push_back(pos);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return reg;
|
||
}
|
||
|
||
/** parse the <floors> node */
|
||
static std::vector<Floor*> parseFloors(const XMLElem* el) {
|
||
std::vector<Floor*> floors;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("floor") == n->Name()) {floors.push_back(parseFloor(n));}
|
||
}
|
||
return floors;
|
||
}
|
||
|
||
/** parse one <floor> node */
|
||
static Floor* parseFloor(const XMLElem* el) {
|
||
Floor* floor = new Floor();
|
||
Log::add(name, std::string("parsing floor ") + el->Attribute("name"));
|
||
floor->atHeight = el->FloatAttribute("atHeight");
|
||
floor->height = el->FloatAttribute("height");
|
||
floor->name = el->Attribute("name");
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("outline") == n->Name()) {floor->outline = parseFloorOutline(n);}
|
||
if (std::string("obstacles") == n->Name()) {floor->obstacles = parseFloorObstacles(n);}
|
||
if (std::string("accesspoints") == n->Name()) {floor->accesspoints = parseFloorAccessPoints(n);}
|
||
if (std::string("beacons") == n->Name()) {floor->beacons = parseFloorBeacons(n);}
|
||
if (std::string("fingerprints") == n->Name()) {floor->fpLocations = parseFingerprintLocations(n);}
|
||
if (std::string("regions") == n->Name()) {floor->regions = parseFloorRegions(n);}
|
||
if (std::string("underlays") == n->Name()) {floor->underlays = parseFloorUnderlays(n);}
|
||
if (std::string("pois") == n->Name()) {floor->pois = parseFloorPOIs(n);}
|
||
if (std::string("stairs") == n->Name()) {floor->stairs = parseFloorStairs(n);}
|
||
if (std::string("elevators") == n->Name()) {floor->elevators = parseFloorElevators(n);}
|
||
if (std::string("gtpoints") == n->Name()) {floor->gtpoints = parseFloorGroundTruthPoints(n);}
|
||
}
|
||
return floor;
|
||
}
|
||
|
||
|
||
/** parse the <elevators> tag */
|
||
static FloorElevators parseFloorElevators(const XMLElem* el) {
|
||
FloorElevators vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("elevator") == n->Name()) { vec.push_back(parseFloorElevator(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse the <stairs> tag */
|
||
static FloorStairs parseFloorStairs(const XMLElem* el) {
|
||
FloorStairs vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("stair") == n->Name()) { vec.push_back(parseFloorStair(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse an <elevator> tag */
|
||
static Elevator* parseFloorElevator(const XMLElem* el) {
|
||
Elevator* elev = new Elevator();
|
||
elev->center = Point2(el->FloatAttribute("cx"), el->FloatAttribute("cy"));
|
||
elev->depth = el->FloatAttribute("depth");
|
||
elev->width = el->FloatAttribute("width");
|
||
elev->height_m = el->FloatAttribute("height");
|
||
elev->rotation = el->FloatAttribute("rotation");
|
||
return elev;
|
||
}
|
||
|
||
/** parse a <stair> tag */
|
||
static Stair* parseFloorStair(const XMLElem* el) {
|
||
Stair* stair = nullptr;
|
||
if (el->IntAttribute("type") == 0) {
|
||
stair = new StairFreeform();
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("part") == n->Name()) {
|
||
StairPart part;
|
||
part.connectWithPrev = n->BoolAttribute("connect");
|
||
part.start.x = n->FloatAttribute("x1");
|
||
part.start.y = n->FloatAttribute("y1");
|
||
part.start.z = n->FloatAttribute("z1");
|
||
part.end.x = n->FloatAttribute("x2");
|
||
part.end.y = n->FloatAttribute("y2");
|
||
part.end.z = n->FloatAttribute("z2");
|
||
part.width = n->FloatAttribute("w");
|
||
((StairFreeform*)stair)->parts.push_back(part);
|
||
} else {
|
||
throw "not yet implemented";
|
||
}
|
||
}
|
||
} else {
|
||
throw "not yet implemented";
|
||
}
|
||
|
||
// stair meta information?
|
||
const XMLElem* meta = el->FirstChildElement("meta");
|
||
if (meta) {stair->setMeta(parseMetaElement(meta));}
|
||
|
||
return stair;
|
||
|
||
}
|
||
|
||
|
||
/** parse the <pois> tag */
|
||
static FloorPOIs parseFloorPOIs(const XMLElem* el) {
|
||
FloorPOIs vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("poi") == n->Name()) { vec.push_back(parseFloorPOI(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse a <poi> tag */
|
||
static POI* parseFloorPOI(const XMLElem* el) {
|
||
POI* poi = new POI();
|
||
poi->name = el->Attribute("name");
|
||
poi->type = (POIType) el->IntAttribute("type");
|
||
poi->pos = parsePoint2(el);
|
||
return poi;
|
||
}
|
||
|
||
|
||
/** parse the <gtpoints> tag */
|
||
static FloorGroundTruthPoints parseFloorGroundTruthPoints(const XMLElem* el) {
|
||
FloorGroundTruthPoints vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("gtpoint") == n->Name()) { vec.push_back(parseFloorGroundTruthPoint(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse a <gtpoint> tag */
|
||
static GroundTruthPoint* parseFloorGroundTruthPoint(const XMLElem* el) {
|
||
GroundTruthPoint* gtp = new GroundTruthPoint();
|
||
gtp->id = el->IntAttribute("id");
|
||
gtp->pos = parsePoint3(el);
|
||
return gtp;
|
||
}
|
||
|
||
/** parse the <accesspoints> tag */
|
||
static FloorAccessPoints parseFloorAccessPoints(const XMLElem* el) {
|
||
FloorAccessPoints vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("accesspoint") == n->Name()) { vec.push_back(parseAccessPoint(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse the <underlays> tag */
|
||
static FloorUnderlays parseFloorUnderlays(const XMLElem* el) {
|
||
FloorUnderlays res;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("underlay") == n->Name()) { res.push_back(parseFloorUnderlay(n)); }
|
||
}
|
||
return res;
|
||
}
|
||
|
||
/** parse an underlay image */
|
||
static UnderlayImage* parseFloorUnderlay(const XMLElem* el) {
|
||
UnderlayImage* img = new UnderlayImage();
|
||
img->anchor.x = el->FloatAttribute("x");
|
||
img->anchor.y = el->FloatAttribute("y");
|
||
img->scaleX = el->FloatAttribute("sx");
|
||
img->scaleY = el->FloatAttribute("sy");
|
||
img->name = el->Attribute("name");
|
||
img->filename = el->Attribute("file");
|
||
return img;
|
||
}
|
||
|
||
// /** parse the <other> tag */
|
||
// static FloorKeyValue parseFloorKeyValue(const XMLElem* el) {
|
||
// FloorKeyValue res;
|
||
// FOREACH_NODE(n, el) {
|
||
// if (std::string("keyval") == n->Name()) { res.elements.push_back(parseKeyValueElement(n)); }
|
||
// }
|
||
// return res;
|
||
// }
|
||
|
||
/** parse one <meta> element */
|
||
static Meta* parseMetaElement(const XMLElem* n) {
|
||
Meta* elem = new Meta();
|
||
// const XMLAttr* attr = n->FirstAttribute();
|
||
// while (attr) {
|
||
// elem->setVal(attr->Name(), attr->Value());
|
||
// attr = attr->Next();
|
||
// }
|
||
const XMLElem* sub = n->FirstChildElement();
|
||
while(sub) {
|
||
// <entry key="123">abc</entry>
|
||
const std::string key = sub->Attribute("key");
|
||
const std::string val = sub->GetText();
|
||
elem->add(key, val);
|
||
sub = sub->NextSiblingElement();
|
||
}
|
||
return elem;
|
||
}
|
||
|
||
static AccessPoint* parseAccessPoint(const XMLElem* n) {
|
||
assertNode("accesspoint", n);
|
||
AccessPoint* ap = new AccessPoint();
|
||
ap->mac = n->Attribute("mac");
|
||
ap->name = n->Attribute("name");
|
||
ap->pos = parsePoint3(n);
|
||
ap->model.txp = n->FloatAttribute("mdl_txp");
|
||
ap->model.exp = n->FloatAttribute("mdl_exp");
|
||
ap->model.waf = n->FloatAttribute("mdl_waf");
|
||
const XMLElem* meta = n->FirstChildElement("meta");
|
||
if (meta) {ap->setMeta(parseMetaElement(meta));}
|
||
return ap;
|
||
}
|
||
|
||
|
||
/** parse the <beacons> tag */
|
||
static FloorBeacons parseFloorBeacons(const XMLElem* el) {
|
||
FloorBeacons vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("beacon") == n->Name()) { vec.push_back(parseBeacon(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
static Beacon* parseBeacon(const XMLElem* n) {
|
||
assertNode("beacon", n);
|
||
Beacon* b = new Beacon();
|
||
b->mac = n->Attribute("mac");
|
||
b->name = n->Attribute("name");
|
||
b->major = n->Attribute("major") ? n->Attribute("major") : "";
|
||
b->minor = n->Attribute("minor") ? n->Attribute("minor") : "";
|
||
b->uuid = n->Attribute("uuid") ? n->Attribute("uuid") : "";
|
||
b->model.txp = n->FloatAttribute("mdl_txp");
|
||
b->model.exp = n->FloatAttribute("mdl_exp");
|
||
b->model.waf = n->FloatAttribute("mdl_waf");
|
||
b->pos = parsePoint3(n);
|
||
return b;
|
||
}
|
||
|
||
/** parse <fingerprints> <location>s */
|
||
static FloorFingerprintLocations parseFingerprintLocations(const XMLElem* el) {
|
||
assertNode("fingerprints", el);
|
||
FloorFingerprintLocations vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("location") == n->Name()) { vec.push_back(parseFingerprintLocation(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
/** parse one fingerprint <location> */
|
||
static FingerprintLocation* parseFingerprintLocation(const XMLElem* n) {
|
||
assertNode("location", n);
|
||
FingerprintLocation* fpl = new FingerprintLocation();
|
||
fpl->name = n->Attribute("name");
|
||
fpl->posOnFloor.x = n->FloatAttribute("x");
|
||
fpl->posOnFloor.y = n->FloatAttribute("y");
|
||
fpl->heightAboveFloor = n->FloatAttribute("dz");
|
||
const XMLElem* meta = n->FirstChildElement("meta");
|
||
if (meta) {fpl->setMeta(parseMetaElement(meta));}
|
||
return fpl;
|
||
}
|
||
|
||
static FloorRegions parseFloorRegions(const XMLElem* el) {
|
||
FloorRegions vec;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("region") == n->Name()) { vec.push_back(parseFloorRegion(n)); }
|
||
}
|
||
return vec;
|
||
}
|
||
|
||
static FloorRegion* parseFloorRegion(const XMLElem* n) {
|
||
assertNode("region", n);
|
||
FloorRegion* reg = new FloorRegion();
|
||
reg->name = n->Attribute("name");
|
||
reg->poly = parsePoly2(n);
|
||
return reg;
|
||
}
|
||
|
||
/** parse the <obstacles> tag */
|
||
static FloorObstacles parseFloorObstacles(const XMLElem* el) {
|
||
assertNode("obstacles", el);
|
||
FloorObstacles obstacles;
|
||
FOREACH_NODE(n, el) {
|
||
// if (std::string("wall") == n->Name()) {obstacles.push_back(parseFloorObstacleWall(n));}
|
||
// if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
|
||
// if (std::string("window") == n->Name()) {obstacles.push_back(parseFloorObstacleWindow(n));}
|
||
// if (std::string("pillar") == n->Name()) {obstacles.push_back(parseFloorObstaclePillar(n));}
|
||
//if (std::string("obstacle") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));} // OLD
|
||
if (std::string("wall") == n->Name()) {obstacles.push_back(parseFloorObstacleWall(n));}
|
||
if (std::string("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));}
|
||
if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));}
|
||
if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
|
||
if (std::string("object") == n->Name()) {obstacles.push_back(parseFloorObstacleObject(n));}
|
||
}
|
||
return obstacles;
|
||
}
|
||
|
||
/** parse one wall */
|
||
static FloorObstacleWall* parseFloorObstacleWall(const XMLElem* el) {
|
||
|
||
FloorObstacleWall* wall = new FloorObstacleWall(
|
||
parseObstacleType(el->Attribute("type")),
|
||
parseMaterial(el->Attribute("material")),
|
||
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
|
||
el->FloatAttribute("x2"), el->FloatAttribute("y2"),
|
||
(el->FloatAttribute("thickness") > 0) ? (el->FloatAttribute("thickness")) : (0.15), // default wall thickness in m
|
||
el->FloatAttribute("height")
|
||
);
|
||
|
||
// doors
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("door") == n->Name()) {
|
||
FloorObstacleWallDoor* door = new FloorObstacleWallDoor(
|
||
parseDoorType(n->Attribute("type")),
|
||
parseMaterial(n->Attribute("material")),
|
||
n->FloatAttribute("x01"),
|
||
n->FloatAttribute("width"),
|
||
n->FloatAttribute("height"),
|
||
n->BoolAttribute("lr"),
|
||
n->BoolAttribute("io")
|
||
);
|
||
wall->doors.push_back(door);
|
||
}
|
||
}
|
||
|
||
// windows
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("window") == n->Name()) {
|
||
FloorObstacleWallWindow* win = new FloorObstacleWallWindow(
|
||
parseWindowType(n->Attribute("type")),
|
||
parseMaterial(n->Attribute("material")),
|
||
n->FloatAttribute("x01"),
|
||
n->FloatAttribute("y"),
|
||
n->FloatAttribute("width"),
|
||
n->FloatAttribute("height"),
|
||
n->BoolAttribute("io")
|
||
);
|
||
wall->windows.push_back(win);
|
||
}
|
||
}
|
||
|
||
return wall;
|
||
|
||
}
|
||
|
||
/** parse one line */
|
||
static FloorObstacleLine* parseFloorObstacleLine(const XMLElem* el) {
|
||
return new FloorObstacleLine(
|
||
parseObstacleType(el->Attribute("type")),
|
||
parseMaterial(el->Attribute("material")),
|
||
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
|
||
el->FloatAttribute("x2"), el->FloatAttribute("y2"),
|
||
(el->FloatAttribute("thickness") > 0) ? (el->FloatAttribute("thickness")) : (0.15), // default wall thickness in m
|
||
el->FloatAttribute("height")
|
||
);
|
||
}
|
||
|
||
/** parse one cirlce */
|
||
static FloorObstacleCircle* parseFloorObstacleCircle(const XMLElem* el) {
|
||
return new FloorObstacleCircle(
|
||
parseMaterial(el->Attribute("material")),
|
||
el->FloatAttribute("cx"), el->FloatAttribute("cy"),
|
||
el->FloatAttribute("radius"),
|
||
el->FloatAttribute("height")
|
||
);
|
||
}
|
||
|
||
/** parse one door */
|
||
static FloorObstacleDoor* parseFloorObstacleDoor(const XMLElem* el) {
|
||
return new FloorObstacleDoor(
|
||
parseDoorType(el->Attribute("type")),
|
||
parseMaterial(el->Attribute("material")),
|
||
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
|
||
el->FloatAttribute("x2"), el->FloatAttribute("y2"),
|
||
el->FloatAttribute("height"), el->BoolAttribute("swap")
|
||
);
|
||
}
|
||
|
||
/** parse one object */
|
||
static FloorObstacleObject* parseFloorObstacleObject(const XMLElem* el) {
|
||
return new FloorObstacleObject(
|
||
el->Attribute("file"),
|
||
Point3(el->FloatAttribute("x"), el->FloatAttribute("y"), el->FloatAttribute("z")),
|
||
Point3(el->FloatAttribute("rx", 0), el->FloatAttribute("ry", 0), el->FloatAttribute("rz", 0)),
|
||
Point3(el->FloatAttribute("sx", 1), el->FloatAttribute("sy", 1), el->FloatAttribute("sz", 1))
|
||
);
|
||
}
|
||
|
||
/** parse a floor's <outline> tag */
|
||
static FloorOutline parseFloorOutline(const XMLElem* el) {
|
||
FloorOutline outline;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("polygon") == n->Name()) {
|
||
outline.push_back(parseFloorPolygon(n));
|
||
}
|
||
}
|
||
return outline;
|
||
}
|
||
|
||
/** parse one polygon */
|
||
static FloorOutlinePolygon* parseFloorPolygon(const XMLElem* el) {
|
||
FloorOutlinePolygon* poly = new FloorOutlinePolygon();
|
||
poly->name = el->Attribute("name");
|
||
poly->outdoor = el->BoolAttribute("outdoor");
|
||
poly->method = parseOutlineMethod(el->Attribute("method"));
|
||
poly->poly = parsePoly2(el);
|
||
return poly;
|
||
}
|
||
|
||
/** parse a 2d-polygon denoted by several points */
|
||
static Polygon2 parsePoly2(const XMLElem* el) {
|
||
Polygon2 poly;
|
||
FOREACH_NODE(n, el) {
|
||
if (std::string("point") == n->Name()) {
|
||
const Point2 p2 = parsePoint2(n);
|
||
poly.points.push_back(p2);
|
||
}
|
||
}
|
||
return poly;
|
||
}
|
||
|
||
/** parse a 2D point (x,y) using the given tag's attributes. missing attributes are set to 0 */
|
||
static Point2 parsePoint2(const XMLElem* el) {
|
||
Point2 point;
|
||
point.x = el->FloatAttribute("x");
|
||
point.y = el->FloatAttribute("y");
|
||
return point;
|
||
}
|
||
|
||
/** parse a 3D point (x,y,z) using the given tag's attributes. missing attributes are set to 0 */
|
||
static Point3 parsePoint3(const XMLElem* el) {
|
||
Point3 point;
|
||
point.x = el->FloatAttribute("x");
|
||
point.y = el->FloatAttribute("y");
|
||
point.z = el->FloatAttribute("z");
|
||
return point;
|
||
}
|
||
|
||
static ObstacleType parseObstacleType(const std::string type) {
|
||
try {
|
||
return (ObstacleType) std::stoi(type);
|
||
} catch (...) {
|
||
return ObstacleType::UNKNOWN;
|
||
}
|
||
}
|
||
|
||
static DoorType parseDoorType(const std::string type) {
|
||
try { return (DoorType) std::stoi(type); } catch (...) { return DoorType::UNKNOWN; }
|
||
}
|
||
|
||
static WindowType parseWindowType(const std::string type) {
|
||
try { return (WindowType) std::stoi(type); } catch (...) { return WindowType::UNKNOWN; }
|
||
}
|
||
|
||
static Material parseMaterial(const std::string material) {
|
||
try {
|
||
return (Material) std::stoi(material);
|
||
} catch (...) {
|
||
return Material::UNKNOWN;
|
||
}
|
||
}
|
||
|
||
static OutlineMethod parseOutlineMethod(const std::string method) {
|
||
try {
|
||
return (OutlineMethod) std::stoi(method);
|
||
} catch (...) {
|
||
return OutlineMethod::ADD;
|
||
}
|
||
}
|
||
|
||
};
|
||
|
||
}
|
||
|
||
#endif // FLOORPLANREADER_H
|