Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYBoundaryNoiseMap.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 #include <qdir.h>
17 
18 #include "Tympan/core/config.h"
19 #include "Tympan/core/logging.h"
22 #include "TYBoundaryNoiseMap.h"
23 #if TY_USE_IHM
26 #endif
27 
28 #undef min
29 #undef max
30 
32 
41 double compute_segment_point_square_distance(double point_x, double point_y, double a_x, double a_y,
42  double b_x, double b_y)
43 {
44  double l2 = (a_x - b_x) * (a_x - b_x) + (a_y - b_y) * (a_y - b_y);
45  if (l2 != 0)
46  {
47  double t = ((point_x - a_x) * (b_x - a_x) + (point_y - a_y) * (b_y - a_y)) / l2;
48  if (t < 0)
49  {
50  return (point_x - a_x) * (point_x - a_x) + (point_y - a_y) * (point_y - a_y);
51  }
52  else if (t > 1)
53  {
54  return (point_x - b_x) * (point_x - b_x) + (point_y - b_y) * (point_y - b_y);
55  }
56  else
57  {
58  return (point_x - (a_x + t * (b_x - a_x))) * (point_x - (a_x + t * (b_x - a_x))) +
59  (point_y - (a_y + t * (b_y - a_y))) * (point_y - (a_y + t * (b_y - a_y)));
60  }
61  }
62  return (point_x - a_x) * (point_x - a_x) + (point_y - a_y) * (point_y - a_y);
63 }
64 
67 
69 {
71 
72  _thickness = 0.1;
73  _closed = false;
74  _canBeClosed = true;
75  _density = 0.1;
76  _posLabel = TYPoint(0, 0, 0);
77 }
78 
80 {
81  *this = rhs;
82 }
83 
85 
87 {
88  if (this != &rhs)
89  {
91  _thickness = rhs._thickness;
92  _closed = rhs._closed;
93  _density = rhs._density;
94  _nbPointsY = rhs._nbPointsY;
95  _tabPoint = rhs._tabPoint;
97  }
98  return *this;
99 }
100 
102 {
103  if (this != &rhs)
104  {
105  if (TYMaillage::operator!=(rhs))
106  {
107  return false;
108  }
109  if (!(_thickness == rhs._thickness))
110  {
111  return false;
112  }
113  if (!(_closed == rhs._closed))
114  {
115  return false;
116  }
117  if (!(_density == rhs._density))
118  {
119  return false;
120  }
121  }
122  return true;
123 }
124 
126 {
127  return !operator==(rhs);
128 }
129 
130 bool TYBoundaryNoiseMap::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
131 {
132  if (!TYMaillage::deepCopy(pOther, copyId))
133  {
134  return false;
135  }
136 
137  const TYBoundaryNoiseMap* pOtherMaillage = static_cast<const TYBoundaryNoiseMap*>(pOther);
138  if (!pOtherMaillage)
139  {
140  return false;
141  }
142 
143  _thickness = pOtherMaillage->_thickness;
144  _closed = pOtherMaillage->_closed;
145  _density = pOtherMaillage->_density;
146 
147  return true;
148 }
149 
150 std::string TYBoundaryNoiseMap::toString() const
151 {
152  return "TYBoundaryNoiseMap";
153 }
154 
156 {
157  DOM_Element domNewElem = TYMaillage::toXML(domElement);
158 
159  TYXMLTools::addElementDoubleValue(domNewElem, "thickness", _thickness);
160  TYXMLTools::addElementBoolValue(domNewElem, "closed", _closed);
161  TYXMLTools::addElementDoubleValue(domNewElem, "density", _density);
162 
163  TYXMLTools::addElementUIntValue(domNewElem, "nbPoints", _tabPoint.size());
164 
165  size_t nbPoints = _tabPoint.size();
166  for (size_t i = 0; i < nbPoints; ++i)
167  {
168  _tabPoint[i].toXML(domNewElem);
169  }
170 
171  return domNewElem;
172 }
173 
175 {
176  TYMaillage::fromXML(domElement);
177 
178  bool nbPointsIsOk = false;
179  bool bOldDatas = false;
180 
181  int nbPoints = 0;
182  TYPoint pt;
183 
184  LPTYSpectre pSpectre = new TYSpectre();
185  TYTabLPSpectre* compatibilityVector = new TYTabLPSpectre();
186 
187  DOM_Element elemCur;
188 
189  QDomNodeList childs = domElement.childNodes();
190  for (unsigned int i = 0; i < childs.length(); i++)
191  {
192  elemCur = childs.item(i).toElement();
193 
194  TYXMLTools::getElementDoubleValue(elemCur, "thickness", _thickness);
195  TYXMLTools::getElementBoolValue(elemCur, "closed", _closed);
196  TYXMLTools::getElementDoubleValue(elemCur, "density", _density);
197 
198  TYXMLTools::getElementIntValue(elemCur, "nbPoints", nbPoints, nbPointsIsOk);
199 
200  if (pt.callFromXMLIfEqual(elemCur))
201  {
202  _tabPoint.push_back(pt);
203  }
204 
205  // Old version : if we encounter spectra
206  if (pSpectre->callFromXMLIfEqual(elemCur))
207  {
208  bOldDatas = true;
209  compatibilityVector->push_back(pSpectre);
210  pSpectre = new TYSpectre();
211  }
212  }
213 
214  if (bOldDatas == true)
215  {
216  setAllUses((void*)compatibilityVector);
217  }
218  else
219  {
220  delete compatibilityVector;
221  }
222 
225 
226  return 1;
227 }
228 
229 bool TYBoundaryNoiseMap::toXML(const std::string& sFilePath)
230 {
231  bool bRet = false;
232  QString fileName = QString(sFilePath.c_str());
233  int i = fileName.lastIndexOf('/');
234  QDir fileDirectory = QDir(fileName.mid(0, i));
235  if (!fileDirectory.exists())
236  {
237  fileDirectory.mkdir(fileName.mid(0, i));
238  }
239 
240  if (fileName.isEmpty())
241  {
242  return false;
243  }
244  if (!fileName.endsWith(".xml"))
245  {
246  fileName += ".xml";
247  }
248 
249  TYXMLManager xmlManager;
250 
251  xmlManager.createDoc(TY_PRODUCT_XMLTAG_, TY_PRODUCT_VERSION_);
252  xmlManager.addElement(this);
253 
254  if (xmlManager.save(fileName) == 0)
255  {
256  bRet = true;
257  }
258 
259  return bRet;
260 }
261 
262 bool TYBoundaryNoiseMap::fromXML(const std::string& sFilePath)
263 {
264  bool bRet = false;
265  QString fileName = QString(sFilePath.c_str());
266 
267  if (fileName.isEmpty())
268  {
269  return false;
270  }
271 
272  TYXMLManager xmlManager;
273  LPTYElementArray elements;
274  if (xmlManager.load(fileName, elements))
275  {
276  if (elements.size() == 1)
277  {
278  LPTYElement elt = elements[0];
279  if (strcmp(elt->getClassName(), "TYBoundaryNoiseMap") == 0)
280  {
281  TYBoundaryNoiseMap* pTmpMaillage = static_cast<TYBoundaryNoiseMap*>(elt.getRealPointer());
282  TYBoundaryNoiseMap::operator=(*pTmpMaillage);
283  bRet = true;
284  }
285  }
286  }
287 
288  return bRet;
289 }
290 
292 {
293  TYXMLManager xmlManager;
294 
295  xmlManager.createDoc(TY_PRODUCT_XMLTAG_, TY_PRODUCT_VERSION_);
296  xmlManager.addElement(this);
297 
298  QString retString = xmlManager.saveToString();
299 
300  return retString.toStdString();
301 }
302 
303 bool TYBoundaryNoiseMap::fromXMLString(const std::string& sXMLString)
304 {
305  bool bRet = false;
306 
307  TYXMLManager xmlManager;
308  LPTYElementArray elements;
309  if (xmlManager.loadFromString(QString(sXMLString.c_str()), elements))
310  {
311  if (elements.size() == 1)
312  {
313  LPTYElement elt = elements[0];
314  if (strcmp(elt->getClassName(), "TYBoundaryNoiseMap") == 0)
315  {
316  TYBoundaryNoiseMap* pTmpMaillage = static_cast<TYBoundaryNoiseMap*>(elt.getRealPointer());
317  TYBoundaryNoiseMap::operator=(*pTmpMaillage);
318  bRet = true;
319  }
320  }
321  }
322 
323  return bRet;
324 }
325 
327 {
329 }
330 
331 // XXX Add some comments.
332 void TYBoundaryNoiseMap::make(const TYTabPoint& tabPoint, double thickness, bool closed, double density)
333 {
334  // Reset
336  _ptsIndices.clear();
337 
338  // Param
339  _thickness = thickness;
340  _closed = closed;
341  _density = density;
342  _tabPoint = tabPoint;
343 
344  const size_t nbPoints = _tabPoint.size();
345  for (size_t i = 0; i < nbPoints; ++i)
346  {
347  _tabPoint[i]._z = _hauteur;
348  }
349 
350  double box_x_min = 0., box_x_max = 0., box_y_min = 0., box_y_max = 0.;
351  computeBoundingBox(box_x_min, box_x_max, box_y_min, box_y_max);
352 
353  computePoints(box_x_min, box_x_max, box_y_min, box_y_max);
354 
355  setIsGeometryModified(true);
356 }
357 
358 void TYBoundaryNoiseMap::computeBoundingBox(double& box_x_min, double& box_x_max, double& box_y_min,
359  double& box_y_max) const
360 {
361  box_x_min = _tabPoint[0]._x;
362  box_x_max = _tabPoint[0]._x;
363  box_y_min = _tabPoint[0]._y;
364  box_y_max = _tabPoint[0]._y;
365 
366  // XXX Should use OBox with OBox::EnLarge? BUT it's in 3D.
367  const size_t length = _tabPoint.size();
368  double current_x = 0.;
369  double current_y = 0.;
370  for (size_t i = 1; i < length; ++i)
371  {
372  current_x = _tabPoint[i]._x;
373  current_y = _tabPoint[i]._y;
374 
375  box_x_min = std::min(box_x_min, current_x);
376  box_x_max = std::max(box_x_max, current_x);
377 
378  box_y_min = std::min(box_y_min, current_y);
379  box_y_max = std::max(box_y_max, current_y);
380  }
381 
382  // Create the bounding box (greater than tickness / 2.).
383  box_x_min -= _thickness * 0.5;
384  box_x_max += _thickness * 0.5;
385  box_y_min -= _thickness * 0.5;
386  box_y_max += _thickness * 0.5;
387 }
388 
389 void TYBoundaryNoiseMap::computePoints(double box_x_min, double box_x_max, double box_y_min, double box_y_max)
390 {
391  int nb_points_x = std::ceil((box_x_max - box_x_min) * _density);
392  int nb_points_y = std::ceil((box_y_max - box_y_min) * _density);
393  const double step_x = (box_x_max - box_x_min) / (double)nb_points_x;
394  const double step_y = (box_y_max - box_y_min) / (double)nb_points_y;
395 
396  // Initialize 2D array
397  ++nb_points_x;
398  ++nb_points_y;
399  _nbPointsY = nb_points_y;
400  int nbPoints = nb_points_x * nb_points_y;
401  _ptsIndices = std::vector<int>(nbPoints, -1);
402 
403  size_t l = 1;
404  double current_x = 0.;
405  double current_y = 0.;
406  const double squared_thick = _thickness * _thickness / 4.;
407  const size_t length = _tabPoint.size();
408  const size_t nb_segment = _closed ? length : length - 1;
409 
410  for (int i = 0; i < nb_points_x; ++i)
411  {
412  current_x = box_x_min + i * step_x;
413  for (int j = 0; j < nb_points_y; ++j)
414  {
415  int index2D = i * nb_points_y + j;
416  current_y = box_y_min + j * step_y;
417  for (size_t k = 0; k < nb_segment; ++k)
418  {
419  l = (k < length - 1) ? k + 1 : 0;
420  double squared_distance = compute_segment_point_square_distance(
421  current_x, current_y, _tabPoint[k]._x, _tabPoint[k]._y, _tabPoint[l]._x, _tabPoint[l]._y);
422  if (squared_distance <= squared_thick)
423  {
424  LPTYPointCalcul pPoint = new TYPointCalcul(TYPoint(current_x, current_y, _hauteur));
425  pPoint->setSpectre(new TYSpectre());
426  addPointCalcul(pPoint);
427 
428  _ptsIndices[index2D] = static_cast<int>(_ptsCalcul.size()) - 1;
429  break; // no need to test with other segments
430  }
431  }
432  }
433  }
434 }
435 
437 {
438  return 2.0 / thickness;
439 }
440 
442 {
443  return _ptsIndices[x * _nbPointsY + y];
444 }
445 
446 void TYBoundaryNoiseMap::getDimensions(int& x, int& y) const
447 {
448  y = _nbPointsY;
449  x = static_cast<int>(_ptsIndices.size()) / y;
450 }
QDomElement DOM_Element
Definition: QT2DOM.h:30
Graphical representation of the BoundaryNoiseMap entity (header file)
BoundaryNoiseMap widget (header file)
double compute_segment_point_square_distance(double point_x, double point_y, double a_x, double a_y, double b_x, double b_y)
Compute the squared distance between a point and a segment.
TY_EXTENSION_INST(TYBoundaryNoiseMap)
TY_EXT_GRAPHIC_INST(TYBoundaryNoiseMap)
#define min(a, b)
std::vector< TYPoint > TYTabPoint
Collection de TYPoint.
Definition: TYDefines.h:340
std::vector< LPTYSpectre > TYTabLPSpectre
Collection de TYSpectre.
Definition: TYDefines.h:337
std::vector< LPTYElement > LPTYElementArray
Definition: TYElement.h:345
virtual const char * getClassName() const
Definition: TYElement.h:249
T * getRealPointer()
Definition: smartptr.h:291
This class represents a polyline with a thickness. Acoustic receptors are sampled inside this region.
virtual DOM_Element toXML(DOM_Element &domElement)
std::vector< int > _ptsIndices
Array of points indices : -1 means the point doesn't exist.
void computePoints(double box_x_min, double box_x_max, double box_y_min, double box_y_max)
Compute the calcul points.
bool fromXMLString(const std::string &sXMLString)
virtual void clearResult()
Clear result.
TYTabPoint _tabPoint
The tab point defining the polyline.
bool _canBeClosed
If the polyline can be closed.
bool operator!=(const TYBoundaryNoiseMap &other) const
Operator !=.
static double computeMinimumDensity(double thickness)
Return the minimum density to get a correct sampling.
int _nbPointsY
Number of points in column y (rectangular bounding box).
virtual void make(const TYTabPoint &tabPoints, double thickness, bool closed, double density=TY_MAILLAGE_DEFAULT_DENSITE)
Build the table of TYPointCalcul around the polyline.
void computeBoundingBox(double &box_x_min, double &box_x_max, double &box_y_min, double &box_y_max) const
Compute the bounding box of the polyline.
double _density
Density of points (number of points per meter).
virtual int getIndexPtCalcul(int x, int y) const
Return the index.
virtual std::string toString() const
TYPoint _posLabel
The position of the label.
virtual int fromXML(DOM_Element domElement)
virtual void getDimensions(int &x, int &y) const
Return the dimensions in x and y.
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
bool _closed
If the polyline is closed.
double _thickness
Thickness of the polyline (in meters).
bool operator==(const TYBoundaryNoiseMap &other) const
Operator ==.
virtual ~TYBoundaryNoiseMap()
Destructor. TYBoundaryNoiseMap destructor.
TYBoundaryNoiseMap & operator=(const TYBoundaryNoiseMap &other)
Operator =.
TYBoundaryNoiseMap()
Constructor. TYBoundaryNoiseMap constructor.
QString _name
Nom courant de l'element.
Definition: TYElement.h:966
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:544
void setAllUses(void *allUses)
Definition: TYElement.h:936
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
double _hauteur
La hauteur par rapport au sol (a l'altimetrie en fait) a laquelle se trouve ce maillage.
Definition: TYMaillage.h:415
virtual void clearResult()
Definition: TYMaillage.cpp:334
bool addPointCalcul(LPTYPointCalcul pPtCalcul)
Ajoute un nouveau point de calcul.
Definition: TYMaillage.cpp:342
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
Definition: TYMaillage.cpp:133
TYTabLPPointCalcul _ptsCalcul
Liste des points de calcul.
Definition: TYMaillage.h:409
virtual int fromXML(DOM_Element domElement)
Definition: TYMaillage.cpp:191
TYMaillage & operator=(const TYMaillage &other)
Operateur =.
Definition: TYMaillage.cpp:77
void remAllPointCalcul()
Suppression de tous les elements.
Definition: TYMaillage.cpp:396
virtual DOM_Element toXML(DOM_Element &domElement)
Definition: TYMaillage.cpp:165
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
static TYNameManager * get()
Retourne l'instance singleton.
Classe de definition d'un point de calcul.C'est une classe derivee a TYPoint avec en plus un spectrep...
Definition: TYPointCalcul.h:33
void setSpectre(const LPTYSpectre spectre)
Set du spectre resultat d'un calcul donne.
int save(QString fileName)
int load(const QString &fileName, LPTYElementArray &eltCollection)
void createDoc(QString docName, QString version)
QString saveToString()
int addElement(TYElement *pElt)
int loadFromString(const QString &xmlString, LPTYElementArray &eltCollection)
static void addElementDoubleValue(DOM_Element &parentElem, DOMString nodeName, double nodeValue)
Definition: TYXMLTools.cpp:87
static bool getElementBoolValue(DOM_Element parentElem, DOMString nodeName, bool &nodeValue)
Definition: TYXMLTools.cpp:179
static bool getElementIntValue(DOM_Element parentElem, DOMString nodeName, int &nodeValue)
Definition: TYXMLTools.cpp:129
static bool getElementDoubleValue(DOM_Element parentElem, DOMString nodeName, double &nodeValue)
Definition: TYXMLTools.cpp:243
static void addElementUIntValue(DOM_Element &parentElem, DOMString nodeName, unsigned int nodeValue)
Definition: TYXMLTools.cpp:42
static void addElementBoolValue(DOM_Element &parentElem, DOMString nodeName, bool nodeValue)
Definition: TYXMLTools.cpp:77