urbanopt-geojson 0.1.0 → 0.2.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/CONTRIBUTING.md +58 -0
  6. data/Gemfile +3 -3
  7. data/Jenkinsfile +2 -2
  8. data/LICENSE.md +1 -1
  9. data/Rakefile +1 -1
  10. data/doc_templates/LICENSE.md +1 -1
  11. data/doc_templates/copyright_erb.txt +1 -1
  12. data/doc_templates/copyright_js.txt +1 -1
  13. data/doc_templates/copyright_ruby.txt +1 -1
  14. data/docs/package-lock.json +2291 -2205
  15. data/docs/package.json +8 -1
  16. data/lib/change_log.rb +147 -0
  17. data/lib/measures/urban_geometry_creation/LICENSE.md +1 -1
  18. data/lib/measures/urban_geometry_creation/measure.rb +1 -3
  19. data/lib/measures/urban_geometry_creation/tests/shadowed_tests.rb +1 -1
  20. data/lib/measures/urban_geometry_creation/tests/urban_geometry_creation_test.rb +3 -7
  21. data/lib/measures/urban_geometry_creation_zoning/LICENSE.md +1 -1
  22. data/lib/measures/urban_geometry_creation_zoning/measure.rb +5 -6
  23. data/lib/measures/urban_geometry_creation_zoning/tests/{urban_geometry_creation_test.rb → urban_geometry_creation_zoning_test.rb} +3 -7
  24. data/lib/urbanopt-geojson.rb +31 -0
  25. data/lib/urbanopt/geojson.rb +1 -1
  26. data/lib/urbanopt/geojson/building.rb +90 -18
  27. data/lib/urbanopt/geojson/district_system.rb +1 -1
  28. data/lib/urbanopt/geojson/extension.rb +1 -1
  29. data/lib/urbanopt/geojson/feature.rb +9 -7
  30. data/lib/urbanopt/geojson/files/electrical_database.json +28 -0
  31. data/lib/urbanopt/geojson/geo_file.rb +213 -31
  32. data/lib/urbanopt/geojson/helper.rb +10 -8
  33. data/lib/urbanopt/geojson/logging.rb +1 -1
  34. data/lib/urbanopt/geojson/mapper_classes.rb +1 -1
  35. data/lib/urbanopt/geojson/model.rb +1 -1
  36. data/lib/urbanopt/geojson/region.rb +1 -1
  37. data/lib/urbanopt/geojson/schema/building_properties.json +28 -5
  38. data/lib/urbanopt/geojson/schema/district_system_properties.json +29 -28
  39. data/lib/urbanopt/geojson/schema/electrical_connector_properties.json +150 -10
  40. data/lib/urbanopt/geojson/schema/electrical_junction_properties.json +3 -2
  41. data/lib/urbanopt/geojson/schema/thermal_connector_properties.json +2 -1
  42. data/lib/urbanopt/geojson/update_areas.rb +1 -1
  43. data/lib/urbanopt/geojson/validate_geojson.rb +1 -1
  44. data/lib/urbanopt/geojson/version.rb +2 -2
  45. data/lib/urbanopt/geojson/zoning.rb +1 -1
  46. data/urbanopt-geojson-gem.gemspec +4 -1
  47. metadata +14 -8
  48. data/.travis.yml +0 -35
data/docs/package.json CHANGED
@@ -17,6 +17,13 @@
17
17
  "webpack-dev-middleware": "^3.6.0"
18
18
  },
19
19
  "devDependencies": {
20
- "gh-pages": "^2.0.1"
20
+ "braces": ">=2.3.1",
21
+ "gh-pages": "^2.0.1",
22
+ "js-yaml": ">=3.13.1",
23
+ "lodash": ">=4.17.12",
24
+ "lodash.template": ">=4.5.0",
25
+ "mixin-deep": ">=1.3.2",
26
+ "serialize-javascript": ">=2.1.1",
27
+ "set-value": ">=2.0.1"
21
28
  }
22
29
  }
