Tutorial 7 — Advanced Trip Modeling & Time-Based Analysis

  • Completed Tutorial 7 script here: Download

Modeling Proportional Building Population from Parcel Data

  • Navigate to the “Import Building from OSM” section in the example script, and embed the imported OSM attribute data to the building curves via the Embed Metadata into Curve component — so we can lookup attribute data later.
  • Repeat the same process for the parcel dataset.
  • To build population data into the building footprints, we will use the ResiArea and ComArea information from the parcel dataset.
  • Compare the Building Footprints to the Parcels geometry. Notice that some parcels include multiple buildings. Therefore, for each parcel we will distribute the Resi/Com Area proportionally between buildings within it based on the building’s Gross Floor Area or Volume (assuming that all buildings have the same floor-to-floor height).
  • Pass the Building footprints into an Area component to get the centroid of each building. Use the PointInCurve component to test whether every building points is within each parcel. (Make sure that the building footprints list is Flattened — so every building centroid is tested against each parcel)
  • The Relationship(R) output from PointInCurve categorizes every point as 0 — outside, 1 — coincident, 2 — inside of the curve tested. Any building centroid touching or inside each parcel curve will be given a 1 or 2 value (True) and centroids outside (False). In essence, this is a list of True/False pattern that determines which building is inside each parcel.
  • Place a CullPattern component, connect the list of Flattened building footprint into List, and the Relationships(R) output into Pattern(P).
  • Look at the result list structure and compare to the parcel and building footprint data list — notice that there are 709 curves grouped in the same data-tree structure as the parcel data list (some building curves do not fall into any parcels, and are therefore culled from the list)
  • Now that we’ve grouped building footprint by parcels, calculate each building’s Building Volume by calculating the building area via Area and multiply it with building height from OSM metadata via LookupMetadata.
  • Calculate the total building volume of each parcel, and divide each individual building volume by total volume to get the Volume Proportion of each building.
  • Retrieve Residential Area (ResiArea) and Commercial Area (ComArea) from the parcel dataset via LookupMetadata. Multiply the respective areas with the building’s proportion ratio — finally, you now have Resi/Com Area per Building.
  • Connect the two area values to BuildingPopulation component. Here we can translate program areas (Resi / Com) into Residential and Office population by using an approximate Area/per person ratio + building logistical proportions.
  • Use the following ratio and connect them into Residential Programs provide 40 sqm / person
  • We now have a list of metadata including Residential Population and Office Population.
  • To merge these metadata into the building footprints, first ensure that the two data trees are the same — a quick ListLength and CullPattern combination will remove any extra data from the longer list. (This happens when some of the data from the second data tree were invalid and therefore no longer exist.)
  • use MergeMetadata to combine the existing building footprint metdata with the new population metadata. Rebuild the Urbano building using a new CreateBuilding component.
  • Finally, we have a set of detailed building footprints with population. Connect the buildings into the BuildUrbanoModel component.

Creating Routing Factor by Network Betweenness

This part of the tutorial will combine work done in Tutorial 4 — Network Analysis. You can also Download Tutorial 4 Files here.

Recall in Lecture Space Syntax: Urban Network & Spatial Relations, spatial relations of the street network often inform human travel behavior. Specifically, network betweenness (through-movement potential) describes the accessibility of a street and the likelihood of it being chosen in a route.

In Urbano, the default routing behavior is via the shortest path. As we know, this is rarely how people travel (shortest path is also known as the taxi-driver route). To improve the accuracy of the simulation, lets incorporate the betweenness of a street as its Routing Factor.

The Routing Factor modifies the relative length of a street segment in the overall graph. In short, a street with a routing factor of (0.5) is perceived as half as long in the shortest path calculation and therefore more likely to be chosen!

  • First, filter the streets that are non-pedestrian (motorways, trunk, etc.) Since the street network from OSM can be messy, you may have to include some non-pedestrian street types to ensure the completeness of the network (no missing streets)
New filtering module in Tutorial 7. Script may look different than Tutorial 4
  • Next, we will combine the network analysis operation from Tutorial 4. Copy over the “Network Analysis” portion of the script (Processing Geometry, Custom Weights, Spatial Relations Calculation, Visualize Network.)
  • To convert betweenness value into routing factor, we will create a copy the “Remap log¹⁰ values to 0–1” used in the Visualize Network group.
  • Its very important to recognize that a LARGE betweenness value (more accessible) should correspond to SMALL routing factor (smaller travel cost.)
  • Instead of mapping the results to 0–1, we will remap the betweenness values to 1–0.5, meaning that a highly accessible route is considered 50% shorter than its actual length in a shortest path calculation.
  • Create a new metadata using the CreateMetadata component, select Routing Factor as the Key and use the remapped values as Values (Right-click on Values and select “Graft” to create a one-to-one match between Key and Values)
  • Use another CreateStreetNetwork component to combine street segments (from 1. Process Geometry component in the Network Analysis portion)
  • Connect the newly created routing factor metadata into the Metadata input, and supply UTM and Vec values from the ImportOSMData component at the beginning of the script.
  • Finally, we have a street network with routing factors based on network betweenness. Connect the street network into the BuildUrbanoModel component.

