/*
* Copyright 2012 Red Hat, Inc. and/or its affiliates.
*
* 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.
*/
package org.optaplanner.examples.common.swingui.latitudelongitude;
import java.awt.Graphics2D;
import java.awt.geom.CubicCurve2D;
import org.optaplanner.swing.impl.TangoColorFactory;
public class LatitudeLongitudeTranslator {
public static final double MARGIN_RATIO = 0.04;
private double minimumLatitude = Double.MAX_VALUE;
private double maximumLatitude = -Double.MAX_VALUE;
private double minimumLongitude = Double.MAX_VALUE;
private double maximumLongitude = -Double.MAX_VALUE;
private double latitudeLength = 0.0;
private double longitudeLength = 0.0;
private double innerWidth = 0.0;
private double innerHeight = 0.0;
private double innerWidthMargin = 0.0;
private double innerHeightMargin = 0.0;
private int imageWidth = -1;
private int imageHeight = -1;
public void addCoordinates(double latitude, double longitude) {
if (latitude < minimumLatitude) {
minimumLatitude = latitude;
}
if (latitude > maximumLatitude) {
maximumLatitude = latitude;
}
if (longitude < minimumLongitude) {
minimumLongitude = longitude;
}
if (longitude > maximumLongitude) {
maximumLongitude = longitude;
}
}
public void prepareFor(double width, double height) {
latitudeLength = maximumLatitude - minimumLatitude;
longitudeLength = maximumLongitude - minimumLongitude;
innerWidthMargin = width * MARGIN_RATIO;
innerHeightMargin = height * MARGIN_RATIO;
innerWidth = width - (2.0 * innerWidthMargin);
innerHeight = height - (2.0 * innerHeightMargin);
// Keep ratio visually correct
if (innerWidth > innerHeight * longitudeLength / latitudeLength) {
innerWidth = innerHeight * longitudeLength / latitudeLength;
} else {
innerHeight = innerWidth * latitudeLength / longitudeLength;
}
imageWidth = (int) Math.floor((2.0 * innerWidthMargin) + innerWidth);
imageHeight = (int) Math.floor((2.0 * innerHeightMargin) + innerHeight);
}
public int translateLongitudeToX(double longitude) {
return (int) Math.floor(((longitude - minimumLongitude) * innerWidth / longitudeLength) + innerWidthMargin);
}
public int translateLatitudeToY(double latitude) {
return (int) Math.floor(((maximumLatitude - latitude) * innerHeight / latitudeLength) + innerHeightMargin);
}
public double translateXToLongitude(int x) {
return minimumLongitude + ((((double) x) - innerWidthMargin) * longitudeLength / innerWidth);
}
public double translateYToLatitude(double y) {
return maximumLatitude - ((((double) y) - innerHeightMargin) * latitudeLength / innerHeight);
}
public int getImageWidth() {
return imageWidth;
}
public int getImageHeight() {
return imageHeight;
}
public void drawSquare(Graphics2D g, double lon, double lat, int diameter) {
drawSquare(g, lon, lat, diameter, null);
}
public void drawSquare(Graphics2D g, double lon, double lat, int diameter, String label) {
int x = translateLongitudeToX(lon);
int y = translateLatitudeToY(lat);
g.fillRect(x - (diameter / 2), y - (diameter / 2), diameter, diameter);
if (label != null) {
g.drawString(label, x + diameter, y - diameter);
}
}
public void drawRoute(Graphics2D g, double lon1, double lat1, double lon2, double lat2, boolean straight, boolean dashed) {
int x1 = translateLongitudeToX(lon1);
int y1 = translateLatitudeToY(lat1);
int x2 = translateLongitudeToX(lon2);
int y2 = translateLatitudeToY(lat2);
if (dashed) {
g.setStroke(TangoColorFactory.FAT_DASHED_STROKE);
}
if (straight) {
g.drawLine(x1, y1, x2, y2);
} else {
double xDistPart = (x2 - x1) / 3.0;
double yDistPart = (y2 - y1) / 3.0;
double ctrlx1 = x1 + xDistPart + yDistPart;
double ctrly1 = y1 - xDistPart + yDistPart;
double ctrlx2 = x2 - xDistPart - yDistPart;
double ctrly2 = y2 + xDistPart - yDistPart;
g.draw(new CubicCurve2D.Double(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2));
}
if (dashed) {
g.setStroke(TangoColorFactory.NORMAL_STROKE);
}
}
}