~o|16 ~?!i&32768 ~o=39 ~$>end_of_copyright ~/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ~/Copyright (C) Heinz Spiess, CH-2558 Aegerten, 1994. All rights reserved. ~/ ~/The right to use this macro is granted to all EMME/2 users, provided the ~/following conditions are met: ~/ 1) The macro cannot be sold for a fee (but it can be used and distributed ~/ without charge within consulting projects). ~/ 2) The user is aware that this macro is not a part of the EMME/2 software ~/ licence and there is no explicit or implied warranty or support ~/ provided with this macro. ~/ 3) The comments in this macros must not be removed and any additions or ~/ modification must be appropriately identified as such and give at least ~/ date, name and the reason of the modification. ~/!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ~:end_of_copyright ~/***************************************************************************** ~/* OPPVOL 1.1 - COMPUTE OPPOSING VOLUMES OF TURNS USING TURN ANGLE RELATIONS * ~/* Copyright (C) Heinz Spiess, CH-2558 Aegerten, 1994 * ~/***************************************************************************** ~/ This macro is an example showing how to use the EMME/2 network calculator ~/ module to compute opposing volumes at intersection. In this simplistic ~/ example, opposing turns are defined only by the geometry of the intersection. ~/ Given the turn JMN, the other turns JIK are classified into categories from ~/ where they originate (rear, right, left, front) and where they lead to ~/ (front, right, left, rear). A weight factor for each of the categories is ~/ given in a look up matrix which can be easily modified if required. ~/ ~/ Calling sequence: ~/ ~ ~/ ~/ The parameter specifies the turn user attribute (up1, up2, up3 or ~/ extra attribute) in which the resulting opposing volumes are stored. ~/ ~/ This macro uses scalar ms99 to store the number of turns at the largest ~/ intersection. It also uses 6 temporary node data items and 1 temporary ~/ turn data item. Divide by zero warnings are from handling of the u-turns, ~/ they are benign and can be ignored. ~x=%0% ~?!x=1 ~$>end_of_macro ~/ c='Starting macro OPPVOL.' 2.41 / call network calculator module 1 / sequential numbering of all turns within each intersection ~+|y|tmpp1|put((get(2)==j)*get(1)+1)+0*put(j)||all|all ~+|5|3|99|TMP|TMP(max. no. of turns per intersection)||||r|~t1=%%%ms99%%% ~+|1|y|%1% / initialize final result vector ~?q=1 /if result is stored in extra attribute change description ~+|y|result of macro OPPVOL (%d%) ~+|0||||5|r ~x=0 / initialize loop over turns JMN within intersection ~:next_turn ~x+1 ~/ ... compute opposing volumes for turn %x% of all intersections ~+|1|y|tmpj1|(tmpp1==%x%)*xi||4|||5|r / store xm in tmpj1 ~+|1|y|tmpj2|(tmpp1==%x%)*yi||4|||5|r / store ym in tmpj2 ~+|1|y|tmpj3|(tmpp1==%x%)*xk||4|||5|r / store xn in tmpj3 ~+|1|y|tmpj4|(tmpp1==%x%)*yk||4|||5|r / store yn in tmpj4 ~+|1|y|tmpj5|(tmpp1==%x%)*i||4|||5|r / store m in tmpj5 ~+|1|y|tmpp2 / compute turn category of turn JIK with respect to turn JMN '0*put(' /get(3) is turning angle MJK 180.*atan(put((xk-xj)*(yj-tmpj2)-(yk-yj)*(xj-tmpj1))/ put((xk-xj)*(xj-tmpj1)+(yk-yj)*(yj-tmpj2)))/3.1415926 +360*((get(1)>0)-.5)*(get(2)<0)) '+0*put(' /get(6) is turning angle MJI 180.*atan(put((xi-xj)*(yj-tmpj2)-(yi-yj)*(xj-tmpj1))/ put((xi-xj)*(xj-tmpj1)+(yi-yj)*(yj-tmpj2)))/3.1415926 +360*((get(4)>0)-.5)*(get(5)<0)) '+0*put(' /get(9) is turning angle MJN 180.*atan(put((tmpj3-xj)*(yj-tmpj2)-(tmpj4-yj)*(xj-tmpj1))/ put((tmpj3-xj)*(xj-tmpj1)+(tmpj4-yj)*(yj-tmpj2)))/3.1415926 +360*((get(7)>0)-.5)*(get(8)<0)) +((get(3)-get(9)<0)*2+(get(3)-get(9)>0)*1)*(k!=tmpj5)+(k==tmpj5)*3 +((get(6)-get(9)<0)*8+(get(6)-get(9)==0)*12+(get(6)-get(9)>0)*4)*(i!=tmpj5) ~+||||5|r 1 / now compute weighted sum of opposing volumes using coefficient matrix ~+|y|tmpj6 / to: front(N) right left rear(M) from: '0*( put( 0)+put( 0)+put( 0)+put( 0)' / rear(M) ' +put( 1)+put( 0)+put( 1)+put( 1)' / right ' +put( 1)+put( 1)+put( 0)+put( 0)' / back ' +put( 1)+put( 1)+put( 0)+put( 0)' / from(N) )+ get(tmpp2+1)*pvolau ~+||4|||5|r 1 / fill opposing volumes into the corresponding turn attribute ~+|y|%1%|~?q=1|n|%1%*(tmpp1!=%x%)+tmpj6*(tmpp1==%x%)||||5|r ~?x<%t1% ~$next_turn q ~/ ~/ Macro OPPVOL terminated normally. Opposing volumes are stored in %1%. c='Macro OPPVOL %1% terminated normally.' ~:end_of_macro ~/***************************************************************************** ~o=6