This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mkgmap.

commit 8bcef4e1565c1a1328f311f033b36d369aba7211
Author: Bas Couwenberg <[email protected]>
Date:   Mon Aug 1 10:26:23 2016 +0200

    Imported Upstream version 0.0.0+svn3686
---
 resources/mkgmap-version.properties                |   4 +-
 resources/styles/default/inc/landuse_polygons      |   1 +
 src/uk/me/parabola/imgfmt/app/BitWriter.java       |  23 +++
 .../parabola/imgfmt/app/trergn/LinePreparer.java   | 204 ++++++++++++---------
 src/uk/me/parabola/imgfmt/app/trergn/Polyline.java |   4 +-
 .../parabola/mkgmap/combiners/OverviewBuilder.java |  72 +++++++-
 .../mkgmap/filters/PolygonSplitterBase.java        |   2 +-
 .../filters/PolygonSubdivSizeSplitterFilter.java   |   4 +
 .../mkgmap/filters/RemoveObsoletePointsFilter.java |  24 ++-
 .../mkgmap/reader/osm/MultiPolygonRelation.java    |  12 +-
 test/uk/me/parabola/imgfmt/app/BitReaderTest.java  |  21 +++
 11 files changed, 260 insertions(+), 111 deletions(-)

diff --git a/resources/mkgmap-version.properties 
b/resources/mkgmap-version.properties
index 491d833..9f219a3 100644
--- a/resources/mkgmap-version.properties
+++ b/resources/mkgmap-version.properties
@@ -1,2 +1,2 @@
-svn.version: 3677
-build.timestamp: 2016-07-06T10:48:34+0100
+svn.version: 3686
+build.timestamp: 2016-07-29T09:57:12+0100
diff --git a/resources/styles/default/inc/landuse_polygons 
b/resources/styles/default/inc/landuse_polygons
index 7c6a7f4..c46085a 100644
--- a/resources/styles/default/inc/landuse_polygons
+++ b/resources/styles/default/inc/landuse_polygons
@@ -16,6 +16,7 @@ landuse=residential [0x10 resolution 23-19]
 landuse=retail [0x08 resolution 23-20]
 landuse=village_green [0x17 resolution 20]
 landuse=vineyard [0x4e resolution 20]
+landuse=orchard [0x4e resolution 20]
 
 military=airfield [0x04 resolution 20]
 military=barracks [0x04 resolution 23]
diff --git a/src/uk/me/parabola/imgfmt/app/BitWriter.java 
b/src/uk/me/parabola/imgfmt/app/BitWriter.java
index 2c813f5..db090e9 100644
--- a/src/uk/me/parabola/imgfmt/app/BitWriter.java
+++ b/src/uk/me/parabola/imgfmt/app/BitWriter.java
@@ -110,11 +110,34 @@ public class BitWriter {
 
                buflen = (bitoff+7)/8;
        }
+       
+       /**
+        * Write a signed value. If the value doesn't fit into nb bits, write 
one or more 1 << (nb-1)  
+        * as a flag for extended range.
+        */
 
+       public void sputn(int bval, int nb) {
+               int top = 1 << (nb - 1);
+               int mask = top - 1;
+               int val = Math.abs(bval);
+               while (val > mask) {
+                       putn(top, nb);
+                       val -= mask;
+               }
+               if (bval < 0) {
+                       putn((top - val) | top, nb);
+               } else {
+                       putn(val, nb);
+               }
+       }
+       
        public byte[] getBytes() {
                return buf;
        }
 
