001: /*
002: * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
003: * for visualizing and manipulating spatial features with geometry and attributes.
004: *
005: * Copyright (C) 2003 Vivid Solutions
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: *
021: * For more information, contact:
022: *
023: * Vivid Solutions
024: * Suite #1A
025: * 2328 Government Street
026: * Victoria BC V8T 5G5
027: * Canada
028: *
029: * (250)385-6040
030: * www.vividsolutions.com
031: */
032: package com.vividsolutions.jump.workbench.ui.cursortool;
033:
034: import java.util.*;
035: import com.vividsolutions.jts.geom.Coordinate;
036: import com.vividsolutions.jump.I18N;
037: import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
038: import com.vividsolutions.jump.geom.Angle;
039:
040: /**
041: * Generates strings describing metrics for coordinate lists.
042: *
043: * @author Martin Davis
044: * @version 1.0
045: */
046: public class CoordinateListMetrics {
047: String sArea = I18N.get("ui.cursortool.CoordinateListMetrics.Area");
048: String sAngle = I18N
049: .get("ui.cursortool.CoordinateListMetrics.Angle");
050: String sDistance = I18N
051: .get("ui.cursortool.CoordinateListMetrics.Distance");
052:
053: public CoordinateListMetrics() {
054: }
055:
056: public void displayMetrics(List coordinates, LayerViewPanel panel) {
057: panel.getContext().setStatusMessage(
058: getMetricsString(coordinates, panel));
059: }
060:
061: public String getMetricsString(List coordinates,
062: LayerViewPanel panel) {
063: double dist = distance(coordinates);
064: String dispStr = sDistance + ": " + panel.format(dist);
065:
066: double angle = angle(coordinates);
067: dispStr += " " + sAngle + ": " + panel.format(angle);
068:
069: if (coordinates.size() > 2) {
070: double area = area(coordinates);
071: dispStr += " " + sArea + ": " + panel.format(area);
072: }
073: return dispStr;
074: }
075:
076: public static double distance(List coordinates) {
077: double distance = 0;
078: for (int i = 1; i < coordinates.size(); i++) {
079: distance += ((Coordinate) coordinates.get(i - 1))
080: .distance((Coordinate) coordinates.get(i));
081: }
082: return distance;
083: }
084:
085: /**
086: * Computes the angle between the last 2 segments in the coordinates list
087: *
088: * @param coordinates
089: * @return the angle in degrees
090: */
091: public static double angle(List coordinates) {
092: int size = coordinates.size();
093: if (size <= 1)
094: return 0.0;
095: Coordinate p1 = (Coordinate) coordinates.get(size - 2);
096: Coordinate p2 = (Coordinate) coordinates.get(size - 1);
097: // if only 2 coords, compute angle relative to X axis
098: Coordinate p0 = null;
099: if (size > 2)
100: p0 = (Coordinate) coordinates.get(size - 3);
101: else
102: p0 = new Coordinate(p1.x + 1.0, p1.y);
103:
104: double angRad = Angle.angleBetween(p1, p0, p2);
105: return Math.toDegrees(angRad);
106: }
107:
108: /**
109: * Computes the area for the coordinates list.
110: * The area is forcd to be positive.
111: * The coordinate list can be open, and the closing coordinate is supplied
112: */
113: private static double area(List coordinates) {
114: if (coordinates.size() < 3)
115: return 0.0;
116: double sum = 0.0;
117: for (int i = 0; i < coordinates.size(); i++) {
118: Coordinate b = (Coordinate) coordinates.get(i);
119: int nexti = i + 1;
120: if (nexti > coordinates.size() - 1)
121: nexti = 0;
122: Coordinate c = (Coordinate) coordinates.get(nexti);
123: sum += (b.x + c.x) * (c.y - b.y);
124: }
125: double signedArea = -sum / 2.0;
126: if (signedArea >= 0)
127: return signedArea;
128: return -signedArea;
129: }
130:
131: }
|