交给大地算法Topology

By admin in 天文台 on 2019年2月26日

整个世界算法简介

  • 连带概念

地轴:即为地球斜轴,又称地球自转轴。是指地球自转所绕的轴,北端与地球表面的交点是北极,南端与地球表面的交点是南极
赤道:地表包车型地铁点处处球自转发生的轨道中周长最长的圆周线,赤道半径6,378.137km。
纬度:纬度是指某点与地球球心的连线和地球赤道面所成的线面角,其数值在0至90度之间。位于赤道以北的点的纬度叫北纬,记为N,位于赤道以南的点的纬度称南纬,记为S。
经度:一般指球面坐标系的纵坐标,具体来说正是地球上一个地点离一根被称作本初子午线的南北方向走线以东或以西的度数。
本初子午线:即0度经线,亦称格林威治子午线或格林尼治子午线,是位于U.K.格林尼治天文台的一条经线(亦称子午线)。本初子午线的东西两边分别定为东经和西经,于180度相遇。

  • 满世界算法:
    在事实上行使中,大家总括3个任务的相距,经常做法便是取得一个地方基本处的经纬度,然后依据经纬度总括它们中间地球表面弧线距离。总括地球表面弧线距离的点子即称为满世界算法。

  • 算法推导

图片 1

全世界算法

如图所示,大家总括A点和B点之间的弧线距离,因此大家的对象要博取OA、OB之间的夹角,记为C。
设第贰点A的经 纬度为(jA, wA),第2点B的中纬度为(jB,
wB),依照0度经线的原则,东经取经度的正在(Longitude),西经取经度负值(-Longitude),北纬取90-纬度值(90-
Latitude),南纬取90+纬度值(90+Latitude),则通过上述处理现在的两点被计为(MLonA,
MLatA)和(MLonB,
MLatB)。那么依照三角推导,可以博得总结两点离开的如下公式:

C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)
Distance = R*Arccos(C)*Pi/180

一旦仅对经度作正负的处理,而不对纬度作90-Latitude(假使都是北半球,南半球唯有澳大汉诺威(Australia)颇具应用意义)的拍卖,那么公式将是:

C = sin(wA)*sin(wB) + cos(wA)*cos(wB)*cos(jA-jB)
Distance = R*Arccos(C)*Pi/180

本着那种景观,可以不难演示下推导进度:

图片 2

演绎进度

  • Java实现

  public static double Distance(Location loc1, Location loc2) {
    double a, b, R;
    R = 6378137; // 地球半径,单位:米
    double lat1 = loc1.latitude;
    double long1 = loc1.longitude;
    double lat2 = loc2.latitude;
    double long2 = loc2.longitude;

    a = (lat1 - lat2) * Math.PI / 180.0;
    b = (long1 - long2) * Math.PI / 180.0;

    double d;
    double sa2, sb2;
    sa2 = Math.sin(a / 2.0);
    sb2 = Math.sin(b / 2.0);
    d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));

    return d;
}

Spout/Bolt编程

大家的对象是本地不断的肆意生成3个坐标点,然后总括这一个点到3个原则性地方的偏离。

  • Location类
    率先,为了书写方便,大家先创建3个Location的Class。

public class Location {
    public double longitude;
    public double latitude;

    public Location(double lon, double lat) {
        this.longitude = lon;
        this.latitude = lat;
    }

    public String locationInfo() {
        String info = "location:( " + longitude + "," + latitude + " ) ";
        return info;
    }
}
  • RandomLocationSpout类
    开创RandomLocationSpout类,继承BaseRichSpout,一视同仁写基类的大旨措施。

public class RandomLocationSpout extends BaseRichSpout {

    SpoutOutputCollector spoutOutputCollector;

    @Override
    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
        // TODO Auto-generated method stub
        spoutOutputCollector = collector;
    }

    @Override
    public void nextTuple() {
        // TODO Auto-generated method stub

        double lat = 39 + (Math.random()*2);
        double lon = 116 + Math.random();

        String loc = lon + "," + lat;

        spoutOutputCollector.emit(new Values(loc));
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        // TODO Auto-generated method stub
         declarer.declare(new Fields("spout"));
    }

}

