Skip to content
Commits on Source (4)
mkgmap (0.0.0+svn4183-2) UNRELEASED; urgency=medium
mkgmap (0.0.0+svn4193-1) unstable; urgency=medium
* New upstream SVN snapshot.
* Strip trailing whitespace from control & rules files.
-- Bas Couwenberg <sebastic@debian.org> Mon, 07 May 2018 21:16:14 +0200
-- Bas Couwenberg <sebastic@debian.org> Fri, 01 Jun 2018 17:42:46 +0200
mkgmap (0.0.0+svn4183-1) unstable; urgency=medium
......
svn.version: 4183
build.timestamp: 2018-04-28T08:17:17+0100
svn.version: 4193
build.timestamp: 2018-05-31T07:29:23+0100
......@@ -28,6 +28,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.zip.GZIPInputStream;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
import uk.me.parabola.imgfmt.app.Coord;
/**
* Some miscellaneous functions that are used within the .img code.
......@@ -443,4 +444,12 @@ public class Utils {
return 4;
}
public static void put3sLongitude(ImgFileWriter writer, int longitude) {
// handle special case, write -180/-8388608 instead of 180/8388608 to avoid assertion
if (longitude == Utils.MAX_LON_MAP_UNITS)
writer.put3s(Utils.MIN_LON_MAP_UNITS);
else
writer.put3s(longitude);
}
}
......@@ -411,39 +411,49 @@ public class DEMTile {
}
}
/**
*
* @param oldsum
* @param elemcount
* @param newdata
* @return
*/
private static int evalSumSpec(int oldsum, int elemcount, int newdata) {
/*
D < -2 – (ls + 3*k)/2 -1 – ls – k
D < 0 – (ls + k)/2 2*(d + k) + 3
D < 2 – (ls – k)/2 2*d – 1
D < 4 – (ls – 3*k)/2 2*(d – k) - 5
1 – ls + k
*/
int v = 0;
private static int evaluateData(int oldsum, int elemcount, int newdata, int region) {
switch (region) {
case 0:
return -1 - oldsum - elemcount;
case 1:
return 2 * (newdata + elemcount) + 3;
case 2:
return 2 * newdata - 1;
case 3:
return 2 * (newdata - elemcount) - 5;
default:
return 1 - oldsum + elemcount;
}
}
private static int getEvaluateDataRegion(int oldsum, int elemcount, int newdata) {
if (elemcount < 63) {
if (newdata < -2 - ((oldsum + 3 * elemcount) >> 1)) {
v = -1 - oldsum - elemcount;
return 0;
} else if (newdata < -((oldsum + elemcount) >> 1)) {
v = 2 * (newdata + elemcount) + 3;
return 1;
} else if (newdata < 2 - ((oldsum - elemcount) >> 1)) {
v = 2 * newdata - 1;
return 2;
} else if (newdata < 4 - ((oldsum - 3 * elemcount) >> 1)) {
v = 2 * (newdata - elemcount) - 5;
return 3;
} else {
v = 1 - oldsum + elemcount;
return 4;
}
} else {
if (newdata < -2 - ((oldsum + 3 * elemcount) >> 1)) {
return 0;
} else if (newdata < -((oldsum + elemcount) >> 1) - 1) {
// special case in if !
return 1;
} else if (newdata < 2 - ((oldsum - elemcount) >> 1)) {
return 2;
} else if (newdata < 4 - ((oldsum - 3 * elemcount) >> 1)) {
return 3;
} else {
return 4;
}
}
// System.out.println(oldsum + " " + elemcount + " " + newdata + " -> " + v);
return v;
}
/**
* This class keeps statistics about the previously encoded values and tries to predict the next value.
......@@ -584,36 +594,43 @@ public class DEMTile {
private void processVal(int delta1) {
if (type == CalcType.CALC_STD) {
// calculate threshold sum hybrid
sumH += delta1 > 0 ? delta1 : -delta1;
if (sumH + unitDelta + 1 >= 0xffff)
sumH -= 0x10000;
// calculate threshold sum for length encoding
int evalRegion = -1;
int workData = delta1;
if (elemCount == 63) {
// special case
if (sumL > 0) { // pos. SumL
if ((sumL + 1) % 4 == 0) {
if (workData % 2 != 0)
workData--;
} else {
if (workData % 2 == 0)
workData--;
evalRegion = getEvaluateDataRegion(sumL, elemCount, delta1);
boolean datagerade = delta1 % 2 == 0;
boolean sumL1 = (sumL - 1) % 4 == 0;
switch (evalRegion) {
case 0:
case 2:
case 4:
if ((sumL1 && !datagerade) || (!sumL1 && datagerade)) {
workData++;
}
} else { // neg. SumL
if ((sumL - 1) % 4 == 0) {
if (workData % 2 != 0)
break;
case 1:
workData++;
} else {
if (workData % 2 == 0)
if ((sumL1 && !datagerade) || (!sumL1 && datagerade)) {
workData++;
}
break;
case 3:
if ((sumL1 && datagerade) || (!sumL1 && !datagerade)) {
workData--;
}
break;
}
}
int eval = evalSumSpec(sumL, elemCount, workData);
if (evalRegion < 0)
evalRegion = getEvaluateDataRegion(sumL, elemCount, workData);
int eval = evaluateData(sumL, elemCount, workData, evalRegion);
sumL += eval;
// now update elem counter
......@@ -624,9 +641,6 @@ public class DEMTile {
sumH = ((sumH - unitDelta) >> 1) - 1;
sumL /= 2;
if (sumL % 2 != 0) {
sumL++;
}
}
// calculate new hunit
......
......@@ -72,7 +72,7 @@ public class Mdr20 extends Mdr2x {
boolean citySameByName = lastCity != null && city.getMdr20SortPos() == lastCity.getMdr20SortPos();
int rr = street.checkRepeat(lastStreet, collator);
// Only save a single copy of each street name.
if (!citySameByName || rr != 3) {
if (!citySameByName || rr != 3 || lastStreet.getIndex() != street.getIndex()) {
record++;
streets.add(street);
}
......
......@@ -16,6 +16,7 @@ package uk.me.parabola.imgfmt.app.net;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.Area;
import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
......@@ -134,7 +135,7 @@ public class RouteCenter {
// Write the tables header
writer.put1u(tabC.getFormat());
writer.put3s(centralPoint.getLongitude());
Utils.put3sLongitude(writer, centralPoint.getLongitude());
writer.put3s(centralPoint.getLatitude());
writer.put1u(tabA.getNumberOfItems());
writer.put1u(tabB.getNumberOfItems());
......
......@@ -20,6 +20,8 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.Coord;
import uk.me.parabola.imgfmt.app.CoordNode;
import uk.me.parabola.imgfmt.app.ImgFileWriter;
......@@ -253,7 +255,7 @@ public class RouteNode implements Comparable<RouteNode> {
public void writeNod3OrNod4(ImgFileWriter writer) {
assert isBoundary() : "trying to write nod3 for non-boundary node";
writer.put3s(coord.getLongitude());
Utils.put3sLongitude(writer, coord.getLongitude());
writer.put3s(coord.getLatitude());
writer.put3u(offsetNod1);
}
......
......@@ -152,7 +152,7 @@ public class RGNFileReader extends ImgReader {
Point p = new Point(sd);
int type = reader.get1u() << 8;
byte b = reader.get();
int b = reader.get1u();
type |= 0x10000 + (b & 0x1f);
p.setType(type);
p.setDeltaLong(reader.get2s());
......@@ -262,7 +262,7 @@ public class RGNFileReader extends ImgReader {
* @param line The line or shape that is to be populated.
*/
private void readLineCommon(ImgFileReader reader, Subdivision div, Polyline line) {
byte type = reader.get();
int type = reader.get1u();
if (line instanceof Polygon)
line.setType(type & 0x7f);
else {
......@@ -293,7 +293,7 @@ public class RGNFileReader extends ImgReader {
else
len = reader.get2u();
int base = reader.get();
int base = reader.get1u();
byte[] bitstream = reader.get(len);
BitReader br = new BitReader(bitstream);
......@@ -309,8 +309,7 @@ public class RGNFileReader extends ImgReader {
* @param line The line or shape that is to be populated.
*/
private void readLineCommonExtType(ImgFileReader reader, Subdivision div, Polyline line) {
int type = reader.get1u();
type <<= 8;
int type = reader.get1u() << 8;
int b1 = reader.get1u();
boolean hasExtraBytes = (b1 & 0x80) != 0;
boolean hasLabel = (b1 & 0x20) != 0;
......
......@@ -269,7 +269,7 @@ public class Subdivision {
log.debug("write subdiv", latitude, longitude);
file.put3u(startRgnPointer);
file.put1u(getType());
file.put3s(longitude);
Utils.put3sLongitude(file, longitude);
file.put3s(latitude);
assert width <= 0x7fff;
......
......@@ -228,7 +228,7 @@ public class TREFileReader extends ImgReader {
long pos = sect.getPosition();
while (pos < sect.getEndPos()) {
reader.position(pos);
int offset = reader.get3s();
int offset = reader.get3u();
Label label = lblReader.fetchLabel(offset);
if (label != null) {
msgs.add(label.getText());
......
......@@ -163,13 +163,9 @@ public class TREHeader extends CommonHeader {
*/
protected void writeFileHeader(ImgFileWriter writer) {
writer.put3s(area.getMaxLat());
// handle special case, write -180 instead of 180 to avoid assertion
if (area.getMaxLong() == Utils.MAX_LON_MAP_UNITS)
writer.put3s(Utils.MIN_LON_MAP_UNITS);
else
writer.put3s(area.getMaxLong());
Utils.put3sLongitude(writer, area.getMaxLong());
writer.put3s(area.getMinLat());
writer.put3s(area.getMinLong());
writer.put3s(area.getMinLong()); // minLong cant be +180
writer.put4(getMapLevelsPos());
writer.put4(getMapLevelsSize());
......
......@@ -70,7 +70,7 @@ public class LevelInfo implements Comparable<LevelInfo> {
if (key < 0 || key > 16)
throw new ExitException("Error: Level value out of range 0-16: " + s + " in levels specification " + levelSpec);
int value = Integer.parseInt(keyVal[1]);
if (value <= 0 || value > 24)
if (value < 0 || value > 24)
throw new ExitException("Error: Resolution value out of range 0-24: " + s + " in levels specification " + levelSpec);
levels[count] = new LevelInfo(key, value);
} catch (NumberFormatException e) {
......
......@@ -42,4 +42,9 @@ class RuleDetails {
public Set<String> getChangingTags() {
return changingTags;
}
@Override
public String toString() {
return "keystring=\"" + keystring + "\" " + rule.toString();
}
}
......@@ -15,19 +15,19 @@ package uk.me.parabola.mkgmap.osmstyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import uk.me.parabola.mkgmap.osmstyle.eval.Op;
import uk.me.parabola.mkgmap.reader.osm.Rule;
import uk.me.parabola.mkgmap.reader.osm.TagDict;
import uk.me.parabola.util.MultiHashMap;
/**
* An index to reduce the number of rules that have to be executed.
......@@ -72,21 +72,21 @@ public class RuleIndex {
private boolean inited;
private class TagHelper{
// This is an index of all rules that start with EXISTS (A=*) or (A=B)
final BitSet checked;
// This is an index of all rules that start with EXISTS (A=*)
final BitSet exists;
// This is an index of all rules that start with EQUALS (A=B)
Map<String, BitSet> tagVals;
public TagHelper(BitSet checked){
this.checked = checked;
public TagHelper(BitSet exits){
this.exists = exits;
}
public void addTag(String val, BitSet value) {
if (tagVals == null)
tagVals = new HashMap<>();
if (checked != null){
if (exists != null){
BitSet merged = new BitSet();
merged.or(checked);
merged.or(exists);
merged.or(value);
tagVals.put(val, merged);
} else
......@@ -100,8 +100,8 @@ public class RuleIndex {
return (BitSet) set.clone();
}
}
if (checked != null)
return (BitSet) checked.clone();
if (exists != null)
return (BitSet) exists.clone();
return new BitSet();
}
}
......@@ -163,23 +163,14 @@ public class RuleIndex {
public void prepare() {
if (inited)
return;
// This is an index of all rules that start with EXISTS (A=*)
Map<String, BitSet> existKeys = new HashMap<String, BitSet>();
// This is an index of all rules that start with EQUALS (A=B)
Map<String, BitSet> tagVals = new HashMap<String, BitSet>();
// This is an index of all rules by the tag name (A).
Map<String, BitSet> tagnames = new HashMap<String, BitSet>();
// Maps a rule number to the tags that might be changed by that rule
Map<Integer, List<String>> changeTags = new HashMap<Integer, List<String>>();
// Collection of possibly changed or added tags were the new value is
// NOT known (e.g. set x=$y)
Set<String> modOrAddedTagKeys = new HashSet<>();
// Collection of possibly changed or added tags were the new value is
// known (e.g. set x=1)
MultiHashMap<String, String> modOrAddedTags = new MultiHashMap<>();
// remove unnecessary rules
filterRules();
......@@ -187,99 +178,78 @@ public class RuleIndex {
int ruleNumber = i;
RuleDetails rd = ruleDetails.get(i);
String keystring = rd.getKeystring();
Set<String> changeableTags = rd.getChangingTags();
if (keystring.endsWith("=*")) {
String key = keystring.substring(0, keystring.length() - 2);
addNumberToMap(existKeys, key, ruleNumber);
addNumberToMap(tagnames, key, ruleNumber);
} else {
addNumberToMap(tagVals, keystring, ruleNumber);
// check if any of the previous rules may have changed the tag
int ind = keystring.indexOf('=');
assert ind >= 0 : "rule index: error in keystring " + keystring;
if (ind >= 0) {
String key = keystring.substring(0, ind);
boolean needed = (modOrAddedTagKeys.contains(key));
if (!needed) {
List<String> values = modOrAddedTags.get(key);
if (values.contains(keystring.substring(ind + 1)))
needed = true;
}
if (needed) {
addNumberToMap(tagnames, key, ruleNumber);
}
}
addChangables(changeTags, changeableTags, ruleNumber);
for (String ent : changeableTags) {
int ind = ent.indexOf('=');
if (ind >= 0) {
modOrAddedTags.add(ent.substring(0, ind), ent.substring(ind + 1));
} else {
modOrAddedTagKeys.add(ent);
assert false: "rule index: no = in keystring " + keystring;
}
}
}
for (Map.Entry<Integer, List<String>> ent : changeTags.entrySet()) {
int ruleNumber = ent.getKey();
List<String> changeTagList = ent.getValue();
// When we add new rules, we may, in turn get more changeable tags
// which will force us to run again to find more rules that could
// be executed. So save rules that we find here.
Set<String> newChanged = new HashSet<String>(changeTagList);
// we have to find all rules that might be now matched
do {
for (String s : new ArrayList<String>(newChanged)) {
BitSet set;
// If we know the value that could be set, then we can restrict to
// rules that would match that value. Otherwise we look for any
// rule using the tag, no matter what the value.
// find the additional rules which might be triggered as a result of actions changing tags.
Map<Integer, BitSet> additionalRules = new LinkedHashMap<>();
for (int i = 0; i < ruleDetails.size(); i++) {
int ruleNumber = i;
RuleDetails rd = ruleDetails.get(i);
final Set<String> changeableTags = rd.getChangingTags();
BitSet addedRules = new BitSet();
for (String s : changeableTags) {
int ind = s.indexOf('=');
if (ind >= 0) {
String key = s.substring(0, ind);
set = tagnames.get(key);
} else {
set = tagnames.get(s);
BitSet set = tagVals.get(s);
if (set != null) {
addedRules.or(set);
}
if (set != null && !set.isEmpty()) {
// create copy that can be safely modified
BitSet tmp = new BitSet();
tmp.or(set);
set = tmp;
for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) {
// Only rules after this one can be affected
if (i > ruleNumber) {
newChanged.addAll(ruleDetails.get(i).getChangingTags());
// Exists rules can also be triggered, so add them too.
String key = s.substring(0, ind);
BitSet set1 = existKeys.get(key);
if (set1 != null) {
addedRules.or(set1);
}
} else {
set.clear(i);
BitSet set = tagnames.get(s);
if (set != null)
addedRules.or(set);
}
}
// Only rules after the current one can be affected
addedRules.clear(0, ruleNumber);
if (!addedRules.isEmpty()) {
additionalRules.put(ruleNumber, addedRules);
}
}
// now add all the additional rules to the existing sets
for (Entry<Integer, BitSet> e : additionalRules.entrySet()) {
int ruleNumber = e.getKey();
BitSet addSet = e.getValue();
// Find every rule number set that contains the rule number that we
// are examining and add all the newly found rules to each such set.
for (Map<String, BitSet> m : Arrays.asList(tagVals, tagnames)) {
Collection<BitSet> bitSets = m.values();
for (BitSet bi : bitSets) {
for (Map<String, BitSet> m : Arrays.asList(existKeys, tagVals, tagnames)) {
for (Entry<String, BitSet> e2 : m.entrySet()) {
BitSet bi = e2.getValue();
if (bi.get(ruleNumber)) {
// contains the rule that we are looking at so we must
// also add the rules in the set we found.
bi.or(set);
}
}
bi.or(addSet);
}
}
}
newChanged.removeAll(changeTagList);
changeTagList.addAll(newChanged);
} while (!newChanged.isEmpty());
}
// compress the index: create one hash map with one entry for each key
for (Map.Entry<String, BitSet> entry : tagnames.entrySet()){
for (Map.Entry<String, BitSet> entry : existKeys.entrySet()){
Short skey = TagDict.getInstance().xlate(entry.getKey());
tagKeyMap.put(skey, new TagHelper(entry.getValue()));
}
......@@ -374,25 +344,6 @@ public class RuleIndex {
set.set(ruleNumber);
}
/**
* For each rule number, we maintain a list of tags that might be
* changed by that rule.
* @param changeTags
* @param changeableTags The tags that might be changed if the rule is
* matched.
* @param ruleNumber The rule number.
*/
private static void addChangables(Map<Integer, List<String>> changeTags, Set<String> changeableTags, int ruleNumber) {
if(changeableTags.isEmpty())
return;
List<String> tags = changeTags.get(ruleNumber);
if (tags == null) {
tags = new ArrayList<String>();
changeTags.put(ruleNumber, tags);
}
tags.addAll(changeableTags);
}
public List<RuleDetails> getRuleDetails() {
return ruleDetails;
}
......
......@@ -307,5 +307,20 @@ public class RuleSet implements Rule, Iterable<Rule> {
return false;
}
public BitSet getRules(Element el) {
if (!compiled || cacheId == Integer.MAX_VALUE)
compile();
// new element, invalidate all caches
cacheId++;
// Get all the rules that could match from the index.
BitSet candidates = new BitSet();
for (Entry<Short, String> tagEntry : el.getFastTagEntryIterator()) {
BitSet rules = index.getRulesForTag(tagEntry.getKey(), tagEntry.getValue());
if (rules != null && !rules.isEmpty() )
candidates.or(rules);
}
return candidates;
}
}
......@@ -39,13 +39,14 @@ public class HGTConverter {
private int pointsDistanceLat;
private int pointsDistanceLon;
private boolean useComplexInterpolation;
private double[][] eleArray;
private final double[][] eleArray = new double[4][4];
private int statPoints;
private int statBicubic;
private int statBilinear;
private int statVoid;
private int statRdrNull;
private int statRdrRes;
private InterpolationMethod interpolationMethod = InterpolationMethod.Bicubic;
public enum InterpolationMethod {
......@@ -146,8 +147,8 @@ public class HGTConverter {
statPoints++;
if (useComplexInterpolation) {
// bicubic (Catmull-Rom) interpolation with 16 points
eleArray = fillArray(rdr, row, col, xLeft, yBottom);
if (eleArray != null) {
boolean filled = fillArray(rdr, row, col, xLeft, yBottom);
if (filled) {
h = (short) Math.round(bicubicInterpolation(eleArray, qx, qy));
statBicubic++;
}
......@@ -181,7 +182,7 @@ public class HGTConverter {
* Fill 16 values of HGT near required coordinates
* can use HGTreaders near the current one
*/
private double[][] fillArray(HGTReader rdr, int row, int col, int xLeft, int yBottom) {
private boolean fillArray(HGTReader rdr, int row, int col, int xLeft, int yBottom) {
int res = rdr.getRes();
int minX = 0;
int minY = 0;
......@@ -192,62 +193,61 @@ public class HGTConverter {
// check borders
if (xLeft == 0) {
if (col <= 0)
return null;
return false;
minX = 1;
inside = false;
} else if (xLeft == res - 1) {
if (col + 1 >= readers[0].length)
return null;
return false;
maxX = 2;
inside = false;
}
if (yBottom == 0) {
if (row <= 0)
return null;
return false;
minY = 1;
inside = false;
} else if (yBottom == res - 1) {
if (row + 1 >= readers.length)
return null;
return false;
maxY = 2;
inside = false;
}
// fill data from current reader
double[][] eleArray = new double[4][4];
short h;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
h = rdr.ele(xLeft + x - 1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][y] = h;
}
}
if (inside) // no need to check borders again
return eleArray;
return true;
// fill data from adjacent readers, down and up
if (xLeft > 0 && xLeft < res - 1) {
if (yBottom == 0) { // bottom edge
HGTReader rdrBB = prepReader(res, row - 1, col);
if (rdrBB == null)
return null;
return false;
for (int x = 0; x <= 3; x++) {
h = rdrBB.ele(xLeft + x - 1, res - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][0] = h;
}
} else if (yBottom == res - 1) { // top edge
HGTReader rdrTT = prepReader(res, row + 1, col);
if (rdrTT == null)
return null;
return false;
for (int x = 0; x <= 3; x++) {
h = rdrTT.ele(xLeft + x - 1, 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][3] = h;
}
}
......@@ -258,21 +258,21 @@ public class HGTConverter {
if (xLeft == 0) { // left edgge
HGTReader rdrLL = prepReader(res, row, col - 1);
if (rdrLL == null)
return null;
return false;
for (int y = 0; y <= 3; y++) {
h = rdrLL.ele(res - 1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[0][y] = h;
}
} else if (xLeft == res - 1) { // right edge
HGTReader rdrRR = prepReader(res, row, col + 1);
if (rdrRR == null)
return null;
return false;
for (int y = 0; y <= 3; y++) {
h = rdrRR.ele(1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[3][y] = h;
}
}
......@@ -283,122 +283,122 @@ public class HGTConverter {
if (yBottom == 0) { // left bottom corner
HGTReader rdrLL = prepReader(res, row, col - 1);
if (rdrLL == null)
return null;
return false;
for (int y = 1; y <= 3; y++) {
h = rdrLL.ele(res - 1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[0][y] = h;
}
HGTReader rdrBB = prepReader(res, row - 1, col);
if (rdrBB == null)
return null;
return false;
for (int x = 1; x <= 3; x++) {
h = rdrBB.ele(xLeft + x - 1, res - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][0] = h;
}
HGTReader rdrLB = prepReader(res, row - 1, col - 1);
if (rdrLB == null)
return null;
return false;
h = rdrLB.ele(res - 1, res - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[0][0] = h;
} else if (yBottom == res - 1) { // left top corner
HGTReader rdrLL = prepReader(res, row, col - 1);
if (rdrLL == null)
return null;
return false;
for (int y = 0; y <= 2; y++) {
h = rdrLL.ele(res - 1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[0][y] = h;
}
HGTReader rdrTT = prepReader(res, row + 1, col);
if (rdrTT == null)
return null;
return false;
for (int x = 1; x <= 3; x++) {
h = rdrTT.ele(xLeft + x - 1, 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][3] = h;
}
HGTReader rdrLT = prepReader(res, row + 1, col - 1);
if (rdrLT == null)
return null;
return false;
h = rdrLT.ele(res - 1, 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[0][3] = h;
}
} else if (xLeft == res - 1) {
if (yBottom == 0) { // right bottom corner
HGTReader rdrRR = prepReader(res, row, col + 1);
if (rdrRR == null)
return null;
return false;
for (int y = 1; y <= 3; y++) {
h = rdrRR.ele(1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[3][y] = h;
}
HGTReader rdrBB = prepReader(res, row - 1, col);
if (rdrBB == null)
return null;
return false;
for (int x = 0; x <= 2; x++) {
h = rdrBB.ele(xLeft + x - 1, res - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][0] = h;
}
HGTReader rdrRB = prepReader(res, row - 1, col + 1);
if (rdrRB == null)
return null;
return false;
h = rdrRB.ele(1, res - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[3][0] = h;
} else if (yBottom == res - 1) { // right top corner
HGTReader rdrRR = prepReader(res, row, col + 1);
if (rdrRR == null)
return null;
return false;
for (int y = 0; y <= 2; y++) {
h = rdrRR.ele(1, yBottom + y - 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[3][y] = h;
}
HGTReader rdrTT = prepReader(res, row + 1, col);
if (rdrTT == null)
return null;
return false;
for (int x = 0; x <= 2; x++) {
h = rdrTT.ele(xLeft + x - 1, 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[x][3] = h;
}
HGTReader rdrRT = prepReader(res, row + 1, col + 1);
if (rdrRT == null)
return null;
return false;
h = rdrRT.ele(1, 1);
if (h == HGTReader.UNDEF)
return null;
return false;
eleArray[3][3] = h;
}
}
// all 16 values present
return eleArray;
return true;
}
/**
......@@ -665,7 +665,7 @@ public class HGTConverter {
* @param qy value from 0 .. 1 gives relative y position in matrix
*/
private static double bicubicInterpolation(double[][] p, double qx, double qy) {
double[] arr = new double[4];
final double[] arr = new double[4];
arr[0] = cubicInterpolation(p[0], qy);
arr[1] = cubicInterpolation(p[1], qy);
......
......@@ -171,12 +171,14 @@ public class HGTReader {
* @param name wanted file
*/
private void checkZip(String fName, String name) {
try(ZipFile zipFile = new ZipFile(fName)){
File f = new File(fName);
if (!f.exists())
return;
try(ZipFile zipFile = new ZipFile(f)){
ZipEntry entry = findZipEntry(zipFile, name);
if (entry != null){
res = calcRes(entry.getSize(), entry.getName());
}
} catch (FileNotFoundException e) {
} catch (IOException exp) {
log.error("failed to get size for file", name, "from", fName);
}
......
......@@ -14,6 +14,7 @@
package uk.me.parabola.mkgmap.osmstyle;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import uk.me.parabola.mkgmap.reader.osm.Element;
......@@ -367,6 +368,33 @@ public class RuleSetTest {
assertEquals("first element", 0x1f, list.get(0).getType());
}
@Test
public void testIndexWithOddOrder() {
RuleSet rs = makeRuleSet("a=* {set b=1}" +
"b=1 {set c=1}" +
"d=2 {set c=2}" +
"c=* {set a=2}" +
"c=1 {set d=2}" +
"c=2 {set d=1}" +
"d=1 [0x10401 resolution 24]" +
"d=2 [0x10402 resolution 24]"
);
Way el = new Way(1);
el.addTag("a", "1");
BitSet candidates = rs.getRules(el);
BitSet expected = new BitSet();
expected.flip(0,8);
expected.clear(2);
expected.clear(5);
expected.clear(6);
assertEquals("candidates", expected, candidates);
List<GType> list = resolveList(rs, el);
assertEquals("first element", 0x10402, list.get(0).getType());
}
private List<GType> resolveList(RuleSet rs, Way el) {
final List<GType> list = new ArrayList<GType>();
rs.resolveType(el, new TypeResult() {
......