/** * 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'; } }