Rev 1650 |
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.
*
*/
package uk.me.parabola.mkgmap.filters;
import java.util.ArrayList;
import java.util.List;
import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.imgfmt.app.CoordNode;
import uk.me.parabola.mkgmap.general.MapElement;
import uk.me.parabola.mkgmap.general.MapLine;
public class RoundCoordsFilter
implements MapFilter
{
private int shift
;
public void init
(FilterConfig config
) {
shift = config.
getShift();
}
/**
* @param element A map element that will be a line or a polygon.
* @param next This is used to pass the possibly transformed element onward.
*/
public void doFilter
(MapElement element, MapFilterChain next
) {
MapLine line =
(MapLine
) element
;
int half =
1 << (shift -
1); // 0.5 shifted
int mask = ~
((1 << shift
) -
1); // to remove fraction bits
if(shift ==
0) {
// do nothing
next.
doFilter(line
);
}
else {
// round lat/lon values to nearest for shift
List<Coord
> newPoints =
new ArrayList<Coord
>(line.
getPoints().
size());
MapLine newLine = line.
copy();
Coord lastP =
null;
for(Coord p : line.
getPoints()) {
int lat =
(p.
getLatitude() + half
) & mask
;
int lon =
(p.
getLongitude() + half
) & mask
;
Coord newP
;
if(p
instanceof CoordNode
)
newP =
new CoordNode
(lat, lon, p.
getId(), p.
getOnBoundary());
else
newP =
new Coord
(lat, lon
);
newP.
preserved(p.
preserved());
// only add the new point if it has different
// coordinates to the last point or if it's a
// CoordNode and the last point wasn't a CoordNode
if(lastP ==
null ||
!lastP.
equals(newP
) ||
(newP
instanceof CoordNode
&& !(lastP
instanceof CoordNode
))) {
newPoints.
add(newP
);
lastP = newP
;
}
else if(newP.
preserved()) {
// this point is not going to be used because it
// has the same (rounded) coordinates as the last
// node but it has been marked as being "preserved" -
// transfer that property to the previous point so
// that it's not lost
lastP.
preserved(true);
}
}
if(newPoints.
size() > 1) {
newLine.
setPoints(newPoints
);
next.
doFilter(newLine
);
}
}
}
}