说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

阿里巴巴技术专家杨晓明:基于Hadoop技术进行地理空间分析

HTML文档下载 WORD文档下载 PDF文档下载
将交通领域产生的海量车辆位置信息和道路进行关联的统计操作是颇为浩大的工作。本文将介绍一种通过使用地理网格进行数据关联,并利用Shuffle过程的二次排序实现高效的统计各条道路上位置点分布情况的方法。

【编者按】交通领域正产生着海量的车辆位置点数据。将这些车辆位置信息和道路进行关联的统计操作则是一项颇为浩大的工作,而随着Hadoop技术的成熟和普及,使得在海量数据中进行该统计运算的工作变得相对容易了很多。本文将介绍一种通过使用地理网格进行数据关联,并利用Shuffle过程的二次排序实现高效的统计各条道路上位置点分布情况的方法。


中华人民共和国交通运输部、中华人民共和国公安部、国家安全生产监督管理总局于2014年1月28日公布了《道路运输车辆动态监督管理办法》,在该文件中规定,自2014年7月1日起,国内道路运输车辆须安装卫星定位装置,未按照要求安装卫星定位装置,或者已安装卫星定位装置但未能在联网联控系统正常显示的车辆,不予发放或者审验《道路运输证》。

随着该文件规定的落实,必将会产生海量的车辆位置点数据。将这些车辆位置信息与地理信息相结合进行统计,则是相关技术行业中常见的统计分析的应用场景。而在这些统计中,将位置点和道路进行关联的统计操作则属于一种较为复杂的情况。将TB级的车辆位置数据按照道路进行区分,并统计每条道路上的位置点分布情况,需要涉及较复杂的地理空间算法,而且在数据的组织方式上也需要进行更为精巧的设计。在几年前云计算与大数据的技术尚未兴起的条件下,进行这样的操作将会是一项颇为浩大的工作,既需要考虑分布式并行计算,又需要对地理算法进行尽量高效的设计,还需要兼顾分布式情况下系统的健壮性和可靠性。

Hadoop技术的成熟和普及,使得在海量数据中进行统计运算的工作变得相对容易了很多。作为Apache软件基金会的开源分布式计算平台,Hadoop提供了分布式文件系统(HDFS)和分布式计算(MapReduce/Yarn)的基础框架支持。在海量数据的分析与处理领域,Hadoop以其高可靠性、高效性、高扩展性和高容错性等优势,可以使用户很容易的架构和使用分布式计算平台,可以简便的进行海量数据的存储和检索,能够轻松的开发和运行处理海量数据的应用程序。在很多IT领域,尤其是互联网行业,Hadoop被广泛应用于用户行为分析、数据挖掘与机器学习、网页抓取与分析、构建搜索引擎以及推荐广告等与大数据相关的应用之中。

由于Hadoop的MapReduce模型是基于Key/Value对的操作,因此在Key/Value对中如何设计地理数据和位置数据的关联关系将会成为一个可以使统计性能产生质变的关键点。通过合理的Key/Value设计和对MapReduce的Shuffle过程的优化,将会使统计操作的性能产生质的飞跃。以下将介绍一种通过使用地理网格进行数据关联,并利用Shuffle过程的二次排序实现高效的统计各条道路上位置点分布情况的方法。

计算某位置点是否位于某条道路上的一种相对简单的方式是获取道路的轮廓数据(以道路边界的经纬度点组成的多边形顶点经纬度信息)和位置数据的经纬度信息,然后将道路的轮廓坐标构建一个多边形,并通过判断车辆位置的经纬度坐标是否位于多边形的内部来判断车辆是否位于道路之上。在获取车辆和道路关系信息后,可以生成一个类似如下结构的二维表数据模型,进而进行分布状态的统计。


实现这种统计的一个技术关键点是如何判断一个点是否包含于一个多边形内部,如下图中,如何判断各圆点和多边形的包含关系。


在已知多边形各顶点坐标的情况下,判断任意一个点是否位于该多边形的内部的方法在各种开发语言中均有较多实现,下面以Java为例,简述两种常见的方法:

方法一:使用顶点坐标构建一个java.awt.Polygon对象,该对象具有一个contains(int x,int y)方法,通过将x和y两个方向的坐标作为该方法的参数进行调用,即可判断该点是否位于多边形内部。

