Coverage for brodata / cpt.py: 81%
107 statements
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-13 12:57 +0000
« prev ^ index » next coverage.py v7.14.0, created at 2026-05-13 12:57 +0000
1import logging
2import tempfile
3from functools import partial
5import pandas as pd
7from . import bro
9logger = logging.getLogger(__name__)
12class ConePenetrationTest(bro.FileOrUrl):
13 """Class to represent a Cone Penetration Test (CPT) from the BRO."""
15 _rest_url = "https://publiek.broservices.nl/sr/cpt/v1"
16 _xmlns = "http://www.broservices.nl/xsd/dscpt/1.1"
17 _char = "CPT_C"
19 def _read_contents(self, tree):
20 ns = {
21 "brocom": "http://www.broservices.nl/xsd/brocommon/3.0",
22 "gml": "http://www.opengis.net/gml/3.2",
23 "cptcommon": "http://www.broservices.nl/xsd/cptcommon/1.1",
24 "xmlns": self._xmlns,
25 }
26 cpt = self._get_main_object(tree, "CPT_O", ns)
27 for key in cpt.attrib:
28 setattr(self, key.split("}", 1)[1], cpt.attrib[key])
29 for child in cpt:
30 key = self._get_tag(child)
31 if len(child) == 0:
32 setattr(self, key, child.text)
33 elif key == "standardizedLocation":
34 self._read_standardized_location(child)
35 elif key == "deliveredLocation":
36 self._read_delivered_location(child)
37 elif key in ["researchReportDate"]:
38 setattr(self, key, self._read_date(child))
39 elif key in ["deliveredVerticalPosition", "registrationHistory"]:
40 self._read_children_of_children(child)
41 elif key in ["conePenetrometerSurvey"]:
42 for grandchild in child:
43 key = self._get_tag(grandchild)
44 if len(grandchild) == 0:
45 setattr(self, key, grandchild.text)
46 elif key in [
47 "finalProcessingDate",
48 "trajectory",
49 "conePenetrometer",
50 "procedure",
51 ]:
52 self._read_children_of_children(grandchild)
53 elif key == "parameters":
54 self._read_parameters(grandchild)
55 elif key == "conePenetrationTest":
56 self._read_cone_penetration_test(grandchild, key)
57 elif key == "dissipationTest":
58 self._read_cone_penetration_test(grandchild, key)
59 else:
60 self._warn_unknown_tag(key)
61 elif key == "additionalInvestigation":
62 self._read_additional_investigation(child)
63 else:
64 self._warn_unknown_tag(key)
65 if hasattr(self, "conePenetrationTest") and hasattr(self, "parameters"):
66 self.conePenetrationTest.columns = self.parameters.index
67 if "penetrationLength" in self.conePenetrationTest.columns:
68 self.conePenetrationTest = self.conePenetrationTest.set_index(
69 "penetrationLength"
70 )
72 def _read_parameters(self, node):
73 self.parameters = pd.Series()
74 for child in node:
75 key = self._get_tag(child)
76 self.parameters[key] = child.text
78 def _read_cone_penetration_test(self, node, name):
79 for child in node:
80 key = self._get_tag(child)
81 if key in ["phenomenonTime", "resultTime"]:
82 setattr(self, f"{name}_{key}", self._read_time_instant(child))
83 elif key in [
84 "procedure",
85 "observedProperty",
86 "featureOfInterest",
87 "penetrationLength",
88 ]:
89 self._read_children_of_children(child)
90 elif key in ["cptResult", "disResult"]:
91 setattr(self, name, self._read_data_array(child))
92 else:
93 self._warn_unknown_tag(key)
95 def _read_additional_investigation(self, node):
96 for child in node:
97 key = self._get_tag(child)
98 if len(child) == 0:
99 setattr(self, key, child.text)
100 elif key == "removedLayer":
101 if not hasattr(self, key):
102 self.removedLayer = []
103 d = {}
104 self._read_children_of_children(
105 child,
106 d=d,
107 to_float=["upperBoundary", "lowerBoundary"],
108 to_int="sequenceNumber",
109 )
110 self.removedLayer.append(d)
111 if hasattr(self, "removedLayer"):
112 self.removedLayer = pd.DataFrame(self.removedLayer)
113 if "sequenceNumber" in self.removedLayer.columns:
114 self.removedLayer = self.removedLayer.set_index("sequenceNumber")
117def get_graph_types(timeout=5):
118 """
119 Get the graph types that can be generated for CPT by the REST API of the BRO.
121 Parameters
122 ----------
123 timeout : int or float, optional
124 A number indicating how many seconds to wait for the client to make a connection
125 and/or send a response. The default is 5.
127 Returns
128 -------
129 pd.DataFrame
130 A Pandas DataFrame that contains the supported graph types, with the columns
131 'name' and 'description'. The index of this DataFrame contains the strings that
132 can be used for the graphType-argument in nlmod.cpt.graph().
134 """
135 url = "https://publiek.broservices.nl/sr/cpt/v1/result/graph/types"
136 r = bro.util.get_with_rate_limit(url)
137 supported_graphs = r.json()["supportedGraphs"]
138 assert len(supported_graphs) == 1
139 return pd.DataFrame(supported_graphs[0]["graphs"]).set_index("graphType")
142def graph(
143 xml_file, graphType="cptCombinedLength", to_file=None, timeout=5, return_fname=False
144):
145 """
146 Generate a svg-graph of a cpt-file (ConePenetrationTest).
148 Parameters
149 ----------
150 xml_file : str
151 The filename of the xml-file to generate a graphical representation of.
152 graphType : str, optional
153 The type of graph. Run `brodata.cpt.get_graph_types()` to view available graph
154 types. The default is "cptCombinedLength".
155 to_file : str, optional
156 The filename to save the svg-file to. The default is None.
157 timeout : int or float, optional
158 A number indicating how many seconds to wait for the client to make a connection
159 and/or send a response. The default is 5.
160 return_fname : bool, optional
161 If True, Return the filename of the svg-file. The default is False.
163 Returns
164 -------
165 IPython.display.SVG or str
166 A graphical representation of the svg-file or the filename of the svg-file.
168 """
169 url = "https://publiek.broservices.nl/sr/cpt/v1/result/graph/dispatch"
171 params = {"graphType": graphType}
172 with open(xml_file, "rb") as data:
173 r = bro.util.post_with_rate_limit(
174 url, data=data, timeout=timeout, params=params
175 )
176 r.raise_for_status()
177 if to_file is None:
178 to_file = tempfile.NamedTemporaryFile(suffix=".svg").name
179 with open(to_file, "w", encoding="utf-8") as f:
180 f.write(r.text)
181 if return_fname:
182 return to_file
183 else:
184 from IPython.display import SVG
186 return SVG(to_file)
189cl = ConePenetrationTest
191get_bro_ids_of_bronhouder = partial(bro._get_bro_ids_of_bronhouder, cl=cl)
192get_bro_ids_of_bronhouder.__doc__ = bro._get_bro_ids_of_bronhouder.__doc__
194get_data_for_bro_ids = partial(bro._get_data_for_bro_ids, cl)
195get_data_for_bro_ids.__doc__ = bro._get_data_for_bro_ids.__doc__
197get_characteristics = partial(bro._get_characteristics, cl)
198get_characteristics.__doc__ = bro._get_characteristics.__doc__
200get_data_in_extent = partial(bro._get_data_in_extent, cl)
201get_data_in_extent.__doc__ = bro._get_data_in_extent.__doc__