Friday, February 3, 2017

CityEngine vs Drone2Map

Ever since Drone2Map was released, I've wanted to play around with its functionality to see what it could do. When the Esri South Africa Midrand moved to a new office it was the perfect opportunity to capture drone images and run it through Drone2Map. I also decided to create a CityEngine model of the building (using entirely procedural modelling) to compare it with. 



Drone2Map

Drone2Map is an easy to use desktop application that allows you to create an accurate 3D representation of the area in a couple of easy steps:

Step 1:

Open Drone2Map and choose the type of project (2D or 3D) that will be created. A 2D mapping project allows you to create two dimensional datasets including Orthomosaic imagery and a DSM. In order to create 3D datasets select the 3D mapping project. This extends the 2D mapping by also enabling creation of 3D point clouds, 3D textured mesh and a 3D PDF.




Step 2:


Select the Processing Options tab and select the 3D features to be created. Keep in mind that the number of dataset types to be exported will increase the processing time. In this example I have selected a LAS point cloud, .obj and a scene layer package.

Step 3:


Click on the Run button to start the processing. Once the processing has been completed, the 3D textured mesh is added to the scene.



The image below compares the output mesh (right) to the original drone image (left). Once the 3D scene package has been completed, it can be uploaded to ArcGIS Online. Click here to view the 3D Textured mesh in the ArcGIS Online scene viewer.

CityEngine

The next step was to create a rule to create the office in 3D, creating all the geometry aspects from procedural modelling. The fact that no 3D models (like .obj or collada files) were used in the CGA rule, really shows the power of what is possible with procedural scripting (even though the stairs look a bit funny). The video below shows what the rule looks like in CityEngine:



Finally the we can compare the Drone2Map 3D textured mesh to the procedurally created building in a CityEngine webscene. I'll let you decide which one looks better.

View the 3D Web Scene









Tuesday, January 12, 2016

CityEngine & ArcGIS Pro combine to show CCTV coverage in 3D

Happy 2016!!

Once again I failed to post as regularly as I would have liked towards the latter part of 2015. Hopefully I can mange my time better in the new year...(no promises). 

I was asked to create and co-present a presentation at the Esri Africa User Conference plenary session in November 2015 which shows the value of 3D GIS. I thought it is a good place to start the 2016 Urban Scene blog posts.

The aim the presentation was to show the location and coverage of CCTV cameras in downtown Johannesburg, as well as how changing some of the camera attributes (like angle, direction and length) can increase the covered areas. CityEngine was used to create the CCTV coverage rules, and ArcGIS Pro's analysis abilities were utilised to determine the covered areas.  


 CityEngine:

Step 1 was to create a CityEngine rule that creates 3-dimensional pyramid shapes representing the visible area of each camera. The CGA rule is shown in the images below:

Attributes


The attributes used by the Rule file are described in the image above. Note that the Width and HorizontalRotation attributes derives their values by calling the getWidth and getRealDirection functions, respectively.

The getWidth function uses the Pythagorean mathematics to calculate the width (length of the opposite triangle side) by using the CameraAngle and ViewLength attributes.

The getRealDirection function converts the azimuth attribute (N= 0, E = 90, S = 180, W = 270) so that the coverage area has the correct real-world direction.



Rules

The image below show the rather simple rules used to generate the viewing area:


  • Object: The Object rule uses the i-function to transform the CCTV point to an existing triangular Collada shape and then calls the Rotate rule.
  • Rotate: The rotate function uses the VerticalRotation and HorizontalRotation attributes to change the angle of the viewing area, before calling the Scale rule.
  • Scale: Finally the Scale rule scales the viewing are according to the Width, VerticalHeight and ViewLength attributes. The rule then centers, colours and changes the transparency of the 3D viewing area.



ArcGIS Pro

The second part of the presentation showed how these CityEngine rules can be implemented in ArcGIS Pro for further analysis. The examples are listed below


  • Display the 3D view areas alongside existing 3D content (such as buildings) in ArcGIS Pro.  



  • View feature information in a pop-up. This can include attributes, pictures, videos or HTML attributes such as an i-frame of the Google Street View.




  • Calculate the % of the area covered by the cameras. The image below shows the Before and After scenes after additional cameras were added. We can analyse the coverage of the new additions and compare the calculated values to the previous scenario.


Monday, August 31, 2015

Building Simple Urban Development rules Post 4: "Section" (b)

I've had a couple of questions after my previous post about reporting at floor level. One of the questions was: Instead of creating mixed floor use randomly, is it possible to specify the floor usage of each floor manually?

