19 Commits

Author SHA1 Message Date
8da46c0511 build: Update project version 2025-04-29 19:54:46 +08:00
75b5d7708c fix: Disable force HTTPS in NOAA Atom worker when debugging 2025-04-29 19:54:27 +08:00
5b2177a795 feat: Add using raw location name settings for CENC earthquake reports 2025-04-29 19:54:16 +08:00
8cb33dca5f ci: Update plugins 2025-04-29 19:53:24 +08:00
ae2e0af18a fix: Improve ongoing report round-robin period 2025-04-29 19:52:41 +08:00
2ac5a3d4f0 build: Update project version 2025-04-08 10:01:06 +08:00
5f78a1afde refactor: Code cleanup 2025-04-08 10:00:47 +08:00
ef5cf78a03 feat: Add display culture config 2025-04-08 10:00:28 +08:00
b60e62af70 feat: Adapt to breaking changes 2025-04-08 10:00:01 +08:00
3e59fe1462 feat: Implement region editor 2025-04-08 09:56:47 +08:00
4b4bf5ed65 ci: Update plugins 2025-04-08 09:53:33 +08:00
a4f78b3a95 build: Update project version 2025-03-24 00:07:35 +08:00
074a58dabd perf: Optimize performance for status view 2025-03-24 00:06:51 +08:00
a2ef175a81 fix: Fix potentially bad formats in culture info 2025-03-24 00:06:29 +08:00
915ba55c2e fix: Correct lifecycle of event listeners 2025-03-24 00:05:35 +08:00
f154a2a468 fix: Fix history list view flashing hard on update 2025-03-24 00:04:29 +08:00
c52d438d40 ci: Update plugins 2025-03-24 00:03:33 +08:00
8d3f53ba13 perf: Improve performance for line renderer 2025-03-20 21:49:28 +08:00
1db25e62e7 fix: Fix wave circle shape when hypocenter is near antimeridian 2025-03-20 21:47:52 +08:00
205 changed files with 4543 additions and 326 deletions

View File

