urbanopt-geojson 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/.rakeTasks +7 -0
  4. data/.rdoc_options +43 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +10 -0
  7. data/.travis.yml +35 -0
  8. data/CHANGELOG.md +5 -0
  9. data/Gemfile +27 -0
  10. data/Jenkinsfile +10 -0
  11. data/LICENSE.md +27 -0
  12. data/RDOC_MAIN.md +48 -0
  13. data/README.md +40 -0
  14. data/Rakefile +45 -0
  15. data/deploy_docs.sh +4 -0
  16. data/doc_templates/LICENSE.md +27 -0
  17. data/doc_templates/README.md.erb +42 -0
  18. data/doc_templates/copyright_erb.txt +31 -0
  19. data/doc_templates/copyright_js.txt +4 -0
  20. data/doc_templates/copyright_ruby.txt +29 -0
  21. data/docs/.gitignore +3 -0
  22. data/docs/.vuepress/components/BuildingProperties.vue +12 -0
  23. data/docs/.vuepress/components/DistrictSystemProperties.vue +12 -0
  24. data/docs/.vuepress/components/ElectricalConnectorProperties.vue +12 -0
  25. data/docs/.vuepress/components/ElectricalJunctionProperties.vue +12 -0
  26. data/docs/.vuepress/components/InnerJsonSchema.vue +80 -0
  27. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  28. data/docs/.vuepress/components/RegionProperties.vue +12 -0
  29. data/docs/.vuepress/components/SiteProperties.vue +12 -0
  30. data/docs/.vuepress/components/StaticLink.vue +8 -0
  31. data/docs/.vuepress/components/ThermalConnectorProperties.vue +12 -0
  32. data/docs/.vuepress/components/ThermalJunctionProperties.vue +12 -0
  33. data/docs/.vuepress/config.js +22 -0
  34. data/docs/.vuepress/highlight.js +8 -0
  35. data/docs/.vuepress/public/custom_rdoc_styles.css +64 -0
  36. data/docs/.vuepress/utils.js +17 -0
  37. data/docs/README.md +30 -0
  38. data/docs/doc/created.rid +0 -0
  39. data/docs/package-lock.json +11771 -0
  40. data/docs/package.json +22 -0
  41. data/docs/schemas/building-properties.md +3 -0
  42. data/docs/schemas/district-system-properties.md +3 -0
  43. data/docs/schemas/electrical-connector-properties.md +3 -0
  44. data/docs/schemas/electrical-junction-properties.md +3 -0
  45. data/docs/schemas/region-properties.md +3 -0
  46. data/docs/schemas/site-properties.md +3 -0
  47. data/docs/schemas/thermal-connector-properties.md +3 -0
  48. data/docs/schemas/thermal-junction-properties.md +3 -0
  49. data/lib/measures/.rubocop.yml +5 -0
  50. data/lib/measures/urban_geometry_creation/LICENSE.md +27 -0
  51. data/lib/measures/urban_geometry_creation/README.md +48 -0
  52. data/lib/measures/urban_geometry_creation/README.md.erb +42 -0
  53. data/lib/measures/urban_geometry_creation/measure.rb +199 -0
  54. data/lib/measures/urban_geometry_creation/measure.xml +139 -0
  55. data/lib/measures/urban_geometry_creation/tests/nrel_stm_footprints.geojson +3238 -0
  56. data/lib/measures/urban_geometry_creation/tests/shadowed_tests.rb +80 -0
  57. data/lib/measures/urban_geometry_creation/tests/urban_geometry_creation_test.rb +143 -0
  58. data/lib/measures/urban_geometry_creation_zoning/LICENSE.md +27 -0
  59. data/lib/measures/urban_geometry_creation_zoning/README.md +48 -0
  60. data/lib/measures/urban_geometry_creation_zoning/README.md.erb +42 -0
  61. data/lib/measures/urban_geometry_creation_zoning/measure.rb +203 -0
  62. data/lib/measures/urban_geometry_creation_zoning/measure.xml +133 -0
  63. data/lib/measures/urban_geometry_creation_zoning/tests/nrel_stm_footprints.geojson +3238 -0
  64. data/lib/measures/urban_geometry_creation_zoning/tests/urban_geometry_creation_test.rb +143 -0
  65. data/lib/urbanopt/geojson.rb +41 -0
  66. data/lib/urbanopt/geojson/building.rb +341 -0
  67. data/lib/urbanopt/geojson/district_system.rb +53 -0
  68. data/lib/urbanopt/geojson/extension.rb +63 -0
  69. data/lib/urbanopt/geojson/feature.rb +206 -0
  70. data/lib/urbanopt/geojson/geo_file.rb +154 -0
  71. data/lib/urbanopt/geojson/helper.rb +340 -0
  72. data/lib/urbanopt/geojson/logging.rb +46 -0
  73. data/lib/urbanopt/geojson/mapper_classes.rb +85 -0
  74. data/lib/urbanopt/geojson/model.rb +133 -0
  75. data/lib/urbanopt/geojson/region.rb +55 -0
  76. data/lib/urbanopt/geojson/schema/building_properties.json +358 -0
  77. data/lib/urbanopt/geojson/schema/district_system_properties.json +137 -0
  78. data/lib/urbanopt/geojson/schema/electrical_connector_properties.json +77 -0
  79. data/lib/urbanopt/geojson/schema/electrical_junction_properties.json +64 -0
  80. data/lib/urbanopt/geojson/schema/geojson_schema.json +323 -0
  81. data/lib/urbanopt/geojson/schema/region_properties.json +93 -0
  82. data/lib/urbanopt/geojson/schema/site_properties.json +87 -0
  83. data/lib/urbanopt/geojson/schema/thermal_connector_properties.json +107 -0
  84. data/lib/urbanopt/geojson/schema/thermal_junction_properties.json +83 -0
  85. data/lib/urbanopt/geojson/update_areas.rb +102 -0
  86. data/lib/urbanopt/geojson/validate_geojson.rb +147 -0
  87. data/lib/urbanopt/geojson/version.rb +35 -0
  88. data/lib/urbanopt/geojson/workflows/building.osw +187 -0
  89. data/lib/urbanopt/geojson/workflows/building.osw.out +2806 -0
  90. data/lib/urbanopt/geojson/workflows/district_system.osw +84 -0
  91. data/lib/urbanopt/geojson/workflows/district_system.osw.out +646 -0
  92. data/lib/urbanopt/geojson/zoning.rb +134 -0
  93. data/package-lock.json +3 -0
  94. data/urbanopt-geojson-gem.gemspec +39 -0
  95. metadata +238 -0
