/*---------------- 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.LinearRing; import nl.idgis.giclient.geoma.Point; class nl.idgis.giclient.geoma.Polygon extends Geometry { private var exteriorRing:LinearRing = null; private var interiorRings:Array = null; function Polygon(srsName:String, exteriorRing:LinearRing) { super(srsName); this.exteriorRing = exteriorRing; exteriorRing.setSuperGeometry(this); interiorRings = new Array(); } function getGeometries():Array { var geometries:Array = new Array(exteriorRing); for (var i:Number = 0; i < interiorRings.length; i++) { geometries = geometries.concat(interiorRings[i]); } return geometries; } function getExteriorRing():LinearRing { return exteriorRing; } function addInteriorRing(interiorRing:LinearRing):Void { interiorRings.push(interiorRing); interiorRing.setSuperGeometry(this); geometryEventDispatcher.changeGeometry(this); } function removeInteriorRing(interiorRing:LinearRing):Void { for (var i:Number = 0; i < interiorRings.length; i++) { if (interiorRings[i] == interiorRing) { LinearRing(interiorRings[i]).setSuperGeometry(null); interiorRings.splice(i, 1); geometryEventDispatcher.changeGeometry(this); break; } } } function getInteriorRing(num:Number):LinearRing { if (num > interiorRings.length - 1) { // EXCEPTION return null; } return LinearRing(interiorRings[num]); } function getNumInteriorRings():Number { return interiorRings.length; } function addPoint(point:Point, permanent:Boolean):Void { exteriorRing.addPoint(point, permanent); } function addPointN(point:Point, num:Number, permanent:Boolean):Void { exteriorRing.addPointN(point, num, permanent); } function removeGeometry(geometry:Geometry):Void { if (!(geometry instanceof LinearRing)) { return; } removeInteriorRing(LinearRing(geometry)); // The exterior ring cannot be removed. } function removePoint(point:Point, permanent:Boolean):Void { exteriorRing.removePoint(point, permanent); for (var i:String in interiorRings) { LinearRing(interiorRings[i]).removePoint(point, permanent); } } function move(dx:Number, dy:Number):Void { exteriorRing.move(dx, dy); for (var i:String in interiorRings) { LinearRing(interiorRings[i]).move(dx, dy); } } function setPointXY(x:Number, y:Number):Void { exteriorRing.setPointXY(x, y); } function getCoords():Array { var coords:Array = exteriorRing.getCoords(); for (var i:Number = 0; i < interiorRings.length; i++) { coords = coords.concat(LinearRing(interiorRings[i]).getCoords()); } return coords; } function getCenterPoint():Point{ var centerPoint:Point = exteriorRing.getCentroid(); return centerPoint; } function getNearestPoint(point:Point):Point { var currentPoint:Point = exteriorRing.getNearestPoint(point); var distance:Number = currentPoint.getDistance(point); var nearestDistance:Number = distance; var nearestPoint:Point = currentPoint; for (var i:String in interiorRings) { currentPoint = LinearRing(interiorRings[i]).getNearestPoint(point); distance = currentPoint.getDistance(point); if (nearestDistance > distance) { nearestDistance = distance; nearestPoint = currentPoint; } } return nearestPoint; } function getEnvelope():Envelope { return exteriorRing.getEnvelope(); } function toString():String { if (interiorRings.length > 0 ) { return("Polygon (" + exteriorRing.toString() + " , " + interiorRings.toString() + ")"); } else { return("Polygon (" + exteriorRing.toString() + ")"); } } function getArea():Number { var area:Number = 0; var points:Array = exteriorRing.getPoints(); var point:Point = null; var nextPoint:Point = null; var x:Number = -1; var y:Number = -1; var nextX:Number = -1; var nextY:Number = -1; for (var i:Number = 0; i < points.length - 1; i++) { point = Point(points[i]); if (i < points.length - 2) { nextPoint = Point(points[i + 1]); } else { nextPoint = Point(points[0]); } x = point.getX(); y = point.getY(); nextX = nextPoint.getX(); nextY = nextPoint.getY(); area += (x * nextY - nextX * y); } area = Math.abs(area) / 2; // TODO subtract interior rings return area; } function clone():Polygon { //trace("Polygon.clone()"); var extRing:LinearRing = getExteriorRing(); var cloneExt:LinearRing = extRing.clone(); var clonePolygon:Polygon = new Polygon(getSRS(), cloneExt); for (var i:String in interiorRings) { var cloneInt:LinearRing = LinearRing(interiorRings[i]).clone(); clonePolygon.addInteriorRing(cloneInt); } return clonePolygon; } }