Conditional rule + reporting

688
5
Jump to solution
03-25-2014 07:14 AM
HafidhIhromi
New Contributor
Hi, I am new to this forum. I have been working on my project in urban design/planning using City Engine. I have a problem writing CGA rules, specifically writing conditional rule consisting reporting.

Here's the code I wrote (this is just basics, the whole codes is too lengthy to show here. But this shows the essential part)  :

@Range("A","B","C","D","E") attr groundfloorUse = "A"  @Range("A","B","C","D","E") attr upperfloorUse = "A"  reporting -->      case groundfloorUse == "A" : report("F", 1)     case groundfloorUse == "B" : report("G", 2)     case groundfloorUse == "C" : report("H", 3)     case groundfloorUse == "D" : report("I", 4)     case groundfloorUse == "E" : report("J", 5)     else: reporting2  reporting2 --> case upperfloorUse == "A" : report("A", 1)     case upperfloorUse == "B" : report("B", 2)     case upperfloorUse == "C" : report("C", 3)     case upperfloorUse == "D" : report("D", 4)     case upperfloorUse == "E" : report("E", 5)     else: NIL


Now, the frustation begins.. When I apply that code to a lot, it shows 2 parameters as I wrote on CGA rules (just the way I wanted), but when I apply two different attributes to a lot, it only shows result just from one of them. For example; if I apply a lot's groundfloorUse = "A" and upperfloorUse = "B", the reporting window only shows the result regarding to just one of the attributes instead of showing the result from 2 different attributes.

I have been trying many things, writing the whole code in one function, separate it into two functions (just like I showed), using ||, and &&. But it didn't work well.

Can somebody help me? Any answers is much appreciated.

Pardon my English
Thanks
0 Kudos
1 Solution

Accepted Solutions
curtedmonds
New Contributor III
I think the problem lies in the logic of the case.
the first case for groundfloorUse will stop execution and not reach the else

I think you just need the two functions included in a lot call

reporting1 -->
    case groundfloorUse == "A" : report("F", 1)
    case groundfloorUse == "B" : report("G", 2)
    case groundfloorUse == "C" : report("H", 3)
    case groundfloorUse == "D" : report("I", 4)
    else groundfloorUse == "E" : report("J", 5) # or other default


reporting2 --> case upperfloorUse == "A" : report("A", 1)
    case upperfloorUse == "B" : report("B", 2)
    case upperfloorUse == "C" : report("C", 3)
    case upperfloorUse == "D" : report("D", 4)
    else upperfloorUse == "E" : report("E", 5) # or other default

Lot-->
reporting1
reporting2

View solution in original post

0 Kudos
5 Replies
curtedmonds
New Contributor III
I think the problem lies in the logic of the case.
the first case for groundfloorUse will stop execution and not reach the else

I think you just need the two functions included in a lot call

reporting1 -->
    case groundfloorUse == "A" : report("F", 1)
    case groundfloorUse == "B" : report("G", 2)
    case groundfloorUse == "C" : report("H", 3)
    case groundfloorUse == "D" : report("I", 4)
    else groundfloorUse == "E" : report("J", 5) # or other default


reporting2 --> case upperfloorUse == "A" : report("A", 1)
    case upperfloorUse == "B" : report("B", 2)
    case upperfloorUse == "C" : report("C", 3)
    case upperfloorUse == "D" : report("D", 4)
    else upperfloorUse == "E" : report("E", 5) # or other default

Lot-->
reporting1
reporting2
0 Kudos
HafidhIhromi
New Contributor
Wow it worked! I see, so in this function, we have to define every possibilities included in an else. Thanks, you've saved my life!
0 Kudos
curtedmonds
New Contributor III
Thanks, you've saved my life!


No Problem, life saving and making cups of tea are just part of the job.
0 Kudos
HafidhIhromi
New Contributor
Hi, I've created more complex code using the previous template, works fine. But now I face another problem, here's the rules I make :


const far_divider = 1000
const hdens_divider = 100
const junction_count = 5
const crossing_count = 5
const junction_multiplier = 3
const crossing_multiplier = 4

