Search in sources :

Example 96 with Coord

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);
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) MapLine(uk.me.parabola.mkgmap.general.MapLine) ArrayList(java.util.ArrayList)

Example 97 with Coord

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;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord)

Example 98 with Coord

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));
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) Area(uk.me.parabola.imgfmt.app.Area) Test(org.junit.Test)

Example 99 with Coord

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;
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord)

Example 100 with Coord

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);
}
Also used : Coord(uk.me.parabola.imgfmt.app.Coord) Area(java.awt.geom.Area) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

Coord (uk.me.parabola.imgfmt.app.Coord)178 ArrayList (java.util.ArrayList)71 Way (uk.me.parabola.mkgmap.reader.osm.Way)31 MapPoint (uk.me.parabola.mkgmap.general.MapPoint)27 List (java.util.List)23 MapLine (uk.me.parabola.mkgmap.general.MapLine)16 Area (uk.me.parabola.imgfmt.app.Area)15 MapShape (uk.me.parabola.mkgmap.general.MapShape)15 CoordNode (uk.me.parabola.imgfmt.app.CoordNode)13 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)13 Node (uk.me.parabola.mkgmap.reader.osm.Node)13 HashMap (java.util.HashMap)12 IdentityHashMap (java.util.IdentityHashMap)11 Test (org.junit.Test)11 MapRoad (uk.me.parabola.mkgmap.general.MapRoad)9 Long2ObjectOpenHashMap (it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap)8 Area (java.awt.geom.Area)8 HashSet (java.util.HashSet)8 IntArrayList (it.unimi.dsi.fastutil.ints.IntArrayList)5 LinkedHashMap (java.util.LinkedHashMap)5