package cgeo.geocaching.connector.gc;
import android.graphics.Bitmap;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.models.Geocache;
import cgeo.geocaching.settings.Settings;
/**
* icon decoder for cache icons
*
*/
@SuppressWarnings("RedundantIfStatement")
final class IconDecoder {
private static final int CT_TRADITIONAL = 0;
private static final int CT_MULTI = 1;
private static final int CT_MYSTERY = 2;
private static final int CT_EVENT = 3;
private static final int CT_EARTH = 4;
private static final int CT_FOUND = 5;
private static final int CT_OWN = 6;
private static final int CT_CITO = 7;
private static final int CT_VIRTUAL = 8;
private static final int CT_MEGAEVENT = 9;
private static final int CT_WHERIGO = 10;
private static final int CT_WEBCAM = 11;
private static final int CT_LETTERBOX = 12;
private IconDecoder() {
throw new IllegalStateException("utility class");
}
static boolean parseMapPNG(final Geocache cache, final Bitmap bitmap, final UTFGridPosition xy, final int zoomlevel) {
final int topX = xy.getX() * 4;
final int topY = xy.getY() * 4;
final int bitmapWidth = bitmap.getWidth();
final int bitmapHeight = bitmap.getHeight();
if ((topX < 0) || (topY < 0) || (topX + 4 > bitmapWidth) || (topY + 4 > bitmapHeight)) {
return false; //out of image position
}
int numberOfDetections = 9; //for level 12 and 13
if (zoomlevel < 12) {
numberOfDetections = 5;
}
if (zoomlevel > 13) {
numberOfDetections = 9;
}
final int[] pngType = new int[numberOfDetections];
for (int x = topX; x < topX + 4; x++) {
for (int y = topY; y < topY + 4; y++) {
final int color = bitmap.getPixel(x, y);
if ((color >>> 24) != 255) {
continue; //transparent pixels (or semi_transparent) are only shadows of border
}
final int r = (color & 0xFF0000) >> 16;
final int g = (color & 0xFF00) >> 8;
final int b = color & 0xFF;
if (isPixelDuplicated(r, g, b, zoomlevel)) {
continue;
}
final int type;
if (zoomlevel < 12) {
type = getCacheTypeFromPixel11(r, g, b);
} else if (zoomlevel > 13) {
type = getCacheTypeFromPixel14(r, g, b);
} else {
type = getCacheTypeFromPixel13(r, g, b);
}
pngType[type]++;
}
}
int type = -1;
int count = 0;
for (int x = 0; x < pngType.length; x++) {
if (pngType[x] > count) {
count = pngType[x];
type = x;
}
}
if (count > 1) { // 2 pixels need to detect same type and we say good to go
switch (type) {
case CT_TRADITIONAL:
cache.setType(CacheType.TRADITIONAL, zoomlevel);
return true;
case CT_MULTI:
cache.setType(CacheType.MULTI, zoomlevel);
return true;
case CT_MYSTERY:
cache.setType(CacheType.MYSTERY, zoomlevel);
return true;
case CT_EVENT:
cache.setType(CacheType.EVENT, zoomlevel);
return true;
case CT_EARTH:
cache.setType(CacheType.EARTH, zoomlevel);
return true;
case CT_FOUND:
cache.setFound(true);
return true;
case CT_OWN:
cache.setOwnerUserId(Settings.getUserName());
return true;
case CT_MEGAEVENT:
cache.setType(CacheType.MEGA_EVENT, zoomlevel);
return true;
case CT_CITO:
cache.setType(CacheType.CITO, zoomlevel);
return true;
case CT_WEBCAM:
cache.setType(CacheType.WEBCAM, zoomlevel);
return true;
case CT_WHERIGO:
cache.setType(CacheType.WHERIGO, zoomlevel);
return true;
case CT_VIRTUAL:
cache.setType(CacheType.VIRTUAL, zoomlevel);
return true;
case CT_LETTERBOX:
cache.setType(CacheType.LETTERBOX, zoomlevel);
return true;
}
}
return false;
}
/**
* A method that returns true if pixel color appears on more than one cache type and shall be excluded from parsing
*
* @param r
* red value
* @param g
* green value
* @param b
* blue value
* @param zoomlevel
* zoom level of map
* @return true if parsing should not be performed
*/
private static boolean isPixelDuplicated(final int r, final int g, final int b, final int zoomlevel) {
if ((r == g) && (g == b)) {
return true;
}
if (zoomlevel < 12) {
return false;
}
if (zoomlevel > 13) {
if ((r == 252) && (b == 252) && (g == 251) || (r == 206) && (b == 219) && (g == 230) || (r == 178) && (b == 198) && (g == 215) || (r == 162) && (b == 186) && (g == 209) || (r == 187) && (b == 205) && (g == 222) || (r == 216) && (b == 226) && (g == 235) || (r == 253) && (b == 254) && (g == 254) || (r == 243) && (b == 247) && (g == 249) || (r == 136) && (b == 166) && (g == 195) || (r == 254) && (b == 255) && (g == 255) || (r == 222) && (b == 231) && (g == 239) || (r == 240) && (b == 244) && (g == 248) || (r == 194) && (b == 209) && (g == 221) || (r == 153) && (b == 178) && (g == 199) || (r == 228) && (b == 238) && (g == 242) || (r == 109) && (b == 165) && (g == 141) || (r == 124) && (b == 194) && (g == 165) || (r == 206) && (b == 229) && (g == 220) || (r == 199) && (b == 224) && (g == 210) || (r == 252) && (b == 253) && (g == 254) || (r == 244) && (b == 247) && (g == 243) || (r == 197) && (b == 212) && (g == 227) || (r == 171) && (b == 172) && (g == 172) || (r == 160) && (b == 161) && (g == 161) || (r == 232) && (b == 249) && (g == 250) || (r == 253) && (b == 241) && (g == 227) || (r == 254) && (b == 248) && (g == 240) || (r == 72) && (b == 112) && (g == 48) || (r == 251) && (b == 239) && (g == 217) || (r == 214) && (b == 239) && (g == 244) || (r == 202) && (b == 214) && (g == 194) || (r == 168) && (b == 186) && (g == 156) || (r == 254) && (b == 249) && (g == 247) || (r == 132) && (b == 166) && (g == 130) || (r == 238) && (b == 238) && (g == 233) || (r == 241) && (b == 252) && (g == 253) || (r == 101) && (b == 135) && (g == 80) || (r == 193) && (b == 208) && (g == 184) || (r == 251) && (b == 253) && (g == 252)) {
return true;
}
return false;
}
//zoom level 12, 13
if ((r == 247) && (b == 249) && (g == 251) || (r == 253) && (b == 254) && (g == 254) || (r == 252) && (b == 253) && (g == 254) || (r == 241) && (b == 249) && (g == 251) || (r == 249) && (b == 252) && (g == 253) || (r == 251) && (b == 253) && (g == 253) || (r == 254) && (b == 253) && (g == 253)) {
return true;
}
return false;
}
/**
* This method returns detected type from specific pixel from geocaching.com live map.
* It was constructed based on classification tree made by Orange (http://orange.biolab.si/)
* Input file was made from every non-transparent pixel of every possible "middle" cache icon from GC map
*
* @param r
* Red component of pixel (from 0 - 255)
* @param g
* Green component of pixel (from 0 - 255)
* @param b
* Blue component of pixel (from 0 - 255)
* @return Value from 0 to 6 representing detected type or state of the cache.
*/
private static int getCacheTypeFromPixel13(final int r, final int g, final int b) {
if (b < 139) {
if (r < 115) {
if (b < 82) {
if (r < 63) {
if (r < 20) {
if (r < 4) {
return g < 137 ? CT_TRADITIONAL : CT_CITO;
}
return g < 150 ? CT_TRADITIONAL : CT_CITO;
}
return CT_EARTH;
}
if (g < 149) {
return r < 88 ? CT_EARTH : CT_FOUND;
}
return CT_EVENT;
}
if (g < 138) {
if (r < 37) {
return CT_CITO;
}
if (b < 126) {
if (r < 72) {
if (r < 44) {
return g < 90 ? CT_EVENT : CT_CITO;
}
return CT_EVENT;
}
return CT_EARTH;
}
if (g < 90) {
return CT_EVENT;
}
return g < 120 ? CT_CITO : CT_EVENT;
}
if (g < 166) {
return r < 75 ? CT_TRADITIONAL : CT_EARTH;
}
if (r < 62) {
if (g < 175) {
return CT_CITO;
}
return r < 48 ? CT_OWN : CT_CITO;
}
return g < 184 ? CT_TRADITIONAL : CT_CITO;
}
if (r < 201) {
if (g < 118) {
return r < 141 ? CT_FOUND : CT_EVENT;
}
if (g < 170) {
if (r < 150) {
return g < 146 ? CT_FOUND : CT_EARTH;
}
return r < 192 ? CT_FOUND : CT_EVENT;
}
return CT_EVENT;
}
if (g < 183) {
return CT_MULTI;
}
if (r < 239) {
return CT_FOUND;
}
if (g < 210) {
return r < 246 ? CT_MULTI : CT_EARTH;
}
return b < 66 ? CT_FOUND : CT_EARTH;
}
if (r < 234) {
if (r < 86) {
if (b < 180) {
if (b < 151) {
if (r < 55) {
return g < 75 ? CT_EVENT : CT_MYSTERY;
}
return g < 160 ? CT_CITO : CT_OWN;
}
return g < 92 ? CT_EVENT : CT_MYSTERY;
}
return CT_VIRTUAL;
}
if (b < 211) {
if (r < 164) {
if (g < 179) {
if (b < 173) {
if (r < 98) {
return CT_CITO;
}
if (g < 160) {
return CT_EVENT;
}
return r < 133 ? CT_EARTH : CT_EVENT;
}
if (b < 185) {
if (r < 117) {
return CT_MYSTERY;
}
return g < 154 ? CT_EVENT : CT_CITO;
}
if (b < 196) {
return r < 141 ? CT_MYSTERY : CT_CITO;
}
return CT_MYSTERY;
}
if (g < 206) {
if (b < 181) {
if (g < 189) {
return r < 121 ? CT_TRADITIONAL : CT_EARTH;
}
return b < 155 ? CT_CITO : CT_TRADITIONAL;
}
if (g < 188) {
return b < 204 ? CT_CITO : CT_MYSTERY;
}
return CT_EARTH;
}
if (g < 210) {
return g < 208 ? CT_OWN : CT_CITO;
}
if (r < 155) {
if (g < 215) {
return r < 121 ? CT_OWN : CT_CITO;
}
return CT_OWN;
}
return CT_CITO;
}
if (r < 193) {
if (b < 192) {
if (g < 175) {
return b < 176 ? CT_FOUND : CT_EVENT;
}
if (b < 171) {
return CT_EVENT;
}
return r < 167 ? CT_EARTH : CT_EVENT;
}
if (g < 204) {
return b < 199 ? CT_EVENT : CT_CITO;
}
if (g < 226) {
if (r < 186) {
return CT_TRADITIONAL;
}
return g < 218 ? CT_EARTH : CT_TRADITIONAL;
}
return r < 179 ? CT_OWN : CT_CITO;
}
if (g < 208) {
if (g < 180) {
return CT_EVENT;
}
if (r < 198) {
return r < 196 ? CT_FOUND : CT_EVENT;
}
return CT_FOUND;
}
if (g < 215) {
return r < 207 ? CT_EVENT : CT_FOUND;
}
if (b < 199) {
return CT_EVENT;
}
return r < 218 ? CT_EARTH : CT_EVENT;
}
if (r < 174) {
if (r < 156) {
return CT_VIRTUAL;
}
if (g < 201) {
return CT_MYSTERY;
}
if (b < 228) {
return CT_EARTH;
}
if (r < 173) {
return CT_VIRTUAL;
}
return g < 221 ? CT_EARTH : CT_VIRTUAL;
}
if (b < 227) {
if (g < 222) {
if (r < 188) {
return b < 214 ? CT_CITO : CT_MYSTERY;
}
return b < 224 ? CT_CITO : CT_MYSTERY;
}
if (r < 210) {
if (g < 235) {
return g < 233 ? CT_TRADITIONAL : CT_CITO;
}
return CT_OWN;
}
return r < 216 ? CT_TRADITIONAL : CT_EARTH;
}
if (r < 208) {
if (g < 219) {
return CT_MYSTERY;
}
if (b < 240) {
if (r < 190) {
return b < 233 ? CT_EARTH : CT_VIRTUAL;
}
return CT_EARTH;
}
return CT_VIRTUAL;
}
if (g < 233) {
if (b < 233) {
return r < 210 ? CT_MYSTERY : CT_CITO;
}
if (r < 221) {
return CT_MYSTERY;
}
return b < 239 ? CT_CITO : CT_MYSTERY;
}
if (b < 243) {
if (g < 241) {
if (r < 226) {
return CT_EARTH;
}
if (r < 228) {
return CT_CITO;
}
return r < 229 ? CT_MYSTERY : CT_EARTH;
}
if (r < 221) {
return CT_OWN;
}
return r < 230 ? CT_CITO : CT_TRADITIONAL;
}
if (r < 224) {
if (b < 244) {
return r < 216 ? CT_VIRTUAL : CT_EARTH;
}
return CT_VIRTUAL;
}
return g < 241 ? CT_MYSTERY : CT_EARTH;
}
if (b < 230) {
if (r < 246) {
if (b < 206) {
if (r < 243) {
if (r < 240) {
return g < 226 ? CT_EARTH : CT_EVENT;
}
return CT_EARTH;
}
return g < 216 ? CT_MULTI : CT_EARTH;
}
if (b < 219) {
if (r < 243) {
if (r < 237) {
return g < 235 ? CT_EVENT : CT_EARTH;
}
return CT_EVENT;
}
return CT_EARTH;
}
return g < 236 ? CT_FOUND : CT_EVENT;
}
if (g < 220) {
return CT_MULTI;
}
if (g < 243) {
if (r < 249) {
return CT_EARTH;
}
if (r < 251) {
return CT_MULTI;
}
return b < 185 ? CT_EARTH : CT_MULTI;
}
return CT_EARTH;
}
if (r < 249) {
if (b < 242) {
if (r < 246) {
if (r < 240) {
return CT_TRADITIONAL;
}
return g < 237 ? CT_EVENT : CT_FOUND;
}
return CT_EVENT;
}
if (b < 249) {
if (g < 245) {
if (b < 245) {
return CT_CITO;
}
if (g < 243) {
return CT_MYSTERY;
}
return b < 247 ? CT_CITO : CT_MYSTERY;
}
if (b < 248) {
if (g < 250) {
if (r < 236) {
return CT_OWN;
}
if (r < 246) {
if (g < 246) {
return CT_EARTH;
}
if (r < 243) {
return CT_TRADITIONAL;
}
return r < 244 ? CT_EARTH : CT_TRADITIONAL;
}
return CT_EARTH;
}
return CT_OWN;
}
return CT_CITO;
}
if (g < 249) {
return r < 241 ? CT_VIRTUAL : CT_MYSTERY;
}
return CT_VIRTUAL;
}
if (r < 253) {
if (b < 252) {
if (b < 248) {
return CT_EVENT;
}
return r < 251 ? CT_FOUND : CT_EVENT;
}
if (b < 254) {
if (g < 253) {
return r < 252 ? CT_CITO : CT_MYSTERY;
}
return CT_OWN;
}
return CT_EARTH;
}
if (g < 250) {
if (g < 249) {
return CT_MULTI;
}
return b < 240 ? CT_EARTH : CT_MULTI;
}
if (b < 249) {
if (b < 243) {
return CT_EARTH;
}
return g < 253 ? CT_MULTI : CT_EARTH;
}
if (b < 253) {
return CT_EVENT;
}
if (g < 254) {
return CT_MYSTERY;
}
if (b < 255) {
return r < 255 ? CT_MULTI : CT_EARTH;
}
return CT_EARTH;
}
/**
* This method returns detected type from specific pixel from geocaching.com live map level 14 or higher.
* It was constructed based on classification tree made by Orange (http://orange.biolab.si/)
* Input file was made from every non-transparent pixel of every possible "full" cache icon from GC map
*
* @param r
* Red component of pixel (from 0 - 255)
* @param g
* Green component of pixel (from 0 - 255)
* @param b
* Blue component of pixel (from 0 - 255)
* @return Value from 0 to 6 representing detected type or state of the cache.
*/
private static int getCacheTypeFromPixel14(final int r, final int g, final int b) {
if (b < 150) {
if (r < 118) {
if (b < 93) {
if (r < 69) {
if (b < 74) {
return r < 68 ? CT_EARTH : CT_TRADITIONAL;
}
if (r < 3) {
if (b < 78) {
return g < 146 ? CT_TRADITIONAL : CT_CITO;
}
return CT_CITO;
}
return g < 151 ? CT_TRADITIONAL : CT_CITO;
}
if (g < 138) {
if (r < 100) {
return r < 85 ? CT_EARTH : CT_TRADITIONAL;
}
return CT_FOUND;
}
if (g < 145) {
return r < 94 ? CT_EVENT : CT_TRADITIONAL;
}
return CT_EVENT;
}
if (g < 152) {
if (b < 122) {
if (r < 50) {
if (r < 40) {
return CT_CITO;
}
return r < 46 ? CT_EVENT : CT_CITO;
}
if (g < 133) {
return CT_EVENT;
}
return r < 109 ? CT_EARTH : CT_TRADITIONAL;
}
if (r < 46) {
if (g < 79) {
return CT_EVENT;
}
return b < 133 ? CT_EVENT : CT_MYSTERY;
}
if (r < 79) {
return CT_CITO;
}
return r < 81 ? CT_EVENT : CT_CITO;
}
if (g < 175) {
if (g < 163) {
return r < 81 ? CT_TRADITIONAL : CT_EARTH;
}
return b < 110 ? CT_CITO : CT_TRADITIONAL;
}
if (r < 44) {
return CT_OWN;
}
if (g < 184) {
return b < 130 ? CT_CITO : CT_TRADITIONAL;
}
return g < 197 ? CT_CITO : CT_OWN;
}
if (g < 160) {
if (g < 93) {
return CT_EVENT;
}
if (r < 182) {
if (r < 132) {
if (g < 130) {
return CT_FOUND;
}
return b < 60 ? CT_OWN : CT_TRADITIONAL;
}
return CT_FOUND;
}
return b < 80 ? CT_MULTI : CT_EVENT;
}
if (b < 58) {
if (r < 238) {
return r < 162 ? CT_OWN : CT_FOUND;
}
return g < 209 ? CT_EARTH : CT_FOUND;
}
if (r < 233) {
if (g < 191) {
if (r < 147) {
return b < 139 ? CT_EVENT : CT_EARTH;
}
return b < 116 ? CT_OWN : CT_TRADITIONAL;
}
if (r < 176) {
return CT_EVENT;
}
return g < 211 ? CT_OWN : CT_EVENT;
}
if (g < 204) {
if (b < 105) {
return g < 192 ? CT_MULTI : CT_EARTH;
}
return CT_MULTI;
}
if (r < 246) {
if (r < 245) {
return CT_EARTH;
}
return g < 213 ? CT_EARTH : CT_EVENT;
}
return CT_EARTH;
}
if (r < 192) {
if (b < 197) {
if (r < 80) {
if (b < 178) {
if (g < 95) {
return CT_EVENT;
}
if (r < 58) {
return CT_MYSTERY;
}
return b < 158 ? CT_EVENT : CT_MYSTERY;
}
return CT_VIRTUAL;
}
if (g < 171) {
if (b < 172) {
if (r < 149) {
if (g < 136) {
return r < 96 ? CT_CITO : CT_EVENT;
}
return CT_CITO;
}
return CT_FOUND;
}
if (b < 188) {
if (r < 118) {
return g < 128 ? CT_EVENT : CT_MYSTERY;
}
if (r < 142) {
return g < 151 ? CT_EVENT : CT_CITO;
}
return CT_EVENT;
}
if (b < 190) {
return r < 132 ? CT_MYSTERY : CT_CITO;
}
return CT_MYSTERY;
}
if (g < 194) {
if (r < 142) {
if (r < 123) {
return g < 179 ? CT_EARTH : CT_TRADITIONAL;
}
return CT_EARTH;
}
if (b < 176) {
return CT_EARTH;
}
return r < 165 ? CT_CITO : CT_EVENT;
}
if (r < 172) {
if (g < 206) {
if (b < 161) {
return r < 138 ? CT_CITO : CT_EVENT;
}
return CT_TRADITIONAL;
}
if (r < 149) {
if (r < 126) {
return CT_OWN;
}
return r < 140 ? CT_CITO : CT_OWN;
}
if (g < 216) {
return b < 183 ? CT_CITO : CT_TRADITIONAL;
}
return CT_CITO;
}
if (b < 179) {
return g < 199 ? CT_TRADITIONAL : CT_EVENT;
}
return CT_EARTH;
}
if (b < 216) {
if (r < 125) {
return CT_VIRTUAL;
}
if (g < 212) {
if (r < 158) {
return g < 191 ? CT_MYSTERY : CT_EARTH;
}
if (b < 210) {
return CT_CITO;
}
return r < 178 ? CT_MYSTERY : CT_CITO;
}
if (g < 224) {
return CT_TRADITIONAL;
}
return g < 227 ? CT_CITO : CT_OWN;
}
if (r < 156) {
return CT_VIRTUAL;
}
if (b < 229) {
if (r < 175) {
if (r < 160) {
return g < 214 ? CT_EARTH : CT_VIRTUAL;
}
return CT_EARTH;
}
return CT_MYSTERY;
}
if (r < 174) {
return CT_VIRTUAL;
}
if (b < 234) {
if (r < 176) {
return g < 222 ? CT_EARTH : CT_VIRTUAL;
}
return CT_EARTH;
}
return CT_VIRTUAL;
}
if (b < 212) {
if (r < 240) {
if (g < 209) {
if (r < 215) {
if (g < 173) {
return CT_EVENT;
}
if (b < 197) {
return CT_FOUND;
}
return r < 211 ? CT_EVENT : CT_FOUND;
}
return CT_EVENT;
}
if (b < 199) {
if (b < 163) {
return CT_OWN;
}
if (b < 198) {
if (g < 227) {
return CT_EVENT;
}
return b < 189 ? CT_OWN : CT_EVENT;
}
return CT_OWN;
}
if (r < 221) {
if (r < 201) {
return CT_EARTH;
}
if (r < 216) {
return r < 210 ? CT_EVENT : CT_TRADITIONAL;
}
return CT_FOUND;
}
return CT_EVENT;
}
if (g < 224) {
if (r < 246) {
return b < 171 ? CT_EARTH : CT_EVENT;
}
return CT_MULTI;
}
if (g < 235) {
return b < 194 ? CT_EARTH : CT_MULTI;
}
return CT_EARTH;
}
if (r < 239) {
if (b < 235) {
if (r < 222) {
if (g < 226) {
if (b < 225) {
return g < 220 ? CT_CITO : CT_EARTH;
}
if (r < 203) {
return CT_MYSTERY;
}
return b < 233 ? CT_CITO : CT_MYSTERY;
}
if (g < 236) {
if (b < 231) {
if (r < 216) {
return CT_TRADITIONAL;
}
return r < 219 ? CT_EARTH : CT_TRADITIONAL;
}
return CT_CITO;
}
return g < 241 ? CT_CITO : CT_OWN;
}
if (g < 234) {
if (g < 227) {
return CT_FOUND;
}
return r < 231 ? CT_TRADITIONAL : CT_FOUND;
}
if (r < 232) {
return CT_TRADITIONAL;
}
return b < 221 ? CT_EVENT : CT_EARTH;
}
if (r < 215) {
if (b < 243) {
if (r < 198) {
return b < 238 ? CT_EARTH : CT_VIRTUAL;
}
if (r < 201) {
return b < 240 ? CT_EARTH : CT_VIRTUAL;
}
return CT_EARTH;
}
return CT_VIRTUAL;
}
if (b < 247) {
if (r < 229) {
if (g < 236) {
return g < 231 ? CT_MYSTERY : CT_CITO;
}
if (b < 244) {
return CT_EARTH;
}
return r < 225 ? CT_VIRTUAL : CT_EARTH;
}
if (g < 244) {
if (b < 239) {
return CT_EARTH;
}
if (b < 246) {
if (g < 239) {
return r < 231 ? CT_CITO : CT_MYSTERY;
}
return CT_CITO;
}
return CT_MYSTERY;
}
return r < 233 ? CT_CITO : CT_TRADITIONAL;
}
if (b < 248) {
return r < 230 ? CT_VIRTUAL : CT_EARTH;
}
return CT_VIRTUAL;
}
if (b < 245) {
if (r < 251) {
if (b < 223) {
return g < 238 ? CT_EVENT : CT_EARTH;
}
if (g < 241) {
return r < 242 ? CT_FOUND : CT_EVENT;
}
if (b < 240) {
if (r < 244) {
return r < 242 ? CT_OWN : CT_EARTH;
}
return b < 236 ? CT_EVENT : CT_OWN;
}
if (r < 248) {
return CT_FOUND;
}
return b < 243 ? CT_EVENT : CT_OWN;
}
if (g < 246) {
if (b < 239) {
return r < 254 ? CT_MULTI : CT_EARTH;
}
return CT_EVENT;
}
if (b < 243) {
return CT_EARTH;
}
return g < 251 ? CT_MULTI : CT_EARTH;
}
if (b < 251) {
if (r < 250) {
if (g < 248) {
return b < 247 ? CT_FOUND : CT_MYSTERY;
}
if (r < 242) {
return CT_OWN;
}
if (g < 250) {
return r < 245 ? CT_TRADITIONAL : CT_MYSTERY;
}
return r < 248 ? CT_CITO : CT_TRADITIONAL;
}
if (r < 254) {
if (g < 249) {
return CT_EVENT;
}
return r < 252 ? CT_FOUND : CT_EVENT;
}
return CT_MULTI;
}
if (r < 252) {
if (b < 253) {
if (r < 249) {
return CT_VIRTUAL;
}
return g < 253 ? CT_CITO : CT_OWN;
}
if (r < 251) {
return CT_VIRTUAL;
}
return g < 253 ? CT_MYSTERY : CT_VIRTUAL;
}
if (g < 255) {
if (r < 253) {
return g < 254 ? CT_MYSTERY : CT_OWN;
}
if (b < 255) {
if (b < 253) {
return CT_EVENT;
}
return r < 255 ? CT_MYSTERY : CT_EVENT;
}
return CT_MYSTERY;
}
if (r < 255) {
return b < 255 ? CT_OWN : CT_VIRTUAL;
}
return CT_MULTI;
}
/**
* This method returns detected type from specific pixel from geocaching.com live map level 11 or lower.
* It was constructed based on classification tree made by Orange (http://orange.biolab.si/)
* Input file was made from every non-transparent pixel of every possible "full" cache icon from GC map
*
* @param r
* Red component of pixel (from 0 - 255)
* @param g
* Green component of pixel (from 0 - 255)
* @param b
* Blue component of pixel (from 0 - 255)
* @return Value from 0 to 4 representing detected type or state of the cache.
*/
private static int getCacheTypeFromPixel11(final int r, final int g, final int b) {
if (r < 182) {
if (b < 158) {
if (g < 103) {
return r < 94 ? CT_MYSTERY : CT_EVENT;
}
return CT_TRADITIONAL;
}
if (g < 149) {
return CT_MYSTERY;
}
if (r < 143) {
return CT_EARTH;
}
return g < 218 ? CT_MYSTERY : CT_EARTH;
}
if (r < 240) {
if (b < 174) {
return b < 27 ? CT_MULTI : CT_EVENT;
}
if (b < 221) {
return CT_TRADITIONAL;
}
if (g < 239) {
return CT_MYSTERY;
}
if (b < 241) {
return CT_TRADITIONAL;
}
return r < 238 ? CT_EARTH : CT_MYSTERY;
}
if (b < 181) {
return CT_MULTI;
}
if (r < 253) {
if (b < 235) {
return r < 250 ? CT_EVENT : CT_MULTI;
}
if (b < 247) {
return r < 249 ? CT_TRADITIONAL : CT_EVENT;
}
if (g < 255) {
return r < 242 ? CT_EARTH : CT_MYSTERY;
}
return CT_EARTH;
}
if (b < 242) {
return CT_MULTI;
}
if (r < 255) {
return g < 248 ? CT_EVENT : CT_TRADITIONAL;
}
if (b < 248) {
return CT_MULTI;
}
return g < 254 ? CT_EVENT : CT_MULTI;
}
}