Skip to content

Instantly share code, notes, and snippets.

@terokorp
Last active November 14, 2023 05:12
Show Gist options
  • Save terokorp/0c275254ab527c4e4ea482d337e07fdc to your computer and use it in GitHub Desktop.
Save terokorp/0c275254ab527c4e4ea482d337e07fdc to your computer and use it in GitHub Desktop.
Gpx importer for Unity (Mapbox EditorLocationProviderLocationLog)
using System;
using System.Globalization;
using System.IO;
using System.Xml;
using UnityEditor.AssetImporters;
using UnityEngine;
[ScriptedImporter(1, "gpx")]
public class GpxImporter : ScriptedImporter
{
bool locationServiceEnabled = true;
bool locationServiceIntializing = false;
bool locationUpdated = true;
bool userheadingUpdated = false;
public string locationProvider = "unity";
public string locationProviderClass = "DeviceLocationProvider";
string timeDevice = "20230101-000000.000";
string timeLocation = "20230101-000000.000";
double latitude = 62.2506826;
double longitude = 25.7415275;
float? accuracy = null;
float? userHeading = null;
float? deviceOrientation = null;
float? speed = null;
bool? hasGpsFix = null;
int? satellitesUsed = null;
int? satellitesInView = null;
const string header = "#location service enabled;location service intializing;location updated;userheading updated;location provider;location provider class;time device [utc];time location [utc];latitude;longitude;accuracy [m];user heading [?];device orientation [?];speed [km/h];has gps fix;satellites used;satellites in view";
const string notSupportedString = "[not supported by provider]";
public override void OnImportAsset(AssetImportContext ctx)
{
string text = header + "\n";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(File.ReadAllText(ctx.assetPath));
XmlNodeList points = xmlDoc.GetElementsByTagName("trkpt");
foreach (XmlNode point in points)
{
var latAttribute = point.Attributes["lat"];
if (latAttribute.Value != null)
latitude = double.Parse(latAttribute.Value, CultureInfo.InvariantCulture);
var longAttribute = point.Attributes["lon"];
if (longAttribute.Value != null)
longitude = double.Parse(longAttribute.Value, CultureInfo.InvariantCulture);
foreach (XmlNode child in point.ChildNodes)
{
switch (child.Name)
{
case "time":
timeDevice = timeLocation = ParseTime(child.InnerText);
break;
case "extensions":
speed = ParseSpeed(child.ChildNodes);
break;
default:
break;
}
}
text += BuildLine(text, locationServiceEnabled, locationServiceIntializing, locationUpdated, userheadingUpdated, locationProvider, locationProviderClass, timeDevice, timeLocation, latitude, longitude, accuracy, userHeading, deviceOrientation, speed, hasGpsFix, satellitesUsed, satellitesInView);
}
ctx.AddObjectToAsset("Gpx cordinate data", new TextAsset(text));
}
private float? ParseSpeed(XmlNodeList nodes)
{
foreach (XmlNode extension in nodes)
{
switch (extension.Name)
{
case "speed":
var speedText = extension.InnerText;
if (float.TryParse(speedText, out float s))
return s;
break;
default:
break;
}
}
return null;
}
private string ParseTime(string timeText)
{
try
{
var dateTime = DateTime.Parse(timeText);
return dateTime.ToUniversalTime().ToString("yyyyMMdd-HHmmss.fff");
}
catch (Exception)
{
return timeText;
}
}
private static string BuildLine(string text, bool locationServiceEnabled, bool locationServiceIntializing, bool locationUpdated, bool userheadingUpdated, string locationProvider, string locationProviderClass, string timeDevice, string timeLocation, double latitude, double longitude, float? accuracy, float? userHeading, float? deviceOrientation, float? speed, bool? hasGpsFix, int? satellitesUsed, int? satellitesInView)
{
return string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10};{11};{12};{13};{14};{15};{16}\n",
locationServiceEnabled ? "True" : "False",
locationServiceIntializing ? "True" : "False",
locationUpdated ? "True" : "False",
userheadingUpdated ? "True" : "False",
locationProvider,
locationProviderClass,
timeDevice,
timeLocation,
latitude.ToString(CultureInfo.InvariantCulture),
longitude.ToString(CultureInfo.InvariantCulture),
accuracy.HasValue ? accuracy.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString,
userHeading.HasValue ? userHeading.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString,
deviceOrientation.HasValue ? deviceOrientation.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString,
speed.HasValue ? speed.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString,
hasGpsFix.HasValue ? (hasGpsFix.Value ? "1" : "0") : notSupportedString,
satellitesUsed.HasValue ? satellitesUsed.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString,
satellitesInView.HasValue ? satellitesInView.Value.ToString(CultureInfo.InvariantCulture) : notSupportedString
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment