.getName()), true);
}
}
}
ElemStyle wayStyle = styles != null ? getPrimitiveStyle(r) : null;
if (styles != null
&& (wayStyle == null || !(wayStyle instanceof AreaElemStyle))) {
for (Way w : outer) {
if (wayStyle == null || !(wayStyle instanceof AreaElemStyle))
wayStyle = styles.get(w);
}
r.mappaintStyle = wayStyle;
}
if (wayStyle != null && wayStyle instanceof AreaElemStyle) {
Boolean zoomok = isZoomOk(wayStyle);
Boolean visible = false;
Collection<Way> join = new LinkedList<Way>();
drawn = true;
for (Way w : outer) {
if (w.isClosed())
outerclosed.add(w);
else
join.add(w);
}
if (join.size() != 0) {
for (Way w : joinWays(join, incomplete ? null : r))
outerclosed.add(w);
}
join.clear();
for (Way w : inner) {
if (w.isClosed())
innerclosed.add(w);
else
join.add(w);
}
if (join.size() != 0) {
for (Way w : joinWays(join, incomplete ? null : r))
innerclosed.add(w);
}
if (outerclosed.size() == 0) {
r.putError(tr("No outer way for multipolygon ''{0}''.", r
.getName()), true);
visible = true; /* prevent killing remaining ways */
} else if (zoomok) {
class PolyData {
public Polygon poly = new Polygon();
public Way way;
private Point p = null;
private Collection<Polygon> inner = null;
PolyData(Way w) {
way = w;
for (Node n : w.nodes) {
p = nc.getPoint(n.getEastNorth());
poly.addPoint(p.x, p.y);
}
}
public int contains(Polygon p) {
int contains = p.npoints;
for (int i = 0; i < p.npoints; ++i) {
if (poly.contains(p.xpoints[i], p.ypoints[i]))
--contains;
}
if (contains == 0)
return 1;
if (contains == p.npoints)
return 0;
return 2;
}
public void addInner(Polygon p) {
if (inner == null)
inner = new ArrayList<Polygon>();
inner.add(p);
}
public boolean isClosed() {
return (poly.npoints >= 3
&& poly.xpoints[0] == poly.xpoints[poly.npoints - 1] && poly.ypoints[0] == poly.ypoints[poly.npoints - 1]);
}
public Polygon get() {
if (inner != null) {
for (Polygon pp : inner) {
for (int i = 0; i < pp.npoints; ++i)
poly.addPoint(pp.xpoints[i], pp.ypoints[i]);
poly.addPoint(p.x, p.y);
}
inner = null;
}
return poly;
}
}
LinkedList<PolyData> poly = new LinkedList<PolyData>();
for (Way w : outerclosed) {
poly.add(new PolyData(w));
}
for (Way wInner : innerclosed) {
Polygon polygon = new Polygon();
for (Node n : wInner.nodes) {
Point pInner = nc.getPoint(n.getEastNorth());
polygon.addPoint(pInner.x, pInner.y);
}
if (!wInner.isClosed()) {
Point pInner = nc.getPoint(wInner.nodes.get(0)
.getEastNorth());
polygon.addPoint(pInner.x, pInner.y);
}
PolyData o = null;
for (PolyData pd : poly) {
Integer c = pd.contains(polygon);
if (c >= 1) {
if (c > 1 && pd.way.isClosed()) {
r
.putError(
tr(
"Intersection between ways ''{0}'' and ''{1}''.",
pd.way.getName(),
wInner.getName()), true);
}
if (o == null || o.contains(pd.poly) > 0)
o = pd;
}
}
if (o == null) {
if (!incomplete) {
r.putError(tr("Inner way ''{0}'' is outside.",
wInner.getName()), true);
}
o = poly.get(0);
}
o.addInner(polygon);
}
AreaElemStyle areaStyle = (AreaElemStyle) wayStyle;
for (PolyData pd : poly) {
Polygon p = pd.get();
if (isPolygonVisible(p)
&& (!areaStyle.closed || pd.isClosed())) {
drawAreaPolygon(p,
(pd.way.selected || r.selected) ? selectedColor
: areaStyle.color);
visible = true;
}
}
}
if (!visible) /* nothing visible, so disable relation and all its ways */
{
r.mappaintVisibleCode = viewid;
for (Way wInner : inner)
wInner.mappaintVisibleCode = viewid;
for (Way wOuter : outer)
wOuter.mappaintVisibleCode = viewid;
return drawn;
}
for (Way wInner : inner) {
ElemStyle innerStyle = getPrimitiveStyle(wInner);
if (innerStyle == null) {
if (zoomok
&& (wInner.mappaintDrawnCode != paintid || outer
.size() == 0)) {
drawWay(wInner, ((AreaElemStyle) wayStyle).line,
((AreaElemStyle) wayStyle).color,
wInner.selected || r.selected);
}
wInner.mappaintDrawnCode = paintid;
} else {
if (r.selected) {
drawSelectedMember(wInner, innerStyle, !wayStyle
.equals(innerStyle), wInner.selected);
}
if (wayStyle.equals(innerStyle)) {
r
.putError(
tr(
"Style for inner way ''{0}'' equals multipolygon.",
wInner.getName()), false);
if (!r.selected)
wInner.mappaintDrawnAreaCode = paintid;
}
}
}
for (Way wOuter : outer) {
ElemStyle outerStyle = getPrimitiveStyle(wOuter);
if (outerStyle == null) {
if (zoomok) {
drawWay(wOuter, ((AreaElemStyle) wayStyle).line,
((AreaElemStyle) wayStyle).color,
wOuter.selected || r.selected);