Hello,
I'm trying to import back the points exported as landXML to revit however im not getting the correct location. Please see below code and attached XML file. Thank you.
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements)
{
//Revit application data
UIApplication uiapp = revit.Application;
UIDocument uidoc = uiapp.ActiveUIDocument;
Application app = uiapp.Application;
Document doc = uidoc.Document;
uiapplication = uiapp;
uidocument = uidoc;
document = doc;
revitApplication = app;
externalCommand = revit;
//Run the command
// Show the file dialog to select an XML file
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "XML files (*.xml)|*.xml";
openFileDialog.Title = "Select a LandXML File";
// Check if the user selected a file
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// Get the selected file path
string path = openFileDialog.FileName;
// Parse the selected XML file
List<XYZ> points = ParseLandXMLFile(path);
// Translate points to Shared coordinates
List<XYZ> sharedPoints = TransformCoordinates(doc, points);
try
{
using (Transaction trans = new Transaction(doc, "Create Topography Surface"))
{
trans.Start();
TopographySurface surface = TopographySurface.Create(doc, NoncoincidentPoints(sharedPoints));
trans.Commit();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
return Result.Succeeded;
}
public static List<XYZ> TransformCoordinates(Document doc, List<XYZ> points)
{
List<XYZ> transformedPoints = new List<XYZ>();
// Retrieve the active project location position
ProjectPosition projectPosition = doc.ActiveProjectLocation.GetProjectPosition(XYZ.Zero);
// Loop through each point in the list
foreach (XYZ point in points)
{
// Convert each survey point to a relative point using the previously defined method
XYZ relativePoint = ConvertSurveyPointToRelativePoint(point, projectPosition);
transformedPoints.Add(relativePoint);
}
return transformedPoints;
}
private static XYZ ConvertSurveyPointToRelativePoint(XYZ surveyPoint, ProjectPosition projectPosition)
{
// Create the translation vector for the offsets
XYZ translationVector = new XYZ(projectPosition.EastWest, projectPosition.NorthSouth, projectPosition.Elevation);
// Inverse translation: subtract the translation vector from the Survey Point
XYZ relativePoint = surveyPoint - translationVector;
// Inverse rotation: rotate in the opposite direction of the ProjectPosition.Angle
Transform inverseRotationTransform = Transform.CreateRotation(XYZ.BasisZ, -projectPosition.Angle);
// Apply the inverse rotation to the translated point
relativePoint = inverseRotationTransform.OfPoint(relativePoint);
return relativePoint;
}
public static List<XYZ> NoncoincidentPoints(List<XYZ> points)
{
Dictionary<XYZ, int> dictionary = new Dictionary<XYZ, int>(new XyEqualityComparer());
foreach (XYZ xyz in points)
{
if (!dictionary.ContainsKey(xyz))
{
dictionary.Add(xyz, 1);
}
else
{
Dictionary<XYZ, int> dictionary2 = dictionary;
XYZ key = xyz;
int value = dictionary2[key] + 1;
dictionary2[key] = value;
}
}
return new List<XYZ>(dictionary.Keys);
}
private List<XYZ> ParseLandXMLFile(string path)
{
List<XYZ> points = new List<XYZ>();
XDocument doc = XDocument.Load(path);
XNamespace ns = doc.Root.GetDefaultNamespace();
var pointElements = doc.Descendants(ns + "P");
foreach (var pointElement in pointElements)
{
string[] coords = pointElement.Value.Split(' ');
if (coords.Length == 3)
{
//double x = Convert.ToDouble(coords[0]);
//double y = Convert.ToDouble(coords[1]);
//double z = Convert.ToDouble(coords[2]);
double x = Convert.ToDouble(coords[0]) * 3.28084;
double y = Convert.ToDouble(coords[1]) * 3.28084;
double z = Convert.ToDouble(coords[2]) * 3.28084;
//double x = Convert.ToDouble(coords[0]) / 3.28084;
//double y = Convert.ToDouble(coords[1]) / 3.28084;
//double z = Convert.ToDouble(coords[2]) / 3.28084;
points.Add(new XYZ(x, y, z));
}
}
return points;
}
What location is defined in the original file? What is the correct location? What is the wrong location? What transformation are you applying?
Hi Jeremy,
We are extracting points from Revit elements (which are in shared coordinates) and exporting them as an XML file to share with our team using Civil3D. The export process works fine, and they can use the file with the correct coordinates. However, during their workflow, they may modify some information, such as updating the TIN surface. When we try to import this updated information back into Revit, we encounter issues—the imported data from the Civil3D LandXML file doesn't align correctly with the original model. I attempted to use the code above (to transform points and convert to internal units), but it still hasn't resolved the problem.
Can't find what you're looking for? Ask the community or share your knowledge.