`
jianFengGong
  • 浏览: 20481 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基站定位

    博客分类:
  • JAVA
 
阅读更多

在一些项目中,可能会使用到不同的定位,如gps、基站、WiFi定位等。通过调用方法并传入3个基站的数据,则返回定位点的大体经纬度坐标,当然与实际位置坐标还是存在偏差的,小的话可能几十米,大的可能4、5百米。当然也可以付费调用其他定位接口,如图吧等。

 

//基站数据model
public class BaseStationModel {
    
    @Key
    private Long id;
    private String mcc;
    private Long mnc;
    private String lac;
    private String cell;
    private String lng;
    private String lat;
    private String b_lng;
    private String b_lat;
    private String precision;
    private String address;
    
    public BaseStationModel() {
        super();
    }

    /**
     * @return 获  得 id
     */
    public Long getId() {
        return id;
    }

    /**
     * @param id 设置 id
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @return 获得 mcc
     */
    public String getMcc() {
        return mcc;
    }

    /**
     * @param mcc 设置 mcc
     */
    public void setMcc(String mcc) {
        this.mcc = mcc;
    }

    /**
     * @return 获得 mnc
     */
    public Long getMnc() {
        return mnc;
    }

    /**
     * @param mnc 设置 mnc
     */
    public void setMnc(Long mnc) {
        this.mnc = mnc;
    }

    /**
     * @return 获得 lac
     */
    public String getLac() {
        return lac;
    }

    /**
     * @param lac 设置 lac
     */
    public void setLac(String lac) {
        this.lac = lac;
    }

    /**
     * @return 获得 cell
     */
    public String getCell() {
        return cell;
    }

    /**
     * @param cell 设置 cell
     */
    public void setCell(String cell) {
        this.cell = cell;
    }

    /**
     * @return 获得 lng
     */
    public String getLng() {
        return lng;
    }

    /**
     * @param lng 设置 lng
     */
    public void setLng(String lng) {
        this.lng = lng;
    }

    /**
     * @return 获得 lat
     */
    public String getLat() {
        return lat;
    }

    /**
     * @param lat 设置 lat
     */
    public void setLat(String lat) {
        this.lat = lat;
    }

    /**
     * @return 获得 b_lng
     */
    public String getB_lng() {
        return b_lng;
    }

    /**
     * @param b_lng 设置 b_lng
     */
    public void setB_lng(String b_lng) {
        this.b_lng = b_lng;
    }

    /**
     * @return 获得 b_lat
     */
    public String getB_lat() {
        return b_lat;
    }

    /**
     * @param b_lat 设置 b_lat
     */
    public void setB_lat(String b_lat) {
        this.b_lat = b_lat;
    }

    /**
     * @return 获得 precision
     */
    public String getPrecision() {
        return precision;
    }

    /**
     * @param precision 设置 precision
     */
    public void setPrecision(String precision) {
        this.precision = precision;
    }

    /**
     * @return 获得 address
     */
    public String getAddress() {
        return address;
    }

    /**
     * @param address 设置 address
     */
    public void setAddress(String address) {
        this.address = address;
    }
}//经纬度转平面坐标model
public class PlaneCoordinate {

    private double x;  //lng
    private double y;  //lat
    
     /**
     */
    public PlaneCoordinate() {
        super();
    }
    /**
     * @param x
     * @param y
     */
    public PlaneCoordinate(double x, double y) {
        super();
        this.x = x;
        this.y = y;
    }
    /**
     * @return 获得 x
     */
    public double getX() {
        return x;
    }
    /**
     * @param x 设置 x
     */
    public void setX(double x) {
        this.x = x;
    }
    /**
     * @return 获得 y
     */
    public double getY() {
        return y;
    }
    /**
     * @param y 设置 y
     */
    public void setY(double y) {
        this.y = y;
    }
    
    
}
//经纬度model
public class Point {
    double longitude;
    double latitude;
    
     
     /**
     */
    public Point() {
        super();
    }

    /**
     * @param longitude
     * @param latitude
     */
    public Point(double longitude, double latitude) {
        super();
        this.longitude = longitude;
        this.latitude = latitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public double getLatitude() {
        return latitude;
    }
}
//基站定位实现类
public class BaseStationPosition {
    
    public static double latDis1 = 111;    //纬度1度大约相差111Km
    private final static double EARTH_RADIUS = 6378137.0;   
    
    public static final double pi = 3.1415926535898; 
    public static final double X0 = 8;
    public static final double K = 3;//98899
    public static final double iPI = pi/180.0;
    public static final double a=6378137.0;//WGS84:版本长半轴
    public static final double f=1/298.257223563;//WGS84:版本扁率
    public static final int ZoneWide = 6; ////带宽
    
     /**
     *  @Title: getDistance 
     *  @Description: 根据rssi计算出与基站距离 KM
     *  @author jf.gong  DateTime 2014年5月19日 下午2:50:50
     *  @return double 
     *  @param rssiVal
     *  @return
     */
    public static double getDistance(double rssiVal){
        /*
         * RSSI=发射功率(Pt)+天线增益(Pf)一路径损耗(PL(d))
            说是根据该公式可以推算出距离与 RSSI 的关系公式: 
            D = 10^((Pt+Pf-RSSI-PL(d0)-X0)/(10*K))
            
            
            
         * */
        
//        return (10*((195-rssiVal)/(10 * K)))*0.001;
//        return (rssiVal+X0)*K*0.001;
//        return Math.pow(10,(-rssiVal-97.5239)/(38));
        return Math.pow(10,(Math.abs(rssiVal)-60)/(10*K))*0.001;
    }
    
    
     /**
     *  @Title: getWantDouble 
     *  @Description: double保留指定小数位
     *  @author jf.gong  DateTime 2014年5月19日 下午7:48:42
     *  @return double 
     *  @param val
     *  @param unit
     *  @return
     */
    public static double getWantDouble(double val,int unit){
           
            BigDecimal bg = new BigDecimal(val);
            double re_value = bg.setScale(unit, BigDecimal.ROUND_HALF_UP).doubleValue();
            return re_value;
        }
    
     /**
     *  @Title: distance 
     *  @Description: 两坐标距离计算
     *  @author jf.gong  DateTime 2014年5月30日 下午3:40:34
     *  @return double 
     *  @param lat_a
     *  @param lng_a
     *  @param lat_b
     *  @param lng_b
     *  @return
     */
    public static double distance(double lat_a, double lng_a, double lat_b, double lng_b) {  
           double radLat1 = (lat_a * Math.PI / 180.0);  
           double radLat2 = (lat_b * Math.PI / 180.0);  
           double a = radLat1 - radLat2;  
           double b = (lng_a - lng_b) * Math.PI / 180.0;  
           double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)  
                  + Math.cos(radLat1) * Math.cos(radLat2)  
                  * Math.pow(Math.sin(b / 2), 2)));  
           s = s * EARTH_RADIUS;  
           s = Math.round(s * 10000) / 10000;  
           return s;  
        } 

 /**
 *  @Title: getPlanCoordinate 
 *  @Description: 由经纬度反算成高斯投影坐标
 *  @author jf.gong  DateTime 2014年5月30日 下午3:39:06
 *  @return PlaneCoordinate 
 *  @param longitude
 *  @param latitude
 *  @return
 */
public PlaneCoordinate getPlanCoordinate(double longitude, double latitude){
    int ProjNo=0;
    double longitude1,latitude1, longitude0, X0,Y0, xval,yval;
    double e2,ee, NN, T,C,A, M;
    
    ProjNo = (int)(longitude / ZoneWide) ;
    longitude0 = ProjNo * ZoneWide + ZoneWide / 2;
    longitude0 = longitude0 * iPI ;
    longitude1 = longitude * iPI ; //经度转换为弧度
    latitude1 = latitude * iPI ; //纬度转换为弧度
    e2=2*f-f*f;
    ee=e2*(1.0-e2);
    NN=a/Math.sqrt(1.0-e2*Math.sin(latitude1)*Math.sin(latitude1));
    T=Math.tan(latitude1)*Math.tan(latitude1);
    C=ee*Math.cos(latitude1)*Math.cos(latitude1);
    A=(longitude1-longitude0)*Math.cos(latitude1);
    M=a*((1-e2/4-3*e2*e2/64-5*e2*e2*e2/256)*latitude1-(3*e2/8+3*e2*e2/32+45*e2*e2
            *e2/1024)*Math.sin(2*latitude1)
            +(15*e2*e2/256+45*e2*e2*e2/1024)*Math.sin(4*latitude1)-(35*e2*e2*e2/3072)*Math.sin(6*latitude1));
    xval = NN*(A+(1-T+C)*A*A*A/6+(5-18*T+T*T+72*C-58*ee)*A*A*A*A*A/120);
    yval = M+NN*Math.tan(latitude1)*(A*A/2+(5-T+9*C+4*C*C)*A*A*A*A/24
            +(61-58*T+T*T+600*C-330*ee)*A*A*A*A*A*A/720);
    X0 = 1000000L*(ProjNo+1)+500000L;
    Y0 = 0;
    xval = xval+X0; 
    yval = yval+Y0;
    
    return new PlaneCoordinate(xval,yval);

}

 /**
 *  @Title: GaussToBL 
 *  @Description: 由高斯投影坐标反算成经纬度
 *  @author jf.gong  DateTime 2014年5月30日 下午3:36:28
 *  @return Point 
 *  @param X
 *  @param Y
 *  @return
 */
public Point getLngLat(double X, double Y){
  int ProjNo;
  double longitude1,latitude1, longitude0, X0,Y0, xval,yval;//latitude0,
  double e1,e2, ee, NN, T,C, M, D,R,u,fai;
  
  ProjNo = (int)(X/1000000L) ; //查找带号
  longitude0 = (ProjNo-1) * ZoneWide + ZoneWide / 2;
  longitude0 = longitude0 * iPI ; //中央经线
  X0 = ProjNo*1000000L+500000L;
  Y0 = 0;
  xval = X-X0;
  yval = Y-Y0; //带内大地坐标
  e2 = 2*f-f*f;
  e1 = (1.0-Math.sqrt(1-e2))/(1.0+Math.sqrt(1-e2));
  ee = e2/(1-e2);
  M = yval;
  u = M/(a*(1-e2/4-3*e2*e2/64-5*e2*e2*e2/256));
  fai = u+(3*e1/2-27*e1*e1*e1/32)*Math.sin(2*u)+(21*e1*e1/16-55*e1*e1*e1*e1/32)*Math.sin(
          4*u)+(151*e1*e1*e1/96)*Math.sin(6*u)+(1097*e1*e1*e1*e1/512)*Math.sin(8*u);
  C = ee*Math.cos(fai)*Math.cos(fai);
  T = Math.tan(fai)*Math.tan(fai);
  NN = a/Math.sqrt(1.0-e2*Math.sin(fai)*Math.sin(fai));
  R = a*(1-e2)/Math.sqrt((1-e2*Math.sin(fai)*Math.sin(fai))*(1-e2*Math.sin(fai)*Math.sin(fai))*(1-e2*Math.sin
          (fai)*Math.sin(fai)));
  D = xval/NN;
  //计算经度(Longitude) 纬度(Latitude)
  longitude1 = longitude0+(D-(1+2*T+C)*D*D*D/6+(5-2*C+28*T-3*C*C+8*ee+24*T*T)*D  //
          *D*D*D*D/120)/Math.cos(fai);
  latitude1 = fai -(NN*Math.tan(fai)/R)*(D*D/2-(5+3*T+10*C-4*C*C-9*ee)*D*D*D*D/24  //
          +(61+90*T+298*C+45*T*T-256*ee-3*C*C)*D*D*D*D*D*D/720);
  
  return new Point(getWantDouble(longitude1/iPI,6), getWantDouble(latitude1/iPI,6));
}


 /**
 *  @Title: getTargetCoordinate 
 *  @Description: lbs基站定位
 *  @author jf.gong  DateTime 2014年5月30日 下午3:41:59
 *  @return Point 
 *  @param cellId
 *  @return
 */
public Point getTargetCoordinate(String cellId){
    String []cellIdArr = cellId.split("\\|");
    Point point = new Point();
    if(cellIdArr.length >= 4){
        String []mccMncArr =  cellIdArr[0].split(":");
        List<BaseStationModel> baseList = new ArrayList<BaseStationModel>();
        Map<Long,Double> disMap = new HashMap<Long, Double>();
        //获取数据库基站model数据,取前三个信号最强的基站
        for (int i = 1; i < cellIdArr.length; i++) {
            String []baseArr = cellIdArr[i].split(":");
             BaseStationModel baseModel = (BaseStationModel) JdbcUtils.getInstance().getModel(" MCC='"+mccMncArr[0]+"'"
                    + "  AND MNC="+ Long.parseLong(mccMncArr[1])+" AND LAC='"+baseArr[0]+"' AND CELL='"+baseArr[1]+"'",new BaseStationModel());
            if(null != baseModel){
                baseList.add(baseModel);
                disMap.put(baseModel.getId(), getDistance(Double.parseDouble(baseArr[2])));
            }
        }
        if(baseList.size() >= 3){
            PlaneCoordinate plance1 = getPlanCoordinate(Double.parseDouble(baseList.get(0).getLng()),Double.parseDouble(baseList.get(0).getLat()));
            PlaneCoordinate plance2 = getPlanCoordinate(Double.parseDouble(baseList.get(1).getLng()),Double.parseDouble(baseList.get(1).getLat()));
            PlaneCoordinate plance3 = getPlanCoordinate(Double.parseDouble(baseList.get(2).getLng()),Double.parseDouble(baseList.get(2).getLat()));
            //根据信号强度得到与基站距离
            double da = disMap.get(baseList.get(0).getId());
            double db = disMap.get(baseList.get(1).getId());
            double dc = disMap.get(baseList.get(2).getId());
//            //三角质心原理求坐标
//            double y1 = (db*db-dc*dc-plance2.getX()*plance2.getX()+plance3.getX()*plance3.getX()-plance2.getY()*plance2.getY()+plance3.getY()*plance3.getY())*(plance1.getX()-plance2.getX());
//            double y2 =(da*da-db*db-plance1.getX()*plance1.getX()+plance2.getX()*plance2.getX()-plance1.getY()*plance1.getY()+plance2.getY()*plance2.getY())*(plance2.getX()-plance3.getX());
//            double y3 = 2*((plance2.getX()-plance3.getX())*(plance1.getY()-plance2.getY())-(plance1.getX()-plance2.getX())*(plance2.getY()-plance3.getY()));
//            double y = (y1 - y2)/y3;
//            double x1 = da*da-db*db-plance1.getX()*plance1.getX()+plance2.getX()*plance2.getX()-plance1.getY()*plance1.getY()+plance2.getY()*plance2.getY()+2*y*plance1.getY()-2*y*plance2.getY();
//            double x2 = (-2)*(plance1.getX()-plance2.getX());
//            double x = x1/x2;
            
//             // 外切圆圆心
            double x1 = plance1.getX();
            double x2 = plance2.getX();
            double x3 = plance3.getX();
            double y1 = plance1.getY();
            double y2 = plance2.getY();
            double y3 = plance3.getY();
//            double x = ((y2 - y1) * (y3 * y3 - y1 * y1 + x3 * x3 - x1 * x1) - (y3 - y1)
//                        * (y2 * y2 - y1 * y1 + x2 * x2 - x1 * x1))
//                        / (2 * (x3 - x1) * (y2 - y1) - 2 * ((x2 - x1) * (y3 - y1)));
//
//            double y = ((x2 - x1) * (x3 * x3 - x1 * x1 + y3 * y3 - y1 * y1) - (x3 - x1)
//                        * (x2 * x2 - x1 * x1 + y2 * y2 - y1 * y1))
//                        / (2 * (y3 - y1) * (x2 - x1) - 2 * ((y2 - y1) * (x3 - x1)));
            
         // 内切圆圆心
            double d23 = distenceOfPoints(plance2, plance3);
            double d31 = distenceOfPoints(plance3, plance1);
            double d12 = distenceOfPoints(plance1, plance2);
            double sumd = d23+d31+d12;
            double x = (x1 * d23 + x2 * d31 + x3 * d12) / sumd;

            double y = (y1 * d23 + y2 * d31 + y3 * d12) / sumd;
            double d1 = distenceOfPoints(new PlaneCoordinate(x, y), plance2);    
            //计算gps坐标
            point = getLngLat(x,y);
        }
    }
    return point;
}

// 两点之间的距离

public static double distenceOfPoints(PlaneCoordinate plance1, PlaneCoordinate plance2) {

    return Math.sqrt((plance1.getX()- plance2.getX()) * (plance1.getX()- plance2.getX()) + (plance1.getY() - plance2.getY()) * (plance1.getY() - plance2.getY()));

}

 /**
 *  @Title: combination 
 *  @Description: Java实现排列组合去重复
 *  @author jf.gong  DateTime 2014年5月30日 下午6:52:20
 *  @return void 
 */
public static void combination(){
      int data[] = {1,2,3,4,5,6,7};
      f_1(data);
     }
     private static void f_1(int data[]) {
      for(int i=0;i<=2;i++) {
       for(int j=i+1;j<=3;j++) {
           //k<= length-1
        for(int k=j+1;k<=6;k++) {
            System.out.println(data[i]+" "+data[j]+" "+data[k]);
        }
       }
      }
     }
    




 /**
 *  @Title: main 
 *  @Description: TODO
 *  @author jf.gong  DateTime 2014年6月6日 下午2:29:11
 *  @return void 
 *  @param args
 */
public static void main(String[] args) {
    for (int i = 16289; i < 16439; i++) {
        BaseStationPosition stationPosition = new BaseStationPosition();
        T3 t3 = (T3) JdbcUtils.getInstance().getModel(" id="+i,new T3());
        Point point = stationPosition.getTargetCoordinate(t3.getCell_id());
        double s = distance(point.latitude,point.longitude,Double.parseDouble(t3.getLat()),Double.parseDouble(t3.getLng()));
//        if(s > 800){
            System.err.println(t3.getLat() +"," + t3.getLng());
            System.err.println(point.latitude + "," + point.longitude+ "---  distance:"+s + "--" + i);
//        }
        
        
    }
//    combination();
    //double lat_a, double lng_a, double lat_b, double lng_b
//    System.err.println(distance(31.294607,121.337825,31.2887316,121.3428055));
//    System.err.println(getDistance(-54));
    
    
//    BaseStationPosition stationPosition = new BaseStationPosition();
//    PlaneCoordinate coordinate = stationPosition.getPlanCoordinate(121.337825, 31.294607);
//    System.err.println(coordinate.getX()+","+coordinate.getY());
//    Point point = stationPosition.getLngLat(coordinate.getX(), coordinate.getY());
//    
//    System.err.println(point.getLatitude()+"," + point.getLongitude());
    
}

}
 

 

0
0
分享到:
评论
1 楼 lehehe 2014-08-25  
http://www.haoservice.com/apilist/  对的,有好多接口,在这个网站里基站定位,wifi定位,ip定位等等都有,挺全面的.

相关推荐

    移远QueLocator2基站定位服务介绍

    这项服务支持基站定位和Wi-Fi定位,为用户提供便捷、可靠、安全和精准的定位功能。 ### QuecLocator介绍 QuecLocator服务能够覆盖各种场景,包括基站定位和Wi-Fi定位,并且在新版本中加入了混合定位技术,即结合...

    GSM蜂窝基站定位基本原理

    "GSM蜂窝基站定位基本原理" GSM蜂窝基站定位是一种基于蜂窝网络的定位技术,通过蜂窝基站来确定移动设备的位置。该技术的实现基于GSM网络的基础结构,即由一系列的蜂窝基站构成的网络,这些蜂窝基站把整个通信区域...

    基于基站定位数据的商圈分析Python源码.rar

    标题中的“基于基站定位数据的商圈分析Python源码”表明这是一个使用Python编程语言进行的项目,专注于通过基站定位数据来研究商业区的人流分布、活动模式以及潜在的商业价值。基站定位数据通常由移动运营商提供,它...

    android 基站定位程序

    在Android平台上,基站定位是一种基于移动通信网络的定位技术,主要利用手机与周围基站之间的信号交互来确定设备的位置。此技术对于那些GPS信号无法获取或者信号弱的环境(如室内)尤其有用。以下是对"android 基站...

    android基于Gps 定位和基站定位获取经纬度

    在Android平台上,获取设备位置信息是一项关键功能,通常可以通过GPS(全球定位系统)和基站定位两种方式实现。本文将深入探讨这两种方法,并结合提供的源码分析其工作原理和实现细节。 1. GPS定位: GPS定位是...

    基站定位的实现(百度)

    基站定位是一种基于移动通信网络的定位技术,主要利用手机与周围基站之间的信号强度和时间差来确定手机的位置。在移动设备如Android手机上,通过集成百度地图API,我们可以实现基站定位功能。以下是对基站定位技术和...

    Android 基站定位例子

    在Android系统中,基站定位是一种基于移动通信网络的定位方式,它通过获取手机与周围基站的距离来估算设备的位置。这种定位方法尤其适用于GPS信号不可用或者较弱的环境,如室内或城市高楼之间。本节将深入探讨...

    Google 基站定位源码

    基站定位技术是移动通信中的一种重要定位方法,尤其在GPS信号无法接收到或者接收质量差的情况下,如室内环境。Google作为全球领先的科技公司,其在基站定位方面有着深入的研究和应用。Google基站定位源码是Google...

    GPS定位和基站定位

    Android系统提供了丰富的API接口来支持GPS(全球定位系统)和基站定位这两种主流的定位方式。本文将深入探讨这两种定位技术的工作原理、优缺点以及在实际应用中的使用。 GPS定位是通过接收来自多个地球轨道上的GPS...

    基站定位JAVA代码

    基站定位

    Android 基站定位源码.zip

    在Android系统中,基站定位是一种常见的移动设备定位技术,它基于手机接收到来自周围基站的无线电信号强度来确定设备的位置。本压缩包"Android 基站定位源码.zip"包含了一个实现这一功能的源代码示例。下面将详细...

    google基站定位JAVA代码

    在IT行业中,基站定位是一种利用移动通信基站的信号来确定移动设备位置的技术。在Java编程环境下,我们可以利用Google提供的API和服务来实现这一功能。本文将深入探讨如何使用Java编写Google基站定位代码,以及相关...

    Android GPS和基站定位 Android studio开发

    在Android开发中,GPS(全球定位系统)和基站定位是两种常见的定位技术,它们用于获取设备的地理位置信息。本文将详细讲解这两种定位方式,并结合Android Studio的开发实践,阐述如何在实际应用中实现它们。 首先,...

    实时定位 gps基站定位 文字描述

    标题中的“实时定位 gps基站定位 文字描述”指的是在移动设备上实现的一种定位技术,它结合了GPS(全球定位系统)和基站定位两种方法来确定设备的位置。在没有GPS信号或者GPS信号弱的情况下,基站定位成为主要的定位...

    android 3G基站定位(完整源码实例)

    在Android平台上,3G基站定位是一种利用移动网络中的基站信息来确定设备位置的技术。相比于GPS,它在室内或城市峡谷等GPS信号弱的地方仍能提供定位服务。本项目提供了完整的源码实例,经过多次测试,确保了其稳定性...

    android 基站定位 返回定位的城市

    在Android开发中,基站定位是一种常见的获取用户地理位置的方法,它主要依赖于移动设备与周围基站之间的信号强度来确定位置。这种技术尤其适用于GPS信号不佳或者无法接收到GPS信号的环境,如室内。在这个名为...

    SIM900A通过基站定位

    在本文中,我们将深入探讨如何利用SIM900A通过基站定位技术来确定设备的位置。 基站定位是一种基于移动通信网络的定位方法,它依赖于手机与周围基站之间的信号交互。SIM900A模块可以通过发送AT命令获取当前服务小区...

    Android 百度 基站定位

    在Android平台上,百度基站定位是一种常见的地理定位方法,它结合了网络信号和GPS信号来获取设备的位置信息。本文将深入探讨这一技术,并基于提供的资源,包括相关jar包和示例项目,来阐述如何在Android应用中集成并...

    mobile GPS 基站定位 cell id算法

    移动设备上的GPS基站定位是利用手机接收多个移动通信基站发出的信号来确定设备位置的一种技术。这种方法结合了全球定位系统(GPS)与蜂窝网络的数据,特别是在GPS信号弱或者不可用的情况下,如室内环境,基站定位能...

Global site tag (gtag.js) - Google Analytics