data/lib/change_log.rb ADDED
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'github_api'
4
+ require 'date'
5
+ require 'optparse'
6
+ require 'optparse/date'
7
+
8
+ # Instructions:
9
+ # Get a token from github's settings (https://github.com/settings/tokens)
10
+ #
11
+ # Example:
12
+ # ruby change_log.rb -t abcdefghijklmnopqrstuvwxyz -s 2017-09-06
13
+ #
14
+
15
+ options = {}
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: change_log.rb [options]\n" +
18
+ "Prints New, Open, Closed Issues, and number of accepted PRs"
19
+ opts.separator ""
20
+
21
+ # defaults, go back 90 days
22
+ options[:start_date] = Date.today - 90
23
+ options[:end_date] = Date.today
24
+
25
+ opts.on('-s', '--start-date [DATE]', Date, 'Start of data (e.g. 2017-09-06)') do |v|
26
+ options[:start_date] = v
27
+ end
28
+ opts.on('-e', '--end-date [DATE]', Date, 'End of data (e.g. 2017-09-13)') do |v|
29
+ options[:end_date] = v
30
+ end
31
+ opts.on('-t', '--token [String]', String, 'Github API Token') do |v|
32
+ options[:token] = v
33
+ end
34
+ end.parse!
35
+
36
+ # Convert dates to time objects
37
+ options[:start_date] = Time.parse(options[:start_date].to_s)
38
+ options[:end_date] = Time.parse(options[:end_date].to_s)
39
+ puts options
40
+
41
+ ### Repository options
42
+ repo_owner = 'URBANopt'
43
+ repo = 'urbanopt-geojson-gem'
44
+
45
+ github = Github.new
46
+ if options[:token]
47
+ puts 'Using github token'
48
+ github = Github.new oauth_token: options[:token]
49
+ end
50
+
51
+ total_open_issues = []
52
+ total_open_pull_requests = []
53
+ new_issues = []
54
+ closed_issues = []
55
+ accepted_pull_requests = []
56
+
57
+ def get_num(issue)
58
+ issue.html_url.split('/')[-1].to_i
59
+ end
60
+
61
+ def get_issue_num(issue)
62
+ "\##{get_num(issue)}"
63
+ end
64
+
65
+ def get_html_url(issue)
66
+ issue.html_url
67
+ end
68
+
69
+ def get_title(issue)
70
+ issue.title
71
+ end
72
+
73
+ def print_issue(issue)
74
+ is_feature = false
75
+ issue.labels.each { |label| is_feature = true if label.name == 'Feature Request' }
76
+
77
+ if is_feature
78
+ "- Improved [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
79
+ else
80
+ "- Fixed [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
81
+ end
82
+ end
83
+
84
+ # Process Open Issues
85
+ results = -1
86
+ page = 1
87
+ while results != 0
88
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
89
+ state: 'open', per_page: 100, page: page
90
+ results = resp.length
91
+ resp.env[:body].each do |issue, _index|
92
+ created = Time.parse(issue.created_at)
93
+ if !issue.key?(:pull_request)
94
+ total_open_issues << issue
95
+ if created >= options[:start_date] && created <= options[:end_date]
96
+ new_issues << issue
97
+ end
98
+ else
99
+ total_open_pull_requests << issue
100
+ end
101
+ end
102
+
103
+ page += 1
104
+ end
105
+
106
+ # Process Closed Issues
107
+ results = -1
108
+ page = 1
109
+ while results != 0
110
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
111
+ state: 'closed', per_page: 100, page: page
112
+ results = resp.length
113
+ resp.env[:body].each do |issue, _index|
114
+ created = Time.parse(issue.created_at)
115
+ closed = Time.parse(issue.closed_at)
116
+ if !issue.key?(:pull_request)
117
+ if created >= options[:start_date] && created <= options[:end_date]
118
+ new_issues << issue
119
+ end
120
+ if closed >= options[:start_date] && closed <= options[:end_date]
121
+ closed_issues << issue
122
+ end
123
+ elsif closed >= options[:start_date] && closed <= options[:end_date]
124
+ accepted_pull_requests << issue
125
+ end
126
+ end
127
+
128
+ page += 1
129
+ end
130
+
131
+ closed_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
132
+ new_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
133
+ accepted_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
134
+ total_open_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
135
+
136
+ puts "Total Open Issues: #{total_open_issues.length}"
137
+ puts "Total Open Pull Requests: #{total_open_pull_requests.length}"
138
+ puts "\nDate Range: #{options[:start_date].strftime('%m/%d/%y')} - #{options[:end_date].strftime('%m/%d/%y')}:"
139
+ puts "\nNew Issues: #{new_issues.length} (" + new_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
140
+
141
+ puts "\nClosed Issues: #{closed_issues.length}"
142
+ closed_issues.each { |issue| puts print_issue(issue) }
143
+
144
+ puts "\nAccepted Pull Requests: #{accepted_pull_requests.length}"
145
+ accepted_pull_requests.each { |issue| puts print_issue(issue) }
146
+
147
+ puts "\nAll Open Issues: #{total_open_issues.length} (" + total_open_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
@@ -1,4 +1,4 @@
1
- URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
1
+ URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
2
2
  contributors. All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -68,8 +68,6 @@ class UrbanGeometryCreation < OpenStudio::Measure::ModelMeasure
