using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using sam; public class AreaVariableSubsession : MonoBehaviour, IProductDataConsumer { public Text prodNameText; public Text minValText; public Text maxValText; public Text varNameText; public Text curValText; public Text latText; public Text lonText; public Text dateText; public string dateFormat; public Color dataPointColor; [HideInInspector] public int initiallySelectedVariableIndex = 0; protected bool autoSelectVariable = true; [HideInInspector] public ProductData data; [HideInInspector] public ProductProfile profile; [HideInInspector] public int variableIndex; [HideInInspector] public ProductVariable prodvar; public ProductDataPoint selectedDP = null; float selectedLat = 0f; float selectedLon = 0f; public List> latLonDictionaries; public void SetInitiallySelectedVariableIndex(int i) { initiallySelectedVariableIndex = i; } public ProductData GetSelectedProduct() { return data; } public void SelectProduct(ProductData pd) { data = pd; profile = data.profile; variableIndex = -1; prodvar = null; prodNameText.text = data.referenceProductName; BuildLatLonDictionaries(); BroadcastMessage("OnProductSelected", data, SendMessageOptions.DontRequireReceiver); /*string minString = pd.profile.variables[0].name; int minIndex = 0; for (int i = 1; i < pd.variables.Count; i++) { if (pd.profile.variables[i].name.CompareTo(minString) < 0) { minString = pd.profile.variables[i].name; minIndex = i; } }*/ if (autoSelectVariable) SelectVariable(/*minIndex*/initiallySelectedVariableIndex); } void BuildLatLonDictionaries() { latLonDictionaries = new List>(); foreach (var dp in data.dataPoints) { (float, float) coords = (dp.latitude, dp.longitude); bool added = false; for(int i=0; i dic = latLonDictionaries[i]; if (!dic.ContainsKey(coords)) { dic.Add(coords, dp); added = true; break; } } if (!added) { Dictionary<(float, float), ProductDataPoint> dic = new Dictionary<(float, float), ProductDataPoint>(); dic.Add(coords, dp); latLonDictionaries.Add(dic); } } /* Debug.Log($"BuildLatLonDictionaries: built {latLonDictionaries.Count} dictionaries"); for (int i=0; i < latLonDictionaries.Count; i++) { Debug.Log($"Dictionary {i} has {latLonDictionaries[i].Count} entries"); } */ } void UpdateLatLonDictionaries() { if (latLonDictionaries.Count < 2) return; List< (float, float) > allKeys = new List<(float, float)>(latLonDictionaries[1].Keys); //foreach (KeyValuePair<(float, float), ProductDataPoint> entry in latLonDictionaries[1]) //foreach ((float, float) coords in latLonDictionaries[1].Keys) foreach ((float, float) coords in allKeys) { int selectedDict = -1; for (int i = 0; i < latLonDictionaries.Count; i++) { ProductDataPoint dp; if (latLonDictionaries[i].TryGetValue(coords, out dp)) { if (dp.varValid[variableIndex]) { selectedDict = i; break; } } } if (selectedDict > 0) { ProductDataPoint tmp = latLonDictionaries[0][coords]; latLonDictionaries[0][coords] = latLonDictionaries[selectedDict][coords]; latLonDictionaries[selectedDict][coords] = tmp; } } } public virtual void SelectVariable(int varInd) { if (varInd == variableIndex) return; variableIndex = varInd; prodvar = profile.variables[variableIndex]; varNameText.text = prodvar.name; minValText.text = prodvar.ScaledMinValWithUnit(); maxValText.text = prodvar.ScaledMaxValWithUnit(); UpdateLatLonDictionaries(); BroadcastMessage("OnVariableSelected", variableIndex, SendMessageOptions.DontRequireReceiver); } //public void SetScaleFactor(float s) //{ // scaleFactor = s; // scaleText.text = s.ToString() + "x"; // BroadcastMessage("OnScaleFactorChanged", scaleFactor, SendMessageOptions.DontRequireReceiver); //} /*public void SelectTimeStamp(DateTime t) { curTime = t; dateText.text = curTime.ToString(dateFormat); int i = SearchDataPoint(t); if (i < 0) { selectedDP = null; curValText.text = latText.text = lonText.text = ""; } else { selectedDP = data.dataPoints[i]; if (selectedDP.varValid[variableIndex]) curValText.text = selectedDP.variables[variableIndex].ToString() + " " + prodvar.unit; else curValText.text = ""; latText.text = "Lat: " + Utils.FormatLatitude(selectedDP.latitude); lonText.text = "Lon: " + Utils.FormatLongitude(selectedDP.longitude); } BroadcastMessage("OnTimeStampChanged", curTime, SendMessageOptions.DontRequireReceiver); }*/ public void SelectLatLon(float lat, float lon) { float iLat = (float)(Math.Round((lat * 2)) * 0.5f); float iLon = (float)(Math.Round((lon * 2)) * 0.5f); if (iLat == selectedLat && iLon == selectedLon) return; int dpIndex = SearchDataPoint(iLat, iLon); if (dpIndex >= 0) { selectedLat = iLat; selectedLon = iLon; selectedDP = data.dataPoints[dpIndex]; dateText.text = selectedDP.time.ToString(dateFormat); if (selectedDP.varValid[variableIndex]) curValText.text = selectedDP.variables[variableIndex].ToString() + " " + prodvar.unit; else curValText.text = ""; } else { selectedLat = lat; selectedLon = lon; dateText.text = ""; curValText.text = ""; selectedDP = null; } latText.text = "Lat: " + Utils.FormatLatitude(selectedLat); lonText.text = "Lon: " + Utils.FormatLongitude(selectedLon); BroadcastMessage("OnLatLonChanged", (selectedLat, selectedLon), SendMessageOptions.DontRequireReceiver); } public int SearchDataPoint(DateTime t) { ProductDataPoint dp = new ProductDataPoint { time = t }; return data.dataPoints.BinarySearch(dp, new CompareDataPointsTimeStamp()); } public int SearchDataPoint(float lat, float lon) { ProductDataPoint dp; if (latLonDictionaries[0].TryGetValue((lat,lon), out dp)) { return dp.dataPointIndex; } return -1; } public class CompareDataPointsTimeStamp : IComparer { public int Compare(ProductDataPoint dp1, ProductDataPoint dp2) { return DateTime.Compare(dp1.time, dp2.time); } } public class CompareDataPointslatLon : IComparer { public int Compare(ProductDataPoint dp1, ProductDataPoint dp2) { return (dp1.latitude == dp2.latitude) ? dp1.longitude.CompareTo(dp2.longitude) : dp1.latitude.CompareTo(dp2.latitude); } } public virtual Color GetDataPointColor(ProductDataPoint dp) { return dataPointColor; } }