use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class SmoothingFilter method doFilter.
/**
* This applies to both lines and polygons. We are going to smooth out
* the points in the line so that you do not get jaggies. We are assuming
* that there is not an excess of points at the highest resolution.
*
* <ol>
* <li>If there is just one point, the drop it.
* <li>Ff the element is too small altogether, then drop it.
* <li>If there are just two points the pass it on unchanged. This is
* probably a pretty common case.
* <li>The first point goes in unchanged.
* <li>Average points in groups so that they exceed the step size
* at the shifted resolution.
* </ol>
*
* @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;
// First off we don't touch things if at the highest level of detail
if (shift == 0) {
next.doFilter(element);
return;
}
// If the line is not very long then just let it through. This is done
// mainly for the background polygons.
List<Coord> points = line.getPoints();
int n = points.size();
if (n <= 5) {
next.doFilter(element);
return;
}
// Create a new list to rewrite the points into.
List<Coord> coords = new ArrayList<Coord>(n);
// Get the step size, we want to place a point every time the
// average exceeds this size.
int stepsize = MIN_SPACING << shift;
// Always add the first point
Coord last = points.get(0);
coords.add(last);
// Average the rest
Average av = new Average(last, stepsize);
for (int i = 1; i < n; i++) {
Coord co = points.get(i);
av.add(co);
if (av.isMoreThanStep()) {
Coord nco = av.getAverageCoord();
coords.add(nco);
if (av.pointCounter() > 1)
i--;
last = nco;
av.reset(last);
}
}
Coord end = points.get(n - 1);
if (!last.equals(end))
coords.add(end);
MapLine newline = line.copy();
newline.setPoints(coords);
next.doFilter(newline);
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class LineClipper method clip.
/**
* A straight forward implementation of the Liang-Barsky algorithm as described
* in the referenced web page.
* @param a The clipping area.
* @param ends The start and end of the line the contents of this will
* be changed if the line is clipped to contain the new start and end
* points. A point that was inside the box will not be changed.
* @param nullIfInside true: returns null if all points are within the given area
* @return An array of the new start and end points if any of the line is
* within the box. If the line is wholly outside then null is returned.
* If a point is within the box then the same coordinate object will
* be returned as was passed in.
* @see <a href="http://www.skytopia.com/project/articles/compsci/clipping.html">Liang-Barsky algorithm</a>
*/
public static Coord[] clip(Area a, Coord[] ends, boolean nullIfInside) {
assert ends.length == 2;
if (a.insideBoundary(ends[0]) && a.insideBoundary(ends[1])) {
return (nullIfInside ? null : ends);
}
Coord lowerLeft = new Coord(a.getMinLat(), a.getMinLong());
Coord upperRight = new Coord(a.getMaxLat(), a.getMaxLong());
int x0 = ends[0].getHighPrecLon();
int y0 = ends[0].getHighPrecLat();
int x1 = ends[1].getHighPrecLon();
int y1 = ends[1].getHighPrecLat();
int dx = x1 - x0;
int dy = y1 - y0;
double[] t = { 0, 1 };
int p = -dx;
int q = -(lowerLeft.getHighPrecLon() - x0);
boolean scrap = checkSide(t, p, q);
if (scrap)
return null;
p = dx;
q = upperRight.getHighPrecLon() - x0;
scrap = checkSide(t, p, q);
if (scrap)
return null;
p = -dy;
q = -(lowerLeft.getHighPrecLat() - y0);
scrap = checkSide(t, p, q);
if (scrap)
return null;
p = dy;
q = upperRight.getHighPrecLat() - y0;
scrap = checkSide(t, p, q);
if (scrap)
return null;
assert t[0] >= 0;
assert t[1] <= 1;
Coord orig0 = ends[0];
Coord orig1 = ends[1];
if (ends[0].getOnBoundary()) {
// consistency check
assert a.onBoundary(ends[0]) : "Point marked as boundary node at " + ends[0].toString() + " not on boundary of [" + a.getMinLat() + ", " + a.getMinLong() + ", " + a.getMaxLat() + ", " + a.getMaxLong() + "]";
} else if (t[0] > 0) {
// line requires clipping so create a new end point and if
// its position (in map coordinates) is different from the
// original point, use the new point as a boundary node
Coord new0 = Coord.makeHighPrecCoord(calcCoord(y0, dy, t[0]), calcCoord(x0, dx, t[0]));
new0.setAddedByClipper(true);
// check the maths worked out
assert a.onBoundary(new0) : "New boundary point at " + new0.toString() + " not on boundary of [" + a.getMinLat() + ", " + a.getMinLong() + ", " + a.getMaxLat() + ", " + a.getMaxLong() + "]";
if (!new0.highPrecEquals(orig0))
ends[0] = new0;
ends[0].setOnBoundary(true);
} else if (a.onBoundary(ends[0])) {
// point lies on the boundary so it's a boundary node
ends[0].setOnBoundary(true);
}
if (ends[1].getOnBoundary()) {
// consistency check
assert a.onBoundary(ends[1]) : "Point marked as boundary node at " + ends[1].toString() + " not on boundary of [" + a.getMinLat() + ", " + a.getMinLong() + ", " + a.getMaxLat() + ", " + a.getMaxLong() + "]";
} else if (t[1] < 1) {
// line requires clipping so create a new end point and if
// its position (in map coordinates) is different from the
// original point, use the new point as a boundary node
Coord new1 = Coord.makeHighPrecCoord(calcCoord(y0, dy, t[1]), calcCoord(x0, dx, t[1]));
new1.setAddedByClipper(true);
// check the maths worked out
assert a.onBoundary(new1) : "New boundary point at " + new1.toString() + " not on boundary of [" + a.getMinLat() + ", " + a.getMinLong() + ", " + a.getMaxLat() + ", " + a.getMaxLong() + "]";
if (!new1.highPrecEquals(orig1))
ends[1] = new1;
ends[1].setOnBoundary(true);
} else if (a.onBoundary(ends[1])) {
// point lies on the boundary so it's a boundary node
ends[1].setOnBoundary(true);
}
if (t[0] >= t[1] || ends[0].highPrecEquals(ends[1]))
return null;
return ends;
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class HGTConverterTest method testReadHeight.
@Test
public void testReadHeight() throws Exception {
Area bbox = new Area(-1.04296875, -91.1, 0.1, -89.9);
HGTConverter hgtConverter = new HGTConverter(HGT_PATH, bbox, null, DEMFile.EXTRA);
int hgtRes = 1200;
double hgtDis = 1.0D / hgtRes;
int hgtX = 348;
int hgtY = 931;
int fileOffset = 2 * ((hgtRes - hgtY) * (hgtRes + 1) + hgtX);
assertEquals(646834, fileOffset);
// get a value from S01W091.hgt
double hgtLat = 0.0 - (hgtRes - hgtY) * hgtDis;
double hgtLon = -91.0 + hgtX * hgtDis;
// convert to DEM units
int lat32 = (int) (hgtLat / HGTConverter.FACTOR);
int lon32 = (int) (hgtLon / HGTConverter.FACTOR);
assertTrue(bbox.contains(new Coord(hgtLat, hgtLon)));
assertEquals(308, hgtConverter.getElevation(lat32, lon32));
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class RestrictionRelationTest method createRelation.
private static GeneralRelation createRelation() {
GeneralRelation gr = new GeneralRelation(1);
gr.addTag("type", "restriction");
Way fromWay = new Way(1);
Way toWay = new Way(2);
Coord viaCoord = new Coord(100, 100);
Node viaNode = new Node(1, viaCoord);
fromWay.addPoint(new Coord(0, 0));
fromWay.addPoint(viaCoord);
toWay.addPoint(new Coord(120, 200));
toWay.addPoint(viaCoord);
gr.addElement("from", fromWay);
gr.addElement("to", toWay);
gr.addElement("via", viaNode);
return gr;
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class Java2DConverterTest method testPolygonConversionAtMinus180.
@Test
public void testPolygonConversionAtMinus180() throws Exception {
// various calculations near 180.0
List<Coord> points1 = new ArrayList<>();
points1.add(new Coord(-1.0, -180.0));
points1.add(new Coord(0.0, -180.0));
points1.add(new Coord(-1.0, -179.0));
points1.add(points1.get(0));
Area a1 = Java2DConverter.createArea(points1);
uk.me.parabola.imgfmt.app.Area bbox = Java2DConverter.createBbox(a1);
for (Coord co : points1) assertTrue(bbox.contains(co));
Area awtPlanet = Java2DConverter.createBoundsArea(uk.me.parabola.imgfmt.app.Area.PLANET);
a1.intersect(awtPlanet);
assertTrue(a1.isSingular());
List<Coord> points2 = Java2DConverter.singularAreaToPoints(a1);
long testVal1 = ShapeMergeFilter.calcAreaSizeTestVal(points1);
long testVal2 = ShapeMergeFilter.calcAreaSizeTestVal(points2);
assertEquals(testVal1, testVal2);
}
Aggregations