class URBANopt::GeoJSON::GeoFile

Attributes

path[R]

Public Class Methods

from_file(path) click to toggle source
Parameters

Used to check the GeoJSON file path.

  • path - Type:String - GeoJSON file path.

# File lib/urbanopt/geojson/geo_file.rb, line 36
def self.from_file(path)
  if path.nil? || path.empty?
    raise "GeoJSON file '#{path}' could not be found"
  end

  if !File.exist?(path)
    raise "GeoJSON file '#{path}' does not exist"
  end

  geojson_file = JSON.parse(
    File.open(path, 'r', &:read),
    symbolize_names: true
  )


  # validate geojson file against schema
  geojson_errors = validate(@@geojson_schema, geojson_file)
  unless geojson_errors.empty?
    raise "GeoJSON file does not adhere to the schema: \n #{geojson_errors.join('\n  ')}"
  end

  # initialize @@logger
  @@logger ||= URBANopt::GeoJSON.logger

  # validate project section first
  if geojson_file.key?(:project)
    errors = validate(@@site_schema, geojson_file[:project])

    unless errors.empty?
      raise "Project section does not adhere to schema: \n #{errors.join('\n  ')}"
    end
  end

  # validate each feature against schema
  geojson_file[:features].each do |feature|
    properties = feature[:properties]
    type = properties[:type]

    errors = []

    case type
    when 'Building'
      # In case detailed_model_filename present check for fewer properties
      if feature[:properties][:detailed_model_filename]
        if feature[:properties][:id].nil?
          raise('No id found for Building Feature')
        end
        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...ignoring #{feature[:properties][:id]} in shading calculations")
        end
        feature[:additionalProperties] = true
      # In case hpxml_directory present check for fewer properties
      elsif feature[:properties][:hpxml_directory]
        if feature[:properties][:id].nil?
          raise('No id found for Building Feature')
        end
        if feature[:properties][:name].nil?
          raise('No name found for Building Feature')
        end
      # Else validate for all required properties in the schema
      else
        errors = validate(@@building_schema, properties)
      end
    when 'District System'
      errors = validate(@@district_system_schema, properties)
    when 'Region'
      error = validate(@@district_system_schema, properties)
    when 'ElectricalJunction'
      errors = validate(@@electrical_junction_schema, properties)
    when 'ElectricalConnector'
      errors = validate(@@electrical_connector_schema, properties)
    when 'ThermalJunction'
      errors = validate(@@thermal_junction_schema, properties)
    when 'ThermalConnector'
      errors = validate(@@thermal_connector_schema, properties)
    end

    unless errors.empty?
      raise "#{type} does not adhere to schema: \n #{errors.join('\n  ')}"
    end
  end
  return new(geojson_file, path)
end
get_building_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 234
def self.get_building_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/building_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_district_system_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 247
def self.get_district_system_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/district_system_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_electrical_connector_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 286
def self.get_electrical_connector_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/electrical_connector_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_electrical_junction_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 299
def self.get_electrical_junction_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/electrical_junction_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_geojson_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 222
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|
        result = JSON.parse(f.read, symbolize_names: true)
      end
    end
  end
  return result
end
get_region_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 260
def self.get_region_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/region_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_site_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 273
def self.get_site_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/site_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_thermal_connector_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 312
def self.get_thermal_connector_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/thermal_connector_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
get_thermal_junction_schema(strict) click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 325
def self.get_thermal_junction_schema(strict)
  result = nil
  File.open(File.dirname(__FILE__) + '/schema/thermal_junction_properties.json') do |f|
    result = JSON.parse(f.read)
  end
  if strict
    result['additionalProperties'] = true
  else
    result['additionalProperties'] = false
  end
  return result
end
new(geojson_file, path = nil) click to toggle source

Initialize GeoJSON file and path.

Parameters
  • path - Type:String GeoJSON File path.

  • data - Type:Hash Contains the GeoJSON File.