68
68
  chs = OpenStudio::StringVector.new
69
69
  chs << 'None'
70
70
  chs << 'ShadingOnly'
71
- chs << 'All'
72
- # Note: Only ShadingOnly is implemented at the moment
73
71
  surrounding_buildings = OpenStudio::Measure::OSArgument.makeChoiceArgument('surrounding_buildings', chs, true)
74
72
  surrounding_buildings.setDisplayName('Surrounding Buildings')
75
73
  surrounding_buildings.setDescription('Select which surrounding buildings to include.')
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -50,8 +50,6 @@ class UrbanGeometryCreationTest < MiniTest::Unit::TestCase
50
50
  feature_id = '59a9ce2b42f7d007c059d2ee' # Energy Systems Integration Facility
51
51
 
52
52
  surrounding_buildings = 'None'
53
- # surrounding_buildings = "ShadingOnly"
54
- # surrounding_buildings = "All"
55
53
 
56
54
  # get arguments
57
55
  arguments = measure.arguments(model)
@@ -72,7 +70,7 @@ class UrbanGeometryCreationTest < MiniTest::Unit::TestCase
72
70
  end
73
71
  argument_map[arg.name] = temp_arg_var
74
72
  end
75
-
73
+
76
74
  # run the measure
77
75
  measure.run(model, runner, argument_map)
78
76
  result = runner.result
@@ -100,11 +98,9 @@ class UrbanGeometryCreationTest < MiniTest::Unit::TestCase
100
98
 
101
99
  geojson_file = File.absolute_path(File.join(File.dirname(__FILE__), 'nrel_stm_footprints.geojson'))
102
100
 
103
- feature_id = '59a9ce2b42f7d007c059d2f0' # Education Center
101
+ feature_id = '59a9ce2b42f7d007c059d2f0' # Thermal Test Facility
104
102
 
105
- # surrounding_buildings = "None"
106
103
  surrounding_buildings = 'ShadingOnly'
107
- # surrounding_buildings = "All"
108
104
 
109
105
  # get arguments
110
106
  arguments = measure.arguments(model)
@@ -1,4 +1,4 @@
1
- URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
1
+ URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
2
2
  contributors. All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -72,8 +72,6 @@ class UrbanGeometryCreationZoning < OpenStudio::Measure::ModelMeasure
72
72
  chs = OpenStudio::StringVector.new
73
73
  chs << 'None'
74
74
  chs << 'ShadingOnly'
75
- chs << 'All'
76
- # Note: Only ShadingOnly is implemented at the moment
77
75
  surrounding_buildings = OpenStudio::Measure::OSArgument.makeChoiceArgument('surrounding_buildings', chs, true)
78
76
  surrounding_buildings.setDisplayName('Surrounding Buildings')
79
77
  surrounding_buildings.setDescription('Select which surrounding buildings to include.')
@@ -113,8 +111,8 @@ class UrbanGeometryCreationZoning < OpenStudio::Measure::ModelMeasure
113
111
  @runner = runner
114
112
  @origin_lat_lon = nil
