最重要的两个函数是 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查询本地的地理信息数据库了。


 

  1.  



  2. 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 加以改进~

---------


相关博文:

   storm实战:深圳市实时路况分析和实时路径推荐系统


storm单机版和集群版安装配置过程 


使用Storm实现实时大数据分析实例


storm的开发环境部署配置教程 


基于storm的实时GPS数据客流特征分析系统 源码分析之(一)