1
1
#include " SplineToolsEditorComponent.h"
2
- #include " AzCore/Debug/Trace.h"
3
2
4
3
#include < AzCore/Component/TransformBus.h>
5
- #include < AzCore/IO/Path/Path.h>
6
4
#include < AzCore/Serialization/EditContext.h>
7
- #include < AzFramework/Physics/Common/PhysicsTypes.h>
8
- #include < AzToolsFramework/API/EditorAssetSystemAPI.h>
5
+ #include < AzToolsFramework/UI/UICore/WidgetHelpers.h>
9
6
#include < LmbrCentral/Shape/SplineComponentBus.h>
7
+ #include < QFileDialog>
8
+ #include < QMessageBox>
9
+ #include < ROS2/Georeference/GeoreferenceBus.h>
10
+ #include < ROS2/Georeference/GeoreferenceStructures.h>
10
11
#include < csv/csv.hpp>
11
12
12
13
namespace SplineTools
@@ -23,10 +24,8 @@ namespace SplineTools
23
24
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
24
25
if (serializeContext)
25
26
{
26
- serializeContext->Class <SplineToolsEditorComponent, AzToolsFramework::Components::EditorComponentBase>()
27
- ->Version (2 )
28
- ->Field (" CsvAssetId" , &SplineToolsEditorComponent::m_csvAssetId)
29
- ->Field (" IsLocalCoordinates" , &SplineToolsEditorComponent::m_isLocalCoordinates);
27
+ serializeContext->Class <SplineToolsEditorComponent, AzToolsFramework::Components::EditorComponentBase>()->Version (2 )->Field (
28
+ " IsLocalCoordinates" , &SplineToolsEditorComponent::m_isLocalCoordinates);
30
29
31
30
AZ::EditContext* editContext = serializeContext->GetEditContext ();
32
31
if (editContext)
@@ -41,9 +40,7 @@ namespace SplineTools
41
40
&SplineToolsEditorComponent::m_isLocalCoordinates,
42
41
" Local coordinates" ,
43
42
" Local coordinates" )
44
- ->DataElement (AZ::Edit::UIHandlers::Default, &SplineToolsEditorComponent::m_csvAssetId, " CSV Asset" , " CSV asset" )
45
- ->Attribute (AZ::Edit::Attributes::SourceAssetFilterPattern, " *.csv" )
46
- ->UIElement (AZ::Edit::UIHandlers::Button, " Reload spline" , " Reload spline" )
43
+ ->UIElement (AZ::Edit::UIHandlers::Button, " Load spline" , " Load spline" )
47
44
->Attribute (AZ::Edit::Attributes::ButtonText, " Load" )
48
45
->Attribute (AZ::Edit::Attributes::ChangeNotify, &SplineToolsEditorComponent::ReloadCSVAsset)
49
46
->Attribute (AZ::Edit::Attributes::NameLabelOverride, " " )
@@ -74,20 +71,16 @@ namespace SplineTools
74
71
LmbrCentral::SplineComponentRequestBus::EventResult (
75
72
splinePtr, GetEntityId (), &LmbrCentral::SplineComponentRequestBus::Events::GetSpline);
76
73
auto vertices = splinePtr->GetVertices ();
77
- using AssetSysReqBus = AzToolsFramework::AssetSystemRequestBus;
78
- AZ::Data::AssetInfo sourceAssetInfo;
79
- bool ok{ false };
80
- AZStd::string watchFolder;
81
- AZStd::vector<AZ::Data::AssetInfo> productsAssetInfo;
82
-
83
- AssetSysReqBus::BroadcastResult (
84
- ok, &AssetSysReqBus::Events::GetSourceInfoBySourceUUID, m_csvAssetId.m_guid , sourceAssetInfo, watchFolder);
85
- if (!ok)
74
+
75
+ QString fileName = QFileDialog::getSaveFileName (AzToolsFramework::GetActiveWindow (), " Open CSV File" , " " , " CSV Files (*.csv)" );
76
+
77
+ if (fileName.isEmpty ())
86
78
{
87
- AZ_Error ( " SplineToolsEditorComponent " , false , " Failed to get source info for referenced CSV asset. Saving aborted " );
79
+ QMessageBox::warning ( AzToolsFramework::GetActiveWindow (), " Error " , " Please specify file " , QMessageBox::Ok );
88
80
return ;
89
81
}
90
- const AZ::IO::Path sourcePath = AZ::IO::Path (watchFolder) / AZ::IO::Path (sourceAssetInfo.m_relativePath );
82
+
83
+ const AZ::IO::Path sourcePath = AZ::IO::Path (fileName.toUtf8 ().constData ());
91
84
92
85
if (!m_isLocalCoordinates)
93
86
{
@@ -103,33 +96,40 @@ namespace SplineTools
103
96
return worldTm.TransformPoint (point);
104
97
});
105
98
}
106
- AZ_Printf (" SplineToolsEditorComponent" , " Save CSV asset to %s" , sourceAssetInfo. m_relativePath .c_str ());
99
+ AZ_Printf (" SplineToolsEditorComponent" , " Save CSV asset to %s" , sourcePath .c_str ());
107
100
SavePointsToCsv (sourcePath.c_str (), vertices);
108
101
}
109
102
110
103
void SplineToolsEditorComponent::ReloadCSVAsset ()
111
104
{
112
- using AssetSysReqBus = AzToolsFramework::AssetSystemRequestBus;
113
- AZ::Data::AssetInfo sourceAssetInfo;
114
- bool ok{ false };
115
- AZStd::string watchFolder;
116
- AZStd::vector<AZ::Data::AssetInfo> productsAssetInfo;
117
-
118
- AssetSysReqBus::BroadcastResult (
119
- ok, &AssetSysReqBus::Events::GetSourceInfoBySourceUUID, m_csvAssetId.m_guid , sourceAssetInfo, watchFolder);
120
- const AZ::IO::Path sourcePath = AZ::IO::Path (watchFolder) / AZ::IO::Path (sourceAssetInfo.m_relativePath );
105
+ QString fileName = QFileDialog::getOpenFileName (AzToolsFramework::GetActiveWindow (), " Open CSV File" , " " , " CSV Files (*.csv)" );
121
106
107
+ if (fileName.isEmpty ())
108
+ {
109
+ QMessageBox::warning (AzToolsFramework::GetActiveWindow (), " Error" , " Please specify file" , QMessageBox::Ok);
110
+ return ;
111
+ }
112
+ AZStd::string sourcePath = AZStd::string (fileName.toUtf8 ().constData ());
122
113
AZ_Printf (" SplineToolsEditorComponent" , " Reload csv asset from %s" , sourcePath.c_str ());
123
114
124
115
auto points = GetSplinePointsFromCsv (sourcePath.c_str ());
125
116
126
117
if (points.empty ())
127
118
{
128
119
AZ_Error (" SplineToolsEditorComponent" , false , " No points found in CSV file" );
120
+ QMessageBox::warning (AzToolsFramework::GetActiveWindow (), " Error" , " No points found in CSV file" , QMessageBox::Ok);
129
121
return ;
130
122
}
131
123
132
124
AZ::Transform worldInvTm (AZ::Transform::Identity ());
125
+ if (m_isLocalCoordinates && m_isCoordinateLatLon)
126
+ {
127
+ AZ_Error (" SplineToolsEditorComponent" , false , " Cannot use lat, lon, alt coordinates in local coordinates" );
128
+ QMessageBox::warning (
129
+ AzToolsFramework::GetActiveWindow (), " Error" , " Cannot use lat, lon, alt coordinates in local coordinates" , QMessageBox::Ok);
130
+ return ;
131
+ }
132
+
133
133
if (!m_isLocalCoordinates)
134
134
{
135
135
AZ::TransformBus::EventResult (worldInvTm, GetEntityId (), &AZ::TransformBus::Events::GetWorldTM);
@@ -178,41 +178,87 @@ namespace SplineTools
178
178
179
179
AZStd::vector<AZ::Vector3> SplineToolsEditorComponent::GetSplinePointsFromCsv (const AZStd::string& csvFilePath)
180
180
{
181
+ auto getOptionalColumn = [](int column) -> AZStd::optional<int >
182
+ {
183
+ if (column < 0 )
184
+ {
185
+ return AZStd::nullopt ;
186
+ }
187
+ return column;
188
+ };
189
+
181
190
try
182
191
{
183
192
AZStd::vector<AZ::Vector3> ret;
184
193
185
194
csv::CSVReader reader (csvFilePath.c_str ());
186
195
reader.get_col_names ();
187
196
188
- const int index_X = reader.index_of (" x" );
189
- const int index_Y = reader.index_of (" y" );
190
- const int index_Z = reader.index_of (" z" );
197
+ const auto indexX = getOptionalColumn (reader.index_of (" x" ));
198
+ const auto indexY = getOptionalColumn (reader.index_of (" y" ));
199
+ const auto indexZ = getOptionalColumn (reader.index_of (" z" ));
200
+
201
+ const auto indexLat = getOptionalColumn (reader.index_of (" lat" ));
202
+ const auto indexLon = getOptionalColumn (reader.index_of (" lon" ));
203
+ const auto indexAlt = getOptionalColumn (reader.index_of (" alt" ));
204
+
205
+ m_isCoordinateXY = indexX && indexY;
206
+ m_isCoordinateLatLon = indexLat && indexLon && indexAlt;
207
+ const bool isCoordinateCorrect = (m_isCoordinateLatLon || m_isCoordinateXY);
191
208
192
- const bool isCoordinateCorrect = !(index_X < 0 || index_Y < 0 );
193
209
if (!isCoordinateCorrect)
194
210
{
195
- AZ_Error (" SplineToolsEditorComponent" , false , " CSV file must have columns named x, y" );
211
+ AZ_Error (" SplineToolsEditorComponent" , false , " CSV file must have columns named x, y or lat, lon, alt" );
212
+ AZStd::string columns;
213
+ for (const auto & columnName : reader.get_col_names ())
214
+ {
215
+ columns += AZStd::string (columnName.c_str ()) + " , " ;
216
+ }
217
+ AZ_Printf (" SplineToolsEditorComponent" , " CSV file columns: %s" , columns.c_str ());
218
+ QMessageBox::warning (
219
+ AzToolsFramework::GetActiveWindow (),
220
+ " Error" ,
221
+ " CSV file must have columns named x, y or lat, lon, alt" ,
222
+ QMessageBox::Ok);
196
223
return {};
197
224
}
198
225
199
- for (csv::CSVRow& row : reader )
226
+ if (m_isCoordinateXY )
200
227
{
201
- AZ::Vector3 point = AZ::Vector3 (row[index_X].get <float >(), row[index_Y].get <float >(), 0 );
228
+ for (csv::CSVRow& row : reader)
229
+ {
230
+ AZ::Vector3 point = AZ::Vector3 (row[*indexX].get <float >(), row[*indexY].get <float >(), 0 );
231
+
232
+ if (indexZ > 0 )
233
+ {
234
+ point.SetZ (row[*indexZ].get <float >());
235
+ }
202
236
203
- // handle Z column
204
- if (index_Z > 0 )
237
+ ret.emplace_back (AZStd::move (point));
238
+ }
239
+ }
240
+ else if (m_isCoordinateLatLon)
241
+ {
242
+ for (csv::CSVRow& row : reader)
205
243
{
206
- point.SetZ (row[index_Z].get <float >());
244
+ ROS2::WGS::WGS84Coordinate coordinate;
245
+ coordinate.m_latitude = row[*indexLat].get <double >();
246
+ coordinate.m_longitude = row[*indexLon].get <double >();
247
+ coordinate.m_altitude = row[*indexAlt].get <float >();
248
+ auto coordinateInLevel = AZ::Vector3 (-1 );
249
+ ROS2::GeoreferenceRequestsBus::BroadcastResult (
250
+ coordinateInLevel, &ROS2::GeoreferenceRequests::ConvertFromWGS84ToLevel, coordinate);
251
+
252
+ ret.emplace_back (AZStd::move (coordinateInLevel));
207
253
}
208
-
209
- ret.emplace_back (AZStd::move (point));
210
254
}
211
255
212
256
return ret;
213
257
} catch (std::runtime_error& exception)
214
258
{
215
- AZ_Error (" SplineToolsEditorComponent" , false , " Error parsing CSV file: %s" , exception.what ());
259
+ AZStd::string error = AZStd::string::format (" Error parsing CSV file: %s" , exception.what ());
260
+ AZ_Error (" SplineToolsEditorComponent" , false , error.c_str ());
261
+ QMessageBox::warning (AzToolsFramework::GetActiveWindow (), " Error" , error.c_str (), QMessageBox::Ok);
216
262
}
217
263
return {};
218
264
}
0 commit comments