Skip to content

Commit

Permalink
Preperation for adding geolocation
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrouwerdigibase committed Oct 20, 2024
1 parent c9bd0b1 commit 851fca0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 43 deletions.
103 changes: 64 additions & 39 deletions src/bt_ifcmanager/lib/lib_ifc/IfcSite_su.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,60 +23,85 @@

module BimTools
module IfcSite_su
@reflatitude = nil
@reflongitude = nil

# add project location, if set in sketchup model
# (!) north angle still missing?
def set_latlong
if Sketchup.active_model.georeferenced?
local_point = Geom::Point3d.new([0, 0, 0])
@latlong = Sketchup.active_model.point_to_latlong(local_point)
return unless Sketchup.active_model.georeferenced?

local_point = Geom::Point3d.new([0, 0, 0])
@latlong = Sketchup.active_model.point_to_latlong(local_point)
end

def reflatitude=(values)
if valid_latlong_list?(values)
@reflatitude = values
else
puts 'Invalid reflatitude values'
end
end

def latitude
return lat_long_ifc(@latlong[1]) if @latlong
def reflongitude=(values)
if valid_latlong_list?(values)
@reflongitude = values
else
puts 'Invalid reflongitude values'
end
end

def longtitude
return lat_long_ifc(@latlong[0]) if @latlong
def reflatitude
lat_long_ifc(@latlong[1]) if @latlong
end

def reflongitude
lat_long_ifc(@latlong[0]) if @latlong
end

def elevation
return IfcManager::Types::IfcLengthMeasure.new(@ifc_model, @latlong[2]) if @latlong
IfcManager::Types::IfcLengthMeasure.new(@ifc_model, @latlong[2]) if @latlong
end

private

def valid_latlong_list?(values)
values.is_a?(Array) && values.all? { |v| v.is_a?(IfcCompoundPlaneAngleMeasure) }
end

# convert sketchup latlong coordinate (decimal) to IFC notation (degrees)
def lat_long_ifc(coordinate)
if Sketchup.active_model.georeferenced?
d = coordinate.abs
neg_pos = (coordinate / d).to_int

# degrees
i = d.to_int
deg = i * neg_pos

# minutes
d -= i
d *= 60
i = d.to_int

min = i * neg_pos

# seconds
d -= i
d *= 60
i = d.to_int
sec = i * neg_pos

# millionth-seconds
d -= i
d *= 1_000_000
i = d.to_int
msec = i * neg_pos

# (!) values should be Ifc INTEGER objects instead of Strings(!)
# (!) returned object should be of type IFC LIST instead of IFC SET
IfcManager::Types::List.new([deg.to_s, min.to_s, sec.to_s, msec.to_s])
end
return unless Sketchup.active_model.georeferenced?

d = coordinate.abs
neg_pos = (coordinate / d).to_int

# degrees
i = d.to_int
deg = i * neg_pos

# minutes
d -= i
d *= 60
i = d.to_int

min = i * neg_pos

# seconds
d -= i
d *= 60
i = d.to_int
sec = i * neg_pos

# millionth-seconds
d -= i
d *= 1_000_000
i = d.to_int
msec = i * neg_pos

# (!) values should be Ifc INTEGER objects instead of Strings(!)
# (!) returned object should be of type IFC LIST instead of IFC SET
IfcManager::Types::List.new([deg.to_s, min.to_s, sec.to_s, msec.to_s])
end
end
end
47 changes: 44 additions & 3 deletions src/bt_ifcmanager/lib/lib_ifc/ifc_types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
module BimTools
module IfcManager
module Types

# https://technical.buildingsmart.org/wp-content/uploads/2018/05/IFC2x-Model-Implementation-Guide-V2-0b.pdf
# page 19 and 20
def self.replace_char(in_string)
Expand Down Expand Up @@ -207,6 +206,49 @@ def true?(obj)
# OR
# ((SELF[1] <= 0) AND (SELF[2] <= 0) AND (SELF[3] <= 0) AND ((SIZEOF(SELF) = 3) OR (SELF[4] <= 0)));
# END_TYPE;
class IfcCompoundPlaneAngleMeasure < BaseType
def initialize(ifc_model, values, long = false)
super(ifc_model, values, long)
@values = values.map(&:to_i)
validate!
end

def step
val = @values.join(',')
val = add_long(val) if @long
val
end

private

def validate!
raise ArgumentError, 'List must have 3 or 4 integers' unless (3..4).include?(@values.size)
raise ArgumentError, 'Minutes must be in range' unless minutes_in_range?
raise ArgumentError, 'Seconds must be in range' unless seconds_in_range?
raise ArgumentError, 'Microseconds must be in range' unless microseconds_in_range?
raise ArgumentError, 'Sign must be consistent' unless consistent_sign?
end

def minutes_in_range?
@values[1].abs < 60
end

def seconds_in_range?
@values[2].abs < 60
end

def microseconds_in_range?
@values.size == 3 || @values[3].abs < 1_000_000
end

def consistent_sign?
if @values[0] >= 0
@values.all? { |v| v >= 0 }
else
@values.all? { |v| v <= 0 }
end
end
end

# TYPE IfcContextDependentMeasure = REAL;
# END_TYPE;
Expand Down Expand Up @@ -923,15 +965,14 @@ class IfcVolumetricFlowRateMeasure < IfcReal
# END_TYPE;

class PEnum_ElementStatus
def initialize(ifc_model, value, long = true)
def initialize(_ifc_model, value, _long = true)
@value = value
end

def step
@value
end
end

end
end
end
3 changes: 2 additions & 1 deletion src/bt_ifcmanager/lib/lib_ifc/parse_xsd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class IfcXsdParser
IfcRelDefinesByProperties
IfcRelDefinesByType
IfcRelContainedInSpatialStructure
IfcSite
IfcSpatialStructureElement
IfcStyledItem
IfcTypeProduct
Expand Down Expand Up @@ -241,6 +242,7 @@ def get_mixin(ifc_name)
mixin_file = Pathname.new("#{PLUGIN_ROOT_PATH}/bt_ifcmanager/lib/lib_ifc/#{ifc_name}_su.rb")
if mixin_file.exist?
require_relative(mixin_file)
puts "loaded #{ifc_name}_su"
return BimTools.const_get(ifc_name + '_su')
end
nil
Expand Down Expand Up @@ -285,7 +287,6 @@ def create_ifc_class(ifc_name, ifc_object, ifc_objects)

ifc_attributes = get_ifc_attributes(ifc_object, ifc_name)


if mixin && mixin.respond_to?(:required_attributes)
ifc_attributes.concat(mixin.required_attributes)
ifc_attributes.uniq!
Expand Down

0 comments on commit 851fca0

Please sign in to comment.