Class: URBANopt::GeoJSON::Building

Inherits:
Feature
  • Object
show all
Defined in:
lib/urbanopt/geojson/building.rb

Instance Attribute Summary

Attributes inherited from Feature

#feature_json

Instance Method Summary collapse

Methods inherited from Feature

#calculate_aspect_ratio, #create_origin_lat_lon, #find_feature_center, #get_min_lon_lat, #get_multi_polygons, #get_perimeter_multiplier, #id, #method_missing, #name, #schema

Constructor Details

#initialize(feature = {}) ⇒ Building

Used to initialize the feature. This method is inherited from the Feature class.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/urbanopt/geojson/building.rb', line 13

def initialize(feature = {})
  super(feature)

  @id = feature[:properties][:id]
  @name = feature[:properties][:name]
  @detailed_model_filename = feature[:properties][:detailed_model_filename]
  @floor_area = feature[:properties][:floor_area]
  @number_of_stories = feature[:properties][:number_of_stories]
  @number_of_stories_above_ground = feature[:properties][:number_of_stories_above_ground]
  @footprint_area = feature[:properties][:footprint_area]
  @template = feature[:properties][:template]
  @building_type = feature[:properties][:building_type]
  @system_type = feature[:properties][:system_type]
  @weekday_start_time = feature[:properties][:weekday_start_time]
  @weekday_duration = feature[:properties][:weekday_duration]
  @weekend_start_time = feature[:properties][:weekend_start_time]
  @weekend_duration = feature[:properties][:weekend_duration]
  @mixed_type_1 = feature[:properties][:mixed_type_1]
  @mixed_type_1_percentage = feature[:properties][:mixed_type_1_percentage]
  @mixed_type_2 = feature[:properties][:mixed_type_2]
  @mixed_type_2_percentage = feature[:properties][:mixed_type_2_percentage]
  @mixed_type_3 = feature[:properties][:mixed_type_3]
  @mixed_type_3_percentage = feature[:properties][:mixed_type_3_percentage]
  @mixed_type_4 = feature[:properties][:mixed_type_4]
  @mixed_type_4_percentage = feature[:properties][:mixed_type_4_percentage]
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class URBANopt::GeoJSON::Feature

Instance Method Details

#calculate_perimeter(feature) ⇒ Object

Used to calculate the perimeter from the floor polygon of a Feature. Returns the perimeter value.

Parameters
  • feature - An instance of URBANopt::GeoJSON::Feature



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/urbanopt/geojson/building.rb', line 234

def calculate_perimeter(feature)
  model = OpenStudio::Model::Model.new
  runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
  origin_lat_lon = nil
  origin_lat_lon = feature.create_origin_lat_lon(runner)
  spaces = feature.create_building(:space_per_building, model, origin_lat_lon, runner)
  surfaces = spaces[0].surfaces
  ground_surface = nil
  surfaces.each do |surface|
    boundary_condition = surface.outsideBoundaryCondition
    if boundary_condition == 'Ground'
      ground_surface = surface
    end
  end
  vertices = ground_surface.vertices
  n = vertices.size
  perimeter = 0
  for i in (0..n - 1) do i
                         vertex_1 = nil
                         vertex_2 = nil
                         if i == n - 1
                           vertex_1 = vertices[n - 1]
                           vertex_2 = vertices[0]
                         else
                           vertex_1 = vertices[i]
                           vertex_2 = vertices[i + 1]
                         end
                         length = OpenStudio::Vector3d.new(vertex_2 - vertex_1).length
                         perimeter += length
  end
  perimeter = OpenStudio.convert(perimeter, 'm', 'ft').get
  perimeter = perimeter.round(4)
  return perimeter
end

#create_building(create_method, model, origin_lat_lon, runner, zoning = false, scaled_footprint_area = 0, other_building = @feature_json) ⇒ Object Also known as: create_other_building

This method creates a building for a given feature specified in the feature_json as per the create_method.

Returns an array of instances of OpenStudio::Model::Space .

Parameters
  • create_method - Type:Symbol - :space_per_floor or :space_per_building methods can be used.

  • model - Type:String - An instance of OpenStudio::Model::Model_ .

  • origin_lat_lon - Type:Float - An instance of OpenStudio::PointLatLon indicating the latitude and longitude of the origin.

  • runner - Type:String - An instance of OpenStudio::Measure::OSRunner for the measure run.

  • zoning - Type:Boolean - Value is true if utilizing detailed zoning, else false Zoning is set to False by default.

  • scaled_footprint_area - Used to scale the footprint area using the floor area. 0 by default (no scaling).

  • other_building - _Type:URBANopt::GeoJSON::Feature - Optional, allow the user to pass in a different building to process. This is used for creating the other buildings for shading.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/urbanopt/geojson/building.rb', line 69

