Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V0.11.2 #274

Merged
merged 4 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# URBANopt GeoJSON Gem

## Version 0.11.2
* Allow null for some optional fields by @vtnate in https://github.com/urbanopt/urbanopt-geojson-gem/pull/273
* Added UO-ResStock connection variable to the site properties schema by @rawadelkontar in https://github.com/urbanopt/urbanopt-geojson-gem/pull/270


**Full Changelog**: https://github.com/urbanopt/urbanopt-geojson-gem/compare/v0.11.1...v0.11.2

## Version 0.11.1
Date Range: 01/09/24

Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
URBANopt (tm), Copyright (c) 2019-2023, Alliance for Sustainable Energy, LLC, and other
URBANopt (tm), Copyright (c) 2019-2024, Alliance for Sustainable Energy, LLC, and other
contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
2 changes: 1 addition & 1 deletion lib/measures/urban_geometry_creation/LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
URBANopt (tm), Copyright (c) 2019-2023, Alliance for Sustainable Energy, LLC, and other
URBANopt (tm), Copyright (c) 2019-2024, Alliance for Sustainable Energy, LLC, and other
contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
2 changes: 1 addition & 1 deletion lib/measures/urban_geometry_creation/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def run(model, runner, user_arguments)
if scale_footprint_area_by_floor_area
building_hash = feature.to_hash
if building_hash[:number_of_stories] && building_hash[:floor_area]
scaled_footprint_area = building_hash[:floor_area].to_f / building_hash[:number_of_stories].to_f
scaled_footprint_area = building_hash[:floor_area].to_f / building_hash[:number_of_stories]
@runner.registerInfo("Desired footprint area in ft2: #{scaled_footprint_area}")
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/measures/urban_geometry_creation/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>urban_geometry_creation</name>
<uid>5ab85d6b-c9af-4361-8ab9-613ee99a5666</uid>
<version_id>583499fb-4275-4787-9168-e3383dca0fc6</version_id>
<version_modified>2023-11-20T17:10:01Z</version_modified>
<version_id>114e5a3f-0e66-47f2-aa96-299f71b4ef0f</version_id>
<version_modified>2024-06-25T21:15:26Z</version_modified>
<xml_checksum>D254E772</xml_checksum>
<class_name>UrbanGeometryCreation</class_name>
<display_name>UrbanGeometryCreation</display_name>
Expand Down Expand Up @@ -108,7 +108,7 @@
<filename>LICENSE.md</filename>
<filetype>md</filetype>
<usage_type>license</usage_type>
<checksum>9A4578CE</checksum>
<checksum>3C275955</checksum>
</file>
<file>
<filename>README.md</filename>
Expand Down
2 changes: 1 addition & 1 deletion lib/measures/urban_geometry_creation_zoning/LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
URBANopt (tm), Copyright (c) 2019-2023, Alliance for Sustainable Energy, LLC, and other
URBANopt (tm), Copyright (c) 2019-2024, Alliance for Sustainable Energy, LLC, and other
contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
Expand Down
5 changes: 3 additions & 2 deletions lib/measures/urban_geometry_creation_zoning/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ def run(model, runner, user_arguments)
@runner.registerWarning("Surface elevation not set for building '#{name}'")
end

if feature.type == 'Building'
case feature.type
when 'Building'
# make requested building, zoning is set to true
spaces = feature.create_building(:spaces_per_floor, model, @origin_lat_lon, @runner, true)
if spaces.nil? || spaces.empty?
Expand Down Expand Up @@ -157,7 +158,7 @@ def run(model, runner, user_arguments)
URBANopt::GeoJSON::Helper.convert_to_shading_surface_group(space)
end

elsif feature.type == 'District System'
when 'District System'
district_system_type = feature[:properties][:district_system_type]
if district_system_type == 'Community Photovoltaic'
shading_surfaces = URBANopt::GeoJSON::Helper.create_photovoltaics(feature, 0, model, @origin_lat_lon, @runner)
Expand Down
6 changes: 3 additions & 3 deletions lib/measures/urban_geometry_creation_zoning/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>urban_geometry_creation_zoning</name>
<uid>96ea1317-76ac-4670-b51d-71ee3f4fdd65</uid>
<version_id>4d47bb3f-6e49-4309-a4e0-5f2c3748b947</version_id>
<version_modified>2023-11-20T17:10:01Z</version_modified>
<version_id>8b2f1d05-725a-4f06-bcac-1fb685f12f89</version_id>
<version_modified>2024-06-25T21:15:28Z</version_modified>
<xml_checksum>D254E772</xml_checksum>
<class_name>UrbanGeometryCreationZoning</class_name>
<display_name>UrbanGeometryCreationZoning</display_name>
Expand Down Expand Up @@ -89,7 +89,7 @@
<filename>LICENSE.md</filename>
<filetype>md</filetype>
<usage_type>license</usage_type>
<checksum>9A4578CE</checksum>
<checksum>3C275955</checksum>
</file>
<file>
<filename>README.md</filename>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
require 'openstudio'
require 'openstudio/ruleset/ShowRunnerOutput'
require 'minitest/autorun'
require_relative '../measure.rb'
require_relative '../measure'
require 'fileutils'