So, here is my answer:

Yes... to a certain degree :)

I decided to create a new rule file, rather than expanding on my existing rule (as per my previous posts). So....lets start:

The aim of the rule is to create 2 to 4 "sections" in my building that will have different zoning attributes (selected manually by the user).

Splitting sections

Attributes

  • Firstly, I created attributes for the building and floor heights. 
  • Second step was to create attributes for the number of floors that each "section" will have (for example section1NumFloors = 4)
  • Step 3: Create zoning attributes for each section 
  • Step 4: Create a numerical attribute to determine the height of each section (by multiplying the floor height with the number of floors) This attribute will be used when we split the building vertically

Functions

The next part describes the functions for this rule:
  • getFloors: Determines the total number of floors of each building by dividing the building height by the floor height and returning an integer
  • testFloors: This functions checks that the total number of floors of all the "sections" are less than the number of floor returned by getFloors. If the total is less than the maximum floors, the building will be divided into 4 sections. If the number of floors exceed the maximum, one section at a time will be removed until the number of floors is less than the maximum. (I could probably have worded that better....)

Rules

Finally we get to the cool part! The rules:

  1. Lot--> Extrudes the building according to building height and splits it into a top part and side parts
  2. SplitBuilding--> This rule uses testFloors as a guide and splits the floors vertically into sections (either 2; 3; or 4 sections)
At this point our building is divided into 4 sections.




Each section calls the appropriate nested split function, for example Section1Floors


  • Section*Floors--> These rules splits each section repetitively vertically until the end of the section has been reached. Each one in turn calls the SetZoningSection rules
  • SetZoningSection--> These rules assigns zoning type of the floor to disply each zone differently.




So to conclude: it is possible to assign individual zoning types per section manually. By dividing the building into sections we have made the rule a bit more robust, as the number of floors per division can also be changed manually. One can always extend this rule to include more "sections" but for most uses I think 4 should be enough.

Thanks for the comments regarding this series.
If you have any additional comments, questions or suggestions regarding this post please feel free to add them below.

Monday, August 17, 2015

Building Simple Urban Development rules Post 4: Reporting on Building Floors

Up to this point in the Building Simple Urban Development series we've had a look at designing parts of the city. Extending on the previous post where I added detail to our rules (in the form of parking), this week I will have a look at creating reports at floor level.

In most cases a building is occupied by various inhabitants. In the example used during this post, we will imagine that each building can have a "Mixed" zone type. These buildings have different uses per floor, these will include Commercial Use, Residential Use and Unspecified. I will also create reports showing revenue generated by all floor types (using the floor area).

Individual Floor Usage

Attributes

In this post, there was only 5 attributes added (see the image below). These were:
  • CommercialFloorUse: The % of floors that will have a commercial use
  • ResidentialFloorUse: The % of floors that will have a residential use
  • CommercialRevenueSquareMeter: Revenue generated per square meter of commercial use
  • ResidentialRevenueSquareMeter: Revenue generated per square meter of residential use
  • VoidRevenueSquareMeter: Minimum Revenue  lost per square meter
     **Another disclaimer: Just ignore the bad attribute naming convention....I didn't spend too much time on the attribute names
  • I also added a "Mixed" type to the ZoneType attribute that we created in Post 2.

Attributes



Rules

Only two rules were added during this post: ColorFloors and ColorFloors2 (once again great usage of my naming convention).

  • ColorFloors checks if a floor has a "Mixed" ZoneType, and calls the ColorFloors2 rule if it does. It also creates a report for all floors created. To read more about reports, click here.
  • ColorFloors2 uses the CommercialFloorUse and ResidentialFloorUse attributes to determine the usage of each floor by applying the "p-function". The remaining floors  are assigned a usage of Unspecified. The rules also create reports on each floor usage as well as the potential revenue generated.

Rules


Reports