nextTuple()措施中,大家随便生成三个纬度在北纬39度-41度之间,经度在东京(Tokyo)116度-117度之间的一个坐标,然后将该坐标发射出来。

  • CalculateDistantBolt类
    创办CalculateDistantBolt类,不分轩轾写IRichBolt接口的连带方法

public class CalculateDistantBolt implements IRichBolt {
    private OutputCollector outputCollector;

    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
        // TODO Auto-generated method stub
        outputCollector = collector;
    }

    public void execute(Tuple input) {
        // TODO Auto-generated method stub
        String loc = input.getString(0);
        String[] s1 = loc.split(",");

        Location location = new Location(Double.parseDouble(s1[0]), Double.parseDouble(s1[1]));
        Location center = new Location(116.360664, 40.007614);

        double d = Distance(location, center);
        System.out.println("************\\n" +location.locationInfo() + "between" + center.locationInfo() + ":\\n" + "Distant: " + d +"\\n ***********");
    }

    public void cleanup() {
        // TODO Auto-generated method stub

    }

    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        // TODO Auto-generated method stub

    }

    public Map<String, Object> getComponentConfiguration() {
        // TODO Auto-generated method stub
        return null;
    }

    public static double Distance(Location loc1, Location loc2) {
        double a, b, R;
        R = 6378137; // 地球半径
        double lat1 = loc1.latitude;
        double long1 = loc1.longitude;
        double lat2 = loc2.latitude;
        double long2 = loc2.longitude;

        a = (lat1 - lat2) * Math.PI / 180.0;
        b = (long1 - long2) * Math.PI / 180.0;

        double d;
        double sa2, sb2;
        sa2 = Math.sin(a / 2.0);
        sb2 = Math.sin(b / 2.0);
        d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2));

        return d;
    }
}

execute(Tuple input)方法中,大家获得Spout发射的坐标点,并盘算该点到如今职责的地球表面距离(实例中center是自笔者当下的地点)。**
打印输出总计结果**。

  • DistantTopology类
    末尾是创办运营主类DistantTopology,实行拓扑创设。在main艺术中设置好Spout和Bolt,然后Topology任务交给到Storm上。

public class DistantTopology {

    private static TopologyBuilder builder = new TopologyBuilder();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Config config = new Config();

            builder.setSpout("RandomLocationSpout", new RandomLocationSpout(), 2);
            builder.setBolt("CalculateDistantBolt", new CalculateDistantBolt(), 2).shuffleGrouping(
                    "RandomLocationSpout");

            config.setDebug(true);

            //通过是否有参数来控制是否启动集群,或者本地模式执行
            if (args != null && args.length > 0) {
                try {
                    config.setNumWorkers(1);
                    StormSubmitter.submitTopology(args[0], config,
                            builder.createTopology());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                config.setMaxTaskParallelism(1);
                LocalCluster cluster = new LocalCluster();
                cluster.submitTopology("wordcount", config, builder.createTopology());
            }
    }

}

提交Topology任务

  • 使用mvn命令将工程打成jar包
  • 上传jar包到集群的主机上
  • 主机上,终端履行storm jar命令,提交Topology任务
  • 付出成功后,在对应节点上查看worker日志

1041937 [Thread-8-RandomLocationSpout] INFO  backtype.storm.daemon.task - Emitting: RandomLocationSpout default [116.61777982507657,39.25343303306309]
1041937 [Thread-14-CalculateDistantBolt] INFO  backtype.storm.daemon.executor - Processing received message source: RandomLocationSpout:2, stream: default, id: {}, [116.72828785729372,39.204690956457334]
************
location:( 116.72828785729372,39.204690956457334 ) betweenlocation:( 116.360664,40.007614 ) :
Distant: 88969.36622189148
 ***********
1041937 [Thread-8-RandomLocationSpout] INFO  backtype.storm.daemon.task - Emitting: RandomLocationSpout default [116.03394550808655,40.8784387953902]
1041937 [Thread-14-CalculateDistantBolt] INFO  backtype.storm.daemon.executor - Processing received message source: RandomLocationSpout:2, stream: default, id: {}, [116.87086610893954,40.505468257874966]
************
location:( 116.87086610893954,40.505468257874966 ) betweenlocation:( 116.360664,40.007614 ) :
Distant: 71556.36956545932
 ***********

日志中会不断刷新总括距离,职分交给成功。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 亚洲必赢手机官网 版权所有