class UrbanGeometryCreationZoningTest < MiniTest::Test
Expand Down
11 changes: 5 additions & 6 deletions lib/urbanopt/geojson/building.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ def create_building(create_method, model, origin_lat_lon, runner, zoning = false
end

spaces = []
if create_method == :space_per_floor || create_method == :spaces_per_floor
case create_method
when :space_per_floor, :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
when :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
Expand Down Expand Up @@ -417,10 +418,8 @@ def create_space_per_floor(story_number, floor_to_floor_height, model, origin_la
space = space.get
space.setName("Building Story #{story_number} Space")
space.surfaces.each do |surface|
if surface.surfaceType == 'Wall'
if story_number < 1
surface.setOutsideBoundaryCondition('Ground')
end
if surface.surfaceType == 'Wall' && (story_number < 1)
surface.setOutsideBoundaryCondition('Ground')
end
end
spaces << space
Expand Down
4 changes: 0 additions & 4 deletions lib/urbanopt/geojson/district_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@
module URBANopt
module GeoJSON # :nodoc: all
class DistrictSystem < Feature
def initialize(feature)
super(feature)
end

##
# Used to describe the feature type using the base method from the Feature class.
def feature_type
Expand Down
15 changes: 7 additions & 8 deletions lib/urbanopt/geojson/feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def initialize(feature)
@feature_json = validate_feat(feature)
end

# rubocop:disable Style/MethodMissing
def method_missing(name, *args, &blk)
# rubocop:enable Style/MethodMissing
if @feature_json[:properties].keys.map(&:to_sym).include? name.to_sym

return @feature_json[:properties][name.to_sym]
Expand Down Expand Up @@ -196,10 +194,11 @@ def get_min_lon_lat
def get_multi_polygons(json = @feature_json)
geometry_type = json[:geometry][:type]
multi_polygons = []
if geometry_type == 'Polygon'
case geometry_type
when 'Polygon'
polygons = json[:geometry][:coordinates]
multi_polygons = [polygons]
elsif geometry_type == 'MultiPolygon'
when 'MultiPolygon'
multi_polygons = json[:geometry][:coordinates]
end
return multi_polygons
Expand Down Expand Up @@ -256,8 +255,7 @@ def find_feature_center(vertices)
central_latitude = Math.atan2(z, central_square_root)

[central_longitude * 180 / Math::PI,
central_latitude * 180 / Math::PI]

central_latitude * 180 / Math::PI]
end

private
Expand Down Expand Up @@ -292,8 +290,9 @@ def validate_feat(feature) #:doc:
end

geometry_type = feature[:geometry][:type]
if geometry_type == 'Polygon'
elsif geometry_type == 'MultiPolygon'
case geometry_type
when 'Polygon'
when 'MultiPolygon'
else
raise("Unknown geometry type '#{geometry_type}'")
return false
Expand Down
31 changes: 15 additions & 16 deletions lib/urbanopt/geojson/geo_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def self.from_file(path)
symbolize_names: true
)


# validate geojson file against schema
geojson_errors = validate(@@geojson_schema, geojson_file)
unless geojson_errors.empty?
Expand Down Expand Up @@ -83,6 +82,7 @@ def self.from_file(path)
if feature[:properties][:name].nil?
raise('No name found for Building Feature')
end

if feature[:properties][:number_of_stories].nil?
@@logger.warn("Number of stories is required to calculate shading using the UrbanGeometryCreation measure.\n" \
"Not validating #{feature[:properties][:id]} against schema and ignoring in shading calculations")
Expand All @@ -96,6 +96,7 @@ def self.from_file(path)
if feature[:properties][:name].nil?
raise('No name found for Building Feature')
end

@@logger.warn("OS-HPXML files may not conform to schema, which is usually ok.\n" \
"Not validating #{feature[:properties][:id]} against schema")
# Else validate for all required properties in the schema
Expand Down Expand Up @@ -203,12 +204,10 @@ def merge_site_properties(feature)
]

add_props.each do |prop|
if project.key?(prop[:site]) && project[prop[:site]]
# property exists in site
if !feature[:properties].key?(prop[:feature]) || feature[:properties][prop[:feature]].nil? || feature[:properties][prop[:feature]].to_s.empty?
# property does not exist in feature or is nil: add site property (don't overwrite)
feature[:properties][prop[:feature]] = project[prop[:site]]
end
# property exists in site
if project.key?(prop[:site]) && project[prop[:site]] && (!feature[:properties].key?(prop[:feature]) || feature[:properties][prop[:feature]].nil? || feature[:properties][prop[:feature]].to_s.empty?)
# property does not exist in feature or is nil: add site property (don't overwrite)
feature[:properties][prop[:feature]] = project[prop[:site]]
end
end

