- some should be the same as previous commit (sorry!) - some should be new: LINT checks, ...?
123 lines
2.6 KiB
C++
123 lines
2.6 KiB
C++
#ifndef WIFIMODELPERFLOOR_H
|
|
#define WIFIMODELPERFLOOR_H
|
|
|
|
#include "../AccessPoint.h"
|
|
#include "../../../geo/Point3.h"
|
|
#include <vector>
|
|
|
|
#include "WiFiModelFactory.h"
|
|
|
|
/**
|
|
* FOR TESTING
|
|
*
|
|
* this model allows using a different sub-models for each floor to reduce the error
|
|
*/
|
|
class WiFiModelPerFloor : public WiFiModel {
|
|
|
|
struct ModelForFloor {
|
|
|
|
float fromZ;
|
|
float toZ;
|
|
WiFiModel* mdl;
|
|
|
|
/** ctor */
|
|
ModelForFloor(const float fromZ, const float toZ, WiFiModel* mdl) : fromZ(fromZ), toZ(toZ), mdl(mdl) {;}
|
|
|
|
/** does this entry apply to the given z-position? */
|
|
bool matches(const float z) const {
|
|
return (fromZ <= z && z < toZ);
|
|
}
|
|
|
|
};
|
|
|
|
Floorplan::IndoorMap* map;
|
|
|
|
/** all contained models [one per floor] */
|
|
std::vector<ModelForFloor> models;
|
|
|
|
public:
|
|
|
|
WiFiModelPerFloor(Floorplan::IndoorMap* map) : map(map) {
|
|
;
|
|
}
|
|
|
|
/** dtor */
|
|
virtual ~WiFiModelPerFloor() {
|
|
|
|
}
|
|
|
|
|
|
/** get a list of all APs known to the model */
|
|
std::vector<AccessPoint> getAllAPs() const override {
|
|
return models.front().mdl->getAllAPs();
|
|
}
|
|
|
|
void add(WiFiModel* mdl, const Floorplan::Floor* floor) {
|
|
ModelForFloor mff(floor->atHeight, floor->atHeight+floor->height, mdl);
|
|
models.push_back(mff);
|
|
}
|
|
|
|
float getRSSI(const MACAddress& accessPoint, const Point3 position_m) const override {
|
|
|
|
for (const ModelForFloor& mff : models) {
|
|
if (mff.matches(position_m.z)) {return mff.mdl->getRSSI(accessPoint, position_m);}
|
|
}
|
|
|
|
return -120;
|
|
|
|
}
|
|
|
|
void readFromXML(XMLDoc* doc, XMLElem* src) override {
|
|
|
|
// check type
|
|
if (std::string("WiFiModelPerFloor") != 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("floor", xfloor, src) {
|
|
|
|
// floor params
|
|
const float z1 = xfloor->FloatAttribute("z1");
|
|
const float z2 = xfloor->FloatAttribute("z2");
|
|
|
|
// node for the model
|
|
XMLElem* xmodel = xfloor->FirstChildElement("model");
|
|
|
|
// let the factory instantiate the model
|
|
WiFiModel* mdl = fac.readFromXML(doc, xmodel);
|
|
|
|
// add
|
|
models.push_back(ModelForFloor(z1, z2, mdl));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void writeToXML(XMLDoc* doc, XMLElem* dst) override {
|
|
|
|
// set my type
|
|
dst->SetAttribute("type", "WiFiModelPerFloor");
|
|
|
|
for (const ModelForFloor& mff : models) {
|
|
|
|
XMLElem* xfloor = doc->NewElement("floor"); {
|
|
xfloor->SetAttribute("z1", mff.fromZ);
|
|
xfloor->SetAttribute("z2", mff.toZ);
|
|
XMLElem* xmodel = doc->NewElement("model"); {
|
|
mff.mdl->writeToXML(doc, xmodel);
|
|
}; xfloor->InsertEndChild(xmodel);
|
|
}; dst->InsertEndChild(xfloor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
#endif // WIFIMODELPERFLOOR_H
|