大数据实战学习笔记 03
应用场景案例--海量地标定位酒店周边建筑
1. 案例场景假设条件:
60km*60km大小的城镇
2000*1001个地理坐标
其中有2000个是酒店
实验要求:
列出每个酒店1km范围内所有地标
图 1 题目图示
2. 案例实现分析2.1 数据资源:
图 2 原始数据格式
如上图所示,每一行数据分为四个字段,分别为地标标志、编号、x轴和y轴坐标。其中,地标标志为"0"表示该建筑是酒店,为"1"表示是其他建筑;地标编号是唯一的;x、y轴的数据是由经纬度转化而来,单位是米。
图 3 需要处理的数据范围
2.2.2将范围内坐标数据除以要求的半径(1km)并取整进行降维处理,使得降维后的坐标都落在下图四个小正方形的九个顶点上。图 4 降维示意
图 5 冗余酒店地标
2.2.3冗余酒店坐标:将酒店原始数据复制8份,按照除中心外的小正方形的8个顶点位置设置降维后的坐标。2.2.4处理要求范围外的数据:可以通过计算其与酒店的距离来判断是否属于要求的范围。
2.3 代码设计:
思路:建立hotel实例存储原始数据以及降维后的坐标信息,使用两个mapreduce文件实现目标。第一个mapreduce将hotel实例作为key输出,value为NullWritable,并为每个酒店冗余8个数据;通过partitioner把酒店地标数据重新划分到不同的reduce;分组排序中将酒店排在其他建筑之前;进行reducer计算,输出信息为酒店编号、1km范围内建筑编号以及两者实际距离。第二个mapreduce以第一个mapreduce的输出作为输入,将相同编号的酒店数据进行聚合,输出为酒店编号以及1km范围内建筑的编号。
3 案例实现3.1 创建Java Project: HotelLM
图 6 新建HotelLM项目
图 7添加External JARs
3.3删除src并重建source folder避免冲突。3.4 新建com.jkb.jddw package,并在其下创建CreateData、HotelMR及MR2三个类。
public class CreateData {
public static void main(String[] args) throws IOException {
int len = 60000; //范围60km*60km大小的城镇
int hotel = 2000; //2000家酒店
int LM = 1000; //为每个酒店周围创建1000个地理坐标
Random ran = new Random();
int type = 0;
String hdfs_path = "/examples/HotelLM/input/hotel";//输入数据存放的hdfs目录
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://localhost:54310");//根据hadoop name的url设置
FileSystem fs = FileSystem.get(conf);
OutputStream out = fs.create(new Path(hdfs_path));
//创建数据
for(int i = 0 ; i < hotel ; i++){
//酒店坐标
int hx = ran.nextInt(len);
int hy = ran.nextInt(len);
type = 0; //酒店
StringBuilder str = new StringBuilder();
str.append(type);//类型
str.append("\t");
str.append(i * 2000);//编号,保证每个建筑都不重复
str.append("\t");
str.append(hx); //横坐标
str.append("\t");
str.append(hy);
str.append("\r\n");//纵坐标
type = 1;//其他建筑
for(int k = 0 ; k < LM ; k++){
int lmx = ran.nextInt(len);
int lmy = ran.nextInt(len);
str.append(type);
str.append("\t");
str.append(i * 2000 + k + 1);//编号
str.append("\t");
str.append(lmx); //横坐标
str.append("\t");
str.append(lmy);//纵坐标
str.append("\r\n");
}
byte[] data = (str.toString()).getBytes("UTF8");
out.write(data);
System.out.println(i * 1000);
}
out.close();
fs.close();
}
}
图 8 创建实验数据
图 9 在浏览器查看输入数据