def create_building(create_method, model, origin_lat_lon, runner, zoning = false, scaled_footprint_area = 0, other_building = @feature_json)
  number_of_stories = other_building[:properties][:number_of_stories]
  number_of_stories_above_ground = other_building[:properties][:number_of_stories_above_ground]
  number_of_stories_below_ground = other_building[:properties][:number_of_stories_below_ground]
  number_of_residential_units = other_building[:properties][:number_of_residential_units]

  if zoning
    surface_elevation = other_building[:properties][:surface_elevation]
    roof_elevation = other_building[:properties][:roof_elevation]
    floor_to_floor_height = other_building[:properties][:floor_to_floor_height]
  else
    maximum_roof_height = other_building[:properties][:maximum_roof_height]
  end

  if number_of_stories_above_ground.nil?
    number_of_stories_above_ground = number_of_stories
    number_of_stories_below_ground = 0
  else
    number_of_stories_below_ground = number_of_stories - number_of_stories_above_ground
  end
  floor_to_floor_height = zoning ? 3.6 : 3

  if number_of_stories_above_ground && number_of_stories_above_ground > 0 && maximum_roof_height && !zoning
    floor_to_floor_height = maximum_roof_height / number_of_stories_above_ground
    floor_to_floor_height = OpenStudio.convert(floor_to_floor_height, 'ft', 'm').get
  end

  if create_method == :space_per_floor || create_method == :spaces_per_floor
    if number_of_residential_units
      model.getBuilding.setStandardsNumberOfLivingUnits(number_of_residential_units)
    end
    model.getBuilding.setStandardsNumberOfStories(number_of_stories)
    model.getBuilding.setStandardsNumberOfAboveGroundStories(number_of_stories_above_ground)
    model.getBuilding.setNominalFloortoFloorHeight(floor_to_floor_height)
  end

  spaces = []
  if create_method == :space_per_floor || create_method == :spaces_per_floor
    (-number_of_stories_below_ground + 1..number_of_stories_above_ground).each do |story_number|
      new_spaces = create_space_per_floor(story_number, floor_to_floor_height, model, origin_lat_lon, runner, zoning, scaled_footprint_area)
      spaces.concat(new_spaces)
    end
  elsif create_method == :space_per_building
    spaces = create_space_per_building(-number_of_stories_below_ground * floor_to_floor_height, number_of_stories_above_ground * floor_to_floor_height, model, origin_lat_lon, runner, zoning, other_building)
  end
  return spaces
end

#create_other_buildings(other_building_type, other_buildings, model, origin_lat_lon, runner, zoning = false) ⇒ Object

This method is used to create the surrounding buildings as shading objects.

Returns an array of instances of OpenStudio::Model::Space.

Parameters
  • other_building_type - Type:String - Describes the surrounding buildings. Supports ‘None’, ‘ShadingOnly’ options.

  • other_buildings - Type:URBANopt::GeoJSON::FeatureCollection - List of all surrounding features to include (self will be ignored if present in list).

  • model - Type:OpenStudio::Model::Model - An instance of an OpenStudio Model.

  • origin_lat_lon - Type:Float - An instance of OpenStudio::PointLatLon indicating the latitude and longitude of the origin.

  • runner - Type:String - An instance of Openstudio::Measure::OSRunner for the measure run.

  • zoning - Type:Boolean - Value is True if utilizing detailed zoning, else False. Zoning is set to False by default.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/urbanopt/geojson/building.rb', line 182

def create_other_buildings(other_building_type, other_buildings, model, origin_lat_lon, runner, zoning = false)
  building_features = {}
  building_features[:features] = []
  if other_buildings[:features].nil?
    runner.registerWarning("No features found in #{other_buildings}")
    return []
  else
    # remove non-buildings from the other_buildings list of all project features
    # since this is for shading, keep District Systems as well
    other_buildings[:features].each do |f|
      if f[:properties][:type] == 'Building' || f[:properties][:type] == 'District System'
        building_features[:features] << f
      end
    end
  end

  other_spaces = URBANopt::GeoJSON::Helper.process_other_buildings(
    self, other_building_type, building_features, model, origin_lat_lon, runner, zoning
  )
  return other_spaces
end

#create_windows(spaces) ⇒ Object

This method loops through all the spaces of the building and for each Wall surface with Outdoors boundary condition, sets the window to wall ratio as per the specified value or as a default value of 0.3.

Returns an array of instances of OpenStudio::Model::Space with windows.

Parameters
  • spaces - Type:Array - Contains instances of OpenStudio::Model::Space .



213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/urbanopt/geojson/building.rb', line 213