方法二:使用第三方空间拓扑关系工具包JTS Topology Suite进行判断。该工具包中存在一个抽象类com.vividsolutions.jts.geom.Geometry。该抽象类作为JTS的几何元素对象的基类,具有一个contains(Geometry g)方法,该方法可以用于判断一个几何元素是否位于另一个几何元素内部。com.vividsolutions.jts.geom.Geometry有一个表示多边形的子类com.vividsolutions.jts.geom.Polygon和一个表示位置点的子类com.vividsolutions.jts.geom.Point。使用多边形顶点坐标和位置点坐标分别构建com.vividsolutions.jts.geom.Polygon和com.vividsolutions.jts.geom.Point对象,然后根据Polygon.contains(Point p)方法即可判断位置点是否位于多边形内部。

在路网数据和位置点数据量非常巨大的情况下,直接使用这两种方法统计道路-位置点的方法将会遭遇非常严重的性能问题,尤其在统计一个较长时间段内全国道路上位置点的分布情况时候。对于TB级的位置数据和数十GB的路网数据,进行空间关系的判断,如果使用单台服务器会涉及大量的磁盘分片读写,性能会非常底下,而如果使用分布式架构进行统计,网络通信,容错控制,任务管理等工作又会大大增加操作的难度。面对这样的问题,使用Hadoop进行统计操作,则会非常合适。

Hadoop的MapReduce编程模型是Hadoop体系的分布式并行计算框架。MapReduce编程模型假设用户需要处理的输入是一系列的key/value。在此基础上定义了两个函数Map和Reduce。业务逻辑的实现者则需要提供这两个函数的具体实现。

Map函数:输入是一系列Key/Value对(k1,v1),经过相应处理之后,Map函数将会产生中间结果Key/Value对(k2,v2)。MapReduce框架将会对中间结果按照Reduce进行分区/汇总/排序,然后调用Reduce函数。

Reduce函数:输入是经过分区/汇总/排序以后的中间结果(k2,list(v2)),输出则是最后的输出,可记为list(v3)。

MaprReduce的大致过程可以描述为:Map(k1,v1)→list(k2,v2);Reduce(k2,list(v2)) →list(v3)。

MapReduce确保每个reducer的输入都按键排序。系统执行排序的过程——将map输出作为输入传给reducer——称之为shuffle。常见的Shuffle操作包括PartitionerClass中的getPartition方法,SortComparatorClass中的compare方法和GroupingComparatorClass的compare方法。Shuffle的过程如下图所示,该过程对于MapReduce相当重要,适当的优化就可以对整个操作的性能产生质的飞跃。


使用Hadoop统计道路-位置点分布状态,主要的思路是将路网数据和位置点数据存储在HDFS的两个目录下,通过运行MapReduce程序,对路网数据和位置点数据执行Reduce端的join的操作,并在每个Reduce函数内进行路网和位置点的关系判断,生成位置点所属车辆的ID和道路ID以及位置点和时间的关系记录。使用生成的关系记录,再执行一次MapReduce的统计,就可以计算出某个时段内每条道路上车辆的分布状态。

这个操作的关键点是在路网数据和位置点数据进行join操作并判断路网和位置点关系的这个流程,通过采用地理网格进行join并在Shuffle阶段以二次排序的方式进行路网和位置点的预排序,经过二次排序后的相同网格内的数据,可以在Reducer方法中进行高效的空间关系判断。执行这一流程的步骤如下:

1.确定地理网格的划分方式

划分地理网格的目的是使不同的网格内的路网和位置点数据可以在Reduce中并行的执行。适当的划分地理网格的范围,可以使资源更加合理的调配,提高运行的效率。每个地理网格会被设定一个ID,这个网格ID将会成为路网数据和位置点数据执行join操作的依据。例如ID为11025_3810的网格表示东经110.25度到110.30度,北纬38.10度到38.15度之间的地理区间。

2.Map阶段

由于HDFS中路网数据目录和位置数据的目录都被设定为MapReduce的InputPath,因此在map阶段,路网数据文件和位置数据文件的每行都会成为map函数的value参数,通过对该行数据格式的判断,可以确定该行数据是路网数据或是位置数据。

如果是位置数据,则以该网格的ID和”:point”组成的字符串(如11025_3810:point)作为key,以经度、纬度、时间、车辆ID组成的字符串作为value,生成一组map输出的key/value对并执行map的输出。

