Skip to content

Commit 09a43f1

Browse files
committed
get distance along alignment from station
New alignment api function to get the horizontal distance along an alignment from a station value
1 parent c176b9d commit 09a43f1

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

src/ifcopenshell-python/ifcopenshell/api/alignment/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from .create_horizontal_alignment_by_pi_method import create_horizontal_alignment_by_pi_method
5252
from .create_geometric_representation import create_geometric_representation
5353
from .create_vertical_alignment_by_pi_method import create_vertical_alignment_by_pi_method
54+
from .distance_along_from_station import distance_along_from_station
5455
from .get_alignment_layouts import get_alignment_layouts
5556
from .get_axis_subcontext import get_axis_subcontext
5657
from .get_basis_curve import get_basis_curve
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# IfcOpenShell - IFC toolkit and geometry engine
2+
# Copyright (C) 2025 Thomas Krijnen <thomas@aecgeeks.com>
3+
#
4+
# This file is part of IfcOpenShell.
5+
#
6+
# IfcOpenShell is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# IfcOpenShell is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
18+
19+
import ifcopenshell
20+
import ifcopenshell.api.alignment
21+
import ifcopenshell.api.nest
22+
import ifcopenshell.guid
23+
from ifcopenshell import entity_instance
24+
25+
26+
def distance_along_from_station(file: ifcopenshell.file, alignment: entity_instance, station: float) -> float:
27+
"""
28+
Given a station, returns the distance along the horizontal alignment.
29+
30+
If the alignment does not have stationing defined with an IfcReferent, the start of the alignment is assumed
31+
to be at station 0.0. That is, the station is the distance along.
32+
33+
.. note:: The current implementation does not account for station equations and assumes stationing is increasing along the alignment.
34+
35+
:param alignment: the alignment
36+
:param station: station value
37+
:return: distance along the horizontal alignment
38+
39+
Example:
40+
41+
.. code:: python
42+
43+
alignment = model.by_type("IfcAlignment")[0] # alignment with start station 1+00.00
44+
dist_along = ifcopenshell.api.alignment.distance_along_from_station(model,alignment=alignment,station=200.0)
45+
print(dist_along) # 100.00
46+
"""
47+
48+
start_station = 0.0
49+
components = ifcopenshell.util.element.get_components(alignment)
50+
for c in components:
51+
if c.is_a("IfcReferent") and ifcopenshell.util.element.get_predefined_type(c) == "STATION":
52+
start_station = ifcopenshell.util.element.get_pset(c, name="Pset_Stationing", prop="Station")
53+
break
54+
55+
dist_along = station - start_station
56+
return dist_along
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# IfcOpenShell - IFC toolkit and geometry engine
2+
# Copyright (C) 2025 Thomas Krijnen <thomas@aecgeeks.com>
3+
#
4+
# This file is part of IfcOpenShell.
5+
#
6+
# IfcOpenShell is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Lesser General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# IfcOpenShell is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Lesser General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Lesser General Public License
17+
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
18+
19+
import pytest
20+
import ifcopenshell.api.alignment
21+
import ifcopenshell.api.context
22+
23+
24+
def test_add_stationing_to_alignment():
25+
file = ifcopenshell.file(schema="IFC4X3_ADD2")
26+
project = file.createIfcProject(Name="Test")
27+
geometric_representation_context = ifcopenshell.api.context.add_context(file, context_type="Model")
28+
axis_model_representation_subcontext = ifcopenshell.api.context.add_context(
29+
file,
30+
context_type="Model",
31+
context_identifier="Axis",
32+
target_view="MODEL_VIEW",
33+
parent=geometric_representation_context,
34+
)
35+
36+
coordinates = [(500.0, 2500.0), (3340.0, 660.0), (4340.0, 5000.0), (7600.0, 4560.0), (8480.0, 2010.0)]
37+
radii = [(1000.0), (1250.0), (950.0)]
38+
vpoints = [(0.0, 100.0), (2000.0, 135.0), (5000.0, 105.0), (7400.0, 153.0), (9800.0, 105.0), (12800.0, 90.0)]
39+
lengths = [(1600.0), (1200.0), (2000.0), (800.0)]
40+
41+
alignment = ifcopenshell.api.alignment.create_alignment_by_pi_method(
42+
file, "TestAlignment", coordinates, radii, vpoints, lengths
43+
)
44+
45+
# test alignment without stationing referent
46+
assert ifcopenshell.api.alignment.distance_along_from_station(file, alignment, 500.0) == pytest.approx(500.0)
47+
48+
# add stationing referent
49+
ifcopenshell.api.alignment.add_stationing_to_alignment(file, alignment, 10000.0)
50+
51+
# Station 138+83.96
52+
assert ifcopenshell.api.alignment.distance_along_from_station(file, alignment, 13883.96) == pytest.approx(3883.96)
53+
54+
# Station 175+25.36
55+
assert ifcopenshell.api.alignment.distance_along_from_station(file, alignment, 17525.36) == pytest.approx(7525.36)

0 commit comments

Comments
 (0)