Conditional Rule File - Unexpected Token

1645
4
Jump to solution
04-01-2017 07:43 AM
GThomson
New Contributor III

Hi there,

Still very much a learner at using CityEngine (and this forum), so I'm hoping this is a dead easy rookie mistake you guys can help with...

I have building layouts I've imported from ArcMap, I have worked my way up to the point of trying to create a conditional rule to apply a roof type based on the height and area of the building (which is already included within the attributes), and a colour based on whether the building is "Special" (for want of a better term) or not, which i will change myself.

My current rule file is as follows:

## Attributes ##

attr Height = 0
attr Area = 0

@Range("Y", "N")
attr Special = "N"

## Rules ## 

@StartRule
Building -->
     extrude(Height)
     comp(f){side :  Colour | top : RoofType }
          
RoofType--> 
      case Height < 12 :
           case Area < 50 : roofGable(22.5) Colour
           case Area > 50 :
                50% : roofHip(20) Colour
                25% : roofShed(10) Colour
                25% : roofShed(0) Colour
           else:
      case Height > 12 && Height < 25 : 
                 50% : roofHip(20) Colour
                25% : roofGable(22.5) Colour
                25% : roofShed(0) Colour
                else:
      case Height > 25 : roofshed(0) Colour
      else: Colour

Colour-->
          case Special == "N" : color("#c7d3de") 
          case Special == "Y" : color("#00338d") 
          else: color("#c7d3de") ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Long story short, its not working. My last line of code " else: color("#c7d3de") " claims there is an unexpected token, and I think this is where it is going wrong... I have tried fixing it with a terminator e.g. "End.", amongst other things, but I think I'm missing something...

Any help anyone can offer would be greatly appreciated.

Thanks!

Gavin

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
F_RContreras
New Contributor II

Hi;

It should go something like this:

attr Height = 0
attr Area = 0

@Range("Y", "N")
attr Special = "N"

## Rules ##

@StartRule
Building -->
     extrude(Height)
     comp(f){side :  Colour | top : RoofType }
          
RoofType-->
      case Height < 12 :
           case Area < 50 :
                   roofGable(22.5)
                   Colour
           else :
                50% :
                    roofHip(20)
                    Colour
                25% :
                    roofShed(10)
                    Colour
                else :
                    roofShed(0)
                    Colour
           
      case Height > 12 && Height < 25 :
                50% :
                    roofHip(20)
                    Colour
                25% :
                    roofGable(22.5)
                    Colour
                else :
                    roofShed(0)
                    Colour
                
               
      else :
              roofShed(0)
              Colour
              
   

Colour-->
      case Special == "N" :
              color("#c7d3de")
      else :
              color("#00338d")

The mistake is when applying a conditional rule, you must leave the "else" statement for one of the values in the range; in the case of your Colour rule, you have a range of "yes" and "no" but you include an "else" for which there's no parameter, same with your % in the roof rule, 50% + 25% + 25% = 100%, so there's no room for another option

View solution in original post

4 Replies
F_RContreras
New Contributor II

Hi;

It should go something like this:

attr Height = 0
attr Area = 0

@Range("Y", "N")
attr Special = "N"

## Rules ##

@StartRule
Building -->
     extrude(Height)
     comp(f){side :  Colour | top : RoofType }
          
RoofType-->
      case Height < 12 :
           case Area < 50 :
                   roofGable(22.5)
                   Colour
           else :
                50% :
                    roofHip(20)
                    Colour
                25% :
                    roofShed(10)
                    Colour
                else :
                    roofShed(0)
                    Colour
           
      case Height > 12 && Height < 25 :
                50% :
                    roofHip(20)
                    Colour
                25% :
                    roofGable(22.5)
                    Colour
                else :
                    roofShed(0)
                    Colour
                
               
      else :
              roofShed(0)
              Colour
              
   

Colour-->
      case Special == "N" :
              color("#c7d3de")
      else :
              color("#00338d")

The mistake is when applying a conditional rule, you must leave the "else" statement for one of the values in the range; in the case of your Colour rule, you have a range of "yes" and "no" but you include an "else" for which there's no parameter, same with your % in the roof rule, 50% + 25% + 25% = 100%, so there's no room for another option

GThomson
New Contributor III

Ah excellent! Thank you, such a simple fix for something that had me completely confused for hours... 

Many thanks for the help and explanation.

0 Kudos
CherylLau
Esri Regular Contributor

For conditional rules, you don't actually need to make sure that the else statement is reachable.  The Colour rule with two case statements checking if Special is "N" or "Y" and an else statement is valid code and will run correctly.  Since the range of the attribute Special is limited to either "Y" or "N", then the else statement will not be reached, but it is still grammatically correct code, and it will run as expected.

There are compile errors because of errors in the format of the conditional and stochastic (percentage) statements.  In a conditional construction, there can be any number of case statements followed by an else statement, but the else statement must be there (with operations specified).  Similarly, a stochastic construction must also end with an else statement.  Also, the percentages in a stochastic construction must be <=100, and the else statement will get the remainder percentage to make the whole thing sum to 100.  Here are the help pages:

Conditional Rule 

Stochastic Rule 

In your code on line 23, there is an else statement, which is probably intended to go with the case statements on lines 18 and 19, but the compiler thinks it belongs to the percentage statements on lines 20-22.  Whatever follows this else statement is interpreted as the code that should be executed if this else statement were to be reached.  Basically, to make the code work, an else statement for the stochastic construction on lines 20-22 is missing, and the else statement on line 23 is missing some operations after it (and similar for line 28).  In general, if no operations are desired, you could write "NIL".  Or, as Felix points out, you can structure your statements so that one case statement is for when area < 50, and the else statement takes care of the situations when area >= 50.  I wrote this so that you could hopefully understand what's going on with the conditional and stochastic constructions, but you can certainly use Felix's code to solve your problem.  However, note that you'll also want to make sure you account for the case where Height==12 by using the <= or >= signs in your conditions.

GThomson
New Contributor III

That's been a great help in giving me a bit of a stronger understanding! Still trying to get my head round it, but this clears up a lot of the issues I had when I was trying to construct these types of rule.

Thanks!

0 Kudos