如果是路线数据,则需要找到与该路线相交的所有地理网格,实现该操作的方法是判断路线外接矩形的四个顶点所位于的地理网格,然后遍历经纬度位于所有顶点网格之间的所有网格。对于每一个网格,都会输出一个Key/Value对,Key是网格ID和” :line“组成的字符串(如11025_3810:line),value是路线点序列和路线ID组成的字符串。

该过程的主要步骤大致如下:

public void map(LongWritable key, Text value, Context context) {    if (isLine(key)) {    String[] gridIds = chooseGridIds(key);        for (String gridId : gridIds) {                                    context.write(new Text(gridId + ":line"),lineValue(value));        }       } else {       String gridId = chooseGridId(key);                                context.write(new Text(greidId + ":point"), pointValue(value));                        }}

3.shuffle阶段

在Map执行阶段,输出记录的key的格式是网格ID+数据文件类型的组合,为了使具有相同网格ID的输出进入相同的Parition,需要对Partitioner的getPartition函数进行重写,将选择分区的方式修改成使用key字符串的网格ID的部分进行选择。Partition阶段之后,会在map端和reducer端分别根据SortComparatorClass中指定的compare规则进行排序。对于相同的网格ID,由于”line”字符串的字典排序在”point”字符串之前,而我们也希望排序的最终结果是数据量相对很小的路网数据排列在位置点的前面,因此compare函数制定的排序规则是v1.toString().compareTo(v2.toString())即可。排序阶段完成后,会根据GroupingComparatorClass中制定的排序规则,确定最后的Value序列在reduce函数中的排序。GroupingComparatorClass的compare函数会确定最终具有哪些key的value会出现在同一个reduce函数的参数列表中。根据业务规则,我们希望具有相同的网格ID的数据被排列到相同的reduce函数中,因此该compare函数需要从key中获取网格ID部分,然后根据字典顺序排序。

SortComparatorClass的compare方法为:

 public int compare(WritableComparable v1, WritableComparable v2) {    return v1.toString().compareTo(v2.toString()); }GroupingComparatorClass的getPartition方法为:public int getPartition(Text key, Text value, int num) {    return (key.toString().split(":")[0].hashCode() & Integer.MAX_VALUE) % num;}Groupcomparator的compare方法为:public int compare(WritableComparable v1, WritableComparable v2) {    return v1.toString().split(":")[0].compareTo(v2.toString().split(":")[0]);}

4.reduce阶段

Reducer中的reduce函数每次被调用的时候,函数的第一个参数是一个包含网格ID的key,第二个参数是该网格内所有位置点以及与该网格相交的所有路线的数据组成的一个Iterable。通过Shuffle过程的优化,在使用Iterable遍历数据时,所有路网数据都排列在位置点数据的前端。这样的排序方式,可以使判断网格内所有路网和位置点的空间关系的操作只需要遍历一次Iterable。当遍历完位于最前端的路网数据的时候,就可以将所有的路网数据保存在一个list中。遍历的下一步就是开始遍历所有位置点,每遍历一个位置点,都要与保存路网数据的list中的每条数据进行空间关系判断,计算位置点是否位于该路网上。

该过程的主要步骤大致如下:

