blob: 20f8ba71632d470c72c1c80b3e59449de16f4b40 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.sensors.imaging.impl;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import org.eclipse.apogy.addons.sensors.imaging.AzimuthDirection;
import org.eclipse.apogy.addons.sensors.imaging.ElevationDirection;
import org.eclipse.apogy.addons.sensors.imaging.ImageSnapshot;
import org.eclipse.apogy.common.images.AbstractEImage;
import org.eclipse.apogy.common.images.ApogyCommonImagesFactory;
import org.eclipse.apogy.common.images.EImage;
import org.eclipse.apogy.common.images.EImagesUtilities;
public class ImagingUtilitiesCustomImpl extends ImagingUtilitiesImpl {
@Override
public double linearConvertToHorizontalAngle(ImageSnapshot imageSnapshot, int horizontalPixelPosition) {
double hCenter = (imageSnapshot.getImage().getWidth()) / 2.0;
double ratio = (hCenter - horizontalPixelPosition) / (imageSnapshot.getImage().getWidth());
double angle = ratio * imageSnapshot.getFieldOfView().getHorizontalFieldOfViewAngle();
return angle;
}
@Override
public double linearConvertToVerticalAngle(ImageSnapshot imageSnapshot, int verticalPixelPosition) {
double vCenter = (imageSnapshot.getImage().getHeight()) / 2.0;
double ratio = (vCenter - verticalPixelPosition) / (imageSnapshot.getImage().getHeight());
double angle = ratio * imageSnapshot.getFieldOfView().getVerticalFieldOfViewAngle();
return angle;
}
@Override
public AbstractEImage getAzimuthElevationOverlay(int imageWidth, int imageHeight, double panAngle, double tiltAngle,
double horizontalFOVAngle, double verticalFOVAngle, AzimuthDirection azimuthDirection,
ElevationDirection elevationDirection, int angleInterval, String fontName, int fontSize,
Color positiveColor, Color negativeColor, int lineWidth) {
AbstractEImage abstractImage = EImagesUtilities.INSTANCE.createTransparentImage(imageWidth, imageHeight);
BufferedImage image = abstractImage.asBufferedImage();
Graphics2D g2d = image.createGraphics();
Font font = new Font(fontName, Font.BOLD, fontSize);
g2d.setFont(font);
g2d.setStroke(new BasicStroke(lineWidth));
g2d.setColor(positiveColor);
int centerX = (int) Math.round((imageWidth / 2.0));
int centerY = (int) Math.round((imageHeight / 2.0));
// Finds the left and right azimuths.
double leftSideAzimuth = 0;
double rightSideAzimuth = 0;
if (azimuthDirection == AzimuthDirection.POSITIVE_TOWARD_LEFT) {
leftSideAzimuth = panAngle + (horizontalFOVAngle / 2.0);
rightSideAzimuth = panAngle - (horizontalFOVAngle / 2.0);
} else {
leftSideAzimuth = panAngle - (horizontalFOVAngle / 2.0);
rightSideAzimuth = panAngle + (horizontalFOVAngle / 2.0);
}
// Finds the top and bottom tilt.
double topSideElevation = 0;
double bottomSideElevation = 0;
if (elevationDirection == ElevationDirection.POSITIVE_UP) {
topSideElevation = tiltAngle + (verticalFOVAngle / 2.0);
bottomSideElevation = tiltAngle - (verticalFOVAngle / 2.0);
} else {
topSideElevation = tiltAngle - (verticalFOVAngle / 2.0);
bottomSideElevation = tiltAngle + (verticalFOVAngle / 2.0);
}
double pixelPerAzimuthDegree = (imageWidth / horizontalFOVAngle);
double pixelPerElevationDegree = (imageHeight / verticalFOVAngle);
// HORIZONTAL
// Finds the closest integer on the left side
int leftMostAngle = (int) Math.round(leftSideAzimuth);
// Adds horizontal ticks
double azimuth = leftMostAngle;
boolean done = false;
while (!done) {
// Selects the color.
if (azimuth >= 0)
g2d.setColor(positiveColor);
else
g2d.setColor(negativeColor);
int x = 0;
if (azimuthDirection == AzimuthDirection.POSITIVE_TOWARD_LEFT) {
x = (int) Math.round((leftSideAzimuth - azimuth) * pixelPerAzimuthDegree);
} else {
x = (int) Math.round((azimuth - leftSideAzimuth) * pixelPerAzimuthDegree);
}
if (Math.IEEEremainder(azimuth, angleInterval) == 0.0) {
String text = Double.toString(azimuth);
FontMetrics fontMetrics = g2d.getFontMetrics(font);
Rectangle2D textArea = fontMetrics.getStringBounds(text, g2d);
int xOffset = Math.round(((float) textArea.getWidth() / 2.0f));
g2d.drawLine(x, centerY - 10, x, centerY + 10);
g2d.drawString(text, x - xOffset, centerY + 10 + (int) textArea.getHeight());
} else {
g2d.drawLine(x, centerY - 5, x, centerY + 5);
}
// Increment azimuth and checks is azimuth is done.
if (azimuthDirection == AzimuthDirection.POSITIVE_TOWARD_LEFT) {
azimuth -= 1;
done = azimuth <= rightSideAzimuth;
} else {
azimuth += 1;
done = azimuth >= rightSideAzimuth;
}
}
int azimuthZero = -1;
// Draws the horizontal line.
if (leftSideAzimuth >= 0) {
// If the entire interval is positive
if (rightSideAzimuth >= 0) {
g2d.setColor(positiveColor);
g2d.drawLine(0, centerY, imageWidth, centerY);
} else {
// Find where zero is in pixels.
azimuthZero = (int) (pixelPerAzimuthDegree * leftSideAzimuth);
// Left side is Positive
g2d.setColor(positiveColor);
g2d.drawLine(0, centerY, azimuthZero, centerY);
// Right Side is negative
g2d.setColor(negativeColor);
g2d.drawLine(azimuthZero, centerY, imageWidth, centerY);
}
} else {
if (rightSideAzimuth <= 0) {
// The entire interval is negative
g2d.setColor(negativeColor);
g2d.drawLine(0, centerY, imageWidth, centerY);
} else {
// Find where zero is in pixels.
azimuthZero = (int) Math.abs((pixelPerAzimuthDegree * leftSideAzimuth));
// Left side is Negative
g2d.setColor(negativeColor);
g2d.drawLine(0, centerY, azimuthZero, centerY);
// Right Side is Positive
g2d.setColor(positiveColor);
g2d.drawLine(azimuthZero, centerY, imageWidth, centerY);
}
}
// VERTICAL
int topMostAngle = (int) Math.round(topSideElevation);
// Adds vertical ticks
double elevation = topMostAngle;
done = false;
while (!done) {
// Selects the color.
if (elevation >= 0)
g2d.setColor(positiveColor);
else
g2d.setColor(negativeColor);
int y = 0;
if (elevationDirection == ElevationDirection.POSITIVE_UP) {
y = (int) Math.round((topSideElevation - elevation) * pixelPerElevationDegree);
} else {
y = (int) Math.round((elevation - topSideElevation) * pixelPerElevationDegree);
}
if (Math.IEEEremainder(elevation, angleInterval) == 0.0) {
String text = Double.toString(elevation);
FontMetrics fontMetrics = g2d.getFontMetrics(font);
Rectangle2D textArea = fontMetrics.getStringBounds(text, g2d);
int xOffset = (int) textArea.getWidth() + 14;
int yOffset = (int) (textArea.getHeight() / 2.0f);
g2d.drawLine(centerX - 10, y, centerX + 10, y);
g2d.drawString(text, centerX - xOffset, y + yOffset);
} else {
g2d.drawLine(centerX - 5, y, centerX + 5, y);
}
// Increment elevation and checks is azimuth is done.
if (elevationDirection == ElevationDirection.POSITIVE_UP) {
elevation -= 1;
done = elevation <= bottomSideElevation;
} else {
elevation += 1;
done = elevation >= bottomSideElevation;
}
}
// Draws the vertical line.
if (topSideElevation >= 0) {
// If the entire interval is positive
if (bottomSideElevation >= 0) {
g2d.setColor(positiveColor);
g2d.drawLine(centerX, 0, centerX, imageHeight);
} else {
int elevationZero = (int) Math.round(pixelPerElevationDegree * topSideElevation);
g2d.setColor(positiveColor);
g2d.drawLine(centerX, 0, centerX, elevationZero);
g2d.setColor(negativeColor);
g2d.drawLine(centerX, elevationZero, centerX, imageHeight);
}
} else {
if (bottomSideElevation >= 0) {
int elevationZero = (int) Math.abs(pixelPerElevationDegree * topSideElevation);
g2d.setColor(negativeColor);
g2d.drawLine(centerX, 0, centerX, elevationZero);
g2d.setColor(positiveColor);
g2d.drawLine(centerX, elevationZero, centerX, imageHeight);
} else {
// Entire range is negative
g2d.setColor(negativeColor);
g2d.drawLine(centerX, 0, centerX, imageHeight);
}
}
EImage result = ApogyCommonImagesFactory.eINSTANCE.createEImage();
result.setImageContent(image);
g2d.dispose();
return result;
}
} // ImagingUtilitiesImpl