worked on floorplan (v2)
worked on grid-generation (v2) new helper methods for geometry new test cases
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
|
||||
namespace Floorplan {
|
||||
|
||||
using namespace tinyxml2;
|
||||
using XMLAttr = tinyxml2::XMLAttribute;
|
||||
using XMLElem = tinyxml2::XMLElement;
|
||||
|
||||
/**
|
||||
* read an IndoorMaps from XML-data
|
||||
@@ -22,35 +23,37 @@ namespace Floorplan {
|
||||
/** 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());
|
||||
tinyxml2::XMLDocument doc;
|
||||
const tinyxml2::XMLError res = doc.LoadFile(file.c_str());
|
||||
if (res != tinyxml2::XMLError::XML_SUCCESS) {throw Exception("error while loading XML " + file);}
|
||||
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());
|
||||
tinyxml2::XMLDocument doc;
|
||||
const tinyxml2::XMLError res = doc.Parse(str.c_str(), str.length());
|
||||
if (res != tinyxml2::XMLError::XML_SUCCESS) {throw Exception("error while parsing XML");}
|
||||
return parse(doc);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#define FOREACH_NODE(out, in) for( const XMLElement* out = (XMLElement*) in->FirstChild(); out; out = (XMLElement*) out->NextSibling() )
|
||||
#define FOREACH_NODE(out, in) for( const XMLElem* out = (XMLElem*) in->FirstChild(); out; out = (XMLElem*) out->NextSibling() )
|
||||
|
||||
static void assertNode(const std::string& node, const XMLElement* el) {
|
||||
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(XMLDocument& doc) {
|
||||
return parseMap((XMLElement*)doc.FirstChild());
|
||||
static IndoorMap* parse(tinyxml2::XMLDocument& doc) {
|
||||
return parseMap((XMLElem*)doc.FirstChild());
|
||||
}
|
||||
|
||||
/** parse the <map> node */
|
||||
static IndoorMap* parseMap(const XMLElement* el) {
|
||||
static IndoorMap* parseMap(const XMLElem* el) {
|
||||
std::cout << el->Name() << std::endl;
|
||||
IndoorMap* map = new IndoorMap();
|
||||
map->width = el->FloatAttribute("width");
|
||||
@@ -62,7 +65,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse the <floors> node */
|
||||
static std::vector<Floor*> parseFloors(const XMLElement* el) {
|
||||
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));}
|
||||
@@ -71,25 +74,91 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse one <floor> node */
|
||||
static Floor* parseFloor(const XMLElement* el) {
|
||||
static Floor* parseFloor(const XMLElem* 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("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);}
|
||||
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);}
|
||||
if (std::string("pois") == n->Name()) {floor->pois = parseFloorPOIs(n);}
|
||||
if (std::string("stairs") == n->Name()) {floor->stairs = parseFloorStairs(n);}
|
||||
}
|
||||
return floor;
|
||||
}
|
||||
|
||||
|
||||
/** parse the <stairs> tag */
|
||||
static std::vector<Stair*> parseFloorStairs(const XMLElem* el) {
|
||||
std::vector<Stair*> vec;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("stair") == n->Name()) { vec.push_back(parseFloorStair(n)); }
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
/** 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->meta = parseMetaElement(meta);
|
||||
}
|
||||
|
||||
return stair;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** parse the <pois> tag */
|
||||
static std::vector<POI*> parseFloorPOIs(const XMLElem* el) {
|
||||
std::vector<POI*> 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 <accesspoints> tag */
|
||||
static std::vector<AccessPoint*> parseFloorAccessPoints(const XMLElement* el) {
|
||||
assertNode("accesspoints", el);
|
||||
static std::vector<AccessPoint*> parseFloorAccessPoints(const XMLElem* el) {
|
||||
std::vector<AccessPoint*> vec;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("accesspoint") == n->Name()) { vec.push_back(parseAccessPoint(n)); }
|
||||
@@ -97,29 +166,29 @@ namespace Floorplan {
|
||||
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 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 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 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 XMLElement* el) {
|
||||
// static FloorKeyValue parseFloorKeyValue(const XMLElem* el) {
|
||||
// FloorKeyValue res;
|
||||
// FOREACH_NODE(n, el) {
|
||||
// if (std::string("keyval") == n->Name()) { res.elements.push_back(parseKeyValueElement(n)); }
|
||||
@@ -127,10 +196,10 @@ namespace Floorplan {
|
||||
// return res;
|
||||
// }
|
||||
|
||||
/** parse one <keyval> element */
|
||||
static KeyValueElement* parseKeyValueElement(const XMLElement* n) {
|
||||
KeyValueElement* elem = new KeyValueElement();
|
||||
const XMLAttribute* attr = n->FirstAttribute();
|
||||
/** parse one <meta> element */
|
||||
static Meta* parseMetaElement(const XMLElem* n) {
|
||||
Meta* elem = new Meta();
|
||||
const XMLAttr* attr = n->FirstAttribute();
|
||||
while (attr) {
|
||||
elem->params[attr->Name()] = attr->Value();
|
||||
attr = attr->Next();
|
||||
@@ -138,7 +207,7 @@ namespace Floorplan {
|
||||
return elem;
|
||||
}
|
||||
|
||||
static AccessPoint* parseAccessPoint(const XMLElement* n) {
|
||||
static AccessPoint* parseAccessPoint(const XMLElem* n) {
|
||||
assertNode("accesspoint", n);
|
||||
AccessPoint* ap = new AccessPoint();
|
||||
ap->mac = n->Attribute("mac");
|
||||
@@ -149,7 +218,7 @@ namespace Floorplan {
|
||||
|
||||
|
||||
/** parse the <beacons> tag */
|
||||
static std::vector<Beacon*> parseFloorBeacons(const XMLElement* el) {
|
||||
static std::vector<Beacon*> parseFloorBeacons(const XMLElem* el) {
|
||||
std::vector<Beacon*> vec;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("beacon") == n->Name()) { vec.push_back(parseBeacon(n)); }
|
||||
@@ -157,7 +226,7 @@ namespace Floorplan {
|
||||
return vec;
|
||||
}
|
||||
|
||||
static Beacon* parseBeacon(const XMLElement* n) {
|
||||
static Beacon* parseBeacon(const XMLElem* n) {
|
||||
assertNode("beacon", n);
|
||||
Beacon* b = new Beacon();
|
||||
b->mac = n->Attribute("mac");
|
||||
@@ -167,7 +236,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
|
||||
static std::vector<FloorRegion*> parseFloorRegions(const XMLElement* el) {
|
||||
static std::vector<FloorRegion*> parseFloorRegions(const XMLElem* el) {
|
||||
std::vector<FloorRegion*> vec;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("region") == n->Name()) { vec.push_back(parseFloorRegion(n)); }
|
||||
@@ -175,7 +244,7 @@ namespace Floorplan {
|
||||
return vec;
|
||||
}
|
||||
|
||||
static FloorRegion* parseFloorRegion(const XMLElement* n) {
|
||||
static FloorRegion* parseFloorRegion(const XMLElem* n) {
|
||||
assertNode("region", n);
|
||||
FloorRegion* reg = new FloorRegion();
|
||||
reg->name = n->Attribute("name");
|
||||
@@ -184,7 +253,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse the <obstacles> tag */
|
||||
static std::vector<FloorObstacle*> parseFloorObstacles(const XMLElement* el) {
|
||||
static std::vector<FloorObstacle*> parseFloorObstacles(const XMLElem* el) {
|
||||
assertNode("obstacles", el);
|
||||
std::vector<FloorObstacle*> obstacles;
|
||||
FOREACH_NODE(n, el) {
|
||||
@@ -192,38 +261,46 @@ namespace Floorplan {
|
||||
// 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));}
|
||||
//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));}
|
||||
if (std::string("door") == n->Name()) {obstacles.push_back(parseFloorObstacleDoor(n));}
|
||||
}
|
||||
return obstacles;
|
||||
}
|
||||
|
||||
/** parse one line */
|
||||
static FloorObstacleLine* parseFloorObstacleLine(const XMLElement* el) {
|
||||
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")
|
||||
// parsePoint2((XMLElement*) el->FirstChildElement("from")),
|
||||
// parsePoint2((XMLElement*) el->FirstChildElement("to"))
|
||||
);
|
||||
parseObstacleType(el->Attribute("type")),
|
||||
parseMaterial(el->Attribute("material")),
|
||||
el->FloatAttribute("x1"), el->FloatAttribute("y1"),
|
||||
el->FloatAttribute("x2"), el->FloatAttribute("y2")
|
||||
);
|
||||
}
|
||||
|
||||
/** parse one cirlce */
|
||||
static FloorObstacleCircle* parseFloorObstacleCircle(const XMLElement* el) {
|
||||
static FloorObstacleCircle* parseFloorObstacleCircle(const XMLElem* 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")
|
||||
);
|
||||
parseMaterial(el->Attribute("material")),
|
||||
el->FloatAttribute("cx"), el->FloatAttribute("cy"),
|
||||
el->FloatAttribute("radius")
|
||||
);
|
||||
}
|
||||
|
||||
/** 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 a floor's <outline> tag */
|
||||
static FloorOutline parseFloorOutline(const XMLElement* el) {
|
||||
static FloorOutline parseFloorOutline(const XMLElem* el) {
|
||||
FloorOutline outline;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("polygon") == n->Name()) {
|
||||
@@ -234,7 +311,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse one polygon */
|
||||
static FloorOutlinePolygon* parseFloorPolygon(const XMLElement* el) {
|
||||
static FloorOutlinePolygon* parseFloorPolygon(const XMLElem* el) {
|
||||
FloorOutlinePolygon* poly = new FloorOutlinePolygon();
|
||||
poly->name = el->Attribute("name");
|
||||
poly->method = parseOutlineMethod(el->Attribute("method"));
|
||||
@@ -243,7 +320,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse a 2d-polygon denoted by several points */
|
||||
static Polygon2 parsePoly2(const XMLElement* el) {
|
||||
static Polygon2 parsePoly2(const XMLElem* el) {
|
||||
Polygon2 poly;
|
||||
FOREACH_NODE(n, el) {
|
||||
if (std::string("point") == n->Name()) {
|
||||
@@ -255,7 +332,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** parse a 2D point (x,y) using the given tag's attributes. missing attributes are set to 0 */
|
||||
static Point2 parsePoint2(const XMLElement* el) {
|
||||
static Point2 parsePoint2(const XMLElem* el) {
|
||||
Point2 point;
|
||||
point.x = el->FloatAttribute("x");
|
||||
point.y = el->FloatAttribute("y");
|
||||
@@ -263,7 +340,7 @@ namespace Floorplan {
|
||||
}
|
||||
|
||||
/** 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) {
|
||||
static Point3 parsePoint3(const XMLElem* el) {
|
||||
Point3 point;
|
||||
point.x = el->FloatAttribute("x");
|
||||
point.y = el->FloatAttribute("y");
|
||||
@@ -279,6 +356,10 @@ namespace Floorplan {
|
||||
}
|
||||
}
|
||||
|
||||
static DoorType parseDoorType(const std::string type) {
|
||||
try { return (DoorType) std::stoi(type); } catch (...) { return DoorType::UNKNOWN; }
|
||||
}
|
||||
|
||||
static Material parseMaterial(const std::string material) {
|
||||
try {
|
||||
return (Material) std::stoi(material);
|
||||
|
||||
Reference in New Issue
Block a user