• 地图坐标转换


    地图坐标转换

      1 <?php
      2 define('X_PI', 3.14159265358979324 * 3000.0 / 180.0);
      3 
      4 class Coordinate {
      5     // lat
      6     public $x = 0;
      7     // lon
      8     public $y = 0;
      9     // other
     10     public $z = 0;
     11 
     12     public function __construct($lat, $lon) {
     13         $this->x = $lat;
     14         $this->y = $lon;
     15     }
     16 }
     17 
     18 class CoordinateService {
     19 
     20     const GEOTYPEWGS = 1;
     21     const GEOTYPEGCJ = 2;
     22     const GEOTYPEBD  = 3;
     23 
     24     public static $GeoTypeMap = [
     25         self::GEOTYPEWGS => '地球坐标',
     26         self::GEOTYPEGCJ => '火星坐标',
     27         self::GEOTYPEBD => '百度坐标'
     28     ];
     29 
     30     private static $x_pi = X_PI;
     31     private static $pi = 3.14159265358979324;
     32     private static $a = 6378245.0;
     33     private static $ee = 0.00669342162296594323;
     34 
     35     public function format_coordinate($lat, $lon) {
     36         return new Coordinate($lat, $lon);
     37     }
     38     //火星坐标(GCJ02坐标,高德,谷歌,腾讯坐标)到百度坐标BD-09
     39     public static function gcjTObd($from) {
     40         $to = new Coordinate();
     41         $x = $from->y;
     42         $y = $from->x;
     43         $z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * self::$x_pi);
     44         $theta = atan2($y, $x) + 0.000003 * cos($x * self::$x_pi);
     45         $to->y = $z * cos($theta) + 0.0065;
     46         $to->x = $z * sin($theta) + 0.006;
     47 
     48         return ($to);
     49     }
     50 
     51     //百度坐标BD-09到火星坐标GCJ02(高德,谷歌,腾讯坐标)
     52     public static function bdTOgcj($from) {
     53         $to = new Coordinate();
     54         $x = $from->y - 0.0065;
     55         $y = $from->x - 0.006;
     56         $z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * self::$x_pi);
     57         $theta = atan2($y, $x) - 0.000003 * cos($x * self::$x_pi);
     58         $to->y = $z * cos($theta);
     59         $to->x = $z * sin($theta);
     60         return ($to);
     61     }
     62 
     63     // WGS-84(GPS坐标,谷歌地球坐标) 到 GCJ-02(火星坐标) 的转换
     64     public static function wgsTOgcj($from) {
     65         //double wgLat, double wgLon, out double mgLat, out double mgLon
     66         $wgLat = $from->x;
     67         $wgLon = $from->y;
     68         if (self::outOfChina($wgLat, $wgLon)) {
     69             return (new Coordinate($wgLat, $wgLon));
     70         }
     71 
     72         $dLat = self::transformLat($wgLon - 105.0, $wgLat - 35.0);
     73         $dLon = self::transformLon($wgLon - 105.0, $wgLat - 35.0);
     74         $radLat = $wgLat / 180.0 * self::$pi;
     75         $magic = sin($radLat);
     76         $magic = 1 - self::$ee * $magic * $magic;
     77         $sqrtMagic = sqrt($magic);
     78         $dLat = ($dLat * 180.0) / ((self::$a * (1 - self::$ee)) / ($magic * $sqrtMagic) * self::$pi);
     79         $dLon = ($dLon * 180.0) / (self::$a / $sqrtMagic * cos($radLat) * self::$pi);
     80 
     81         $mgLat = $wgLat + $dLat;
     82         $mgLon = $wgLon + $dLon;
     83 
     84         return (new Coordinate($mgLat, $mgLon));
     85     }
     86 
     87     // GCJ-02 到 WGS-84 的转换
     88     public static function gcjTOwgs($from) {
     89         $to = self::wgsTOgcj($from);
     90         $lat = $from->x;
     91         $lon = $from->y;
     92         $g_lat = $to->x;
     93         $g_lon = $to->y;
     94         $d_lat = $g_lat - $lat;
     95         $d_lon = $g_lon - $lon;
     96 
     97         return new Coordinate($lat - $d_lat, $lon - $d_lon);
     98     }
     99 
    100     // 把地球经纬度转换为lat和lon
    101     public static function earthCoordinate($t1, $t2) {
    102         $tt1 = $t1->x + $t1->y / 60.0 + $t1->z / 3600.0;
    103         $tt2 = $t2->x + $t2->y / 60.0 + $t2->z / 3600.0;
    104 
    105         return (new Coordinate($tt1, $tt2));
    106     }
    107 
    108     private static function outOfChina($lat, $lon) {
    109         if ($lon < 72.004 || $lon > 137.8347)
    110             return TRUE;
    111         if ($lat < 0.8293 || $lat > 55.8271)
    112             return TRUE;
    113 
    114         return FALSE;
    115     }
    116 
    117     private static function transformLat($x, $y) {
    118         $ret = -100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt(abs($x));
    119         $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
    120         $ret += (20.0 * sin($y * self::$pi) + 40.0 * sin($y / 3.0 * self::$pi)) * 2.0 / 3.0;
    121         $ret += (160.0 * sin($y / 12.0 * self::$pi) + 320 * sin($y * self::$pi / 30.0)) * 2.0 / 3.0;
    122         return $ret;
    123     }
    124 
    125     private static function transformLon($x, $y) {
    126         $ret = 300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt(abs($x));
    127         $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
    128         $ret += (20.0 * sin($x * self::$pi) + 40.0 * sin($x / 3.0 * self::$pi)) * 2.0 / 3.0;
    129         $ret += (150.0 * sin($x / 12.0 * self::$pi) + 300.0 * sin($x / 30.0 * self::$pi)) * 2.0 / 3.0;
    130         return $ret;
    131     }
    132 
    133 }
  • 相关阅读:
    使用iconv编程进行字符集转换
    Unity3D学习之路 C#学习笔记(一)
    跨平台的游戏客户端Socket封装
    TCP长连接与短连接的区别
    C++中的long long和__int64类型
    基于cocos2dx的游戏客户端优化
    Android NDK带来什么
    strcpy_s与strcpy的比较
    英文字母和中文汉字在不同字符集编码下的字节数
    socket的read和recv函数的区别
  • 原文地址:https://www.cnblogs.com/huqiang/p/6826087.html
Copyright © 2020-2023  润新知