115
113
 
116
- all_features = URBANopt::GeoJSON::GeoFile.from_file(geojson_file)
117
- feature = URBANopt::GeoJSON::GeoFile.from_file(geojson_file).get_feature_by_id(feature_id)
114
+ all_features = URBANopt::GeoJSON::GeoFile.from_file(geojson_file)
115
+ feature = URBANopt::GeoJSON::GeoFile.from_file(geojson_file).get_feature_by_id(feature_id)
118
116
 
119
117
  # EXPOSE NAME
120
118
  name = feature.feature_json[:properties][:name]
@@ -136,7 +134,7 @@ class UrbanGeometryCreationZoning < OpenStudio::Measure::ModelMeasure
136
134
  end
137
135
 
138
136
  if feature.type == 'Building'
139
- # make requested building
137
+ # make requested building, zoning is set to true
140
138
  spaces = feature.create_building(:spaces_per_floor, model, @origin_lat_lon, @runner, true)
141
139
  if spaces.nil? || spaces.empty?
142
140
  @runner.registerError("Failed to create building spaces for feature #{feature_id}")
@@ -155,6 +153,7 @@ class UrbanGeometryCreationZoning < OpenStudio::Measure::ModelMeasure
155
153
  convert_to_shades = feature.create_other_buildings(surrounding_buildings, all_features.json, model, @origin_lat_lon, @runner)
156
154
  end
157
155
 
156
+
158
157
  # intersect surfaces in this building with others
159
158
  @runner.registerInfo('Intersecting surfaces')
160
159
  spaces.each do |space|
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -47,11 +47,9 @@ class UrbanGeometryCreationZoningTest < MiniTest::Unit::TestCase
47
47
 
48
48
  geojson_file = File.absolute_path(File.join(File.dirname(__FILE__), 'nrel_stm_footprints.geojson'))
49
49
 
50
- feature_id = '59a9ce2b42f7d007c059d2ee' # Energy Systems Integration Facility
50
+ feature_id = '59a9ce2b42f7d007c059d2f0'
51
51
 
52
52
  surrounding_buildings = 'None'
53
- # surrounding_buildings = "ShadingOnly"
54
- # surrounding_buildings = "All"
55
53
 
56
54
  # get arguments
57
55
  arguments = measure.arguments(model)
@@ -100,11 +98,9 @@ class UrbanGeometryCreationZoningTest < MiniTest::Unit::TestCase
100
98
 
101
99
  geojson_file = File.absolute_path(File.join(File.dirname(__FILE__), 'nrel_stm_footprints.geojson'))
102
100
 
103
- feature_id = '59a9ce2b42f7d007c059d2f0' # Education Center
101
+ feature_id = '59a9ce2b42f7d007c059d2ee'
104
102
 
105
- # surrounding_buildings = "None"
106
103
  surrounding_buildings = 'ShadingOnly'
107
- # surrounding_buildings = "All"
108
104
 
109
105
  # get arguments
110
106
  arguments = measure.arguments(model)
@@ -0,0 +1,31 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
+ # contributors. All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification,
6
+ # are permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list
9
+ # of conditions and the following disclaimer.
10
+ #
11
+ # Redistributions in binary form must reproduce the above copyright notice, this
12
+ # list of conditions and the following disclaimer in the documentation and/or other
13
+ # materials provided with the distribution.
14
+ #
15
+ # Neither the name of the copyright holder nor the names of its contributors may be
16
+ # used to endorse or promote products derived from this software without specific
17
+ # prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ require_relative 'urbanopt/geojson'
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -33,10 +33,34 @@ require 'urbanopt/geojson/feature'
33
33
  module URBANopt
34
34
  module GeoJSON
35
35
  class Building < URBANopt::GeoJSON::Feature
36
+
36
37
  ##
37
38
  # Used to initialize the feature. This method is inherited from the Feature class.
38
- def initialize(feature)
39
+ def initialize(feature = {})
39
40
  super(feature)