@Range (0,1)
attr envelope_transparency = 0.5

@Range ("living", "commercial", "services", "industrial", "institutional", "recreational", "other", "water")
attr groundfloorUse = "commercial"

@Range ("living", "commercial", "services", "industrial", "institutional", "recreational", "other", "water")
attr upperfloorUse = "living"

@Range(1,2,3,4,5,6,7,8,9,10)
attr groundfloorUse_floorcount = 3

@Range(1,2,3,4,5,6,7,8,9,10)
attr upperfloorUse_floorcount = 3

attr floorheight = 4

@Range (0-20)
attr frontSetback = 0
@Range (0-20)
attr sideStreetback = 0
@Range (0-20)
attr backStreetback = 0

lot --> shape
  report ("con", (junction_count * junction_multiplier) + (crossing_count * crossing_multiplier))
   report ("ent", 0) #I leave it like this for now
  report1
  report2
  report3

shape --> s('1,0,'1)
 setback(frontSetback) { street.front: NIL | remainder: 
  setback(backStreetback) { street.back: NIL | remainder: 
    setback(sideStreetback) { street.side: NIL | remainder:
    ZoningShell 
   }
  }
 }  

height = floorheight * ( groundfloorUse_floorcount * upperfloorUse_floorcount )

ZoningShell --> envelope(height, 0, 90)
    color

zone1height = floorheight * groundfloorUse_floorcount
zone2height = floorheight * upperfloorUse_floorcount

floor_multiplier = groundfloorUse_floorcount + upperfloorUse_floorcount

#living, commercial, services, industrial, institutional, recreational, other, water

report1 --> case groundfloorUse == "commercial" :
   report("far1", (geometry.area(top) * floor_multiplier) / far_divider)
   case groundfloorUse == "living" :
   report ("hdens1", (geometry.area(top) * floor_multiplier) / hdens_divider)
   case groundfloorUse == "services" :
   report ("-", 0)
   case groundfloorUse == "industrial" :
   report ("-", 0)
   case groundfloorUse == "institutional" :
   report ("-", 0)
   case groundfloorUse == "recreational" :
   report ("-", 0)
   case groundfloorUse == "other" :
   report ("-", 0)
   else :
   report ("-", 0)
   
report2 --> case upperfloorUse == "commercial" :
   report("far2", (geometry.area(top) * floor_multiplier) / far_divider)
   case upperfloorUse == "living" :
   report ("hdens2", (geometry.area(top) * floor_multiplier) / hdens_divider)
   case upperfloorUse == "services" :
   report ("-", 0)
   case upperfloorUse == "industrial" :
   report ("-", 0)
   case upperfloorUse == "institutional" :
   report ("-", 0)
   case upperfloorUse == "recreational" :
   report ("-", 0)
   case upperfloorUse == "other" :
   report ("-", 0)
   else :
   report ("-", 0)    


The idea is, I want to report the walkability index by multiplying these factors : far, hdens, con, and ent. I have no problem reporting far and hdens, until I realize I cant combine the value of far1 and far2, and hdens1 and hdens2 using report (or is it possible combining 2 values on report command?). The reason I 'split' this to far1, far2, hdens1, and hdens2(instead only far and hdens) is based on the previous experiment, I have tried to combine all the report (by not making the differences to calculate groundfloorUse and upperfloorUse) but it didn't work. Actually, I am fully aware that I can make tables on Excel to make it easier, but I want to make this all done in City Engine only, if possible, using Excel is my last resort. Any answer will be appreciated. Thanks in advance
0 Kudos
HafidhIhromi
New Contributor
And also, how does the 'count' function works? Does it work just the way like in the help files? like this :
example.1
 count("cityengine", "e")
 # result = 2
 
example.2
 count("cityengine rocks my world; cityengine should rock yours too", "cityengine")
 # result = 2



Can the 'count' function used to count how many 'crossing' and 'junction' are there in the selection, and then report it? I need this to count the con value as I mentioned on my previous post. Thanks
0 Kudos