feat: Initial commit
This commit is contained in:
224
Assets/Cryville.EEW.Unity/Map/MapElementManager.cs
Normal file
224
Assets/Cryville.EEW.Unity/Map/MapElementManager.cs
Normal file
@@ -0,0 +1,224 @@
|
||||
using Cryville.EEW.Core;
|
||||
using Cryville.EEW.Core.Map;
|
||||
using Cryville.EEW.CWAOpenData.Map;
|
||||
using Cryville.EEW.GlobalQuake.Map;
|
||||
using Cryville.EEW.JMAAtom.Map;
|
||||
using Cryville.EEW.Map;
|
||||
using Cryville.EEW.Models.GeoJSON;
|
||||
using Cryville.EEW.NOAA.Map;
|
||||
using Cryville.EEW.Report;
|
||||
using Cryville.EEW.Wolfx.Map;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UnityEngine;
|
||||
using UnityMapElement = Cryville.EEW.Unity.Map.Element.MapElement;
|
||||
|
||||
namespace Cryville.EEW.Unity.Map {
|
||||
sealed class MapElementManager : MonoBehaviour {
|
||||
ReportViewModel _selected;
|
||||
readonly List<UnityMapElement> _displayingElements = new();
|
||||
readonly List<ReportViewModel> _displayingReports = new();
|
||||
readonly List<int> _displayingOrder = new();
|
||||
|
||||
[SerializeField] MapElementManager m_subManager;
|
||||
|
||||
public RectangleF? AABB {
|
||||
get {
|
||||
RectangleF? ret = null;
|
||||
foreach (var element in _displayingElements) {
|
||||
if (element == null) continue;
|
||||
if (element.AABB is not RectangleF aabb) continue;
|
||||
if (ret == null) ret = aabb; // TODO dynamic
|
||||
else ret = MapTileUtils.UnionTileAABBs(ret.Value, aabb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddOngoing(ReportViewModel e) => Add(e);
|
||||
public void RemoveOngoing(ReportViewModel e) => Remove(e);
|
||||
public void SetSelected(ReportViewModel e) {
|
||||
if (_selected is not null)
|
||||
Remove(_selected);
|
||||
Add(e);
|
||||
_selected = e;
|
||||
}
|
||||
|
||||
void Add(ReportViewModel e) {
|
||||
var element = Build(e.Model, out _, out int order);
|
||||
if (element == null) return;
|
||||
var pos = element.transform.localPosition;
|
||||
pos.z = OrderToZ(_displayingOrder.Sum());
|
||||
element.transform.localPosition = pos;
|
||||
_displayingElements.Add(element);
|
||||
_displayingReports.Add(e);
|
||||
_displayingOrder.Add(order);
|
||||
element.transform.SetParent(transform, false);
|
||||
if (m_subManager != null) m_subManager.Add(e);
|
||||
}
|
||||
void Remove(ReportViewModel e) {
|
||||
int index = _displayingReports.IndexOf(e);
|
||||
if (index == -1) return;
|
||||
_displayingElements.RemoveAt(index);
|
||||
_displayingReports.RemoveAt(index);
|
||||
_displayingOrder.RemoveAt(index);
|
||||
var element = transform.GetChild(index);
|
||||
element.SetParent(null, false);
|
||||
Destroy(element.gameObject);
|
||||
|
||||
int order = _displayingOrder.Take(index).Sum();
|
||||
for (int i = index; i < transform.childCount; i++) {
|
||||
var child = transform.GetChild(i);
|
||||
var pos = child.localPosition;
|
||||
pos.z = OrderToZ(order);
|
||||
child.localPosition = pos;
|
||||
order += _displayingOrder[i];
|
||||
}
|
||||
|
||||
if (m_subManager != null) m_subManager.Remove(e);
|
||||
}
|
||||
|
||||
float m_scale = 1;
|
||||
public float Scale {
|
||||
get => m_scale;
|
||||
set {
|
||||
m_scale = value;
|
||||
foreach (Transform element in transform) {
|
||||
element.GetComponent<UnityMapElement>().Scale = value;
|
||||
}
|
||||
if (m_subManager != null) m_subManager.Scale = value;
|
||||
}
|
||||
}
|
||||
|
||||
readonly ContextedGeneratorManager<IMapGeneratorContext, MapElement> _gen = new(new IContextedGenerator<IMapGeneratorContext, MapElement>[] {
|
||||
new CENCEarthquakeMapGenerator(),
|
||||
new CENCEEWMapGenerator(),
|
||||
new CWAEarthquakeMapGenerator(),
|
||||
new CWAEEWMapGenerator(),
|
||||
new CWATsunamiMapGenerator(),
|
||||
new FujianEEWMapGenerator(),
|
||||
new GlobalQuakeMapViewGenerator(),
|
||||
new JMAAtomMapGenerator(),
|
||||
new JMAEEWMapGenerator(),
|
||||
new NOAAMapGenerator(),
|
||||
new SichuanEEWMapGenerator(),
|
||||
});
|
||||
public UnityMapElement Build(object e, out CultureInfo culture, out int order) {
|
||||
culture = CultureInfo.InvariantCulture;
|
||||
order = 0;
|
||||
var ret = Convert(_gen.TryGenerate(e, SharedSettings.Instance, ref culture), ref order);
|
||||
if (ret == null)
|
||||
return null;
|
||||
ret.Scale = Scale;
|
||||
return ret;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float OrderToZ(int order) => order / -1000f;
|
||||
|
||||
[SerializeField] Element.GroupElement m_prefabGroupElement;
|
||||
[SerializeField] Element.MaskedGroupElement m_prefabMaskedGroupElement;
|
||||
[SerializeField] Element.OngoingGroupElement m_prefabOngoingGroupElement;
|
||||
[SerializeField] Element.HypocenterElement m_prefabHypocenterElement;
|
||||
[SerializeField] Element.LabeledPointElement m_prefabLabeledPointElement;
|
||||
[SerializeField] Element.MultiLineElement m_prefabMultiLineElement;
|
||||
[SerializeField] Element.MultiPolygonElement m_prefabMultiPolygonElement;
|
||||
[SerializeField] Element.PointElement m_prefabPointElement;
|
||||
[SerializeField] Element.TsunamiHeightElement m_prefabTsunamiHeightElement;
|
||||
[SerializeField] Element.WaveCircleElement m_prefabWaveCircleElement;
|
||||
public UnityMapElement Convert(MapElement mapElement, ref int order) => mapElement switch {
|
||||
MaskedGroupElement maskedGroup => ConvertMaskedGroup(maskedGroup, ref order),
|
||||
OngoingGroupElement ongoingGroup => ConvertOngoingGroup(ongoingGroup, ref order),
|
||||
GroupElement group => ConvertGroup(group, m_prefabGroupElement, ref order),
|
||||
HypocenterElement hypocenter => ConvertHypocenter(hypocenter, ref order),
|
||||
LabeledPointElement labeledPoint => ConvertLabeledPoint(labeledPoint, ref order),
|
||||
MultiLineElement multiLine => ConvertMultiLine(multiLine, ref order),
|
||||
MultiPolygonElement multiPolygon => ConvertMultiPolygon(multiPolygon, ref order),
|
||||
PointElement point => ConvertPoint(point, ref order),
|
||||
TsunamiHeightElement tsunamiHeight => ConvertTsunamiHeight(tsunamiHeight, ref order),
|
||||
WaveCircleElement waveCircle => ConvertWaveCircle(waveCircle, ref order),
|
||||
_ => null,
|
||||
};
|
||||
T Convert<T>(MapElement element, T prefab) where T : UnityMapElement {
|
||||
var ret = Instantiate(prefab);
|
||||
ret.MaxScale = element.MaxScale;
|
||||
return ret;
|
||||
}
|
||||
T ConvertGroup<T>(GroupElement group, T prefab, ref int order) where T : Element.GroupElement {
|
||||
var ret = Convert(group, prefab);
|
||||
foreach (var e in group.Elements) ret.AddElement(Convert(e, ref order));
|
||||
return ret;
|
||||
}
|
||||
Element.MaskedGroupElement ConvertMaskedGroup(MaskedGroupElement maskedGroup, ref int order) {
|
||||
var ret = ConvertGroup(maskedGroup, m_prefabMaskedGroupElement, ref order);
|
||||
ret.SetMasks(maskedGroup.Masks);
|
||||
return ret;
|
||||
}
|
||||
Element.OngoingGroupElement ConvertOngoingGroup(OngoingGroupElement ongoingGroup, ref int order) {
|
||||
var ret = ConvertGroup(ongoingGroup, m_prefabOngoingGroupElement, ref order);
|
||||
ret.BlinkingPeriod = ongoingGroup.BlinkingPeriod;
|
||||
return ret;
|
||||
}
|
||||
Element.HypocenterElement ConvertHypocenter(HypocenterElement hypocenter, ref int order) {
|
||||
var ret = Convert(hypocenter, m_prefabHypocenterElement);
|
||||
ret.SetLocation(hypocenter.Location, ref order);
|
||||
ret.IsLowQuality = hypocenter.IsLowQuality;
|
||||
ret.Size = hypocenter.Size;
|
||||
return ret;
|
||||
}
|
||||
Element.LabeledPointElement ConvertLabeledPoint(LabeledPointElement labeledPoint, ref int order) {
|
||||
var ret = Convert(labeledPoint, m_prefabLabeledPointElement);
|
||||
ret.SetLocation(labeledPoint.Location, ref order);
|
||||
ret.Text = labeledPoint.Text;
|
||||
ret.Color = labeledPoint.FillColor.ToUnityColor();
|
||||
ret.TextColor = labeledPoint.TextColor.ToUnityColor();
|
||||
ret.IsArea = labeledPoint.IsAreaLabel;
|
||||
ret.Size = labeledPoint.Size;
|
||||
return ret;
|
||||
}
|
||||
Element.MultiLineElement ConvertMultiLine(MultiLineElement multiLine, ref int order) {
|
||||
var ret = Convert(multiLine, m_prefabMultiLineElement);
|
||||
ret.SetLines(multiLine.Lines, ref order);
|
||||
ret.Color = multiLine.BorderColor.ToUnityColor();
|
||||
ret.Width = multiLine.StrokeWidth;
|
||||
return ret;
|
||||
}
|
||||
Element.MultiPolygonElement ConvertMultiPolygon(MultiPolygonElement multiPolygon, ref int order) {
|
||||
var ret = Convert(multiPolygon, m_prefabMultiPolygonElement);
|
||||
ret.SetPolygons(multiPolygon.Polygons, ref order);
|
||||
ret.FillColor = multiPolygon.FillColor.ToUnityColor();
|
||||
ret.BorderColor = multiPolygon.BorderColor.ToUnityColor();
|
||||
ret.BorderWidth = multiPolygon.StrokeWidth;
|
||||
return ret;
|
||||
}
|
||||
Element.PointElement ConvertPoint(PointElement point, ref int order) {
|
||||
var ret = Convert(point, m_prefabPointElement);
|
||||
ret.SetLocation(point.Location, ref order);
|
||||
ret.Color = point.FillColor.ToUnityColor();
|
||||
ret.Size = point.Size;
|
||||
return ret;
|
||||
}
|
||||
Element.TsunamiHeightElement ConvertTsunamiHeight(TsunamiHeightElement tsunamiHeight, ref int order) {
|
||||
var ret = Convert(tsunamiHeight, m_prefabTsunamiHeightElement);
|
||||
ret.SetLocation(tsunamiHeight.Location, ref order);
|
||||
ret.Height = tsunamiHeight.Height;
|
||||
ret.Color = tsunamiHeight.FillColor.ToUnityColor();
|
||||
ret.IsRising = tsunamiHeight.IsRising;
|
||||
ret.IsOutOfRange = tsunamiHeight.IsOutOfRange;
|
||||
ret.IsMissing = tsunamiHeight.IsMissing;
|
||||
ret.Width = tsunamiHeight.Width;
|
||||
return ret;
|
||||
}
|
||||
Element.WaveCircleElement ConvertWaveCircle(WaveCircleElement waveCircle, ref int order) {
|
||||
var ret = Convert(waveCircle, m_prefabWaveCircleElement);
|
||||
ret.SetHypocenterLocation(waveCircle.HypocenterLocation, ref order);
|
||||
ret.OriginTime = waveCircle.OriginTime;
|
||||
ret.Depth = waveCircle.Depth;
|
||||
ret.ReportTime = waveCircle.ReportTime;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user