I’ve my OpenStreetMap knowledge exported utilizing QGIS as a gltf file, and I am making an attempt to align it with Cesium 3d tiles for my excessive decision mannequin.
The issue is that each have totally different coordinate programs:
After I import the gltf and drop it in my scene, each the fashions are misaligned. I attempted to align them collectively utilizing this C# script ChatGPT helped me write, however did not succeed:
utilizing UnityEngine;
utilizing System;
utilizing CesiumForUnity;
[ExecuteAlways]
public class PlaceModelCartographic : MonoBehaviour
{
[Header("Known EPSG:25832 (UTM Zone 32N) coordinates of reference point")]
public double easting = 680813.8264980253;
public double northing = 5779850.461563687;
public double heightEllipsoid = 165.098; // ellipsoidal meters
[Header("Manual alignment offsets")]
public Vector3 localOffsetMeters = Vector3.zero; // small nudge in native house
public float heightOffset = 0.0f; // regulate vertical misalignment
public float uniformScale = 1.0f; // repair scale mismatch
[Range(0.01f, 10f)]
public float scaleFactor = 1.0f;
non-public CesiumForUnity.CesiumGlobeAnchor anchor;
void OnValidate()
{
UpdatePlacement();
}
void UpdatePlacement()
{
// Guarantee anchor exists
if (anchor == null)
{
anchor = GetComponent();
if (anchor == null)
anchor = gameObject.AddComponent();
}
double latDeg, lonDeg;
Epsg25832Utility.UtmToLatLonDegrees(easting, northing, out latDeg, out lonDeg);
anchor.latitude = latDeg;
anchor.longitude = lonDeg;
anchor.top = heightEllipsoid + heightOffset;
// Reset little one transforms
foreach (Remodel little one in remodel)
{
little one.localPosition = Vector3.zero;
little one.localRotation = Quaternion.id;
little one.localScale = Vector3.one * scaleFactor;
}
}
}
///
/// EPSG:25832 UTM → WGS84 lat/lon (levels).
///
static class Epsg25832Utility
{
const double a = 6378137.0; // GRS80
const double f = 1.0 / 298.257222101;
const double k0 = 0.9996;
const double FE = 500000.0;
const int ZONE = 32;
static readonly double LON0 = (ZONE * 6 - 183) * Mathf.Deg2Rad; // 9°E
public static void UtmToLatLonDegrees(double E, double N, out double latDeg, out double lonDeg)
{
double latRad, lonRad;
UtmToLatLonRadians(E, N, out latRad, out lonRad);
latDeg = latRad * Mathf.Rad2Deg;
lonDeg = lonRad * Mathf.Rad2Deg;
}
static void UtmToLatLonRadians(double E, double N, out double lat, out double lon)
{
double b = a * (1 - f);
double e2 = (a * a - b * b) / (a * a);
double ep2 = (a * a - b * b) / (b * b);
double x = (E - FE) / k0;
double y = N / k0;
double e1 = (1 - Mathf.Sqrt(1 - (float)e2)) / (1 + Mathf.Sqrt(1 - (float)e2));
double M = y;
double mu = M / (a * (1 - e2 / 4 - 3 * e2 * e2 / 64 - 5 * Mathf.Pow((float)e2, 3) / 256));
double J1 = (3 * e1 / 2 - 27 * Mathf.Pow((float)e1, 3) / 32);
double J2 = (21 * e1 * e1 / 16 - 55 * Mathf.Pow((float)e1, 4) / 32);
double J3 = (151 * Mathf.Pow((float)e1, 3) / 96);
double J4 = (1097 * Mathf.Pow((float)e1, 4) / 512);
double fp = mu + J1 * Mathf.Sin(2f * (float)mu) + J2 * Mathf.Sin(4f * (float)mu)
+ J3 * Mathf.Sin(6f * (float)mu) + J4 * Mathf.Sin(8f * (float)mu);
double sinfp = Mathf.Sin((float)fp);
double cosfp = Mathf.Cos((float)fp);
double tanfp = Mathf.Tan((float)fp);
double C1 = ep2 * cosfp * cosfp;
double T1 = tanfp * tanfp;
double N1 = a / Math.Sqrt(1 - e2 * sinfp * sinfp);
double R1 = N1 * (1 - e2) / (1 - e2 * sinfp * sinfp);
double D = x / N1;
lat = fp - (N1 * tanfp / R1) * (
(D * D) / 2
- (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * ep2) * Mathf.Pow((float)D, 4) / 24
+ (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * ep2 - 3 * C1 * C1) * Mathf.Pow((float)D, 6) / 720
);
lon = LON0 + (
D
- (1 + 2 * T1 + C1) * Mathf.Pow((float)D, 3) / 6
+ (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * ep2 + 24 * T1 * T1) * Mathf.Pow((float)D, 5) / 120
) / cosfp;
}
}