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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
- data/.github/pull_request_template.md +13 -0
- data/CONTRIBUTING.md +58 -0
- data/Gemfile +3 -3
- data/Jenkinsfile +2 -2
- data/LICENSE.md +1 -1
- data/Rakefile +1 -1
- data/doc_templates/LICENSE.md +1 -1
- data/doc_templates/copyright_erb.txt +1 -1
- data/doc_templates/copyright_js.txt +1 -1
- data/doc_templates/copyright_ruby.txt +1 -1
- data/docs/package-lock.json +2291 -2205
- data/docs/package.json +8 -1
- data/lib/change_log.rb +147 -0
- data/lib/measures/urban_geometry_creation/LICENSE.md +1 -1
- data/lib/measures/urban_geometry_creation/measure.rb +1 -3
- data/lib/measures/urban_geometry_creation/tests/shadowed_tests.rb +1 -1
- data/lib/measures/urban_geometry_creation/tests/urban_geometry_creation_test.rb +3 -7
- data/lib/measures/urban_geometry_creation_zoning/LICENSE.md +1 -1
- data/lib/measures/urban_geometry_creation_zoning/measure.rb +5 -6
- data/lib/measures/urban_geometry_creation_zoning/tests/{urban_geometry_creation_test.rb → urban_geometry_creation_zoning_test.rb} +3 -7
- data/lib/urbanopt-geojson.rb +31 -0
- data/lib/urbanopt/geojson.rb +1 -1
- data/lib/urbanopt/geojson/building.rb +90 -18
- data/lib/urbanopt/geojson/district_system.rb +1 -1
- data/lib/urbanopt/geojson/extension.rb +1 -1
- data/lib/urbanopt/geojson/feature.rb +9 -7
- data/lib/urbanopt/geojson/files/electrical_database.json +28 -0
- data/lib/urbanopt/geojson/geo_file.rb +213 -31
- data/lib/urbanopt/geojson/helper.rb +10 -8
- data/lib/urbanopt/geojson/logging.rb +1 -1
- data/lib/urbanopt/geojson/mapper_classes.rb +1 -1
- data/lib/urbanopt/geojson/model.rb +1 -1
- data/lib/urbanopt/geojson/region.rb +1 -1
- data/lib/urbanopt/geojson/schema/building_properties.json +28 -5
- data/lib/urbanopt/geojson/schema/district_system_properties.json +29 -28
- data/lib/urbanopt/geojson/schema/electrical_connector_properties.json +150 -10
- data/lib/urbanopt/geojson/schema/electrical_junction_properties.json +3 -2
- data/lib/urbanopt/geojson/schema/thermal_connector_properties.json +2 -1
- data/lib/urbanopt/geojson/update_areas.rb +1 -1
- data/lib/urbanopt/geojson/validate_geojson.rb +1 -1
- data/lib/urbanopt/geojson/version.rb +2 -2
- data/lib/urbanopt/geojson/zoning.rb +1 -1
- data/urbanopt-geojson-gem.gemspec +4 -1
- metadata +14 -8
- data/.travis.yml +0 -35
@@ -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,
|
@@ -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,
|
@@ -177,19 +177,21 @@ module URBANopt
|
|
177
177
|
end
|
178
178
|
|
179
179
|
if feature[:geometry].nil?
|
180
|
-
raise("No geometry found in '#{feature}'")
|
180
|
+
raise("No geometry found in '#{feature[:properties][:name]}'")
|
181
181
|
return false
|
182
182
|
end
|
183
183
|
|
184
184
|
if feature[:properties].nil?
|
185
|
-
raise("No properties found in '#{feature}'")
|
185
|
+
raise("No properties found in '#{feature[:properties][:name]}'")
|
186
186
|
return false
|
187
187
|
end
|
188
188
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
189
|
+
unless feature[:properties][:detailed_model_filename]
|
190
|
+
errors = JSON::Validator.fully_validate(schema, feature[:properties])
|
191
|
+
if !errors.empty?
|
192
|
+
raise("Invalid properties for '#{feature[:properties][:name]}'\n #{errors.join('\n ')}")
|
193
|
+
return false
|
194
|
+
end
|
193
195
|
end
|
194
196
|
|
195
197
|
geometry_type = feature[:geometry][:type]
|
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"transformer_properties": {
|
3
|
+
"nameclass": "Transformer--25KVA CT",
|
4
|
+
"kva": 25,
|
5
|
+
"resistance": 0.1,
|
6
|
+
"phases": ["A"],
|
7
|
+
"high_voltage": 13.2,
|
8
|
+
"low_voltage": 0.24,
|
9
|
+
"is_center_tap": true,
|
10
|
+
"connection": "Delta-Wye"
|
11
|
+
},
|
12
|
+
"capacitor_properties": {
|
13
|
+
"nameclass": "Capacitor--150KVAR",
|
14
|
+
"kvar": 150,
|
15
|
+
"resistance": 0.1,
|
16
|
+
"phases": ["A","B","C"],
|
17
|
+
"control_type": "Voltage",
|
18
|
+
"connection": "Delta-Wye"
|
19
|
+
},
|
20
|
+
"wire": {
|
21
|
+
"nameclass": "OH AL 4/0",
|
22
|
+
"phase": "A",
|
23
|
+
"height": 50,
|
24
|
+
"x": 0,
|
25
|
+
"amapcity": 200
|
26
|
+
}
|
27
|
+
|
28
|
+
}
|
@@ -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,
|
@@ -42,17 +42,15 @@ module URBANopt
|
|
42
42
|
@@schema_file_lock = Mutex.new
|
43
43
|
|
44
44
|
##
|
45
|
-
#
|
45
|
+
# Initialize GeoJSON file and path.
|
46
46
|
#
|
47
47
|
# [Parameters]
|
48
48
|
#
|
49
|
-
# * +
|
50
|
-
|
49
|
+
# * +path+ - _Type:String_ GeoJSON File path.
|
50
|
+
# * +data+ - _Type:Hash_ Contains the GeoJSON File.
|
51
|
+
def initialize(geojson_file, path = nil)
|
51
52
|
@path = path
|
52
|
-
@
|
53
|
-
if !valid?
|
54
|
-
raise 'GeoJSON file does not adhere to schema'
|
55
|
-
end
|
53
|
+
@geojson_file = geojson_file
|
56
54
|
end
|
57
55
|
|
58
56
|
##
|
@@ -69,15 +67,69 @@ module URBANopt
|
|
69
67
|
raise "GeoJSON file '#{path}' does not exist"
|
70
68
|
end
|
71
69
|
|
72
|
-
|
70
|
+
geojson_file = JSON.parse(
|
73
71
|
File.open(path, 'r', &:read),
|
74
72
|
symbolize_names: true
|
75
73
|
)
|
76
|
-
|
74
|
+
|
75
|
+
# validate geojson file against schema
|
76
|
+
geojson_errors = validate(@@geojson_schema, geojson_file)
|
77
|
+
unless geojson_errors.empty?
|
78
|
+
raise "GeoJSON file does not adhere to the schema: \n #{geojson_errors.join('\n ')}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# initialize @@logger
|
82
|
+
@@logger ||= URBANopt::GeoJSON.logger
|
83
|
+
|
84
|
+
# validate each feature against schema
|
85
|
+
geojson_file[:features].each do |feature|
|
86
|
+
properties = feature[:properties]
|
87
|
+
type = properties[:type]
|
88
|
+
|
89
|
+
errors = []
|
90
|
+
|
91
|
+
case type
|
92
|
+
when 'Building'
|
93
|
+
# Incase detailed_model_filename present check for fewer properties
|
94
|
+
if feature[:properties][:detailed_model_filename]
|
95
|
+
if feature[:properties][:id].nil?
|
96
|
+
raise("No id found for Building Feature")
|
97
|
+
end
|
98
|
+
if feature[:properties][:name].nil?
|
99
|
+
raise("No name found for Building Feature")
|
100
|
+
end
|
101
|
+
if feature[:properties][:number_of_stories].nil?
|
102
|
+
@@logger.warn("Number of stories is required to calculate shading using the UrbanGeometryCreation measure...ignoring #{feature[:properties][:id]} in shading calculations")
|
103
|
+
end
|
104
|
+
feature[:additionalProperties] = true
|
105
|
+
# Else validate for all required properties in the schema
|
106
|
+
else
|
107
|
+
errors = validate(@@building_schema, properties)
|
108
|
+
end
|
109
|
+
when 'District System'
|
110
|
+
errors = validate(@@district_system_schema, properties)
|
111
|
+
when 'Region'
|
112
|
+
error = validate(@@district_system_schema, properties)
|
113
|
+
when 'ElectricalJunction'
|
114
|
+
errors = validate(@@electrical_junction_schema, properties)
|
115
|
+
when 'ElectricalConnector'
|
116
|
+
errors = validate(@@electrical_connector_schema, properties)
|
117
|
+
when 'ElectricalJunction'
|
118
|
+
errors = validate(@@thermal_junction_schema, properties)
|
119
|
+
when 'ThermalConnector'
|
120
|
+
errors = validate(@@thermal_connector_schema, properties)
|
121
|
+
end
|
122
|
+
|
123
|
+
unless errors.empty?
|
124
|
+
raise ("#{type} does not adhere to schema: \n #{errors.join('\n ')}")
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
return new(geojson_file, path)
|
77
129
|
end
|
78
130
|
|
79
131
|
def json
|
80
|
-
@
|
132
|
+
@geojson_file
|
81
133
|
end
|
82
134
|
|
83
135
|
attr_reader :path
|
@@ -88,7 +140,7 @@ module URBANopt
|
|
88
140
|
#
|
89
141
|
def features
|
90
142
|
result = []
|
91
|
-
@
|
143
|
+
@geojson_file[:features].each do |f|
|
92
144
|
if f[:properties] && f[:properties][:type] == 'Building'
|
93
145
|
result << URBANopt::GeoJSON::Building.new(f)
|
94
146
|
elsif f[:properties] && f[:properties][:type] == 'District System'
|
@@ -101,13 +153,15 @@ module URBANopt
|
|
101
153
|
##
|
102
154
|
# Returns feature object by feature_id from specified GeoJSON file and creates a
|
103
155
|
# new +URBANopt::GeoJSON::Building+ or +URBANopt::GeoJSON::DistrictSystem+ based on the
|
104
|
-
# feature type.
|
156
|
+
# feature type. Before returning the feature, merge 'Site Origin' properties into the feature
|
105
157
|
#
|
106
158
|
# [Parameters]
|
107
159
|
# * +feature_id+ - _Type:String/Number_ - Id affiliated with feature object.
|
108
160
|
def get_feature_by_id(feature_id)
|
109
|
-
@
|
161
|
+
@geojson_file[:features].each do |f|
|
110
162
|
if f[:properties] && f[:properties][:id] == feature_id
|
163
|
+
# merge site origin properties
|
164
|
+
f = merge_site_properties(f)
|
111
165
|
if f[:properties][:type] == 'Building'
|
112
166
|
return URBANopt::GeoJSON::Building.new(f)
|
113
167
|
elsif f[:properties] && f[:properties][:type] == 'District System'
|
@@ -118,37 +172,165 @@ module URBANopt
|
|
118
172
|
return nil
|
119
173
|
end
|
120
174
|
|
121
|
-
##
|
122
|
-
# Returns
|
123
|
-
|
124
|
-
|
175
|
+
##
|
176
|
+
# Merge Site Properties in Feature. Returns feature with site properties added to its properties section. Does not overwrite existing properties.
|
177
|
+
#
|
178
|
+
# [Parameters]
|
179
|
+
# +feature+ - _Type:Hash_ - feature object.
|
180
|
+
def merge_site_properties(feature)
|
181
|
+
site_origins = @geojson_file[:features].select {|f| f[:properties][:type] == 'Site Origin'}
|
182
|
+
if site_origins.size > 0
|
183
|
+
site_origin = site_origins[0]
|
184
|
+
# site origin found, do some merging
|
185
|
+
# this maps site properties to building/district system properties.
|
186
|
+
add_props = [
|
187
|
+
{site: :surface_elevation, feature: :surface_elevation},
|
188
|
+
{site: :timesteps_per_hour, feature: :timesteps_per_hour},
|
189
|
+
{site: :begin_date, feature: :begin_date},
|
190
|
+
{site: :end_date, feature: :end_date},
|
191
|
+
{site: :cec_climate_zone, feature: :cec_climate_zone},
|
192
|
+
{site: :climate_zone, feature: :climate_zone},
|
193
|
+
{site: :default_template, feature: :template},
|
194
|
+
{site: :weather_filename, feature: :weather_filename},
|
195
|
+
{site: :tariff_filename, feature: :tariff_filename}
|
196
|
+
]
|
197
|
+
|
198
|
+
add_props.each do |prop|
|
199
|
+
if site_origin[:properties].key?(prop[:site]) and site_origin[:properties][prop[:site]]
|
200
|
+
# property exists in site
|
201
|
+
if !feature[:properties].key?(prop[:feature]) or feature[:properties][prop[:feature]].nil? or feature[:properties][prop[:feature]].empty?
|
202
|
+
# property does not exist in feature or is nil: add site property (don't overwrite)
|
203
|
+
feature[:properties][prop[:feature]] = site_origin[:properties][prop[:site]]
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
return feature
|
125
209
|
end
|
126
210
|
|
127
211
|
##
|
128
|
-
#
|
129
|
-
|
212
|
+
# Validate GeoJSON against schema
|
213
|
+
#
|
214
|
+
# [Parameters]
|
215
|
+
# * +data+ - + - _Type:Hash_ - Input GeoJSON file
|
216
|
+
def self.validate(schema_json, data)
|
217
|
+
errors = JSON::Validator.fully_validate(schema_json, data, errors_as_objects: true)
|
218
|
+
return errors
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.get_geojson_schema(strict)
|
222
|
+
result = nil
|
130
223
|
if @@geojson_schema.nil?
|
131
224
|
@@schema_file_lock.synchronize do
|
132
|
-
File.open(
|
133
|
-
|
225
|
+
File.open(File.dirname(__FILE__) + '/schema/geojson_schema.json') do |f|
|
226
|
+
result = JSON.parse(f.read, symbolize_names: true)
|
134
227
|
end
|
135
228
|
end
|
136
229
|
end
|
230
|
+
return result
|
231
|
+
end
|
137
232
|
|
138
|
-
|
233
|
+
def self.get_building_schema(strict)
|
234
|
+
result = nil
|
235
|
+
File.open(File.dirname(__FILE__) + '/schema/building_properties.json') do |f|
|
236
|
+
result = JSON.parse(f.read)
|
237
|
+
end
|
238
|
+
if strict
|
239
|
+
result['additionalProperties'] = true
|
240
|
+
else
|
241
|
+
result['additionalProperties'] = false
|
242
|
+
end
|
243
|
+
return result
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.get_district_system_schema(strict)
|
247
|
+
result = nil
|
248
|
+
File.open(File.dirname(__FILE__) + '/schema/district_system_properties.json') do |f|
|
249
|
+
result = JSON.parse(f.read)
|
250
|
+
end
|
251
|
+
if strict
|
252
|
+
result['additionalProperties'] = true
|
253
|
+
else
|
254
|
+
result['additionalProperties'] = false
|
255
|
+
end
|
256
|
+
return result
|
257
|
+
end
|
258
|
+
|
259
|
+
def self.get_region_schema(strict)
|
260
|
+
result = nil
|
261
|
+
File.open(File.dirname(__FILE__) + '/schema/region_properties.json') do |f|
|
262
|
+
result = JSON.parse(f.read)
|
263
|
+
end
|
264
|
+
if strict
|
265
|
+
result['additionalProperties'] = true
|
266
|
+
else
|
267
|
+
result['additionalProperties'] = false
|
268
|
+
end
|
269
|
+
return result
|
139
270
|
end
|
140
271
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
272
|
+
def self.get_electrical_connector_schema(strict)
|
273
|
+
result = nil
|
274
|
+
File.open(File.dirname(__FILE__) + '/schema/electrical_connector_properties.json') do |f|
|
275
|
+
result = JSON.parse(f.read)
|
276
|
+
end
|
277
|
+
if strict
|
278
|
+
result['additionalProperties'] = true
|
279
|
+
else
|
280
|
+
result['additionalProperties'] = false
|
281
|
+
end
|
282
|
+
return result
|
145
283
|
end
|
146
284
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
285
|
+
def self.get_electrical_junction_schema(strict)
|
286
|
+
result = nil
|
287
|
+
File.open(File.dirname(__FILE__) + '/schema/electrical_junction_properties.json') do |f|
|
288
|
+
result = JSON.parse(f.read)
|
289
|
+
end
|
290
|
+
if strict
|
291
|
+
result['additionalProperties'] = true
|
292
|
+
else
|
293
|
+
result['additionalProperties'] = false
|
294
|
+
end
|
295
|
+
return result
|
151
296
|
end
|
297
|
+
|
298
|
+
def self.get_thermal_connector_schema(strict)
|
299
|
+
result = nil
|
300
|
+
File.open(File.dirname(__FILE__) + '/schema/thermal_connector_properties.json') do |f|
|
301
|
+
result = JSON.parse(f.read)
|
302
|
+
end
|
303
|
+
if strict
|
304
|
+
result['additionalProperties'] = true
|
305
|
+
else
|
306
|
+
result['additionalProperties'] = false
|
307
|
+
end
|
308
|
+
return result
|
309
|
+
end
|
310
|
+
|
311
|
+
def self.get_thermal_junction_schema(strict)
|
312
|
+
result = nil
|
313
|
+
File.open(File.dirname(__FILE__) + '/schema/thermal_junction_properties.json') do |f|
|
314
|
+
result = JSON.parse(f.read)
|
315
|
+
end
|
316
|
+
if strict
|
317
|
+
result['additionalProperties'] = true
|
318
|
+
else
|
319
|
+
result['additionalProperties'] = false
|
320
|
+
end
|
321
|
+
return result
|
322
|
+
end
|
323
|
+
|
324
|
+
strict = true
|
325
|
+
@@geojson_schema = get_geojson_schema(strict)
|
326
|
+
@@building_schema = get_building_schema(strict)
|
327
|
+
@@district_system_schema = get_district_system_schema(strict)
|
328
|
+
@@region_schema = get_region_schema(strict)
|
329
|
+
@@electrical_connector_schema = get_electrical_connector_schema(strict)
|
330
|
+
@@electrical_junction_schema = get_electrical_junction_schema(strict)
|
331
|
+
@@thermal_connector_schema = get_thermal_connector_schema(strict)
|
332
|
+
@@thermal_junction_schema = get_thermal_junction_schema(strict)
|
333
|
+
|
152
334
|
end
|
153
335
|
end
|
154
336
|
end
|
@@ -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,
|
@@ -216,7 +216,7 @@ module URBANopt
|
|
216
216
|
#
|
217
217
|
# [Parameters]
|
218
218
|
# * +building+ - _Type:URBANopt::GeoJSON::Building_ - The core building that other buildings will be referenced.
|
219
|
-
# * +other_building_type+ - _Type:String_ - Describes the surrounding buildings.
|
219
|
+
# * +other_building_type+ - _Type:String_ - Describes the surrounding buildings.
|
220
220
|
# * +other_buildings+ - _Type:URBANopt::GeoJSON::FeatureCollection_ - List of surrounding buildings to include (self will be ignored if present in list).
|
221
221
|
# * +model+ - _Type:OpenStudio::Model::Model_ - An instance of an OpenStudio Model.
|
222
222
|
# * +origin_lat_lon+ - _Type:Float_ - An instance of +OpenStudio::PointLatLon+ indicating the latitude and longitude of the origin.
|
@@ -255,14 +255,16 @@ module URBANopt
|
|
255
255
|
# find the polygon of the other_building by passing it to the get_multi_polygons method
|
256
256
|
other_building_points = building.other_points(other_building, other_height, origin_lat_lon, runner, zoning)
|
257
257
|
shadowed = URBANopt::GeoJSON::Helper.is_shadowed(feature_points, other_building_points, origin_lat_lon)
|
258
|
-
next unless shadowed
|
259
|
-
|
258
|
+
next unless shadowed
|
259
|
+
new_building = building.create_other_building(:space_per_building, model, origin_lat_lon, runner, zoning, other_building)
|
260
|
+
if new_building.nil? || new_building.empty?
|
261
|
+
runner.registerWarning("Failed to create spaces for other building '#{name}'")
|
262
|
+
end
|
263
|
+
other_spaces.concat(new_building)
|
260
264
|
|
261
|
-
|
262
|
-
if new_building.nil? || new_building.empty?
|
263
|
-
runner.registerWarning("Failed to create spaces for other building '#{name}'")
|
265
|
+
elsif other_building_type == 'None'
|
264
266
|
end
|
265
|
-
|
267
|
+
|
266
268
|
end
|
267
269
|
return other_spaces
|
268
270
|
end
|
@@ -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,
|
@@ -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,
|