package cgeo.geocaching.files; import java.io.File; import java.util.HashMap; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.os.Handler; import android.util.Log; import cgeo.geocaching.cgBase; import cgeo.geocaching.cgCache; import cgeo.geocaching.cgCacheWrap; import cgeo.geocaching.cgCoord; import cgeo.geocaching.cgSearch; import cgeo.geocaching.cgSettings; import cgeo.geocaching.cgeoapplication; public final class LocParser extends FileParser { private static final Pattern patternGeocode = Pattern .compile("name id=\"([^\"]+)\""); private static final Pattern patternLat = Pattern .compile("lat=\"([^\"]+)\""); private static final Pattern patternLon = Pattern .compile("lon=\"([^\"]+)\""); // premium only >> private static final Pattern patternDifficulty = Pattern .compile("([^<]+)"); private static final Pattern patternTerrain = Pattern .compile("([^<]+)"); private static final Pattern patternContainer = Pattern .compile("([^<]+)"); private static final Pattern patternName = Pattern.compile("CDATA\\[([^\\]]+)\\]"); public static void parseLoc(final cgCacheWrap caches, final String fileContent) { final HashMap cidCoords = parseCoordinates(fileContent); // save found cache coordinates for (cgCache cache : caches.cacheList) { if (cidCoords.containsKey(cache.geocode)) { cgCoord coord = cidCoords.get(cache.geocode); copyCoordToCache(coord, cache); } } } private static void copyCoordToCache(final cgCoord coord, final cgCache cache) { cache.latitude = coord.latitude; cache.longitude = coord.longitude; cache.difficulty = coord.difficulty; cache.terrain = coord.terrain; cache.size = coord.size; cache.geocode = coord.geocode.toUpperCase(); if (cache.name == null || cache.name.length() == 0) { cache.name = coord.name; } } private static HashMap parseCoordinates( final String fileContent) { final HashMap coords = new HashMap(); if (fileContent == null || fileContent.length() <= 0) { return coords; } // >> premium only final String[] points = fileContent.split(""); // parse coordinates for (String pointString : points) { final cgCoord pointCoord = new cgCoord(); HashMap tmp = null; final Matcher matcherGeocode = patternGeocode.matcher(pointString); if (matcherGeocode.find()) { String geocode = matcherGeocode.group(1).trim().toUpperCase(); pointCoord.name = geocode; pointCoord.geocode = geocode; } final Matcher matcherName = patternName.matcher(pointString); if (matcherName.find()) { String name = matcherName.group(1).trim(); int pos = name.indexOf(" by "); if (pos > 0) { name = name.substring(0, pos).trim(); } pointCoord.name = name; } final Matcher matcherLat = patternLat.matcher(pointString); if (matcherLat.find()) { tmp = cgBase.parseCoordinate(matcherLat.group(1).trim(), "lat"); pointCoord.latitude = (Double) tmp.get("coordinate"); } final Matcher matcherLon = patternLon.matcher(pointString); if (matcherLon.find()) { tmp = cgBase.parseCoordinate(matcherLon.group(1).trim(), "lon"); pointCoord.longitude = (Double) tmp.get("coordinate"); } final Matcher matcherDifficulty = patternDifficulty.matcher(pointString); if (matcherDifficulty.find()) { pointCoord.difficulty = new Float(matcherDifficulty.group(1) .trim()); } final Matcher matcherTerrain = patternTerrain.matcher(pointString); if (matcherTerrain.find()) { pointCoord.terrain = new Float(matcherTerrain.group(1).trim()); } final Matcher matcherContainer = patternContainer.matcher(pointString); if (matcherContainer.find()) { final int size = Integer.parseInt(matcherContainer.group(1) .trim()); if (size == 1) { pointCoord.size = "not chosen"; } else if (size == 2) { pointCoord.size = "micro"; } else if (size == 3) { pointCoord.size = "regular"; } else if (size == 4) { pointCoord.size = "large"; } else if (size == 5) { pointCoord.size = "virtual"; } else if (size == 6) { pointCoord.size = "other"; } else if (size == 8) { pointCoord.size = "small"; } else { pointCoord.size = "unknown"; } } if (pointCoord.geocode != null && pointCoord.geocode.length() > 0) { coords.put(pointCoord.geocode, pointCoord); } } Log.i(cgSettings.tag, "Coordinates found in .loc file: " + coords.size()); return coords; } public static long parseLoc(cgeoapplication app, File file, int listId, Handler handler) { cgSearch search = new cgSearch(); long searchId = 0L; try { HashMap coords = parseCoordinates(readFile(file).toString()); final cgCacheWrap caches = new cgCacheWrap(); for (Entry entry : coords.entrySet()) { cgCoord coord = entry.getValue(); if (coord.geocode == null || coord.geocode.length() == 0 || coord.name == null || coord.name.length() == 0) { continue; } cgCache cache = new cgCache(); copyCoordToCache(coord, cache); caches.cacheList.add(cache); fixCache(cache); cache.reason = listId; cache.detailed = false; app.addCacheToSearch(search, cache); } caches.totalCnt = caches.cacheList.size(); showFinishedMessage(handler, search); } catch (Exception e) { Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString()); } Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId)); return search.getCurrentId(); } }