# File lib/urbanopt/geojson/geo_file.rb, line 26
def initialize(geojson_file, path = nil)
  @path = path
  @geojson_file = geojson_file
end
validate(schema_json, data) click to toggle source

Validate GeoJSON against schema.

Parameters
  • data - + - Type:Hash - Input GeoJSON file

# File lib/urbanopt/geojson/geo_file.rb, line 217
def self.validate(schema_json, data)
  errors = JSON::Validator.fully_validate(schema_json, data, errors_as_objects: true)
  return errors
end

Public Instance Methods

features() click to toggle source

This method loops through all the features in the GeoJSON file, creates new Buildings or District Systems based on the feature type, and returns the features.

# File lib/urbanopt/geojson/geo_file.rb, line 133
def features
  result = []
  @geojson_file[:features].each do |f|
    if f[:properties] && f[:properties][:type] == 'Building'
      result << URBANopt::GeoJSON::Building.new(f)
    elsif f[:properties] && f[:properties][:type] == 'District System'
      result << URBANopt::GeoJSON::DistrictSystem.new(f)
    end
  end
  return result
end
get_feature_by_id(feature_id) click to toggle source

Returns feature object by feature_id from specified GeoJSON file and creates a new URBANopt::GeoJSON::Building or URBANopt::GeoJSON::DistrictSystem based on the feature type. Before returning the feature, merge 'Site Origin' properties into the feature

Parameters
  • feature_id - Type:String/Number - Id affiliated with feature object.

# File lib/urbanopt/geojson/geo_file.rb, line 152
def get_feature_by_id(feature_id)
  @geojson_file[:features].each do |f|
    if f[:properties] && f[:properties][:id] == feature_id
      # merge site origin properties
      f = merge_site_properties(f)
      if f[:properties][:type] == 'Building'

        return URBANopt::GeoJSON::Building.new(f)
      elsif f[:properties] && f[:properties][:type] == 'District System'
        return URBANopt::GeoJSON::DistrictSystem.new(f)
      end
    end
  end
  return nil
end
json() click to toggle source
# File lib/urbanopt/geojson/geo_file.rb, line 123
def json
  @geojson_file
end
merge_site_properties(feature) click to toggle source

Merge Site Properties in Feature. Returns feature with site properties added to its properties section. Does not overwrite existing properties.

Parameters

feature - Type:Hash - feature object.

# File lib/urbanopt/geojson/geo_file.rb, line 173
def merge_site_properties(feature)
  project = {}
  if @geojson_file.key?(:project)
    project = @geojson_file[:project]
  end

  # this maps site properties to building/district system properties.
  add_props = [
    { site: :surface_elevation, feature: :surface_elevation },
    { site: :timesteps_per_hour, feature: :timesteps_per_hour },
    { site: :begin_date, feature: :begin_date },
    { site: :end_date, feature: :end_date },
    { site: :cec_climate_zone, feature: :cec_climate_zone },
    { site: :climate_zone, feature: :climate_zone },
    { site: :default_template, feature: :template },
    { site: :weather_filename, feature: :weather_filename },
    { site: :tariff_filename, feature: :tariff_filename },
    { site: :emissions, feature: :emissions },
    { site: :electricity_emissions_future_subregion, feature: :electricity_emissions_future_subregion },
    { site: :electricity_emissions_hourly_historical_subregion, feature: :electricity_emissions_hourly_historical_subregion },
    { site: :electricity_emissions_annual_historical_subregion, feature: :electricity_emissions_annual_historical_subregion },
    { site: :electricity_emissions_future_year, feature: :electricity_emissions_future_year },
    { site: :electricity_emissions_hourly_historical_year, feature: :electricity_emissions_hourly_historical_year },
    { site: :electricity_emissions_annual_historical_year, feature: :electricity_emissions_annual_historical_year }
  ]

  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
    end
  end

  return feature
end