/** * SpeedAltitudePlot.java * * Copyright � 1998-2011 Research In Motion Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Note: For the sake of simplicity, this sample application may not leverage * resource bundles and resource strings. However, it is STRONGLY recommended * that application developers make use of the localization features available * within the BlackBerry development platform to ensure a seamless application * experience across a variety of languages and geographies. For more information * on localizing your application, please refer to the BlackBerry Java Development * Environment Development Guide associated with this release. */ package com.rim.samples.server.gpsdemo; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.util.*; import javax.imageio.ImageIO; /** * <p>This class draws the graphs and plot on the server * It will write out three image files containing data compiled from the * client device. The Files are: * <ol> * <li>Plot.jpg - contains an overhead plot of the route * <li>Speed.jpg - contains the speed plots * <li>Altitude.jpg - contains the altitude plots * </ol> * <p>The files are written to the current running directory (if invoked * from the default install, the directory will be the Samples * directory of the RIM JDE installation) */ public class SpeedAltitudePlot { static double highLatitude = -90.0; static double lowLatitude = 90.0; static double highLongitude = -180.0; static double lowLongitude = 180.0; static double totalDistance; private static final int PLOT_WIDTH = 1200; private static final int PLOT_HEIGHT = 1200; public static void createCombinedChart(Collection c) { RenderedImage rendImage = drawPlot(c); File file = new File("Plot.jpg"); try { ImageIO.write(rendImage, "jpg", file); } catch (IOException e) { e.printStackTrace(); } rendImage = drawAltitudeGraph(c); file = new File("Altitude.jpg"); try { ImageIO.write(rendImage, "jpg", file); } catch (IOException e) { e.printStackTrace(); } rendImage = drawSpeedGraph(c); file = new File("Speed.jpg"); try { ImageIO.write(rendImage, "jpg", file); } catch (IOException e) { e.printStackTrace(); } } private static RenderedImage drawSpeedGraph(Collection c){ Iterator it=c.iterator(); double highSpeed=0; double lowSpeed=Double.MAX_VALUE; double totalDistance=0; // calculate the total distance covered while(it.hasNext()){ Point p = (Point)it.next(); if (p.speed > highSpeed) highSpeed = p.speed; if (p.speed < lowSpeed) lowSpeed = p.speed; totalDistance += p.distance; } BufferedImage bufferedImage = new BufferedImage(PLOT_WIDTH, PLOT_HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bufferedImage.createGraphics(); g2d.setColor(Color.white); g2d.fillRect(0, 0, PLOT_WIDTH, PLOT_HEIGHT); g2d.setColor(Color.black); g2d.drawLine(150,150,150,PLOT_HEIGHT-150); g2d.drawLine(150,PLOT_HEIGHT-150,PLOT_WIDTH-100,PLOT_HEIGHT-150); double speedDiff=highSpeed-lowSpeed; // draw the labels on the y axis for(int i=0;i<15;i++ ){ double yLabelValue=lowSpeed+i*speedDiff/14; double y=(150+ (highSpeed-yLabelValue)*(PLOT_HEIGHT-400)/(speedDiff)); yLabelValue=round(yLabelValue,1); g2d.drawString(String.valueOf(yLabelValue),50f,(float)y); } // draw the labels on the x axis for(int i=0;i<15;i++ ){ double XLabelValue=i*totalDistance/14; int x=(int)(150+ XLabelValue*(PLOT_WIDTH-250)/totalDistance); XLabelValue= round(XLabelValue,1); g2d.drawString(String.valueOf(XLabelValue),(float)x,PLOT_HEIGHT-100); } it=c.iterator(); int previousX=0; int previousY=0; float distance=0; while(it.hasNext()){ Point p=(Point)it.next(); distance+=p.distance; int newY=(int)(150+ (highSpeed-p.speed)*(PLOT_HEIGHT-400)/(speedDiff)); int newX=(int)(150+ distance*(PLOT_WIDTH-250)/totalDistance); if(previousX!=0)g2d.drawLine(previousX,previousY,newX,newY); previousX=newX; previousY=newY; } g2d.setFont(new Font(null,Font.BOLD ,30)); g2d.drawString("Distance",300,PLOT_HEIGHT-50); g2d.drawString("Speed",20,100); g2d.dispose(); return bufferedImage; } private static RenderedImage drawAltitudeGraph(Collection c){ Iterator it=c.iterator(); double highAltitude=0; double lowAltitude=Double.MAX_VALUE; double totalDistance=0; // calculate the total distance while(it.hasNext()){ Point p = (Point)it.next(); if (p.altitude > highAltitude) highAltitude = p.altitude; if (p.altitude < lowAltitude) lowAltitude = p.altitude; totalDistance += p.distance; } BufferedImage bufferedImage = new BufferedImage(PLOT_WIDTH, PLOT_HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bufferedImage.createGraphics(); g2d.setColor(Color.white); g2d.fillRect(0, 0, PLOT_WIDTH, PLOT_HEIGHT); g2d.setColor(Color.black); g2d.drawLine(150,150,150,PLOT_HEIGHT-150); g2d.drawLine(150,PLOT_HEIGHT-150,PLOT_WIDTH-100,PLOT_HEIGHT-150); double altitudeDiff=highAltitude-lowAltitude; // draw the labels on the y axis for(int i=0;i<15;i++ ){ double yLabelValue=lowAltitude+i*altitudeDiff/14; double y=(150+ (highAltitude-yLabelValue)*(PLOT_HEIGHT-400)/(altitudeDiff)); yLabelValue=round(yLabelValue,1); g2d.drawString(String.valueOf(yLabelValue),50f,(float)y); } // draw the labels on the x axis for(int i=0;i<15;i++ ){ double XLabelValue=i*totalDistance/14; int x=(int)(150+ XLabelValue*(PLOT_WIDTH-250)/totalDistance); XLabelValue= round(XLabelValue,1); g2d.drawString(String.valueOf(XLabelValue),(float)x,PLOT_HEIGHT-100); } it=c.iterator(); int previousX=0; int previousY=0; float distance=0; while(it.hasNext()){ Point p=(Point)it.next(); distance+=p.distance; int newY=(int)(150+ (highAltitude-p.altitude)*(PLOT_HEIGHT-400)/(altitudeDiff)); int newX=(int)(150+ distance*(PLOT_WIDTH-250)/totalDistance); if(previousX!=0)g2d.drawLine(previousX,previousY,newX,newY); previousX=newX; previousY=newY; } g2d.setFont(new Font(null,Font.BOLD ,30)); g2d.drawString("Distance",300,PLOT_HEIGHT-50); g2d.drawString("Altitude",20,100); g2d.dispose(); return bufferedImage; } private static double round(double d, int decimal) { double powerOfTen = 1; while (decimal-- > 0) { powerOfTen *= 10.0; } double d1 = d * powerOfTen; int d1asint = (int)d1; //clip the decimal portion away and cache the cast, this is a costly transformation double d2 = d1 - d1asint; //get the remainder of the double //is the remainder > 0.5? if so, round up, otherwise round down (lump in .5 with > case for simplicity) return ( d2 >= 0.5 ? (d1asint + 1)/powerOfTen : (d1asint)/powerOfTen); } private static RenderedImage drawPlot(Collection c) { Iterator it=c.iterator(); totalDistance=0; while(it.hasNext()){ Point p = (Point)it.next(); totalDistance += p.distance; if (p.latitude > highLatitude) highLatitude = p.latitude; if (p.latitude < lowLatitude) lowLatitude = p.latitude; if (p.longitude > highLongitude) highLongitude = p.longitude; if (p.longitude < lowLongitude) lowLongitude = p.longitude; } double lonDiff = highLongitude - lowLongitude; double latDiff = highLatitude - lowLatitude; if (lonDiff > latDiff) latDiff = lonDiff; else lonDiff = latDiff; double x; double y; double oldX = -200; double oldY = -200; int x1; int y1; int oldX1; int oldY1; BufferedImage bufferedImage = new BufferedImage(PLOT_WIDTH, PLOT_HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bufferedImage.createGraphics(); // Draw graphics g2d.setColor(Color.white); g2d.fillRect(0, 0, PLOT_WIDTH, PLOT_HEIGHT); g2d.setColor(Color.black); g2d.setFont(new Font(null,Font.BOLD ,40)); g2d.drawString("Path", PLOT_WIDTH/2-50, PLOT_HEIGHT-50); g2d.drawString("N", 75, PLOT_HEIGHT-125); g2d.drawString("S", 75, PLOT_HEIGHT-20); g2d.drawString("E", 135, PLOT_HEIGHT-75); g2d.drawString("W", 5, PLOT_HEIGHT-75); it = c.iterator(); while (it.hasNext()) { Point p = (Point)it.next(); x = p.longitude; y = p.latitude; if(oldX > -200 && oldY > -200){ x1 = (int)((x - lowLongitude) * PLOT_WIDTH/lonDiff); y1 = PLOT_HEIGHT - (int)((y - lowLatitude) * PLOT_HEIGHT/latDiff); oldX1 = (int)((oldX - lowLongitude) * PLOT_WIDTH/lonDiff); oldY1 = PLOT_HEIGHT - (int)((oldY - lowLatitude) * PLOT_HEIGHT/latDiff); g2d.drawLine(x1, y1, oldX1, oldY1); } oldX = x; oldY = y; } // Graphics context no longer needed so dispose it g2d.dispose(); return bufferedImage; } }