// Created by plusminus on 21:42:53 - 16.10.2008 package org.androad.sys.ors.adt.aoi; import java.util.ArrayList; import java.util.Formatter; import java.util.List; import junit.framework.Assert; import org.osmdroid.util.BoundingBoxE6; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView.Projection; import org.androad.ui.map.overlay.util.ManagedLinePath; import android.graphics.Canvas; import android.graphics.Point; import android.os.Parcel; import android.os.Parcelable; public class Polygon extends AreaOfInterest { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== protected List<GeoPoint> mExterior; protected List<List<GeoPoint>> mInterior; protected BoundingBoxE6 mBoundingBoxE6; // =========================================================== // Constructors // =========================================================== public Polygon() { } public Polygon(final ArrayList<GeoPoint> pExterior) { this(pExterior, null, null); } public Polygon(final ArrayList<GeoPoint> pExterior, final BoundingBoxE6 pBoundingBoxE6) { this(pExterior, pBoundingBoxE6, null); } public Polygon(final List<GeoPoint> pExterior, final BoundingBoxE6 pBoundingBoxE6, final List<List<GeoPoint>> pInterior) { Assert.assertNotNull(pExterior); if(pExterior.size() < 3) { throw new IllegalArgumentException("A Polygon is defined by at least 3 Points!"); } this.mExterior = pExterior; this.mInterior = pInterior; this.mBoundingBoxE6 = pBoundingBoxE6; } // =========================================================== // Getter & Setter // =========================================================== public List<GeoPoint> getExterior() { return this.mExterior; } public List<List<GeoPoint>> getInterior() { return this.mInterior; } public BoundingBoxE6 getBoundingBoxE6() { if(this.mBoundingBoxE6 == null) { ; // TODO Calculate BoundingBox } return this.mBoundingBoxE6; } public void setExterior(final List<GeoPoint> exterior) { this.mExterior = exterior; } public void setInterior(final List<List<GeoPoint>> interior) { this.mInterior = interior; } public void addInterior(final List<GeoPoint> interior) { if(this.mInterior == null) { this.mInterior = new ArrayList<List<GeoPoint>>(); } this.mInterior.add(interior); } public void setBoundingBoxE6(final BoundingBoxE6 boundingBoxE6) { this.mBoundingBoxE6 = boundingBoxE6; } // =========================================================== // Methods from SuperClass/Interfaces // =========================================================== /** * <pre> <xls:AOI> * <gml:Polygon> * <gml:exterior> * <gml:LinearRing> * <gml:pos>45.256 -110.45</gml:pos> * <gml:pos>46.46 -109.48</gml:pos> * <gml:pos>43.84 -109.86</gml:pos> * <gml:pos>45.256 -110.45</gml:pos> * </gml:LinearRing> * </gml:exterior> * </gml:Polygon> * </xls:AOI></pre> */ @Override public void appendToStringBuilder(final StringBuilder sb, final Formatter f) { sb.append(XLS_AREAOFINTEREST_TAG_OPEN) .append(GML_POLYGON_TAG_OPEN) .append(GML_EXTERIOR_TAG_OPEN) .append(GML_LINEARRING_TAG_OPEN); for (final GeoPoint via : this.mExterior) { f.format(GML_POS_TAG, via.getLongitudeE6() / 1E6, via.getLatitudeE6() / 1E6); } sb.append(GML_LINEARRING_TAG_CLOSE) .append(GML_EXTERIOR_TAG_CLOSE) .append(GML_POLYGON_TAG_CLOSE) .append(XLS_AREAOFINTEREST_TAG_CLOSE); } @Override public void drawToCanvas(final Canvas c, final Projection pj) { final Point reuse = new Point(); final ManagedLinePath p = new ManagedLinePath(); for (final GeoPoint gp : this.mExterior) { p.lineTo(pj.toMapPixels(gp, reuse)); } c.drawPath(p, this.mPaint); } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== // =========================================================== // Parcelable // =========================================================== public static final Parcelable.Creator<Polygon> CREATOR = new Parcelable.Creator<Polygon>() { public Polygon createFromParcel(final Parcel in) { return readFromParcel(in); } public Polygon[] newArray(final int size) { return new Polygon[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(final Parcel out, final int arg1) { out.writeTypedList(this.mExterior); out.writeInt(this.mInterior.size()); for(final List<GeoPoint> interior : this.mInterior) { out.writeTypedList(interior); } out.writeParcelable(this.mBoundingBoxE6, 0); } private static Polygon readFromParcel(final Parcel in){ final ArrayList<GeoPoint> exterior = new ArrayList<GeoPoint>(); in.readTypedList(exterior, GeoPoint.CREATOR); final int interiorCount = in.readInt(); final ArrayList<List<GeoPoint>> interiors = new ArrayList<List<GeoPoint>>(); for(int i = 0; i < interiorCount; i++){ final ArrayList<GeoPoint> interior = new ArrayList<GeoPoint>(); in.readTypedList(interior, GeoPoint.CREATOR); interiors.add(interior); } final BoundingBoxE6 bbE6 = in.readParcelable(null); return new Polygon(exterior, bbE6, interiors); } }