This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/floorplan/v2/FloorplanReader.h
kazu 51cab55d37 refactored the new floorplan
new helper methods/operator toe geo classes
2016-05-24 17:01:56 +02:00

303 lines
9.7 KiB
C++

#ifndef FLOORPLANREADER_H
#define FLOORPLANREADER_H
#include <iostream>
#include "Floorplan.h"
#include "../../Assertions.h"
#include "../../lib/tinyxml/tinyxml2.h"
namespace Floorplan {
using namespace tinyxml2;
/**
* read an IndoorMaps from XML-data
*/
class Reader {
public:
/** read an IndoorMap from the given XML-file */
static IndoorMap* readFromFile(const std::string& file) {
setlocale(LC_NUMERIC, "C");
XMLDocument doc;
doc.LoadFile(file.c_str());
return parse(doc);
}
/** read an IndoorMap from the given XMl-string */
static IndoorMap* readFromString(const std::string& str) {
setlocale(LC_NUMERIC, "C");
XMLDocument doc;
doc.Parse(str.c_str(), str.length());
return parse(doc);
}
private:
#define FOREACH_NODE(out, in) for( const XMLElement* out = (XMLElement*) in->FirstChild(); out; out = (XMLElement*) out->NextSibling() )
static void assertNode(const std::string& node, const XMLElement* 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(XMLDocument& doc) {
return parseMap((XMLElement*)doc.FirstChild());
}
/** parse the <map> node */
static IndoorMap* parseMap(const XMLElement* el) {
std::cout << el->Name() << std::endl;
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);}
}
return map;
}
/** parse the <floors> node */
static std::vector<Floor*> parseFloors(const XMLElement* 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 XMLElement* el) {
Floor* floor = new Floor();
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("regions") == n->Name()) {floor->regions = parseFloorRegions(n);}
if (std::string("underlays") == n->Name()) {floor->underlays = parseFloorUnderlays(n);}
}
return floor;
}
/** parse the <accesspoints> tag */
static std::vector<AccessPoint*> parseFloorAccessPoints(const XMLElement* el) {
assertNode("accesspoints", el);
std::vector<AccessPoint*> 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 XMLElement* 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 XMLElement* 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 XMLElement* el) {
// FloorKeyValue res;
// FOREACH_NODE(n, el) {
// if (std::string("keyval") == n->Name()) { res.elements.push_back(parseKeyValueElement(n)); }
// }
// return res;
// }
/** parse one <keyval> element */
static KeyValueElement* parseKeyValueElement(const XMLElement* n) {
KeyValueElement* elem = new KeyValueElement();
const XMLAttribute* attr = n->FirstAttribute();
while (attr) {
elem->params[attr->Name()] = attr->Value();
attr = attr->Next();
}
return elem;
}
static AccessPoint* parseAccessPoint(const XMLElement* n) {
assertNode("accesspoint", n);
AccessPoint* ap = new AccessPoint();
ap->mac = n->Attribute("mac");
ap->name = n->Attribute("name");
ap->pos = parsePoint3(n);
return ap;
}
/** parse the <beacons> tag */
static std::vector<Beacon*> parseFloorBeacons(const XMLElement* el) {
std::vector<Beacon*> vec;
FOREACH_NODE(n, el) {
if (std::string("beacon") == n->Name()) { vec.push_back(parseBeacon(n)); }
}
return vec;
}
static Beacon* parseBeacon(const XMLElement* n) {
assertNode("beacon", n);
Beacon* b = new Beacon();
b->mac = n->Attribute("mac");
b->name = n->Attribute("name");
b->pos = parsePoint3(n);
return b;
}
static std::vector<FloorRegion*> parseFloorRegions(const XMLElement* el) {
std::vector<FloorRegion*> vec;
FOREACH_NODE(n, el) {
if (std::string("region") == n->Name()) { vec.push_back(parseFloorRegion(n)); }
}
return vec;
}
static FloorRegion* parseFloorRegion(const XMLElement* n) {
assertNode("region", n);
FloorRegion* reg = new FloorRegion();
reg->name = n->Attribute("name");
reg->poly = parsePoly2(n);
return reg;
}
/** parse the <obstacles> tag */
static std::vector<FloorObstacle*> parseFloorObstacles(const XMLElement* el) {
assertNode("obstacles", el);
std::vector<FloorObstacle*> 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("line") == n->Name()) {obstacles.push_back(parseFloorObstacleLine(n));}
if (std::string("circle") == n->Name()) {obstacles.push_back(parseFloorObstacleCircle(n));}
}
return obstacles;
}
/** parse one line */
static FloorObstacleLine* parseFloorObstacleLine(const XMLElement* el) {
return new FloorObstacleLine(
parseObstacleType(el->Attribute("type")),
parseMaterial(el->Attribute("material")),
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
el->FloatAttribute("x2"), el->FloatAttribute("y2")
// parsePoint2((XMLElement*) el->FirstChildElement("from")),
// parsePoint2((XMLElement*) el->FirstChildElement("to"))
);
}
/** parse one cirlce */
static FloorObstacleCircle* parseFloorObstacleCircle(const XMLElement* el) {
return new FloorObstacleCircle(
parseObstacleType(el->Attribute("type")),
parseMaterial(el->Attribute("material")),
el->FloatAttribute("cx"), el->FloatAttribute("cy"),
//parsePoint2((XMLElement*) el->FirstChildElement("from")),
el->FloatAttribute("radius")
);
}
/** parse a floor's <outline> tag */
static FloorOutline parseFloorOutline(const XMLElement* el) {
FloorOutline outline;
FOREACH_NODE(n, el) {
if (std::string("polygon") == n->Name()) {
outline.push_back(parseFloorPolygon(n)); // TODO
}
}
return outline;
}
/** parse one polygon */
static FloorOutlinePolygon* parseFloorPolygon(const XMLElement* el) {
FloorOutlinePolygon* poly = new FloorOutlinePolygon();
poly->name = el->Attribute("name");
poly->method = parseOutlineMethod(el->Attribute("method"));
poly->poly = parsePoly2(el);
return poly;
}
/** parse a 2d-polygon denoted by several points */
static Polygon2 parsePoly2(const XMLElement* 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 XMLElement* 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 XMLElement* 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 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