Unity小地图纬度/经度计算偏移量

问题描述 投票:0回答:1

我正在一个项目中担任实习生,该项目是一对一比例的荷兰城市:格罗宁根。

我的工作是制作(迷你)地图,所以我就这么做了。只有一个问题。在生成时,玩家和小地图的位置是对齐的,但距离生成点越远,这种对齐就越不准确。我希望有人可以帮助我并看看我做错了什么,因为我被困住了! 这是整个 miniMapManager。看着那(这 double[] 翻译坐标()

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using InfinityCode.OnlineMapsExamples;
using TMPro;
using SimpleJSON;
using UnityEngine.Networking;
using System.Globalization;
using Unity.Netcode;


public class miniMapManager : MonoBehaviour
{
public Button plusButton;
public Button minButton;
public Button mapButton;
public OnlineMaps map;
public OnlineMaps bigMap;
public GameObject bigMapContainer;
public GameObject miniMapContainer;
public OnlineMapsMarkerManager markerManager;
private bool bigMapActive = false;

public double lat = 53.218814f;
public double lon = 6.569044f;
private double latOffset = 0.0080574904785f; // x MIN DEZE waarde is lat
private double lonOffset = 0.04740894445801f; // x PLUS DEZE waarde is lon
public GameObject objectToFollow;
private PlayerManager playerManager;
private UserManager userManager;
private float r_earth = 6378137f;

public TMP_InputField searchInput;
public string nominatimBaseUrl = "https://nominatim.openstreetmap.org/search?format=json&q=";
public Button searchButton;

bool groningenFound = false;

double player_Lat;
double player_Lon;
public GameObject player_icon;
public float rotationSpeed = 10f;

List<Vector3> otherPlayerPositions = new List<Vector3>();

private void Start()
{
if (plusButton != null)
{
plusButton.onClick.AddListener(OnPlusButtonClick);
}

if (minButton != null)
{
minButton.onClick.AddListener(OnMinButtonClick);
}

if (mapButton != null)
{
mapButton.onClick.AddListener(OnMapButtonClick);
}

if (searchButton != null)
{
searchButton.onClick.AddListener(SetCoordinates);
// Debug.Log("search button geklikt");
}

userManager = UserManager.Instance;
}

void Update()
{
if (bigMapActive)
{
if (Input.GetKey(KeyCode.Escape))
{
BigMapClose();
}
}


if(PlayerManager.instance_exists){
playerManager = PlayerManager.Instance;
}

if (playerManager != null)
{
objectToFollow = playerManager.gameObject;
}
else
{
Debug.LogWarning("PlayerManager instance not found.");
}

// is de afwijking er niet omdat die latoffset en lonoffset er steeds opnieuw bijgegooid worden???
player_Lat = translateCoordinates()[0];
player_Lon = translateCoordinates()[1];

if(!bigMapActive){
map.SetPosition(player_Lon, player_Lat);
}

// Voeg de positie van de lokale speler toe aan de lijst met andere spelerposities
otherPlayerPositions = userManager.GetOtherPlayerPositions(NetworkManager.Singleton.LocalClientId);
if(otherPlayerPositions != null){
UpdateOtherPlayerPositions(otherPlayerPositions);
Debug.Log(otherPlayerPositions);
}


if (PlayerManager.Instance != null && player_icon != null)
{
// Zoek het gameobject met de naam "Prefab_Player(Clone)"
GameObject prefabPlayer = GameObject.Find("Prefab_Player(Clone)");

if (prefabPlayer != null)
{
Debug.LogWarning("Alles gevonden, nu nog roteren.");

// Gebruik de rotatie van het specifieke gameobject
Quaternion playerRotation = prefabPlayer.transform.rotation;

// Pas de rotatie toe op player_icon, let op het gebruik van localRotation
player_icon.GetComponent<RectTransform>().localRotation = playerRotation;
Debug.LogWarning("Rotatie toegepast op player_icon.");
}
else
{
Debug.LogWarning("Prefab_Player(Clone) not found.");
}
}
else
{
Debug.LogWarning("Player manager en/of icon not found.");
}
}

public void UpdateOtherPlayerPositions(List<Vector3> playerPositions)
{
// Verwijder eerst alle bestaande markers op de kaart
// markerManager.RemoveAll();

foreach (Vector3 position in playerPositions)
{
double dLat = position.z / r_earth;
double dLon = position.x / (r_earth * Mathf.Cos(Mathf.Deg2Rad * (float)lat));

double[] result = new double[2];

result[0] = lat - dLat * 180.0 / Mathf.PI - latOffset;
result[1] = lon - dLon * 180.0 / Mathf.PI + lonOffset;

// Creëer een marker voor elke andere speler op de kaart
markerManager.Create(result[1], result[0]);
}
}

double[] translateCoordinates()
{
Debug.LogWarning(lat);
Debug.LogWarning((float)lat);

double dLat = objectToFollow.transform.localPosition.z / r_earth;
// 3.1455
double dLon = objectToFollow.transform.localPosition.x / (r_earth * Mathf.Cos(Mathf.Deg2Rad * (float)lat));
// 3.15

double[] result = new double[2];

result[0] = lat - dLat * 180.0 / Mathf.PI - latOffset;
result[1] = lon - dLon * 180.0 / Mathf.PI + lonOffset;

return result;
}

private void OnPlusButtonClick()
{
// Debug.Log("Zoom in button");
map.zoom = Mathf.Clamp(map.zoom + 1, 3, 20);
}

private void OnMinButtonClick()
{
// Debug.Log("Zoom out button");
map.zoom = Mathf.Clamp(map.zoom - 1, 3, 20);
}

private void OnMapButtonClick()
{
bigMapContainer.SetActive(true);
miniMapContainer.SetActive(false);
bigMapActive = true;
bigMap.SetPosition(player_Lon, player_Lat);
bigMap.zoom = 16;
}

private void BigMapClose()
{
bigMapContainer.SetActive(false);
miniMapContainer.SetActive(true);
bigMapActive = false;

}

[System.Obsolete]
public void SetCoordinates()
{
string location = searchInput.text;

StartCoroutine(GeocodeLocation(location));
}

[System.Obsolete]
IEnumerator GeocodeLocation(string location)
{
string url = nominatimBaseUrl + WWW.EscapeURL(location);

using (UnityWebRequest webRequest = UnityWebRequest.Get(url))
{
yield return webRequest.SendWebRequest();

if (webRequest.isNetworkError || webRequest.isHttpError)
{
Debug.LogError("Error: " + webRequest.error);
}
else
{
string json = webRequest.downloadHandler.text;
JSONNode parsedData = JSON.Parse(json);
// Debug.Log("request is gemaakt");
Debug.Log(parsedData);

if (parsedData.Count > 0)
{
// Debug.Log("Data is geparsed en opgehaald");
double newLat = parsedData[0]["lat"].AsDouble;
double newLon = parsedData[0]["lon"].AsDouble;

float newLatFloat = (float)newLat; // Zet double om naar float
float newLonFloat = (float)newLon; // Zet double om naar float

bigMap.SetPosition(newLonFloat, newLatFloat);

// if (CheckForGroningen(parsedData))
// {
// bigMap.SetPosition(newLonFloat, newLatFloat);
// }
// else
// {
// Debug.LogWarning("Dit is niet in Groningen.");
// }
}
}
}
}
}

这也是发生的视频: https://www.youtube.com/watch?v=4Ntnau6nlz0

如你所见,我计算了 m 的 x/z 位置,并据此给出了纬度/经度,但有些地方出了问题。

c# unity-game-engine maps
1个回答
0
投票

这是一个疯狂的猜测,但您是否尝试过使用

double
进行所有计算?这可能不是全部问题,但至少应该减少影响。

当前您正在使用

Mathf
,它使用
float
(请参阅Mathf的源代码)。

=> 可能会到处引入舍入问题,这种比例的 GPS 坐标和纬度/经度需要很高的精度!

如果你查看Mathf的源代码,它主要使用

System.Math
,然后转换为
float

=> 只需坚持自己使用

System.Math
,而在事物不存在的情况下(例如
RadToDegree
),请使用您自己的基于
double
的值:

public const double Deg2Rad = Math.PI * 2.0 / 360.0;

public const double Rad2Deg = 1.0 / Deg2Rad;

等等

© www.soinside.com 2019 - 2024. All rights reserved.