use of uk.me.parabola.imgfmt.app.Area 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);
}
}
}
use of uk.me.parabola.imgfmt.app.Area in project mkgmap by openstreetmap.
the class MapBuilder method makeMap.
/**
* Main method to create the map, just calls out to several routines
* that do the work.
*
* @param map The map.
* @param src The map data.
*/
public void makeMap(Map map, LoadableMapDataSource src) {
RGNFile rgnFile = map.getRgnFile();
TREFile treFile = map.getTreFile();
lblFile = map.getLblFile();
NETFile netFile = map.getNetFile();
DEMFile demFile = map.getDemFile();
if (routeCenterBoundaryType != 0 && netFile != null && src instanceof MapperBasedMapDataSource) {
for (RouteCenter rc : src.getRoadNetwork().getCenters()) {
((MapperBasedMapDataSource) src).addBoundaryLine(rc.getArea(), routeCenterBoundaryType, rc.reportSizes());
}
}
if (mapInfo.isEmpty())
getMapInfo();
normalizeCountries(src);
processCities(map, src);
processRoads(map, src);
processPOIs(map, src);
processOverviews(map, src);
processInfo(map, src);
makeMapAreas(map, src);
if (driveOnLeft == null) {
// check if source gives info about driving side
if (src instanceof MapperBasedMapDataSource) {
driveOnLeft = ((MapperBasedMapDataSource) src).getDriveOnLeft();
}
}
if (driveOnLeft == null)
driveOnLeft = false;
treFile.setDriveOnLeft(driveOnLeft);
treFile.setLastRgnPos(rgnFile.position() - RGNHeader.HEADER_LEN);
rgnFile.write();
treFile.write(rgnFile.haveExtendedTypes());
lblFile.write();
lblFile.writePost();
if (netFile != null) {
RoadNetwork network = src.getRoadNetwork();
netFile.setNetwork(network.getRoadDefs());
NODFile nodFile = map.getNodFile();
if (nodFile != null) {
nodFile.setNetwork(network.getCenters(), network.getRoadDefs(), network.getBoundary());
nodFile.setDriveOnLeft(driveOnLeft);
nodFile.write();
}
netFile.write(lblFile.numCities(), lblFile.numZips());
if (nodFile != null) {
nodFile.writePost();
}
netFile.writePost(rgnFile.getWriter());
}
warnAbout3ByteImgRefs();
if (demFile != null) {
try {
long t1 = System.currentTimeMillis();
java.awt.geom.Area demArea = null;
if (demPolygon != null) {
Area bbox = src.getBounds();
// the rectangle is a bit larger to avoid problems at tile boundaries
Rectangle2D r = new Rectangle2D.Double(bbox.getMinLong() - 2, bbox.getMinLat() - 2, bbox.getWidth() + 4, bbox.getHeight() + 4);
if (demPolygon.intersects(r) && !demPolygon.contains(r)) {
demArea = demPolygon;
}
}
if (demArea == null && src instanceof OverviewMapDataSource) {
Path2D demPoly = ((OverviewMapDataSource) src).getTileAreaPath();
if (demPoly != null) {
demArea = new java.awt.geom.Area(demPoly);
}
}
Area treArea = demFile.calc(src.getBounds(), demArea, pathToHGT, demDists, demOutsidePolygonHeight, demInterpolationMethod);
map.setBounds(treArea);
long t2 = System.currentTimeMillis();
log.info("DEM file calculation for", map.getFilename(), "took", (t2 - t1), "ms");
demFile.write();
} catch (MapFailedException e) {
log.error("exception while creating DEM file", e.getMessage());
// TODO: better remove DEM file?
throw new MapFailedException("DEM");
}
}
treFile.writePost();
}
use of uk.me.parabola.imgfmt.app.Area in project mkgmap by openstreetmap.
the class OverviewBuilder method readPoints.
/**
* Read the points from the .img file and add them to the overview map.
* We read from the least detailed level (apart from the empty one).
*
* @param mapReader Map reader on the detailed .img file.
*/
private void readPoints(MapReader mapReader) {
Area bounds = overviewSource.getBounds();
Zoom[] levels = mapReader.getLevels();
for (int l = 1; l < levels.length; l++) {
int min = levels[l].getLevel();
int res = levels[l].getResolution();
List<Point> pointList = mapReader.pointsForLevel(min, MapReader.WITH_EXT_TYPE_DATA);
for (Point point : pointList) {
if (log.isDebugEnabled())
log.debug("got point", point);
if (bounds.contains(point.getLocation()) == false) {
if (log.isDebugEnabled())
log.debug(point, "dropped, is outside of tile boundary");
continue;
}
MapPoint mp = new MapPoint();
mp.setType(point.getType());
if (point.getLabel() != null) {
mp.setName(point.getLabel().getText());
}
mp.setMaxResolution(res);
mp.setMinResolution(res);
mp.setLocation(point.getLocation());
overviewSource.addPoint(mp);
}
}
}
use of uk.me.parabola.imgfmt.app.Area 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.Area in project mkgmap by openstreetmap.
the class HGTConverterTest method testLat0Top.
@Test
public void testLat0Top() throws Exception {
// top is exactly at 0, caused ArrayIndexOutOfBoundsException with r4065
Area bbox = new Area(-1.04296875, -90.9, 0.0, -90.0);
HGTConverter hgtConverter = new HGTConverter(HGT_PATH, bbox, null, DEMFile.EXTRA);
// test data contains sone islands with volcanos, bbox corners are all in the ocean
assertEquals(0, hgtConverter.getElevation(bbox.getMaxLat() * 256, bbox.getMinLong() * 256));
assertEquals(0, hgtConverter.getElevation(bbox.getMaxLat() * 256, bbox.getMaxLong() * 256));
assertEquals(0, hgtConverter.getElevation(bbox.getMinLat() * 256, bbox.getMinLong() * 256));
assertEquals(0, hgtConverter.getElevation(bbox.getMinLat() * 256, bbox.getMaxLong() * 256));
// retrieve value at offset 646834 (0x9DEB2) in S01W091.hgt
double hgtDis = 1.0D / 1200;
int lat32 = (int) ((Math.round(-0.22395 / hgtDis) * hgtDis) * (1 << 29) / 45);
int lon32 = (int) ((Math.round(-90.71 / hgtDis) * hgtDis) * (1 << 29) / 45);
assertEquals(308, hgtConverter.getElevation(lat32, lon32));
}
Aggregations