41
+
42
+ @id = feature[:properties][:id]
43
+ @name = feature[:properties][:name]
44
+ @detailed_model_filename = feature[:properties][:detailed_model_filename]
45
+ @floor_area = feature[:properties][:floor_area]
46
+ @number_of_stories = feature[:properties][:number_of_stories]
47
+ @number_of_stories_above_ground = feature[:properties][:number_of_stories_above_ground]
48
+ @footprint_area = feature[:properties][:footprint_area]
49
+ @template = feature[:properties][:template]
50
+ @building_type = feature[:properties][:building_type]
51
+ @system_type = feature[:properties][:system_type]
52
+ @weekday_start_time = feature[:properties][:weekday_start_time]
53
+ @weekday_duration = feature[:properties][:weekday_duration]
54
+ @weekend_start_time = feature[:properties][:weekend_start_time]
55
+ @weekend_duration = feature[:properties][:weekend_duration]
56
+ @mixed_type_1 = feature[:properties][:mixed_type_1]
57
+ @mixed_type_1_percentage = feature[:properties][:mixed_type_1_percentage]
58
+ @mixed_type_2 = feature[:properties][:mixed_type_2]
59
+ @mixed_type_2_percentage = feature[:properties][:mixed_type_2_percentage]
60
+ @mixed_type_3 = feature[:properties][:mixed_type_3]
61
+ @mixed_type_3_percentage = feature[:properties][:mixed_type_3_percentage]
62
+ @mixed_type_4 = feature[:properties][:mixed_type_4]
63
+ @mixed_type_4_percentage = feature[:properties][:mixed_type_4_percentage]
40
64
  end
41
65
 
42
66
  ##
@@ -174,20 +198,30 @@ module URBANopt
174
198
  # Returns an array of instances of +OpenStudio::Model::Space+.
175
199
  #
176
200
  # [Parameters]
177
- # * +other_building_type+ - _Type:String_ - Describes the surrounding buildings. Currently 'ShadingOnly' is the only option that is processed.
178
- # * +other_buildings+ - _Type:URBANopt::GeoJSON::FeatureCollection_ - List of surrounding buildings to include (self will be ignored if present in list).
201
+ # * +other_building_type+ - _Type:String_ - Describes the surrounding buildings. Supports 'None', 'ShadingOnly' options.
202
+ # * +other_buildings+ - _Type:URBANopt::GeoJSON::FeatureCollection_ - List of all surrounding features to include (self will be ignored if present in list).
179
203
  # * +model+ - _Type:OpenStudio::Model::Model_ - An instance of an OpenStudio Model.
180
204
  # * +origin_lat_lon+ - _Type:Float_ - An instance of +OpenStudio::PointLatLon+ indicating the latitude and longitude of the origin.
181
205
  # * +runner+ - _Type:String_ - An instance of +Openstudio::Measure::OSRunner+ for the measure run.
182
206
  # * +zoning+ - _Type:Boolean_ - Value is +True+ if utilizing detailed zoning, else +False+. Zoning is set to False by default.
183
207
  def create_other_buildings(other_building_type, other_buildings, model, origin_lat_lon, runner, zoning = false)
208
+ building_features = {}
209
+ building_features[:features] = []
184
210
  if other_buildings[:features].nil?
185
211
  runner.registerWarning("No features found in #{other_buildings}")
186
212
  return []
213
+ else
214
+ # remove non-buildings from the other_buildings list of all project features
215
+ # since this is for shading, keep District Systems as well
216
+ other_buildings[:features].each do |f|
217
+ if f[:properties][:type] == 'Building' || f[:properties][:type] == 'District System'
218
+ building_features[:features] << f
219
+ end
220
+ end
187
221
  end
188
222
 
189
223
  other_spaces = URBANopt::GeoJSON::Helper.process_other_buildings(
190
- self, other_building_type, other_buildings, model, origin_lat_lon, runner, zoning
224
+ self, other_building_type, building_features, model, origin_lat_lon, runner, zoning
191
225
  )
192
226
  return other_spaces
193
227
  end
@@ -215,6 +249,39 @@ module URBANopt
215
249
  end
216
250
  end
217
251
 
