use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class Java2DConverter method createPath2D.
/**
* Creates a Java2D {@link Path2D} object from a polygon given as a list of
* {@link Coord} objects. This list should describe a closed polygon.
*
* @param polygonPoints a list of points that describe a closed polygon
* @return the converted Java2D path
*/
public static Path2D createPath2D(List<Coord> polygonPoints) {
int n = polygonPoints.size();
if (n < 3)
return new Path2D.Double();
Path2D path = new Path2D.Double(PathIterator.WIND_NON_ZERO, n);
if (polygonPoints.get(0).highPrecEquals(polygonPoints.get(n - 1))) {
// if first and last point are high-prec-equal, ignore last point
// because we use closePath() to signal that
--n;
}
int lastLat = Integer.MAX_VALUE, lastLon = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
Coord co = polygonPoints.get(i);
int latHp = co.getHighPrecLat();
int lonHp = co.getHighPrecLon();
double x = (double) lonHp / (1 << Coord.DELTA_SHIFT);
double y = (double) latHp / (1 << Coord.DELTA_SHIFT);
if (i == 0)
path.moveTo(x, y);
else {
if (lastLon != lonHp || lastLat != latHp)
path.lineTo(x, y);
}
lastLon = lonHp;
lastLat = latHp;
}
path.closePath();
return path;
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class LineSplitterFilterTest method testSizes.
@Test
public void testSizes() {
List<Coord> points = new ArrayList<>();
points.add(new Coord(1, 1));
for (int n = 2; n < 10 * LineSplitterFilter.MAX_POINTS_IN_LINE; n++) {
points.add(new Coord(n, n));
test(points);
}
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class LineClipperTest method testAllInside.
/**
* If all the lines are inside, then it should just return null to indicate that.
*/
@Test
public void testAllInside() {
Area a = new Area(100, 100, 200, 200);
List<Coord> l = Arrays.asList(new Coord(102, 110), new Coord(150, 150), new Coord(190, 195));
List<List<Coord>> list = LineClipper.clip(a, l);
assertNull("all lines inside", list);
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class LineClipperTest method testExampleClip.
/**
* This is the example as given on the referenced web page.
* We now use integers instead of floats so the 101.425 from the
* example is just 101 here.
*/
@Test
public void testExampleClip() {
Area a = new Area(60, 70, 150, 230);
Coord[] co = { new Coord(20, 30), new Coord(160, 280) };
List<List<Coord>> listList = LineClipper.clip(a, Arrays.asList(co));
assertTrue("list should be empty", !listList.isEmpty());
Coord[] result = { new Coord(60, 101), new Coord(132, 230) };
assertArrayEquals("example result", result, listList.get(0).toArray());
}
use of uk.me.parabola.imgfmt.app.Coord in project mkgmap by openstreetmap.
the class MapArea method splitIntoAreas.
/**
* Spit the polygon into areas
*
* @param areas The available areas to choose from.
* @param e The map element.
* @param used flag vector to say area has been added to.
*/
private void splitIntoAreas(MapArea[] areas, MapShape e) {
if (areas.length == 1) {
// this happens quite a lot
areas[0].addShape(e);
return;
}
// quick check if bbox of shape lies fully inside one of the areas
Area shapeBounds = e.getBounds();
// this is worked out at standard precision, along with Area.contains() and so can get
// tricky problems as it might not really be fully within the area.
// so: pretend the shape is a touch bigger. Will get the optimisation most of the time
// and in the boundary cases will fall into the precise code.
int xtra = 2;
// notices with an debug message and then output filters probably chuck away.
if (Math.min(shapeBounds.getWidth(), shapeBounds.getHeight()) > 8)
// pretend shape is smaller
xtra = -2;
shapeBounds = new Area(shapeBounds.getMinLat() - xtra, shapeBounds.getMinLong() - xtra, shapeBounds.getMaxLat() + xtra, shapeBounds.getMaxLong() + xtra);
for (int areaIndex = 0; areaIndex < areas.length; ++areaIndex) {
if (areas[areaIndex].getBounds().contains(shapeBounds)) {
areas[areaIndex].addShape(e);
return;
}
}
if (areasHashMap == null)
areasHashMap = new Long2ObjectOpenHashMap<>();
if (areas.length == 2) {
// just divide along the line between the two areas
int dividingLine = 0;
boolean isLongitude = false;
boolean commonLine = true;
if (areas[0].getBounds().getMaxLat() == areas[1].getBounds().getMinLat()) {
dividingLine = areas[0].getBounds().getMaxLat();
isLongitude = false;
} else if (areas[0].getBounds().getMaxLong() == areas[1].getBounds().getMinLong()) {
dividingLine = areas[0].getBounds().getMaxLong();
isLongitude = true;
} else {
commonLine = false;
log.error("Split into 2 expects shared edge between the areas");
}
if (commonLine) {
List<List<Coord>> lessList = new ArrayList<>(), moreList = new ArrayList<>();
ShapeSplitter.splitShape(e.getPoints(), dividingLine << Coord.DELTA_SHIFT, isLongitude, lessList, moreList, areasHashMap);
for (List<Coord> subShape : lessList) {
MapShape s = e.copy();
s.setPoints(subShape);
s.setClipped(true);
areas[0].addShape(s);
}
for (List<Coord> subShape : moreList) {
MapShape s = e.copy();
s.setPoints(subShape);
s.setClipped(true);
areas[1].addShape(s);
}
return;
}
}
for (int areaIndex = 0; areaIndex < areas.length; ++areaIndex) {
List<List<Coord>> subShapePoints = ShapeSplitter.clipToBounds(e.getPoints(), areas[areaIndex].getBounds(), areasHashMap);
for (List<Coord> subShape : subShapePoints) {
MapShape s = e.copy();
s.setPoints(subShape);
s.setClipped(true);
areas[areaIndex].addShape(s);
}
}
}
Aggregations