+       public int getBitPosition() {
+               return bitoff;
+       }
        /**
         * Get the number of bytes actually used to hold the bit stream. This 
therefore can be and usually
         * is less than the length of the buffer returned by {@link 
#getBytes()}.
diff --git a/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java 
b/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java
index bbdd51a..2efc4b4 100644
--- a/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java
@@ -69,25 +69,91 @@ public class LinePreparer {
 
        /**
         * Write the bit stream to a BitWriter and return it.
+        * Try different values for xBase and yBase to find the one
+        * that results in the shortest bit stream.
+        * 
+        * @return A class containing the written byte stream.
+        */
+       public BitWriter makeShortestBitStream(int minPointsRequired) {
+               BitWriter bsSimple = makeBitStream(minPointsRequired, xBase, 
yBase);
+               if (bsSimple == null)
+                       return bsSimple;
+               BitWriter bsBest = bsSimple; 
+               int xBestBase = xBase;
+               int yBestBase = yBase;
+               if (xBase > 0 ||  yBase > 0){
+                       if (log.isDebugEnabled())
+                               log.debug("start opt:", xBase, yBase, 
xSameSign, xSignNegative, ySameSign, ySignNegative);
+               }
+               if (xBase > 0){
+                       int notBetter = 0;
+                       boolean xSameSignBak = xSameSign;
+                       xSameSign = false;
+                       for (int xTestBase = xBase-1; xTestBase >= 0; 
xTestBase--){
+                               BitWriter bstest = 
makeBitStream(minPointsRequired, xTestBase, yBase);
+//                             System.out.println(xBase + " "  + xTestBase + " 
-> " + bsBest.getBitPosition() + " " + bstest.getBitPosition());
+                               if (bstest.getBitPosition() >= 
bsBest.getBitPosition() ){
+                                       if (++notBetter >= 2)
+                                               break; // give up
+                               } else {
+                                       xBestBase = xTestBase;
+                                       bsBest = bstest;
+                                       xSameSignBak = false;
+                               }
+                       }
+                       xSameSign = xSameSignBak;
+               }
+               if (yBase > 0){
+                       int notBetter = 0;
+                       boolean ySameSignBak = ySameSign;
+                       ySameSign = false;
+                       for (int yTestBase = yBase-1; yTestBase >= 0; 
yTestBase--){
+                               BitWriter bstest = 
makeBitStream(minPointsRequired, xBestBase, yTestBase);
+//                             System.out.println(yBase + " "  + yTestBase + " 
-> " + bsBest.getBitPosition() + " " + bstest.getBitPosition());
+                               if (bstest.getBitPosition() >= 
bsBest.getBitPosition()){
+                                       if (++notBetter >= 2)
+                                               break; // give up
+                               } else {
+                                       yBestBase = yTestBase;
+                                       bsBest = bstest;
+                                       ySameSignBak = false;
+                               }
+                       }
+                       ySameSign = ySameSignBak;
+               }
+               if (xBase != xBestBase || yBestBase != yBase){
+                       if (log.isInfoEnabled()){
+                               if (bsSimple.getLength() > bsBest.getLength())
+                                       log.info("optimizer reduced bit stream 
byte length from",bsSimple.getLength(),"->",bsBest.getLength(),"(" + 
(bsSimple.getLength()-bsBest.getLength()), " byte(s)) 
for",polyline.getClass().getSimpleName(),"with",polyline.getPoints().size(),"points");
+                               else 
+                                       log.info("optimizer only reduced bit 
stream bit length 
from",bsSimple.getBitPosition(),"->",bsBest.getBitPosition(),"bits 
for",polyline.getClass().getSimpleName(),"with",polyline.getPoints().size(),"points,
 using original bit stream");
+                       }
+               }
+               if (bsSimple.getLength() == bsBest.getLength()){
+                       // if the (byte) length was not improved, 
+                       // prefer the bit stream that doesn't need the special 
"trick"
+                       // to encode large values, it is assumed that this can 
safe a  
+                       // few CPU cycles when reading the map
+                       return bsSimple;
+               }
+               return bsBest;
+       }
+       /**
+        * Write the bit stream to a BitWriter and return it.
         *
         * @return A class containing the written byte stream.
         */
-       public BitWriter makeBitStream(int minPointsRequired) {
-
-               assert xBase >= 0 && yBase >= 0;
-
-               int xbits = 2;
-               if (xBase < 10)
-                       xbits += xBase;
-               else
-                       xbits += (2 * xBase) - 9;
-
-               int ybits = 2;
-               if (yBase < 10)
-                       ybits += yBase;
-               else
-                       ybits += (2 * yBase) - 9;
+       public BitWriter makeBitStream(int minPointsRequired, int xb, int yb) {
+               assert xb >= 0 && yb >= 0;
+               
+               int xbits = base2Bits(xb);
+               if (!xSameSign)
+                       xbits++;
+               int ybits = base2Bits(yb);
+               if (!ySameSign)
+                       ybits++;
 
+                       
                // Note no sign included.
                if (log.isDebugEnabled())
                        log.debug("xbits", xbits, ", y=", ybits);
@@ -96,8 +162,8 @@ public class LinePreparer {
                BitWriter bw = new BitWriter();
 
                // Pre bit stream info
-               bw.putn(xBase, 4);
-               bw.putn(yBase, 4);
+               bw.putn(xb, 4);
+               bw.putn(yb, 4);
 
                bw.put1(xSameSign);
                if (xSameSign)
@@ -133,28 +199,18 @@ public class LinePreparer {
 
                        if (log.isDebugEnabled())
                                log.debug("x delta", dx, "~", xbits);
-                       assert dx >> xbits == 0 || dx >> xbits == -1;
                        if (xSameSign) {
                                bw.putn(Math.abs(dx), xbits);
                        } else {
-                               // catch inadvertent output of "magic" value 
that has
-                               // sign bit set but other bits all 0
-                               assert dx >= 0 || (dx & ((1 << xbits) - 1)) != 
0;
-                               bw.putn(dx, xbits);
-                               bw.put1(dx < 0);
+                               bw.sputn(dx, xbits);
                        }
 
                        if (log.isDebugEnabled())
                                log.debug("y delta", dy, ybits);
-                       assert dy >> ybits == 0 || dy >> ybits == -1;
                        if (ySameSign) {
                                bw.putn(Math.abs(dy), ybits);
                        } else {
-                               // catch inadvertent output of "magic" value 
that has
-                               // sign bit set but other bits all 0
-                               assert dy >= 0 || (dy & ((1 << ybits) - 1)) != 
0;
-                               bw.putn(dy, ybits);
-                               bw.put1(dy < 0);
+                               bw.sputn(dy, ybits);
                        }
                        if (extraBit)
                                bw.put1(nodes[i/2+1]);
@@ -191,7 +247,6 @@ public class LinePreparer {
                Subdivision subdiv = polyline.getSubdiv();
                if(log.isDebugEnabled())
                        log.debug("label offset", 
polyline.getLabel().getOffset());
-               int shift = subdiv.getShift();
                List<Coord> points = polyline.getPoints();
 
                // Space to hold the deltas
@@ -209,10 +264,6 @@ public class LinePreparer {
                // OK go through the points
                int lastLat = 0;
                int lastLong = 0;
-               boolean xDiffSign = false; // The long values have different 
sign
-               boolean yDiffSign = false; // The lat values have different sign
-               int xSign = 0;  // If all the same sign, then this 1 or -1 
depending on +ve or -ve
-               int ySign = 0;  // As above for lat.
                int minDx = Integer.MAX_VALUE, maxDx = 0;
                int minDy = Integer.MAX_VALUE, maxDy = 0;
                // index of first point in a series of identical coords (after 
shift)
@@ -231,14 +282,8 @@ public class LinePreparer {
                                continue;
                        }
 
-                       // compute normalized differences
-                       //   -2^(shift-1) <= dx, dy < 2^(shift-1)
-                       // XXX: relies on the fact that java integers are 32 
bit signed
-                       final int offset = 8+shift;
-                       int dx = (lon - lastLong) << offset >> offset;
-                       int dy = (lat - lastLat) << offset >> offset;
-                       assert (dx == 0 && lon != lastLong) == false: ("delta 
lon too large: " +  (lon - lastLong));
-                       assert (dy == 0 && lat != lastLat) == false: ("delta 
lat too large: " +  (lat - lastLat));
+                       int dx = lon - lastLong;
+                       int dy = lat - lastLat;
                        lastLong = lon;
                        lastLat = lat;
                        boolean isSpecialNode = false;
@@ -280,26 +325,6 @@ public class LinePreparer {
                                nodes[firstsame] = nodes[firstsame] || extra;
                        }
 
-                       // See if they can all be the same sign.
-                       if (!xDiffSign) {
-                               int thisSign = (dx >= 0)? 1: -1;
-                               if (xSign == 0) {
-                                       xSign = thisSign;
-                               } else if (thisSign != xSign) {
-                                       // The signs are different
-                                       xDiffSign = true;
-                               }
-                       }
-                       if (!yDiffSign) {
-                               int thisSign = (dy >= 0)? 1: -1;
-                               if (ySign == 0) {
-                                       ySign = thisSign;
-                               } else if (thisSign != ySign) {
-                                       // The signs are different
-                                       yDiffSign = true;
-                               }
-                       }
-
                        // find largest delta values
                        if (dx < minDx)
                                minDx = dx;
@@ -323,43 +348,25 @@ public class LinePreparer {
                // adjustments to get the final value.  We need to try and work
                // backwards from this.
                //
-               // I don't care about getting the smallest possible file size so
-               // err on the side of caution.
-               //
                // Note that the sign bit is already not included so there is
                // no adjustment needed for it.
 
                if (log.isDebugEnabled())
                        log.debug("initial xBits, yBits", xBits, yBits);
 
-               if (xBits < 2)
-                       xBits = 2;
-               int tmp = xBits - 2;
-               if (tmp > 10) {
-                       if ((tmp & 0x1) == 0)
-                               tmp++;
-                       tmp = 9 + (tmp - 9) / 2;
-               }
-               this.xBase = tmp;
-
-               if (yBits < 2)
-                       yBits = 2;
-               tmp = yBits - 2;
-               if (tmp > 10) {
-                       if ((tmp & 0x1) == 0)
-                               tmp++;
-                       tmp = 9 + (tmp - 9) / 2;
-               }
-               this.yBase = tmp;
+               this.xBase = bits2Base(xBits);
+               this.yBase = bits2Base(yBits);
 
                if (log.isDebugEnabled())
                        log.debug("initial xBase, yBase", xBase, yBase);
 
                // Set flags for same sign etc.
-               this.xSameSign = !xDiffSign;
-               this.ySameSign = !yDiffSign;
-               this.xSignNegative = xSign < 0;
-               this.ySignNegative = ySign < 0;
+               this.xSameSign = !(minDx < 0 && maxDx > 0);
+               this.ySameSign = !(minDy < 0 && maxDy > 0);
+               if (this.xSameSign)
+                       this.xSignNegative = minDx < 0;
+               if (this.ySameSign)
+                       this.ySignNegative = minDy < 0;
        }
 
        /**
@@ -371,16 +378,35 @@ public class LinePreparer {
        public static int bitsNeeded(int val) {
                int n = Math.abs(val);
 
-               int count = val < 0? 1: 0;
+               int count = 0;
                while (n != 0) {
                        n >>>= 1;
                        count++;
                }
                return count;
+//             count should be equal to Integer.SIZE - 
Integer.numberOfLeadingZeros(Math.abs(val));
+
        }
 
        public boolean isExtraBit() {
                return extraBit;
        }
 
+       private static int base2Bits(int base){
+               int bits = 2;
+               if (base < 10)
+                       return bits + base;
+               else
+                       return bits + (2 * base) - 9;
+       }
+       
+       private static int bits2Base(int bits){
+               int base = Math.max(0, bits - 2);
+               if (base > 10) {
+                       if ((base & 0x1) == 0)
+                               base++;
+                       base = 9 + (base - 9) / 2;
+               }
+               return base;
+       }
 }
diff --git a/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java 
b/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java
index e8f9ce4..6e4550d 100644
--- a/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java
+++ b/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java
@@ -91,7 +91,7 @@ public class Polyline extends MapObject {
                }
 
                int minPointsRequired = (this instanceof Polygon)? 3 : 2;
-               BitWriter bw = w.makeBitStream(minPointsRequired);
+               BitWriter bw = w.makeShortestBitStream(minPointsRequired);
                if(bw == null) {
                        log.error("Level " + getSubdiv().getZoom().getLevel() + 
" " + ((this instanceof Polygon)? "polygon" : "polyline") + " has less than " + 
minPointsRequired + " points, discarding");
                        return;
@@ -171,7 +171,7 @@ public class Polyline extends MapObject {
                        return;
                }
                int minPointsRequired = (this instanceof Polygon)? 3 : 2;
-               BitWriter bw = w.makeBitStream(minPointsRequired);
+               BitWriter bw = w.makeShortestBitStream(minPointsRequired);
                if(bw == null) {
                        log.error("Level " + getSubdiv().getZoom().getLevel() + 
" " + ((this instanceof Polygon)? "polygon" : "polyline") + " has less than " + 
minPointsRequired + " points, discarding");
                        return;
diff --git a/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java 
b/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java
index 9f6fa08..5fa08ab 100644
--- a/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java
+++ b/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java
@@ -55,12 +55,12 @@ public class OverviewBuilder implements Combiner {
        private String areaName;
        private String overviewMapname;
        private String overviewMapnumber;
-       private Zoom[] levels;
        private String outputDir;               
        private Integer codepage;
        private Integer encodingType;
        private List<String[]> copyrightMsgs = new ArrayList<String[]>();
        private List<String[]> licenseInfos = new ArrayList<String[]>();
+       private LevelInfo[] wantedLevels;
 
 
        public OverviewBuilder(OverviewMap overviewSource) {
@@ -87,9 +87,57 @@ public class OverviewBuilder implements Combiner {
 
        public void onFinish() {
                addBackground();
+               calcLevels();
                writeOverviewMap();
        }
        
+       private void calcLevels() {
+               List<MapShape> shapes = overviewSource.getShapes();
+               int maxRes = 16; // we can write a 0x4a polygon for planet in 
res 16
+               if (wantedLevels != null)
+                       maxRes = wantedLevels[wantedLevels.length-1].getBits();
+               int maxSize = 0xffff << (24 - maxRes); 
+               for (MapShape s : shapes){
+                       if (s.getType() != 0x4a)
+                               continue;
+                       int maxDimPoly = s.getBounds().getMaxDimension();
+                       if (maxDimPoly > maxSize){
+                               int oldMaxRes = maxRes; 
+                               while (maxDimPoly > maxSize){
+                                       maxRes--;
+                                       maxSize = 0xffff << (24 - maxRes);
+                               }
+                               String[] name = s.getName().split("\u001d");
+                               String msg = "Tile selection (0x4a) polygon for 
"; 
+                               if (name != null && name.length == 2)
+                                       msg += "tile " + name[1].trim();
+                               else 
+                                       msg += s.getBounds(); 
+                               log.error(msg,"cannot be written in level 0 
resolution",oldMaxRes + ", using",maxRes,"instead");
+                               
+                       }
+               }
+               if (wantedLevels == null)
+                       setRes(maxRes);
+               else {
+                       // make sure that the wanted levels for the overview map
+                       // can store the largest 0x4a polygon at level 0
+                       int n = wantedLevels.length-1;
+                       while (n > 0 && wantedLevels[n].getBits() > maxRes)
+                               n--;
+                       if (n > 0){
+                               int l = 0;
+                               while (n >= 0){
+                                       wantedLevels[n] = new LevelInfo(l++, 
wantedLevels[n].getBits());
+                                       n--;
+                               }
+                               wantedLevels = Arrays.copyOfRange(wantedLevels, 
0, l);
+                               overviewSource.setMapLevels(wantedLevels);
+                       } else
+                               setRes(maxRes); 
+               }
+       }
+
        /**
         * Add background polygon that covers the whole area of the overview 
map. 
         */
@@ -187,8 +235,8 @@ public class OverviewBuilder implements Combiner {
                                licenseInfos.add(msgs);
                        
                        
-                       levels = mapReader.getLevels();
-                       if (overviewSource.mapLevels() == null){
+                       Zoom[] levels = mapReader.getLevels();
+                       if (wantedLevels == null){
                                LevelInfo[] mapLevels;
                                if (isOverviewImg(filename)){
                                        mapLevels = new 
LevelInfo[levels.length-1]; 
@@ -199,7 +247,7 @@ public class OverviewBuilder implements Combiner {
                                        mapLevels = new LevelInfo[1];
                                        mapLevels[0] = new 
LevelInfo(levels[1].getLevel(), levels[1].getResolution());
                                }
-                               overviewSource.setMapLevels(mapLevels);
+                               wantedLevels = mapLevels;
                        }
                        if (isOverviewImg(filename)){
                                readPoints(mapReader);
@@ -221,6 +269,7 @@ public class OverviewBuilder implements Combiner {
         */
        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();
@@ -251,6 +300,7 @@ public class OverviewBuilder implements Combiner {
         * @param mapReader Map reader on the detailed .img file.
         */
        private void readLines(MapReader mapReader) {
+               Zoom[] levels = mapReader.getLevels();
                for (int l = 1; l < levels.length; l++){
                        int min = levels[l].getLevel();
                        int res = levels[l].getResolution();
@@ -286,6 +336,7 @@ public class OverviewBuilder implements Combiner {
         * @param mapReader Map reader on the detailed .img file.
         */
        private void readShapes(MapReader mapReader) {
+               Zoom[] levels = mapReader.getLevels();
                for (int l = 1; l < levels.length; l++){
                        int min = levels[l].getLevel();
                        int res = levels[l].getResolution();
@@ -332,7 +383,7 @@ public class OverviewBuilder implements Combiner {
                for (Coord co: points){
                        overviewSource.addToBounds(co);
                }
-               // Create the background rectangle
+               // Create the tile coverage rectangle
                MapShape bg = new MapShape();
                bg.setType(0x4a);
                bg.setPoints(points);
@@ -385,4 +436,15 @@ public class OverviewBuilder implements Combiner {
                }
                return list;
        }
+
+       /**
+        * Set the highest resolution
+        * @param resolution
+        */
+       private void setRes(int resolution) {
+               LevelInfo[] mapLevels = new LevelInfo[1];
+               mapLevels[0] = new LevelInfo(0, resolution);
+               overviewSource.setMapLevels(mapLevels); 
+       }
+
 }
diff --git a/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java 
b/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java
index 4a19c52..b908c85 100644
--- a/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java
+++ b/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java
@@ -28,7 +28,7 @@ import uk.me.parabola.util.Java2DConverter;
  * @author Steve Ratcliffe
  */
 public class PolygonSplitterBase extends BaseFilter {
-       protected static final int MAX_SIZE = 0x7fff;
+       protected static final int MAX_SIZE = 0xffff; // larger value causes 
problem in delta encoding of lines
        private int shift;
        
        public void init(FilterConfig config) {
diff --git 
a/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java 
b/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java
index 961278d..760adb5 100644
--- a/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java
+++ b/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java
@@ -89,6 +89,10 @@ public class PolygonSubdivSizeSplitterFilter extends 
PolygonSplitterBase impleme
        }
 
        private boolean isSizeOk(MapShape shape) {
+               // do not cut the background shape
+               if (shape.getType() == 0x4a)
+                       return true;
+               
                // Estimate the size taken by lines and shapes as a constant 
plus
                // a factor based on the number of points.
                int numPoints = shape.getPoints().size();
diff --git a/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java 
b/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java
index ba2d583..3c2224d 100644
--- a/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java
+++ b/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java
@@ -105,13 +105,25 @@ public class RemoveObsoletePointsFilter implements 
MapFilter {
                        points = newPoints;
                        newPoints = new ArrayList<Coord>(points.size());
                }
-               if (line instanceof MapShape && newPoints.size() > 3){
-                       // check special case: shape starts with spike
-                       if (Utils.isStraight(newPoints.get(0), 
newPoints.get(1), newPoints.get(newPoints.size()-2)) == 
Utils.STRICTLY_STRAIGHT){
-                               newPoints.remove(0);
-                               newPoints.set(newPoints.size()-1, 
newPoints.get(0));
-                               if 
(newPoints.get(newPoints.size()-2).equals(newPoints.get(newPoints.size()-1)))
+               if (line instanceof MapShape){
+                       // Check special cases caused by the fact that the 
first and last point 
+                       // in a shape are identical. 
+                       while (newPoints.size() > 3){
+                               int nPoints = newPoints.size();
+                               
switch(Utils.isStraight(newPoints.get(newPoints.size()-2), newPoints.get(0), 
newPoints.get(1))){
+                               case Utils.STRAIGHT_SPIKE:
+                                       newPoints.remove(0);
+                                       newPoints.set(newPoints.size()-1, 
newPoints.get(0));
+                                       if 
(newPoints.get(newPoints.size()-2).equals(newPoints.get(newPoints.size()-1)))
+                                               
newPoints.remove(newPoints.size()-1);
+                                       break;
+                               case Utils.STRICTLY_STRAIGHT:
                                        newPoints.remove(newPoints.size()-1);
+                                       newPoints.set(0, 
newPoints.get(newPoints.size()-1));
+                                       break;
+                               }
+                               if (nPoints == newPoints.size())
+                                       break;
                        }
                }
                
diff --git a/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java 
b/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
index 62202dd..4d357b9 100644
--- a/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
+++ b/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java
@@ -2071,11 +2071,11 @@ public class MultiPolygonRelation extends Relation {
         */
        private boolean linesCutEachOther(Coord p1_1, Coord p1_2, Coord p2_1,
                        Coord p2_2) {
-               int width1 = p1_2.getLongitude() - p1_1.getLongitude();
-               int width2 = p2_2.getLongitude() - p2_1.getLongitude();
+               int width1 = p1_2.getHighPrecLon() - p1_1.getHighPrecLon();
+               int width2 = p2_2.getHighPrecLon() - p2_1.getHighPrecLon();
 
-               int height1 = p1_2.getLatitude() - p1_1.getLatitude();
-               int height2 = p2_2.getLatitude() - p2_1.getLatitude();
+               int height1 = p1_2.getHighPrecLat() - p1_1.getHighPrecLat();
+               int height2 = p2_2.getHighPrecLat() - p2_1.getHighPrecLat();
 
                int denominator = ((height2 * width1) - (width2 * height1));
                if (denominator == 0) {
@@ -2084,8 +2084,8 @@ public class MultiPolygonRelation extends Relation {
                        return false;
                }
                
-               int x1Mx3 = p1_1.getLongitude() - p2_1.getLongitude();
-               int y1My3 = p1_1.getLatitude() - p2_1.getLatitude();
+               int x1Mx3 = p1_1.getHighPrecLon() - p2_1.getHighPrecLon();
+               int y1My3 = p1_1.getHighPrecLat() - p2_1.getHighPrecLat();
 
                double isx = (double)((width2 * y1My3) - (height2 * x1Mx3))
                                / denominator;
diff --git a/test/uk/me/parabola/imgfmt/app/BitReaderTest.java 
b/test/uk/me/parabola/imgfmt/app/BitReaderTest.java
index 6ab84c1..f50dc1b 100644
--- a/test/uk/me/parabola/imgfmt/app/BitReaderTest.java
+++ b/test/uk/me/parabola/imgfmt/app/BitReaderTest.java
@@ -46,6 +46,13 @@ public class BitReaderTest {
                int s = br.sget2(3);
                assertEquals(-12, s);
        }
+       @Test
+       public void testSpecialNegative2() {
+               BitReader br = new BitReader(new byte[]{0x2c, 0x0});
+
+               int s = br.sget2(3);
+               assertEquals(-6, s);
+       }
 
        @Test
        public void testSpecialPositive() {
@@ -54,4 +61,18 @@ public class BitReaderTest {
                int s = br.sget2(3);
                assertEquals(8, s);
        }
+       
+       @Test
+       public void testWriteRead() {
+               for (int i = -20; i <= 20; i++){
+                       BitWriter bw = new BitWriter();
+                       bw.sputn(i,3);
+                       BitReader br = new BitReader(bw.getBytes());
+
+                       int s = br.sget2(3);
+                       assertEquals(i, s);
+               }
+       }
+       
+       
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-grass/mkgmap.git

_______________________________________________
Pkg-grass-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

Reply via email to