Rev 3408 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2007 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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 General Public License for more details.
*
*
* Author: Steve Ratcliffe
* Create date: Dec 2, 2007
*/
package uk.me.parabola.mkgmap.filters;
import uk.me.parabola.mkgmap.general.MapElement;
import uk.me.parabola.mkgmap.general.MapShape;
import java.util.ArrayList;
import java.util.List;
/**
* Split polygons so that they have less than the maximum number of points.
* This is handled by using java built in classes. Basically I am just taking
* the bounding box, splitting that in half and getting the intersection of
* each half-box with the original shape. Recurse until all are small enough.
*
* <p>Cutting things up may make discontiguous shapes, but this is handled by
* the java classes (for sure) and my code (probably).
*
* <p>Written assuming that this is not very common, once we start doing sea
* areas, may want to re-examine to see if we can optimize.
*
* @author Steve Ratcliffe
*/
public class PolygonSplitterFilter
extends PolygonSplitterBase
implements MapFilter
{
public static final int MAX_POINT_IN_ELEMENT =
250;
/**
* Split up polygons that have more than the max allowed number of points.
* Initially I shall just throw out polygons that have too many points
* to see if this is causing particular problems.
*
* @param element A map element, only polygons will be processed.
* @param next This is used to pass the possibly transformed element onward.
*/
public void doFilter
(MapElement element, MapFilterChain next
) {
assert element
instanceof MapShape
;
MapShape shape =
(MapShape
) element
;
int n = shape.
getPoints().
size();
if (n
< MAX_POINT_IN_ELEMENT
) {
// This is ok let it through and return.
next.
doFilter(element
);
return;
}
List<MapShape
> outputs =
new ArrayList<MapShape
>();
// Do an initial split
split
(shape, outputs
);
// Now check that all the resulting parts are also small enough.
// NOTE: the end condition is changed from within the loop.
for (int i =
0; i
< outputs.
size(); i++
) {
MapShape s = outputs.
get(i
);
if (s.
getPoints().
size() > MAX_POINT_IN_ELEMENT
) {
// Not small enough, so remove it and split it again. The resulting
// pieces will be placed at the end of the list and will be
// picked up later on.
outputs.
set(i,
null);
split
(s, outputs
);
}
}
// Now add all to the chain.
for (MapShape s : outputs
) {
if (s ==
null)
continue;
next.
doFilter(s
);
}
}
}