Skip to content

Commit

Permalink
PHP5.4+ support & PSR-4 autoload
Browse files Browse the repository at this point in the history
  • Loading branch information
larryli committed Dec 10, 2015
1 parent 2a2b8a8 commit 2d8dd1c
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 79 deletions.
16 changes: 8 additions & 8 deletions README.md
Expand Up @@ -7,7 +7,7 @@ GCJ-02 coordiante is used by Google Maps, Autonavi Map and other china map servi
func WGStoGCJ(wgsLat, wgsLng float64) (gcjLat, gcjLng float64) // Go/Golang
void wgs2gcj(double wgsLat, double wgsLng, double *gcjLat, double *gcjLng) // C/C++/Obj-C
eviltransform.wgs2gcj(wgsLat, wgsLng) // JavaScript/Python
EvilTransform::WGStoGCJ($wgsLat, $wgsLng) // PHP
\larryli\eviltransform\EvilTransform::WGStoGCJ($wgsLat, $wgsLng) // PHP5.4+
EvilTransform.Transform.WGS2GCJ(wgsLat, wgsLng) // CSharp
wgs2Gcj (gcjLat, gcjLng) // Haskell

Expand All @@ -20,7 +20,7 @@ Input WGS-84 coordinate(wgsLat, wgsLng) and convert to GCJ-02 coordinate(gcjLat,
func GCJtoWGS(gcjLat, gcjLng float64) (wgsLat, wgsLng float64) // Go/Golang
void gcj2wgs(double gcjLat, double gcjLng, double *wgsLat, double *wgsLnt) // C/C++/Obj-C
eviltransform.gcj2wgs(gcjLat, gcjLng) // JavaScript/Python
EvilTransform::GCJtoWGS($gcjLat, $gcjLng) // PHP
\larryli\eviltransform\EvilTransform::GCJtoWGS($gcjLat, $gcjLng) // PHP5.4+
EvilTransform.Transform.GCJ2WGS(gcjLat, gcjLng) //CSharp
gcj2Wgs (gcjLat, gcjLng) // Haskell

Expand All @@ -35,7 +35,7 @@ The output WGS-84 coordinate's accuracy is 1m to 2m. If you want more exactly re
func GCJtoWGSExact(gcjLat, gcjLng float64) (wgsLat, wgsLng float64) // Go/Golang
void gcj2wgs_exact(double gcjLat, double gcjLng, double *wgsLat, double *wgsLnt) // C/C++/Obj-C
eviltransform.gcj2wgs_exact(gcjLat, gcjLng) // JavaScript/Python
EvilTransform::GCJtoWGSExact($gcjLat, $gcjLng) // PHP
\larryli\eviltransform\EvilTransform::GCJtoWGSExact($gcjLat, $gcjLng) // PHP5.4+
EvilTransform.Transform.GCJ2WGSExact(gcjLat, gcjLng) //CSharp
gcj2WgsExact (gcjLat, gcjLng) //Haskell

Expand All @@ -50,7 +50,7 @@ The output WGS-84 coordinate's accuracy is less than 0.5m, but much slower than
func Distance(latA, lngA, latB, lngB float64) float64 // Go/Golang
double distance(double latA, double lngA, double latB, double lngB) // C/C++/Obj-C
eviltransform.distance(latA, lngA, latB, lngB) // JavaScript/Python
EvilTransform::Distance($latA, $lngA, $latB, $lngB) // PHP
\larryli\eviltransform\EvilTransform::Distance($latA, $lngA, $latB, $lngB) // PHP5.4+
EvilTransform.Transform.Distance(latA, lngA, latB, lngB) //CSharp
distance (lat, lng)

Expand Down Expand Up @@ -78,7 +78,7 @@ GCJ-02坐标用在谷歌地图,高德地图等中国地图服务。(百度
func WGStoGCJ(wgsLat, wgsLng float64) (gcjLat, gcjLng float64) // Go/Golang
void wgs2gcj(double wgsLat, double wgsLng, double *gcjLat, double *gcjLng) // C/C++/Obj-C
eviltransform.wgs2gcj(wgsLat, wgsLng) // JavaScript/Python
EvilTransform::WGStoGCJ($wgsLat, $wgsLng) // PHP
\larryli\eviltransform\EvilTransform::WGStoGCJ($wgsLat, $wgsLng) // PHP5.4+
EvilTransform.Transform.WGS2GCJ(wgsLat, wgsLng) // CSharp
wgs2Gcj (gcjLat, gcjLng) // Haskell

Expand All @@ -91,7 +91,7 @@ GCJ-02坐标用在谷歌地图,高德地图等中国地图服务。(百度
func GCJtoWGS(gcjLat, gcjLng float64) (wgsLat, wgsLng float64) // Go/Golang
void gcj2wgs(double gcjLat, double gcjLng, double *wgsLat, double *wgsLnt) // C/C++/Obj-C
eviltransform.gcj2wgs(gcjLat, gcjLng) // JavaScript/Python
EvilTransform::GCJtoWGS($gcjLat, $gcjLng) // PHP
\larryli\eviltransform\EvilTransform::GCJtoWGS($gcjLat, $gcjLng) // PHP5.4+
EvilTransform.Transform.GCJ2WGS(gcjLat, gcjLng) //CSharp
gcj2Wgs (gcjLat, gcjLng) // Haskell

Expand All @@ -106,7 +106,7 @@ GCJ-02坐标用在谷歌地图,高德地图等中国地图服务。(百度
func GCJtoWGSExact(gcjLat, gcjLng float64) (wgsLat, wgsLng float64) // Go/Golang
void gcj2wgs_exact(double gcjLat, double gcjLng, double *wgsLat, double *wgsLnt) // C/C++/Obj-C
eviltransform.gcj2wgs_exact(gcjLat, gcjLng) // JavaScript/Python
EvilTransform::GCJtoWGSExact($gcjLat, $gcjLng) // PHP
\larryli\eviltransform\EvilTransform::GCJtoWGSExact($gcjLat, $gcjLng) // PHP5.4+
EvilTransform.Transform.GCJ2WGSExact(gcjLat, gcjLng) //CSharp
gcj2WgsExact (gcjLat, gcjLng) //Haskell

Expand All @@ -121,7 +121,7 @@ GCJ-02坐标用在谷歌地图,高德地图等中国地图服务。(百度
func Distance(latA, lngA, latB, lngB float64) float64 // Go/Golang
double distance(double latA, double lngA, double latB, double lngB) // C/C++/Obj-C
eviltransform.distance(latA, lngA, latB, lngB) // JavaScript/Python
EvilTransform::Distance($latA, $lngA, $latB, $lngB) // PHP
\larryli\eviltransform\EvilTransform::Distance($latA, $lngA, $latB, $lngB) // PHP5.4+
EvilTransform.Transform.Distance(latA, lngA, latB, lngB) //CSharp
distance (lat, lng)

Expand Down
2 changes: 2 additions & 0 deletions php/.gitignore
@@ -0,0 +1,2 @@
/vendor
/composer.lock
118 changes: 81 additions & 37 deletions php/EvilTransform.php
@@ -1,9 +1,19 @@
<?php

// Package transform coordinate between earth(WGS-84) and mars in china(GCJ-02).
namespace larryli\eviltransform;

/**
* Package transform coordinate between earth(WGS-84) and mars in china(GCJ-02).
* @package larryli\eviltransform
*/
class EvilTransform
{

/**
* outOfChina
* @param float $lat
* @param float $lng
* @return bool
*/
private static function outOfChina($lat, $lng)
{
if ($lng < 72.004 || $lng > 137.8347) {
Expand All @@ -15,6 +25,12 @@ private static function outOfChina($lat, $lng)
return false;
}

/**
* transform
* @param float $x
* @param float $y
* @return float[]
*/
private static function transform($x, $y)
{
$xy = $x * $y;
Expand All @@ -33,67 +49,87 @@ private static function transform($x, $y)
$lat += (160.0 * sin($y / 12.0 * pi()) + 320 * sin($y / 30.0 * pi())) * 2.0 / 3.0;
$lng += (150.0 * sin($x / 12.0 * pi()) + 300.0 * sin($x / 30.0 * pi())) * 2.0 / 3.0;

return array($lat, $lng);
return [$lat, $lng];
}

/**
* delta
* @param float $lat
* @param float $lng
* @return float[] [$lat, $lng]
*/
private static function delta($lat, $lng)
{
/*const */$a = 6378245.0;
/*const */$ee = 0.00669342162296594323;
$a = 6378245.0;
$ee = 0.00669342162296594323;
list($dLat, $dLng) = self::transform($lng - 105.0, $lat - 35.0);
$radLat = $lat / 180.0 * pi();
$magic = sin($radLat);
$magic = 1 - $ee * $magic * $magic;
$sqrtMagic = sqrt($magic);
$dLat = ($dLat * 180.0) / (($a * (1 - $ee)) / ($magic * $sqrtMagic) * pi());
$dLng = ($dLng * 180.0) / ($a / $sqrtMagic * cos($radLat) * pi());
return array($dLat, $dLng);
return [$dLat, $dLng];
}

// WGStoGCJ convert WGS-84 coordinate(wgsLat, wgsLng) to GCJ-02 coordinate(gcjLat, gcjLng).
/**
* WGStoGCJ convert WGS-84 coordinate(wgsLat, wgsLng) to GCJ-02 coordinate(gcjLat, gcjLng).
* @param float $wgsLat
* @param float $wgsLng
* @return float[] [$gcjLat, $gcjLng]
*/
public static function WGStoGCJ($wgsLat, $wgsLng)
{
if (self::outOfChina($wgsLat, $wgsLng)) {
list($gcjLat, $gcjLng) = array($wgsLat, $wgsLng);
return array($gcjLat, $gcjLng);
return [$wgsLat, $wgsLng];
}
list($dLat, $dLng) = self::delta($wgsLat, $wgsLng);
list($gcjLat, $gcjLng) = array($wgsLat + $dLat, $wgsLng + $dLng);
return array($gcjLat, $gcjLng);
return [$wgsLat + $dLat, $wgsLng + $dLng];
}

// GCJtoWGS convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng).
// The output WGS-84 coordinate's accuracy is 1m to 2m. If you want more exactly result, use GCJtoWGSExact/gcj2wgs_exact.
/**
* GCJtoWGS convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng).
*
* The output WGS-84 coordinate's accuracy is 1m to 2m. If you want more exactly result, use GCJtoWGSExact/gcj2wgs_exact.
* @param float $gcjLat
* @param float $gcjLng
* @return float[] [$wgsLat, $wgsLng]
*/
public static function GCJtoWGS($gcjLat, $gcjLng)
{
if (self::outOfChina($gcjLat, $gcjLng)) {
list($wgsLat, $wgsLng) = array($gcjLat, $gcjLng);
return array($wgsLat, $wgsLng);
return [$gcjLat, $gcjLng];
}
list($dLat, $dLng) = self::delta($gcjLat, $gcjLng);
list($wgsLat, $wgsLng) = array($gcjLat - $dLat, $gcjLng - $dLng);
return array($wgsLat, $wgsLng);
return [$gcjLat - $dLat, $gcjLng - $dLng];
}

// GCJtoWGSExact convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng).
// The output WGS-84 coordinate's accuracy is less than 0.5m, but much slower than GCJtoWGS/gcj2wgs.
/**
* GCJtoWGSExact convert GCJ-02 coordinate(gcjLat, gcjLng) to WGS-84 coordinate(wgsLat, wgsLng).
*
* The output WGS-84 coordinate's accuracy is less than 0.5m, but much slower than GCJtoWGS/gcj2wgs.
* @param float $gcjLat
* @param float $gcjLng
* @return float[] [$wgsLat, $wgsLng]
*/
public static function GCJtoWGSExact($gcjLat, $gcjLng)
{
/*const */$initDelta = 0.01;
/*const */$threshold = 0.000001;
$initDelta = 0.01;
$threshold = 0.000001;
// list($tmpLat, $tmpLng) = self::GCJtoWGS($gcjLat, $gcjLng);
// list($tryLat, $tryLng) = self::WGStoGCJ($tmpLat, $tmpLng);
// list($dLat, $dLng) = array(abs($tmpLat-$tryLat), abs($tmpLng-$tryLng));
list($dLat, $dLng) = array($initDelta, $initDelta);
list($mLat, $mLng) = array($gcjLat - $dLat, $gcjLng - $dLng);
list($pLat, $pLng) = array($gcjLat + $dLat, $gcjLng + $dLng);
// list($dLat, $dLng) = [abs($tmpLat-$tryLat), abs($tmpLng-$tryLng)];
list($dLat, $dLng) = [$initDelta, $initDelta];
list($mLat, $mLng) = [$gcjLat - $dLat, $gcjLng - $dLng];
list($pLat, $pLng) = [$gcjLat + $dLat, $gcjLng + $dLng];
list($wgsLat, $wgsLng) = [false, false];
for ($i = 0; $i < 30; $i++) {
list($wgsLat, $wgsLng) = array(($mLat + $pLat) / 2, ($mLng + $pLng) / 2);
list($wgsLat, $wgsLng) = [($mLat + $pLat) / 2, ($mLng + $pLng) / 2];
list($tmpLat, $tmpLng) = self::WGStoGCJ($wgsLat, $wgsLng);
list($dLat, $dLng) = array($tmpLat - $gcjLat, $tmpLng - $gcjLng);
list($dLat, $dLng) = [$tmpLat - $gcjLat, $tmpLng - $gcjLng];
if (abs($dLat) < $threshold && abs($dLng) < $threshold) {
// echo("i:", $i);
return array($wgsLat, $wgsLng);
return [$wgsLat, $wgsLng];
}
if ($dLat > 0) {
$pLat = $wgsLat;
Expand All @@ -106,25 +142,33 @@ public static function GCJtoWGSExact($gcjLat, $gcjLng)
$mLng = $wgsLng;
}
}
return array($wgsLat, $wgsLng);
return [$wgsLat, $wgsLng];
}

// Distance calculate the distance between point(latA, lngA) and point(latB, lngB), unit in meter.
/**
* Distance calculate the distance between point(latA, lngA) and point(latB, lngB), unit in meter.
* @param float $latA lat of the point A
* @param float $lngA lng of the point A
* @param float $latB lat of the point B
* @param float $lngB lng of the point B
* @return float distance, unit in meter
*/
public static function Distance($latA, $lngA, $latB, $lngB)
{
/*const */$earthR = 6371000;
$x = cos($latA * pi() / 180) * cos($latB * pi() / 180) * cos(($lngA - $lngB) * pi() / 180);
$y = sin($latA * pi() / 180) * sin($latB * pi() / 180);
$earthR = 6371000;
$latA *= pi() / 180;
$lngA *= pi() / 180;
$latB *= pi() / 180;
$lngB *= pi() / 180;
$x = cos($latA) * cos($latB) * cos($lngA - $lngB);
$y = sin($latA) * sin($latB);
$s = $x + $y;
if ($s > 1) {
$s = 1;
}
if ($s < -1) {
$s = -1;
}
$alpha = acos($s);
$distance = $alpha * $earthR;
return $distance;
return acos($s) * $earthR;
}

}

0 comments on commit 2d8dd1c

Please sign in to comment.