/*---------------- FILE HEADER --------------------------------------- This file is part of Geoide. Copyright (C) 2005-2006 by: IDgis B.V. http://www.idgis.nl This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Herman Assink IDgis bv P.O. Box 15 7450 AA Holten The Netherlands E-Mail: herman.assink@idgis.nl * @version 1.4.0 * @author IDgis team * ------------------------------------------------------------------------*/ import nl.idgis.giclient.geoma.Envelope; import nl.idgis.giclient.geoma.Geometry; import nl.idgis.giclient.geoma.LineSegment; import nl.idgis.giclient.geoma.Point; import nl.idgis.giclient.geoma.GeometryTools; import nl.idgis.giclient.geoma.NullGeometry; class nl.idgis.giclient.geoma.LineString extends Geometry { private var points:Array = null; function LineString(srsName:String, points:Array) { super(srsName); this.points = points; for (var i:String in points) { Point(points[i]).setSuperGeometry(this); } } function getGeometries():Array { var lineSegments:Array = getLineSegments(); var geometries:Array = points.concat(lineSegments); return geometries; } function addPoint(point:Point, permanent:Boolean):Void { if ((points.length == 2) && (points[0] == points[1])) { points[1] = point; } else { points.push(point); } point.setSuperGeometry(this); geometryEventDispatcher.changeGeometry(this, permanent); } function addPointN(point:Point, num:Number, permanent:Boolean):Void { if ((num < 1) || (num > (points.length - 1))) { // EXCEPTION return; } points.splice(num, 0, point); point.setSuperGeometry(this); geometryEventDispatcher.changeGeometry(this, permanent); } function addPoints(points:Array, permanent:Boolean):Void { for (var i:Number = 0; i < points.length; i++) { addPoint(Point(points[i]), permanent); } } function removePoint(point:Point, permanent:Boolean):Void { if (points.length == 2) { if (point == null) { return; } else if (points[0] == points[1]) { return; } else { var otherPoint:Point = null; var pointIndex:Number = -1; if (point == points[0]) { otherPoint = Point(points[1]); pointIndex = 0; } else if (point == points[1]) { otherPoint = Point(points[0]); pointIndex = 1; } point.setSuperGeometry(null); points[pointIndex] = new Point(getSRS(), otherPoint.getX(), otherPoint.getY()); geometryEventDispatcher.changeGeometry(this, permanent); } } else { if (point == null) { Point(points[points.length - 1]).setSuperGeometry(null); points.pop(); geometryEventDispatcher.changeGeometry(this, permanent); } else { for (var i:Number = 0; i < points.length; i++) { if (points[i] == point) { point.setSuperGeometry(null); points.splice(i, 1); geometryEventDispatcher.changeGeometry(this, permanent); break; } } } } } function setPointXY(x:Number, y:Number):Void { points[points.length - 1].setXY(x, y); } function removePointN(num:Number, permanent:Boolean):Void { // if ((num < 1) || (num > (points.length - 1))) { // // EXCEPTION // return; // } if (points.length == 2) { if (points[0] == points[1]) { // EXCEPTION return; } else { points[1] = points[0]; } } else { Point(points[num]).setSuperGeometry(null); points.splice(num, 1); } geometryEventDispatcher.changeGeometry(this, permanent); } function move(dx:Number, dy:Number, permanent:Boolean):Void { var n:Number = null; if (points[0] == points[points.length - 1]) { n = 1; } else { n = 0; } for (var i:Number = n; i < points.length; i++) { Point(points[i]).move(dx, dy, permanent); } } function getCoords():Array { return points; } function getPoints():Array { return points; } function getLineSegments():Array { var lineSegment:LineSegment = null; var lineSegments:Array = new Array(); for (var i:Number = 0; i < points.length - 1; i++) { lineSegment = new LineSegment(getSRS(), points[i], points[i + 1], i + 1); lineSegment.setSuperGeometry(this); lineSegments.push(lineSegment); } return lineSegments; } function getCenterPoint():Point { var centerPoint:Point = getCentroid(); return centerPoint; } function getCentroid():Point { var sumX:Number = 0; var sumY:Number = 0; var numUniquePoints:Number = 0; var n:Number = null; if (points[0] == points[points.length - 1]) { n = 1; } else { n = 0; } var point:Point = null; for (var i:Number = n; i < points.length; i++) { point = Point(points[i]); sumX = sumX + point.getX(); sumY = sumY + point.getY(); numUniquePoints++; } var centroid:Point = new Point(getSRS(), sumX / numUniquePoints, sumY / numUniquePoints); return centroid; } function getNearestPoint(point:Point):Point { var currentPoint:Point = Point(points[0]); var distance:Number = currentPoint.getDistance(point); var nearestDistance:Number = distance; var nearestPoint:Point = currentPoint; for (var i:String in points) { currentPoint = Point(points[i]); distance = currentPoint.getDistance(point); if (nearestDistance > distance) { nearestDistance = distance; nearestPoint = currentPoint; } } return nearestPoint; } function getEnvelope():Envelope { var point:Point = Point(points[0]); var minX:Number = point.getX(); var minY:Number = point.getY(); var maxX:Number = point.getX(); var maxY:Number = point.getY(); for (var i:Number = 1; i < points.length; i++) { point = Point(points[i]); if (minX > point.getX()) { minX = point.getX(); } if (minY > point.getY()) { minY = point.getY(); } if (maxX < point.getX()) { maxX = point.getX(); } if (maxY < point.getY()) { maxY = point.getY(); } } return new Envelope(getSRS(), minX, minY, maxX, maxY); } function clip(envelope:Envelope):Geometry { var lineSegments:Array = getLineSegments(); var clip:Geometry = null; var clippedLineSegments:Array = new Array(); for (var i:Number = 0; i < lineSegments.length; i++) { clip = LineSegment(lineSegments[i]).clip(envelope); if (!(clip instanceof NullGeometry)) { clippedLineSegments.push(clip); } } var points:Array = new Array(); var lineSegment:LineSegment = null; var point0:Point = null; var point1:Point = null; var previousPoint:Point = null; for (var i:Number = 0; i < clippedLineSegments.length; i++) { lineSegment = LineSegment(clippedLineSegments[i]); point0 = lineSegment.getPoints()[0]; point1 = lineSegment.getPoints()[1]; if (i == 0) { points.push(point0); } else { // i > 0 previousPoint = Point(points[points.length - 1]); if (!point0.equals(previousPoint)) { points = points.concat(GeometryTools.getCornersInBetween(previousPoint, point0, envelope)); points.push(point0); } } points.push(point1); } return new LineString(getSRS(), points); } function clone():Geometry { if ((points == null) || (points.length == 0)) { return null; } var pnts:Array = new Array(); for (var i:String in points) { pnts.push(Point(points[i]).clone()); } return new LineString(getSRS(), pnts); } function toString():String { return("LineString (" + points.toString() + ")"); } function getLength():Number { var length:Number = 0; var point:Point = null; var previousPoint:Point = null; var dx:Number = -1; var dy:Number = -1; for (var i:Number = 1; i < points.length; i++) { point = Point(points[i]); previousPoint = Point(points[i - 1]); dx = point.getX() - previousPoint.getX(); dy = point.getY() - previousPoint.getY(); length += Math.sqrt(dx * dx + dy * dy); } return length; } function isClosed():Boolean { if (points[0] == points[points.length - 1]) { return true; } else { return false; } } }