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/FloorplanWriter.h
kazu 51cab55d37 refactored the new floorplan
new helper methods/operator toe geo classes
2016-05-24 17:01:56 +02:00

244 lines
7.7 KiB
C++

#ifndef FLOORPLANWRITER_H
#define FLOORPLANWRITER_H
#include <iostream>
#include "Floorplan.h"
#include "../../Assertions.h"
#include "../../lib/tinyxml/tinyxml2.h"
namespace Floorplan {
using namespace tinyxml2;
/**
* write floorplans as XML
*/
class Writer {
public:
static void writeToFile(const IndoorMap* map, const std::string& file) {
XMLDocument doc;
construct(doc, map);
doc.SaveFile(file.c_str(), false);
}
static std::string writeToString(const IndoorMap* map) {
XMLDocument doc;
construct(doc, map);
XMLPrinter printer;
doc.Accept( &printer );
return printer.CStr();
}
private:
static std::string toString(const ObstacleType t) {
return std::to_string((int)t);
}
static std::string toString(const Material m) {
return std::to_string((int)m);
}
static std::string toString(const OutlineMethod m) {
return std::to_string((int)m);
}
static void construct(XMLDocument& doc, const IndoorMap* map) {
XMLElement* root = doc.NewElement("map");
doc.InsertEndChild(root);
root->SetAttribute("width", map->width);
root->SetAttribute("depth", map->depth);
// add all floors to the map
addFloors(doc, root, map);
}
/** add all floors to the map */
static void addFloors(XMLDocument& doc, XMLElement* root, const IndoorMap* map) {
XMLElement* floors = doc.NewElement("floors");
for(const Floor* mf : map->floors) {addFloor(doc, floors, mf);}
root->InsertEndChild(floors);
}
/** add one floor to the floors-node */
static void addFloor(XMLDocument& doc, XMLElement* floors, const Floor* mf) {
XMLElement* floor = doc.NewElement("floor");
floor->SetAttribute("atHeight", mf->atHeight);
floor->SetAttribute("height", mf->height);
floor->SetAttribute("name", mf->name.c_str());
floors->InsertEndChild(floor);
addFloorOutline(doc, floor, mf);
addFloorObstacles(doc, floor, mf);
addFloorUnderlays(doc, floor, mf);
// add all sorts of POI
addFloorPOI(doc, floor, mf);
}
/** add all sorts of POI to the floor */
static void addFloorPOI(XMLDocument& doc, XMLElement* floor, const Floor* mf) {
XMLElement* accesspoints = doc.NewElement("accesspoints");
for (const AccessPoint* ap : mf->accesspoints) {
XMLElement* accesspoint = doc.NewElement("accesspoint");
accesspoint->SetAttribute("name", ap->name.c_str());
accesspoint->SetAttribute("mac", ap->mac.c_str());
accesspoint->SetAttribute("x", ap->pos.x);
accesspoint->SetAttribute("y", ap->pos.y);
accesspoint->SetAttribute("z", ap->pos.z);
accesspoints->InsertEndChild(accesspoint);
}
floor->InsertEndChild(accesspoints);
XMLElement* beacons = doc.NewElement("beacons");
for (const Beacon* b : mf->beacons) {
XMLElement* beacon = doc.NewElement("beacon");
beacon->SetAttribute("name", b->name.c_str());
beacon->SetAttribute("mac", b->mac.c_str());
beacon->SetAttribute("x", b->pos.x);
beacon->SetAttribute("y", b->pos.y);
beacon->SetAttribute("z", b->pos.z);
beacons->InsertEndChild(beacon);
}
floor->InsertEndChild(beacons);
}
static void addFloorOutline(XMLDocument& doc, XMLElement* floor, const Floor* mf) {
XMLElement* outline = doc.NewElement("outline");
floor->InsertEndChild(outline);
// XMLElement* add = doc.NewElement("add");
// outline->InsertEndChild(add);
for (const FloorOutlinePolygon* poly : mf->outline) { addFloorOutlinePolygon(doc, outline, poly); }
// XMLElement* remove = doc.NewElement("remove");
// outline->InsertEndChild(remove);
// for (const FloorOutlinePolygon& poly : mf.outline.remove) { addFloorOutlinePolygon(doc, remove, poly); }
}
static void addFloorOutlinePolygon(XMLDocument& doc, XMLElement* dst, const FloorOutlinePolygon* poly) {
std::string method = toString(poly->method);
XMLElement* polygon = doc.NewElement("polygon");
polygon->SetAttribute("name", poly->name.c_str());
polygon->SetAttribute("method", method.c_str());
dst->InsertEndChild(polygon);
for (Point2 p : poly->poly.points) {
XMLElement* point = doc.NewElement("point");
point->SetAttribute("x", p.x);
point->SetAttribute("y", p.y);
// skip the z-attribute as the value is also given by the polygons floor: floor.atHeight
polygon->InsertEndChild(point);
}
}
/** write one <keyval> element */
static void addKeyValueElement(XMLDocument& doc, XMLElement* other, const KeyValueElement* kv) {
XMLElement* elem = doc.NewElement("keyval");
for (auto it : kv->params) {
elem->Attribute(it.first.c_str(), it.second.c_str());
}
other->InsertEndChild(elem);
}
/** write the <underlays> tag */
static void addFloorUnderlays(XMLDocument& doc, XMLElement* floor, const Floor* mf) {
XMLElement* other = doc.NewElement("underlays");
for (const UnderlayImage* kv : mf->underlays) {
addFloorUnderlay(doc, other, kv);
}
floor->InsertEndChild(other);
}
/** write one underlay */
static void addFloorUnderlay(XMLDocument& doc, XMLElement* underlays, const UnderlayImage* img) {
XMLElement* underlay = doc.NewElement("underlay");
underlay->SetAttribute("x", img->anchor.x);
underlay->SetAttribute("y", img->anchor.y);
underlay->SetAttribute("sx", img->scaleX);
underlay->SetAttribute("sy", img->scaleY);
underlay->SetAttribute("name", img->name.c_str());
underlay->SetAttribute("file", img->filename.c_str());
underlays->InsertEndChild(underlay);
}
// /** write the <other> tag */
// static void addFloorKeyValue(XMLDocument& doc, XMLElement* floor, const Floor* mf) {
// XMLElement* other = doc.NewElement("other");
// for (const KeyValueElement* kv : mf->other.elements) {
// addKeyValueElement(doc, other, kv);
// }
// floor->InsertEndChild(other);
// }
static void addFloorObstacles(XMLDocument& doc, XMLElement* floor, const Floor* mf) {
XMLElement* obstacles = doc.NewElement("obstacles");
for (FloorObstacle* fo : mf->obstacles) {
if (dynamic_cast<FloorObstacleLine*>(fo)) {
addFloorObstacleLine(doc, obstacles, (FloorObstacleLine*)fo);
} else if (dynamic_cast<FloorObstacleCircle*>(fo)) {
addFloorObstacleCircle(doc, obstacles, (FloorObstacleCircle*)fo);
}
}
floor->InsertEndChild(obstacles);
}
static void addFloorObstacleLine(XMLDocument& doc, XMLElement* obstacles, FloorObstacleLine* line) {
XMLElement* obstacle = doc.NewElement("line");
const std::string type = toString(line->type);
const std::string material = toString(line->material);
obstacle->SetAttribute("material", material.c_str());
obstacle->SetAttribute("type", type.c_str());
obstacle->SetAttribute("x1", line->from.x);
obstacle->SetAttribute("y1", line->from.y);
obstacle->SetAttribute("x2", line->to.x);
obstacle->SetAttribute("y2", line->to.y);
obstacles->InsertEndChild(obstacle);
}
static void addFloorObstacleCircle(XMLDocument& doc, XMLElement* obstacles, FloorObstacleCircle* circle) {
XMLElement* obstacle = doc.NewElement("line");
const std::string type = toString(circle->type);
const std::string material = toString(circle->material);
obstacle->SetAttribute("material", material.c_str());
obstacle->SetAttribute("type", type.c_str());
obstacle->SetAttribute("cx", circle->center.x);
obstacle->SetAttribute("cy", circle->center.y);
obstacle->SetAttribute("radius", circle->radius);
obstacles->InsertEndChild(obstacle);
}
};
}
#endif // FLOORPLANWRITER_H