2 Replies Latest reply on Dec 9, 2013 11:08 PM by hughestj

    Creating a City from GIS data - Transport Infrastructure

    ejph
      Hello Everyone,


      I thought I'd start a thread for people wishing to make simple City Models based in part, on real world data in ArcGIS.  Hopefully it will help in the creation of quite a complex city model that people can modify for their own purposes.   It's intended to be a simple discussion that anyone can join in with so feel free to add to it!   This will assume a basic working knowledge of CityEngine, for example import/export of data as well as tools like 'CleanUp' graph.

      NB : I am not a programmer and my knowledge is limited in many areas of CityEngine so if you spot mistakes or can suggest betters ways of doing something, please tell me!

      As you can link CGA rules together and add to the complexity I thought it would be helpful to break the various components down.   Firstly I'm a planner mainly working on Master Planning projects so this is from my perspective, I would welcome other people's perspectives though!

      The city model I want to create already has a few distinct data sets, they can be simply characterised as:

      • Existing data, shapefiles/GDBs (polylines, and polygons) of the existing city which are quite detailed

      • New data, GDBS (again polylines, and polygons) of the proposals/planned expansion which as a master plan are more general (No internal local streets yet) which I have created

      Now to break it down further, I want to control and model in CityEngine the general headings below:

      1. Transport Infrastructure (mainly roads, but some rail and other types, such as covered market street)

      2. LandUse (I put it at the top because,it's what I do)

      3. Plotsizes (Blocks on or off, Lot sizes, lot minimum width etc..)

      4. Models, initially simple block models that we can add detail to based on Landuse, plotsizes etc..

      So I'm proposing that we aim to create a set of CGA rules that are easy to understand and create a basic city model from which we can add more complexity to.  I really want to build code that can be flexible, often there are a couple of ways to do rules in CityEngine but I propose we don't always do the simple route, that way people can build in complexity.    I'm also assuming that we start with all the base data we need.

      I suggest we start with a discussion of Transport Infrastructure since these allow blocks to be created.   I've looked at the rule files in the tutorials in particular the Modern streets CGA.  However as we're building on existing data I think we need to start with what fields in the polyline data from the GIS we might want to use:

      1. Right of Way (ROW) width

      2. Number of Lanes

      3. Direction (one way, two way and actual direction)

      4. Pavement (sidewalk in the USA!)  Left

      5. Pavement (sidewalk in the USA!)  Right

      6. Surface (asphalt, unmade etc..)

      7. Class (Motorway/Highway/Main/Secondary/Distributor/Access/Track)

      8. Central reservation

      9. Bridge?

      Any other fields we might want to use in CityEngine,  any suggestions?

      So the best way of controlling how CityEngine draws the correct width of your streetnetwork is via the "layer attributes" window once you've selected the imported Streetnetwork data in the Scene window.  CityEngine helpfully already does some of this automatically but it doesn't hurt to repeat it!

      I've modified the code to show you can change the road width based on a text field not just a number :

      streetscale = 1  // street width scale factorstreetWidthDefault = 5
      width            = getObjectAttr("rdClass")// Instead of reading a number this reads the type of road eg motorway or local street I use prefix rd to indicate where it is located
      attr streetWidth = // street width dependeding on "width" attributes
          case width == "Primary" : 55 * streetscale
          case width == "Secondary" : 30 * streetscale
          case width == "Tertiary" : 20 * streetscale
          case width == "Footpath" : 2.5 * streetscale
          case width == "" :0 *streetscale // if there is no class attribute then the width is zero
          else           : streetWidthDefault
      


      So can anyone add anything more to this, thoughts about the process or additional ways to set road widths?

      Next post will be creating a CGA rule file that models a road based on the object attributes such as surface and class...
        • Transport Infrastructure 2 - Simple Road
          ejph
          The next part of this thread is to start a simple road CGA rule file that can take into account the road classification field.   This code is based in part on the tutorial examples given by CityEngine but I've modified them for the purpose of this discussion (with myself).   The principles here can be applied for many rule sets not just road networks.

          This CGA rule will create different looking roads depending on the road classification and place a lamp post at regular intervals on designated streets.  I've also added a rule for a covered market street but this is to be added manually in CityEngine.

          Road classes are taken from the Streetnetwork's "layer attribbutes" with code code like this : attr roadClass = getObjectAttr("ROADCLASS_FIELDNAME_FROM_GIS")

          const lamp_asset = "lamppost.obj" // this is under your assets directory you can get a quick model from places like Google 3D Warehouse just be sure you have permission to use them!
          attr sidewalkHeight =0.25
          attr lampDistance =25 // you could change this or add different attributes for each road class
          attr roadClass = "None" // attribute name declared in layer attribute 
          
          
          
          
          Street--> // I've coloured these in simple primary colours so you can see what's happening
           case roadClass == "Primary" : color ("#ff0000")
           case roadClass == "Secondary" : color ("#00ff00")
           case roadClass == "Tertiary" : color ("#0000ff") // you can add more classes here
           else : color("#535353")
          
          
          Sidewalk-->
           set(trim.vertical,false) set(trim.horizontal,false)
           comp(f){ all: SidewalkPart }
          
          
          
          
          SidewalkPart -->
           case scope.sx > 5:
            SidewalkWithCurbs
            alignScopeToAxes(y) t(0,sidewalkHeight,0)
            SidewalkLampTest
           else:
            SidewalkWithCurbs
          
          
          
          
          SidewalkWithCurbs -->
           extrude(world.y,sidewalkHeight)
           comp(f) 
            { top   : split(y){ sidewalkHeight : Curbs | ~1 : Pavement }
            | front : Curbs }
          
          
          SidewalkLampTest--> // in this example only my primary and secondary classes of street get lampposts!
           case roadClass == "Primary" : SidewalkLamps
           case roadClass == "Secondary" : SidewalkLamps
           else : nil 
          
          
          SidewalkLamps -->
           split(x){ ~lampDistance :  NIL 
            | { 0.1: Lamp | ~lampDistance : NIL }* }
           
          
          
          Pavement -->
           color("#C0C0C0")
          
          
          
          
          Lamp -->
           t(0,0,scope.sz-sidewalkHeight*2)
           s(0,5,0)
           r(0,90,0)
           i(lamp_asset)
          
          
          
          
          Curbs -->
           color("#C0C0C0")
          
          
          
          
          Crossing-->
           color("#535353")
          
          
          
          
          Junction-->
           color("#535353")
          
          
          
          
          JunctionEntry-->
           color("#535353")
           
          Island-->
           extrude(0.5) color("#008000")
          
          
          StreetMarketRoof--> // you need to select the shapes start rule manually to enable this but you could do it via road class as well
              extrude(10) comp(f) {  bottom : marketstreet | top : marketroof  } 
          
          
          marketroof--> roofGable(22.5)
          marketstreet -->  reverseNormals color("#008000") // I seem to need to do this so I can have a coloured street under my marketroof
          
          


          Has anyone got anything else to add or correct?   Can someone provide code for a nice simple bridge?
          • Re: Creating a City from GIS data - Transport Infrastructure
            hughestj
            Hey Elliot,

            Has this thread fallen off the radar? Should I be looking somewhere else?

            Cheers!