/*
* Copyright (C) 2015 Alec Dhuse
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.foldingmap.map.vector;
import co.foldingmap.Logger;
import co.foldingmap.map.MapView;
import co.foldingmap.map.ObjectNotWithinBoundsException;
import co.foldingmap.map.labeling.LabelAbbreviations;
import co.foldingmap.map.labeling.LineStringLabel;
import co.foldingmap.map.themes.ColorStyle;
import co.foldingmap.map.themes.LabelStyle;
import co.foldingmap.map.themes.LineStyle;
import co.foldingmap.map.themes.MapTheme;
import co.foldingmap.xml.XmlOutput;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.StringTokenizer;
/**
* Handles LineString objects, drawing and operation for modifying.
*
* @author Alec Dhuse
*/
public class LineString extends VectorObject {
protected boolean lineLeftInit, lineCenterInit, lineRightInit;
protected GeneralPath lineLeft, lineCenter, lineRight;
/**
* Constructor for super class.
*
*/
public LineString() {
super();
}
/**
* Constructor for objects of class LineString
*
* @param name
* @param lineClass
* @param lineCoordinates
*/
public LineString(String name, String lineClass, String lineCoordinates) {
super();
Coordinate newCoordinate;
String currentCoordinateString;
StringTokenizer st = new StringTokenizer(lineCoordinates);
commonConstructor(name, lineClass);
//get coordinates
while (st.hasMoreTokens()) {
currentCoordinateString = st.nextToken();
newCoordinate = new Coordinate(currentCoordinateString);
coordinates.add(newCoordinate);
}
}
/**
* Constructor for objects of class LineString
*
* @param name
* @param type
* @param lineCoordinates
*/
public LineString(String name, String type, CoordinateList lineCoordinates) {
super();
commonConstructor(name, type);
this.coordinates.addAll(lineCoordinates);
}
/**
* Constructor elements from multiple constructors in one place.
*
* @param name
* @param lineClass
*/
protected final void commonConstructor(String name, String lineClass) {
try {
this.altitudeMode = CLAMP_TO_GROUND;
this.coordinates = new CoordinateList<Coordinate>();
this.objectName = name;
this.objectClass = lineClass;
this.objectDescription = "";
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.commonConstructor(String, String) - " + e);
}
}
/**
* Creates a copy of this LineString.
*
* @return
*/
@Override
public VectorObject copy() {
LineString newCopy;
newCopy = new LineString(this.objectName, this.getObjectClass(), this.getCoordinateList());
newCopy.setDescription(this.getDescription());
newCopy.setParentLayer(this.getParentLayer());
newCopy.setCustomDataFields(this.customDataFields);
newCopy.setAltitudeMode(this.altitudeMode);
return newCopy;
}
/**
* Converts the objects latitude and longitude coordinates screen x,y points.
*
* @param mapView
*/
protected void convertCoordinatesToLines(MapView mapView) {
Coordinate currentCoordinate;
int loopStart;
Point2D.Float tempPoint;
Point2D[] points = null;
try {
this.lineCenter = new GeneralPath();
lineLeftInit = false;
lineCenterInit = false;
lineRightInit = false;
loopStart = 0;
if (coordinates.size() > 0) {
//prime the loop
currentCoordinate = (Coordinate) coordinates.get(loopStart);
tempPoint = currentCoordinate.getCenterPoint();
loopStart++;
lineCenter.moveTo(tempPoint.getX(), tempPoint.getY());
lineCenterInit = true;
//is left wrapping needed
if (mapView.getMapProjection().isLeftShown()) {
tempPoint = currentCoordinate.getLeftPoint();
lineLeft = new GeneralPath();
lineLeftInit = true;
lineLeft.moveTo(tempPoint.getX(), tempPoint.getY());
}
//right wrapping is needed
if (mapView.getMapProjection().isRightShown()) {
tempPoint = currentCoordinate.getRightPoint();
lineRight = new GeneralPath();
lineRightInit = true;
lineRight.moveTo(tempPoint.getX(), tempPoint.getY());
}
}
//Check to see if we are in the modify mode
if (!mapView.arePointsShown()) {
//Test for Ramer–Douglas–Peucker algorithm
points = new Point2D[coordinates.size()];
for (int i = 0; i < coordinates.size(); i++)
points[i] = coordinates.get(i).centerPoint;
// points = CoordinateMath.douglasPeuckerLine(points, 2);
}
//create the line
for (int i = loopStart; i < coordinates.size(); i++) {
currentCoordinate = coordinates.get(i);
if (lineCenterInit) {
if (!mapView.arePointsShown()) {
//Normal View Mode
if (i == (coordinates.size() - 1)) {
tempPoint = currentCoordinate.getCenterPoint();
lineCenter.lineTo(tempPoint.getX(), tempPoint.getY());
} else {
if (i < points.length)
lineCenter.lineTo(points[i].getX(), points[i].getY());
}
} else {
//Modify Mode, show all points
tempPoint = currentCoordinate.getCenterPoint();
lineCenter.lineTo(tempPoint.getX(), tempPoint.getY());
}
}
if (lineLeftInit) {
tempPoint = currentCoordinate.getLeftPoint();
lineLeft.lineTo(tempPoint.getX(), tempPoint.getY());
}
if (lineRightInit) {
tempPoint = currentCoordinate.getRightPoint();
lineRight.lineTo(tempPoint.getX(), tempPoint.getY());
}
}
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.convertCoordinatesToLines(MapView) - " + e);
}
}
/**
* Creates a label for this LineStirng.
*
* @param g2
* @param mapView
* @param labelStyle
* @return
*/
public ArrayList<LineStringLabel> createLabel(Graphics2D g2,
MapView mapView,
LabelStyle labelStyle) {
ArrayList<LineStringLabel> labels;
boolean createLabel;
double slope;
int offset;
float angle;
float centeredX, yOffset;
float labelLength, labelPartLength, segmentLengths;
float modifiedWidth, widthModifier;
float[] lengths;
LabelAbbreviations labelAbbreviations;
LineStringLabel lineLabel;
LineStyle lineStringStyle;
Point2D.Float p1, p2;
String nameAbbr;
StringBuffer namePart;
labels = new ArrayList<LineStringLabel>();
try {
labelAbbreviations = new LabelAbbreviations();
lengths = getSegmentLengths();
lineLabel = new LineStringLabel(g2);
nameAbbr = labelAbbreviations.replaceWithAbbreviations(objectName).trim();
segmentLengths = 0;
labelLength = lineLabel.getLabelLength(g2, nameAbbr);
lineStringStyle = (LineStyle) mapView.getMapTheme().getLineStyle(this.getObjectClass());
if (lineStringStyle == null)
lineStringStyle = (LineStyle) mapView.getMapTheme().getLineStyle("(Unspecified Linestring)");
widthModifier = getWidthModifier(mapView);
modifiedWidth = (lineStringStyle.getLineWidth() * widthModifier);
yOffset = (modifiedWidth <= 12 ? (modifiedWidth / 3.0f) : 4);
for (int i = 0; i < lengths.length; i++) {
Float f = lengths[i];
segmentLengths += f.floatValue();
if (labels.size() > 0) {
/* Only draw the label if there has been enough space
* since the last place the label was drawn */
if ((segmentLengths > labelLength * 2) && segmentLengths > 15) {
createLabel = true;
} else {
createLabel = false;
}
} else {
//No previous labels drawn, draw one now.
createLabel = true;
}
if (createLabel) {
lineLabel = new LineStringLabel(g2);
if ((f.floatValue() >= labelLength) && !coordinates.get(i).isShared()) {
p1 = this.coordinates.get(i).centerPoint;
p2 = this.coordinates.get(i+1).centerPoint;
angle = (float) Math.atan2((p2.getY() - p1.getY()) , (p2.getX() - p1.getX())); //convert slope to an angle
//Check to see if label will be drawn upside-down
if ((angle > 1.5707f && angle < 4.712f) ||
(angle < -1.5707f && angle > -4.712f)) {
p1 = this.coordinates.get(i+1).centerPoint;
p2 = this.coordinates.get(i).centerPoint;
angle = (float) Math.atan2((p2.getY() - p1.getY()) , (p2.getX() - p1.getX()));
}
centeredX = (float) ((p1.getX() + (f.floatValue() / 2.0f)) - (labelLength / 2.0f));
lineLabel.addLabelInstruction(angle, p1, centeredX, ((float) p1.getY()) + yOffset, nameAbbr);
lineLabel.setComplete(true);
segmentLengths = 0;
//Set Label Style
if (labelStyle != null) {
lineLabel.setOutlineColor(labelStyle.getOutlineColor());
lineLabel.setFillColor(labelStyle.getFillColor());
lineLabel.setFont(labelStyle.getFont());
}
// if (!labels.contains(lineLabel))
labels.add(lineLabel);
} else {
//Break up the label
//TODO: Write code to have lables drawn in multiple parts at different angles.
}
}
}
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.createLabel(Graphics2D, MapView) - " + e);
}
return labels;
}
/**
* Method that will draw this object.
*
* @param g2
* @param mapView
* @param colorStyle
*/
@Override
public void drawObject(Graphics2D g2, MapView mapView, ColorStyle colorStyle) {
boolean drawObject;
float width, widthModifier;
LineStyle lineStringStyle;
String lineStroke;
try {
drawObject = this.isVisible(mapView);
if (drawObject) {
//style
if (colorStyle == null) {
lineStringStyle = (LineStyle) mapView.getMapTheme().getStyle(this, mapView.getZoomLevel());
} else {
lineStringStyle = (LineStyle) colorStyle;
}
if (lineStringStyle == null)
lineStringStyle = (LineStyle) mapView.getMapTheme().getLineStyle("(Unspecified Linestring)");
convertCoordinatesToLines(mapView);
//Check to see if width is Modified based on zoom.
if (lineStringStyle.scaleWidth()) {
widthModifier = getWidthModifier(mapView);
width = lineStringStyle.getLineWidth() * widthModifier;
} else {
width = lineStringStyle.getLineWidth();
}
if (width > 28) width = 28;
if (width < lineStringStyle.getLineWidth()) lineStringStyle.getLineWidth();
if (highlighted) {
g2.setColor(lineStringStyle.getSelectedFillColor());
} else {
g2.setColor(lineStringStyle.getFillColor());
}
lineStroke = lineStringStyle.getLineStroke();
if (lineStroke.equals(LineStyle.SOLID_DASHED) || lineStroke.equals(LineStyle.IN_DASH)) {
//draw the solid part first
lineStyle = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2.setStroke(lineStyle);
if (lineLeftInit)
g2.draw(lineLeft);
if (lineCenterInit)
g2.draw(lineCenter);
if (lineRightInit)
g2.draw(lineRight);
//draw the dashed part next
if (lineStroke.equals(LineStyle.IN_DASH)) {
lineStyle = new BasicStroke(lineStringStyle.getLineWidth(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 8.0f, LineStyle.IN_DASHED_STYLE, (10.0f));
} else {
lineStyle = new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.SOLID_DASHED_STYLE, (10.0f));
}
g2.setStroke(lineStyle);
g2.setColor(lineStringStyle.getOutlineColor());
if (lineLeftInit)
g2.draw(lineLeft);
if (lineCenterInit)
g2.draw(lineCenter);
if (lineRightInit)
g2.draw(lineRight);
} else {
if (lineStringStyle.getLineStroke() != null) {
switch (lineStroke) {
case LineStyle.SOLID:
lineStyle = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
break;
case LineStyle.DASHED:
lineStyle = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.DASHED_STYLE, 0.0f);
break;
case LineStyle.DOTTED:
lineStyle = MapTheme.getStroke(LineStyle.DOTTED, lineStringStyle.getLineWidth() + 0.5f);
break;
case LineStyle.DASH_DOT:
lineStyle = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.DASHED_STYLE, 0.0f);
break;
}
} else {
lineStyle = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
}
g2.setStroke(lineStyle);
if (lineLeftInit)
g2.draw(lineLeft);
if (lineCenterInit)
g2.draw(lineCenter);
if (lineRightInit)
g2.draw(lineRight);
}
//create label
if (lineStringStyle.getLabel() != null)
mapView.getLabelManager().addLabels(g2, createLabel(g2, mapView, lineStringStyle.getLabel()));
} //end if draw object
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.drawObject(Graphics2D, MapView) " + e + " - " + this.objectName);
}
}// end drawObject
/**
* Draws the outline for this LineString.
*
* @param g2
* @param mapView
* @param inMultiGeometry
*/
@Override
public void drawOutline(Graphics2D g2, MapView mapView, boolean inMultiGeometry) {
BasicStroke lineOutlineStroke;
boolean drawObject, outline;
int styleCap;
float width, widthModifier;
LineStyle lineStringStyle;
try {
if (inMultiGeometry) {
styleCap = BasicStroke.CAP_BUTT;
} else {
styleCap = BasicStroke.CAP_ROUND;
}
lineStringStyle = (LineStyle) mapView.getMapTheme().getLineStyle(this.getObjectClass());
if (lineStringStyle != null) {
outline = lineStringStyle.isOutlined();
if (outline) {
if (lineStringStyle.scaleWidth()) {
widthModifier = getWidthModifier(mapView);
width = (lineStringStyle.getLineWidth() * widthModifier) + 1.2f;
} else {
width = lineStringStyle.getLineWidth();
}
if (width > 28) width = 28;
if (width < lineStringStyle.getLineWidth()) lineStringStyle.getLineWidth();
drawObject = this.isVisible(mapView);
if (lineStringStyle.getLineStroke() != null) {
if (lineStringStyle.getLineStroke().equals(LineStyle.SOLID)) {
lineOutlineStroke = new BasicStroke(width, styleCap, BasicStroke.JOIN_ROUND);
} else if (lineStringStyle.getLineStroke().equals(LineStyle.DASHED)) {
lineOutlineStroke = new BasicStroke(width, styleCap, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.DASHED_STYLE, 0.0f);
} else if (lineStringStyle.getLineStroke().equalsIgnoreCase(LineStyle.DOTTED)) {
lineOutlineStroke = MapTheme.getStroke(LineStyle.DOTTED, lineStringStyle.getLineWidth() + 1.4f);
} else if (lineStringStyle.getLineStroke().equals(LineStyle.DASH_DOT)) {
lineOutlineStroke = new BasicStroke(width, styleCap, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.DASHED_STYLE, 0.0f);
} else {
lineOutlineStroke = new BasicStroke(width, styleCap, BasicStroke.JOIN_ROUND);
}
} else {
lineOutlineStroke = new BasicStroke(width, styleCap, BasicStroke.JOIN_ROUND);
}
g2.setStroke(lineOutlineStroke);
g2.setColor(lineStringStyle.getOutlineColor());
if (drawObject) {
convertCoordinatesToLines(mapView);
if (lineLeftInit)
g2.draw(lineLeft);
if (lineCenterInit)
g2.draw(lineCenter);
if (lineRightInit)
g2.draw(lineRight);
}
} // end style != null check
}
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.drawOutline(Graphics2D, MapView) - " + e);
}
}
/**
* Draws the points that make up this object.
*
* @param g2
* @param mapView
*/
@Override
public void drawPoints(Graphics2D g2, MapView mapView) {
Shape leftShape, centerShape, rightShape;
leftShape = null;
rightShape = null;
if (selectedCoordinate == null)
selectedCoordinate = getCoordinateList().getCoordinateClosestTo(mapView.getLastMouseClickCoordinate());
//prevent null pointer exceptions
if (selectedCoordinate == null)
selectedCoordinate = Coordinate.UNKNOWN_COORDINATE;
//change the draw style
g2.setStroke(new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
for (int i = 0; i < coordinates.size(); i++) {
centerShape = getPointShape(coordinates.get(i), MapView.NO_WRAP);
g2.setColor(mapView.getMapTheme().getPointColor());
g2.draw(centerShape);
if (mapView.getMapProjection().isLeftShown()) {
leftShape = getPointShape(coordinates.get(i), MapView.WRAP_LEFT);
g2.draw(leftShape);
}
if (mapView.getMapProjection().isRightShown()) {
rightShape = getPointShape(coordinates.get(i), MapView.WRAP_RIGHT);
g2.draw(rightShape);
}
if (selectedCoordinate.equals(coordinates.get(i)))
g2.setColor(Color.WHITE);
g2.fill(centerShape);
if (mapView.getMapProjection().isRightShown())
g2.fill(rightShape);
if (mapView.getMapProjection().isLeftShown())
g2.fill(leftShape);
}
}
// /**
// * Returns whether or not this LineString is the same as another by comparing their coordinates.
// * Other information is not compared.
// *
// * @param lineStringToCompare The LineString being compared to this LineString.
// * @return If the two LineStrings are equal.
// */
// @Override
// public boolean equals(Object o) {
// LineString lineStringToCompare;
//
// if (o instanceof LineString) {
// lineStringToCompare = (LineString) o;
//
// return (this.hashCode() == lineStringToCompare.hashCode());
// } else {
// return false;
// }
// }
/**
* Returns the first Coordinate in this line's CoordinateList.
*
* @return
*/
public Coordinate firstCoordinate() {
return coordinates.get(0);
}
/**
* Returns this object sided to a given boundary.
*
* @param boundry
* @return
* @throws ObjectNotWithinBoundsException
*/
@Override
public VectorObject fitToBoundry(LatLonAltBox boundry) throws ObjectNotWithinBoundsException {
Coordinate northEastCoordinate, northWestCoordinate, southEastCoordinate, southWestCoordinate;
Coordinate cutOffCoordinate;
LineString fittedObject;
fittedObject= this;
fittedObject.getCoordinateList().clear();
cutOffCoordinate = Coordinate.UNKNOWN_COORDINATE;
northEastCoordinate = boundry.getNorthEastCoordinate();
northWestCoordinate = boundry.getNorthWestCoordinate();
southEastCoordinate = boundry.getSouthEastCoordinate();
southWestCoordinate = boundry.getSouthWestCoordinate();
for (int i = 0; i < this.coordinates.size(); i++) {
Coordinate currentCoordinate = this.coordinates.get(i);
if (boundry.contains(currentCoordinate)) {
if (boundry.contains(this.coordinates.get(i-1))) {
fittedObject.appendCoordinate(currentCoordinate);
} else {
if (currentCoordinate.isNorthOf(northWestCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northWestCoordinate, northEastCoordinate);
} else if (currentCoordinate.isSouthOf(southEastCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, southWestCoordinate, southEastCoordinate);
} else if (currentCoordinate.isWestOf(northWestCoordinate, 90)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northWestCoordinate, southWestCoordinate);
} else if (currentCoordinate.isEastOf(southEastCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northEastCoordinate, southEastCoordinate);
}
fittedObject.appendCoordinate(cutOffCoordinate);
}
} else {
//coordinate is not within the area
if (boundry.contains(this.coordinates.get(i-1))) {
//last object was in the boundry
if (currentCoordinate.isNorthOf(northWestCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northWestCoordinate, northEastCoordinate);
} else if (currentCoordinate.isSouthOf(southEastCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, southWestCoordinate, southEastCoordinate);
} else if (currentCoordinate.isWestOf(northWestCoordinate, 90)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northWestCoordinate, southWestCoordinate);
} else if (currentCoordinate.isEastOf(southEastCoordinate)) {
cutOffCoordinate = Intersection.getIntersection(coordinates.get(i-1), currentCoordinate, northEastCoordinate, southEastCoordinate);
}
fittedObject.appendCoordinate(cutOffCoordinate);
}
}
} //end for loop
fittedObject = this;
return fittedObject;
}
/**
* Returns a Coordinate within a given range.
*
* @param range
* @return
*/
@Override
public Coordinate getCoordinateWithinRectangle(Rectangle2D range) {
Coordinate returnCoordinate = null;
Point2D currentPoint;
for (int i = 0; i < coordinates.size(); i++) {
currentPoint = this.coordinates.get(i).getCenterPoint();
if (range.contains(currentPoint.getX(), currentPoint.getY())) {
returnCoordinate = coordinates.get(i);
//break; //Why was this removed?
}
}
return returnCoordinate;
}
/**
* Calculates the length of segments for Coordinates in this list.
*
* @return
*/
public float[] getSegmentLengths() {
float[] lengths;
float distance;
Point2D p1, p2;
lengths = new float[(coordinates.size() - 1)];
for (int i = 1; i < coordinates.size(); i++) {
p1 = this.coordinates.get(i-1).getCenterPoint();
p2 = this.coordinates.get(i).getCenterPoint();
distance = (float) Math.sqrt(Math.pow(p2.getX() - p1.getX(), 2) + Math.pow(p2.getY() - p1.getY(), 2));
lengths[i-1] = distance;
}
return lengths;
}
/**
* Gets the line width modifier to know the width when the map is zoomed in.
*
* @param mapView
* @return the current width modifier.
*/
protected float getWidthModifier(MapView mapView) {
float widthModifier;
if (mapView.getZoomLevel() < 100) {
widthModifier = 1f;
} else {
widthModifier = (float) (mapView.getZoomLevel() / 100.0);
}
return widthModifier;
}
/**
* Checks to see if the supplied coordinate is at the beginning or end of
* this LineString.
*
* @param c
* The Coordinate to test.
* @return If the coordinate is an endpoint.
*/
public boolean isEndPoint(Coordinate c) {
return coordinates.isEndPoint(c);
}
@Override
public boolean isObjectWithinRectangle(Rectangle2D range) {
boolean returnValue;
Line2D testLine;
Point2D lastPoint, lastPointLeft, lastPointRight;
//init
returnValue = false;
lastPoint = null;
lastPointLeft = null;
lastPointRight = null;
try {
if ((lineCenter != null)) {
for (Coordinate c: this.coordinates) {
//Check to see if the line's points itersect the range
if ((c.getCenterPoint() != null) && range.contains(c.getCenterPoint())) {
returnValue = true;
break;
}
if (lineLeftInit) {
if (range.contains(c.getLeftPoint())) {
returnValue = true;
break;
}
}
if (lineRightInit) {
if (range.contains(c.getRightPoint())) {
returnValue = true;
break;
}
}
/** Construct a line from the current point and
* the last to check if the range intersects it. */
if (c.getCenterPoint() != null && lastPoint != null) {
testLine = new Line2D.Float(lastPoint, c.getCenterPoint());
if (testLine.intersects(range)) {
returnValue = true;
break;
}
}
if (lineLeftInit) {
if (c.getLeftPoint() != null && lastPointLeft != null) {
testLine = new Line2D.Float(lastPointLeft, c.getLeftPoint());
if (testLine.intersects(range)) {
returnValue = true;
break;
}
}
}
if (lineRightInit) {
if (c.getRightPoint() != null && lastPointRight != null) {
testLine = new Line2D.Float(lastPointRight, c.getRightPoint());
if (testLine.intersects(range)) {
returnValue = true;
break;
}
}
}
lastPoint = c.getCenterPoint();
lastPointLeft = c.getLeftPoint();
lastPointRight = c.getRightPoint();
}
}
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.isObjectWithinRectangle(Rectangle2D) - " + e);
}
return returnValue;
}
/**
* Returns the last Coordinate in this LineString's Coordinate List.
*
* @return
*/
public Coordinate lastCoordinate() {
return coordinates.lastCoordinate();
}
@Override
public void toXML(XmlOutput xmlWriter) {
try {
xmlWriter.openTag ("LineString class=\"" + getObjectClass() + "\" id=\"" + getName() + "\"");
if (hasDisplayableText(getDescription()) && !getDescription().equalsIgnoreCase("null"))
xmlWriter.writeTag("description", "<![CDATA[" + getDescription() + "]]>");
xmlWriter.writeTag("Ref", Long.toString(getReference()));
xmlWriter.writeTag("coordinates", getCoordinateString());
if (visibility != null)
visibility.toXML(xmlWriter);
writeCustomDataFieldsAsXML(xmlWriter);
xmlWriter.closeTag("LineString");
} catch (Exception e) {
Logger.log(Logger.ERR, "Error in LineString.toXML(xmlWriter) Object: " + this.objectName + " - " + e);
}
}
}