// Fill out your copyright notice in the Description page of Project Settings.


#include "BFL_Coordinate.h"
#include "Math/UnrealMathUtility.h"

FVector2D UBFL_Coordinate::GCJ02ToWGS84(double Longitude, double Latitude)
{
	const FVector2D Coord(Longitude, Latitude);

	if (IsOutOfChina(Coord))
	{
		return Coord; // 中国境外直接返回原坐标
	}

	// 计算偏移量
	const double dLng = TransformLongitude(Longitude - 105.0, Latitude - 35.0);
	const double dLat = TransformLatitude(Longitude - 105.0, Latitude - 35.0);

	const double radLat = FMath::DegreesToRadians(Latitude);
	const double magic = FMath::Sin(radLat);
	const double sqrtMagic = FMath::Sqrt(1 - ee * magic * magic);

	// 计算精确偏移
	const double finalDLat = (dLat * 180.0) / ((a * (1 - ee)) / (sqrtMagic * (1 - ee * magic * magic)) * PI);
	const double finalDLng = (dLng * 180.0) / (a / sqrtMagic * FMath::Cos(radLat) * PI);

	// 计算墨卡托投影坐标
	const double mgLat = Latitude + finalDLat;
	const double mgLng = Longitude + finalDLng;

	// 返回WGS84坐标
	return FVector2D(
		Longitude * 2 - mgLng,
		Latitude * 2 - mgLat
	);
}

bool UBFL_Coordinate::IsOutOfChina(const FVector2D& Coord)
{
	return !(Coord.X >= 72.004 && Coord.X <= 137.8347 &&
		Coord.Y >= 0.8293 && Coord.Y <= 55.8271);
}

double UBFL_Coordinate::TransformLatitude(double lng, double lat)
{
	double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat +
		0.1 * lng * lat + 0.2 * FMath::Sqrt(FMath::Abs(lng));

	ret += (20.0 * FMath::Sin(6.0 * lng * PI) +
		20.0 * FMath::Sin(2.0 * lng * PI)) * 2.0 / 3.0;

	ret += (20.0 * FMath::Sin(lat * PI) +
		40.0 * FMath::Sin(lat / 3.0 * PI)) * 2.0 / 3.0;

	ret += (160.0 * FMath::Sin(lat / 12.0 * PI) +
		320.0 * FMath::Sin(lat * PI / 30.0)) * 2.0 / 3.0;

	return ret;
}

double UBFL_Coordinate::TransformLongitude(double lng, double lat)
{
	double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng +
		0.1 * lng * lat + 0.1 * FMath::Sqrt(FMath::Abs(lng));

	ret += (20.0 * FMath::Sin(6.0 * lng * PI) +
		20.0 * FMath::Sin(lng * PI)) * 2.0 / 3.0;

	ret += (20.0 * FMath::Sin(lng * PI) +
		40.0 * FMath::Sin(lng / 3.0 * PI)) * 2.0 / 3.0;

	ret += (150.0 * FMath::Sin(lng / 12.0 * PI) +
		300.0 * FMath::Sin(lng / 30.0 * PI)) * 2.0 / 3.0;

	return ret;
}


FColor UBFL_Coordinate::HexToColor(FString HexString)
{
	return FColor::FromHex(HexString);
}

FString UBFL_Coordinate::ColorToHex(FColor Color)
{
	return Color.ToHex();
}