blob: a540ac62ac870510d4057ed7c890fabfc08d2dbb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 Bundesinstitut für Risikobewertung.
* 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:
* Bundesinstitut für Risikobewertung - initial API and implementation
*******************************************************************************/
package org.eclipse.stem.ui.grapheditor;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.Segment;
public class Polygon {
public int npoints;
public double[] x;
public double[] y;
private double area;
private double cx;
private double cy;
private double xMin;
private double yMin;
private double xMax;
private double yMax;
public Polygon(Segment segment) {
getPolygon(segment);
computeAreaAndCentroid();
computeMinAndMax();
}
public double getArea() {
return area;
}
public Point2D.Double getCentroid() {
return new Point2D.Double(cx, cy);
}
public Rectangle2D.Double getBounds() {
return new Rectangle2D.Double(xMin, yMin, xMax - xMin, yMax - yMin);
}
/**
* all lat long data as a single string for file output
*
* @return all lat long data as a single string
*/
public String getData() {
StringBuffer sb = new StringBuffer(npoints * 24);
for (int i = 0; i < npoints; i++) {
sb.append(y[i] + " " + x[i] + " ");
}
return sb.substring(0, sb.length() - 1);
}
private void getPolygon(Segment segment) {
npoints = segment.size();
y = new double[npoints];
x = new double[npoints];
for (int i = 0; i < npoints; i++) {
y[i] = segment.latitude(i);
x[i] = segment.longitude(i);
}
// check if it is a polygon, repair if necessary
if (y[0] != y[npoints - 1] || x[0] != x[npoints - 1]) {
double[] y_new = new double[npoints + 1];
double[] x_new = new double[npoints + 1];
for (int i = 0; i < npoints; i++) {
y_new[i] = y[i];
x_new[i] = x[i];
}
y_new[npoints] = y[0];
x_new[npoints] = x[0];
x = x_new;
y = y_new;
npoints++;
}
}
private void computeAreaAndCentroid() {
area = 0.0;
cx = 0.0;
cy = 0.0;
for (int i = 0; i < npoints - 1; i++) {
double mem = x[i] * y[i + 1] - x[i + 1] * y[i];
area += mem;
cx += (x[i] + x[i + 1]) * mem;
cy += (y[i] + y[i + 1]) * mem;
}
area /= 2.0;
cx /= 6 * area;
cy /= 6 * area;
// area is negative if points are ordered clockwise, nevertheless cx and
// cy are correct
area = Math.abs(area);
}
private void computeMinAndMax() {
xMin = x[0];
yMin = y[0];
xMax = x[0];
yMax = y[0];
for (int i = 1; i < npoints; i++) {
xMin = Math.min(xMin, x[i]);
yMin = Math.min(yMin, y[i]);
xMax = Math.max(xMax, x[i]);
yMax = Math.max(yMax, y[i]);
}
}
}