Thanks a lot for the support, I post the code, in case it can be useful to someone.
Now I want to ask if someone know how to make the automatic zoom of the map, based on the coordinates entered?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Coordinate;
using System.Globalization;
public delegate void MyEventHandler();
public class CtrlCoordinate : MonoBehaviour
{
// delegate per richiamare un evento, una volta terminato di caricare la lista di punti
public event MyEventHandler OnEventTriggered;
string coordinateString = "(8.93266215617905 44.40604327943526, 8.932524131901832 44.40601228591227, 8.932359430658943 44.405996835286025, 8.93207661034279 44.40596474551083)";
public List<CoordinateStruct> coordinateList = new List<CoordinateStruct>();
public List<GameObject> PuntiList = new List<GameObject>();
public List<Texture> cubeTextures = new List<Texture>();
private static float scale = 10750000f;
public GameObject referenceObject;
public GameObject markerPrefab;
public Transform markerParent;
OnlineMapsMarkerManager onlineMaps;
// Start is called before the first frame update
void Start()
{
onlineMaps = GameObject.Find("Map").GetComponent<OnlineMapsMarkerManager>();
// All of this stuff is used to convert the string to float and serialize the class Coordinate for eac value from the array!
string modifiedCoordinaateString = coordinateString.Replace("(", "").Replace(")", "");
string[] coordinateArray = modifiedCoordinaateString.Split(new string[] { ", " }, StringSplitOptions.None);
foreach (string coordinatePair in coordinateArray)
{
string[] coordinateValues = coordinatePair.Split(' ');
decimal decimLongitude = decimal.Parse(coordinateValues[0], CultureInfo.InvariantCulture);
decimal decimLatitude = decimal.Parse(coordinateValues[1], CultureInfo.InvariantCulture);
float longitude = (float)decimal.Round(decimLongitude, 6);
float latitude = (float)decimal.Round(decimLatitude, 6);
CoordinateStruct coordinate = new CoordinateStruct(latitude, longitude);
coordinateList.Add(coordinate);
//Debug.Log(coordinate.latitude);
}
InstantiatePoints();
}
// use this method to instanciate the gameobjects!
void InstantiatePoints()
{
float distanzaTotale=0;
float distanzaTotaleGeografica = 0;
for (int i = 0; i < coordinateList.Count; i++)
{
CoordinateStruct coordinate = coordinateList[i];
GameObject pointObject = Instantiate(referenceObject);
Vector2 coordinateAttuali = new Vector2(coordinate.longitude, coordinate.latitude);
//Vector3 position = FromLongLat(coordinateAttuali);
Vector3 position = AlbersProjection(coordinate.longitude, coordinate.latitude);
pointObject.transform.position = position;
PuntiList.Add(pointObject);
if (i > 0)
{
float geographicDistance = CalculateGeographicDistance(coordinateList[i], coordinateList[i-1]);
float distance = Vector3.Distance(PuntiList[i].transform.position, PuntiList[i-1].transform.position);
Debug.Log($"distanza geografica = {geographicDistance}");
Debug.Log($"distnza vettori = {distance}");
distanzaTotale += distance;
distanzaTotaleGeografica += geographicDistance;
}
}
OnEventTriggered.Invoke();
Debug.Log(distanzaTotale);
Debug.Log(distanzaTotaleGeografica);
List<Vector2> line = new List<Vector2>();
for(int i = 0; i<= coordinateList.Count-1; i++)
{
Vector2 vector2 = new Vector2(coordinateList[i].longitude, coordinateList[i].latitude);
line.Add(vector2);
}
OnlineMapsDrawingElementManager.AddItem(new OnlineMapsDrawingLine(line, Color.magenta, 5));
InstantiateMarkers(coordinateList);
}
// creiamo i marker sulla mappa in base alla mia lista di punti
public void InstantiateMarkers(List<CoordinateStruct> coordinates)
{
foreach (CoordinateStruct coordinate in coordinates)
{
//GameObject markerObject = Instantiate(OnlineMapsMarkerManager. markerPrefab, markerParent);;
OnlineMapsMarkerManager.CreateItem(coordinate.longitude, coordinate.latitude, onlineMaps.defaultTexture);
}
}
public static Vector3 AlbersProjection(float latitude, float longitude)
{
// Coordinate di riferimento per Genova
float centralMeridian = 8.9463f; // Longitudine di riferimento
float standardParallel1 = 44f; // Primo parallelo standard
float standardParallel2 = 45f; // Secondo parallelo standard
// Conversione da gradi a radianti
float latRad = Mathf.Deg2Rad * latitude;
float longRad = Mathf.Deg2Rad * longitude;
float centralMeridianRad = Mathf.Deg2Rad * centralMeridian;
float stdParallel1Rad = Mathf.Deg2Rad * standardParallel1;
float stdParallel2Rad = Mathf.Deg2Rad * standardParallel2;
// Parametri per la proiezione di Albers
float n = (Mathf.Sin(stdParallel1Rad) + Mathf.Sin(stdParallel2Rad)) / 2f;
float c = Mathf.Pow(Mathf.Cos(stdParallel1Rad), 2f) + 2f * n * Mathf.Sin(stdParallel1Rad);
float rho0 = Mathf.Sqrt(c - 2f * n * Mathf.Sin(stdParallel1Rad)) / n;
// Calcolo della proiezione di Albers
float rho = Mathf.Sqrt(c - 2f * n * Mathf.Sin(latRad)) / n;
float theta = n * (longRad - centralMeridianRad);
float x = scale * (rho * Mathf.Sin(theta));
float z = scale * (rho0 - rho * Mathf.Cos(theta));
return new Vector3(ScaleCoordinates(x)/2, 0, ScaleCoordinates(z)/2);
}
public static Vector3 GPSToMapCoords(float latitude, float longitude)
{
float radius = 6371000f; // raggio della Terra in metri
float longitude0 = 0f; // longitudine di riferimento
float latRad = Mathf.Deg2Rad * latitude;
float longRad = Mathf.Deg2Rad * longitude;
float x = scale*(radius * (longRad - Mathf.Deg2Rad * longitude0));
float y = 0;
float z = scale*(radius * Mathf.Log(Mathf.Tan(Mathf.PI / 4f + latRad / 2f)));
return new Vector3(ScaleCoordinates(x), y, ScaleCoordinates(z));
}
//use this method to reduce the size of the number cause u really dont need all the firs part of the number, and smaller one can readed easily from unity transform!
public static float ScaleCoordinates(float num)
{
// Converti il numero in una stringa
string numString = num.ToString();
// Rimuovi le prime quattro cifre decimali
string scaledString = numString.Substring(2);
// Converti la stringa risultante in float
float scaledNum = float.Parse(scaledString);
// Restituisce il numero con le cifre decimali ridotte
return scaledNum;
}
public static float CalculateGeographicDistance(CoordinateStruct coordinate1, CoordinateStruct coordinate2)
{
float earthRadius = 6371000f;
float lat1Rad = Mathf.Deg2Rad * coordinate1.latitude;
float lat2Rad = Mathf.Deg2Rad * coordinate2.latitude;
float lon1Rad = Mathf.Deg2Rad * coordinate1.longitude;
float lon2Rad = Mathf.Deg2Rad * coordinate2.longitude;
float deltaLat = lat2Rad - lat1Rad;
float deltaLon = lon2Rad - lon1Rad;
float a = Mathf.Sin(deltaLat / 2) * Mathf.Sin(deltaLat / 2) + Mathf.Cos(lat1Rad) * Mathf.Cos(lat2Rad) * Mathf.Sin(deltaLon / 2) * Mathf.Sin(deltaLon / 2);
float c = 2 * Mathf.Atan2(Mathf.Sqrt(a), Mathf.Sqrt(1 - a));
float distance = earthRadius * c;
return distance;
}
}