177 lines
4.1 KiB
C++
177 lines
4.1 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.
|
||
* Keine Verwendung ohne explizite Genehmigung.
|
||
* (vgl. § 106 ff UrhG / § 97 UrhG)
|
||
*/
|
||
|
||
#ifndef WIFIMODELPERBBOX_H
|
||
#define WIFIMODELPERBBOX_H
|
||
|
||
#include "../AccessPoint.h"
|
||
#include "../../../geo/Point3.h"
|
||
#include "../../../geo/BBoxes3.h"
|
||
#include <vector>
|
||
|
||
#include "WiFiModelFactory.h"
|
||
|
||
/**
|
||
* FOR TESTING
|
||
*
|
||
* this model allows using a different sub-models
|
||
* identified by a bound-box to reduce the error
|
||
*/
|
||
class WiFiModelPerBBox : public WiFiModel {
|
||
|
||
struct ModelForBBoxes {
|
||
|
||
WiFiModel* mdl;
|
||
BBoxes3 bboxes;
|
||
|
||
/** ctor */
|
||
ModelForBBoxes(WiFiModel* mdl, BBoxes3 bboxes) : mdl(mdl), bboxes(bboxes) {;}
|
||
|
||
/** does this entry apply to the given position? */
|
||
bool matches(const Point3 pt) const {
|
||
if (bboxes.get().empty()) {throw Exception("no bbox(es) given for model!");}
|
||
return bboxes.contains(pt);
|
||
}
|
||
|
||
};
|
||
|
||
Floorplan::IndoorMap* map;
|
||
|
||
/** all contained models [one per bbox] */
|
||
std::vector<ModelForBBoxes> models;
|
||
|
||
public:
|
||
|
||
WiFiModelPerBBox(Floorplan::IndoorMap* map) : map(map) {
|
||
;
|
||
}
|
||
|
||
/** dtor */
|
||
virtual ~WiFiModelPerBBox() {
|
||
|
||
}
|
||
|
||
|
||
/** get a list of all APs known to the model */
|
||
std::vector<AccessPoint> getAllAPs() const override {
|
||
|
||
// combine all submodels
|
||
std::vector<AccessPoint> res;
|
||
for (const ModelForBBoxes& sub : models) {
|
||
for (const AccessPoint& ap : sub.mdl->getAllAPs()) {
|
||
if (std::find(res.begin(), res.end(), ap) == res.end()) { // TODO use map instead?
|
||
res.push_back(ap);
|
||
}
|
||
}
|
||
}
|
||
return res;
|
||
|
||
}
|
||
|
||
void add(WiFiModel* mdl, const BBoxes3 bboxes) {
|
||
if (bboxes.get().empty()) {throw Exception("no bbox(es) given for model!");}
|
||
ModelForBBoxes mfb(mdl, bboxes);
|
||
models.push_back(mfb);
|
||
}
|
||
|
||
float getRSSI(const MACAddress& accessPoint, const Point3 position_m) const override {
|
||
|
||
for (const ModelForBBoxes& mfb : models) {
|
||
if (mfb.matches(position_m)) {return mfb.mdl->getRSSI(accessPoint, position_m);}
|
||
}
|
||
|
||
return -120;
|
||
|
||
}
|
||
|
||
void readFromXML(XMLDoc* doc, XMLElem* src) override {
|
||
|
||
// check type
|
||
if (std::string("WiFiModelPerBBox") != src->Attribute("type")) {throw Exception("invalid model type");}
|
||
|
||
models.clear();
|
||
|
||
// model factory [create models based on XMl content]
|
||
WiFiModelFactory fac(map);
|
||
|
||
// parse all contained models [one per floor]
|
||
XML_FOREACH_ELEM_NAMED("entry", xentry, src) {
|
||
|
||
// all bboxes
|
||
BBoxes3 bboxes;
|
||
XML_FOREACH_ELEM_NAMED("bbox", xbbox, xentry) {
|
||
|
||
const float x1 = xbbox->FloatAttribute("x1");
|
||
const float y1 = xbbox->FloatAttribute("y1");
|
||
const float z1 = xbbox->FloatAttribute("z1");
|
||
|
||
const float x2 = xbbox->FloatAttribute("x2");
|
||
const float y2 = xbbox->FloatAttribute("y2");
|
||
const float z2 = xbbox->FloatAttribute("z2");
|
||
|
||
const BBox3 bbox(Point3(x1,y1,z1), Point3(x2,y2,z2));
|
||
bboxes.add(bbox);
|
||
|
||
}
|
||
|
||
// node for the model
|
||
XMLElem* xmodel = xentry->FirstChildElement("model");
|
||
|
||
// let the factory instantiate the model
|
||
WiFiModel* mdl = fac.readFromXML(doc, xmodel);
|
||
|
||
// add
|
||
models.push_back(ModelForBBoxes(mdl, bboxes));
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void writeToXML(XMLDoc* doc, XMLElem* dst) override {
|
||
|
||
// set my type
|
||
dst->SetAttribute("type", "WiFiModelPerBBox");
|
||
|
||
for (const ModelForBBoxes& mfb : models) {
|
||
|
||
// all models
|
||
XMLElem* xentry = doc->NewElement("entry"); {
|
||
|
||
// each bbox
|
||
for (const BBox3& bbox : mfb.bboxes.get()) {
|
||
XMLElem* xbbox = doc->NewElement("bbox"); {
|
||
|
||
xbbox->SetAttribute("x1", bbox.getMin().x);
|
||
xbbox->SetAttribute("y1", bbox.getMin().y);
|
||
xbbox->SetAttribute("z1", bbox.getMin().z);
|
||
|
||
xbbox->SetAttribute("x2", bbox.getMax().x);
|
||
xbbox->SetAttribute("y2", bbox.getMax().y);
|
||
xbbox->SetAttribute("z2", bbox.getMax().z);
|
||
|
||
}; xentry->InsertFirstChild(xbbox);
|
||
}
|
||
|
||
// the corresponding model
|
||
XMLElem* xmodel = doc->NewElement("model"); {
|
||
mfb.mdl->writeToXML(doc, xmodel);
|
||
}; xentry->InsertEndChild(xmodel);
|
||
|
||
}; dst->InsertEndChild(xentry);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
};
|
||
|
||
|
||
#endif // WIFIMODELPERBBOX_H
|