Class: URBANopt::GeoJSON::Feature
- Inherits:
-
Core::Feature
- Object
- Core::Feature
- URBANopt::GeoJSON::Feature
- Defined in:
- lib/urbanopt/geojson/feature.rb
Direct Known Subclasses
Constant Summary collapse
- @@feature_schema =
{}
- @@schema_file_lock =
Mutex.new
Instance Attribute Summary collapse
-
#feature_json ⇒ Object
readonly
Returns the value of attribute feature_json.
Instance Method Summary collapse
-
#calculate_aspect_ratio ⇒ Object
Used to calculate the aspect ratio for a given floor polygon.
-
#create_origin_lat_lon(runner) ⇒ Object
Returns instance of OpenStudio::PointLatLon for latitude and longitude of feature.
-
#feature_type ⇒ Object
Raises an error if the
feature_typeis not specified the the Feature’s class. -
#find_feature_center(vertices) ⇒ Object
Used to determine the centroid for the feature’s geojson coordinates.
-
#get_min_lon_lat ⇒ Object
Returns coordinate with the minimum longitute and latitude within a given
building_json. -
#get_multi_polygons(json = @feature_json) ⇒ Object
Returns MultiPolygon coordinates (coordinate pairs in double nested Array) [Parameters]
json. -
#get_perimeter_multiplier(area, aspect_ratio, perimeter_original) ⇒ Object
Used to calculate the perimeter multiplier given the aspect ratio, original perimeter and area.
-
#id ⇒ Object
Returns the id of the feature.
-
#initialize(feature) ⇒ Feature
constructor
Used to validate the feature using the validate_feat method.
-
#method_missing(name, *args, &blk) ⇒ Object
rubocop:disable Style/MethodMissing.
-
#name ⇒ Object
Returns the name of the feature.
- #schema ⇒ Object
-
#schema_file ⇒ Object
Raises an error if the
schema_fileis not specified the the Feature’s class.
Constructor Details
#initialize(feature) ⇒ Feature
Used to validate the feature using the validate_feat method.
18 19 20 |
# File 'lib/urbanopt/geojson/feature.rb', line 18 def initialize(feature) @feature_json = validate_feat(feature) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &blk) ⇒ Object
rubocop:disable Style/MethodMissing
23 24 25 26 27 28 29 30 31 |
# File 'lib/urbanopt/geojson/feature.rb', line 23 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] else super end end |
Instance Attribute Details
#feature_json ⇒ Object (readonly)
Returns the value of attribute feature_json.
11 12 13 |
# File 'lib/urbanopt/geojson/feature.rb', line 11 def feature_json @feature_json end |
Instance Method Details
#calculate_aspect_ratio ⇒ Object
Used to calculate the aspect ratio for a given floor polygon.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/urbanopt/geojson/feature.rb', line 79 def calculate_aspect_ratio multi_polygons = get_multi_polygons(@feature_json) rad_per_deg = 0.017453293 multi_polygons.each do |multi_polygon| if multi_polygon.size > 1 runner.registerWarning('Ignoring holes in polygon') end multi_polygon.each do |polygon| n = polygon.size length = 0 north = 0 east = 0 south = 0 west = 0 aspect_ratio = 0 for i in (0..n - 2) do i vertex_1 = nil vertex_2 = nil if i == n - 2 vertex_1 = polygon[n - 2] vertex_2 = polygon[0] else vertex_1 = polygon[i] vertex_2 = polygon[i + 1] end x_1 = vertex_1[0] y_1 = vertex_1[1] x_2 = vertex_2[0] y_2 = vertex_2[1] dist = (x_2 - x_1)**2 + (y_2 - y_1)**2 length = Math.sqrt(dist) # delta latitude dlat = x_2 - x_1 # delta longitude dlon = y_2 - y_1 # convert radian to degree sin_angle = Math.asin(dlon / length) * (1 / rad_per_deg) sin_angle = sin_angle.round(4) cos_angle = Math.acos(dlat / length) * (1 / rad_per_deg) cos_angle = cos_angle.round(4) if cos_angle >= 45 && cos_angle <= 135 && sin_angle >= 45 && sin_angle <= 90 north += length elsif cos_angle >= 0 && cos_angle < 45 && sin_angle > -45 && sin_angle < 45 east += length elsif cos_angle >= 45 && cos_angle <= 135 && sin_angle >= -90 && sin_angle <= -45 south += length elsif cos_angle > 135 && cos_angle <= 180 && sin_angle > -45 && sin_angle < 45 west += length end if east + west != 0 aspect_ratio = (north + south) / (east + west) else aspect_ratio = 1 end end aspect_ratio = aspect_ratio.round(4) return aspect_ratio end end end |
#create_origin_lat_lon(runner) ⇒ Object
Returns instance of OpenStudio::PointLatLon for latitude and longitude of feature.
- Parameters
-
runner- An instance ofOpenstudio::Measure::OSRunnerfor the measure run.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/urbanopt/geojson/feature.rb', line 213 def create_origin_lat_lon(runner) min_lon_lat = get_min_lon_lat min_lon = min_lon_lat[0] min_lat = min_lon_lat[1] if min_lon == Float::MAX || min_lat == Float::MAX runner.registerError('Could not determine min_lat and min_lon') return false else runner.registerInfo("Min_lat = #{min_lat}, min_lon = #{min_lon}") end return OpenStudio::PointLatLon.new(min_lat, min_lon, 0) end |
#feature_type ⇒ Object
Raises an error if the feature_type is not specified the the Feature’s class.
50 51 52 |
# File 'lib/urbanopt/geojson/feature.rb', line 50 def feature_type raise 'feature_type not implemented for Feature, override in your class' end |
#find_feature_center(vertices) ⇒ Object
Used to determine the centroid for the feature’s geojson coordinates.
- Parameters
-
vertices- The first set polygon vertices in the array of feature coordinates.
- Returns
-
Returns Feature centroid coordinates [long, lat]
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/urbanopt/geojson/feature.rb', line 235 def find_feature_center(vertices) number_of_locations = vertices.length return vertices.first if number_of_locations == 1 x = y = z = 0.0 vertices.each do |station| latitude = station[1] * Math::PI / 180 longitude = station[0] * Math::PI / 180 x += Math.cos(latitude) * Math.cos(longitude) y += Math.cos(latitude) * Math.sin(longitude) z += Math.sin(latitude) end x /= number_of_locations y /= number_of_locations z /= number_of_locations central_longitude = Math.atan2(y, x) central_square_root = Math.sqrt(x * x + y * y) central_latitude = Math.atan2(z, central_square_root) [central_longitude * 180 / Math::PI, central_latitude * 180 / Math::PI] end |
#get_min_lon_lat ⇒ Object
Returns coordinate with the minimum longitute and latitude within a given building_json .
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/urbanopt/geojson/feature.rb', line 161 def get_min_lon_lat min_lon = Float::MAX min_lat = Float::MAX multi_polygons = get_multi_polygons multi_polygons.each do |multi_polygon| multi_polygon.each do |polygon| polygon.each do |point| min_lon = point[0] if point[0] < min_lon min_lat = point[1] if point[1] < min_lat end break end end return [min_lon, min_lat] end |
#get_multi_polygons(json = @feature_json) ⇒ Object
Returns MultiPolygon coordinates (coordinate pairs in double nested Array)
- Parameters
-
jsonFor example:
polygon = { 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [0, 5], [5, 5], [5, 0] ] ] } }
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/urbanopt/geojson/feature.rb', line 196 def get_multi_polygons(json = @feature_json) geometry_type = json[:geometry][:type] multi_polygons = [] if geometry_type == 'Polygon' polygons = json[:geometry][:coordinates] multi_polygons = [polygons] elsif geometry_type == 'MultiPolygon' multi_polygons = json[:geometry][:coordinates] end return multi_polygons end |
#get_perimeter_multiplier(area, aspect_ratio, perimeter_original) ⇒ Object
Used to calculate the perimeter multiplier given the aspect ratio, original perimeter and area.
153 154 155 156 157 |
# File 'lib/urbanopt/geojson/feature.rb', line 153 def get_perimeter_multiplier(area, aspect_ratio, perimeter_original) perimeter_new = 2 * (Math.sqrt(area * aspect_ratio) + Math.sqrt(area / aspect_ratio)) perimeter_ratio = perimeter_original / perimeter_new return perimeter_ratio end |
#id ⇒ Object
Returns the id of the feature.
36 37 38 |
# File 'lib/urbanopt/geojson/feature.rb', line 36 def id return @feature_json[:properties][:id] end |
#name ⇒ Object
Returns the name of the feature.
43 44 45 |
# File 'lib/urbanopt/geojson/feature.rb', line 43 def name return @feature_json[:properties][:name] end |
#schema ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/urbanopt/geojson/feature.rb', line 61 def schema if @@feature_schema[feature_type].nil? @@schema_file_lock.synchronize do File.open(schema_file, 'r') do |file| @@feature_schema[feature_type] = JSON.parse(file.read, symbolize_names: true) # Allows additional properties. @@feature_schema[feature_type][:additionalProperties] = true end end end return @@feature_schema[feature_type] end |
#schema_file ⇒ Object
Raises an error if the schema_file is not specified the the Feature’s class.
57 58 59 |
# File 'lib/urbanopt/geojson/feature.rb', line 57 def schema_file raise 'schema_file not implemented for Feature, override in your class' end |