Files
SHI-Cesium/Assets/Scripts/MeasureLine.cs
geondo55 968297d262 init
2025-09-11 18:05:50 +09:00

112 lines
3.5 KiB
C#

using UnityEngine;
using Unity.Mathematics;
using UnityEngine.InputSystem;
using CesiumForUnity;
public class MeasureLine : MonoBehaviour
{
public LineRenderer line; // LineRenderer 할당 (positionCount=2, Use World Space=true)
private CesiumGeoreference geoRef; // Cesium 지오리퍼런스
private Vector3? pointA = null;
private Vector3? pointB = null;
void Awake()
{
geoRef = GetComponent<CesiumGeoreference>();
if (line)
{
line.positionCount = 2;
line.enabled = false;
}
}
void Update()
{
// 신 Input System (Mouse.current) 사용
if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame)
{
if (TryGetClickPosition(out Vector3 unityPos))
{
if (pointA == null) // 첫 번째 점
{
pointA = unityPos;
pointB = null;
}
else if (pointB == null) // 두 번째 점
{
pointB = unityPos;
}
else // 세 번째 클릭 → 초기화
{
pointA = unityPos;
pointB = null;
}
}
}
DrawLineAndShowDistance();
}
bool TryGetClickPosition(out Vector3 pos)
{
Ray ray = Camera.main.ScreenPointToRay(Mouse.current.position.ReadValue());
if (Physics.Raycast(ray, out RaycastHit hit, 100000f))
{
pos = hit.point;
return true;
}
pos = Vector3.zero;
return false;
}
void DrawLineAndShowDistance()
{
if (pointA.HasValue && pointB.HasValue)
{
line.enabled = true;
line.SetPosition(0, pointA.Value);
line.SetPosition(1, pointB.Value);
float unityDist = Vector3.Distance(pointA.Value, pointB.Value);
var (lon1, lat1, h1) = GetLonLatHeight(pointA.Value);
var (lon2, lat2, h2) = GetLonLatHeight(pointB.Value);
double geoDist = Haversine(lat1, lon1, lat2, lon2);
Debug.Log(
$"Unity 거리: {unityDist:F2} m | 지구 곡면 거리: {geoDist:F2} m\n" +
$"점A 위도:{lat1:F6}, 경도:{lon1:F6}, 고도:{h1:F1} m\n" +
$"점B 위도:{lat2:F6}, 경도:{lon2:F6}, 고도:{h2:F1} m"
);
}
else
{
line.enabled = false;
}
}
(double lon, double lat, double height) GetLonLatHeight(Vector3 unityPos)
{
double3 ecef = geoRef.TransformUnityPositionToEarthCenteredEarthFixed(math.double3(unityPos));
double3 llh = CesiumWgs84Ellipsoid.EarthCenteredEarthFixedToLongitudeLatitudeHeight(ecef);
return (llh.x, llh.y, llh.z);
}
double Haversine(double lat1, double lon1, double lat2, double lon2)
{
double R = 6371000.0; // 지구 반경 (m)
double latRad1 = Mathf.Deg2Rad * (float)lat1;
double latRad2 = Mathf.Deg2Rad * (float)lat2;
double dLat = Mathf.Deg2Rad * (float)(lat2 - lat1);
double dLon = Mathf.Deg2Rad * (float)(lon2 - lon1);
double a = Mathf.Sin((float)dLat / 2) * Mathf.Sin((float)dLat / 2) +
Mathf.Cos((float)latRad1) * Mathf.Cos((float)latRad2) *
Mathf.Sin((float)dLon / 2) * Mathf.Sin((float)dLon / 2);
double c = 2 * Mathf.Atan2(Mathf.Sqrt((float)a), Mathf.Sqrt((float)(1 - a)));
return R * c;
}
}