def create_windows(spaces)
  window_to_wall_ratio = @feature_json[:properties][:window_to_wall_ratio]
  if window_to_wall_ratio.nil?
    window_to_wall_ratio = 0.3
  end
  spaces.each do |space|
    space.surfaces.each do |surface|
      if surface.surfaceType == 'Wall' && surface.outsideBoundaryCondition == 'Outdoors'
        surface.setWindowToWallRatio(window_to_wall_ratio)
      end
    end
  end
end

#feature_points(origin_lat_lon, runner, zoning) ⇒ Object

Return the features multi polygon in an array of the form coordinate pairs in double nested Array.

Parameters
  • origin_lat_lon - Type:Float - An instance of OpenStudio::PointLatLon indicating the latitude and longitude of the origin.

  • runner - Type:String - An instance of Openstudio::Measure::OSRunner for the measure run.

  • zoning - Type:Boolean - Should be true if you’d like to utilize aspects of function that are specific to zoning.



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/urbanopt/geojson/building.rb', line 125

def feature_points(origin_lat_lon, runner, zoning)
  feature_points = []
  multi_polygons = get_multi_polygons(@feature_json)
  multi_polygons.each do |multi_polygon|
    multi_polygon.each do |polygon|
      elevation = 0
      floor_print = URBANopt::GeoJSON::Helper.floor_print_from_polygon(polygon, elevation, origin_lat_lon, runner, zoning)
      floor_print.each do |point|
        feature_points << point
      end

      # Subsequent polygons are holes, and are not supported.
      break
    end
  end
  return feature_points
end

#feature_typeObject

Used to describe the Building feature type using the base method from the Feature class.



42
43
44
# File 'lib/urbanopt/geojson/building.rb', line 42

def feature_type
  'Building'
end

#other_points(other_building, other_height, origin_lat_lon, runner, zoning) ⇒ Object

Return the points of the other building object. This method is similar to feature_points, but accepts the other building and other height.

Parameters
  • other_building - Type:Array - Array of points.

  • other_height - Type:Double - Value of the other height from which to create the floor prints.

  • origin_lat_lon - Type:Float - An instance of OpenStudio::PointLatLon indicating the latitude and longitude of the origin.

  • runner - Type:String - An instance of Openstudio::Measure::OSRunner for the measure run.

  • zoning - Type:Boolean - Should be true if you’d like to utilize aspects of function that are specific to zoning.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/urbanopt/geojson/building.rb', line 153

def other_points(other_building, other_height, origin_lat_lon, runner, zoning)
  other_points = []
  multi_polygons = get_multi_polygons(other_building)
  multi_polygons.each do |multi_polygon|
    multi_polygon.each do |polygon|
      floor_print = URBANopt::GeoJSON::Helper.floor_print_from_polygon(polygon, other_height, origin_lat_lon, runner, zoning)
      floor_print.each do |point|
        other_points << point
      end

      # Subsequent polygons are holes, and are not supported.
      break
    end
  end
  return other_points
end

#schema_fileObject

Returns the building_properties schema.



48
49
50
# File 'lib/urbanopt/geojson/building.rb', line 48

def schema_file
  return File.join(File.dirname(__FILE__), 'schema', 'building_properties.json')
end

#to_hashObject

Convert to a Hash equivalent for JSON serialization. Excludes attributes with nil value.



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/urbanopt/geojson/building.rb', line 273

def to_hash
  result = {}
  result[:id] = @id if @id
  result[:name] = @name if @name
  result[:detailed_model_filename] = @detailed_model_filename if @detailed_model_filename
  result[:floor_area] = @floor_area if @floor_area
  result[:number_of_stories] = @number_of_stories if @number_of_stories
  result[:number_of_stories_above_ground] = @number_of_stories_above_ground if @number_of_stories_above_ground
  result[:footprint_area] = @footprint_area if @footprint_area
  result[:template] = @template if @template
  result[:building_type] = @building_type if @building_type
  result[:system_type] = @system_type if @system_type
  result[:weekday_start_time] = @weekday_start_time if @weekday_start_time
  result[:weekday_duration] = @weekday_duration if @weekday_duration
  result[:weekend_start_time] = @weekend_start_time if @weekend_start_time
  result[:weekend_duration] = @weekend_duration if @weekend_duration
  result[:mixed_type_1] = @mixed_type_1 if @mixed_type_1
  result[:mixed_type_1_percentage] = @mixed_type_1_percentage if @mixed_type_1_percentage
  result[:mixed_type_2] = @mixed_type_2 if @mixed_type_2
  result[:mixed_type_2_percentage] = @mixed_type_2_percentage if @mixed_type_2_percentage
  result[:mixed_type_3] = @mixed_type_3 if @mixed_type_3
  result[:mixed_type_3_percentage] = @mixed_type_3_percentage if @mixed_type_3_percentage
  result[:mixed_type_4] = @mixed_type_4 if @mixed_type_4
  result[:mixed_type_4_percentage] = @mixed_type_4_percentage if @mixed_type_4_percentage
  return result
end