public int getPartition(WritablePoint key, LongWritable value, int numReduceTasks) { int grid = (int) Math.sqrt(numReduceTasks); minlat = conf.getDouble(OSMMapper.MINLAT, 0); minlon = conf.getDouble(OSMMapper.MINLON, 0); maxlat = conf.getDouble(OSMMapper.MAXLAT, 0); maxlon = conf.getDouble(OSMMapper.MAXLON, 0); double w = (maxlon - minlon) / grid; double h = (maxlat - minlat) / grid; int ret = -1; for (int i = 0; i < grid; i++) { double comp = minlat + (double) (i + 1) * h; if (key.getY() < comp) { ret = i * grid; // determine highside value break; } } if (ret == -1) { // We had a slight double imprecision problem assume we didn't properly arrive at maxlat ret = grid * grid - grid; } for (int i = 0; i < grid; i++) { if (key.getX() < minlon + (double) (i + 1) * w) { ret = ret + i; return ret; // determine lowside value } } ret = ret + grid - 1; return ret; }
public void map(Object key, Text value, Context context) throws IOException, InterruptedException { int start = 0; while (start < value.getLength()) { // Find the start of a node start = value.find("node", start); if (start == -1) break; // Find the id of that node start = value.find(" id", start); if (start == -1) break; start += 5; int c = ':'; StringBuilder temp = new StringBuilder(); for (; start < value.getLength(); start++) { c = value.charAt(start); if (c != '"') temp.append(c); else break; } if (start > value.getLength()) break; try { id.set(Long.parseLong(temp.toString())); } catch (NumberFormatException e) { // My Job isn't to worry about java not having unsigned values because they are stupid id.set(404); } start = value.find(" lat", start); if (start == -1) break; start += 6; c = ':'; temp.delete(0, temp.length()); for (; start < value.getLength(); start++) { c = value.charAt(start); if (c != '"') temp.append((char) c); else break; } if (start > value.getLength()) break; node.setY(Double.parseDouble(temp.toString())); if (node.getY() < minlat || node.getY() > maxlat) { continue; // Don't care about nodes outside our area of interest } start = value.find(" lon", start); if (start == -1) break; start += 6; c = ':'; temp.delete(0, temp.length()); for (; start < value.getLength(); start++) { c = value.charAt(start); if (c != '"') temp.append((char) c); else break; } if (start > value.getLength()) break; node.setX(Double.parseDouble(temp.toString())); if (node.getX() < minlon || node.getX() > maxlon) continue; // Don't care about nodes outside our area of interest context.write(node, id); } }