The reports that are created with the new rules can be seen in the image below. The N, Sum and Avg, columns returns the Count, Sum and Average of each floor or floor revenue, respectively.
  • All Floors displays the count of all floors (excluding the ground floor) 
  • Commercial Floors, Residential Floors and Unspecified Floors returns the count for each floor usage type
  • Commercial Floors Revenue and Residential Floors Revenue returns the count of each floor type as well as the estimated revenue generated by each (as a sum and average). The revenue is generated by multiplying the square meters of the floor (getArea in the image above) with the price-per-square-meter for the specified floor type (e.g. CommercialRevenueSquareMeter
  • The Unspecified Floors Revenue calculates the estimated amount of revenue lost by having a unspecified/void floor. 

Reporting per Floor





Tuesday, August 4, 2015

Building Simple Urban Development rules Post 3: Adding Detail (Parking)

In the 3rd post of the Building Simple Urban Development rules series, we'll have a look at extending the rules by adding more detail.

In the previous post we divided our building into 4 "types", Commercial, Industrial, Residential and Parks (coloring each one individually). In this post we'll have a look at adding parking areas to our buildings.

Procedural Parking in CityEngine
But first we'll make a couple of assumptions:

  • Parking areas will only be assigned to half of all Commercial buildings
  • Parking areas will start from the floor and will extend to a quarter of the building height.
  • We will add ramps between the parking floors on both sides of the building (up and down)

Attributes

Following the same template for the rest of the post series, we'll first have a look at the attributes added during this post.

Attributes
From the image above, the attributes that were added include:
  • useHeight ( remaining building height after the parking has been subtracted)
  • floorHeight (random number between 2.8 and 4 meters)
  • parkingHeight (roughly a 1/4 of the building height)
  • rampObject (a Collada file for the ramps)
  • Textures
  • Counts for reporting purposes

Rules

There were quite a lot of rules added during this post. The first half of the rules are shown below

Rules added (part 1)

These are:

  • ErrorTracking: Defines whether a building exceeds its height restriction
  • SplitBuilding: Guides 50% of all Commercial buildings to create parking
  • ExtrudeFloor and ExtrudeFloor2: Uses the bottom part of an extruded building (while discarding the sides and top parts) and extrudes it inversely (-Height)
  • CheckDimensions: Verifies that neither sides of the footprint polygon exceed 60% of the length of the other. This helps to cancel out lop-sided buildings
  • HasParking: Checks if a building exceeds it maximum height and splits it accordingly:
    • If it exceeds the max: The building is split into a groundfloor, parking, remaining height and an error
    • If it doesn't exceed the max: It is split into a groundfloor, parking and remaining floors
  • RemainingFloors: Counts and reports on the number of non-parking floors. Splits the remainder of the building into floors and color it
  • CreateFloor: Counts and reports the number of parking floors and uses the bottom part of the floor "cube" to create parking floors.

The second part describing the rules in this post is focused on splitting each floor horizontally into parts in order to create Ramps, General Parking, Ramp Platform and Pillars respectively (see image below).


Splitting the Parking Floors

I think it would be best to look at the above image step-by-step:
  1. 50% of all Commercial buildings are defined as having parking available
  2. Roughly 25% (bottom 1/4) of the building is split into parking floors, and then split again into sections
  3. First, the parking floor is split into three parts (from top to bottom in the image). A ramp on the left, general parking and a ramp on the right
  4. Each ramp is then split into three parts (from left to right). A ramp platform at the top, the actual ramp, and another ramp platform at the bottom
  5. Similarly each ramp platform is split (again) to create pillars.

I know, I know....another long post. So grab a quick cup of coffee and lets wrap this up...



The rules showed in the image above are:

  • ParkingRamps: Splits the parking floor in 3 parts (ramp, parking, ramp)
  • ParkingMain: Textures the general parking area
  • ParkingRampsLeft & ParkingRampsRight splits each ramp into 3 parts (platform, ramp, platform)
  • Each of the ParkingPillar* Rules splits the 4 platforms (4 corners of the building to create pillars)
  • ExtrudePillar: Extrudes the pillar upwards
  • AddRamp: Adds ramps, either upwards or downwards. This rule calls a Collada file and rotates it accordingly
  • Texture: Generic rule that takes a path name to an image as input and applies the texture to the shape

*Disclaimer: This example was made only to show the ability of using procedural rules. These methods are not perfect (far from it) so use the information and techniques on your own risk. 

Thursday, July 16, 2015

Building Simple Urban Development rules Post 2: Applying Scenarios

I started my previous post by talking about New Years resolutions, and posting more often....I then went on to publish the follow up post 6 months later.... My apologies for the very late response.

In my previous post I started look at the basics of CityEngine to create easy-to-use rules that incorporate  commonly found Urban Development rules. This post will extend that theme by applying various scenarios to a city. The post shows the ease at which CityEngine quickly updates the 3D content using different sets of attributes.

Applying different Zoning scenarios on the same data

Continuing from the 1st post of this series, we'll start by adding some more attributes. The first two attributes in the image below specifies the themes that will be applied to the scene.
  • Scenario: This attribute defines the Zoning theme that will be applied to the scene; either predominantly Residential, Commercial, Industrial or Mixed
  • ErrorScenario: If true, the scene will show buildings that exceed its height restriction. If set to false, the scene does not allow the buildings to exceed the height restriction at all.
The remaining new attributes are:
  • ZoneType: Assigns a percentage of the shapes to a ZoneType, according to the specified Scenario
  • Height: This attribute is determined by the getHeight function (described below)
  • HeightRatio: Assigns a value to HeightRatio according to the ZoneType. This value will be used later by the getHeight function.
  • MaxHeight: This is the height restriction associated with each ZoneType 

Adding rule attributes


This post adds one function to the rule, namely the getHeight function. The height is determined by multiplying the HeightRation with the square root of the shape area.
Functions

Finally, the Rules that were added were:

  • CreateBuilding: If the ZoneType is "Parks", go-ahead and color the shapes green, else call the ExtrudeBuilding rule
  • ExtrudeBuilding: If the ErrorScenario is set to true call ErrorTracking, else compare the building height to the maximum height. 
    • If height exceeds the max, extrude the building to the max, otherwise just extrude the building according to the height. (So to recap: if the ErrorScenario is set to false, the height exceeding errors will not be visible)
    • ErrorTracking: Checks whether the Height attribute exceeds the MaxHeight, if it does it will call the SplitBuilding rule.
  • SplitBuilding: This rule splits the building into a top (and colors it) and then into sides (which calls the ValidateBuildingHeight
  • ValidateBuildingHeight: This rule splits the sides of the building horizontally at the maximum height. Everything below this split is colored according to the ZoneType while the parts exceeding the maximum height is colored as red.

New Rules
To see the ErrorScenario theme in action, have a look at the video below.


Tuesday, January 6, 2015

Building Simple Urban Development rules Post 1: Coverage areas


First thing first... Happy New Year! I've got a feeling that 2015 will be a big year for 3D.

After the long off period, I find it difficult to start being productive straight away... I'd much rather focus on a little bit of 3D first.

Normally when writing a blog post I get a bit carried away and end up writing very long posts. So I've decided to start writing shorter, more to the point posts. This will probably help me write more often...call it a New Year's resolution if you want :)

Building Simple Housing Development rules

The focus for this series (for lack of a better word) will be back to the basics in the sense that it will focus on Urban Development (CityEngine's original purpose believe it or not).

It is probably worth mentioning that I am expanding this series as I go along, so I have no idea what will be the follow up post, or how many parts there are - guess we'll find out together.

Post 1: Coverage areas

In short, coverage areas (in this post anyway) refer to the percentage of the lot/property area that is covered by a building footprint. As I am not from a town planning background, I don't necessarily need to know about the HOW and WHERE of using coverage areas, I only want to be able to represent the rules procedurally. The best way of achieving this is to create a robust RuleFile that can be used with a number of different inputs.

Coverage refers to the % of property that is covered by a building


The first part of creating the rule files is - as in most cases - is setting up some attributes and functions. Normally writing a rule file is an iterative process, and this part will most probably be re-visited.


   
In the image above, we can see two coding blocks for attributes and functions. Lets start from the top and work our way down:

The first line creates a constant called Area. The value of Area is determined by calling the getArea function. The getArea function in turn executes a CE system function (geometry.area()), which returns the surface area of the property. Area is set as a constant so that it can not be changed by the user.

The ValidArea attribute value is determined by the getAreaValidation function. This function checks if the area of the property is larger than 100 m² and returns a 1 if is, otherwise it returns a 0. This attribute will be used at a later stage to ignore areas that are too small.

The remaining attributes define values for the Minimum Coverage, Maximum Coverage and the offset area.


The image above shows the simple rules to procedurally represent coverage areas.
The First step (Lot) is to check whether the area is large enough to contain a building. The second part (TopArea) makes sure the rule works with the top part of the the property.

The FootprintOffset rule then creates an offset using the OffsetDist attribute. The offset size can be changed as needed by the user. It then calls the SplitFootprint rule.

The SplitFootprint rule applies different rules to each of the shapes created by the offset tool: border and inside. The border is colored RED, while the inside shape calls the CheckCoverage rule.

Lastly, the CheckCoverage rule checks whether the Coverage (new shape area ÷ original area) is within the Minimum- and Maximum Coverage range. The tool also display the Coverage in a report that can be seen in the Inspector window in CE (see video below). If the Coverage is within the valid range, it is displayed as Green, else it is colored yellow.

The video below shows how the coverage area changes dynamically when the attributes are altered. You can see the changes in the area (Yellow vs Green), as well as the report (Coverage) when the Maximum Coverage, Minimum Coverage and Offset attributes are changed.