/*
* Copyright 2010, 2011, 2012 mapsforge.org
*
* This program 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 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mapsforge.android.maps.overlay;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.Point;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.FillType;
/**
* A {@code Polygon} draws a list of {@link PolygonalChain PolygonalChains}. As a polygon represents a closed area, any
* open {@code PolygonalChain} will automatically be closed during the draw process.
* <p>
* A {@code Polygon} holds two {@link Paint} objects to allow for different outline and filling. These paints define
* drawing parameters such as color, stroke width, pattern and transparency. {@link Paint#setAntiAlias Anti-aliasing}
* should be enabled to minimize visual distortions and to improve the overall drawing quality.
*/
public class Polygon implements OverlayItem {
private Paint paintFill;
private Paint paintStroke;
private final List<PolygonalChain> polygonalChains;
/**
* @param polygonalChains
* the initial polygonal chains on this polygon (may be null).
* @param paintFill
* the initial {@code Paint} used to fill this polygon (may be null).
* @param paintStroke
* the initial {@code Paint} used to stroke this polygon (may be null).
*/
public Polygon(Collection<PolygonalChain> polygonalChains, Paint paintFill, Paint paintStroke) {
if (polygonalChains == null) {
this.polygonalChains = Collections.synchronizedList(new ArrayList<PolygonalChain>());
} else {
this.polygonalChains = Collections.synchronizedList(new ArrayList<PolygonalChain>(polygonalChains));
}
this.paintFill = paintFill;
this.paintStroke = paintStroke;
}
@Override
public synchronized boolean draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point canvasPosition) {
synchronized (this.polygonalChains) {
if (this.polygonalChains.isEmpty() || (this.paintStroke == null && this.paintFill == null)) {
return false;
}
Path path = new Path();
path.setFillType(FillType.EVEN_ODD);
for (int i = 0; i < this.polygonalChains.size(); ++i) {
PolygonalChain polygonalChain = this.polygonalChains.get(i);
Path closedPath = polygonalChain.draw(zoomLevel, canvasPosition, true);
if (closedPath != null) {
path.addPath(closedPath);
}
}
if (this.paintStroke != null) {
canvas.drawPath(path, this.paintStroke);
}
if (this.paintFill != null) {
canvas.drawPath(path, this.paintFill);
}
return true;
}
}
/**
* @return the {@code Paint} used to fill this polygon (may be null).
*/
public synchronized Paint getPaintFill() {
return this.paintFill;
}
/**
* @return the {@code Paint} used to stroke this polygon (may be null).
*/
public synchronized Paint getPaintStroke() {
return this.paintStroke;
}
/**
* @return a synchronized (thread-safe) list of all polygonal chains on this polygon. Manual synchronization on this
* list is necessary when iterating over it.
*/
public List<PolygonalChain> getPolygonalChains() {
synchronized (this.polygonalChains) {
return this.polygonalChains;
}
}
/**
* @param paintFill
* the new {@code Paint} used to fill this polygon (may be null).
*/
public synchronized void setPaintFill(Paint paintFill) {
this.paintFill = paintFill;
}
/**
* @param paintStroke
* the new {@code Paint} used to stroke this polygon (may be null).
*/
public synchronized void setPaintStroke(Paint paintStroke) {
this.paintStroke = paintStroke;
}
}