mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 19:27:10 +00:00
Refactor geolocation MicroMVD definitions
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
from behave import step
|
from behave import step
|
||||||
from utils import IfcFile
|
from utils import IfcFile, assert_number, assert_pset, assert_attribute
|
||||||
import math
|
import math
|
||||||
import ifcopenshell.util
|
import ifcopenshell.util
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
@@ -9,18 +9,6 @@ def step_impl(context, ifc_class):
|
|||||||
assert len(IfcFile.get().by_type(ifc_class)) >= 1, 'An element of {} could not be found'.format(ifc_class)
|
assert len(IfcFile.get().by_type(ifc_class)) >= 1, 'An element of {} could not be found'.format(ifc_class)
|
||||||
|
|
||||||
|
|
||||||
def check_ifc2x3_geolocation(pset_name, prop_name=None, value=None):
|
|
||||||
for site in IfcFile.get().by_type('IfcSite'):
|
|
||||||
psets = ifcopenshell.util.element.get_psets(site)
|
|
||||||
if pset_name not in psets:
|
|
||||||
assert False, 'The site {} does not have a property set named {}'.format(site, pset_name)
|
|
||||||
if not prop_name:
|
|
||||||
continue
|
|
||||||
if prop_name not in psets[pset_name]:
|
|
||||||
assert False, 'The site {} does not have a property named "{}" in {}'.format(site, prop_name, pset_name)
|
|
||||||
actual_value = psets[pset_name][prop_name]
|
|
||||||
assert actual_value == value, 'We expected a value of "{}" but instead got "{}"'.format(value, actual_value)
|
|
||||||
|
|
||||||
def check_ifc4_geolocation(entity_name, prop_name=None, value=None, should_assert=True):
|
def check_ifc4_geolocation(entity_name, prop_name=None, value=None, should_assert=True):
|
||||||
if entity_name not in IfcFile.bookmarks:
|
if entity_name not in IfcFile.bookmarks:
|
||||||
has_entity = False
|
has_entity = False
|
||||||
@@ -53,56 +41,72 @@ def check_ifc4_geolocation(entity_name, prop_name=None, value=None, should_asser
|
|||||||
@step(u'The project must have coordinate reference system data')
|
@step(u'The project must have coordinate reference system data')
|
||||||
def step_impl(context):
|
def step_impl(context):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS')
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS')
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS')
|
check_ifc4_geolocation('IfcProjectedCRS')
|
||||||
|
|
||||||
|
|
||||||
@step(u'The name of the CRS must be {coordinate_reference_name}')
|
@step(u'The name of the CRS must be {coordinate_reference_name}')
|
||||||
def step_impl(context, coordinate_reference_name):
|
def step_impl(context, coordinate_reference_name):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'Name', coordinate_reference_name)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'Name', coordinate_reference_name)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'Name', coordinate_reference_name)
|
check_ifc4_geolocation('IfcProjectedCRS', 'Name', coordinate_reference_name)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The description of the CRS must be {value}')
|
@step(u'The description of the CRS must be {value}')
|
||||||
def step_impl(context, value):
|
def step_impl(context, value):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'Description', value)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'Description', value)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'Description', value)
|
check_ifc4_geolocation('IfcProjectedCRS', 'Description', value)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The geodetic datum must be {coordinate_reference_name}')
|
@step(u'The geodetic datum must be {coordinate_reference_name}')
|
||||||
def step_impl(context, coordinate_reference_name):
|
def step_impl(context, coordinate_reference_name):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'GeodeticDatum', coordinate_reference_name)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'GeodeticDatum', coordinate_reference_name)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'GeodeticDatum', coordinate_reference_name)
|
check_ifc4_geolocation('IfcProjectedCRS', 'GeodeticDatum', coordinate_reference_name)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The vertical datum must be {coordinate_reference_name}')
|
@step(u'The vertical datum must be {coordinate_reference_name}')
|
||||||
def step_impl(context, coordinate_reference_name):
|
def step_impl(context, coordinate_reference_name):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'VerticalDatum', coordinate_reference_name)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'VerticalDatum', coordinate_reference_name)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'VerticalDatum', coordinate_reference_name)
|
check_ifc4_geolocation('IfcProjectedCRS', 'VerticalDatum', coordinate_reference_name)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The map projection must be {coordinate_reference_name}')
|
@step(u'The map projection must be {coordinate_reference_name}')
|
||||||
def step_impl(context, coordinate_reference_name):
|
def step_impl(context, coordinate_reference_name):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'MapProjection', coordinate_reference_name)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'MapProjection', coordinate_reference_name)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'MapProjection', coordinate_reference_name)
|
check_ifc4_geolocation('IfcProjectedCRS', 'MapProjection', coordinate_reference_name)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The map zone must be {coordinate_reference_name}')
|
@step(u'The map zone must be {coordinate_reference_name}')
|
||||||
def step_impl(context, coordinate_reference_name):
|
def step_impl(context, coordinate_reference_name):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'MapZone', coordinate_reference_name)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'MapZone', coordinate_reference_name)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcProjectedCRS', 'MapZone', coordinate_reference_name)
|
check_ifc4_geolocation('IfcProjectedCRS', 'MapZone', coordinate_reference_name)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The map unit must be {unit}')
|
@step(u'The map unit must be {unit}')
|
||||||
def step_impl(context, unit):
|
def step_impl(context, unit):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_ProjectedCRS', 'MapUnit', unit)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_ProjectedCRS', 'MapUnit', unit)
|
||||||
|
return
|
||||||
actual_value = check_ifc4_geolocation('IfcProjectedCRS', 'MapUnit', should_assert=False)
|
actual_value = check_ifc4_geolocation('IfcProjectedCRS', 'MapUnit', should_assert=False)
|
||||||
if actual_value.is_a('IfcSIUnit'):
|
if actual_value.is_a('IfcSIUnit'):
|
||||||
prefix = actual_value.Prefix if actual_value.Prefix else ''
|
prefix = actual_value.Prefix if actual_value.Prefix else ''
|
||||||
@@ -115,49 +119,44 @@ def step_impl(context, unit):
|
|||||||
@step(u'The project must have coordinate transformations to convert from local to global coordinates')
|
@step(u'The project must have coordinate transformations to convert from local to global coordinates')
|
||||||
def step_impl(context):
|
def step_impl(context):
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion')
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_MapConversion')
|
||||||
check_ifc4_geolocation('IfcMapConversion')
|
check_ifc4_geolocation('IfcMapConversion')
|
||||||
|
|
||||||
|
|
||||||
@step(u'The eastings of the model must be offset by {number} to derive its global coordinates')
|
@step(u'The eastings of the model must be offset by {number} to derive its global coordinates')
|
||||||
def step_impl(context, number):
|
def step_impl(context, number):
|
||||||
try:
|
number = assert_number(number)
|
||||||
number = float(number)
|
|
||||||
except:
|
|
||||||
assert False, 'A number should be specified, not {}'.format(number)
|
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion', 'Eastings', number)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_MapConversion', 'Eastings', number)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcMapConversion', 'Eastings', number)
|
check_ifc4_geolocation('IfcMapConversion', 'Eastings', number)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The northings of the model must be offset by {number} to derive its global coordinates')
|
@step(u'The northings of the model must be offset by {number} to derive its global coordinates')
|
||||||
def step_impl(context, number):
|
def step_impl(context, number):
|
||||||
try:
|
number = assert_number(number)
|
||||||
number = float(number)
|
|
||||||
except:
|
|
||||||
assert False, 'A number should be specified, not {}'.format(number)
|
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion', 'Northings', number)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_MapConversion', 'Northings', number)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcMapConversion', 'Northings', number)
|
check_ifc4_geolocation('IfcMapConversion', 'Northings', number)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The height of the model must be offset by {number} to derive its global coordinates')
|
@step(u'The height of the model must be offset by {number} to derive its global coordinates')
|
||||||
def step_impl(context, number):
|
def step_impl(context, number):
|
||||||
try:
|
number = assert_number(number)
|
||||||
number = float(number)
|
|
||||||
except:
|
|
||||||
assert False, 'A number should be specified, not {}'.format(number)
|
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion', 'OrthogonalHeight', number)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_MapConversion', 'OrthogonalHeight', number)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcMapConversion', 'OrthogonalHeight', number)
|
check_ifc4_geolocation('IfcMapConversion', 'OrthogonalHeight', number)
|
||||||
|
|
||||||
|
|
||||||
@step(u'The model must be rotated clockwise by {number} to derive its global coordinates')
|
@step(u'The model must be rotated clockwise by {number} to derive its global coordinates')
|
||||||
def step_impl(context, number):
|
def step_impl(context, number):
|
||||||
try:
|
number = assert_number(number)
|
||||||
number = float(number)
|
|
||||||
except:
|
|
||||||
assert False, 'A number should be specified, not {}'.format(number)
|
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion', 'Height', number)
|
return check_ifc2x3_geolocation('EPset_MapConversion', 'Height', number)
|
||||||
abscissa = check_ifc4_geolocation('IfcMapConversion', 'XAxisAbscissa', should_assert=False)
|
abscissa = check_ifc4_geolocation('IfcMapConversion', 'XAxisAbscissa', should_assert=False)
|
||||||
@@ -170,10 +169,36 @@ def step_impl(context, number):
|
|||||||
|
|
||||||
@step(u'The model must be scaled along the horizontal axis by {number} to derive its global coordinates')
|
@step(u'The model must be scaled along the horizontal axis by {number} to derive its global coordinates')
|
||||||
def step_impl(context, number):
|
def step_impl(context, number):
|
||||||
try:
|
number = assert_number(number)
|
||||||
number = float(number)
|
|
||||||
except:
|
|
||||||
assert False, 'A number should be specified, not {}'.format(number)
|
|
||||||
if IfcFile.get().schema == 'IFC2X3':
|
if IfcFile.get().schema == 'IFC2X3':
|
||||||
return check_ifc2x3_geolocation('EPset_MapConversion', 'Scale', number)
|
for site in IfcFile.get().by_type('IfcSite'):
|
||||||
|
assert_pset(site, 'EPset_MapConversion', 'Scale', number)
|
||||||
|
return
|
||||||
check_ifc4_geolocation('IfcMapConversion', 'Scale', number)
|
check_ifc4_geolocation('IfcMapConversion', 'Scale', number)
|
||||||
|
|
||||||
|
|
||||||
|
@step(u'The site {guid} has a longitude of {number}')
|
||||||
|
def step_impl(context, guid, number):
|
||||||
|
number = assert_number(number)
|
||||||
|
site = IfcFile.by_guid(guid)
|
||||||
|
if not site.is_a('IfcSite'):
|
||||||
|
assert False, 'The element {} is not an IfcSite'.format(site)
|
||||||
|
assert_attribute(site, 'RefLongitude', number)
|
||||||
|
|
||||||
|
|
||||||
|
@step(u'The site {guid} has a latitude of {number}')
|
||||||
|
def step_impl(context, guid, number):
|
||||||
|
number = assert_number(number)
|
||||||
|
site = IfcFile.by_guid(guid)
|
||||||
|
if not site.is_a('IfcSite'):
|
||||||
|
assert False, 'The element {} is not an IfcSite'.format(site)
|
||||||
|
assert_attribute(site, 'RefLatitude', number)
|
||||||
|
|
||||||
|
|
||||||
|
@step(u'The site {guid} has an elevation of {number}')
|
||||||
|
def step_impl(context, guid, number):
|
||||||
|
number = assert_number(number)
|
||||||
|
site = IfcFile.by_guid(guid)
|
||||||
|
if not site.is_a('IfcSite'):
|
||||||
|
assert False, 'The element {} is not an IfcSite'.format(site)
|
||||||
|
assert_attribute(site, 'RefElevation', number)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
import ifcopenshell.util
|
||||||
|
import ifcopenshell.util.element
|
||||||
|
|
||||||
class IfcFile(object):
|
class IfcFile(object):
|
||||||
file = None
|
file = None
|
||||||
@@ -13,3 +15,35 @@ class IfcFile(object):
|
|||||||
if not cls.file:
|
if not cls.file:
|
||||||
assert False, 'No file was loaded, so this requirement cannot be checked'
|
assert False, 'No file was loaded, so this requirement cannot be checked'
|
||||||
return cls.file
|
return cls.file
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def by_guid(cls, guid):
|
||||||
|
try:
|
||||||
|
return cls.get().by_guid(guid)
|
||||||
|
except:
|
||||||
|
assert False, 'An element with the ID {} could not be found.'.format(guid)
|
||||||
|
|
||||||
|
def assert_number(number):
|
||||||
|
try:
|
||||||
|
return float(number)
|
||||||
|
except ValueError:
|
||||||
|
assert False, 'A number should be specified, not {}'.format(number)
|
||||||
|
|
||||||
|
def assert_attribute(element, name, value):
|
||||||
|
if not hasattr(element, name):
|
||||||
|
assert False, 'The element {} does not have the attribute {}'.format(element, name)
|
||||||
|
actual_value = getattr(element, name)
|
||||||
|
assert actual_value == value, 'We expected a value of "{}" but instead got "{}"'.format(value, actual_value)
|
||||||
|
|
||||||
|
def assert_pset(element, pset_name, prop_name=None, value=None):
|
||||||
|
psets = ifcopenshell.util.element.get_psets(site)
|
||||||
|
if pset_name not in psets:
|
||||||
|
assert False, 'The element {} does not have a property set named {}'.format(element, pset_name)
|
||||||
|
if prop_name is None:
|
||||||
|
return psets[pset_name]
|
||||||
|
if prop_name not in psets[pset_name]:
|
||||||
|
assert False, 'The element {} does not have a property named "{}" in the pset "{}"'.format(element, prop_name, pset_name)
|
||||||
|
if value is None:
|
||||||
|
return psets[pset_name][prop_name]
|
||||||
|
actual_value = psets[pset_name][prop_name]
|
||||||
|
assert actual_value == value, 'We expected a value of "{}" but instead got "{}"'.format(value, actual_value)
|
||||||
|
|||||||
Reference in New Issue
Block a user