@@ -56,7 +56,7 @@ namespace Cryville.Common.Unity.UI {
const float _placeholderLength = 100; const float _placeholderLength = 100;
int _firstIndex, _lastIndex; int _firstIndex, _lastIndex;
readonly Stack<GameObject> _pool = new(); readonly Stack<GameObject> _pool = new();
void Update() { void LateUpdate() {
int axis = (int)m_direction; int axis = (int)m_direction;
int sign = m_direction == 0 ? 1 : -1; int sign = m_direction == 0 ? 1 : -1;
float padding = axis == 0 ? m_padding.left : m_padding.top; float padding = axis == 0 ? m_padding.left : m_padding.top;

View File

@@ -1,3 +1,3 @@
using System.Reflection; using System.Reflection;
[assembly: AssemblyVersion("0.0.2")] [assembly: AssemblyVersion("0.0.5")]

View File

@@ -13,6 +13,8 @@ namespace Cryville.EEW.Unity {
bool DoDisplayTimeZone, bool DoDisplayTimeZone,
bool DoSwitchBackToHistory, bool DoSwitchBackToHistory,
string OverrideDisplayCulture,
IReadOnlyCollection<EventSourceConfig> EventSources IReadOnlyCollection<EventSourceConfig> EventSources
) { ) {
public static Config Default => new( public static Config Default => new(
@@ -25,6 +27,8 @@ namespace Cryville.EEW.Unity {
true, true,
true, true,
"",
new List<EventSourceConfig> { new List<EventSourceConfig> {
new JMAAtomEventSourceConfig(Array.Empty<string>()), new JMAAtomEventSourceConfig(Array.Empty<string>()),
new UpdateCheckerEventSourceConfig(), new UpdateCheckerEventSourceConfig(),
@@ -54,7 +58,7 @@ namespace Cryville.EEW.Unity {
record NOAAEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig; record NOAAEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig;
record UpdateCheckerEventSourceConfig : EventSourceConfig; record UpdateCheckerEventSourceConfig : EventSourceConfig;
record USGSQuakeMLEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig; record USGSQuakeMLEventSourceConfig([property: JsonRequired] string Subtype) : EventSourceConfig;
record WolfxEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false) : EventSourceConfig; record WolfxEventSourceConfig(IReadOnlyCollection<string> Filter = null, bool IsFilterWhitelist = false, bool UseRawCENCLocationName = false) : EventSourceConfig;
[JsonSerializable(typeof(Config))] [JsonSerializable(typeof(Config))]
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]

View File

@@ -17,19 +17,24 @@ namespace Cryville.EEW.Unity.Map {
GameObject m_prefabTile; GameObject m_prefabTile;
[SerializeField] [SerializeField]
GameObject m_prefabBitmapHolder; GameObject m_prefabBitmapHolder;
[SerializeField]
int m_maxMapTileZoom = 10;
[SerializeField]
bool m_isEditor;
readonly MapTileCacheManager _tiles = new(); MapTileCacheManager _tiles;
float _elementLayerZ; float _elementLayerZ;
void Start() { void Start() {
_camera = GetComponent<Camera>(); _camera = GetComponent<Camera>();
_tiles = m_isEditor ? new EditorMapTileCacheManager() : new MapTileCacheManager();
_tiles.ExtraCachedZoomLevel = 20; _tiles.ExtraCachedZoomLevel = 20;
_tiles.Parent = m_layerTile; _tiles.Parent = m_layerTile;
_tiles.PrefabTile = m_prefabTile; _tiles.PrefabTile = m_prefabTile;
_tiles.PrefabBitmapHolder = m_prefabBitmapHolder; _tiles.PrefabBitmapHolder = m_prefabBitmapHolder;
_tiles.CacheDir = Application.temporaryCachePath; _tiles.CacheDir = Application.temporaryCachePath;
_camera.orthographicSize = 0.5f / MathF.Max(1, (float)_camera.pixelWidth / _camera.pixelHeight); _camera.orthographicSize = 0.5f / MathF.Max(1, (float)_camera.pixelWidth / _camera.pixelHeight);
_elementLayerZ = m_layerElement.transform.position.z; if (m_layerElement != null) _elementLayerZ = m_layerElement.transform.position.z;
_mapElementUpdated = true; _mapElementUpdated = true;
} }
void OnDestroy() { void OnDestroy() {
@@ -74,7 +79,7 @@ namespace Cryville.EEW.Unity.Map {
} }
} }
void ZoomToMapElement() { void ZoomToMapElement() {
var aabb = m_layerElement.AABB; var aabb = m_layerElement != null ? m_layerElement.AABB : null;
if (aabb is not RectangleF b) return; if (aabb is not RectangleF b) return;
if (b.Width * _camera.pixelHeight < _camera.pixelWidth * b.Height) if (b.Width * _camera.pixelHeight < _camera.pixelWidth * b.Height)
Scale = b.Height; Scale = b.Height;
@@ -97,26 +102,30 @@ namespace Cryville.EEW.Unity.Map {
transform.localPosition = new(nx, Math.Clamp(transform.position.y, h / 2 - 1, -h / 2), -20); transform.localPosition = new(nx, Math.Clamp(transform.position.y, h / 2 - 1, -h / 2), -20);
var bounds = new Bounds((Vector2)transform.position, new Vector2(w, h)); var bounds = new Bounds((Vector2)transform.position, new Vector2(w, h));
int zoom = Math.Clamp((int)Math.Log(vz / 256, 2) + 1, 0, 10); int zoom = Math.Clamp((int)Math.Log(vz / 256, 2) + 1, 0, m_maxMapTileZoom);
int zoomScale = 1 << zoom; int zoomScale = 1 << zoom;
_tiles.MoveTo( _tiles.MoveTo(
new(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom), new(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom),
new(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom) new(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom)
); );
m_layerElement.Scale = h; if (m_layerElement != null) {
m_layerElementSub.Scale = h; m_layerElement.Scale = h;
}
if (m_layerElementSub != null) {
m_layerElementSub.Scale = h;
if (nx - w / 2 < 0) { if (nx - w / 2 < 0) {
m_layerElementSub.gameObject.SetActive(true); m_layerElementSub.gameObject.SetActive(true);
m_layerElementSub.transform.localPosition = new(-1, 0, _elementLayerZ); m_layerElementSub.transform.localPosition = new(-1, 0, _elementLayerZ);
} }
else if (nx + w / 2 > 1) { else if (nx + w / 2 > 1) {
m_layerElementSub.gameObject.SetActive(true); m_layerElementSub.gameObject.SetActive(true);
m_layerElementSub.transform.localPosition = new(1, 0, _elementLayerZ); m_layerElementSub.transform.localPosition = new(1, 0, _elementLayerZ);
} }
else { else {
m_layerElementSub.gameObject.SetActive(false); m_layerElementSub.gameObject.SetActive(false);
}
} }
} }
} }

View File

@@ -0,0 +1,15 @@
using Cryville.EEW.Core.Map;
using System.IO;
using UnityEngine;
namespace Cryville.EEW.Unity.Map {
sealed class EditorMapTileCacheManager : MapTileCacheManager {
protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(
index,
GameObject.Instantiate(PrefabBitmapHolder, Parent, false),
new($"https://tile.openstreetmap.org/{index.Z}/{index.NX}/{index.NY}.png")
);
protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map_editor/{index.Z}/{index.NX}/{index.NY}");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 478198b8ecc0082449fa3f68795174a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -98,24 +98,25 @@ namespace Cryville.EEW.Unity.Map.Element {
for (int d = 0; d < 360; d++) { for (int d = 0; d < 360; d++) {
Quaternion q = Quaternion.AngleAxis(d, axis); Quaternion q = Quaternion.AngleAxis(d, axis);
Vector3 p = q * rp; Vector3 p = q * rp;
Vector2 p2 = ToTilePos(p).ToVector2(); AddVertex(renderer, ref lp2, ref segmentIndex, d, p);
if (lp2 != null) {
float dx = p2.x - lp2.Value.x;
if (MathF.Abs(dx) >= 0.5) {
_vertexBuffer[d] = p2.x < 0.5 ? p2 + new Vector2(1, 0) : p2 - new Vector2(1, 0);
renderer.AddSegment(_vertexBuffer, segmentIndex, d - segmentIndex + 1);
segmentIndex = d;
}
}
_vertexBuffer[d] = p2;
lp2 = p2;
} }
Vector2 rp2 = ToTilePos(rp).ToVector2(); AddVertex(renderer, ref lp2, ref segmentIndex, 360, rp);
_vertexBuffer[360] = rp2;
renderer.AddSegment(_vertexBuffer, segmentIndex, 361 - segmentIndex); renderer.AddSegment(_vertexBuffer, segmentIndex, 361 - segmentIndex);
} }
renderer.SetMaterial(isHistory ? m_historyMaterial : m_ongoingMaterial); renderer.SetMaterial(isHistory ? m_historyMaterial : m_ongoingMaterial);
} }
void AddVertex(MultiLineRenderer renderer, ref Vector2? lp2, ref int segmentIndex, int d, Vector3 p) {
Vector2 p2 = ToTilePos(p).ToVector2();
if (lp2 != null && MathF.Abs(p2.x - lp2.Value.x) >= 0.5) {
_vertexBuffer[d] = p2.x < 0.5 ? p2 + new Vector2(1, 0) : p2 - new Vector2(1, 0);
renderer.AddSegment(_vertexBuffer, segmentIndex, d - segmentIndex + 1);
segmentIndex = d;
}
_vertexBuffer[d] = p2;
lp2 = p2;
}
static PointF ToTilePos(Vector3 p) => MapTileUtils.WorldToTilePos(new(MathF.Atan2(p.z, p.x) / MathF.PI * 180f, MathF.Asin(p.y) / MathF.PI * 180f)); static PointF ToTilePos(Vector3 p) => MapTileUtils.WorldToTilePos(new(MathF.Atan2(p.z, p.x) / MathF.PI * 180f, MathF.Asin(p.y) / MathF.PI * 180f));
} }
} }

View File

@@ -150,12 +150,8 @@ namespace Cryville.EEW.Unity.Map {
_mesh.Clear(); _mesh.Clear();
if (_positions == null) return; if (_positions == null) return;
if (_positionCount <= 1) return; if (_positionCount <= 1) return;
float hw = m_width / 2;
int maxVertexCount = 4 * (_positionCount - 1);
var vbuf = ArrayPool<Vector3>.Shared.Rent(maxVertexCount);
var ubuf = ArrayPool<Vector2>.Shared.Rent(maxVertexCount);
var ibuf = ArrayPool<int>.Shared.Rent(3 * (2 + 4 * (_positionCount - 2)));
float hw = m_width / 2;
int i, vi = 0, ii = 0, li = 0, ri = 1; int i, vi = 0, ii = 0, li = 0, ri = 1;
float uvScale = 1 / (m_tilingScale * m_width); float uvScale = 1 / (m_tilingScale * m_width);
Vector2 p0 = _positions[0], p1 = default; Vector2 p0 = _positions[0], p1 = default;
@@ -163,6 +159,12 @@ namespace Cryville.EEW.Unity.Map {
if ((p1 = _positions[i]) != p0) break; if ((p1 = _positions[i]) != p0) break;
} }
if (i >= _positionCount) return; if (i >= _positionCount) return;
int maxVertexCount = 4 * (_positionCount - 1);
var vbuf = ArrayPool<Vector3>.Shared.Rent(maxVertexCount);
var ubuf = ArrayPool<Vector2>.Shared.Rent(maxVertexCount);
var ibuf = ArrayPool<int>.Shared.Rent(3 * (2 + 4 * (_positionCount - 2)));
Vector2 dp0 = NormalizeSmallVector(p1 - p0), np0 = GetNormal(dp0 * hw); Vector2 dp0 = NormalizeSmallVector(p1 - p0), np0 = GetNormal(dp0 * hw);
vbuf[vi] = p0 - np0; ubuf[vi++] = new(0, 0); vbuf[vi] = p0 - np0; ubuf[vi++] = new(0, 0);
vbuf[vi] = p0 + np0; ubuf[vi++] = new(0, 1); vbuf[vi] = p0 + np0; ubuf[vi++] = new(0, 1);

View File

@@ -7,10 +7,12 @@ using UnityEngine;
namespace Cryville.EEW.Unity.Map { namespace Cryville.EEW.Unity.Map {
sealed class MapTileBitmapHolder : Core.Map.MapTileBitmapHolder { sealed class MapTileBitmapHolder : Core.Map.MapTileBitmapHolder {
MapTileBitmapHolderBehaviour _behaviour; readonly MapTileBitmapHolderBehaviour _behaviour;
readonly Uri _uri;
public MapTileBitmapHolder(MapTileIndex index, GameObject gameObject) : base(index) { public MapTileBitmapHolder(MapTileIndex index, GameObject gameObject, Uri uri) : base(index) {
_behaviour = gameObject.GetComponent<MapTileBitmapHolderBehaviour>(); _behaviour = gameObject.GetComponent<MapTileBitmapHolderBehaviour>();
_uri = uri;
} }
protected override void Dispose(bool disposing) { protected override void Dispose(bool disposing) {
@@ -20,8 +22,7 @@ namespace Cryville.EEW.Unity.Map {
} }
} }
protected override Uri GetUri() => protected override Uri GetUri() => _uri;
new($"https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{Index.Z}/{Index.NY}/{Index.NX}");
protected override Task LoadBitmap(FileInfo file, CancellationToken cancellationToken) { protected override Task LoadBitmap(FileInfo file, CancellationToken cancellationToken) {
_behaviour.Load(file); _behaviour.Load(file);

View File

@@ -45,13 +45,13 @@ namespace Cryville.EEW.Unity.Map {
_isReady = false; _isReady = false;
} }
if (_req == null || !_req.isDone) return; if (_req == null || !_req.isDone) return;
if (_texHandler.isDone) { if (_texHandler.isDone && _texHandler.texture != null) {
_tex = _texHandler.texture; _tex = _texHandler.texture;
_tex.wrapMode = TextureWrapMode.Clamp; _tex.wrapMode = TextureWrapMode.Clamp;
_sprite = Sprite.Create(_tex, new Rect(0, 0, _tex.width, _tex.height), Vector2.zero, _tex.height, 0, SpriteMeshType.FullRect, Vector4.zero, false); _sprite = Sprite.Create(_tex, new Rect(0, 0, _tex.width, _tex.height), Vector2.zero, _tex.height, 0, SpriteMeshType.FullRect, Vector4.zero, false);
} }
else { else {
Debug.LogError(_req.error); Debug.LogError(_texHandler.error);
_localFile.Delete(); _localFile.Delete();
} }
_req.Dispose(); _req.Dispose();

View File

@@ -4,7 +4,7 @@ using System.IO;
using UnityEngine; using UnityEngine;
namespace Cryville.EEW.Unity.Map { namespace Cryville.EEW.Unity.Map {
sealed class MapTileCacheManager : MapTileCacheManager<MapTileBitmapHolder> { class MapTileCacheManager : MapTileCacheManager<MapTileBitmapHolder> {
public GameObject PrefabTile { get; set; } public GameObject PrefabTile { get; set; }
public GameObject PrefabBitmapHolder { get; set; } public GameObject PrefabBitmapHolder { get; set; }
@@ -12,7 +12,11 @@ namespace Cryville.EEW.Unity.Map {
public string CacheDir { get; set; } public string CacheDir { get; set; }
protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(index, GameObject.Instantiate(PrefabBitmapHolder, Parent, false)); protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new(
index,
GameObject.Instantiate(PrefabBitmapHolder, Parent, false),
new($"https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{index.Z}/{index.NY}/{index.NX}")
);
protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map/{index.Z}/{index.NX}/{index.NY}"); protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map/{index.Z}/{index.NX}/{index.NY}");

View File

@@ -0,0 +1,219 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using TMPro;
using UnityEngine;
namespace Cryville.EEW.Unity.Map {
sealed class RegionEditor : MonoBehaviour {
QuadTreeNode _root;
[SerializeField] CameraController m_cameraController;
[SerializeField] GameObject m_regionViewPrefab;
[SerializeField] TMP_Text m_textSelectedInfo;
[SerializeField] TMP_Text m_textHoveredInfo;
[SerializeField] TMP_InputField m_inputId;
readonly Dictionary<QuadTreeNode, RegionView> _map = new();
void Start() {
var file = new FileInfo(Path.Combine(Application.persistentDataPath, "regions.json"));
if (file.Exists) {
using var stream = file.OpenRead();
_root = JsonSerializer.Deserialize<QuadTreeNode>(stream);
}
else {
_root = NewNode();
}
BuildView(_root);
}
public void Save() {
var file = new FileInfo(Path.Combine(Application.persistentDataPath, "regions.json"));
using var stream = file.Open(FileMode.Create);
JsonSerializer.Serialize(stream, _root);
}
void BuildView(QuadTreeNode node) {
var view = Instantiate(m_regionViewPrefab, transform, false).GetComponent<RegionView>();
view.Init(node.X, node.Y, node.Z);
view.Id = node.Data.Id;
view.IsLeaf = node.Children == null;
_map.Add(node, view);
BuildChildViews(node);
}
void BuildChildViews(QuadTreeNode node) {
if (node.Children == null) return;
foreach (var child in node.Children) {
BuildView(child);
}
}
void DestroyChildViews(QuadTreeNode node) {
if (node.Children == null) return;
foreach (var child in node.Children) {
Destroy(_map[child].gameObject);
_map.Remove(child);
}
}
QuadTreeNode _hoveredNode;
QuadTreeNode _selectedNode;
Vector3? _ppos;
void Update() {
var pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
pos.y += 1;
var hoveredNode = _root.Get(pos);
if (hoveredNode != _hoveredNode) {
HoverNode(hoveredNode);
}
if (Input.GetMouseButtonDown(0)) {
_ppos = Input.mousePosition;
}
if (Input.GetMouseButton(0) && _ppos is Vector3 pos0) {
if (Input.mousePosition != pos0) {
_ppos = null;
}
}
if (hoveredNode == null) return;
if (Input.GetMouseButtonUp(0) && _ppos != null) {
SelectNode(hoveredNode);
_ppos = null;
}
if (m_inputId.isFocused)
return;
if (Input.GetKeyUp(KeyCode.A)) {
MergeNode(hoveredNode);
}
if (Input.GetKeyUp(KeyCode.S)) {
SplitNode(hoveredNode);
}
if (Input.GetKeyUp(KeyCode.C)) {
m_inputId.text = hoveredNode.Data.Id;
}
if (Input.GetKeyUp(KeyCode.V)) {
hoveredNode.Data.Id = m_inputId.text;
_map[hoveredNode].Id = hoveredNode.Data.Id;
}
}
void HoverNode(QuadTreeNode node) {
if (_hoveredNode != null) {
_map[_hoveredNode].IsHovered = false;
}
_hoveredNode = node;
if (_hoveredNode != null) {
_map[_hoveredNode].IsHovered = true;
m_textHoveredInfo.text = string.Format(CultureInfo.InvariantCulture, "<Hovered>\nZ: {2}, XY: ({0}, {1})\nD: {3}", node.X, node.Y, node.Z, node.Data.Id);
}
else {
m_textHoveredInfo.text = "";
}
}
void SelectNode(QuadTreeNode node) {
if (_selectedNode != null) {
_map[_selectedNode].IsSelected = false;
}
_selectedNode = node;
if (_selectedNode != null) {
_map[_selectedNode].IsSelected = true;
m_textSelectedInfo.text = string.Format(CultureInfo.InvariantCulture, "<Selected>\nZ: {2}, XY: ({0}, {1})\nD: {3}", node.X, node.Y, node.Z, node.Data.Id);
}
else {
m_textSelectedInfo.text = "";
}
}
void MergeNode(QuadTreeNode node) {
var parent = node.Parent;
if (parent == null)
return;
DestroyChildViews(parent);
_map[parent].IsLeaf = true;
parent.Merge();
_hoveredNode = null;
if (_selectedNode != null && !_map.ContainsKey(_selectedNode)) {
_selectedNode = null;
}
}
void SplitNode(QuadTreeNode node) {
node.Split();
_map[node].IsLeaf = false;
BuildChildViews(node);
}
static QuadTreeNode NewNode() => new() { Data = new("") };
sealed class QuadTreeNode {
QuadTreeNode[] m_children;
public QuadTreeNode[] Children {
get => m_children;
set {
if (m_children != null) {
foreach (var child in m_children) {
child.DetachFromParent();
}
}
m_children = value;
UpdateChildren();
}
}
QuadTreeNode m_parent;
[JsonIgnore] public QuadTreeNode Parent => m_parent;
void AttachToParent(QuadTreeNode parent, int index) {
if (m_parent != null && m_parent != parent)
throw new InvalidOperationException("Node already in a tree.");
m_parent = parent;
X = (parent.X << 1) | (index is 0 or 3 ? 1 : 0);
Y = (parent.Y << 1) | (index is 0 or 1 ? 1 : 0);
Z = parent.Z + 1;
UpdateChildren();
}
void DetachFromParent() => m_parent = null;
void UpdateChildren() {
if (m_children != null) {
for (int i = 0; i < m_children.Length; i++) {
m_children[i].AttachToParent(this, i);
}
}
}
[JsonIgnore] public int X { get; private set; }
[JsonIgnore] public int Y { get; private set; }
[JsonIgnore] public int Z { get; private set; }
public RegionData Data { get; set; }
public QuadTreeNode Get(Vector2 pos) {
if ((pos.x is < 0 or >= 1) || (pos.y is < 0 or >= 1))
return null;
if (m_children == null)
return this;
Vector2 subPos = pos * 2;
subPos.x %= 1;
subPos.y %= 1;
return pos.x >= 0.5f
? (pos.y >= 0.5f ? m_children[0] : m_children[3]).Get(subPos)
: (pos.y >= 0.5f ? m_children[1] : m_children[2]).Get(subPos);
}
public void Merge() {
Children = null;
}
public void Split() {
Children = new QuadTreeNode[] {
new() { Data = Data.Copy() },
new() { Data = Data.Copy() },
new() { Data = Data.Copy() },
new() { Data = Data.Copy() },
};
}
}
sealed record RegionData(string Id) {
public string Id { get; set; } = Id;
public RegionData Copy() => (RegionData)MemberwiseClone();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fd7b70d11ebfe324e830806e394cc334
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
using UnityEngine;
namespace Cryville.EEW.Unity.Map {
sealed class RegionView : MonoBehaviour {
[SerializeField]
SpriteRenderer m_spriteRenderer;
Color _color;
bool m_isHovered;
public bool IsHovered {
get => m_isHovered;
set {
m_isHovered = value;
UpdateColor();
}
}
bool m_isSelected;
public bool IsSelected {
get => m_isSelected;
set {
m_isSelected = value;
UpdateColor();
}
}
bool m_isLeaf = true;
public bool IsLeaf {
get => m_isLeaf;
set {
m_isLeaf = value;
UpdateColor();
}
}
string m_id;
public string Id {
get => m_id;
set {
m_id = value;
unchecked {
uint hash = (uint)value.GetHashCode();
_color = Color.HSVToRGB(((hash >> 24) ^ ((hash >> 16) & 0xff) ^ ((hash >> 8) & 0xff) ^ (hash & 0xff)) / (float)0xff, 1, 1);
}
UpdateColor();
}
}
public void Init(int x, int y, int z) {
float scale = 1f / (1 << z);
transform.localScale = new Vector3(scale, scale, 1);
transform.localPosition = new Vector3(x * scale, y * scale - 1, -1 - z / 100f);
}
void UpdateColor() {
if (!m_isLeaf)
_color.a = 0.0f;
else if (m_isSelected)
_color.a = 0.6f;
else if (m_isHovered)
_color.a = 0.4f;
else
_color.a = 0.2f;
m_spriteRenderer.color = _color;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c57a0e86eb63b6048ba265e9d98e84f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,5 @@
using Cryville.EEW.Colors; using Cryville.EEW.Colors;
using Cryville.EEW.Core;
using Cryville.EEW.Core.Colors; using Cryville.EEW.Core.Colors;
using Cryville.EEW.FERegion; using Cryville.EEW.FERegion;
using Cryville.EEW.Map; using Cryville.EEW.Map;
@@ -25,9 +26,21 @@ namespace Cryville.EEW.Unity {
public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance); public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance);
public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance)); public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance));
public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black); public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black);
public ILocationConverter LocationConverter => new FERegionLongConverter(); // TODO TTS
public TimeSpan NowcastWarningDelayTolerance => TimeSpan.FromMinutes(60); // TODO TTS public TimeSpan NowcastWarningDelayTolerance => TimeSpan.FromMinutes(60); // TODO TTS
public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture;
readonly int _infoLocationSpecificity = 3;
readonly int _ttsLocationSpecificity = 3;
readonly LocationNamer _locationNamer = new() { Namer = new FERegionLongNamer() }; // TODO TTS
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name, out int specificity) {
specificity = _ttsLocationSpecificity;
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
}
public bool NameLocation(double lat, double lon, CultureInfo localCulture, ref CultureInfo targetCulture, out string name) {
int specificity = _infoLocationSpecificity;
return _locationNamer.Name(lat, lon, localCulture, ref targetCulture, out name, ref specificity);
}
public TimeZoneInfo OverrideTimeZone { get; private set; } public TimeZoneInfo OverrideTimeZone { get; private set; }
public bool DoDisplayTimeZone { get; private set; } = true; public bool DoDisplayTimeZone { get; private set; } = true;
public bool DoSwitchBackToHistory { get; private set; } = true; public bool DoSwitchBackToHistory { get; private set; } = true;
@@ -104,6 +117,9 @@ namespace Cryville.EEW.Unity {
OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone); OverrideTimeZone = ParseTimeZone(config.OverrideTimeZone);
DoDisplayTimeZone = config.DoDisplayTimeZone; DoDisplayTimeZone = config.DoDisplayTimeZone;
DoSwitchBackToHistory = config.DoSwitchBackToHistory; DoSwitchBackToHistory = config.DoSwitchBackToHistory;
RVMCulture = config.OverrideDisplayCulture is string rvmCulture
? (string.IsNullOrEmpty(rvmCulture) ? SharedCultures.CurrentUICulture : SharedCultures.Get(rvmCulture))
: CultureInfo.InvariantCulture;
EventSources = config.EventSources; EventSources = config.EventSources;
} }

View File

@@ -5,7 +5,7 @@ using System.IO;
using UnityEngine; using UnityEngine;
namespace Cryville.EEW.Unity { namespace Cryville.EEW.Unity {
class SoundPlayer : Core.SoundPlayer { class SoundPlayer : Core.Audio.SoundPlayer {
public SoundPlayer() : base(GetEngineList(), AudioUsage.NotificationEvent) { } public SoundPlayer() : base(GetEngineList(), AudioUsage.NotificationEvent) { }
static List<Type> GetEngineList() => new() { static List<Type> GetEngineList() => new() {
typeof(Audio.Wasapi.MMDeviceEnumeratorWrapper), typeof(Audio.Wasapi.MMDeviceEnumeratorWrapper),

View File

@@ -4,7 +4,7 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Cryville.EEW.Unity { namespace Cryville.EEW.Unity {
class TTSWorker : Core.TTSWorker { class TTSWorker : Core.Audio.TTSWorker {
public TTSWorker() : base(CreateSoundPlayer()) { } public TTSWorker() : base(CreateSoundPlayer()) { }
static SoundPlayer CreateSoundPlayer() { static SoundPlayer CreateSoundPlayer() {

View File

@@ -14,9 +14,12 @@ namespace Cryville.EEW.Unity.UI {
[SerializeField] GameObject m_listViewRail; [SerializeField] GameObject m_listViewRail;
[SerializeField] GameObject m_expander; [SerializeField] GameObject m_expander;
void Start() { void OnEnable() {
m_groupHeader.onClick.AddListener(OnGroupHeaderClicked); m_groupHeader.onClick.AddListener(OnGroupHeaderClicked);
} }
void OnDisable() {
m_groupHeader.onClick.RemoveListener(OnGroupHeaderClicked);
}
void OnGroupHeaderClicked() { void OnGroupHeaderClicked() {
SetExpanded(!m_listViewContainer.activeSelf); SetExpanded(!m_listViewContainer.activeSelf);
} }

View File

@@ -23,6 +23,7 @@ namespace Cryville.EEW.Unity.UI {
child.SetViewModel(e); child.SetViewModel(e);
child.transform.SetParent(m_listView, false); child.transform.SetParent(m_listView, false);
_displayingViews.Add(child); _displayingViews.Add(child);
OnDisplayingViewsChanged();
SwitchTo(_displayingReports.Count - 1); SwitchTo(_displayingReports.Count - 1);
@@ -37,6 +38,7 @@ namespace Cryville.EEW.Unity.UI {
child.SetParent(null, false); child.SetParent(null, false);
Destroy(child.gameObject); Destroy(child.gameObject);
_displayingViews.RemoveAt(index); _displayingViews.RemoveAt(index);
OnDisplayingViewsChanged();
if (_displayingReports.Count == 0) { if (_displayingReports.Count == 0) {
m_currentView.gameObject.SetActive(false); m_currentView.gameObject.SetActive(false);
@@ -49,6 +51,14 @@ namespace Cryville.EEW.Unity.UI {
if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false); if (_displayingReports.Count <= 1) m_listView.gameObject.SetActive(false);
} }
void OnDisplayingViewsChanged() {
_maxBaseDuration = 1;
foreach (var e in _displayingReports) {
float duration = GetBaseDuration(e);
if (duration > _maxBaseDuration)
_maxBaseDuration = duration;
}
}
void Awake() { void Awake() {
if (Instance != null) { if (Instance != null) {
@@ -63,6 +73,7 @@ namespace Cryville.EEW.Unity.UI {
int _index = -1; int _index = -1;
float _tickDown; float _tickDown;
float _maxBaseDuration;
void Update() { void Update() {
if (_displayingReports.Count == 0) return; if (_displayingReports.Count == 0) return;
_tickDown -= Time.deltaTime; _tickDown -= Time.deltaTime;
@@ -77,12 +88,15 @@ namespace Cryville.EEW.Unity.UI {
_index = index; _index = index;
var e = _displayingReports[index]; var e = _displayingReports[index];
m_currentView.SetViewModel(e, true); m_currentView.SetViewModel(e, true);
var keyProp = e.Properties.FirstOrDefault();
_displayingViews[_index].SetCurrent(true); _displayingViews[_index].SetCurrent(true);
_tickDown = MathF.Exp(Math.Max(-1f, keyProp?.Severity ?? -1f) + 1); _tickDown = GetBaseDuration(e) / Math.Min(_maxBaseDuration, 4) * 4;
m_currentView.gameObject.SetActive(true); m_currentView.gameObject.SetActive(true);
Worker.Instance.SetCurrent(e); Worker.Instance.SetCurrent(e);
} }
static float GetBaseDuration(ReportViewModel e) {
return MathF.Exp(Math.Max(-1f, e.Properties.FirstOrDefault()?.Severity ?? -1f) + 1);
}
public void OnItemClicked(ReportViewModel viewModel) { public void OnItemClicked(ReportViewModel viewModel) {
int index = _displayingReports.IndexOf(viewModel); int index = _displayingReports.IndexOf(viewModel);
if (index == -1) return; if (index == -1) return;

View File

@@ -27,7 +27,7 @@ namespace Cryville.EEW.Unity.UI {
} }
void SetView(float mainSeverity, string title, string location, CultureInfo culture) { void SetView(float mainSeverity, string title, string location, CultureInfo culture) {
SetSeverity(mainSeverity); SetSeverity(mainSeverity);
SetText(m_textView, string.Format("{0} {1}", title, location), culture); SetText(m_textView, string.Format(culture, "{0} {1}", title, location), culture);
} }
static void SetText(TMPLocalizedText view, string text, CultureInfo culture) { static void SetText(TMPLocalizedText view, string text, CultureInfo culture) {
if (string.IsNullOrWhiteSpace(text)) { if (string.IsNullOrWhiteSpace(text)) {
@@ -47,9 +47,12 @@ namespace Cryville.EEW.Unity.UI {
void Awake() { void Awake() {
_dockRatioTweener = new(() => m_dockLayoutGroup.DockOccupiedRatio, v => m_dockLayoutGroup.DockOccupiedRatio = v, Tweeners.Single); _dockRatioTweener = new(() => m_dockLayoutGroup.DockOccupiedRatio, v => m_dockLayoutGroup.DockOccupiedRatio = v, Tweeners.Single);
} }
void Start() { void OnEnable() {
m_button.onClick.AddListener(OnViewClicked); m_button.onClick.AddListener(OnViewClicked);
} }
void OnDisable() {
m_button.onClick.RemoveListener(OnViewClicked);
}
void OnViewClicked() { void OnViewClicked() {
EventOngoingListView.Instance.OnItemClicked(_viewModel); EventOngoingListView.Instance.OnItemClicked(_viewModel);
} }

View File

@@ -14,9 +14,12 @@ namespace Cryville.EEW.Unity.UI {
[SerializeField] TMPLocalizedText m_revisionView; [SerializeField] TMPLocalizedText m_revisionView;
ReportViewModel _viewModel; ReportViewModel _viewModel;
protected virtual void Start() { protected virtual void OnEnable() {
if (m_reportViewButton != null) m_reportViewButton.onClick.AddListener(OnViewClicked); if (m_reportViewButton != null) m_reportViewButton.onClick.AddListener(OnViewClicked);
} }
protected virtual void OnDisable() {
if (m_reportViewButton != null) m_reportViewButton.onClick.RemoveListener(OnViewClicked);
}
void OnViewClicked() { void OnViewClicked() {
Worker.Instance.SetSelected(_viewModel); Worker.Instance.SetSelected(_viewModel);
} }

View File

@@ -8,10 +8,14 @@ namespace Cryville.EEW.Unity.UI {
[SerializeField] Button m_revisionViewContainerButton; [SerializeField] Button m_revisionViewContainerButton;
protected override void Start() { protected override void OnEnable() {
base.Start(); base.OnEnable();
m_revisionViewContainerButton.onClick.AddListener(OnRevisionViewClicked); m_revisionViewContainerButton.onClick.AddListener(OnRevisionViewClicked);
} }
protected override void OnDisable() {
base.OnDisable();
m_revisionViewContainerButton.onClick.RemoveListener(OnRevisionViewClicked);
}
void OnRevisionViewClicked() { void OnRevisionViewClicked() {
m_listView.gameObject.SetActive(!m_listView.gameObject.activeSelf); m_listView.gameObject.SetActive(!m_listView.gameObject.activeSelf);
} }

View File

@@ -1,4 +1,5 @@
using System.Globalization; using System.Globalization;
using System.Text;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
@@ -11,17 +12,30 @@ namespace Cryville.EEW.Unity.UI {
_textView = GetComponent<TMP_Text>(); _textView = GetComponent<TMP_Text>();
} }
readonly StringBuilder _sb = new();
readonly char[] _buffer = new char[256];
void Update() { void Update() {
_textView.text = string.Format( _sb.Clear();
_sb.AppendFormat(
CultureInfo.InvariantCulture, CultureInfo.InvariantCulture,
"FPS: i{0:0} / s{1:0}\nSMem: {2:N0} / {3:N0}\nIMem: {4:N0} / {5:N0}", "FPS: i{0:0} / s{1:0}\n",
1 / Time.deltaTime, 1 / Time.deltaTime,
1 / Time.smoothDeltaTime, 1 / Time.smoothDeltaTime
);
_sb.AppendFormat(
CultureInfo.InvariantCulture,
"SMem: {0:N0} / {1:N0}\n",
UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong(), UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong(),
UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong(), UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong()
);
_sb.AppendFormat(
CultureInfo.InvariantCulture,
"IMem: {0:N0} / {1:N0}",
UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong(), UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong(),
UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong() UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong()
); );
_sb.CopyTo(0, _buffer, _sb.Length);
_textView.SetText(_buffer, 0, _sb.Length);
} }
} }
} }

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Globalization;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
@@ -19,7 +18,7 @@ namespace Cryville.EEW.Unity.UI {
time = TimeZoneInfo.ConvertTime(time, timeZone, tTimeZone); time = TimeZoneInfo.ConvertTime(time, timeZone, tTimeZone);
else else
tTimeZone = timeZone; tTimeZone = timeZone;
_textView.text = SharedSettings.Instance.DoDisplayTimeZone ? string.Format(CultureInfo.CurrentCulture, "{0:G} ({1})", time, tTimeZone.ToTimeZoneString()) : time.ToString(CultureInfo.CurrentCulture); _textView.text = SharedSettings.Instance.DoDisplayTimeZone ? string.Format(SharedCultures.CurrentCulture, "{0:G} ({1})", time, tTimeZone.ToTimeZoneString()) : time.ToString(SharedCultures.CurrentCulture);
} }
} }
} }

View File

@@ -64,6 +64,7 @@ namespace Cryville.EEW.Unity {
BuildWorkers(); BuildWorkers();
_worker.RVMGeneratorContext = SharedSettings.Instance; _worker.RVMGeneratorContext = SharedSettings.Instance;
_worker.TTSMessageGeneratorContext = SharedSettings.Instance; _worker.TTSMessageGeneratorContext = SharedSettings.Instance;
_worker.RVMCulture = SharedSettings.Instance.RVMCulture;
_ongoingReportManager.Changed += OnOngoingReported; _ongoingReportManager.Changed += OnOngoingReported;
_worker.Reported += OnReported; _worker.Reported += OnReported;
_grouper.GroupUpdated += OnGroupUpdated; _grouper.GroupUpdated += OnGroupUpdated;
@@ -87,9 +88,10 @@ namespace Cryville.EEW.Unity {
_ongoingReportManager.Dispose(); _ongoingReportManager.Dispose();
} }
static void RegisterViewModelGenerators(CoreWorker worker) { CENCEarthquakeRVMGenerator _cencEarthquakeRVMGenerator;
void RegisterViewModelGenerators(CoreWorker worker) {
worker.RegisterViewModelGenerator(new BMKGEarthquakeRVMGenerator()); worker.RegisterViewModelGenerator(new BMKGEarthquakeRVMGenerator());
worker.RegisterViewModelGenerator(new CENCEarthquakeRVMGenerator()); worker.RegisterViewModelGenerator(_cencEarthquakeRVMGenerator = new CENCEarthquakeRVMGenerator());
worker.RegisterViewModelGenerator(new CENCEEWRVMGenerator()); worker.RegisterViewModelGenerator(new CENCEEWRVMGenerator());
worker.RegisterViewModelGenerator(new CWAEarthquakeRVMGenerator()); worker.RegisterViewModelGenerator(new CWAEarthquakeRVMGenerator());
worker.RegisterViewModelGenerator(new CWAEEWRVMGenerator()); worker.RegisterViewModelGenerator(new CWAEEWRVMGenerator());
@@ -104,9 +106,10 @@ namespace Cryville.EEW.Unity {
worker.RegisterViewModelGenerator(new SichuanEEWRVMGenerator()); worker.RegisterViewModelGenerator(new SichuanEEWRVMGenerator());
worker.RegisterViewModelGenerator(new VersionRVMGenerator()); worker.RegisterViewModelGenerator(new VersionRVMGenerator());
} }
static void RegisterTTSMessageGenerators(CoreWorker worker) { CENCEarthquakeTTSMessageGenerator _cencEarthquakeTTSMessageGenerator;
void RegisterTTSMessageGenerators(CoreWorker worker) {
worker.RegisterTTSMessageGenerator(new BMKGEarthquakeTTSMessageGenerator()); worker.RegisterTTSMessageGenerator(new BMKGEarthquakeTTSMessageGenerator());
worker.RegisterTTSMessageGenerator(new CENCEarthquakeTTSMessageGenerator()); worker.RegisterTTSMessageGenerator(_cencEarthquakeTTSMessageGenerator = new CENCEarthquakeTTSMessageGenerator());
worker.RegisterTTSMessageGenerator(new CENCEEWTTSMessageGenerator()); worker.RegisterTTSMessageGenerator(new CENCEEWTTSMessageGenerator());
worker.RegisterTTSMessageGenerator(new CWAEarthquakeTTSMessageGenerator()); worker.RegisterTTSMessageGenerator(new CWAEarthquakeTTSMessageGenerator());
worker.RegisterTTSMessageGenerator(new CWAEEWTTSMessageGenerator()); worker.RegisterTTSMessageGenerator(new CWAEEWTTSMessageGenerator());
@@ -129,7 +132,7 @@ namespace Cryville.EEW.Unity {
BMKGOpenDataWorker bmkgWorker = new(new Uri("http://localhost:9095/autogempa.json")); BMKGOpenDataWorker bmkgWorker = new(new Uri("http://localhost:9095/autogempa.json"));
bmkgWorker.SetDataUris(new Uri[] { new("http://localhost:9095/gempadirasakan.json") }); bmkgWorker.SetDataUris(new Uri[] { new("http://localhost:9095/gempadirasakan.json") });
_worker.AddWorker(bmkgWorker); _worker.AddWorker(bmkgWorker);
_worker.AddWorker(new NOAAAtomWorker(new("http://localhost:9095/PAAQAtom.xml"))); _worker.AddWorker(new NOAAAtomWorker(new("http://localhost:9095/PAAQAtom.xml"), forceHttps: false));
_worker.AddWorker(new UpdateCheckerWorker(typeof(Worker).Assembly.GetName().Version?.ToString(3) ?? "", "unity")); _worker.AddWorker(new UpdateCheckerWorker(typeof(Worker).Assembly.GetName().Version?.ToString(3) ?? "", "unity"));
#else #else
foreach (var source in SharedSettings.Instance.EventSources) { foreach (var source in SharedSettings.Instance.EventSources) {
@@ -163,7 +166,7 @@ namespace Cryville.EEW.Unity {
worker.IsFilterWhitelist = config.IsFilterWhitelist; worker.IsFilterWhitelist = config.IsFilterWhitelist;
return worker; return worker;
} }
static WolfxWorker BuildWolfxWorkerFilter(WolfxWorker worker, WolfxEventSourceConfig config) { WolfxWorker BuildWolfxWorkerFilter(WolfxWorker worker, WolfxEventSourceConfig config) {
if (config.Filter != null) worker.SetFilter(config.Filter.Select(i => i switch { if (config.Filter != null) worker.SetFilter(config.Filter.Select(i => i switch {
"cenc_eew" => typeof(CENCEEW), "cenc_eew" => typeof(CENCEEW),
"cenc_eqlist" => typeof(WolfxEarthquakeList<CENCEarthquake>), "cenc_eqlist" => typeof(WolfxEarthquakeList<CENCEarthquake>),
@@ -174,6 +177,11 @@ namespace Cryville.EEW.Unity {
_ => throw new InvalidOperationException("Unknown Wolfx event type."), _ => throw new InvalidOperationException("Unknown Wolfx event type."),
})); }));
worker.IsFilterWhitelist = config.IsFilterWhitelist; worker.IsFilterWhitelist = config.IsFilterWhitelist;
_cencEarthquakeRVMGenerator.UseRawLocationName
= _cencEarthquakeTTSMessageGenerator.UseRawLocationName
= config.UseRawCENCLocationName;
return worker; return worker;
} }
static BMKGOpenDataWorker BuildBMKGOpenDataWorkerUris(BMKGOpenDataWorker worker, BMKGOpenDataEventSourceConfig config) { static BMKGOpenDataWorker BuildBMKGOpenDataWorkerUris(BMKGOpenDataWorker worker, BMKGOpenDataEventSourceConfig config) {

Binary file not shown.

View File

@@ -0,0 +1,78 @@
fileFormatVersion: 2
guid: 88e8ae9c8ce06934ab7681fb678d7b00
labels:
- RoslynAnalyzer
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 550171b48a648b34e9ce5f1aba6244f1
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,33 @@
fileFormatVersion: 2
guid: 0f848a4ea2f35e7449e584beee48c659
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -14,10 +14,10 @@
The shared instance of the <see cref="T:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext" /> class. The shared instance of the <see cref="T:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext" /> class.
</summary> </summary>
</member> </member>
<member name="P:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext.LocationConverter"> <member name="P:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext.NowcastWarningDelayTolerance">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext.NowcastWarningDelayTolerance"> <member name="M:Cryville.EEW.TTS.EmptyTTSMessageGeneratorContext.NameLocation(System.Double,System.Double,System.Globalization.CultureInfo,System.Globalization.CultureInfo@,System.String@)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="T:Cryville.EEW.TTS.ITTSMessageGeneratorContext"> <member name="T:Cryville.EEW.TTS.ITTSMessageGeneratorContext">
@@ -25,16 +25,22 @@
Represents a context used in TTS message generators. Represents a context used in TTS message generators.
</summary> </summary>
</member> </member>
<member name="P:Cryville.EEW.TTS.ITTSMessageGeneratorContext.LocationConverter">
<summary>
The location converter.
</summary>
</member>
<member name="P:Cryville.EEW.TTS.ITTSMessageGeneratorContext.NowcastWarningDelayTolerance"> <member name="P:Cryville.EEW.TTS.ITTSMessageGeneratorContext.NowcastWarningDelayTolerance">
<summary> <summary>
The delay tolerance before a nowcast warning event cannot trigger sounds and TTS. The delay tolerance before a nowcast warning event cannot trigger sounds and TTS.
</summary> </summary>
</member> </member>
<member name="M:Cryville.EEW.TTS.ITTSMessageGeneratorContext.NameLocation(System.Double,System.Double,System.Globalization.CultureInfo,System.Globalization.CultureInfo@,System.String@)">
<summary>
Names a location in a culture.
</summary>
<param name="lat">The latitude of the location.</param>
<param name="lon">The longitude of the location.</param>
<param name="localCulture">The local culture supported by the event itself.</param>
<param name="targetCulture">The target culture of the location name. When the method returns, set to the actual culture of the location name.</param>
<param name="name">The location name.</param>
<returns>Whether the name is given by the context. <see langword="false" /> if the generator should provide a local name instead.</returns>
</member>
<member name="T:Cryville.EEW.TTS.TTSEntry"> <member name="T:Cryville.EEW.TTS.TTSEntry">
<summary> <summary>
Represents an entry sent to a TTS worker. Represents an entry sent to a TTS worker.
@@ -101,7 +107,7 @@
</member> </member>
<member name="P:Cryville.EEW.TTS.TTSEntry.IssueTime"> <member name="P:Cryville.EEW.TTS.TTSEntry.IssueTime">
<summary> <summary>
The time when the entry is created. The time when the entry is created in UTC.
</summary> </summary>
</member> </member>
</members> </members>

Binary file not shown.

Binary file not shown.

View File

@@ -30,17 +30,17 @@
<param name="amount">The amount of phase to increment.</param> <param name="amount">The amount of phase to increment.</param>
<returns>The next delay value.</returns> <returns>The next delay value.</returns>
</member> </member>
<member name="T:Cryville.EEW.EmptyLocationConverter"> <member name="T:Cryville.EEW.EmptyLocationNamer">
<summary> <summary>
An empty <see cref="T:Cryville.EEW.ILocationConverter" />. An empty <see cref="T:Cryville.EEW.ILocationNamer" />.
</summary> </summary>
</member> </member>
<member name="P:Cryville.EEW.EmptyLocationConverter.Instance"> <member name="P:Cryville.EEW.EmptyLocationNamer.Instance">
<summary> <summary>
The shared instance of the <see cref="T:Cryville.EEW.EmptyLocationConverter" /> class. The shared instance of the <see cref="T:Cryville.EEW.EmptyLocationNamer" /> class.
</summary> </summary>
</member> </member>
<member name="M:Cryville.EEW.EmptyLocationConverter.Convert(Cryville.EEW.INamedLocation,System.Globalization.CultureInfo@)"> <member name="M:Cryville.EEW.EmptyLocationNamer.Name(System.Double,System.Double,System.Globalization.CultureInfo@,System.Int32@)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="T:Cryville.EEW.GeoUtils"> <member name="T:Cryville.EEW.GeoUtils">
@@ -213,18 +213,20 @@
<param name="culture">The preferred culture of the generated object. When the method returns, set to the actual culture of the generated object.</param> <param name="culture">The preferred culture of the generated object. When the method returns, set to the actual culture of the generated object.</param>
<returns>The generated object.</returns> <returns>The generated object.</returns>
</member> </member>
<member name="T:Cryville.EEW.ILocationConverter"> <member name="T:Cryville.EEW.ILocationNamer">
<summary> <summary>
Represents a converter that converts a named location to a name in a specified culture. Represents a namer that names a location in a specified culture.
</summary> </summary>
</member> </member>
<member name="M:Cryville.EEW.ILocationConverter.Convert(Cryville.EEW.INamedLocation,System.Globalization.CultureInfo@)"> <member name="M:Cryville.EEW.ILocationNamer.Name(System.Double,System.Double,System.Globalization.CultureInfo@,System.Int32@)">
<summary> <summary>
Converts a named location to a name in a specified culture. Names a location in a specified culture.
</summary> </summary>
<param name="location">The named location.</param> <param name="lat">The latitude.</param>
<param name="lon">The longitude.</param>
<param name="culture">The preferred culture of the name. When the method returns, set to the actual culture of the name.</param> <param name="culture">The preferred culture of the name. When the method returns, set to the actual culture of the name.</param>
<returns>The converted name.</returns> <param name="specificity">The preferred specificity of the name. When the method returns, set to the actual specificity of the name.</param>
<returns>The name.</returns>
</member> </member>
<member name="T:Cryville.EEW.ISourceWorker"> <member name="T:Cryville.EEW.ISourceWorker">
<summary> <summary>
@@ -349,6 +351,16 @@
<returns>The string of the specified name in the resource.</returns> <returns>The string of the specified name in the resource.</returns>
<exception cref="T:System.Collections.Generic.KeyNotFoundException">The string of the specified name is not found.</exception> <exception cref="T:System.Collections.Generic.KeyNotFoundException">The string of the specified name is not found.</exception>
</member> </member>
<member name="M:Cryville.EEW.MessageStringSetExtensions.GetStringOrDefault(Cryville.EEW.IMessageStringSet,System.String,System.String)">
<summary>
Gets a string in the string set, or a default string in the string set if not found.
</summary>
<param name="set">The string set.</param>
<param name="name">The name of the string.</param>
<param name="defaultName">The name of the default string.</param>
<returns>The string of the specified name in the resource, or the default string of the specified default name in the string set if not found.</returns>
<exception cref="T:System.Collections.Generic.KeyNotFoundException">The default string of the specified default name is not found.</exception>
</member>
<member name="M:Cryville.EEW.MessageStringSetExtensions.GetStringSetRequired(Cryville.EEW.IMessageStringSet,System.String)"> <member name="M:Cryville.EEW.MessageStringSetExtensions.GetStringSetRequired(Cryville.EEW.IMessageStringSet,System.String)">
<summary> <summary>
Gets a string set in the string set. Gets a string set in the string set.
@@ -960,61 +972,6 @@
</summary> </summary>
<param name="value">An instance of the <see cref="T:Cryville.EEW.Models.XmlSerializedDateTimeOffset" /> struct.</param> <param name="value">An instance of the <see cref="T:Cryville.EEW.Models.XmlSerializedDateTimeOffset" /> struct.</param>
</member> </member>
<member name="T:Cryville.EEW.INamedLocation">
<summary>
Represents a named location.
</summary>
</member>
<member name="P:Cryville.EEW.INamedLocation.Name">
<summary>
The source name of the location.
</summary>
</member>
<member name="P:Cryville.EEW.INamedLocation.Culture">
<summary>
The source culture of <see cref="P:Cryville.EEW.INamedLocation.Name" />.
</summary>
</member>
<member name="P:Cryville.EEW.INamedLocation.Latitude">
<summary>
The latitude of the location.
</summary>
</member>
<member name="P:Cryville.EEW.INamedLocation.Longitude">
<summary>
The longitude of the location.
</summary>
</member>
<member name="T:Cryville.EEW.NamedLocation">
<summary>
Represents a named location.
</summary>
<param name="Name">The source name of the location.</param>
<param name="Culture">The source culture of <paramref name="Name" />.</param>
<param name="Latitude">The latitude of the location.</param>
<param name="Longitude">The longitude of the location.</param>
</member>
<member name="M:Cryville.EEW.NamedLocation.#ctor(System.String,System.Globalization.CultureInfo,System.Double,System.Double)">
<summary>
Represents a named location.
</summary>
<param name="Name">The source name of the location.</param>
<param name="Culture">The source culture of <paramref name="Name" />.</param>
<param name="Latitude">The latitude of the location.</param>
<param name="Longitude">The longitude of the location.</param>
</member>
<member name="P:Cryville.EEW.NamedLocation.Name">
<summary>The source name of the location.</summary>
</member>
<member name="P:Cryville.EEW.NamedLocation.Culture">
<summary>The source culture of <paramref name="Name" />.</summary>
</member>
<member name="P:Cryville.EEW.NamedLocation.Latitude">
<summary>The latitude of the location.</summary>
</member>
<member name="P:Cryville.EEW.NamedLocation.Longitude">
<summary>The longitude of the location.</summary>
</member>
<member name="T:Cryville.EEW.NonstandardDateTimeJsonConverter"> <member name="T:Cryville.EEW.NonstandardDateTimeJsonConverter">
<summary> <summary>
Converts instances of the <see cref="T:System.DateTime" /> struct to or from JSON. Converts instances of the <see cref="T:System.DateTime" /> struct to or from JSON.
@@ -1039,7 +996,7 @@
<member name="P:Cryville.EEW.Report.EmptyRVMGeneratorContext.SeverityScheme"> <member name="P:Cryville.EEW.Report.EmptyRVMGeneratorContext.SeverityScheme">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="P:Cryville.EEW.Report.EmptyRVMGeneratorContext.LocationConverter"> <member name="M:Cryville.EEW.Report.EmptyRVMGeneratorContext.NameLocation(System.Double,System.Double,System.Globalization.CultureInfo,System.Globalization.CultureInfo@,System.String@,System.Int32@)">
<inheritdoc /> <inheritdoc />
</member> </member>
<member name="T:Cryville.EEW.Report.EmptySeverityScheme"> <member name="T:Cryville.EEW.Report.EmptySeverityScheme">
@@ -1192,10 +1149,34 @@
The severity scheme. The severity scheme.
</summary> </summary>
</member> </member>
<member name="P:Cryville.EEW.Report.IRVMGeneratorContext.LocationConverter"> <member name="M:Cryville.EEW.Report.IRVMGeneratorContext.NameLocation(System.Double,System.Double,System.Globalization.CultureInfo,System.Globalization.CultureInfo@,System.String@,System.Int32@)">
<summary> <summary>
The location converter. Names a location in a culture.
</summary> </summary>
<param name="lat">The latitude of the location.</param>
<param name="lon">The longitude of the location.</param>
<param name="localCulture">The local culture supported by the event itself.</param>
<param name="targetCulture">The target culture of the location name. When the method returns, set to the actual culture of the location name.</param>
<param name="name">The location name.</param>
<param name="specificity">The location specificity. See <see cref="P:Cryville.EEW.Report.ReportViewModel.LocationSpecificity" />.</param>
<returns>Whether the name is given by the context. <see langword="false" /> if the generator should provide a local name instead.</returns>
</member>
<member name="T:Cryville.EEW.Report.RVMGeneratorContextExtensions">
<summary>
Provides a set of <see langword="static" /> methods related to <see cref="T:Cryville.EEW.Report.IRVMGeneratorContext" />.
</summary>
</member>
<member name="M:Cryville.EEW.Report.RVMGeneratorContextExtensions.NameLocationTo(Cryville.EEW.Report.IRVMGeneratorContext,Cryville.EEW.Report.ReportViewModel,System.Double,System.Double,System.Globalization.CultureInfo,System.Globalization.CultureInfo)">
<summary>
Names a location in a culture and sets the result to a report view model.
</summary>
<param name="context">The context.</param>
<param name="e">The report view model.</param>
<param name="lat">The latitude of the location.</param>
<param name="lon">The longitude of the location.</param>
<param name="localCulture">The local culture supported by the event itself.</param>
<param name="targetCulture">The target culture of the location name. When the method returns, set to the actual culture of the location name.</param>
<returns>Whether the name is given by the context. <see langword="false" /> if the generator should provide a local name instead.</returns>
</member> </member>
<member name="T:Cryville.EEW.Report.ISeverityScheme"> <member name="T:Cryville.EEW.Report.ISeverityScheme">
<summary> <summary>
@@ -1525,6 +1506,16 @@
The culture <c>zh-TW</c>. The culture <c>zh-TW</c>.
</summary> </summary>
</member> </member>
<member name="F:Cryville.EEW.SharedCultures.CurrentCulture">
<summary>
The current culture.
</summary>
</member>
<member name="F:Cryville.EEW.SharedCultures.CurrentUICulture">
<summary>
The current UI culture.
</summary>
</member>
<member name="M:Cryville.EEW.SharedCultures.Get(System.String)"> <member name="M:Cryville.EEW.SharedCultures.Get(System.String)">
<summary> <summary>
Gets a culture of the specified name. Gets a culture of the specified name.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,132 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2984379317001549352
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2984379317001549359}
- component: {fileID: 2962259339337128397}
m_Layer: 0
m_Name: RegionView
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2984379317001549359
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2984379317001549352}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 3524170046801625328}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2962259339337128397
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2984379317001549352}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c57a0e86eb63b6048ba265e9d98e84f6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_spriteRenderer: {fileID: 3524170046801625329}
--- !u!1 &3524170046801625335
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3524170046801625328}
- component: {fileID: 3524170046801625329}
m_Layer: 0
m_Name: Area
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3524170046801625328
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3524170046801625335}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0.5, y: 0.5, z: 1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2984379317001549359}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &3524170046801625329
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3524170046801625335}
m_Enabled: 1
m_CastShadows: 0
m_ReceiveShadows: 0
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 0
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 0
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_Sprite: {fileID: 7482667652216324306, guid: 311925a002f4447b3a28927169b83ea6, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 0.2509804}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: bcdaa327335962646879336458cd7379
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

1973
Assets/RegionEditor.unity Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8d07fde72bae47a4990c95f764ca2b43
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -6,7 +6,7 @@
"HeadlineMagnitude": " of magnitude {0:F1}", "HeadlineMagnitude": " of magnitude {0:F1}",
"MaxIntensity": "The maximum intensity observed is {0}.", "MaxIntensity": "The maximum intensity observed is {0}.",
"Region": "The epicenter is in {0}.", "Region": "The epicenter is in {0}.",
"Title": "Earthquake Data.", "Title": "Earthquake data.",
"TitleStandAlone": "Earthquake Data" "TitleStandAlone": "Earthquake data"
} }
} }

View File

@@ -6,7 +6,7 @@
"HeadlineMagnitude": ", dengan magnitudo {0:F1}", "HeadlineMagnitude": ", dengan magnitudo {0:F1}",
"MaxIntensity": "Intensitas gempa maksimum yang dirasakan adalah {0}.", "MaxIntensity": "Intensitas gempa maksimum yang dirasakan adalah {0}.",
"Region": "Pusat gempa berada di {0}.", "Region": "Pusat gempa berada di {0}.",
"Title": "Data Gempabumi.", "Title": "Data gempabumi.",
"TitleStandAlone": "Data Gempabumi" "TitleStandAlone": "Data gempabumi"
} }
} }

View File

@@ -3,7 +3,7 @@
"Strings": { "Strings": {
"Headline": "印度尼西亞西部時間{0},發生咗一次{1}地震。{2}", "Headline": "印度尼西亞西部時間{0},發生咗一次{1}地震。{2}",
"HeadlineDepth": "震源深度{0}公里。", "HeadlineDepth": "震源深度{0}公里。",
"HeadlineMagnitude": "規模{0:F1}級", "HeadlineMagnitude": "震級{0:F1}級",
"MaxIntensity": "觀測到嘅最大烈度為{0}。", "MaxIntensity": "觀測到嘅最大烈度為{0}。",
"Region": "震中位於{0}。", "Region": "震中位於{0}。",
"Title": "地震數據。", "Title": "地震數據。",

View File

@@ -3,7 +3,7 @@
"Strings": { "Strings": {
"Headline": "印度尼西亞西部時間{0},發生了一次{1}地震。{2}", "Headline": "印度尼西亞西部時間{0},發生了一次{1}地震。{2}",
"HeadlineDepth": "震源深度{0}公里。", "HeadlineDepth": "震源深度{0}公里。",
"HeadlineMagnitude": "規模{0:F1}級", "HeadlineMagnitude": "規模{0:F1}級",
"MaxIntensity": "觀測到的最大震度為{0}。", "MaxIntensity": "觀測到的最大震度為{0}。",
"Region": "震中位於{0}。", "Region": "震中位於{0}。",
"Title": "地震數據。", "Title": "地震數據。",

View File

@@ -3,7 +3,7 @@
"Strings": { "Strings": {
"Headline": "印度尼西亚西部时间{0},发生了一次{1}地震。{2}", "Headline": "印度尼西亚西部时间{0},发生了一次{1}地震。{2}",
"HeadlineDepth": "震源深度{0}千米。", "HeadlineDepth": "震源深度{0}千米。",
"HeadlineMagnitude": "规模{0:F1}级", "HeadlineMagnitude": "震级{0:F1}级",
"MaxIntensity": "观测到的最大烈度为{0}。", "MaxIntensity": "观测到的最大烈度为{0}。",
"Region": "震中位于{0}。", "Region": "震中位于{0}。",
"Title": "地震数据。", "Title": "地震数据。",

View File

@@ -1,6 +1,12 @@
{ {
"Culture": "en-US", "Culture": "en-US",
"Strings": { "Strings": {
"SourceName": "BMKG Open Data" "AuthorityName": "BMKG",
"PropertyDepth": "Depth",
"PropertyDepthValue": "{0}km",
"PropertyMagnitude": "M",
"PropertyMaxIntensity": "Max intensity",
"SourceName": "BMKG Open Data",
"Title": "Earthquake data"
} }
} }

View File

@@ -1,6 +1,12 @@
{ {
"Culture": "id-ID", "Culture": "id-ID",
"Strings": { "Strings": {
"SourceName": "Data Terbuka BMKG" "AuthorityName": "BMKG",
"PropertyDepth": "Kedalaman",
"PropertyDepthValue": "{0}km",
"PropertyMagnitude": "M",
"PropertyMaxIntensity": "Intensitas maks.",
"SourceName": "Data Terbuka BMKG",
"Title": "Data gempabumi"
} }
} }

View File

@@ -1,6 +1,12 @@
{ {
"Culture": "yue-HK", "Culture": "yue-HK",
"Strings": { "Strings": {
"SourceName": "BMKG 開放數據" "AuthorityName": "BMKG",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMagnitude": "M",
"PropertyMaxIntensity": "最大烈度",
"SourceName": "BMKG 開放數據",
"Title": "地震數據"
} }
} }

View File

@@ -1,6 +1,12 @@
{ {
"Culture": "zh-TW", "Culture": "zh-TW",
"Strings": { "Strings": {
"SourceName": "BMKG 開放數據" "AuthorityName": "BMKG",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMagnitude": "M",
"PropertyMaxIntensity": "最大震度",
"SourceName": "BMKG 開放數據",
"Title": "地震數據"
} }
} }

View File

@@ -1,6 +1,12 @@
{ {
"Culture": "zh-CN", "Culture": "zh-CN",
"Strings": { "Strings": {
"SourceName": "BMKG 开放数据" "AuthorityName": "BMKG",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMagnitude": "M",
"PropertyMaxIntensity": "最大烈度",
"SourceName": "BMKG 开放数据",
"Title": "地震数据"
} }
} }

View File

@@ -13,6 +13,7 @@
"Title": { "Title": {
"Strings": { "Strings": {
"地震報告": "Earthquake report", "地震報告": "Earthquake report",
"海嘯消息": "Tsunami message",
"海嘯警報": "Tsunami warning", "海嘯警報": "Tsunami warning",
"海嘯警報解除": "Tsunami warning lifted" "海嘯警報解除": "Tsunami warning lifted"
} }

View File

@@ -1,7 +1,7 @@
{ {
"Culture": "yue-HK", "Culture": "yue-HK",
"Strings": { "Strings": {
"EarthquakeBody": "{0}{1}發生規模{2:F1}有感地震,最大震度{3}。", "EarthquakeBody": "{0}{1}發生震級{2:F1}有感地震,最大震度{3}。",
"EarthquakeFocalDepth": "震源深度{0}公里。", "EarthquakeFocalDepth": "震源深度{0}公里。",
"TsunamiForecast": "以下地區預計海嘯高度{0}。", "TsunamiForecast": "以下地區預計海嘯高度{0}。",
"TsunamiForecastArea": "{0}。預計到達時間{1:HH:mm}。", "TsunamiForecastArea": "{0}。預計到達時間{1:HH:mm}。",
@@ -13,6 +13,7 @@
"Title": { "Title": {
"Strings": { "Strings": {
"地震報告": "地震報告", "地震報告": "地震報告",
"海嘯消息": "海嘯消息",
"海嘯警報": "海嘯警報", "海嘯警報": "海嘯警報",
"海嘯警報解除": "海嘯警報解除" "海嘯警報解除": "海嘯警報解除"
} }

View File

@@ -1,7 +1,7 @@
{ {
"Culture": "zh-CN", "Culture": "zh-CN",
"Strings": { "Strings": {
"EarthquakeBody": "{0}{1}发生规模{2:F1}有感地震,最大震度{3}。", "EarthquakeBody": "{0}{1}发生震级{2:F1}有感地震,最大震度{3}。",
"EarthquakeFocalDepth": "震源深度{0}千米。", "EarthquakeFocalDepth": "震源深度{0}千米。",
"TsunamiForecast": "以下地区预计海啸高度{0}。", "TsunamiForecast": "以下地区预计海啸高度{0}。",
"TsunamiForecastArea": "{0}。预计到达时间{1:HH:mm}。", "TsunamiForecastArea": "{0}。预计到达时间{1:HH:mm}。",
@@ -13,6 +13,7 @@
"Title": { "Title": {
"Strings": { "Strings": {
"地震報告": "地震报告", "地震報告": "地震报告",
"海嘯消息": "海啸消息",
"海嘯警報": "海啸警报", "海嘯警報": "海啸警报",
"海嘯警報解除": "海啸警报解除" "海嘯警報解除": "海啸警报解除"
} }

View File

@@ -1,6 +1,15 @@
{ {
"Culture": "en-US", "Culture": "en-US",
"Strings": { "Strings": {
"AuthorityName": "CWA",
"PropertyDepth": "Depth",
"PropertyDepthValue": "{0}km",
"PropertyMaxIntensity": "Max intensity",
"PropertyMaxTsunamiHeight": "Max tsunami height",
"PropertyMaxTsunamiHeightValue": "{0}m",
"PropertyMaxTsunamiHeightValueUnknown": "Unknown",
"PropertyTsunamiMessage": "Tsunami message",
"PropertyTsunamiWarning": "Tsunami warning",
"SourceName": "CWA ({0})" "SourceName": "CWA ({0})"
}, },
"StringSets": { "StringSets": {
@@ -9,6 +18,20 @@
"Earthquake": "Earthquake", "Earthquake": "Earthquake",
"Tsunami": "Tsunami" "Tsunami": "Tsunami"
} }
},
"PropertyMagnitude": {
"Strings": {
"": "Magnitude",
"芮氏規模": "Richter magnitude"
}
},
"Title": {
"Strings": {
"地震報告": "Earthquake report",
"海嘯消息": "Tsunami message",
"海嘯警報": "Tsunami warning",
"海嘯警報解除": "Tsunami warning lifted"
}
} }
} }
} }

View File

@@ -1,6 +1,15 @@
{ {
"Culture": "zh-TW", "Culture": "zh-TW",
"Strings": { "Strings": {
"AuthorityName": "CWA",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMaxIntensity": "最大震度",
"PropertyMaxTsunamiHeight": "最大波高",
"PropertyMaxTsunamiHeightValue": "{0}m",
"PropertyMaxTsunamiHeightValueUnknown": "不明",
"PropertyTsunamiMessage": "海\u2060嘯消\u2060息",
"PropertyTsunamiWarning": "海\u2060嘯警\u2060報",
"SourceName": "CWA{0}" "SourceName": "CWA{0}"
}, },
"StringSets": { "StringSets": {
@@ -9,6 +18,20 @@
"Earthquake": "地震", "Earthquake": "地震",
"Tsunami": "海嘯" "Tsunami": "海嘯"
} }
},
"PropertyMagnitude": {
"Strings": {
"": "規模",
"芮氏規模": "芮氏規模"
}
},
"Title": {
"Strings": {
"地震報告": "地震報告",
"海嘯消息": "海嘯消息",
"海嘯警報": "海嘯警報",
"海嘯警報解除": "海嘯警報解除"
}
} }
} }
} }

View File

@@ -1,6 +1,15 @@
{ {
"Culture": "yue-HK", "Culture": "yue-HK",
"Strings": { "Strings": {
"AuthorityName": "CWA",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMaxIntensity": "最大震度",
"PropertyMaxTsunamiHeight": "最大波高",
"PropertyMaxTsunamiHeightValue": "{0}m",
"PropertyMaxTsunamiHeightValueUnknown": "不明",
"PropertyTsunamiMessage": "海\u2060嘯消\u2060息",
"PropertyTsunamiWarning": "海\u2060嘯警\u2060報",
"SourceName": "CWA{0}" "SourceName": "CWA{0}"
}, },
"StringSets": { "StringSets": {
@@ -9,6 +18,20 @@
"Earthquake": "地震", "Earthquake": "地震",
"Tsunami": "海嘯" "Tsunami": "海嘯"
} }
},
"PropertyMagnitude": {
"Strings": {
"": "震級",
"芮氏規模": "黎克特制震級"
}
},
"Title": {
"Strings": {
"地震報告": "地震報告",
"海嘯消息": "海嘯消息",
"海嘯警報": "海嘯警報",
"海嘯警報解除": "海嘯警報解除"
}
} }
} }
} }

View File

@@ -1,6 +1,15 @@
{ {
"Culture": "zh-CN", "Culture": "zh-CN",
"Strings": { "Strings": {
"AuthorityName": "CWA",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"PropertyMaxIntensity": "最大震度",
"PropertyMaxTsunamiHeight": "最大波高",
"PropertyMaxTsunamiHeightValue": "{0}m",
"PropertyMaxTsunamiHeightValueUnknown": "不明",
"PropertyTsunamiMessage": "海\u2060啸消\u2060息",
"PropertyTsunamiWarning": "海\u2060啸警\u2060报",
"SourceName": "CWA{0}" "SourceName": "CWA{0}"
}, },
"StringSets": { "StringSets": {
@@ -9,6 +18,20 @@
"Earthquake": "地震", "Earthquake": "地震",
"Tsunami": "海啸" "Tsunami": "海啸"
} }
},
"PropertyMagnitude": {
"Strings": {
"": "震级",
"芮氏規模": "里氏震级"
}
},
"Title": {
"Strings": {
"地震報告": "地震报告",
"海嘯消息": "海啸消息",
"海嘯警報": "海啸警报",
"海嘯警報解除": "海啸警报解除"
}
} }
} }
} }

View File

@@ -1,6 +1,11 @@
{ {
"Culture": "en-US", "Culture": "en-US",
"Strings": { "Strings": {
"SourceName": "EMSC" "AuthorityName": "EMSC",
"AuthorityNameForwarded": "EMSC | {0}",
"PropertyDepth": "Depth",
"PropertyDepthValue": "{0}km",
"SourceName": "EMSC",
"Title": "Earthquake event"
} }
} }

View File

@@ -0,0 +1,11 @@
{
"Culture": "yue-HK",
"Strings": {
"AuthorityName": "EMSC",
"AuthorityNameForwarded": "EMSC | {0}",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"SourceName": "EMSC",
"Title": "地震事件"
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 9c44f369185730644b6e777e84ee0569 guid: 0bc7279c4dd92ae43afb3f503643a84c
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@@ -0,0 +1,11 @@
{
"Culture": "zh-TW",
"Strings": {
"AuthorityName": "EMSC",
"AuthorityNameForwarded": "EMSC | {0}",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"SourceName": "EMSC",
"Title": "地震事件"
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 704940476687b1b43a713305dd275d3c guid: dcc04accbfc4e6b43a60d0bac2a76202
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:

View File

@@ -0,0 +1,11 @@
{
"Culture": "zh-CN",
"Strings": {
"AuthorityName": "EMSC",
"AuthorityNameForwarded": "EMSC | {0}",
"PropertyDepth": "深度",
"PropertyDepthValue": "{0}km",
"SourceName": "EMSC",
"Title": "地震事件"
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 643c09fce5fa33048a0a599cab63f9e3 guid: c900640f0d0bccc42a6017504c74a8cb
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:

Some files were not shown because too many files have changed in this diff Show More