Expand All @@ -229,7 +228,7 @@ def self.get_geojson_schema(strict)
result = nil
if @@geojson_schema.nil?
@@schema_file_lock.synchronize do
File.open(File.dirname(__FILE__) + '/schema/geojson_schema.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/geojson_schema.json") do |f|
result = JSON.parse(f.read, symbolize_names: true)
end
end
Expand All @@ -239,7 +238,7 @@ def self.get_geojson_schema(strict)

def self.get_building_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/building_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/building_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -252,7 +251,7 @@ def self.get_building_schema(strict)

def self.get_district_system_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/district_system_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/district_system_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -265,7 +264,7 @@ def self.get_district_system_schema(strict)

def self.get_region_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/region_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/region_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -278,7 +277,7 @@ def self.get_region_schema(strict)

def self.get_site_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/site_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/site_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -291,7 +290,7 @@ def self.get_site_schema(strict)

def self.get_electrical_connector_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/electrical_connector_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/electrical_connector_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -304,7 +303,7 @@ def self.get_electrical_connector_schema(strict)

def self.get_electrical_junction_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/electrical_junction_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/electrical_junction_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -317,7 +316,7 @@ def self.get_electrical_junction_schema(strict)

def self.get_thermal_connector_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/thermal_connector_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/thermal_connector_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand All @@ -330,7 +329,7 @@ def self.get_thermal_connector_schema(strict)

def self.get_thermal_junction_schema(strict)
result = nil
File.open(File.dirname(__FILE__) + '/schema/thermal_junction_properties.json') do |f|
File.open("#{File.dirname(__FILE__)}/schema/thermal_junction_properties.json") do |f|
result = JSON.parse(f.read)
end
if strict
Expand Down
16 changes: 10 additions & 6 deletions lib/urbanopt/geojson/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ def self.process_other_buildings(building, other_building_type, other_buildings,
other_buildings[:features].each do |other_building|
other_id = other_building[:properties][:id]
next if other_id == building.id

# Consider building, if other building type is ShadingOnly and other id is not equal to building id
if other_building_type == 'ShadingOnly' && other_id != building.id
# Checks if any building point is shaded by any other building point.
Expand Down Expand Up @@ -277,6 +278,7 @@ def self.process_other_buildings(building, other_building_type, other_buildings,
runner.registerInfo("Feature #{other_building[:properties][:id]} is acting as shading object for #{building.id}")
end
next unless shadowed

new_building = building.create_other_building(:space_per_building, model, origin_lat_lon, runner, zoning, 0, other_building)
if new_building.nil? || new_building.empty?
runner.registerWarning("Failed to create spaces for other building '#{name}'")
Expand Down Expand Up @@ -321,6 +323,7 @@ def self.is_shadowed(potentially_shaded, potential_shader, origin_lat_lon)
if is_shaded(min_pair[:building_point], min_pair[:other_building_point], origin_lat_lon)
return true
end

return false
end

Expand All @@ -339,7 +342,8 @@ def self.is_shaded(building_point, other_building_point, origin_lat_lon)
if distance < 1
return true
end
elevation_angle = 2.5 #not sure of best value maybe allow as project level argument

elevation_angle = 2.5 # not sure of best value maybe allow as project level argument
height = vector.z
apparent_angle_rad = Math.atan2(height, distance)
apparent_angle = OpenStudio.radToDeg(apparent_angle_rad)
Expand All @@ -351,9 +355,9 @@ def self.is_shaded(building_point, other_building_point, origin_lat_lon)
return result
end

class << self
private :is_shaded
end
end
end
class << self
private :is_shaded
end
end
end
end
2 changes: 1 addition & 1 deletion lib/urbanopt/geojson/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

module URBANopt
module GeoJSON
@@logger = Logger.new(STDERR)
@@logger = Logger.new($stderr)
@@logger.progname = 'URBANopt::GeoJSON'

def self.logger
Expand Down
7 changes: 4 additions & 3 deletions lib/urbanopt/geojson/mapper_classes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,16 @@ def create_osw(scenario, feature_id, feature_name)
feature_file = scenario.feature_file
feature = feature_file.get_feature_by_id(feature_id)
raise "Cannot find feature '#{feature_id}' in '#{scenario.geometry_file}'" if feature.nil?

# deep clone of @@osw before we configure it #:nodoc:
osw = Marshal.load(Marshal.dump(@@osw))
osw[:name] = feature_name
osw[:description] = feature_name
end
end
# rubocop:disable Lint/ReturnInVoidContext
return osw
# rubocop:enable Lint/ReturnInVoidContext
end
# rubocop:enable Lint/ReturnInVoidContext
end
end
end
end
Loading