下面是一个里程计算的简单mapreduce实现
1.rowkey设计:每一小时用一个rowkey,每分钟一个column,每10s中一条GPS protobuf数据
2.将每小时的设备GPS数据计算出设备每个小时的行驶里程。
3.将里程结果存到本rowkey一个新的column字段
public void reduce(ImmutableBytesWritable key, Iterable<Result> values, Context context) throws IOException, InterruptedException {
List<Distance> list = new ArrayList<Distance>();
double distance = 0;
String rowkey = new String(key.get());
System.out.println("key:"+new String(key.get()));
for (Result value : values) {
for (Cell cell : value.rawCells()) {
//根据hbase查询出来的数据反序列化成对象
ElectricVehiMsgListProbuf.ElectricVehiMsgList msgList = ElectricVehiMsgListProbuf.ElectricVehiMsgList.parseFrom(CellUtil.cloneValue(cell));
//将延迟数据加入到原始builder中
for (int i = 0; i < msgList.getGpsList().size(); i++) {
Distance dis = new Distance();
long time = msgList.getGpsList().get(i).getTime();
Double lat = msgList.getGpsList().get(i).getLatitude();
Double lon = msgList.getGpsList().get(i).getLongitude();
if ( time >0 && lat >0.0) {
dis.setTime(time);
dis.setLatitude(lat);
dis.setLongitude(lon);
list.add(dis);
}
// if(rowkey.contains("F7FC08AE7C40BE3B")){
// System.out.println("lat:"+lat+"lng:"+lon+"time:"+ new Date(msgList.getGpsList().get(i).getTime()));
// }
}
//CellUtil.cloneRow(cell)+"|"+CellUtil.cloneFamily(cell) +"|"+CellUtil.cloneQualifier(cell) +"|"+CellUtil.cloneValue(cell)
}
}
Distance last_dis = new Distance();
if (list.size() > 0) {
Collections.sort(list, new DistanceCompartor());
for (int i = 0; i < list.size(); i++) {
//当i取到最后一个的时候就结束循环 否则会抛出异常
if (i == list.size() - 1) break;
//gps.get属性
double first_Lat = list.get(i).getLatitude();
double first_Lng = list.get(i).getLongitude();
double second_Lat = list.get(i + 1).getLatitude();
double second_Lng = list.get(i + 1).getLongitude();
distance = getDistance(first_Lat, first_Lng, second_Lat, second_Lng) + distance;
}
}
list.clear();
list.add(last_dis);
System.out.println("d:"+distance);
System.out.println("时间:" + DataUtils.byteArrayToLong(DataUtils.subBytes(key.get(), 19, 8)));
Put put = new Put(key.get());
put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("odo"), Bytes.toBytes(distance));
context.write(null, put);
}