Hi Gerd,
I have prepared patch according to these guessed rules. It rounds
dem-dist and shift coordinates of top-left corner of DEM areas. Since
dem-dist doesn't correspond exactly to HGT, interpolation is always active.
I think there could be 2 ways to improve DEM quality. Interpolation
could be changed to bicubic or mkgmap could use preprocessed data with
correct pixel size. In the latter case probably data format other than
HGT should be used.
--
Best regards,
Andrzej
Index: src/uk/me/parabola/imgfmt/app/dem/DEMFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/dem/DEMFile.java (revision 4070)
+++ src/uk/me/parabola/imgfmt/app/dem/DEMFile.java (working copy)
@@ -52,20 +52,57 @@
* @param outsidePolygonHeight the height value that should be used for
points outside of the bounding polygon
*/
public void calc(Area area, java.awt.geom.Area demPolygonMapUnits,
String pathToHGT, List<Integer> pointDistances, short outsidePolygonHeight) {
- HGTConverter hgtConverter = new HGTConverter(pathToHGT, area,
demPolygonMapUnits);
+ // HGT area is extended by 0.01 degree in each direction
+ HGTConverter hgtConverter = new HGTConverter(pathToHGT, area,
demPolygonMapUnits, 0.01D);
hgtConverter.setOutsidePolygonHeight(outsidePolygonHeight);
+ int top = area.getMaxLat() * 256;
+ int bottom = area.getMinLat() * 256;
+ int left = area.getMinLong() * 256;
+ int right = area.getMaxLong() * 256;
+
int zoom = 0;
int lastDist = pointDistances.get(pointDistances.size()-1);
for (int pointDist : pointDistances) {
- DEMSection section = new DEMSection(zoom++, area,
hgtConverter, pointDist, pointDist == lastDist);
+ int distance = pointDist;
+ if (distance == -1) {
+ int res = (hgtConverter.getHighestRes() > 0) ?
hgtConverter.getHighestRes() : 1200;
+ distance = (int) ((1 << 29) / (res * 45));
+ }
+ // last 4 bits of distance should be 0
+ distance = ((distance + 8)/16)*16;
+
+ int xtop = top;
+ int xleft = left;
+
+ // align DEM to distance raster, if distance not bigger
than widening of HGT area
+ if (distance < (int)Math.floor((0.01D/45.0D * (1 <<
29)))) {
+ if (xtop >= 0) {
+ xtop -= xtop % distance;
+ if (xtop < 0x3FFFFFFF - distance)
+ xtop += distance;
+ }
+ else {
+ xtop -= xtop % distance;
+ }
+
+ if (xleft >= 0) {
+ xleft -= xleft % distance;
+ }
+ else {
+ xleft -= xleft % distance;
+ if (xleft > Integer.MIN_VALUE +
distance)
+ xleft -= distance;
+ }
+ }
+
+ // to improve: DEM secition should get area in 32bit
units
+ DEMSection section = new DEMSection(zoom++, xtop,
xleft, xtop - bottom, right - xleft, hgtConverter, distance, pointDist ==
lastDist);
demHeader.addSection(section);
}
return;
}
-
-
public void write() {
ImgFileWriter w = getWriter();
if (w instanceof BufferedImgFileWriter) {
Index: src/uk/me/parabola/imgfmt/app/dem/DEMSection.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/dem/DEMSection.java (revision 4070)
+++ src/uk/me/parabola/imgfmt/app/dem/DEMSection.java (working copy)
@@ -48,16 +48,12 @@
private int maxHeight = Integer.MIN_VALUE;
private List<DEMTile> tiles = new ArrayList<>();
- public DEMSection(int zoomLevel, Area bbox, HGTConverter hgtConverter,
int pointDist, boolean lastLevel) {
+ public DEMSection(int zoomLevel, int areaTop, int areaLeft, int
areaHeight, int areaWidth, HGTConverter hgtConverter, int pointDist, boolean
lastLevel) {
this.zoomLevel = zoomLevel;
this.lastLevel = lastLevel;
- if (pointDist == -1) {
- int res = (hgtConverter.getHighestRes() > 0) ?
hgtConverter.getHighestRes() : 1200;
- pointDist = (int) ((1 << 29) / (res * 45));
- }
- this.top = bbox.getMaxLat() * 256;
- this.left = bbox.getMinLong() * 256;
+ this.top = areaTop;
+ this.left = areaLeft;
// calculate raster that starts at top left corner
// last row and right column have non-standard height / row
values
@@ -64,8 +60,8 @@
pointsDistanceLat = pointDist;
pointsDistanceLon = pointDist;
- int []latInfo = getTileInfo(bbox.getHeight() * 256,
pointsDistanceLat);
- int []lonInfo = getTileInfo(bbox.getWidth() * 256,
pointsDistanceLon);
+ int []latInfo = getTileInfo(areaHeight, pointsDistanceLat);
+ int []lonInfo = getTileInfo(areaWidth, pointsDistanceLon);
// store the values written to the header
tilesLat = latInfo[0];
tilesLon = lonInfo[0];
Index: src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java (revision 4070)
+++ src/uk/me/parabola/mkgmap/reader/hgt/HGTConverter.java (working copy)
@@ -46,14 +46,18 @@
* @param demPolygonMapUnits optional bounding polygon which describes
the area for
* which elevation should be read from hgt files.
*/
- public HGTConverter(String path, Area bbox, java.awt.geom.Area
demPolygonMapUnits) {
- int minLat = (int)
Math.floor(Utils.toDegrees(bbox.getMinLat()));
- int minLon = (int)
Math.floor(Utils.toDegrees(bbox.getMinLong()));
- // the bbox is slightly enlarged so that we dont fail when
rounding has no effect
- // e.g. if getMaxLat() returns 0
- int maxLat = (int) Math.ceil(Utils.toDegrees(bbox.getMaxLat() +
1));
- int maxLon = (int) Math.ceil(Utils.toDegrees(bbox.getMaxLong()
+ 1));
+ public HGTConverter(String path, Area bbox, java.awt.geom.Area
demPolygonMapUnits, double extra) {
+ // make bigger box for interpolation or aligning of areas
+ int minLat = (int) Math.floor(Utils.toDegrees(bbox.getMinLat())
- extra);
+ int minLon = (int)
Math.floor(Utils.toDegrees(bbox.getMinLong()) - extra);
+ int maxLat = (int) Math.ceil(Utils.toDegrees(bbox.getMaxLat())
+ extra);
+ int maxLon = (int) Math.ceil(Utils.toDegrees(bbox.getMaxLong())
+ extra);
+ if (minLat < -90) minLat = -90;
+ if (maxLat > 90) maxLat = 90;
+ if (minLon < -180) minLon = -180;
+ if (maxLon > 180) maxLon = 180;
+
minLat32 = Utils.toMapUnit(minLat) * 256;
minLon32 = Utils.toMapUnit(minLon) * 256;
// create matrix of readers
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev