Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYBoundaryNoiseMap.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
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  setDensity(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;
95  _nbPointsY = rhs._nbPointsY;
96  _tabPoint = rhs._tabPoint;
98  }
99  return *this;
100 }
101 
103 {
104  if (this != &rhs)
105  {
106  if (TYMaillage::operator!=(rhs))
107  {
108  return false;
109  }
110  if (!(_thickness == rhs._thickness))
111  {
112  return false;
113  }
114  if (!(_closed == rhs._closed))
115  {
116  return false;
117  }
118  if (!(_density == rhs._density))
119  {
120  return false;
121  }
123  {
124  return false;
125  }
126  }
127  return true;
128 }
129 
131 {
132  return !operator==(rhs);
133 }
134 
135 bool TYBoundaryNoiseMap::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
136 {
137  if (!TYMaillage::deepCopy(pOther, copyId))
138  {
139  return false;
140  }
141 
142  const TYBoundaryNoiseMap* pOtherMaillage = static_cast<const TYBoundaryNoiseMap*>(pOther);
143  if (!pOtherMaillage)
144  {
145  return false;
146  }
147 
148  _thickness = pOtherMaillage->_thickness;
149  _closed = pOtherMaillage->_closed;
150  _density = pOtherMaillage->_density;
152 
153  return true;
154 }
155 
156 std::string TYBoundaryNoiseMap::toString() const
157 {
158  return "TYBoundaryNoiseMap";
159 }
160 
162 {
163  DOM_Element domNewElem = TYMaillage::toXML(domElement);
164 
165  TYXMLTools::addElementDoubleValue(domNewElem, "thickness", _thickness);
166  TYXMLTools::addElementBoolValue(domNewElem, "closed", _closed);
167  TYXMLTools::addElementDoubleValue(domNewElem, "density", _density);
168 
169  TYXMLTools::addElementUIntValue(domNewElem, "nbPoints", _tabPoint.size());
170 
171  size_t nbPoints = _tabPoint.size();
172  for (size_t i = 0; i < nbPoints; ++i)
173  {
174  _tabPoint[i].toXML(domNewElem);
175  }
176 
177  return domNewElem;
178 }
179 
181 {
182  TYMaillage::fromXML(domElement);
183 
184  bool nbPointsIsOk = false;
185  bool bOldDatas = false;
186  double density = 0.0;
187 
188  int nbPoints = 0;
189  TYPoint pt;
190 
191  LPTYSpectre pSpectre = new TYSpectre();
192  TYTabLPSpectre* compatibilityVector = new TYTabLPSpectre();
193 
194  DOM_Element elemCur;
195 
196  QDomNodeList childs = domElement.childNodes();
197  for (unsigned int i = 0; i < childs.length(); i++)
198  {
199  elemCur = childs.item(i).toElement();
200 
201  TYXMLTools::getElementDoubleValue(elemCur, "thickness", _thickness);
202  TYXMLTools::getElementBoolValue(elemCur, "closed", _closed);
203  TYXMLTools::getElementDoubleValue(elemCur, "density", density);
204 
205  TYXMLTools::getElementIntValue(elemCur, "nbPoints", nbPoints, nbPointsIsOk);
206 
207  if (pt.callFromXMLIfEqual(elemCur))
208  {
209  _tabPoint.push_back(pt);
210  }
211 
212  // Old version : if we encounter spectra
213  if (pSpectre->callFromXMLIfEqual(elemCur))
214  {
215  bOldDatas = true;
216  compatibilityVector->push_back(pSpectre);
217  pSpectre = new TYSpectre();
218  }
219  }
220  setDensity(density);
221 
222  if (bOldDatas == true)
223  {
224  setAllUses((void*)compatibilityVector);
225  }
226  else
227  {
228  delete compatibilityVector;
229  }
230 
233 
234  return 1;
235 }
236 
237 bool TYBoundaryNoiseMap::toXML(const std::string& sFilePath)
238 {
239  bool bRet = false;
240  QString fileName = QString(sFilePath.c_str());
241  int i = fileName.lastIndexOf('/');
242  QDir fileDirectory = QDir(fileName.mid(0, i));
243  if (!fileDirectory.exists())
244  {
245  fileDirectory.mkdir(fileName.mid(0, i));
246  }
247 
248  if (fileName.isEmpty())
249  {
250  return false;
251  }
252  if (!fileName.endsWith(".xml"))
253  {
254  fileName += ".xml";
255  }
256 
257  TYXMLManager xmlManager;
258 
259  xmlManager.createDoc(TY_PRODUCT_XMLTAG_, TY_PRODUCT_VERSION_);
260  xmlManager.addElement(this);
261 
262  if (xmlManager.save(fileName) == 0)
263  {
264  bRet = true;
265  }
266 
267  return bRet;
268 }
269 
270 bool TYBoundaryNoiseMap::fromXML(const std::string& sFilePath)
271 {
272  bool bRet = false;
273  QString fileName = QString(sFilePath.c_str());
274 
275  if (fileName.isEmpty())
276  {
277  return false;
278  }
279 
280  TYXMLManager xmlManager;
281  LPTYElementArray elements;
282  if (xmlManager.load(fileName, elements))
283  {
284  if (elements.size() == 1)
285  {
286  LPTYElement elt = elements[0];
287  if (strcmp(elt->getClassName(), "TYBoundaryNoiseMap") == 0)
288  {
289  TYBoundaryNoiseMap* pTmpMaillage = static_cast<TYBoundaryNoiseMap*>(elt.getRealPointer());
290  TYBoundaryNoiseMap::operator=(*pTmpMaillage);
291  bRet = true;
292  }
293  }
294  }
295 
296  return bRet;
297 }
298 
300 {
301  TYXMLManager xmlManager;
302 
303  xmlManager.createDoc(TY_PRODUCT_XMLTAG_, TY_PRODUCT_VERSION_);
304  xmlManager.addElement(this);
305 
306  QString retString = xmlManager.saveToString();
307 
308  return retString.toStdString();
309 }
310 
311 bool TYBoundaryNoiseMap::fromXMLString(const std::string& sXMLString)
312 {
313  bool bRet = false;
314 
315  TYXMLManager xmlManager;
316  LPTYElementArray elements;
317  if (xmlManager.loadFromString(QString(sXMLString.c_str()), elements))
318  {
319  if (elements.size() == 1)
320  {
321  LPTYElement elt = elements[0];
322  if (strcmp(elt->getClassName(), "TYBoundaryNoiseMap") == 0)
323  {
324  TYBoundaryNoiseMap* pTmpMaillage = static_cast<TYBoundaryNoiseMap*>(elt.getRealPointer());
325  TYBoundaryNoiseMap::operator=(*pTmpMaillage);
326  bRet = true;
327  }
328  }
329  }
330 
331  return bRet;
332 }
333 
335 {
337 }
338 
339 // XXX Add some comments.
340 void TYBoundaryNoiseMap::make(const TYTabPoint& tabPoint, double thickness, bool closed, double density)
341 {
342  // Reset
344  _ptsIndices.clear();
345 
346  // Param
347  _thickness = thickness;
348  _closed = closed;
349  setDensity(density);
350  _tabPoint = tabPoint;
351 
352  const size_t nbPoints = _tabPoint.size();
353  for (size_t i = 0; i < nbPoints; ++i)
354  {
355  _tabPoint[i]._z = _tabPoint[i]._z + _hauteur;
356  }
357 
358  double box_x_min = 0., box_x_max = 0., box_y_min = 0., box_y_max = 0.;
359  computeBoundingBox(box_x_min, box_x_max, box_y_min, box_y_max);
360 
361  computePoints(box_x_min, box_x_max, box_y_min, box_y_max);
362 
363  setIsGeometryModified(true);
364 }
365 
366 void TYBoundaryNoiseMap::computeBoundingBox(double& box_x_min, double& box_x_max, double& box_y_min,
367  double& box_y_max) const
368 {
369  box_x_min = _tabPoint[0]._x;
370  box_x_max = _tabPoint[0]._x;
371  box_y_min = _tabPoint[0]._y;
372  box_y_max = _tabPoint[0]._y;
373 
374  // XXX Should use OBox with OBox::EnLarge? BUT it's in 3D.
375  const size_t length = _tabPoint.size();
376  double current_x = 0.;
377  double current_y = 0.;
378  for (size_t i = 1; i < length; ++i)
379  {
380  current_x = _tabPoint[i]._x;
381  current_y = _tabPoint[i]._y;
382 
383  box_x_min = std::min(box_x_min, current_x);
384  box_x_max = std::max(box_x_max, current_x);
385 
386  box_y_min = std::min(box_y_min, current_y);
387  box_y_max = std::max(box_y_max, current_y);
388  }
389 
390  // Create the bounding box (greater than tickness / 2.).
391  box_x_min -= _thickness * 0.5;
392  box_x_max += _thickness * 0.5;
393  box_y_min -= _thickness * 0.5;
394  box_y_max += _thickness * 0.5;
395 }
396 
397 void TYBoundaryNoiseMap::computePoints(double box_x_min, double box_x_max, double box_y_min, double box_y_max)
398 {
399  int nb_points_x = std::ceil((box_x_max - box_x_min) * _density);
400  int nb_points_y = std::ceil((box_y_max - box_y_min) * _density);
401  const double step_x = (box_x_max - box_x_min) / (double)nb_points_x;
402  const double step_y = (box_y_max - box_y_min) / (double)nb_points_y;
403 
404  // Initialize 2D array
405  ++nb_points_x;
406  ++nb_points_y;
407  _nbPointsY = nb_points_y;
408  int nbPoints = nb_points_x * nb_points_y;
409  _ptsIndices = std::vector<int>(nbPoints, -1);
410 
411  size_t l = 1;
412  double current_x = 0.;
413  double current_y = 0.;
414  const double squared_thick = _thickness * _thickness / 4.;
415  const size_t length = _tabPoint.size();
416  const size_t nb_segment = _closed ? length : length - 1;
417 
418  for (int i = 0; i < nb_points_x; ++i)
419  {
420  current_x = box_x_min + i * step_x;
421  for (int j = 0; j < nb_points_y; ++j)
422  {
423  int index2D = i * nb_points_y + j;
424  current_y = box_y_min + j * step_y;
425  for (size_t k = 0; k < nb_segment; ++k)
426  {
427  l = (k < length - 1) ? k + 1 : 0;
428  double squared_distance = compute_segment_point_square_distance(
429  current_x, current_y, _tabPoint[k]._x, _tabPoint[k]._y, _tabPoint[l]._x, _tabPoint[l]._y);
430  if (squared_distance <= squared_thick)
431  {
432  LPTYPointCalcul pPoint = new TYPointCalcul(TYPoint(current_x, current_y, _hauteur));
433  pPoint->setSpectre(new TYSpectre());
434  addPointCalcul(pPoint);
435 
436  _ptsIndices[index2D] = static_cast<int>(_ptsCalcul.size()) - 1;
437  break; // no need to test with other segments
438  }
439  }
440  }
441  }
442 }
443 
445 {
446  return 2.0 / thickness;
447 }
448 
450 {
451  return _ptsIndices[x * _nbPointsY + y];
452 }
453 
454 void TYBoundaryNoiseMap::getDimensions(int& x, int& y) const
455 {
456  y = _nbPointsY;
457  x = static_cast<int>(_ptsIndices.size()) / y;
458 }
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:344
virtual const char * getClassName() const
Definition: TYElement.h:248
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.
double _distancePointsCalcul
Distance between two consecutive points.
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 setDensity(double density)
Set density of computation points.
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:956
bool callFromXMLIfEqual(DOM_Element &domElement, int *pRetVal=NULL)
Definition: TYElement.cpp:545
void setAllUses(void *allUses)
Definition: TYElement.h:926
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