@@ -0,0 +1,80 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019, 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 'openstudio'
32
+ require 'openstudio/ruleset/ShowRunnerOutput'
33
+ require 'urbanopt/geojson'
34
+ require 'minitest/autorun'
35
+ require_relative '../measure.rb'
36
+ require 'fileutils'
37
+
38
+ class UrbanGeometryCreationTest < MiniTest::Unit::TestCase
39
+ def test_shadowed_case
40
+ denver_zoo = OpenStudio::PointLatLon.new(39.749242, -104.951024, 0)
41
+ blocky = [
42
+ OpenStudio::Point3d.new(0, 0, 2),
43
+ OpenStudio::Point3d.new(2, 0, 2),
44
+ OpenStudio::Point3d.new(2, 2, 2),
45
+ OpenStudio::Point3d.new(0, 2, 2),
46
+ OpenStudio::Point3d.new(0, 0, 2)
47
+ ]
48
+ rector = [
49
+ OpenStudio::Point3d.new(2.7, 4.4, 1),
50
+ OpenStudio::Point3d.new(4.7, 4.4, 1),
51
+ OpenStudio::Point3d.new(4.7, 8.4, 1),
52
+ OpenStudio::Point3d.new(2.7, 8.4, 1),
53
+ OpenStudio::Point3d.new(2.7, 4.4, 1)
54
+ ]
55
+
56
+ blocky_shadows_rector = URBANopt::GeoJSON::Helper.is_shadowed(rector, blocky, denver_zoo)
57
+ assert blocky_shadows_rector, 'Expected blocky to shadow the rector'
58
+ end
59
+
60
+ def test_flat_blocky_does_not_shadow
61
+ denver_zoo = OpenStudio::PointLatLon.new(39.749242, -104.951024, 0)
62
+ blocky = [
63
+ OpenStudio::Point3d.new(0, 0, 0),
64
+ OpenStudio::Point3d.new(2, 0, 0),
65
+ OpenStudio::Point3d.new(2, 2, 0),
66
+ OpenStudio::Point3d.new(0, 2, 0),
67
+ OpenStudio::Point3d.new(0, 0, 0)
68
+ ]
69
+ rector = [
70
+ OpenStudio::Point3d.new(2.7, 4.4, 1),
71
+ OpenStudio::Point3d.new(4.7, 4.4, 1),
72
+ OpenStudio::Point3d.new(4.7, 8.4, 1),
73
+ OpenStudio::Point3d.new(2.7, 8.4, 1),
74
+ OpenStudio::Point3d.new(2.7, 4.4, 1)
75
+ ]
76
+
77
+ blocky_shadows_rector = URBANopt::GeoJSON::Helper.is_shadowed(rector, blocky, denver_zoo)
78
+ assert !blocky_shadows_rector, 'Expected blocky at 0m tall not to shadow the rector'
79
+ end
80
+ end
@@ -0,0 +1,143 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019, 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 'openstudio'
32
+ require 'openstudio/ruleset/ShowRunnerOutput'
33
+ require 'urbanopt/geojson'
34
+ require 'minitest/autorun'
35
+ require_relative '../measure.rb'
36
+ require 'fileutils'
37
+
38
+ class UrbanGeometryCreationTest < MiniTest::Unit::TestCase
39
+ def test_one_building
40
+ # create an instance of the measure
41
+ measure = UrbanGeometryCreation.new
42
+ # create an empty model
43
+ model = OpenStudio::Model::Model.new
44
+
45
+ # create an instance of a runner
46
+ runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
47
+
48
+ geojson_file = File.absolute_path(File.join(File.dirname(__FILE__), 'nrel_stm_footprints.geojson'))
49
+
50
+ feature_id = '59a9ce2b42f7d007c059d2ee' # Energy Systems Integration Facility
51
+
52
+ surrounding_buildings = 'None'
53
+ # surrounding_buildings = "ShadingOnly"
54
+ # surrounding_buildings = "All"
55
+
56
+ # get arguments
57
+ arguments = measure.arguments(model)
58
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
59
+
60
+ # create hash of argument values.
61
+ # If the argument has a default that you want to use, you don't need it in the hash
62
+ args_hash = {}
63
+ args_hash['geojson_file'] = geojson_file
64
+ args_hash['feature_id'] = feature_id
65
+ args_hash['surrounding_buildings'] = surrounding_buildings
66
+
67
+ # populate argument with specified hash value if specified
68
+ arguments.each do |arg|
69
+ temp_arg_var = arg.clone
70
+ if args_hash[arg.name]
71
+ assert(temp_arg_var.setValue(args_hash[arg.name]))
72
+ end
73
+ argument_map[arg.name] = temp_arg_var
74
+ end
75
+
76
+ # run the measure
77
+ measure.run(model, runner, argument_map)
78
+ result = runner.result
79
+
80
+ # save the model to test output directory
81
+ output_file_path = OpenStudio::Path.new(File.dirname(__FILE__) + "/output/#{feature_id}.osm")
82
+ model.save(output_file_path, true)
83
+
84
+ # show the output
85
+ show_output(result)
86
+
87
+ # assert that it ran correctly
88
+ assert_equal('Success', result.value.valueName)
89
+ end
90
+
91
+ def test_one_building_w_surrounding_buildings
92
+ # create an instance of the measure
93
+ measure = UrbanGeometryCreation.new
94
+
95
+ # create an empty model
96
+ model = OpenStudio::Model::Model.new
97
+
98
+ # create an instance of a runner
99
+ runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
100
+
101
+ geojson_file = File.absolute_path(File.join(File.dirname(__FILE__), 'nrel_stm_footprints.geojson'))
102
+
103
+ feature_id = '59a9ce2b42f7d007c059d2f0' # Education Center
104
+
105
+ # surrounding_buildings = "None"
106
+ surrounding_buildings = 'ShadingOnly'
107
+ # surrounding_buildings = "All"
108
+
109
+ # get arguments
110
+ arguments = measure.arguments(model)
111
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
112
+
113
+ # create hash of argument values.
114
+ # If the argument has a default that you want to use, you don't need it in the hash
115
+ args_hash = {}
116
+ args_hash['geojson_file'] = geojson_file
117
+ args_hash['feature_id'] = feature_id
118
+ args_hash['surrounding_buildings'] = surrounding_buildings
119
+
120
+ # populate argument with specified hash value if specified
121
+ arguments.each do |arg|
122
+ temp_arg_var = arg.clone
123
+ if args_hash[arg.name]
124
+ assert(temp_arg_var.setValue(args_hash[arg.name]))
125
+ end
126
+ argument_map[arg.name] = temp_arg_var
127
+ end
128
+
129
+ # run the measure
130
+ measure.run(model, runner, argument_map)
131
+ result = runner.result
132
+
133
+ # save the model to test output directory
134
+ output_file_path = OpenStudio::Path.new(File.dirname(__FILE__) + "/output/#{feature_id}.osm")
135
+ model.save(output_file_path, true)
136
+
137
+ # show the output
138
+ show_output(result)
139
+
140
+ # assert that it ran correctly
141
+ assert_equal('Success', result.value.valueName)
142
+ end
143
+ end
@@ -0,0 +1,27 @@
1
+ URBANopt, Copyright (c) 2019, Alliance for Sustainable Energy, LLC, and other
2
+ contributors. All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ Redistributions of source code must retain the above copyright notice, this list
8
+ of conditions and the following disclaimer.
9
+
10
+ Redistributions in binary form must reproduce the above copyright notice, this
11
+ list of conditions and the following disclaimer in the documentation and/or other
12
+ materials provided with the distribution.
13
+
14
+ Neither the name of the copyright holder nor the names of its contributors may be
15
+ used to endorse or promote products derived from this software without specific
16
+ prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27
+ OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,48 @@
1
+
2
+
3
+ ###### (Automatically generated documentation)
4
+
5
+ # UrbanGeometryCreationZoning
6
+
7
+ ## Description
8
+ This measure reads an URBANopt GeoJSON and creates geometry for a particular building. Surrounding buildings are included as shading structures.
9
+
10
+ ## Modeler Description
11
+
12
+
13
+ ## Measure Type
14
+ ModelMeasure
15
+
16
+ ## Taxonomy
17
+
18
+
19
+ ## Arguments
20
+
21
+
22
+ ### GeoJSON File
23
+ GeoJSON File.
24
+ **Name:** geojson_file,
25
+ **Type:** String,
26
+ **Units:** ,
27
+ **Required:** true,
28
+ **Model Dependent:** false
29
+
30
+ ### Feature ID
31
+ Feature ID.
32
+ **Name:** feature_id,
33
+ **Type:** String,
34
+ **Units:** ,
35
+ **Required:** true,
36
+ **Model Dependent:** false
37
+
38
+ ### Surrounding Buildings
39
+ Select which surrounding buildings to include.
40
+ **Name:** surrounding_buildings,
41
+ **Type:** Choice,
42
+ **Units:** ,
43
+ **Required:** true,
44
+ **Model Dependent:** false
45
+
46
+
47
+
48
+
@@ -0,0 +1,42 @@
1
+ <%#= README.md.erb is used to auto-generate README.md. %>
2
+ <%#= To manually maintain README.md throw away README.md.erb and manually edit README.md %>
3
+ ###### (Automatically generated documentation)
4
+
5
+ # <%= name %>
6
+
7
+ ## Description
8
+ <%= description %>
9
+
10
+ ## Modeler Description
11
+ <%= modelerDescription %>
12
+
13
+ ## Measure Type
14
+ <%= measureType %>
15
+
16
+ ## Taxonomy
17
+ <%= taxonomy %>
18
+
19
+ ## Arguments
20
+
21
+ <% arguments.each do |argument| %>
22
+ ### <%= argument[:display_name] %>
23
+ <%= argument[:description] %>
24
+ **Name:** <%= argument[:name] %>,
25
+ **Type:** <%= argument[:type] %>,
26
+ **Units:** <%= argument[:units] %>,
27
+ **Required:** <%= argument[:required] %>,
28
+ **Model Dependent:** <%= argument[:model_dependent] %>
29
+ <% end %>
30
+
31
+ <% if arguments.size == 0 %>
32
+ <%= "This measure does not have any user arguments" %>
33
+ <% end %>
34
+
35
+ <% if outputs.size > 0 %>
36
+ ## Outputs
37
+ <% output_names = [] %>
38
+ <% outputs.each do |output| %>
39
+ <% output_names << output[:display_name] %>
40
+ <% end %>
41
+ <%= output_names.join(", ") %>
42
+ <% end %>
@@ -0,0 +1,203 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019, 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
+ # see the URL below for information on how to write OpenStudio measures
32
+ # http://nrel.github.io/OpenStudio-user-documentation/measures/measure_writing_guide/
33
+
34
+ require 'json'
35
+ require 'net/http'
36
+ require 'uri'
37
+ require 'openssl'
38
+ require 'urbanopt/geojson'
39
+
40
+ # start the measure
41
+ class UrbanGeometryCreationZoning < OpenStudio::Measure::ModelMeasure
42
+ attr_accessor :origin_lat_lon
43
+
44
+ # human readable name
45
+ def name
46
+ return 'UrbanGeometryCreationZoning'
47
+ end
48
+
49
+ # human readable description
50
+ def description
51
+ return 'This measure reads an URBANopt GeoJSON and creates geometry with zoning for a particular building. Surrounding buildings are included as shading structures.'
52
+ end
53
+
54
+ # human readable description of modeling approach
55
+ def modeler_description
56
+ return ''
57
+ end
58
+
59
+ def arguments(model)
60
+ args = OpenStudio::Measure::OSArgumentVector.new
61
+ # geojson file
62
+ geojson_file = OpenStudio::Measure::OSArgument.makeStringArgument('geojson_file', true)
63
+ geojson_file.setDisplayName('GeoJSON File')
64
+ geojson_file.setDescription('GeoJSON File.')
65
+ args << geojson_file
66
+ # feature id of the building to create
67
+ feature_id = OpenStudio::Measure::OSArgument.makeStringArgument('feature_id', true)
68
+ feature_id.setDisplayName('Feature ID')
69
+ feature_id.setDescription('Feature ID.')
70
+ args << feature_id
71
+ # which surrounding buildings to include
72
+ chs = OpenStudio::StringVector.new
73
+ chs << 'None'
74
+ chs << 'ShadingOnly'
75
+ chs << 'All'
76
+ # Note: Only ShadingOnly is implemented at the moment
77
+ surrounding_buildings = OpenStudio::Measure::OSArgument.makeChoiceArgument('surrounding_buildings', chs, true)
78
+ surrounding_buildings.setDisplayName('Surrounding Buildings')
79
+ surrounding_buildings.setDescription('Select which surrounding buildings to include.')
80
+ surrounding_buildings.setDefaultValue('ShadingOnly')
81
+ args << surrounding_buildings
82
+ return args
83
+ end
84
+
85
+ # define what happens when the measure is run
86
+ def run(model, runner, user_arguments)
87
+ super(model, runner, user_arguments)
88
+ # use the built-in error checking
89
+ if !runner.validateUserArguments(arguments(model), user_arguments)
90
+ return false
91
+ end
92
+
93
+ # assign the user inputs to variables
94
+ geojson_file = runner.getStringArgumentValue('geojson_file', user_arguments)
95
+ feature_id = runner.getStringArgumentValue('feature_id', user_arguments)
96
+ surrounding_buildings = runner.getStringArgumentValue('surrounding_buildings', user_arguments)
97
+
98
+ default_construction_set = URBANopt::GeoJSON::Model.create_construction_set(model, runner)
99
+
100
+ stories = []
101
+ model.getBuildingStorys.each { |story| stories << story }
102
+ stories.sort! { |x, y| x.nominalZCoordinate.to_s.to_f <=> y.nominalZCoordinate.to_s.to_f }
103
+
104
+ space_types = URBANopt::GeoJSON::Helper.create_space_types(stories, model, runner)
105
+
106
+ # delete the previous building
107
+ model.getBuilding.remove
108
+
109
+ # create new building and transfer default construction set
110
+ model.getBuilding.setDefaultConstructionSet(default_construction_set)
111
+
112
+ # instance variables
113
+ @runner = runner
114
+ @origin_lat_lon = nil
115
+
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)
118
+
119
+ # EXPOSE NAME
120
+ name = feature.feature_json[:properties][:name]
121
+ model.getBuilding.setName(name)
122
+
123
+ # find min and max x coordinate
124
+ @origin_lat_lon = feature.create_origin_lat_lon(@runner)
125
+
126
+ site = model.getSite
127
+ site.setLatitude(@origin_lat_lon.lat)
128
+ site.setLongitude(@origin_lat_lon.lon)
129
+
130
+ begin
131
+ surface_elevation = feature.surface_elevation.to_f
132
+ surface_elevation = OpenStudio.convert(surface_elevation, 'ft', 'm').get
133
+ site.setElevation(surface_elevation)
134
+ rescue StandardError
135
+ @runner.registerWarning("Surface elevation not set for building '#{name}'")
136
+ end
137
+
138
+ if feature.type == 'Building'
139
+ # make requested building
140
+ spaces = feature.create_building(:spaces_per_floor, model, @origin_lat_lon, @runner, true)
141
+ if spaces.nil? || spaces.empty?
142
+ @runner.registerError("Failed to create building spaces for feature #{feature_id}")
143
+ return false
144
+ end
145
+
146
+ # DLM: temp hack
147
+ building_type = feature.building_type
148
+ if building_type == 'Vacant'
149
+ shading_surfaces = URBANopt::GeoJSON::Helper.create_shading_surfaces(feature, model, @origin_lat_lon, @runner, spaces)
150
+ end
151
+
152
+ # make other buildings to convert to shading
153
+ convert_to_shades = []
154
+ if surrounding_buildings == 'ShadingOnly'
155
+ convert_to_shades = feature.create_other_buildings(surrounding_buildings, all_features.json, model, @origin_lat_lon, @runner)
156
+ end
157
+
158
+ # intersect surfaces in this building with others
159
+ @runner.registerInfo('Intersecting surfaces')
160
+ spaces.each do |space|
161
+ convert_to_shades.each do |other_space|
162
+ space.intersectSurfaces(other_space)
163
+ end
164
+ end
165
+
166
+ # match surfaces
167
+ @runner.registerInfo('Matching surfaces')
168
+ all_spaces = OpenStudio::Model::SpaceVector.new
169
+ model.getSpaces.each do |space|
170
+ all_spaces << space
171
+ end
172
+ OpenStudio::Model.matchSurfaces(all_spaces)
173
+
174
+ # make windows
175
+ spaces = feature.create_windows(spaces)
176
+
177
+ # change adjacent surfaces to adiabatic
178
+ model = URBANopt::GeoJSON::Model.change_adjacent_surfaces_to_adiabatic(model, @runner)
179
+
180
+ # convert other buildings to shading surfaces
181
+ convert_to_shades.map do |space|
182
+ URBANopt::GeoJSON::Helper.convert_to_shading_surface_group(space)
183
+ end
184
+
185
+ elsif feature.type == 'District System'
186
+ district_system_type = feature[:properties][:district_system_type]
187
+ if district_system_type == 'Community Photovoltaic'
188
+ shading_surfaces = URBANopt::GeoJSON::Helper.create_photovoltaics(feature, 0, model, @origin_lat_lon, @runner)
189
+ end
190
+ else
191
+ @runner.registerError("Unknown feature type '#{feature.type}'")
192
+ return false
193
+ end
194
+
195
+ # transfer data from previous model
196
+ stories = URBANopt::GeoJSON::Model.transfer_prev_model_data(model, space_types)
197
+
198
+ return true
199
+ end
200
+ end
201
+
202
+ # register the measure to be used by the application
203
+ UrbanGeometryCreationZoning.new.registerWithApplication