gov.nasa.worldwind.layers.StarsConvertor Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.layers;
import com.jogamp.common.nio.Buffers;
import gov.nasa.worldwind.geom.Vec4;
import gov.nasa.worldwind.util.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.nio.*;
import java.util.ArrayList;
/**
* Converts a star background based on a subset of ESA Hipparcos catalog to ByteBuffer.
*
* @author Patrick Murris
* @version $Id: StarsConvertor.java 1171 2013-02-11 21:45:02Z dcollins $
*/
public class StarsConvertor
{
private static final float DEFAULT_RADIUS = 6356752 * 10; // Earth radius x 10
/**
* Convert star tsv text file to binary dat file
*
* @param tsvFileName name of tsv text star file
*/
public static void convertTsvToDat(String tsvFileName)
{
String datFileName = WWIO.replaceSuffix(tsvFileName, ".dat");
convertTsvToDat(tsvFileName, datFileName, DEFAULT_RADIUS);
}
/**
* Convert star tsv text file to binary dat file
*
* @param tsvFileName name of tsv text star file
* @param radius radius of star sphere
*/
public static void convertTsvToDat(String tsvFileName, float radius)
{
String datFileName = WWIO.replaceSuffix(tsvFileName, ".dat");
convertTsvToDat(tsvFileName, datFileName, radius);
}
/**
* Convert star tsv text file to binary dat file
*
* @param tsvFileName name of tsv text star file
* @param datFileName name of dat binary star file
*/
public static void convertTsvToDat(String tsvFileName, String datFileName)
{
convertTsvToDat(tsvFileName, datFileName, DEFAULT_RADIUS);
}
/**
* Convert star tsv text file to binary dat file
*
* @param tsvFileName name of tsv text star file
* @param datFileName name of dat binary star file
* @param radius radius of star sphere
*/
public static void convertTsvToDat(String tsvFileName, String datFileName, float radius)
{
//Convert the Tsv Star file to a ByteBuffer in little-endian order
ByteBuffer bbuf = convertTsvToByteBuffer(tsvFileName, radius);
try
{
WWIO.saveBuffer(bbuf, new File(datFileName));
}
catch (IOException e)
{
Logging.logger().log(java.util.logging.Level.SEVERE,
Logging.getMessage("generic.ExceptionAttemptingToWriteTo", datFileName), e);
}
}
/**
* Converts a Stars tsv file to a ByteBuffer with radius DEFAULT_RADIUS
*
* @param starsFileName filename of tsv file
*
* @return ByteBuffer with interleaved color and vertex positions as floats in little-endian order
*/
public static ByteBuffer convertTsvToByteBuffer(String starsFileName)
{
return convertTsvToByteBuffer(starsFileName, DEFAULT_RADIUS);
}
/**
* Converts a Stars tsv file to a ByteBuffer
*
* @param starsFileName filename of tsv file
* @param radius radius of the sphere on which to paint stars
*
* @return ByteBuffer with interleaved color and vertex positions as floats in little-endian order
*/
public static ByteBuffer convertTsvToByteBuffer(String starsFileName, float radius)
{
try
{
ArrayList tmpBuffer = new ArrayList();
InputStream starsStream = StarsConvertor.class.getResourceAsStream("/" + starsFileName);
if (starsStream == null)
{
File starsFile = new File(starsFileName);
if (starsFile.exists())
{
starsStream = new FileInputStream(starsFile);
}
}
if (starsStream == null)
// TODO: logger error
return null;
BufferedReader starsReader = new BufferedReader(new InputStreamReader(starsStream));
String line;
int idxRAhms = 2; // Catalog field indices
int idxDEdms = 3;
int idxVmag = 4;
int idxBV = 5;
double longitude;
double latitude;
boolean isData = false;
//Add the radius as the first value
tmpBuffer.add(radius);
while ((line = starsReader.readLine()) != null)
{
if (line.length() < 3)
continue;
if (line.substring(0, 1).equals("#"))
continue;
if (isData) // Star data here
{
// Split data in ';' separated values
String[] starData = line.trim().split(";");
String RAhms, DEdms, Vmag, BV;
RAhms = starData[idxRAhms]; // Right Asc in H, min, sec "00 01 35.85"
DEdms = starData[idxDEdms]; // Declinaison Degre min sec "-77 03 55.1"
Vmag = starData[idxVmag]; // Apparent magnitude " 4.78"
// B-V spectral color " 1.254" (may be missing)
BV = idxBV < starData.length ? starData[idxBV] : "";
// compute RAhms into longitude
double RAh = Double.parseDouble(RAhms.substring(0, 2));
double RAm = Double.parseDouble(RAhms.substring(3, 5));
double RAs = Double.parseDouble(RAhms.substring(6));
longitude = (RAh * 15) + (RAm * .25) + (RAs * 0.0041666) - 180;
// compute DEdms into latitude
String DEsign = DEdms.substring(0, 1);
double DEd = Double.parseDouble(DEdms.substring(1, 3));
double DEm = Double.parseDouble(DEdms.substring(4, 6));
double DEs = Double.parseDouble(DEdms.substring(7));
latitude = DEd + (DEm / 60) + (DEs / 3600);
if (DEsign.equals("-"))
latitude *= -1;
// compute aparent magnitude -1.5 - 10 to grayscale 0 - 255
double VM = Double.parseDouble(Vmag);
double Vdec = 255 - ((VM + 1.5) * 255 / 10);
if (Vdec > 255)
Vdec = 255;
Vdec /= 255; // scale back to 0.0 - 1.0
// convert B-V -0.5 - 4 for rgb color select
double BVdec;
try
{
BVdec = Double.parseDouble(BV);
}
catch (Exception e)
{
BVdec = 0;
}
// Star color
Color color = BVColor(BVdec);
tmpBuffer.add(color.getRed() / 255f * (float) Vdec);
tmpBuffer.add(color.getGreen() / 255f * (float) Vdec);
tmpBuffer.add(color.getBlue() / 255f * (float) Vdec);
// Place vertex for point star
Vec4 pos = SphericalToCartesian(latitude, longitude, radius);
tmpBuffer.add((float) pos.getX());
tmpBuffer.add((float) pos.getY());
tmpBuffer.add((float) pos.getZ());
}
// Data starting next line
if (line.substring(0, 3).equals("---"))
isData = true;
}
starsReader.close();
ByteBuffer buf = Buffers.newDirectByteBuffer(tmpBuffer.size() * 4);
buf.order(ByteOrder.LITTLE_ENDIAN);
FloatBuffer fBuf = buf.asFloatBuffer();
for (Float fVal : tmpBuffer)
{
fBuf.put(fVal);
}
buf.rewind();
return buf;
}
catch (IOException e)
{
// TODO: Log proper message
//String message = WorldWind.retrieveErrMsg("generic.IOExceptionWhileLoadingData");
String message = "IOException while loading stars data from " + starsFileName;
Logging.logger().severe(message);
}
catch (Exception e)
{
String message = "Error while loading stars data from " + starsFileName;
Logging.logger().severe(message);
}
return null;
}
/**
* Converts position in spherical coordinates (lat/lon/radius) to cartesian (XYZ) coordinates.
*
* @param latitude Latitude in decimal degrees
* @param longitude Longitude in decimal degrees
* @param radius Radius
*
* @return the corresponding Point
*/
private static Vec4 SphericalToCartesian(double latitude, double longitude, float radius)
{
latitude *= Math.PI / 180.0f;
longitude *= Math.PI / 180.0f;
double radCosLat = radius * Math.cos(latitude);
return new Vec4(
radCosLat * Math.sin(longitude),
(double) radius * Math.sin(latitude),
radCosLat * Math.cos(longitude));
}
/**
* Returns the corresponding B-V color
*
* @param BV the star B-V decimal value (-.5 .. 4)
*
* @return the corresponding Color
*/
private static Color BVColor(double BV)
{
// TODO: interpolate between values
if (BV < 0)
return new Color(.635f, .764f, .929f); // Light blue
else if (BV < .5)
return new Color(1f, 1f, 1f); // White
else if (BV < 1)
return new Color(1f, .984f, .266f); // Yellow
else if (BV < 1.5)
return new Color(.964f, .725f, .0784f); // Orange
else
return new Color(.921f, .376f, .0392f); // Redish
}
public static void main(String[] args)
{
JFileChooser fileChooser = new JFileChooser();
fileChooser.setAcceptAllFileFilterUsed(true);
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
fileChooser.setMultiSelectionEnabled(true);
int status = fileChooser.showOpenDialog(null);
if (status != JFileChooser.APPROVE_OPTION)
return;
File[] files = fileChooser.getSelectedFiles();
if (files == null)
{
System.out.println("No files selected");
return;
}
String ans;
ans = JOptionPane.showInputDialog("Enter star sphere radius?", DEFAULT_RADIUS);
float radius;
while (true)
{
try
{
radius = Float.parseFloat(ans);
break;
}
catch (NumberFormatException e)
{
String message = Logging.getMessage("generic.NumberFormatException");
Logging.logger().warning(message);
ans = JOptionPane.showInputDialog(
"INVALID VALUE: Please enter a floating point number."
+ "
Enter star sphere radius?", DEFAULT_RADIUS);
}
}
for (File file : files)
{
convertTsvToDat(file.getAbsolutePath(), radius);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy