From 4f195449b92de519daacbc2e76945fc1a6762d1d Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 8 Feb 2021 10:12:21 +0100 Subject: [PATCH 01/18] Tile key now uses the key defined by Imageset --- engine/wwtlib/Tile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/wwtlib/Tile.cs b/engine/wwtlib/Tile.cs index b7e03b11..30cea54a 100644 --- a/engine/wwtlib/Tile.cs +++ b/engine/wwtlib/Tile.cs @@ -945,7 +945,7 @@ public String Key { get { - return dataset.ImageSetID.ToString() + @"\" + Level.ToString() + @"\" + tileY.ToString() + "_" + tileX.ToString(); + return Imageset.GetTileKey(dataset, Level, tileX, tileY, Parent); } } From 3aea70679930a1310b99b015232cc56b8ebec1cb Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 8 Feb 2021 10:15:10 +0100 Subject: [PATCH 02/18] WebFile now treats http codes >= 400 as errors --- engine/wwtlib/WebFile.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/engine/wwtlib/WebFile.cs b/engine/wwtlib/WebFile.cs index 8db22121..1df3d7da 100644 --- a/engine/wwtlib/WebFile.cs +++ b/engine/wwtlib/WebFile.cs @@ -132,14 +132,22 @@ private void CORS() } else { - if (ResponseType == "") + if(xhr.Status >= 400) { - LoadData(xhr.ResponseText); - } - else + _message = xhr.StatusText; + State = StateType.Error; + } else { - LoadBlob(xhr.Response); + if (ResponseType == "") + { + LoadData(xhr.ResponseText); + } + else + { + LoadBlob(xhr.Response); + } } + } } From 927ed7c6e49a1c92f922a178404b2adfda211a68 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 8 Feb 2021 10:17:36 +0100 Subject: [PATCH 03/18] Removed unused call --- engine/wwtlib/WWTControl.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/engine/wwtlib/WWTControl.cs b/engine/wwtlib/WWTControl.cs index d653bc4e..e2a0a375 100644 --- a/engine/wwtlib/WWTControl.cs +++ b/engine/wwtlib/WWTControl.cs @@ -687,8 +687,6 @@ public void RenderOneFrame() Matrix3d viewSave = RenderContext.View; Matrix3d projSave = RenderContext.Projection; - Vector2d raDecDownDown = GetCoordinatesForScreenPoint(RenderContext.Width / 2, RenderContext.Height / 2); - if (Settings.Current.ShowCrosshairs) { DrawCrosshairs(RenderContext); From faff368ffeb6b5d354754fecd1ae34a973c2eae1 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 8 Feb 2021 14:20:58 +0100 Subject: [PATCH 04/18] Basic HiPS catalog support --- engine/wwtlib/HealpixTile.cs | 279 ++++++++++++++++++++++----- engine/wwtlib/HipsProperties.cs | 5 + engine/wwtlib/Layers/LayerManager.cs | 7 +- engine/wwtlib/Layers/VoTableLayer.cs | 68 +++++-- 4 files changed, 298 insertions(+), 61 deletions(-) diff --git a/engine/wwtlib/HealpixTile.cs b/engine/wwtlib/HealpixTile.cs index 60a21672..c9053ecc 100644 --- a/engine/wwtlib/HealpixTile.cs +++ b/engine/wwtlib/HealpixTile.cs @@ -21,7 +21,9 @@ public class HealpixTile : Tile private int step; private string url; private bool subDivided = false; - private static Matrix3d galacticMatrix = Matrix3d.Create( + private bool catalogRowsAdded = false; + private readonly List CatalogRows = new List(); + private static readonly Matrix3d galacticMatrix = Matrix3d.Create( -0.0548755604024359, -0.4838350155267381, -0.873437090247923, 0, -0.8676661489811610, 0.4559837762325372, -0.1980763734646737, 0, 0.4941094279435681, 0.7469822444763707, -0.4448296299195045, 0, @@ -75,7 +77,7 @@ public HealpixTile(int level, int x, int y, Imageset dataset, Tile parent) this.faceY = parentTile.faceY * 2 + y; } - + IsCatalogTile = dataset.Extension.ToLowerCase().IndexOf("tsv") > -1; // All healpix is inside out //insideOut = true; ComputeBoundingSphere(); @@ -224,29 +226,24 @@ private string GetHipsFileExtention() //prioritize transparent Png over other image formats if (dataset.Extension.ToLowerCase().IndexOf("png") > -1) { - IsCatalogTile = false; return ".png"; } // Check for either type if (dataset.Extension.ToLowerCase().IndexOf("jpeg") > -1 || dataset.Extension.ToLowerCase().IndexOf("jpg") > -1) { - IsCatalogTile = false; return ".jpg"; } if (dataset.Extension.ToLowerCase().IndexOf("tsv") > -1) { - IsCatalogTile = true; return ".tsv"; } if (dataset.Extension.ToLowerCase().IndexOf("fits") > -1) { - IsCatalogTile = false; return ".fits"; } - IsCatalogTile = false; //default to most common return ".jpg"; @@ -292,6 +289,11 @@ private void SetCorners() public override bool Draw3D(RenderContext renderContext, double opacity) { + if (IsCatalogTile) + { + DrawCatalogTile(renderContext, opacity); + return true; + } RenderedGeneration = CurrentRenderGeneration; TilesTouched++; @@ -362,15 +364,6 @@ public override bool Draw3D(RenderContext renderContext, double opacity) { renderChildPart[childIndex].TargetState = renderChildPart[childIndex].State = false; } - - //if (renderChildPart[childIndex].TargetState == true || !blendMode) - //{ - // renderChildPart[childIndex].State = renderChildPart[childIndex].TargetState; - //} - //if (renderChildPart[childIndex].TargetState != renderChildPart[childIndex].State) - //{ - // transitioning = true; - //} } else { @@ -400,7 +393,6 @@ public override bool Draw3D(RenderContext renderContext, double opacity) Parent.RenderedAtOrBelowGeneration = RenderedAtOrBelowGeneration; } } - if (!anythingToRender) { return true; @@ -418,7 +410,6 @@ public override bool Draw3D(RenderContext renderContext, double opacity) TilesInView++; - for (int i = 0; i < 4; i++) { if (renderChildPart[i].TargetState) @@ -430,33 +421,233 @@ public override bool Draw3D(RenderContext renderContext, double opacity) return true; } + public void DrawCatalogTile(RenderContext renderContext, double opacity) + { + RenderedGeneration = CurrentRenderGeneration; + TilesTouched++; + + InViewFrustum = true; + bool onlyDrawChildren = false; + + if (!ReadyToRender) + { + if (!errored) + { + TileCache.AddTileToQueue(this); + return; + } + + if (errored && Level < 3) //Level 0-2 sometimes deleted in favor of allsky.jpg/tsv + { + onlyDrawChildren = true; + } + else + { + return; + } + } + + bool anyChildInFrustum = false; + int childIndex = 0; + for (int y1 = 0; y1 < 2; y1++) + { + for (int x1 = 0; x1 < 2; x1++) + { + if (Level < dataset.Levels) + { + if (children[childIndex] == null) + { + children[childIndex] = TileCache.GetTile(Level + 1, x1, y1, dataset, this); + } + + if (children[childIndex].IsTileInFrustum(renderContext.Frustum)) + { + InViewFrustum = true; + anyChildInFrustum = true; + if (children[childIndex].IsTileBigEnough(renderContext) || onlyDrawChildren) + { + ((HealpixTile)children[childIndex]).DrawCatalogTile(renderContext, opacity); + } + else + { + ((HealpixTile)children[childIndex]).RemoveCatalogTile(); + } + } + else + { + ((HealpixTile)children[childIndex]).RemoveCatalogTile(); + } + } + + childIndex++; + } + } + if (Level == 0 && !anyChildInFrustum && !onlyDrawChildren) + { + RemoveCatalogTile(); + } else if (anyChildInFrustum) + { + TilesInView++; + AddCatalogTile(renderContext, (float)opacity); + } + } + + public void RemoveCatalogTile() + { + if (catalogRowsAdded) + { + foreach (Tile child in children) + { + if(child != null) + { + ((HealpixTile)child).RemoveCatalogTile(); + } + } + VoTable table = dataset.HipsProperties.CatalogVoTable; + + foreach (VoRow row in CatalogRows) + { + table.Rows.Remove(row); + } + catalogRowsAdded = false; + + dataset.HipsProperties.CatalogVoTableLayer.CleanUp(); + } + } + + public bool AddCatalogTile(RenderContext renderContext, float opacity) + { + if (!catalogRowsAdded) + { + catalogRowsAdded = true; + VoTable table = dataset.HipsProperties.CatalogVoTable; + + foreach (VoRow row in CatalogRows) + { + row.Owner = table; + table.Rows.Add(row); + } + if (dataset.HipsProperties.CatalogVoTableLayer == null) + { + dataset.HipsProperties.CatalogVoTableLayer = LayerManager.AddVoTableLayerWithPlotType(table, dataset.Name, PlotTypes.Circle); + } else + { + dataset.HipsProperties.CatalogVoTableLayer.CleanUp(); + } + } + + return true; + } + + private WebFile catalogData; + private void SetStep() { - switch (Level) - { - case 0: - case 1: - case 2: - step = 64; - break; - case 3: - step = 32; - break; - case 4: - step = 16; - break; - case 5: - step = 8; - break; - case 6: - step = 4; - break; - case 7: - step = 2; - break; - default: - step = 2; - break; + if (IsCatalogTile) + { + step = 2; + } else + { + switch (Level) + { + case 0: + case 1: + case 2: + step = 64; + break; + case 3: + step = 32; + break; + case 4: + step = 16; + break; + case 5: + step = 8; + break; + case 6: + step = 4; + break; + default: + step = 2; + break; + } + } + } + + + public override void RequestImage() + { + if (IsCatalogTile) + { + if (!Downloading && !ReadyToRender) + { + Downloading = true; + catalogData = new WebFile(this.URL); + catalogData.OnStateChange = LoadCatalogData; + catalogData.Send(); + } + } + else + { + base.RequestImage(); + } + + } + + private void LoadCatalogData() + { + if (catalogData.State == StateType.Error) + { + RequestPending = false; + Downloading = false; + errored = true; + TileCache.RemoveFromQueue(this.Key, true); + } + else if (catalogData.State == StateType.Received) + { + string tableData = ""; + bool header = true; + foreach (string line in catalogData.GetText().Split("\n")) + { + if (!line.StartsWith("#") && header) + { + tableData += line.Replace("RAJ2000", "RA").Replace("DEJ2000", "Dec") + "\r\n"; + header = false; + continue; + } + + if (!line.StartsWith("#")) + { + tableData += line + "\r\n"; + } + } + Table table = new Table(); + table.LoadFromString(tableData, false, false, true); + header = true; + foreach (List row in table.Rows) + { + if (header) + { + header = false; + } else + { + VoRow voRow = new VoRow(dataset.HipsProperties.CatalogVoTable); + voRow.ColumnData = new object[dataset.HipsProperties.CatalogVoTable.Columns.Count]; + + for (int i = 0; i < row.Count; i++) + { + voRow.ColumnData[i] = row[i]; + } + CatalogRows.Add(voRow); + } + } + + texReady = true; + Downloading = false; + errored = false; + ReadyToRender = true; + RequestPending = false; + TileCache.RemoveFromQueue(this.Key, true); } } @@ -529,8 +720,6 @@ public override double GetSurfacePointAltitude(double lat, double lng, bool mete if (Level < lastDeepestLevel) { - //interate children - foreach (Tile child in children) { if (child != null) diff --git a/engine/wwtlib/HipsProperties.cs b/engine/wwtlib/HipsProperties.cs index 69ba1c9d..cb87093a 100644 --- a/engine/wwtlib/HipsProperties.cs +++ b/engine/wwtlib/HipsProperties.cs @@ -6,11 +6,16 @@ namespace wwtlib public class HipsProperties { public Dictionary Properties { get { return properties; } } + public VoTableLayer CatalogVoTableLayer { + get { return catalogVoTableLayer; } + set { catalogVoTableLayer = value; } + } public VoTable CatalogVoTable { get { return catalogVoTable; } } public bool DownloadComplete { get { return downloadComplete; } } private Dictionary properties = new Dictionary(); private VoTable catalogVoTable = null; + private VoTableLayer catalogVoTableLayer = null; private bool downloadComplete = false; private WebFile webFile; private readonly string url; diff --git a/engine/wwtlib/Layers/LayerManager.cs b/engine/wwtlib/Layers/LayerManager.cs index a4185bdd..bc15f39d 100644 --- a/engine/wwtlib/Layers/LayerManager.cs +++ b/engine/wwtlib/Layers/LayerManager.cs @@ -379,8 +379,11 @@ private static void AddMoons(string file) public static VoTableLayer AddVoTableLayer(VoTable table, string title) { - - VoTableLayer layer = VoTableLayer.Create(table); + return LayerManager.AddVoTableLayerWithPlotType(table, title, PlotTypes.Circle); + } + public static VoTableLayer AddVoTableLayerWithPlotType(VoTable table, string title, PlotTypes plotType) + { + VoTableLayer layer = VoTableLayer.Create(table, plotType); layer.Name = title; layer.Astronomical = true; layer.ReferenceFrame = "Sky"; diff --git a/engine/wwtlib/Layers/VoTableLayer.cs b/engine/wwtlib/Layers/VoTableLayer.cs index 9070a4d7..04e22d2a 100644 --- a/engine/wwtlib/Layers/VoTableLayer.cs +++ b/engine/wwtlib/Layers/VoTableLayer.cs @@ -883,16 +883,17 @@ public PointScaleTypes PointScaleType protected Date baseDate = new Date(2010, 0, 1, 12, 00, 00); - static ImageElement circleTexture = null; + static Texture circleTexture = null; - static ImageElement CircleTexture + static Texture CircleTexture { get { - //if (circleTexture == null) - //{ - // circleTexture = UiTools.LoadTextureFromBmp(Tile.prepDevice, Properties.Resources.circle, 0); - //} + if (circleTexture == null) + { + string url = URLHelpers.singleton.engineAssetUrl("circle.png"); + circleTexture = Planets.LoadPlanetTexture(url); + } return circleTexture; } @@ -956,12 +957,30 @@ public override bool Draw(RenderContext renderContext, float opacity, bool flat) if (pointList != null) { pointList.DepthBuffered = false; - pointList.Decay = decay; + pointList.ShowFarSide = ShowFarSide; + pointList.Decay = timeSeries ? decay : 0; pointList.Sky = this.Astronomical; pointList.TimeSeries = timeSeries; pointList.JNow = jNow; pointList.scale = (markerScale == MarkerScales.World) ? (float)adjustedScale : -(float)adjustedScale; - pointList.Draw(renderContext, opacity * Opacity, false); + switch (plotType) + { + case PlotTypes.Gaussian: + pointList.Draw(renderContext, opacity * Opacity, false); + break; + case PlotTypes.Circle: + case PlotTypes.Point: + case PlotTypes.Square: + pointList.DrawTextured(renderContext, CircleTexture.Texture2d, opacity * Opacity); + break; + case PlotTypes.Custom: + case PlotTypes.PushPin: + pointList.DrawTextured(renderContext, PushPin.GetPushPinTexture(markerIndex), opacity * Opacity); + break; + + default: + break; + } } if (lineList != null) @@ -1292,7 +1311,7 @@ public VoTableLayer() PlotType = PlotTypes.Circle; } - public static VoTableLayer Create(VoTable table) + public static VoTableLayer Create(VoTable table, PlotTypes plotType) { VoTableLayer layer = new VoTableLayer(); @@ -1300,7 +1319,8 @@ public static VoTableLayer Create(VoTable table) layer.filename = table.LoadFilename; layer.LngColumn = table.GetRAColumn().Index; layer.LatColumn = table.GetDecColumn().Index; - layer.PlotType = PlotTypes.Circle; + layer.sizeColumn = table.GetColumnByUcd("phot.mag").Index; + layer.PlotType = plotType; return layer; } @@ -1434,6 +1454,20 @@ public override Place FindClosest(Coordinates target, float distance, Place defa return place; } + private bool IsPointInFrustum(Vector3d position, PlaneD[] frustum) + { + Vector4d centerV4 = new Vector4d(position.X, position.Y, position.Z, 1f); + + for (int i = 0; i < 6; i++) + { + if (frustum[i].Dot(centerV4) < 0) + { + return false; + } + } + return true; + } + protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) { VoColumn col = table.GetColumnByUcd("meta.id"); @@ -1481,16 +1515,22 @@ protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) Color color = Color.FromArgb((int)(opacity * (float)Color.A), Color.R, Color.G, Color.B); pointScaleType = PointScaleTypes.StellarMagnitude; - foreach (VoRow row in table.Rows) { try { if (lngColumn > -1 && latColumn > -1) { - double Xcoord = Coordinates.ParseRA(row[this.LngColumn].ToString(), true) * 15; - double Ycoord = Coordinates.ParseDec(row[this.LatColumn].ToString()); - lastItem.Position = Coordinates.GeoTo3dDouble(Ycoord, Xcoord); + double ra = Double.Parse(row[this.LngColumn].ToString()); + double dec = Double.Parse(row[this.LatColumn].ToString()); + Vector3d position = Coordinates.GeoTo3dDouble(dec, ra); + + //if (!IsPointInFrustum(position, renderContext.Frustum)) + //{ + // //continue; + //} + + lastItem.Position = position; positions.Add(lastItem.Position); lastItem.Color = color; if (sizeColumn > -1) From 651995911de37200029be552f947589ed9eb33f9 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 8 Feb 2021 18:23:17 +0100 Subject: [PATCH 05/18] Bugfix: Last character of SplitString was ignored if it was a delimiter --- engine/wwtlib/UiTools.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/engine/wwtlib/UiTools.cs b/engine/wwtlib/UiTools.cs index 354676fe..e82ead8a 100644 --- a/engine/wwtlib/UiTools.cs +++ b/engine/wwtlib/UiTools.cs @@ -151,7 +151,16 @@ public static List SplitString(string data, string delimiter) } if (current == (data.Length - 1)) { - count++; + if (data.Substr(current, 1) == delimiter) + { + output.Add(data.Substr(start, count)); + output.Add(""); + return output; + } + else + { + count++; + } } if (current == (data.Length - 1) || (data.Substr(current, 1) == delimiter && delimiter == "\t") || (nestingLevel == 0 && data.Substr(current, 1) == delimiter)) From 056a0c75509f717dd212a6653edb1db348efc2d2 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 14 Feb 2021 18:57:02 +0100 Subject: [PATCH 06/18] Added getMagColumn for VoTable --- engine/wwtlib/Layers/VOTable.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/engine/wwtlib/Layers/VOTable.cs b/engine/wwtlib/Layers/VOTable.cs index 4ec45a8e..dc89753c 100644 --- a/engine/wwtlib/Layers/VOTable.cs +++ b/engine/wwtlib/Layers/VOTable.cs @@ -235,6 +235,19 @@ public VoColumn GetDecColumn() return null; } + public VoColumn GetMagColumn() + { + foreach (string key in Columns.Keys) + { + VoColumn col = Columns[key]; + if (col.Ucd.ToLowerCase().IndexOf("phot.mag") > -1 || col.Ucd.ToLowerCase().IndexOf("phot_mag") > -1) + { + return col; + } + } + return null; + } + public VoColumn GetDistanceColumn() { foreach (string key in Columns.Keys) From 386b33272338c95047327903c251032358cfaf45 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Mon, 15 Feb 2021 07:22:30 +0100 Subject: [PATCH 07/18] Switched to using SpreadsheetLayer instead of VoTableLayer for catalog HiPS --- engine/wwtlib/HealpixTile.cs | 95 ++---- engine/wwtlib/HipsProperties.cs | 19 +- engine/wwtlib/Imageset.cs | 2 +- engine/wwtlib/Layers/LayerManager.cs | 10 +- engine/wwtlib/Layers/SpreadSheetLayer.cs | 382 +++++++++++++---------- 5 files changed, 265 insertions(+), 243 deletions(-) diff --git a/engine/wwtlib/HealpixTile.cs b/engine/wwtlib/HealpixTile.cs index c9053ecc..91fe88a5 100644 --- a/engine/wwtlib/HealpixTile.cs +++ b/engine/wwtlib/HealpixTile.cs @@ -21,8 +21,9 @@ public class HealpixTile : Tile private int step; private string url; private bool subDivided = false; + private readonly List> catalogRows = new List>(); private bool catalogRowsAdded = false; - private readonly List CatalogRows = new List(); + private WebFile catalogData; private static readonly Matrix3d galacticMatrix = Matrix3d.Create( -0.0548755604024359, -0.4838350155267381, -0.873437090247923, 0, -0.8676661489811610, 0.4559837762325372, -0.1980763734646737, 0, @@ -488,7 +489,7 @@ public void DrawCatalogTile(RenderContext renderContext, double opacity) } else if (anyChildInFrustum) { TilesInView++; - AddCatalogTile(renderContext, (float)opacity); + AddCatalogTile(); } } @@ -496,51 +497,49 @@ public void RemoveCatalogTile() { if (catalogRowsAdded) { - foreach (Tile child in children) - { - if(child != null) - { - ((HealpixTile)child).RemoveCatalogTile(); - } - } - VoTable table = dataset.HipsProperties.CatalogVoTable; - - foreach (VoRow row in CatalogRows) + catalogRowsAdded = false; + foreach (List row in catalogRows) { - table.Rows.Remove(row); + dataset.HipsProperties.CatalogSpreadSheetLayer.Table.Rows.Remove(row); } - catalogRowsAdded = false; - - dataset.HipsProperties.CatalogVoTableLayer.CleanUp(); + dataset.HipsProperties.CatalogSpreadSheetLayer.dirty = true; } } - public bool AddCatalogTile(RenderContext renderContext, float opacity) + private void AddCatalogTile() { if (!catalogRowsAdded) { catalogRowsAdded = true; - VoTable table = dataset.HipsProperties.CatalogVoTable; - foreach (VoRow row in CatalogRows) + foreach(List row in catalogRows) { - row.Owner = table; - table.Rows.Add(row); + dataset.HipsProperties.CatalogSpreadSheetLayer.Table.Rows.Add(row); } - if (dataset.HipsProperties.CatalogVoTableLayer == null) + dataset.HipsProperties.CatalogSpreadSheetLayer.dirty = true; + } + + } + + private void ExtractCatalogTileRows() + { + bool headerRemoved = false; + foreach (string line in catalogData.GetText().Split("\n")) + { + if (!line.StartsWith("#") && !headerRemoved) { - dataset.HipsProperties.CatalogVoTableLayer = LayerManager.AddVoTableLayerWithPlotType(table, dataset.Name, PlotTypes.Circle); - } else + headerRemoved = true; + continue; + } + + if (!line.StartsWith("#")) { - dataset.HipsProperties.CatalogVoTableLayer.CleanUp(); + List rowData = UiTools.SplitString(line, dataset.HipsProperties.CatalogSpreadSheetLayer.Table.Delimiter); + catalogRows.Add(rowData); } } - - return true; } - private WebFile catalogData; - private void SetStep() { if (IsCatalogTile) @@ -605,43 +604,7 @@ private void LoadCatalogData() } else if (catalogData.State == StateType.Received) { - string tableData = ""; - bool header = true; - foreach (string line in catalogData.GetText().Split("\n")) - { - if (!line.StartsWith("#") && header) - { - tableData += line.Replace("RAJ2000", "RA").Replace("DEJ2000", "Dec") + "\r\n"; - header = false; - continue; - } - - if (!line.StartsWith("#")) - { - tableData += line + "\r\n"; - } - } - Table table = new Table(); - table.LoadFromString(tableData, false, false, true); - header = true; - foreach (List row in table.Rows) - { - if (header) - { - header = false; - } else - { - VoRow voRow = new VoRow(dataset.HipsProperties.CatalogVoTable); - voRow.ColumnData = new object[dataset.HipsProperties.CatalogVoTable.Columns.Count]; - - for (int i = 0; i < row.Count; i++) - { - voRow.ColumnData[i] = row[i]; - } - CatalogRows.Add(voRow); - } - } - + ExtractCatalogTileRows(); texReady = true; Downloading = false; errored = false; diff --git a/engine/wwtlib/HipsProperties.cs b/engine/wwtlib/HipsProperties.cs index cb87093a..710ad9d2 100644 --- a/engine/wwtlib/HipsProperties.cs +++ b/engine/wwtlib/HipsProperties.cs @@ -6,22 +6,26 @@ namespace wwtlib public class HipsProperties { public Dictionary Properties { get { return properties; } } - public VoTableLayer CatalogVoTableLayer { - get { return catalogVoTableLayer; } - set { catalogVoTableLayer = value; } + public SpreadSheetLayer CatalogSpreadSheetLayer + { + get { return catalogSpreadSheetLayer; } + set { catalogSpreadSheetLayer = value; } } - public VoTable CatalogVoTable { get { return catalogVoTable; } } + public bool DownloadComplete { get { return downloadComplete; } } private Dictionary properties = new Dictionary(); private VoTable catalogVoTable = null; - private VoTableLayer catalogVoTableLayer = null; + private SpreadSheetLayer catalogSpreadSheetLayer = new SpreadSheetLayer(); + private bool downloadComplete = false; private WebFile webFile; private readonly string url; + private string datasetName; - public HipsProperties (string datasetUrl) + public HipsProperties (string datasetUrl, string datasetName) { + this.datasetName = datasetName; if (datasetUrl.ToLowerCase().IndexOf("norder") > -1) { datasetUrl = datasetUrl.Substring(0, datasetUrl.ToLowerCase().IndexOf("norder")); @@ -56,6 +60,9 @@ private void OnPropertiesDownloadComplete() private void OnCatalogMetadataDownloadComplete () { + catalogSpreadSheetLayer.UseHeadersFromVoTable(catalogVoTable); + catalogSpreadSheetLayer.Name = datasetName; + LayerManager.AddSpreadsheetLayer(CatalogSpreadSheetLayer, "Sky"); downloadComplete = true; } diff --git a/engine/wwtlib/Imageset.cs b/engine/wwtlib/Imageset.cs index ee129eae..bc50e92c 100644 --- a/engine/wwtlib/Imageset.cs +++ b/engine/wwtlib/Imageset.cs @@ -61,7 +61,7 @@ public static Tile GetNewTile(Imageset imageset, int level, int x, int y, Tile p { if (imageset.HipsProperties == null) { - imageset.HipsProperties = new HipsProperties(imageset.Url); + imageset.HipsProperties = new HipsProperties(imageset.Url, imageset.Name); } if (imageset.HipsProperties.DownloadComplete) { diff --git a/engine/wwtlib/Layers/LayerManager.cs b/engine/wwtlib/Layers/LayerManager.cs index bc15f39d..a6c1020f 100644 --- a/engine/wwtlib/Layers/LayerManager.cs +++ b/engine/wwtlib/Layers/LayerManager.cs @@ -2130,16 +2130,20 @@ public static SpreadSheetLayer CreateSpreadsheetLayer(string frame, string name, { SpreadSheetLayer layer = new SpreadSheetLayer(); layer.LoadFromString(data, false, false, false, true); - layer.Enabled = true; layer.Name = name; + LayerManager.AddSpreadsheetLayer(layer, frame); + return layer; + } - LayerList[layer.ID] = layer; + public static void AddSpreadsheetLayer(SpreadSheetLayer layer, string frame) + { + layer.Enabled = true; + LayerList[layer.ID] = layer; layer.ReferenceFrame = CurrentMap; AllMaps[frame].Layers.Add(layer); AllMaps[frame].Open = true; version++; LoadTree(); - return layer; } static void showOrbitPlanet_Click(object sender, EventArgs e) diff --git a/engine/wwtlib/Layers/SpreadSheetLayer.cs b/engine/wwtlib/Layers/SpreadSheetLayer.cs index 5367d6f9..bd8e170e 100644 --- a/engine/wwtlib/Layers/SpreadSheetLayer.cs +++ b/engine/wwtlib/Layers/SpreadSheetLayer.cs @@ -10,7 +10,7 @@ namespace wwtlib { - // public enum PointScaleTypes { Linear=0, Power=1, Log=2, Constant=3, StellarMagnitude=4 }; + // public enum PointScaleTypes { Linear=0, Power=1, Log=2, Constant=3, StellarMagnitude=4 }; public class SpreadSheetLayer : Layer @@ -48,7 +48,7 @@ public override void CopyToClipboard() //todo copy binary format - // Clipboard.SetText(table.ToString()); + // Clipboard.SetText(table.ToString()); } @@ -221,9 +221,9 @@ public override void AddFilesToCabinet(FileCabinet fc) // See PrepareBackCompatTable for an explanation of the // circumstances under which table_backcompat is used. if (table_backcompat == null) { - data = table.Save(); + data = table.Save(); } else { - data = table_backcompat.Save(); + data = table_backcompat.Save(); } Blob blob = new Blob(new object[] { data }); @@ -241,44 +241,44 @@ public override void AddFilesToCabinet(FileCabinet fc) private void PrepareBackCompatTable() { - // In this this layer class we implement dynamic normalization of the - // points based on one of the existing numerical columns. However, we - // need to produce XML files that are backward-compatible with older - // versions of WWT, so the approach we take is to add a column with - // the computed sizes for versions of WWT that can't do the dynamic - // scaling - while in newer versions we ignore this additional column - // and use the dynamic scaling. + // In this this layer class we implement dynamic normalization of the + // points based on one of the existing numerical columns. However, we + // need to produce XML files that are backward-compatible with older + // versions of WWT, so the approach we take is to add a column with + // the computed sizes for versions of WWT that can't do the dynamic + // scaling - while in newer versions we ignore this additional column + // and use the dynamic scaling. - // Take a shortcut to avoid copying the table if possible - if ((sizeColumn == -1 || !NormalizeSize) && (colorMapColumn == -1 || !DynamicColor)) { - lastNormalizeSizeColumnIndex = -1; - lastDynamicColorColumnIndex = -1; - return; - } + // Take a shortcut to avoid copying the table if possible + if ((sizeColumn == -1 || !NormalizeSize) && (colorMapColumn == -1 || !DynamicColor)) { + lastNormalizeSizeColumnIndex = -1; + lastDynamicColorColumnIndex = -1; + return; + } - table_backcompat = table.Clone(); + table_backcompat = table.Clone(); - if (sizeColumn > -1 && NormalizeSize) { - List normalizedPointSize = new List(); - foreach (string[] row in table_backcompat.Rows) { - normalizedPointSize.Add(NormalizePointSize(Single.Parse(row[sizeColumn])).ToString()); + if (sizeColumn > -1 && NormalizeSize) { + List normalizedPointSize = new List(); + foreach (string[] row in table_backcompat.Rows) { + normalizedPointSize.Add(NormalizePointSize(Single.Parse(row[sizeColumn])).ToString()); + } + table_backcompat.AddColumn(NormalizeSizeColumnName, normalizedPointSize); + lastNormalizeSizeColumnIndex = table_backcompat.Header.Count - 1; + } else { + lastNormalizeSizeColumnIndex = -1; } - table_backcompat.AddColumn(NormalizeSizeColumnName, normalizedPointSize); - lastNormalizeSizeColumnIndex = table_backcompat.Header.Count - 1; - } else { - lastNormalizeSizeColumnIndex = -1; - } - if (colorMapColumn > -1 && DynamicColor) { - List pointColors = new List(); - foreach (string[] row in table_backcompat.Rows) { - pointColors.Add(ColorMapper.FindClosestColor(NormalizeColorMapValue(Single.Parse(row[ColorMapColumn]))).ToSimpleHex()); + if (colorMapColumn > -1 && DynamicColor) { + List pointColors = new List(); + foreach (string[] row in table_backcompat.Rows) { + pointColors.Add(ColorMapper.FindClosestColor(NormalizeColorMapValue(Single.Parse(row[ColorMapColumn]))).ToSimpleHex()); + } + table_backcompat.AddColumn(DynamicColorColumnName, pointColors); + lastDynamicColorColumnIndex = table_backcompat.Header.Count - 1; + } else { + lastDynamicColorColumnIndex = -1; } - table_backcompat.AddColumn(DynamicColorColumnName, pointColors); - lastDynamicColorColumnIndex = table_backcompat.Header.Count - 1; - } else { - lastDynamicColorColumnIndex = -1; - } } @@ -287,96 +287,132 @@ public void GuessHeaderAssignments() int index = 0; foreach (string headerName in table.Header) { - string name = headerName.ToLowerCase(); + GuessHeaderAssignment(headerName, index++); + } - if (name.IndexOf("lat") > -1 && latColumn == -1) - { - latColumn = index; - } + if (table.Header.Count > 0) + { + nameColumn = 0; + } + } - if ((name.IndexOf("lon") > -1 || name.IndexOf("lng") > -1) && lngColumn == -1) - { - lngColumn = index; - } + public void GuessHeaderAssignmentsFromVoTable(VoTable votable) + { + VoColumn decColumn = votable.GetDecColumn(); + if (decColumn != null) + { + latColumn = decColumn.Index; + astronomical = true; - if (name.IndexOf("dec") > -1 && latColumn == -1) - { - latColumn = index; - astronomical = true; - } + } + VoColumn raColumn = votable.GetRAColumn(); + if (raColumn != null) + { + lngColumn = raColumn.Index; + astronomical = true; + pointScaleType = PointScaleTypes.StellarMagnitude; + } + VoColumn magColumn = votable.GetMagColumn(); + if (magColumn != null) + { + sizeColumn = magColumn.Index; + } - if ((name.IndexOf("ra") > -1 || name.IndexOf("ascen") > -1) && lngColumn == -1) - { - lngColumn = index; - astronomical = true; - pointScaleType = PointScaleTypes.StellarMagnitude; - } + int index = 0; + foreach (VoColumn column in votable.Column) + { + GuessHeaderAssignment(column.Name, index++); + } - if ((name.IndexOf("mag") > -1 || name.IndexOf("size") > -1) && sizeColumn == -1) - { - sizeColumn = index; - } + if (table.Header.Count > 0) + { + nameColumn = 0; + } + } - if ((name.IndexOf("date") > -1 || name.IndexOf("time") > -1 || name.IndexOf("dt") > -1 || name.IndexOf("tm") > -1)) - { - if (name.IndexOf("end") > -1 && endDateColumn == -1) - { - endDateColumn = index; - } - else if (startDateColumn == -1) - { - startDateColumn = index; - } - } + private void GuessHeaderAssignment(string name, int index) + { + name = name.ToLowerCase(); + if (name.IndexOf("lat") > -1 && latColumn == -1) + { + latColumn = index; + } + if ((name.IndexOf("lon") > -1 || name.IndexOf("lng") > -1) && lngColumn == -1) + { + lngColumn = index; + } - if ((name.IndexOf("altitude") > -1 || name.IndexOf("alt") > -1 ) && altColumn == -1) - { - altColumn = index; - AltType = AltTypes.Altitude; - AltUnit = AltUnits.Meters; - } + if (name.IndexOf("dec") > -1 && latColumn == -1) + { + latColumn = index; + astronomical = true; + } - if (name.IndexOf("depth") > -1 && altColumn == -1) - { - altColumn = index; - AltType = AltTypes.Depth; - AltUnit = AltUnits.Kilometers; - } + if ((name.IndexOf("ra") > -1 || name.IndexOf("ascen") > -1) && lngColumn == -1) + { + lngColumn = index; + astronomical = true; + pointScaleType = PointScaleTypes.StellarMagnitude; + } - if (name.StartsWith("x") && XAxisColumn == -1) - { - XAxisColumn = index; - } + if ((name.IndexOf("mag") > -1 || name.IndexOf("size") > -1) && sizeColumn == -1) + { + sizeColumn = index; + } - if (name.StartsWith("y") && YAxisColumn == -1) + if ((name.IndexOf("date") > -1 || name.IndexOf("time") > -1 || name.IndexOf("dt") > -1 || name.IndexOf("tm") > -1)) + { + if (name.IndexOf("end") > -1 && endDateColumn == -1) { - YAxisColumn = index; + endDateColumn = index; } - - if (name.StartsWith("z") && ZAxisColumn == -1) + else if (startDateColumn == -1) { - ZAxisColumn = index; + startDateColumn = index; } + } - if (name.IndexOf("color") > -1 && ColorMapColumn == -1) - { - ColorMapColumn = index; - } - if ((name.IndexOf("geometry") > -1 || name.IndexOf("geography") > -1) && geometryColumn == -1) - { - geometryColumn = index; - } - index++; + if ((name.IndexOf("altitude") > -1 || name.IndexOf("alt") > -1) && altColumn == -1) + { + altColumn = index; + AltType = AltTypes.Altitude; + AltUnit = AltUnits.Meters; } - if (table.Header.Count > 0) + if (name.IndexOf("depth") > -1 && altColumn == -1) { - nameColumn = 0; + altColumn = index; + AltType = AltTypes.Depth; + AltUnit = AltUnits.Kilometers; } - } + if (name.StartsWith("x") && XAxisColumn == -1) + { + XAxisColumn = index; + } + + if (name.StartsWith("y") && YAxisColumn == -1) + { + YAxisColumn = index; + } + + if (name.StartsWith("z") && ZAxisColumn == -1) + { + ZAxisColumn = index; + } + + if (name.IndexOf("color") > -1 && ColorMapColumn == -1) + { + ColorMapColumn = index; + } + + if ((name.IndexOf("geometry") > -1 || name.IndexOf("geography") > -1) && geometryColumn == -1) + { + geometryColumn = index; + } + } public void ComputeDateDomainRange(int columnStart, int columnEnd) { @@ -613,10 +649,10 @@ protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) positions.Clear(); UInt32 currentIndex = 0; - // device.RenderState.FillMode = FillMode.WireFrame; + // device.RenderState.FillMode = FillMode.WireFrame; Color colorLocal = Color; - // colorLocal.A = (byte)(Color.A * Opacity); + // colorLocal.A = (byte)(Color.A * Opacity); // for space 3d double ecliptic = Coordinates.MeanObliquityOfEcliptic(SpaceTimeController.JNow) / 180.0 * Math.PI; @@ -634,7 +670,7 @@ protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) Vector3d position = new Vector3d(); float pointSize = .0002f; - Color pointColor = Colors.White ; + Color pointColor = Colors.White; float pointStartTime = 0; float pointEndTime = 0; foreach (string[] row in table.Rows) @@ -1086,7 +1122,7 @@ private List SplitShapes(string shapes) int current = 0; while (current < shapes.Length) { - if (shapes.Substr(current,1) == "(") + if (shapes.Substr(current, 1) == "(") { nesting++; } @@ -1287,74 +1323,74 @@ public double GetScaleFactor(AltUnits AltUnit, double custom) return factor; } - // public override Place FindClosest(Coordinates target, float distance, IPlace defaultPlace, bool astronomical) - // { - //Vector3 searchPoint = Coordinates.GeoTo3d(target.Lat, target.Lng); + // public override Place FindClosest(Coordinates target, float distance, IPlace defaultPlace, bool astronomical) + // { + //Vector3 searchPoint = Coordinates.GeoTo3d(target.Lat, target.Lng); - ////searchPoint = -searchPoint; - //Vector3 dist; - //if (defaultPlace != null) - //{ - // Vector3 testPoint = Coordinates.RADecTo3d(defaultPlace.RA, -defaultPlace.Dec, -1.0).Vector3; - // dist = searchPoint - testPoint; - // distance = dist.Length(); - //} + ////searchPoint = -searchPoint; + //Vector3 dist; + //if (defaultPlace != null) + //{ + // Vector3 testPoint = Coordinates.RADecTo3d(defaultPlace.RA, -defaultPlace.Dec, -1.0).Vector3; + // dist = searchPoint - testPoint; + // distance = dist.Length(); + //} - //int closestItem = -1; - //int index = 0; - //foreach (Vector3 point in positions) - //{ - // dist = searchPoint - point; - // if (dist.Length() < distance) - // { - // distance = dist.Length(); - // closestItem = index; - // } - // index++; - //} + //int closestItem = -1; + //int index = 0; + //foreach (Vector3 point in positions) + //{ + // dist = searchPoint - point; + // if (dist.Length() < distance) + // { + // distance = dist.Length(); + // closestItem = index; + // } + // index++; + //} - //if (closestItem == -1) - //{ - // return defaultPlace; - //} + //if (closestItem == -1) + //{ + // return defaultPlace; + //} - //Coordinates pnt = Coordinates.CartesianToSpherical2(positions[closestItem]); + //Coordinates pnt = Coordinates.CartesianToSpherical2(positions[closestItem]); - //string name = table.Rows[closestItem][this.nameColumn]; - //if (nameColumn == startDateColumn || nameColumn == endDateColumn) - //{ - // name = ParseDate(name).ToString("u"); - //} + //string name = table.Rows[closestItem][this.nameColumn]; + //if (nameColumn == startDateColumn || nameColumn == endDateColumn) + //{ + // name = ParseDate(name).ToString("u"); + //} - //if (String.IsNullOrEmpty(name)) - //{ - // name = string.Format("RA={0}, Dec={1}", Coordinates.FormatHMS(pnt.RA), Coordinates.FormatDMS(pnt.Dec)); - //} - //TourPlace place = new TourPlace(name, pnt.Lat, pnt.Lng, Classification.Unidentified, "", ImageSetType.Earth, -1); + //if (String.IsNullOrEmpty(name)) + //{ + // name = string.Format("RA={0}, Dec={1}", Coordinates.FormatHMS(pnt.RA), Coordinates.FormatDMS(pnt.Dec)); + //} + //TourPlace place = new TourPlace(name, pnt.Lat, pnt.Lng, Classification.Unidentified, "", ImageSetType.Earth, -1); - //Dictionary rowData = new Dictionary(); - //for (int i = 0; i < table.Header.GetLength(0); i++) - //{ - // string colValue = table.Rows[closestItem][i]; - // if (i == startDateColumn || i == endDateColumn) - // { - // colValue = ParseDate(colValue).ToString("u"); - // } + //Dictionary rowData = new Dictionary(); + //for (int i = 0; i < table.Header.GetLength(0); i++) + //{ + // string colValue = table.Rows[closestItem][i]; + // if (i == startDateColumn || i == endDateColumn) + // { + // colValue = ParseDate(colValue).ToString("u"); + // } - // if (!rowData.ContainsKey(table.Header[i]) && !string.IsNullOrEmpty(table.Header[i])) - // { - // rowData.Add(table.Header[i], colValue); - // } - // else - // { - // rowData.Add("Column" + i.ToString(), colValue); - // } - //} - //place.Tag = rowData; + // if (!rowData.ContainsKey(table.Header[i]) && !string.IsNullOrEmpty(table.Header[i])) + // { + // rowData.Add(table.Header[i], colValue); + // } + // else + // { + // rowData.Add("Column" + i.ToString(), colValue); + // } + //} + //place.Tag = rowData; - //return place; - // } + //return place; + // } @@ -1367,9 +1403,21 @@ internal Table Table set { table = value; } } - public void LoadFromString(string data, bool isUpdate, bool purgeOld, bool purgeAll, bool hasHeader) + public void UseHeadersFromVoTable(VoTable voTable) { + foreach(VoColumn column in voTable.Column) + { + Header.Add(column.Name); + } + GuessHeaderAssignmentsFromVoTable(voTable); + if(voTable.GetRAColumn() != null && voTable.GetRAColumn().Unit.ToLowerCase() == "deg") + { + RaUnits = RAUnits.Degrees; + } + } + public void LoadFromString(string data, bool isUpdate, bool purgeOld, bool purgeAll, bool hasHeader) + { if (!isUpdate) { table = new Table(); From 74f8b2ac42cbc5f49df606ed58942f8cd4069c91 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:43:34 +0100 Subject: [PATCH 08/18] Removed layer cleanup on color change --- engine/wwtlib/Layers/Layer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/engine/wwtlib/Layers/Layer.cs b/engine/wwtlib/Layers/Layer.cs index 65f092d0..d00e6f73 100644 --- a/engine/wwtlib/Layers/Layer.cs +++ b/engine/wwtlib/Layers/Layer.cs @@ -414,8 +414,6 @@ public virtual Color Color { color = value; version++; - CleanUp(); - //todo should this invalidate and cleanup } } @@ -423,7 +421,6 @@ public virtual Color Color public virtual void ColorChanged() { - CleanUp(); } public virtual string ColorValue From 3539eb04bdaf669fb3ea3f82d43c0a0a98051202 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:45:15 +0100 Subject: [PATCH 09/18] Deleting a layer now also cleans layer content --- engine/wwtlib/Layers/LayerManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/wwtlib/Layers/LayerManager.cs b/engine/wwtlib/Layers/LayerManager.cs index a6c1020f..7765f91f 100644 --- a/engine/wwtlib/Layers/LayerManager.cs +++ b/engine/wwtlib/Layers/LayerManager.cs @@ -2004,6 +2004,8 @@ static private void DeleteSelectedLayer() LayerList.Remove(node.ID); AllMaps[CurrentMap].Layers.Remove(node); + node.CleanUp(); + node.Version++; LoadTree(); version++; } From d4725f4fa511736062aaa5469b4e160ccc083c85 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:46:19 +0100 Subject: [PATCH 10/18] Bugfix: SpreadsheetLayers are now added to the correct reference frame --- engine/wwtlib/Layers/LayerManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/wwtlib/Layers/LayerManager.cs b/engine/wwtlib/Layers/LayerManager.cs index 7765f91f..fc402a51 100644 --- a/engine/wwtlib/Layers/LayerManager.cs +++ b/engine/wwtlib/Layers/LayerManager.cs @@ -2141,7 +2141,7 @@ public static void AddSpreadsheetLayer(SpreadSheetLayer layer, string frame) { layer.Enabled = true; LayerList[layer.ID] = layer; - layer.ReferenceFrame = CurrentMap; + layer.ReferenceFrame = frame; AllMaps[frame].Layers.Add(layer); AllMaps[frame].Open = true; version++; From 515d691ead56221cd40a5e50d505a6b8709b2c30 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:47:43 +0100 Subject: [PATCH 11/18] Added CatalogSpreadsheetLayer & method to get only table data in FoV --- engine/wwtlib/Layers/SpreadSheetLayer.cs | 101 +++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/engine/wwtlib/Layers/SpreadSheetLayer.cs b/engine/wwtlib/Layers/SpreadSheetLayer.cs index bd8e170e..dcf75453 100644 --- a/engine/wwtlib/Layers/SpreadSheetLayer.cs +++ b/engine/wwtlib/Layers/SpreadSheetLayer.cs @@ -581,6 +581,71 @@ public int BarChartBitmask private double meanRadius = 6371000; + private bool IsPointInFrustum(Vector3d position, PlaneD[] frustum) + { + Vector4d centerV4 = new Vector4d(position.X, position.Y, position.Z, 1f); + + for (int i = 0; i < 6; i++) + { + if (frustum[i].Dot(centerV4) < 0) + { + return false; + } + } + return true; + } + + public string GetTableDataInView() + { + + string data = ""; + + bool first = true; + + foreach (string col in Header) + { + if (!first) + { + data += "\t"; + } + else + { + first = false; + } + + data += col; + } + data += "\r\n"; + foreach (string[] row in Table.Rows) + { + double ra = Double.Parse(row[LngColumn]); + double dec = Double.Parse(row[LatColumn]); + Vector3d position = Coordinates.GeoTo3dDouble(dec, ra); + + if(!IsPointInFrustum(position, WWTControl.Singleton.RenderContext.Frustum)) + { + continue; + } + first = true; + foreach (string col in row) + { + if (!first) + { + data += "\t"; + } + else + { + first = false; + } + + data += col; + } + data += "\r\n"; + } + + return data; + } + protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) { table.Lock(); @@ -2941,7 +3006,43 @@ public void CleanUpBase() } + public class CatalogSpreadSheetLayer : SpreadSheetLayer + { + // HashSet not compilable with scriptSharp + private Dictionary addedTiles = new Dictionary(); + public void AddTileRows(string tileKey, List> catalogRows) + { + if (!addedTiles.ContainsKey(tileKey)) + { + foreach (List row in catalogRows) + { + Table.Rows.Add(row); + } + dirty = true; + addedTiles[tileKey] = true; + } + } + + public void RemoveTileRows(string tileKey, List> catalogRows) + { + if (addedTiles.ContainsKey(tileKey)) + { + foreach (List row in catalogRows) + { + Table.Rows.Remove(row); + } + dirty = true; + addedTiles.Remove(tileKey); + } + } + public override void CleanUp() + { + base.CleanUp(); + addedTiles.Clear(); + Table.Rows.Clear(); + } + } //public struct PointVertex From 1bd82bdad90974d9da3f2c1da92d8b8669696946 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:50:17 +0100 Subject: [PATCH 12/18] CatalogSpreadSheet keeps track of which Tiles are added instead of Tile keeping track --- engine/wwtlib/HealpixTile.cs | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/engine/wwtlib/HealpixTile.cs b/engine/wwtlib/HealpixTile.cs index 91fe88a5..88f5a0d7 100644 --- a/engine/wwtlib/HealpixTile.cs +++ b/engine/wwtlib/HealpixTile.cs @@ -22,7 +22,6 @@ public class HealpixTile : Tile private string url; private bool subDivided = false; private readonly List> catalogRows = new List>(); - private bool catalogRowsAdded = false; private WebFile catalogData; private static readonly Matrix3d galacticMatrix = Matrix3d.Create( -0.0548755604024359, -0.4838350155267381, -0.873437090247923, 0, @@ -78,7 +77,7 @@ public HealpixTile(int level, int x, int y, Imageset dataset, Tile parent) this.faceY = parentTile.faceY * 2 + y; } - IsCatalogTile = dataset.Extension.ToLowerCase().IndexOf("tsv") > -1; + IsCatalogTile = dataset.DataSetType == ImageSetType.CatalogHips; // All healpix is inside out //insideOut = true; ComputeBoundingSphere(); @@ -495,30 +494,12 @@ public void DrawCatalogTile(RenderContext renderContext, double opacity) public void RemoveCatalogTile() { - if (catalogRowsAdded) - { - catalogRowsAdded = false; - foreach (List row in catalogRows) - { - dataset.HipsProperties.CatalogSpreadSheetLayer.Table.Rows.Remove(row); - } - dataset.HipsProperties.CatalogSpreadSheetLayer.dirty = true; - } + dataset.HipsProperties.CatalogSpreadSheetLayer.RemoveTileRows(Key, catalogRows); } private void AddCatalogTile() { - if (!catalogRowsAdded) - { - catalogRowsAdded = true; - - foreach(List row in catalogRows) - { - dataset.HipsProperties.CatalogSpreadSheetLayer.Table.Rows.Add(row); - } - dataset.HipsProperties.CatalogSpreadSheetLayer.dirty = true; - } - + dataset.HipsProperties.CatalogSpreadSheetLayer.AddTileRows(Key, catalogRows); } private void ExtractCatalogTileRows() From 356a321d86961149879f4310d5756887f7bad58a Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:51:20 +0100 Subject: [PATCH 13/18] Tile now caches tile key --- engine/wwtlib/Tile.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/engine/wwtlib/Tile.cs b/engine/wwtlib/Tile.cs index 30cea54a..1b504a24 100644 --- a/engine/wwtlib/Tile.cs +++ b/engine/wwtlib/Tile.cs @@ -940,12 +940,16 @@ public Imageset Dataset } } - + private String key = null; public String Key { get { - return Imageset.GetTileKey(dataset, Level, tileX, tileY, Parent); + if (key == null) + { + key = Imageset.GetTileKey(dataset, Level, tileX, tileY, Parent); + } + return key; } } From b70bcc3b9415404153beab62ae80fde26273a61f Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 18:59:27 +0100 Subject: [PATCH 14/18] Can now show any number of catalog HiPS + Added API controls --- engine/wwtlib/HipsProperties.cs | 22 ++++++++++++++++--- engine/wwtlib/RenderContext.cs | 37 ++++++++++++++++++++++++++++++++ engine/wwtlib/ScriptInterface.cs | 30 +++++++++++++++++++++++++- engine/wwtlib/WWTControl.cs | 37 +++++++++++++++++++++++++++++++- 4 files changed, 121 insertions(+), 5 deletions(-) diff --git a/engine/wwtlib/HipsProperties.cs b/engine/wwtlib/HipsProperties.cs index 710ad9d2..677fe6fe 100644 --- a/engine/wwtlib/HipsProperties.cs +++ b/engine/wwtlib/HipsProperties.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace wwtlib { @@ -6,7 +7,7 @@ namespace wwtlib public class HipsProperties { public Dictionary Properties { get { return properties; } } - public SpreadSheetLayer CatalogSpreadSheetLayer + public CatalogSpreadSheetLayer CatalogSpreadSheetLayer { get { return catalogSpreadSheetLayer; } set { catalogSpreadSheetLayer = value; } @@ -16,12 +17,13 @@ public SpreadSheetLayer CatalogSpreadSheetLayer private Dictionary properties = new Dictionary(); private VoTable catalogVoTable = null; - private SpreadSheetLayer catalogSpreadSheetLayer = new SpreadSheetLayer(); + private CatalogSpreadSheetLayer catalogSpreadSheetLayer = new CatalogSpreadSheetLayer(); private bool downloadComplete = false; private WebFile webFile; private readonly string url; private string datasetName; + private Action onDownloadComplete; public HipsProperties (string datasetUrl, string datasetName) { @@ -54,6 +56,10 @@ private void OnPropertiesDownloadComplete() } else { downloadComplete = true; + if(onDownloadComplete != null) + { + onDownloadComplete.Invoke(); + } } } } @@ -62,8 +68,18 @@ private void OnCatalogMetadataDownloadComplete () { catalogSpreadSheetLayer.UseHeadersFromVoTable(catalogVoTable); catalogSpreadSheetLayer.Name = datasetName; + catalogSpreadSheetLayer.ID = Guid.FromString(this.datasetName); LayerManager.AddSpreadsheetLayer(CatalogSpreadSheetLayer, "Sky"); downloadComplete = true; + if (onDownloadComplete != null) + { + onDownloadComplete.Invoke(); + } + } + + public void SetDownloadCompleteListener(Action listener) + { + this.onDownloadComplete = listener; } private void ParseProperties(string data) diff --git a/engine/wwtlib/RenderContext.cs b/engine/wwtlib/RenderContext.cs index 38cb92f6..465cbe51 100644 --- a/engine/wwtlib/RenderContext.cs +++ b/engine/wwtlib/RenderContext.cs @@ -298,6 +298,43 @@ public Imageset ForegroundImageset set { foregroundImageset = value; } } + + private List catalogHipsImagesets = new List(); + + public List CatalogHipsImagesets + { + get { return catalogHipsImagesets; } + } + + public void AddCatalogHips(Imageset imageset, Action onLoad) + { + if (!catalogHipsImagesets.Contains(imageset)) + { + catalogHipsImagesets.Add(imageset); + } + if (imageset.HipsProperties == null) + { + imageset.HipsProperties = new HipsProperties(imageset.Url, imageset.Name); + imageset.HipsProperties.SetDownloadCompleteListener(onLoad); + } else if(imageset.HipsProperties != null && imageset.HipsProperties.DownloadComplete) + { + LayerManager.AddSpreadsheetLayer(imageset.HipsProperties.CatalogSpreadSheetLayer, "Sky"); + if(onLoad != null) + { + onLoad.Invoke(); + } + } + } + + public void RemoveCatalogHips(Imageset imageset) + { + catalogHipsImagesets.Remove(imageset); + if(imageset.HipsProperties != null) + { + LayerManager.DeleteLayerByID(imageset.HipsProperties.CatalogSpreadSheetLayer.ID, true, true); + } + } + public double GetAltitudeForLatLongForPlanet(int planetID, double viewLat, double viewLong) { diff --git a/engine/wwtlib/ScriptInterface.cs b/engine/wwtlib/ScriptInterface.cs index d686dfd2..71c2ca12 100644 --- a/engine/wwtlib/ScriptInterface.cs +++ b/engine/wwtlib/ScriptInterface.cs @@ -214,7 +214,11 @@ public VoTableLayer AddVoTableLayer(VoTable table) { return LayerManager.AddVoTableLayer(table, "Vo Table"); } - + + public Dictionary GetLayers() + { + return LayerManager.LayerList; + } public void SetForegroundImageByName(string name) { @@ -234,6 +238,30 @@ public void SetForegroundOpacity(double opacity) } } + public void AddCatalogHipsByName(string name) + { + if (WWTControl.Singleton != null) + { + WWTControl.Singleton.AddCatalogHipsByName(name); + } + } + + public void AddCatalogHipsByNameWithCallback(string name, Action onLoad) + { + if (WWTControl.Singleton != null) + { + WWTControl.Singleton.AddCatalogHipsByNameWithCallback(name, onLoad); + } + } + + public void RemoveCatalogHipsByName(string name) + { + if (WWTControl.Singleton != null) + { + WWTControl.Singleton.RemoveCatalogHipsByName(name); + } + } + public void HideUI(bool hide) { //todo enable diff --git a/engine/wwtlib/WWTControl.cs b/engine/wwtlib/WWTControl.cs index e2a0a375..80b107f2 100644 --- a/engine/wwtlib/WWTControl.cs +++ b/engine/wwtlib/WWTControl.cs @@ -638,6 +638,18 @@ public void RenderOneFrame() } } + if(RenderType == ImageSetType.Sky) + { + foreach (Imageset imageset in RenderContext.CatalogHipsImagesets) + { + if (imageset.HipsProperties.CatalogSpreadSheetLayer.Enabled + && imageset.HipsProperties.CatalogSpreadSheetLayer.lastVersion == imageset.HipsProperties.CatalogSpreadSheetLayer.Version) + { + RenderContext.DrawImageSet(imageset, 100); + } + } + } + if (RenderType == ImageSetType.Sky && Settings.Active.ShowSolarSystem) { Planets.DrawPlanets(RenderContext, 1); @@ -1889,7 +1901,7 @@ double startZoom webFolder = new Folder(); webFolder.LoadFromUrl( - URLHelpers.singleton.engineAssetUrl("builtin-image-sets.wtml"), + URLHelpers.singleton.engineAssetUrl("builtin-image-sets.wtml"), SetupComplete ); } @@ -2547,6 +2559,29 @@ public void SetForegroundImageByName(string name) } } + public void AddCatalogHipsByName(string name) + { + AddCatalogHipsByNameWithCallback(name, null); + } + + public void AddCatalogHipsByNameWithCallback(string name, Action onLoad) + { + Imageset catalogHips = GetImagesetByName(name); + if (catalogHips != null) + { + RenderContext.AddCatalogHips(catalogHips, onLoad); + } + } + + public void RemoveCatalogHipsByName(string name) + { + Imageset catalogHips = GetImagesetByName(name); + if (catalogHips != null) + { + RenderContext.RemoveCatalogHips(catalogHips); + } + } + private SimpleLineList crossHairs = null; private void DrawCrosshairs(RenderContext context) From 56cd0a0acfc3b3847039110b7b8834f2a320a95c Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 19:01:06 +0100 Subject: [PATCH 15/18] Added CatalogHips dataset type --- engine/wwtlib/IImageSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/wwtlib/IImageSet.cs b/engine/wwtlib/IImageSet.cs index 7fe95bbf..ce00ad06 100644 --- a/engine/wwtlib/IImageSet.cs +++ b/engine/wwtlib/IImageSet.cs @@ -43,6 +43,6 @@ namespace wwtlib //} public enum ProjectionType { Mercator = 0, Equirectangular = 1, Tangent = 2, Tan = 2, Toast = 3, Spherical = 4, SkyImage = 5, Plotted = 6, Healpix = 7 }; - public enum ImageSetType { Earth = 0, Planet = 1, Sky = 2, Panorama = 3, SolarSystem = 4, Sandbox = 5}; + public enum ImageSetType { Earth = 0, Planet = 1, Sky = 2, Panorama = 3, SolarSystem = 4, Sandbox = 5, CatalogHips = 6}; public enum BandPass { Gamma = 0, XRay = 1, Ultraviolet = 2, Visible = 3, HydrogenAlpha = 4, IR = 4, Microwave = 5, Radio = 6, VisibleNight = 6 }; } From ab6b913946a438ab31569c4ca9eba933d55563d2 Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 21 Feb 2021 19:13:25 +0100 Subject: [PATCH 16/18] Removed some unused code and fixed white spaces --- engine/wwtlib/Imageset.cs | 2 +- engine/wwtlib/Layers/SpreadSheetLayer.cs | 119 +++++++++++------------ engine/wwtlib/Layers/VoTableLayer.cs | 19 ---- engine/wwtlib/WWTControl.cs | 2 +- 4 files changed, 60 insertions(+), 82 deletions(-) diff --git a/engine/wwtlib/Imageset.cs b/engine/wwtlib/Imageset.cs index bc50e92c..0c0d1710 100644 --- a/engine/wwtlib/Imageset.cs +++ b/engine/wwtlib/Imageset.cs @@ -18,7 +18,7 @@ public object WcsImage public static string GetTileKey(Imageset imageset, int level, int x, int y, Tile parent) { - if (imageset.Projection ==ProjectionType.Healpix && parent != null) + if (imageset.Projection == ProjectionType.Healpix && parent != null) { int ipix = ((HealpixTile)parent).ipix * 4 + y * 2 + x; return imageset.ImageSetID.ToString() + @"\" + level.ToString() + @"\" + ipix.ToString(); diff --git a/engine/wwtlib/Layers/SpreadSheetLayer.cs b/engine/wwtlib/Layers/SpreadSheetLayer.cs index dcf75453..432ff50c 100644 --- a/engine/wwtlib/Layers/SpreadSheetLayer.cs +++ b/engine/wwtlib/Layers/SpreadSheetLayer.cs @@ -1,11 +1,8 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Html; using System.Xml; -using System.Html.Services; using System.Html.Media.Graphics; -using System.Net; using System.Html.Data.Files; namespace wwtlib @@ -1388,74 +1385,74 @@ public double GetScaleFactor(AltUnits AltUnit, double custom) return factor; } - // public override Place FindClosest(Coordinates target, float distance, IPlace defaultPlace, bool astronomical) - // { - //Vector3 searchPoint = Coordinates.GeoTo3d(target.Lat, target.Lng); + // public override Place FindClosest(Coordinates target, float distance, IPlace defaultPlace, bool astronomical) + // { + //Vector3 searchPoint = Coordinates.GeoTo3d(target.Lat, target.Lng); - ////searchPoint = -searchPoint; - //Vector3 dist; - //if (defaultPlace != null) - //{ - // Vector3 testPoint = Coordinates.RADecTo3d(defaultPlace.RA, -defaultPlace.Dec, -1.0).Vector3; - // dist = searchPoint - testPoint; - // distance = dist.Length(); - //} + ////searchPoint = -searchPoint; + //Vector3 dist; + //if (defaultPlace != null) + //{ + // Vector3 testPoint = Coordinates.RADecTo3d(defaultPlace.RA, -defaultPlace.Dec, -1.0).Vector3; + // dist = searchPoint - testPoint; + // distance = dist.Length(); + //} - //int closestItem = -1; - //int index = 0; - //foreach (Vector3 point in positions) - //{ - // dist = searchPoint - point; - // if (dist.Length() < distance) - // { - // distance = dist.Length(); - // closestItem = index; - // } - // index++; - //} + //int closestItem = -1; + //int index = 0; + //foreach (Vector3 point in positions) + //{ + // dist = searchPoint - point; + // if (dist.Length() < distance) + // { + // distance = dist.Length(); + // closestItem = index; + // } + // index++; + //} - //if (closestItem == -1) - //{ - // return defaultPlace; - //} + //if (closestItem == -1) + //{ + // return defaultPlace; + //} - //Coordinates pnt = Coordinates.CartesianToSpherical2(positions[closestItem]); + //Coordinates pnt = Coordinates.CartesianToSpherical2(positions[closestItem]); - //string name = table.Rows[closestItem][this.nameColumn]; - //if (nameColumn == startDateColumn || nameColumn == endDateColumn) - //{ - // name = ParseDate(name).ToString("u"); - //} + //string name = table.Rows[closestItem][this.nameColumn]; + //if (nameColumn == startDateColumn || nameColumn == endDateColumn) + //{ + // name = ParseDate(name).ToString("u"); + //} - //if (String.IsNullOrEmpty(name)) - //{ - // name = string.Format("RA={0}, Dec={1}", Coordinates.FormatHMS(pnt.RA), Coordinates.FormatDMS(pnt.Dec)); - //} - //TourPlace place = new TourPlace(name, pnt.Lat, pnt.Lng, Classification.Unidentified, "", ImageSetType.Earth, -1); + //if (String.IsNullOrEmpty(name)) + //{ + // name = string.Format("RA={0}, Dec={1}", Coordinates.FormatHMS(pnt.RA), Coordinates.FormatDMS(pnt.Dec)); + //} + //TourPlace place = new TourPlace(name, pnt.Lat, pnt.Lng, Classification.Unidentified, "", ImageSetType.Earth, -1); - //Dictionary rowData = new Dictionary(); - //for (int i = 0; i < table.Header.GetLength(0); i++) - //{ - // string colValue = table.Rows[closestItem][i]; - // if (i == startDateColumn || i == endDateColumn) - // { - // colValue = ParseDate(colValue).ToString("u"); - // } + //Dictionary rowData = new Dictionary(); + //for (int i = 0; i < table.Header.GetLength(0); i++) + //{ + // string colValue = table.Rows[closestItem][i]; + // if (i == startDateColumn || i == endDateColumn) + // { + // colValue = ParseDate(colValue).ToString("u"); + // } - // if (!rowData.ContainsKey(table.Header[i]) && !string.IsNullOrEmpty(table.Header[i])) - // { - // rowData.Add(table.Header[i], colValue); - // } - // else - // { - // rowData.Add("Column" + i.ToString(), colValue); - // } - //} - //place.Tag = rowData; + // if (!rowData.ContainsKey(table.Header[i]) && !string.IsNullOrEmpty(table.Header[i])) + // { + // rowData.Add(table.Header[i], colValue); + // } + // else + // { + // rowData.Add("Column" + i.ToString(), colValue); + // } + //} + //place.Tag = rowData; - //return place; - // } + //return place; + // } diff --git a/engine/wwtlib/Layers/VoTableLayer.cs b/engine/wwtlib/Layers/VoTableLayer.cs index 04e22d2a..ec762ad4 100644 --- a/engine/wwtlib/Layers/VoTableLayer.cs +++ b/engine/wwtlib/Layers/VoTableLayer.cs @@ -1454,20 +1454,6 @@ public override Place FindClosest(Coordinates target, float distance, Place defa return place; } - private bool IsPointInFrustum(Vector3d position, PlaneD[] frustum) - { - Vector4d centerV4 = new Vector4d(position.X, position.Y, position.Z, 1f); - - for (int i = 0; i < 6; i++) - { - if (frustum[i].Dot(centerV4) < 0) - { - return false; - } - } - return true; - } - protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) { VoColumn col = table.GetColumnByUcd("meta.id"); @@ -1525,11 +1511,6 @@ protected bool PrepVertexBuffer(RenderContext renderContext, float opacity) double dec = Double.Parse(row[this.LatColumn].ToString()); Vector3d position = Coordinates.GeoTo3dDouble(dec, ra); - //if (!IsPointInFrustum(position, renderContext.Frustum)) - //{ - // //continue; - //} - lastItem.Position = position; positions.Add(lastItem.Position); lastItem.Color = color; diff --git a/engine/wwtlib/WWTControl.cs b/engine/wwtlib/WWTControl.cs index 80b107f2..89d2495e 100644 --- a/engine/wwtlib/WWTControl.cs +++ b/engine/wwtlib/WWTControl.cs @@ -1901,7 +1901,7 @@ double startZoom webFolder = new Folder(); webFolder.LoadFromUrl( - URLHelpers.singleton.engineAssetUrl("builtin-image-sets.wtml"), + URLHelpers.singleton.engineAssetUrl("builtin-image-sets.wtml"), SetupComplete ); } From d2d58c130ae7c72885daba1f07b6b1fc1fac975b Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Tue, 23 Feb 2021 11:29:00 +0100 Subject: [PATCH 17/18] Can now fetch all data (even not yet loaded) from a catalog HiPS --- engine/wwtlib/HealpixTile.cs | 49 ++++++++++++++++ engine/wwtlib/HipsProperties.cs | 12 +++- engine/wwtlib/RenderContext.cs | 99 ++++++++++++++++++++++++++++++-- engine/wwtlib/ScriptInterface.cs | 8 +++ engine/wwtlib/WWTControl.cs | 9 +++ 5 files changed, 169 insertions(+), 8 deletions(-) diff --git a/engine/wwtlib/HealpixTile.cs b/engine/wwtlib/HealpixTile.cs index 88f5a0d7..324e9a3a 100644 --- a/engine/wwtlib/HealpixTile.cs +++ b/engine/wwtlib/HealpixTile.cs @@ -521,6 +521,55 @@ private void ExtractCatalogTileRows() } } + + public bool GetDataInView(RenderContext renderContext, bool limit, CatalogSpreadSheetLayer catalogSpreadSheetLayer) + { + if (!ReadyToRender) + { + if (!errored) + { + RequestImage(); + if (limit) + { + return false; + } + } else if(Level >= 3) //Level 0-2 sometimes deleted in favor of allsky.jpg/tsv + { + return true; + } + } + + bool allChildrenReady = true; + bool anyChildInFrustum = false; + int childIndex = 0; + for (int y1 = 0; y1 < 2; y1++) + { + for (int x1 = 0; x1 < 2; x1++) + { + if (Level < dataset.Levels) + { + if (children[childIndex] == null) + { + children[childIndex] = TileCache.GetTile(Level + 1, x1, y1, dataset, this); + } + + if (children[childIndex].IsTileInFrustum(renderContext.Frustum)) + { + anyChildInFrustum = true; + allChildrenReady = allChildrenReady && ((HealpixTile)children[childIndex]).GetDataInView(renderContext, limit, catalogSpreadSheetLayer); + } + } + + childIndex++; + } + } + if (anyChildInFrustum) + { + catalogSpreadSheetLayer.AddTileRows(Key, catalogRows); + } + return allChildrenReady && !Downloading; + } + private void SetStep() { if (IsCatalogTile) diff --git a/engine/wwtlib/HipsProperties.cs b/engine/wwtlib/HipsProperties.cs index 677fe6fe..c49818e9 100644 --- a/engine/wwtlib/HipsProperties.cs +++ b/engine/wwtlib/HipsProperties.cs @@ -13,10 +13,16 @@ public CatalogSpreadSheetLayer CatalogSpreadSheetLayer set { catalogSpreadSheetLayer = value; } } + public VoTable CatalogColumnInfo + { + get { return catalogColumnInfo; } + set { catalogColumnInfo = value; } + } + public bool DownloadComplete { get { return downloadComplete; } } private Dictionary properties = new Dictionary(); - private VoTable catalogVoTable = null; + private VoTable catalogColumnInfo = null; private CatalogSpreadSheetLayer catalogSpreadSheetLayer = new CatalogSpreadSheetLayer(); private bool downloadComplete = false; @@ -52,7 +58,7 @@ private void OnPropertiesDownloadComplete() ParseProperties(webFile.GetText()); if (Properties.ContainsKey("dataproduct_type") && Properties["dataproduct_type"].ToLowerCase() == "catalog") { - catalogVoTable = VoTable.LoadFromUrl(url.Replace("/properties", "/metadata.xml"), OnCatalogMetadataDownloadComplete); + catalogColumnInfo = VoTable.LoadFromUrl(url.Replace("/properties", "/metadata.xml"), OnCatalogMetadataDownloadComplete); } else { downloadComplete = true; @@ -66,7 +72,7 @@ private void OnPropertiesDownloadComplete() private void OnCatalogMetadataDownloadComplete () { - catalogSpreadSheetLayer.UseHeadersFromVoTable(catalogVoTable); + catalogSpreadSheetLayer.UseHeadersFromVoTable(catalogColumnInfo); catalogSpreadSheetLayer.Name = datasetName; catalogSpreadSheetLayer.ID = Guid.FromString(this.datasetName); LayerManager.AddSpreadsheetLayer(CatalogSpreadSheetLayer, "Sky"); diff --git a/engine/wwtlib/RenderContext.cs b/engine/wwtlib/RenderContext.cs index 465cbe51..015639dd 100644 --- a/engine/wwtlib/RenderContext.cs +++ b/engine/wwtlib/RenderContext.cs @@ -18,6 +18,12 @@ public class Material public bool IsDefault; } + public class InViewReturnMessage + { + public string table; + public bool aborted; + } + public class RenderContext { public static bool UseGl = false; @@ -299,18 +305,101 @@ public Imageset ForegroundImageset } - private List catalogHipsImagesets = new List(); + private List activeCatalogHipsImagesets = new List(); public List CatalogHipsImagesets { - get { return catalogHipsImagesets; } + get { return activeCatalogHipsImagesets; } + } + + + public void GetCatalogHipsDataInView(Imageset imageset, bool limit, Action onComplete) + { + CatalogSpreadSheetLayer layer = new CatalogSpreadSheetLayer(); + Action onHeaderInfoLoad = delegate () + { + layer.UseHeadersFromVoTable(imageset.HipsProperties.CatalogColumnInfo); + TryGetAllDataInView(imageset, limit, layer, onComplete, 0); + }; + + if (imageset.HipsProperties == null) + { + imageset.HipsProperties = new HipsProperties(imageset.Url, imageset.Name); + imageset.HipsProperties.SetDownloadCompleteListener(onHeaderInfoLoad); + } + else if (imageset.HipsProperties != null && imageset.HipsProperties.DownloadComplete) + { + onHeaderInfoLoad.Invoke(); + } else + { + imageset.HipsProperties.SetDownloadCompleteListener(onHeaderInfoLoad); + } + } + + private void TryGetAllDataInView(Imageset imageset, bool limit, CatalogSpreadSheetLayer catalogSpreadSheetLayer, Action onComplete, int i) + { + int maxX = GetTilesXForLevel(imageset, imageset.BaseLevel); + int maxY = GetTilesYForLevel(imageset, imageset.BaseLevel); + bool anyTileStillDownloading = false; + for (int x = 0; x < maxX; x++) + { + for (int y = 0; y < maxY; y++) + { + Tile tile = TileCache.GetTile(imageset.BaseLevel, x, y, imageset, null); + if (tile != null) + { + bool tileAndChildrenReady = ((HealpixTile)tile).GetDataInView(this, limit, catalogSpreadSheetLayer); + anyTileStillDownloading = anyTileStillDownloading || !tileAndChildrenReady; + } + else + { + anyTileStillDownloading = true; + } + } + } + if (anyTileStillDownloading) + { + int count = catalogSpreadSheetLayer.Table.Rows.Count; + if((count > 10000 || i > 100 * 60 * 5) && limit) // ~5 minutes + { + Script.Literal("console.log('Too Many results - Aborting')"); + Script.Literal("console.log(count)"); + InViewReturnMessage returnMessage = new InViewReturnMessage(); + returnMessage.aborted = true; + returnMessage.table = catalogSpreadSheetLayer.GetTableDataInView(); + onComplete.Invoke(returnMessage); + catalogSpreadSheetLayer.CleanUp(); + } + else + { + Script.SetTimeout(delegate () { TryGetAllDataInView(imageset, limit, catalogSpreadSheetLayer, onComplete, i); }, 10); + if(i % 200 == 0) + { + Script.Literal("console.log('Waiting for more tiles to load')"); + Script.Literal("console.log(count)"); + } + i++; + } + } + else + { + int count = catalogSpreadSheetLayer.Table.Rows.Count; + Script.Literal("console.log('Done!')"); + Script.Literal("console.log(count)"); + InViewReturnMessage returnMessage = new InViewReturnMessage(); + returnMessage.aborted = false; + returnMessage.table = catalogSpreadSheetLayer.GetTableDataInView(); + onComplete.Invoke(returnMessage); + catalogSpreadSheetLayer.CleanUp(); + } + } public void AddCatalogHips(Imageset imageset, Action onLoad) { - if (!catalogHipsImagesets.Contains(imageset)) + if (!activeCatalogHipsImagesets.Contains(imageset)) { - catalogHipsImagesets.Add(imageset); + activeCatalogHipsImagesets.Add(imageset); } if (imageset.HipsProperties == null) { @@ -328,7 +417,7 @@ public void AddCatalogHips(Imageset imageset, Action onLoad) public void RemoveCatalogHips(Imageset imageset) { - catalogHipsImagesets.Remove(imageset); + activeCatalogHipsImagesets.Remove(imageset); if(imageset.HipsProperties != null) { LayerManager.DeleteLayerByID(imageset.HipsProperties.CatalogSpreadSheetLayer.ID, true, true); diff --git a/engine/wwtlib/ScriptInterface.cs b/engine/wwtlib/ScriptInterface.cs index 71c2ca12..5c838ad2 100644 --- a/engine/wwtlib/ScriptInterface.cs +++ b/engine/wwtlib/ScriptInterface.cs @@ -262,6 +262,14 @@ public void RemoveCatalogHipsByName(string name) } } + public void GetCatalogHipsDataInView(string name, bool limit, Action onComplete) + { + if (WWTControl.Singleton != null) + { + WWTControl.Singleton.GetCatalogHipsDataInView(name, limit, onComplete); + } + } + public void HideUI(bool hide) { //todo enable diff --git a/engine/wwtlib/WWTControl.cs b/engine/wwtlib/WWTControl.cs index 89d2495e..38faa664 100644 --- a/engine/wwtlib/WWTControl.cs +++ b/engine/wwtlib/WWTControl.cs @@ -2582,6 +2582,15 @@ public void RemoveCatalogHipsByName(string name) } } + public void GetCatalogHipsDataInView(string name, bool limit, Action onComplete) + { + Imageset catalogHips = GetImagesetByName(name); + if (catalogHips != null) + { + RenderContext.GetCatalogHipsDataInView(catalogHips, limit, onComplete); + } + } + private SimpleLineList crossHairs = null; private void DrawCrosshairs(RenderContext context) From 2e0a8a306b90926a8da16082a656bff85e5ae2bc Mon Sep 17 00:00:00 2001 From: Henrik Norman Date: Sun, 14 Mar 2021 11:54:29 +0100 Subject: [PATCH 18/18] Removed need for imageset datatype "CatalogHips" --- engine/wwtlib/HealpixTile.cs | 3 ++- engine/wwtlib/IImageSet.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/engine/wwtlib/HealpixTile.cs b/engine/wwtlib/HealpixTile.cs index 324e9a3a..73bd5e64 100644 --- a/engine/wwtlib/HealpixTile.cs +++ b/engine/wwtlib/HealpixTile.cs @@ -77,7 +77,8 @@ public HealpixTile(int level, int x, int y, Imageset dataset, Tile parent) this.faceY = parentTile.faceY * 2 + y; } - IsCatalogTile = dataset.DataSetType == ImageSetType.CatalogHips; + IsCatalogTile = dataset.HipsProperties.Properties.ContainsKey("dataproduct_type") + && dataset.HipsProperties.Properties["dataproduct_type"].ToLowerCase() == "catalog"; // All healpix is inside out //insideOut = true; ComputeBoundingSphere(); diff --git a/engine/wwtlib/IImageSet.cs b/engine/wwtlib/IImageSet.cs index ce00ad06..7fe95bbf 100644 --- a/engine/wwtlib/IImageSet.cs +++ b/engine/wwtlib/IImageSet.cs @@ -43,6 +43,6 @@ namespace wwtlib //} public enum ProjectionType { Mercator = 0, Equirectangular = 1, Tangent = 2, Tan = 2, Toast = 3, Spherical = 4, SkyImage = 5, Plotted = 6, Healpix = 7 }; - public enum ImageSetType { Earth = 0, Planet = 1, Sky = 2, Panorama = 3, SolarSystem = 4, Sandbox = 5, CatalogHips = 6}; + public enum ImageSetType { Earth = 0, Planet = 1, Sky = 2, Panorama = 3, SolarSystem = 4, Sandbox = 5}; public enum BandPass { Gamma = 0, XRay = 1, Ultraviolet = 2, Visible = 3, HydrogenAlpha = 4, IR = 4, Microwave = 5, Radio = 6, VisibleNight = 6 }; }