252
+ ##
253
+ # Convert to a Hash equivalent for JSON serialization
254
+ ##
255
+ # - Exclude attributes with nil values.
256
+ ##
257
+ def to_hash
258
+ result = {}
259
+ result[:id] = @id if @id
260
+ result[:name] = @name if @name
261
+ result[:detailed_model_filename] = @detailed_model_filename if @detailed_model_filename
262
+ result[:floor_area] = @floor_area if @floor_area
263
+ result[:number_of_stories] = @number_of_stories if @number_of_stories
264
+ result[:number_of_stories_above_ground] = @number_of_stories_above_ground if @number_of_stories_above_ground
265
+ result[:footprint_area] = @footprint_area if @footprint_area
266
+ result[:template] = @template if @template
267
+ result[:building_type] = @building_type if @building_type
268
+ result[:system_type] = @system_type if @system_type
269
+ result[:weekday_start_time] = @weekday_start_time if @weekday_start_time
270
+ result[:weekday_duration] = @weekday_duration if @weekday_duration
271
+ result[:weekend_start_time] = @weekend_start_time if @weekend_start_time
272
+ result[:weekend_duration] = @weekend_duration if @weekend_duration
273
+ result[:mixed_type_1] = @mixed_type_1 if @mixed_type_1
274
+ result[:mixed_type_1_percentage] = @mixed_type_1_percentage if @mixed_type_1_percentage
275
+ result[:mixed_type_2] = @mixed_type_2 if @mixed_type_2
276
+ result[:mixed_type_2_percentage] = @mixed_type_2_percentage if @mixed_type_2_percentage
277
+ result[:mixed_type_3] = @mixed_type_3 if @mixed_type_3
278
+ result[:mixed_type_3_percentage] = @mixed_type_3_percentage if @mixed_type_3_percentage
279
+ result[:mixed_type_4] = @mixed_type_4 if @mixed_type_4
280
+ result[:mixed_type_4_percentage] = @mixed_type_4_percentage if @mixed_type_4_percentage
281
+ return result
282
+ end
283
+
284
+
218
285
  private
219
286
 
220
287
  ##
@@ -298,7 +365,7 @@ module URBANopt
298
365
  floor_print = URBANopt::GeoJSON::Helper.floor_print_from_polygon(polygon, elevation, origin_lat_lon, runner, zoning)
299
366
  if floor_print
300
367
  if zoning
301
- this_floor_prints = URBANopt::GeoJSON::Zoning.divide_floor_print(floor_print, 4.0, runner)
368
+ this_floor_prints = URBANopt::GeoJSON::Zoning.divide_floor_print(floor_print, 4.0, runner)
302
369
  floor_prints.concat(this_floor_prints)
303
370
  else
304
371
  floor_prints << floor_print
@@ -308,9 +375,9 @@ module URBANopt
308
375
  end
309
376
  # Subsequent polygons are holes, and are not supported.
310
377
  break
311
- end
312
- end
313
- result = []
378
+ end
379
+ end
380
+ spaces = []
314
381
  floor_prints.each do |floor_print|
315
382
  space = OpenStudio::Model::Space.fromFloorPrint(floor_print, floor_to_floor_height, model)
316
383
  if space.empty?
@@ -325,17 +392,22 @@ module URBANopt
325
392
  surface.setOutsideBoundaryCondition('Ground')
326
393
  end
327
394
  end
328
- end
329
- building_story = OpenStudio::Model::BuildingStory.new(model)
330
- building_story.setName("Building Story #{story_number}")
395
+ end
396
+ spaces << space
397
+ end
398
+
399
+ building_story = OpenStudio::Model::BuildingStory.new(model)
400
+ building_story.setName("Building Story #{story_number}")
401
+ spaces.each do |space|
331
402
  space.setBuildingStory(building_story)
332
403
  thermal_zone = OpenStudio::Model::ThermalZone.new(model)
333
404
  thermal_zone.setName("Building Story #{story_number} ThermalZone")
334
405
  space.setThermalZone(thermal_zone)
335
- result << space
336
- end
337
- return result
406
+ end
407
+
408
+ return spaces
338
409
  end
339
- end
340
- end
341
- end
410
+
411
+ end
412
+ end
413
+ end