NMPB08 Shared Libraries
|
00001 #include "RailwayEmission.h" 00002 #include "stdlib.h" 00003 #include <math.h> 00004 00005 // frequency range for NMPB-2008 00006 // in a future version, this might be adapted for other models 00007 00008 static double defaultFreq[] = 00009 { 00010 100, 125, 160, 00011 200, 250, 315, 00012 400, 500, 630, 00013 800, 1000, 1250, 00014 1600, 2000, 2500, 00015 3200, 4000, 5000 00016 } ; 00017 00018 // equivalent source heights for NMPB-2008 00019 // in a future version, this might be adapted for other models 00020 00021 static double defaultHeight[] = 00022 { 00023 0.00, 0.50, 4.00 00024 } ; 00025 00026 #define TRACE_DEBUG GetOptions(OPTION_TRACE_DEBUG) 00027 00028 char* my_strdup (const char* s) 00029 { 00030 size_t n = strlen(s) + 1 ; 00031 char* c = (char*) malloc (n) ; 00032 memcpy (c, s, n) ; 00033 return c ; 00034 } 00035 // -------------------------------------------------------------------------------------- 00036 00037 static inline double POW10 (double x) 00038 { 00039 return (x < -99) ? 0.0 : pow(10., x/10.) ; 00040 } 00041 00042 static inline double LOG10 (double x) 00043 { 00044 return (x <= 0) ? -99.9 : 10 * log10(x) ; 00045 } 00046 00047 template <class T> inline T MIN (T const& x, T const& y) 00048 { 00049 return (x < y) ? x : y ; 00050 } 00051 00052 template <class T> inline T MAX (T const& x, T const& y) 00053 { 00054 return (x > y) ? x : y ; 00055 } 00056 00057 extern std::string getID (const char *s) ; 00058 00059 // -------------------------------------------------------------------------------------- 00060 00061 // NOTE: deleteEmission / createEmission should be called whenever we change 00062 // the frequency range or the equivalent source heights in the emission model 00063 00064 void RailwaySourceModel::createEmission(void) 00065 { 00066 emission.nbFreq = 18 ; 00067 emission.freq = defaultFreq ; 00068 00069 emission.nbSources = 3 ; 00070 emission.source = (RailwayEquivalentSource*) 00071 malloc (emission.nbSources * sizeof (RailwayEquivalentSource)) ; 00072 00073 for (unsigned int i = 0 ; i < emission.nbSources ; i++) 00074 { 00075 emission.source[i].height = defaultHeight[i] ; 00076 emission.source[i].Lw_dir = (double*) malloc (emission.nbFreq * sizeof(double)) ; 00077 } 00078 00079 emission.sin_h = 0 ; 00080 emission.sin_v = 0 ; 00081 } 00082 00083 // -------------------------------------------------------------------------------------- 00084 00085 void RailwaySourceModel::deleteEmission(void) 00086 { 00087 for (unsigned int i = 0 ; i < emission.nbSources ; i++) 00088 { 00089 free (emission.source[i].Lw_dir) ; 00090 } 00091 free (emission.source) ; 00092 00093 emission.nbSources = 0 ; 00094 emission.source = 0 ; 00095 } 00096 00097 // -------------------------------------------------------------------------------------- 00098 00099 void RailwaySourceModel::createTraffic (void) 00100 { 00101 traffic.component = 0 ; 00102 traffic.nbComponents = 0 ; 00103 traffic.maxComponents = 0 ; 00104 traffic.railCorrection = 0 ; 00105 traffic.nbHours = 1 ; 00106 } 00107 00108 // -------------------------------------------------------------------------------------- 00109 00110 void RailwaySourceModel::deleteTraffic (void) 00111 { 00112 if (traffic.maxComponents > 0) 00113 { 00114 ClearTraffic() ; 00115 free (traffic.component) ; 00116 traffic.maxComponents = 0 ; 00117 traffic.component = 0 ; 00118 } 00119 } 00120 00121 // -------------------------------------------------------------------------------------- 00122 00123 bool RailwaySourceModel::AddTraffic (const char* id, double nb, double speed) 00124 { 00125 if (id == 0 || strlen(id) == 0 || speed <= 0 || nb <= 0) return false ; 00126 00127 if (traffic.nbComponents == traffic.maxComponents) 00128 { 00129 int n = traffic.maxComponents ; 00130 if (n == 0) n = 4 ; else n *= 2 ; 00131 traffic.component = (RailwayTrafficComponent*) 00132 realloc (traffic.component, n * sizeof (RailwayTrafficComponent)) ; 00133 traffic.maxComponents = n ; 00134 } 00135 00136 int n = traffic.nbComponents ; 00137 traffic.component[n].id = my_strdup (id) ; 00138 traffic.component[n].speed = speed ; 00139 traffic.component[n].number = nb ; 00140 00141 traffic.nbComponents = n+1 ; 00142 00143 return true ; 00144 } 00145 00146 // -------------------------------------------------------------------------------------- 00147 00148 RailwayEmission const* RailwaySourceModel::GetEmission (ScreenBodyInteraction* screenBodyInteraction) 00149 { 00150 try 00151 { 00152 prepareEmission() ; 00153 00154 prepareScreenBodyCorrection (screenBodyInteraction) ; 00155 00156 if (maxInteractions > 0 && TRACE_DEBUG) 00157 { 00158 printf ("ScreenBodyInteraction correction table\n") ; 00159 for (unsigned int h = 0 ; h < emission.nbSources ; h++) 00160 { 00161 printf ("source height : %.2fm \n", emission.source[h].height) ; 00162 printf ("Freq") ; 00163 for (int n = 0 ; n <= maxInteractions ; ++n) printf ("\t N=%d",n) ; 00164 printf ("\n") ; 00165 00166 for (unsigned int i = 0 ; i < emission.nbFreq ; i++) 00167 { 00168 printf ("%.0f", emission.freq[i]) ; 00169 for (int n = 0 ; n <= maxInteractions ; ++n) 00170 { 00171 printf ("\t%.1f", difInteraction[h][n][i]) ; 00172 } 00173 printf ("\n") ; 00174 } 00175 } 00176 } 00177 addTraffic (traffic) ; 00178 } 00179 catch (...) 00180 { 00181 return 0 ; 00182 } 00183 finaliseEmission() ; 00184 return &emission ; 00185 } 00186 00187 // -------------------------------------------------------------------------------------- 00188 00189 void RailwaySourceModel::prepareEmission(void) 00190 { 00191 for (unsigned int i = 0 ; i < emission.nbSources ; i++) 00192 { 00193 emission.source[i].has_Lw = false ; 00194 for (unsigned int j = 0 ; j < emission.nbFreq ; j++) 00195 { 00196 emission.source[i].Lw_dir[j] = 0 ; 00197 } 00198 } 00199 } 00200 00201 // -------------------------------------------------------------------------------------- 00202 00203 void RailwaySourceModel::finaliseEmission(void) 00204 { 00205 for (unsigned int i = 0 ; i < emission.nbSources ; i++) 00206 { 00207 double corr_rail = (emission.source[i].height < 1.0) ? traffic.railCorrection : 0.0 ; 00208 for (unsigned int j = 0 ; j < emission.nbFreq ; j++) 00209 { 00210 double val = emission.source[i].Lw_dir[j] ; 00211 if (val > 0) emission.source[i].has_Lw = true ; 00212 emission.source[i].Lw_dir[j] = LOG10 (val) + corr_rail ; 00213 } 00214 } 00215 } 00216 00217 // -------------------------------------------------------------------------------------- 00218 00219 void RailwaySourceModel::addTraffic (RailwayTraffic const& traffic) 00220 { 00221 for (unsigned int i = 0 ; i < traffic.nbComponents ; i++) 00222 { 00223 double speed = traffic.component[i].speed ; 00224 double flow = traffic.component[i].number 00225 / (1000 * traffic.component[i].speed * traffic.nbHours) ; 00226 00227 IDREF id = getID (traffic.component[i].id) ; 00228 00229 if (TRACE_DEBUG) printf ("add traffic \n") ; 00230 00231 RailwayTrain const* train ; 00232 RailwayUnit const* unit ; 00233 RailwaySource const* source ; 00234 00235 if ((train = db->getTrain (id)) != 0) 00236 { 00237 if (TRACE_DEBUG) printf ("add train [%s] \n", id.c_str()) ; 00238 addTrain (*train, speed, flow) ; 00239 } 00240 else if ((unit = db->getUnit (id)) != 0) 00241 { 00242 if (TRACE_DEBUG) printf ("add unit [%s] \n", id.c_str()) ; 00243 addUnit (*unit, speed, flow) ; 00244 } 00245 else if ((source = db->getSource (id)) != 0) 00246 { 00247 if (TRACE_DEBUG) printf ("add source [%s] \n", id.c_str()) ; 00248 addSource (*source, speed, flow) ; 00249 } 00250 else 00251 { 00252 if (TRACE_DEBUG) printf ("unknown id (%s) in addTraffic \n", id.c_str()) ; 00253 } 00254 } 00255 } 00256 00257 // -------------------------------------------------------------------------------------- 00258 00259 void RailwaySourceModel::addTrain (RailwayTrain const& train, double speed, double train_flow) 00260 { 00261 for (unsigned int i = 0 ; i < train.unit.size() ; i++) 00262 { 00263 double unit_flow = train_flow * train.unit[i]. nb ; 00264 00265 IDREF id = train.unit[i].ref ; 00266 00267 RailwayUnit const* unit ; 00268 RailwaySource const* source ; 00269 00270 if ((unit = db->getUnit (id)) != 0) 00271 { 00272 if (TRACE_DEBUG) printf ("add unit [%s] \n", id.c_str()) ; 00273 addUnit (*unit, speed, unit_flow) ; 00274 } 00275 else if ((source = db->getSource (id)) != 0) 00276 { 00277 if (TRACE_DEBUG) printf ("add source [%s] \n", id.c_str()) ; 00278 addSource (*source, speed, unit_flow) ; 00279 } 00280 else 00281 { 00282 if (TRACE_DEBUG) printf ("unknown id (%s) in addTrain \n", id.c_str()) ; 00283 } 00284 } 00285 } 00286 00287 // -------------------------------------------------------------------------------------- 00288 00289 void RailwaySourceModel::addUnit (RailwayUnit const& unit, double speed, double unit_flow) 00290 { 00291 for (unsigned int i = 0 ; i < unit.source.size() ; i++) 00292 { 00293 IDREF id = unit.source[i].ref ; 00294 00295 RailwaySource const* source ; 00296 00297 if ((source = db->getSource (id)) != 0) 00298 { 00299 if (TRACE_DEBUG) printf ("add source [%s] \n", id.c_str()) ; 00300 00301 // add sources (and their image) 00302 for (nbInteractions = 0 ; nbInteractions <= maxInteractions ; nbInteractions++) 00303 { 00304 double source_flow = unit_flow * unit.source[i].nb ; 00305 00306 // take into account reflections on the car body 00307 if (nbInteractions > 0) source_flow *= pow (unit.cref, nbInteractions) ; 00308 00309 addSource (*source, speed, source_flow) ; 00310 } 00311 } 00312 else 00313 { 00314 if (TRACE_DEBUG) printf ("unknown id (%s) in addUnit \n", id.c_str()) ; 00315 } 00316 } 00317 } 00318 00319 // -------------------------------------------------------------------------------------- 00320 00321 void RailwaySourceModel::addSource (RailwaySource const& source, double speed, double flow) 00322 { 00323 std::vector<SourceDistribution> distrib ; 00324 getSourceDistribution (source, distrib) ; 00325 00326 if (TRACE_DEBUG) printf ("source height = %.2fm \n", source.height) ; 00327 if (TRACE_DEBUG) printf ("nb eq. sources = %ld \n", distrib.size()); 00328 00329 if ((options & OPTION_MODIFY_HEIGHTS) == 0) 00330 { 00331 size_t nb_sources = distrib.size() ; 00332 if (nb_sources != 1) throw InvalidHeight() ; 00333 int index = distrib[0].index ; 00334 double height = emission.source[index].height ; 00335 if (fabs(source.height - height) > 0.01) throw InvalidHeight() ; 00336 } 00337 00338 double corr_speed = pow (speed / source.vref, source.slope/10.) ; 00339 double corr_flow = flow ; 00340 00341 for (unsigned int i = 0 ; i < emission.nbFreq ; i++) 00342 { 00343 double Lw_source = POW10 (source.Lw[i]) ; 00344 00345 double corr_h = 1 ; 00346 double corr_v = 1 ; 00347 if (! GetOptions (OPTION_NO_DIRECTIVITY)) 00348 { 00349 corr_h = getHorizontalDirectivity (source.hdir_model, emission.sin_h, emission.freq[i]) ; 00350 corr_v = getVerticalDirectivity ( source.vdir_model, emission.sin_v, emission.freq[i]) ; 00351 } 00352 00353 double corr = corr_flow * corr_speed * corr_h * corr_v ; 00354 00355 // cumulate sound powers per source height 00356 for (unsigned int j = 0 ; j < distrib.size() ; j++) 00357 { 00358 int index = distrib[j].index ; 00359 double weight = corr * distrib[j].weight ; 00360 if (i == 0 && TRACE_DEBUG) 00361 { 00362 printf ("height = %.2fm weight = %.2f%% \n", 00363 emission.source[index].height, 100. * distrib[j].weight) ; 00364 } 00365 00366 // apply car body / barrier interaction 00367 // depending on source height, number of interactions and frequency 00368 if (nbInteractions > 0) 00369 { 00370 double dif_direct = difInteraction[index][0][i] ; 00371 double dif_image = difInteraction[index][nbInteractions][i] ; 00372 if (i==10 && TRACE_DEBUG) 00373 { 00374 printf ("N=%d H=%.2f att=%.2f at %.0fHz\n", 00375 nbInteractions, 00376 emission.source[index].height, 00377 dif_image, 00378 emission.freq[i]) ; 00379 } 00380 weight *= POW10 (dif_image - dif_direct) ; 00381 } 00382 00383 emission.source[index].Lw_dir[i] += weight * Lw_source ; 00384 } 00385 } 00386 } 00387 00388 // -------------------------------------------------------------------------------------- 00389 00390 int RailwaySourceModel::getSourceDistribution (RailwaySource const& source, 00391 std::vector<SourceDistribution>& distrib) 00392 { 00393 int index_low = -1 ; 00394 int index_high = -1 ; 00395 double delta_low = 0 ; 00396 double delta_high = 0 ; 00397 00398 // if there is only one source height in the model 00399 // assign all sound power to the equivalent source at that height 00400 00401 if (emission.nbSources == 1) 00402 { 00403 distrib.resize(1) ; 00404 distrib[0].index = 0 ; 00405 distrib[0].weight = 1.00 ; 00406 return 1 ; 00407 } 00408 00409 // find equivalent source above/below the source height as defined in the database 00410 00411 for (unsigned int i = 0 ; i < emission.nbSources ; ++i) 00412 { 00413 // if source height match, assign all the sound power to that height 00414 00415 if (fabs(source.height - emission.source[i].height) < 0.01) 00416 { 00417 distrib.resize(1) ; 00418 distrib[0].index = i ; 00419 distrib[0].weight = 1.00 ; 00420 return 1 ; 00421 } 00422 else if (source.height > emission.source[i].height) 00423 { 00424 double delta = source.height - emission.source[i].height ; 00425 if (index_low < 0 || delta < delta_low) 00426 { 00427 index_low = i ; 00428 delta_low = delta ; 00429 } 00430 } 00431 else 00432 { 00433 double delta = emission.source[i].height - source.height ; 00434 if (index_high < 0 || delta < delta_high) 00435 { 00436 index_high = i ; 00437 delta_high = delta ; 00438 } 00439 } 00440 } 00441 00442 // if the source is below the lowest height in model, 00443 // assign all power to the lowest equivalent source 00444 // if the source is above the highest height in model, 00445 // assign all power to the highest equivalent source 00446 // if the source height falls in between two equivalent sources, 00447 // distribute the sound power over those equivalent sources 00448 // proportional to the difference in height 00449 00450 if (index_high < 0) 00451 { 00452 distrib.resize(1) ; 00453 distrib[0].index = index_low ; 00454 distrib[0].weight = 1.00 ; 00455 } 00456 else if (index_low < 0) 00457 { 00458 distrib.resize(1) ; 00459 distrib[0].index = index_high ; 00460 distrib[0].weight = 1.00 ; 00461 } 00462 else 00463 { 00464 distrib.resize(2) ; 00465 distrib[0].index = index_low ; 00466 distrib[0].weight = delta_high / (delta_high + delta_low) ; 00467 distrib[1].index = index_high ; 00468 distrib[1].weight = delta_low / (delta_high + delta_low) ; 00469 } 00470 00471 return (int) distrib.size() ; 00472 } 00473 00474 // -------------------------------------------------------------------------------------- 00475 00476 const double PI = 3.1415926 ; 00477 00478 double RailwaySourceModel::getHorizontalDirectivity (int model, double sin_h, double freq) 00479 { 00480 if (model == HDIR_OMNI) return 1 ; 00481 00482 double cos_h = sqrt (1. - sin_h * sin_h) ; 00483 return 4 * cos_h / PI ; 00484 } 00485 00486 // -------------------------------------------------------------------------------------- 00487 00488 double RailwaySourceModel::getVerticalDirectivity (int model, double sin_v, double freq) 00489 { 00490 if (model == VDIR_OMNI) return 1 ; 00491 00492 if (model == VDIR_HEMI) return (sin_v > 0) ? 2 : 0 ; 00493 00494 if (sin_v < 0) return 1 ; 00495 00496 double sin_2v = 2. * sin_v * sqrt (1. - sin_v * sin_v) ; 00497 00498 double A = 40./3. * (2./3. * sin_2v - sin_v) ; 00499 double B = log10 ((freq + 600.)/200.) ; 00500 00501 return POW10 (A * B) ; 00502 } 00503 00504 // -------------------------------------------------------------------------------------- 00505 00506 // calculate norm of a vector in 2D 00507 static double getNorm (double x1, double y1) 00508 { 00509 return sqrt (x1*x1 + y1*y1) ; 00510 } 00511 00512 // calculate distance between two points in 2D 00513 static double getDist (double x1, double y1, double x2, double y2) 00514 { 00515 return getNorm (x1-x2, y1-y2) ; 00516 } 00517 00518 // calculate path difference, positive if the line of sight is blocked, negative otherwise 00519 static double getDelta (double x1, double y1, double x2, double y2, double x3, double y3) 00520 { 00521 double delta = getDist (x1,y1,x2,y2) + getDist(x2,y2,x3,y3) - getDist(x1,y1,x3,y3) ; 00522 double yr = y1 + (x2 - x1) * (y3 - y1) / (x3 - x1) ; 00523 return (yr < y2) ? delta : -delta ; 00524 } 00525 00526 // attenuation due to diffraction, Deygout approximation 00527 static double GetDiffractionDeygout (double delta, double freq) 00528 { 00529 double lambda = 334 / freq ; 00530 double n = 2 * delta / lambda ; 00531 double dn = 0 ; 00532 00533 if (n < -0.25) 00534 { 00535 dn = 0 ; 00536 } 00537 else if (n < 0) 00538 { 00539 dn = -6 + 12 * sqrt(-n) ; 00540 } 00541 else if (n < 0.25) 00542 { 00543 dn = -6 - 12 * sqrt(n) ; 00544 } 00545 else if (n < 1) 00546 { 00547 dn = -8 - 8 * sqrt(n) ; 00548 } 00549 else 00550 { 00551 dn = -16 - 10 * log10 (n) ; 00552 } 00553 00554 return dn ; 00555 } 00556 00557 // attenuation due to diffraction, NMPB08 diffraction 00558 static double GetDiffractionNMPB08 (double delta, double freq) 00559 { 00560 double lambda = 334. / freq ; 00561 double q = 3 + 40 * delta / lambda ; 00562 return (q > 1) ? -LOG10 (q) : 0.0 ; 00563 } 00564 00565 // -------------------------------------------------------------------------------------- 00566 00567 double RailwaySourceModel::getDiffraction (double delta, double freq) 00568 { 00569 return GetOptions(OPTION_DEYGOUT_DIFFRACTION) ? GetDiffractionDeygout (delta, freq) 00570 : GetDiffractionNMPB08 (delta, freq) ; 00571 } 00572 00573 // -------------------------------------------------------------------------------------- 00574 00575 void RailwaySourceModel::prepareScreenBodyCorrection (ScreenBodyInteraction* screenBodyInteraction) 00576 { 00577 if (screenBodyInteraction == 0 || screenBodyInteraction->maxInteractions == 0) 00578 { 00579 maxInteractions = 0 ; 00580 difInteraction.clear() ; 00581 return ; 00582 } 00583 00584 double dist_direct ; 00585 double dist_image ; 00586 00587 maxInteractions = screenBodyInteraction->maxInteractions ; 00588 difInteraction.resize (emission.nbSources) ; 00589 for (int i = 0 ; i < difInteraction.size() ; ++i) 00590 { 00591 difInteraction[i].resize (maxInteractions+1) ; 00592 for (int j = 0 ; j <= maxInteractions ; ++j) 00593 { 00594 // express source, barrier top and receiver in DZ coordinates, D=0 at the (image) source 00595 double dS = 0 ; 00596 double zS = emission.source[i].height ; 00597 double dB = (2*j + 1) * screenBodyInteraction->dS ; 00598 double zB = screenBodyInteraction->hS ; 00599 double dR = dB + screenBodyInteraction->dR ; 00600 double zR = screenBodyInteraction->hR ; 00601 00602 // spherical spreading 00603 double corr_dist = 0 ; 00604 if (j == 0) 00605 { 00606 dist_direct = getDist (dS,zS,dR,zR) ; 00607 } 00608 else 00609 { 00610 dist_image = getDist (dS,zS,dR,zR) ; 00611 corr_dist = 2 * LOG10 (dist_direct / dist_image) ; 00612 } 00613 00614 // prepare output spectrum 00615 difInteraction[i][j].resize (emission.nbFreq) ; 00616 for (unsigned int k = 0 ; k < emission.nbFreq ; ++k) difInteraction[i][j][k] = corr_dist ; 00617 00618 // diffraction 00619 double delta = getDelta (dS, zS, dB, zB, dR, zR) ; 00620 for (unsigned int k = 0 ; k < emission.nbFreq ; ++k) 00621 { 00622 difInteraction[i][j][k] += getDiffraction (delta, emission.freq[k]) ; 00623 } 00624 00625 if (j == 0) continue ; 00626 00627 // absorption on the inner side of the barrier 00628 if (screenBodyInteraction->alpha) 00629 { 00630 for (unsigned int k = 0 ; k < emission.nbFreq ; ++k) 00631 { 00632 difInteraction[i][j][k] += j * LOG10 (1- screenBodyInteraction->alpha[k]) ; 00633 } 00634 } 00635 00636 // retro-diffraction for (multiple) reflexions on the barrier 00637 for (int jp = 1 ; jp <= j ; ++jp) 00638 { 00639 double dP = (2*jp-1) * screenBodyInteraction->dS ; 00640 double zP = zB ; 00641 double dQ = dR ; 00642 double zQ = std::max (zB * dR / dB, zR) ; 00643 double delta = -getDelta (dS,zS,dP,zP,dQ,zQ) ; 00644 for (unsigned int k = 0 ; k < emission.nbFreq ; ++k) 00645 { 00646 difInteraction[i][j][k] += getDiffraction (delta, emission.freq[k]) ; 00647 } 00648 } 00649 } 00650 } 00651 } 00652 00653 // -------------------------------------------------------------------------------------- 00654 00655 /* 00656 * /brief extern C interface for RailwaySourceModel::CreateTraffic 00657 * 00658 */ 00659 void* NMPB08_CreateRailwayTraffic (double nb_hours) 00660 { 00661 RailwaySourceModel* model = new RailwaySourceModel ; 00662 model->CreateTraffic(nb_hours) ; 00663 return (void*) model ; 00664 } 00665 00666 /* 00667 * /brief extern C interface for new RailwaySourceModel::ClearTraffic 00668 * 00669 */ 00670 int NMPB08_ClearRailwayTraffic (void* id) 00671 { 00672 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00673 if (model == 0) return ERROR_INVALID_ID ; 00674 return model->ClearTraffic() ; 00675 } 00676 00677 /* 00678 * /brief extern C interface for new RailwaySourceModel::AddTraffic 00679 * 00680 */ 00681 int NMPB08_AddRailwayTraffic (void* id, const char* unit_or_train, double number, double speed) 00682 { 00683 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00684 if (model == 0) return ERROR_INVALID_ID ; 00685 return model->AddTraffic(unit_or_train, number, speed) ; 00686 } 00687 00688 /* 00689 * /brief extern C interface for new RailwaySourceModel::GetEmission 00690 * 00691 */ 00692 RailwayEmission const* NMPB08_GetRailwayEmission (void* id, ScreenBodyInteraction* screenBodyInteraction) 00693 { 00694 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00695 if (model == 0) return 0 ; 00696 return model->GetEmission (screenBodyInteraction) ; 00697 } 00698 00699 /* 00700 * /brief extern C interface for new RailwaySourceModel::DeleteTraffic 00701 * 00702 */ 00703 int NMPB08_DeleteRailwayTraffic (void* id) 00704 { 00705 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00706 if (model == 0) return ERROR_INVALID_ID ; 00707 delete model ; 00708 return 0 ; 00709 } 00710 00711 /* 00712 * /brief extern C interface for new RailwaySourceModel::SetOptions 00713 * 00714 */ 00715 unsigned int NMPB08_SetRailwayOptions (void* id, unsigned int option, bool on_off) 00716 { 00717 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00718 if (model == 0) return 0 ; 00719 return model->SetOptions (option, on_off) ; 00720 } 00721 00722 /* 00723 * /brief extern C interface for new RailwaySourceModel::GetOptions 00724 * 00725 */ 00726 unsigned int NMPB08_GetRailwayOptions (void* id, unsigned int option) 00727 { 00728 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00729 if (model == 0) return 0 ; 00730 return model->GetOptions (option) ; 00731 } 00732 00733 /* 00734 * /brief extern C interface for new RailwaySourceModel::SetEmissionAngles 00735 * 00736 */ 00737 int NMPB08_SetRailwayEmissionAngles (void* id, double sin_h, double sin_v) 00738 { 00739 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00740 if (model == 0) return 0 ; 00741 return model->SetEmissionAngles (sin_h, sin_v) ; 00742 } 00743 00744 /* 00745 * /brief extern C interface for new RailwaySourceModel::SetRailCorrection 00746 * 00747 */ 00748 unsigned int NMPB08_SetRailCorrection (void* id, NMPB_RailCorrectionType corr) 00749 { 00750 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00751 if (model == 0) return 0 ; 00752 return model->SetRailCorrection (corr) ; 00753 } 00754 00755 /* 00756 * /brief extern C interface for new RailwaySourceModel::GetOptions 00757 * 00758 */ 00759 NMPB_RailCorrectionType NMPB08_GetRailwayOptions (void* id) 00760 { 00761 RailwaySourceModel* model = static_cast<RailwaySourceModel*>(id) ; 00762 if (model == 0) return 0 ; 00763 return model->GetRailCorrection() ; 00764 }