Creating Destination Factor by Amenity Capacity

Similar to the Routing Factor, the Destination Factor modifies how Trip Population is calculated by the Urbano Trip Engine.

As explained in Lecture — Modeling Mobility, the Amenity Demand is an estimate of the total population that will take a trip to a given amenity. The destination factor helps determine the proportional population each amenity will receive. A HIGHER Destination Factor means that it will attract a HIGHER population to visit.

For example, in a simulation with two amenities (A, B) of the same category (restaurant), where their respective destination factor are 0.1 (A) and 0.9 (B) — the trip engine first determines how much of the Total Population will visit a restaurant (based on the Amenity Demand Profile), and from the Trip Population, 10% of the population will visit Amenity A, and 90% will visit Amenity B.

  • See class demo for how to create destination in tutorial file.

Visualize Demand/ Movement Over Time

The first part of this section uses the example from Terrain Example in Workshop 2. You can also Download Example Files here.

The second part of this second uses the visualization created from Tutorial 5 — Trip Simulation with Urbano. You can Download Tutorial 5 Files here.

Creating a Simple Animation

  • Grasshopper can be a great tool for creating animations using the “Animate Slider” feature.
  • Open the Terrain Example in Workshop 2. In this example, see that the water flow is controlled by a slider. The slider controls the Parameter (t) value from 0.00–1.00 of each waterflow curve used by the EvaluateCurve component to place a point on each curve. The “movement” is created when we slide the parameter quickly from one end to the other.
  • We can easily recreate this movement by exporting a screenshot for each step of the slider (a frame), and compiling all the frames to create a stop-motion animation.
  • Right-click on the Slider, select “Animate…”. You should see the animation controls window pop up. Specify the Export Directory (recommended to create a new folder for this since this will produce many screenshots). Leave the Filename Template as is, but adjust the Viewport and Resolution to the desired output format.
  • The Frame Count field determines how many steps will Grasshopper cycle the slider. Make sure that the frame count matches the slider range. (Ex. the slider in the example ranges from 0.00–1.00, meaning that there are 99 steps on the slider.)
  • Once done with the export settings, click “OK” to start the animation.
  • Once the slider animation completed, navigate to the export directory and you should see a series of screenshots in sequence, each image representing a step in the slider.
  • To compile these images into a stop-motion-animation, launch Photoshop. Select File…Open…, and select the first frame in the folder. Check the “Image Sequence” box at the bottom of the window, and click “Open”.
  • Specify the number of frames per second, and click “OK”.
  • If done correctly, the exported screenshots will be imported into Photoshop as a video group. In Photoshop, you can further adjust the color, speed, and duration of the animation.
  • When ready to export, select File…Export…Save For Web (Legacy), and export the animation as a .GIF file.
  • Et voila! Now you have an animated GIF of your Grasshopper Visualization!

Animating an Analysis

  • We can adapt the same method to animate a complex analysis like the trip simulation, as long as the analysis includes a sequential element (Travel Demand, Sun Position, Elevation of Building…etc.)
  • Since Urbano’s Amenity Demand Profile includes demands across 24-hours, lets try to visualize the travel pattern of a weekday in Downtown Brooklyn!
  • Copy the Visualization clusters from Tutorial 5 into the script, and connect the result trips from the new Trip Engine simulation into the visualization clusters. Since the input is the same datatype, you should need to make any big changes.
  • Create an animation scene. Adjust and add any graphic elements to your liking. In the tutorial file, I added the NYC boundary as a nice backdrop.
  • To animate the Trip Simulation over 24-hours, simply connect a slider ranging from 1–24 into the index input of AmenityDemandProfile , and follow the same steps to animate the slider.
  • Since the trip analysis takes about 1–3 minutes to run each time, you can expect the script to take approximately 48–72 to simulate a full 24-hours trip simulation (although some time steps will run faster since there are fewer trips to simulate based on smaller demand from 2AM–6AM!).
  • So make sure that you save your files before animating through the slider. Once the script is running, take a coffee break and come back in an hour!
The final result should look something like this

--

--

Richard Chou
Data Mining the City — City Playlab

I am passionate about developing data-driven design strategies for urban design and city building of the next century.