public void reduce(Text key, Iterable<Text> values, Context context) {    List<Road> roadList = new ArrayList<Road>();    boolean isPoint = false;               for (Text v : values) {           if (!isPoint) {					                if (isLine(v)) {  			    Road road = initRoad(v);                lineList.add(road);            } else {                isPoint = true;                 //以下5行代码应归属到某个业务方法中Position pos = initPosition(v);for(Road  road: roadList){if (road.contains(pos)) {                        output(road,pos,context);                    }}            }        } else {            //以下5行代码应归属到某个业务方法中            Position pos = initPosition(v);            for (Road road : roadList) {                if (road.contains(pos)) {                    output(road,pos,context);                }            }        }     }}

在数据规模较大的场景下统计位置点和路网的空间关系,由于涉及到两类数据进行join操作并执行空间计算的工作,因此传统的基于单服务器地理信息系统运算的模式会遇到很严重的性能问题,当数据量超过一定规模后,传统的方式甚至无法执行空间数据统计的工作。基于Hadoop的MapReduce框架,采用以地理网格进行join的方式,通过二次排序排列地理类型,可以使统计操作的空间、时间复杂度或是编程的工作量都会大为降低,使原本非常复杂的工作变成可以在生产环境中被常规操作的工作。

采用上述方法进行地理空间分析,对于类似在一个较大地理范围内统计某个时段内车辆在各条道路上的分布情况这样的应用场景可以发挥有效的作用。这种应用场景对于分析全国交通流量状态,规划路网设计的工作都有非常重要的参考价值。而在Hadoop上,使用基于网格的join操作,几乎可以应用于各种数据规模庞大的地理统计分析之中。目前,在实验环境下进行统计测试,对于600G的车辆轨迹点数据和300M的路网数据,在由10台PC服务器组成的Hadoop集群中,完成车辆轨迹点在路网上的分布情况的统计,大约耗时5小时可以完成,而采用传统技术对于这种数据规模的轨迹点和路网数据进行空间分析,需要耗费数天的时间。在下一步的工作中,可以将这样的地理空间统计方法推广到性能更加优秀的Spark平台,在数据规模不是很大的情况下,这种方法对于实时计算各条道路上的车辆分布情况,预测交通流量,解决道路拥堵问题,将会发挥很有实际意义的效用。

作者:杨晓明,阿里巴巴技术专家,曾担任中交兴路系统架构师。2003年开始全职从事软件研发工作,2007年后一直担任架构师的工作。曾参与民航航空安全管理信息系统、民航总局运行管理中心、中国空中交通流量预测系统、交通部全国货运监管服务平台、雅迅车联网系统、浪淘金全媒体推荐引擎、位客网、分分网、简单网等包括政府平台、SNS系统及电子商务平台的开发和架构工作。长期关注新兴技术,目前主要研究可应用于交通领域的高并发、大数据及数据挖掘相关技术。

W3C启动Web支付标准工作,推进在线结算流程 W3C中国区会员沙龙在京召开 W3C CEO Jeff分享W3C未来发展重点 【SDCC讲师专访】车轮互联总架构师韩天峰:PHP是最好的编程语言 SDCC 2015讲师专访精彩集锦(一):你想知道的,都在这! (入门篇)带你走进Erlang 【大神来了】Elixir语言设计者Jos&#233; Valim:释放Erlang VM的能量 【SDCC 2015讲师专访】刘小溪:Vert.x3的异步框架实战 【CTO讲堂】支付接入开发的陷阱有多深? 程序员界“香饽饽”、大神级别人物集体亮相——SDCC 2015编程语言专场议题曝光 【CTO沙龙】CDN在共享经济下的创新应用 深入浅出Fetch API 带你入解应用场景及适用问题 SDCC 2015讲师专访精彩集锦(二):途牛网、饿了么、快的等大牛都来了 百度、饿了么、美团专家齐聚SDCC2015,剖析前端开发核心技术 【SDCC讲师专访】百度乔刚:前端可视化难点分析及探索实践 【CTO讲堂】Growth Hacking背后,数据分析平台的架构调整 BAT、巨杉、南大、柏睿等齐聚SDCC—新一代数据库专场议题曝光! 《近匠》BeeCloud创始人黄君贤:三行代码集成支付的技术实现 【SDCC讲师专访】AdMaster技术副总裁卢亿雷:分布式数据库挑战与分析 tvOS真的代表了应用的未来吗? 使用Fetch API和ES6生成器构建异步API Android应用性能优化实践 华云数据:OpenStack的技术践行之路 【SDCC讲师专访】腾讯潘安群:腾讯云金融级数据库TDSQL分析 高颜值、高品质——安全技术论坛议题曝光! 移动应用开发者正饱受折磨 在Android平台上加载本地库的危险性 《近匠》程序员客栈,程序员背后的经纪人 【CTO讲堂】浅析工业级物联网项目的快速开发 云适配陈本峰:平台型企业级浏览器是未来办公移动化的核心 警报:XcodeGhost已扩散至第三方框架 我们眼中的应用另一端是什么? 我要在wsda5.0下使用jdk1.4,怎么办? aspx页面滚动如何实现 第二届深圳Delphi爱好者聚会通知 我的InterBase7为何登录不了? 两个窗体问题,希望今晚能结贴。谢谢了!!! Microsoft.Web.UI.WebControls --- Treeview的应用(请大家帮帮忙) 请为一个界面问题 在9i中为什么提示这个表或视图不存在? 在线等…… 为何在邮箱定则中建了规则,还是收到满足该定则的垃圾邮件,急急! ASP如何调用进程外组件,在线等待,急!!! 帮个忙吧! html中 文本框失去焦点的事件 函数名是什么?? 谢谢 高分求助--关闭进程问题 关于在窗体上画线的问题。 大家讨论一下,做一个游戏修改器应该如何下手? 分不多,只是希望能解决问题!!!!还望各位帮助 一个简单的问题:无线网关是否要和无线网关配套? 问一个Swing做界面算是设计模式方面的问题,语言上应如何去实现 关于xslt的两个问题,各位高手帮忙。。。 怎样获得一个IP地址的整数值? 左连接(left join) 速度很慢,如何解决? “WGE”团队诚邀英才 访问这个页面试试看,能不能跟踪到文件的下载地址? 一个简单的问题 @Command([RefreshHideFormulas]) 有什么作用? 怎么找不到我的mapping 和formbean??? 菜鸟初学问题,两个表之间导入数据时候,一个表比另外一个表多一个字段的时候…… 我的软件在发布一周之后,终于有破解版了,悲喜交加中! 高分求教(大家看看下面的程序,尤其是编,解码部分,有什么问题) CSocket连接错误... 访问这个页面试试看,能不能跟踪到文件的下载地址? 在Javascript中嵌入Jsp问题 怎样在TcxGrid中实现类似TDBGrid的OnColExit的功能? 最近接私活累死了,哎,赚钱难呀,还是散分容易!! 求救高手,ie打印屏蔽ip 地址的问题 在sun Solaris下配置锅IBM MQ Client的高手请进... 怎样将%赋值给一个变量? 简单问题:如何获得一个文件的更新时间 特难问题!!求救。。。。 对于MyWebService.asmx中大家的用法 我想找thining in java第三版,中文版,且是CHM格式的,各位帮帮忙 请问往word文档写内容的API是什么? 螃蟹今天生日。再放分。来者有分 运行时提示"找不到文件msadomd.rll in c:\winnt\system32\resources\1033\"? 当前时间提交数据库问题 关于给水晶报表传递DataSet的问题 查找文件问题 急救:进制转换问题 怎么执行一个data.sql文件 我想开一个巨基础的问题,想邀请各路高手来讨论,是关于字符串的,不知道大家有没有兴趣! 蘑菇头怎么留长剪了蘑菇头··不想要这么短了··不知道怎么留长···求方法 理和天地万物是一种什么样的关系 一个2.5兆瓦的风力发电机每年需要维护的部件都有哪些呢?各种维护费用大概是多少钱? 重庆市垫江县有些什么村找人 去年6月1日我将800元钱存入银行,利息税为5%;今年6月1日到期时,我共取得本金和税后利息817.1元.定期存款一年的年利率是百分之几? 不饮浊泉水,不息曲木阴.什么意思 水积春塘晚,阴交夏木繁 至今有没有拍摄到黑洞的真实照片? 黑洞里面是什么,把摄像头扔进去去拍. Authentic & Innovative Japanese Cuisine at Attractive Prices兄弟们给点有价值的答案。不拿机器翻的出来忽悠人,俺就在国外,自己翻的就是太土了 怎样辨别红枣的好坏? 范佩西或因与主帅不和被雪藏 赛前对话高校生“共享”淫秽视频 “随手之举”南京科委坦言不完全排除靠关系申请科技江苏成人高考:医学类考生考试要查指纹首尔FC主场如临大敌 恒大球迷将占到土硬顶别买中国导弹警告 已用中方导弹金正恩出席朝军2万人连长大会 发表\中印携手,印媒欢呼并警惕美国情报机构“搞砸了”奥斯卡影后赞与查尔斯王子跳舞比“亲热朝或将第四次核试 美韩揣测朝“核冒险万花筒浅绛藏瓷专场拍卖四月举行51.2%受访者认为运动式校服“丑”沃尔沃建筑设备设计大赛收官故宫拟推年票制中澳加强海空力量搜寻MH370《一号目标》讲述国共谈判故事社会学家把脉教育:到底谁病了?“他是俺们村的好党!”团中央举办学习习近平总书记系列重要讲国扶贫困县重金延揽师范生天印地痕网游之御剑无双御龙乘风记极剑游隐鸾歌官路十三级血之镰不灭神皇皇道帝业四公子传奇东方根源录小野柳旅游关山风景区旅游受镇宫旅游三代木旅游姐妹潭旅游燕翔洞旅游遂昌金矿国家矿山公园旅游中国竹炭博物馆旅游千佛山景区旅游南尖岩旅游梅源梯田旅游
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