最重要的两个函数是 excute() 和declareOutputFields(OutputFieldsDeclarer declarer)。
excute()将GPSReceiverSpout接受到的数据提取经度和纬度,调用Sects类 Sect.fetchSect(GPSrecord)方法,查询本地的地理信息数据库,返回该条GPS记录所在的区域标号 districtID,并将这个字段添加到GPS后面,发射给下一个bolt : countBolt。
declareOutputFields()告诉下一个countBolt , 这个DistrcitMatchingBolt的输出数据格式是:"viechleID", "dateTime", "occupied", "speed","bearing", "latitude", "longitude", "districtID"。
需要说明的是Sects类调用了开源的地理信息系统工具geotools,感兴趣的朋友可以去http://www.geotools.org/ 下载安装包,并将相关的jar包全部添加到Eclipse 的building path里面,就可以调用geotools查询本地的地理信息数据库了。
packagemain.java.realODMatrix.bolt;
importjava.io.IOException;
importjava.util.List;
importjava.util.Map;
importbacktype.storm.task.OutputCollector;
importbacktype.storm.task.TopologyContext;
importbacktype.storm.topology.IRichBolt;
importbacktype.storm.topology.OutputFieldsDeclarer;
importbacktype.storm.tuple.Fields;
importbacktype.storm.tuple.Values;
importbacktype.storm.tuple.Tuple;
importmain.java.realODMatrix.spout.FieldListenerSpout;
importmain.java.realODMatrix.struct.*;
publicclassDistrictMatchingBolt implementsIRichBolt{
privatestaticfinallong serialVersionUID=-433427751113113358L;
privateOutputCollector_collector;
IntegerdistrictID;
GPSRcrdrecord;
Map<<span style="margin: 0px; padding: 0px; border: 0px;">GPSRcrd,Integer>gpsMatch;//map
IntegertaskID;
Stringtaskname;
List<<span style="margin: 0px; padding: 0px; border: 0px;">Object>inputLine;
FieldsmatchBoltDeclare=null;
staticStringpath="/home/ghchen/sects/sects.shp";
staticSectssects=null;
int count=0;
@Override
publicvoid prepare(MapstormConf,TopologyContextcontext,
OutputCollectorcollector){
// TODO Auto-generated method stub
this._collector=collector;
this.taskID=context.getThisTaskId();
this.taskname=context.getThisComponentId();
}
@Override
publicvoid execute(Tupleinput){
try{
if(sects==null){
sects=newSects(path);
}
List<</span>Object>inputLine=input.getValues();//getFields();
FieldsinputLineFields=input.getFields();
record=newGPSRcrd(Double.parseDouble((String)inputLine.get(6)),
Double.parseDouble((String)inputLine.get(5)),Integer.parseInt((String)inputLine.get(3)),
Integer.parseInt((String)inputLine.get(4)));
if(Double.parseDouble((String)inputLine.get(6))>114.5692938||
Double.parseDouble((String)inputLine.get(6))<</span>113.740000||
Double.parseDouble((String)inputLine.get(5))>22.839945||
Double.parseDouble((String)inputLine.get(5))<</span>22.44
)return;
districtID=sects.fetchSect(record);
if(districtID!=-1)
{
System.out.println(count+++": GPS Point falls into Sect No. :" +districtID);
inputLine.add(Integer.toString(districtID));
//input.getFields().toList().add("districtID");
List<<span style="margin: 0px; padding: 0px; border: 0px;">String>fieldList=input.getFields().toList();
fieldList.add("districtID");
matchBoltDeclare=newFields(fieldList);
//FieldListenerSpout.writeToFile("/home/ghchen/output","matchBoltDeclare="+matchBoltDeclare);
String[]obToStrings=newString[inputLine.size()];
obToStrings=inputLine.toArray(obToStrings);
_collector.emit(newValues(obToStrings));
//_collector.emit(new Values(inputLine));
}
}catch(Exceptione){
e.printStackTrace();
}
_collector.ack(input);
}
@Override
publicvoid cleanup(){
// TODO Auto-generated method stub
System.out.println("-- District Mathchier ["+taskname+"-"+districtID+"] --");
for(Map.Entry<</span>GPSRcrd,Integer>entry:gpsMatch.entrySet()){
System.out.println(entry.getKey()+": "+entry.getValue());
}
}
@Override
publicvoid declareOutputFields(OutputFieldsDeclarerdeclarer){
declarer.declare(newFields("viechleID","dateTime","occupied","speed",
"bearing","latitude","longitude","districtID"));
}
@Override
publicMap<</span>String,Object>getComponentConfiguration(){
// TODO Auto-generated method stub
returnnull;
}
}
本文介绍的项目,我们基于storm开发了深圳市实时交通路况系统,源码已经在github上开源:
https://github.com/whughchen/RealTimeTraffic
https://github.com/whughchen/realODMatrix
欢迎关注 并 fork 加以改进~
---------
相关博文:
转载于:https://blog.51cto.com/3237526/1636874