/**
* Map Generator Groovy weather sample
*/
package weather.map.generator;
import idea.geometry.CartesianDimension;
import idea.geometry.CartesianPosition;
import idea.geometry.Offset;
import idea.graphics.shapes.complex.meteo.WindBarb.SpeedUnit;
import idea.geographic.coordsys.orthogonal2d.CartesianGeoDimension;
import idea.geographic.coordsys.orthogonal2d.CartesianGeoOffset;
import idea.geographic.coordsys.orthogonal2d.CartesianGeoPosition;
import idea.geographic.coordsys.orthogonal3d.WGS84GeoPosition;
import idea.geometry.CartesianDimension;
import idea.geometry.CartesianOffset;
import idea.geometry.CartesianPosition;
import idea.graphics.map.GeographicImageMap;
import idea.graphics.map.HtmlImageMap;
import idea.graphics.map.HtmlImageMapItemsFromInputDataValues;
import idea.graphics.map.GeographicImageMap.ImageMapParameters;
import idea.graphics.shapes.complex.ListColorScaleLegend;
import idea.graphics.shapes.complex.geo.czech.RegionsCzechRepublic;
import idea.graphics.shapes.simple.Text;
import idea.graphics.shapes.complex.meteo.WindBarb;
import idea.map.colorscale.ColorForValueRange;
import idea.map.colorscale.StandardListColorScale;
import idea.map.generator.GeographicMapCanvas;
import idea.map.generator.MapGenerator;
import idea.map.generator.MapGenerator.MapGeneratorResult;
import idea.map.matrix.ComputedMatrix;
import idea.map.interpolator.IDWInterpolator;
import idea.map.interpolator.IDWParameters;
import idea.map.matrix.MatrixParameters;
import idea.map.renderer.AbstractRenderer;
import idea.map.renderer.GeoImageMapRenderer;
import idea.map.writer.AbstractMapWriter;
import idea.map.writer.ImageMapWriterToCanvas;
import idea.map.writer.MapWriterToFile;
import idea.map.writer.MapWriterToHtmlFile;
import idea.map.writer.MapWriters;
import idea.map.writer.WriterGroup;
import idea.geographic.coordsys.transformation.BursaWolf;
import idea.geographic.coordsys.transformation.CoordinateTransformationWGS84_S42;
import idea.geographic.coordsys.transformation.CoordinateTransformationWGS84_S42.S42zoneWide;
import java.awt.Color;
import java.awt.Font;
import java.net.URI;
import java.util.ArrayList;
import java.util.Locale;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import weather.data.*;
/**
* Entry point
* Use this for educational purposes only, not for real flying
*
* @author Lumir Vanek, vanek@idea-envi.cz
*
*/
class Main
{
/**
* Generate simple weather map
*
* @param args Arguments
*/
static main(args)
{
/*
* Load airports data from XML
*/
def xmlAirports = new XmlParser().parse('./input/airports.xml');
final List< Airport > airports = new ArrayList< Airport >();
xmlAirports.each
{
Airport airport = new Airport(icaoCode: it.@icaoCode,
name: it.@name,
geoPosition: new WGS84GeoPosition(Double.valueOf(it.WGS84GeoPosition[0].@longitude), Double.valueOf(it.WGS84GeoPosition[0].@latitude)));
println "Loaded airport: " + airport.toString();
airports.add airport;
}
/*
* For each airport, get weather info - simple METAR decoding
*/
airports.each { Airport airport ->
URL url = new URL("http://weather.noaa.gov/pub/data/observations/metar/stations/" + airport.icaoCode + ".TXT");
URLConnection connection = url.openConnection();
connection.connect();
String metar = connection.content.text;
println "Metar for:" + airport.icaoCode + " is: " + metar;
airport.weather = new Weather(airport.icaoCode, metar);
}
/**
* Create weather map
*/
final String renderedMatrixId = 'matrix';
/*
* Define Color scale ranges and colors
*/
int seq = 0; // value range sequence
List colorScaleItems = [
new ColorForValueRange("Lowest", "#FFFFFF", null, 0.0f, 900.0f, ++seq),
new ColorForValueRange("Lower", "#D7F2FD", null, 900.0f, 950.0f, ++seq),
new ColorForValueRange("Low", "#C2E4FD", null, 950.0f, 1000.0f, ++seq),
new ColorForValueRange("Low-Mid", "#AED5FE", null, 1000.0f, 1015.0f, ++seq),
new ColorForValueRange("Mid", "#98C1FF", null, 1015.0f, 1016.0f, ++seq),
new ColorForValueRange("High", "#81ABFF", null, 1016.0f, 1017.0f, ++seq),
new ColorForValueRange("Higher", "#6B8FFF", null, 1017.0f, 1020.0f, ++seq),
new ColorForValueRange("Highest", "#5970F4", null, 1020.0f, null, ++seq)
] as ArrayList;
// HTML image map serves tooltips, when user move mouse over map in HTML viewer
HtmlImageMap htmlImageMap = new HtmlImageMap('imageMap');
BursaWolf bursaWolf = new BursaWolf(-23, 124, 84, -0.13, -0.25, 0.02, -1.1e-6);
final CoordinateTransformationWGS84_S42 ct = new CoordinateTransformationWGS84_S42(3, S42zoneWide.dg6, bursaWolf);
MapGenerator generator = new MapGenerator('Weather info',
Locale.ENGLISH,
null, // create own collector
ct,
// Matrixes parameters
new MatrixParameters(450, 680, 1000, new CartesianGeoPosition(3200000, 5300000)),
// Color scale
new StandardListColorScale("Air pressure", "hPa", colorScaleItems),
// Map parameters
renderedMatrixId,
new CartesianDimension(680, 450),
new CartesianGeoPosition(3200000, 5300000),
1000, // Size of pixel in geographic units
Color.white, // Background color
htmlImageMap);
htmlImageMap.add(new MyHtmlImageMapItems(HtmlImageMapItemsFromInputDataValues.Type.CIRCLE,
renderedMatrixId,
8) // Size of item in pixels
);
/*
* Add computed matrix
*/
generator.getMatrixes().put(renderedMatrixId,
new ComputedMatrix(generator.getMatrixes(),
renderedMatrixId,
new IDWInterpolator(new IDWParameters(), null),
new WeatherDataValues(airports)));
/*
* Add map writers
*/
// To show final map in GUI window
generator.getMapWriters().add(new ImageMapWriterToCanvas(false));
// Write map PNG image and enclosing HTML
generator.getMapWriters().add(new MapWriterToFile('./output/map.png', MapWriterToFile.OutputFormat.PNG, false));
generator.getMapWriters().add(new MapWriterToHtmlFile('./output/weather.html',
'map.png',
null,
null, // headerFileName,
null, // footerFileName,
'Weather map',
'wz_tooltip.js',
null, // jsGraphicsFileName,
null, // divMapCanvasClass,
null, // divMapCanvasStyle,
null, // alternateText,
false));
/*
* Setup renderer
*/
AbstractRenderer renderer = generator.getRenderer();
if(renderer instanceof GeoImageMapRenderer)
{
final GeoImageMapRenderer imageMapRenderer = (GeoImageMapRenderer) renderer;
final GeographicImageMap geographicMap = imageMapRenderer.getGeographicMap();
final ImageMapParameters mapParameters = geographicMap.getImageMapParameters();
/**
* Add vector shapes, you wish to render over map
*/
// Czech Republic regions borders
geographicMap.addShape(new RegionsCzechRepublic(1.0f, Color.gray, geographicMap.getImageMapParameters()));
// Color scale legend
geographicMap.addShape(new ListColorScaleLegend(ListColorScaleLegend.Type.STANDARD,
new CartesianGeoPosition(3700000, 5740000).convertToPixels(mapParameters), // Left bottom position
new CartesianGeoDimension(165000, 120000).convertToPixels(mapParameters), // Dimension
new CartesianGeoDimension(20000, 10000).convertToPixels(mapParameters), // Dimension of Item rectangle
new CartesianOffset(3, 15), // Main label offset
new CartesianOffset(3, 20), // Items offset
new CartesianOffset(22, 10), // Item ranges offset
new CartesianOffset(110, 10), // Item names offset
"####", // DecimalFormat pattern for formatting numbers
new Font("Lucida Sans" , Font.BOLD, 14), // Font for drawing main label text
new Font("Lucida Console" , Font.PLAIN, 12), // Font for drawing items text
true, // True, if legend has rectangular frame
true, // True, if legend items has names
false) // Show item for NODATA ?
);
// Text with copyright info
geographicMap.addShape(new Text(new CartesianPosition(10, 15),
"Map Generator, © IDEA-ENVI s.r.o.",
new Font("Lucida Console" , Font.PLAIN, 15),
Color.BLUE,
null));
// For each airport put WindBarb info
airports.each { Airport airport ->
geographicMap.addShape(new WindBarb(airport.weather.windSpeed,
airport.weather.windDirection,
SpeedUnit.KNOTS,
airport.weather.skyCoverage,
generator.getCoordTransformation().transformWGS84ToCartesianGeoPos(airport.geoPosition).convertToCartesianGeoPosition().convertToPixels(mapParameters),
new CartesianDimension(8, 8),
5,
Color.black,
Color.white,
airport.icaoCode,
new Font("Lucida Sans" , Font.PLAIN, 10),
Color.red,
new CartesianOffset(5, 5)));
}
}
else assert false;
// Generate map
generator.initialize();
MapGeneratorResult result = generator.generate(WriterGroup.getAll());
if(result == MapGeneratorResult.success)
{
MapWriters mapWriters = generator.getMapWriters();
// Find ImageMapWriterToCanvas, force it to render final map to GUI
for(AbstractMapWriter mapWriter : mapWriters)
{
if(mapWriter instanceof ImageMapWriterToCanvas)
{
ImageMapWriterToCanvas imageMapWriterToCanvas = (ImageMapWriterToCanvas) mapWriter;
GeographicMapCanvas canvas = imageMapWriterToCanvas.getCanvas();
if(canvas != null)
{
JFrame frame = new JFrame(generator.getDescription() == null ? "Map" : generator.getDescription());
frame.add(canvas);
frame.setSize(canvas.getGeographicsMap().getImageMapParameters().getDimension().toAwtDimension());
imageMapWriterToCanvas.setParent(frame);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
break;
}
}
}
println 'Finished';
}
}