Skip to content

Commit deb4b8c

Browse files
committed
rewrite the library
1 parent a571607 commit deb4b8c

9 files changed

Lines changed: 310 additions & 223 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
# Composer
3+
4+
composer.lock
5+
/vendor/

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
# coord-transform
2-
A simple coord transformer between BD09, WGS84, GCJ02.
1+
# coord-php
2+
3+
A simple coord library with distance calculating and BD09-WGS84-GCJ02 transforming.
4+
5+
Use case see the tests.

composer.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
{
2-
"name": "leoding86/coord-transform",
3-
"description": "A simple coord transformer with BD09, WGS84, GCJ02.",
2+
"name": "labs7in0/coord",
3+
"description": "A simple coord library with distance calculating and BD09-WGS84-GCJ02 transforming.",
44
"type": "library",
55
"license": "MIT",
66
"authors": [
77
{
8-
"name": "Leo Ding",
9-
"email": "leoding86@msn.com"
8+
"name": "Chino Chang",
9+
"email": "me@7in0.me"
1010
}
1111
],
12-
"minimum-stability": "dev",
1312
"require": {
14-
"php": ">=5.3"
13+
"php": ">=5.4"
14+
},
15+
"require-dev": {
16+
"phpunit/phpunit": "^4.8"
1517
},
1618
"autoload": {
1719
"psr-4": {
18-
"leoding86\\CoordTransform\\": "src/"
20+
"labs7in0\\coord\\": "src/"
1921
}
2022
}
2123
}

phpunit.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<phpunit>
2+
<testsuites>
3+
<testsuite name="coord">
4+
<directory suffix="Test.php">tests</directory>
5+
</testsuite>
6+
</testsuites>
7+
</phpunit>

src/Coord.php

Lines changed: 209 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,219 @@
11
<?php
2-
namespace leoding86\CoordTransform;
32

4-
class Coord extends Transform
3+
namespace labs7in0\coord;
4+
5+
use labs7in0\coord\Exceptions\UnknownTypeException;
6+
7+
class Coord
58
{
6-
public function __construct($lng, $lat, $type)
9+
const WGS84 = 1;
10+
const GCJ02 = 2;
11+
const BD09 = 3;
12+
const X_PI = 52.359877559829887333333333333333; // 3.14159265358979324 * 3000.0 / 180.0;
13+
const PI = 3.1415926535897932384626;
14+
const A = 6378245.0;
15+
const EE = 0.00669342162296594323;
16+
17+
private $longitude;
18+
private $latitude;
19+
private $type;
20+
21+
public function __construct(float $longitude, float $latitude, int $type = self::WGS84)
722
{
8-
$this->lng = $lng;
9-
$this->lat = $lat;
23+
if (!in_array($type, [1, 2, 3])) {
24+
throw new UnknownTypeException($this->type);
25+
}
26+
27+
$this->longitude = $longitude;
28+
$this->latitude = $latitude;
1029
$this->type = $type;
1130
}
1231

32+
private function gcj02ToWgs84()
33+
{
34+
if ($this->isOutOfChina()) {
35+
return $this;
36+
} else {
37+
$dlatitude = $this->transformLatitude($this->longitude - 105.0, $this->latitude - 35.0);
38+
$dlongitude = $this->transformLongitude($this->longitude - 105.0, $this->latitude - 35.0);
39+
$radlatitude = $this->latitude / 180.0 * self::PI;
40+
$magic = sin($radlatitude);
41+
$magic = 1 - self::EE * $magic * $magic;
42+
$sqrtmagic = sqrt($magic);
43+
$dlatitude = ($dlatitude * 180.0) / ((self::A * (1 - self::EE)) / ($magic * $sqrtmagic) * self::PI);
44+
$dlongitude = ($dlongitude * 180.0) / (self::A / $sqrtmagic * cos($radlatitude) * self::PI);
45+
$mglatitude = $this->latitude + $dlatitude;
46+
$mglongitude = $this->longitude + $dlongitude;
47+
48+
return new self($this->longitude * 2 - $mglongitude, $this->latitude * 2 - $mglatitude, self::WGS84);
49+
}
50+
}
51+
52+
private function wgs84ToGcj02()
53+
{
54+
if ($this->isOutOfChina()) {
55+
return $this;
56+
} else {
57+
$dlatitude = $this->transformLatitude($this->longitude - 105.0, $this->latitude - 35.0);
58+
$dlongitude = $this->transformLongitude($this->longitude - 105.0, $this->latitude - 35.0);
59+
$radlatitude = $this->latitude / 180.0 * self::PI;
60+
$magic = sin($radlatitude);
61+
$magic = 1 - self::EE * $magic * $magic;
62+
$sqrtmagic = sqrt($magic);
63+
$dlatitude = ($dlatitude * 180.0) / ((self::A * (1 - self::EE)) / ($magic * $sqrtmagic) * self::PI);
64+
$dlongitude = ($dlongitude * 180.0) / (self::A / $sqrtmagic * cos($radlatitude) * self::PI);
65+
$mglatitude = $this->latitude + $dlatitude;
66+
$mglongitude = $this->longitude + $dlongitude;
67+
68+
return new self($mglongitude, $mglatitude, self::GCJ02);
69+
}
70+
}
71+
72+
private function bd09ToGcj02()
73+
{
74+
$x = $this->longitude - 0.0065;
75+
$y = $this->latitude - 0.006;
76+
$z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * self::X_PI);
77+
$theta = atan2($y, $x) - 0.000003 * cos($x * self::X_PI);
78+
79+
return new self($z * cos($theta), $z * sin($theta), self::GCJ02);
80+
}
81+
82+
private function gcj02ToBd09()
83+
{
84+
$z = sqrt($this->longitude * $this->longitude + $this->latitude * $this->latitude) + 0.00002 * sin($this->latitude * self::X_PI);
85+
$theta = atan2($this->latitude, $this->longitude) + 0.000003 * cos($this->longitude * self::X_PI);
86+
$bd_longitude = $z * cos($theta) + 0.0065;
87+
$bd_latitude = $z * sin($theta) + 0.006;
88+
89+
return new self($bd_longitude, $bd_latitude, self::BD09);
90+
}
91+
92+
private function bd09ToWgs84()
93+
{
94+
return $this->bd09ToGcj02()->gcj02ToWgs84();
95+
}
96+
97+
private function wgs84ToBd09()
98+
{
99+
return $this->wgs84ToGcj02()->gcj02ToBd09();
100+
}
101+
102+
private function transformLatitude(float $longitude, float $latitude)
103+
{
104+
$ret = -100.0 + 2.0 * $longitude + 3.0 * $latitude + 0.2 * $latitude * $latitude + 0.1 * $longitude * $latitude + 0.2 * sqrt(abs($longitude));
105+
$ret += (20.0 * sin(6.0 * $longitude * self::PI) + 20.0 * sin(2.0 * $longitude * self::PI)) * 2.0 / 3.0;
106+
$ret += (20.0 * sin($latitude * self::PI) + 40.0 * sin($latitude / 3.0 * self::PI)) * 2.0 / 3.0;
107+
$ret += (160.0 * sin($latitude / 12.0 * self::PI) + 320 * sin($latitude * self::PI / 30.0)) * 2.0 / 3.0;
108+
return $ret;
109+
}
110+
111+
private function transformLongitude(float $longitude, float $latitude)
112+
{
113+
$ret = 300.0 + $longitude + 2.0 * $latitude + 0.1 * $longitude * $longitude + 0.1 * $longitude * $latitude + 0.1 * sqrt(abs($longitude));
114+
$ret += (20.0 * sin(6.0 * $longitude * self::PI) + 20.0 * sin(2.0 * $longitude * self::PI)) * 2.0 / 3.0;
115+
$ret += (20.0 * sin($longitude * self::PI) + 40.0 * sin($longitude / 3.0 * self::PI)) * 2.0 / 3.0;
116+
$ret += (150.0 * sin($longitude / 12.0 * self::PI) + 300.0 * sin($longitude / 30.0 * self::PI)) * 2.0 / 3.0;
117+
return $ret;
118+
}
119+
120+
public function isOutOfChina()
121+
{
122+
return ($this->longitude < 72.004 || $this->longitude > 137.8347)
123+
|| ($this->latitude < 0.8293 || $this->latitude > 55.8271);
124+
}
125+
126+
public function toWgs84()
127+
{
128+
switch ($this->type) {
129+
case self::WGS84:
130+
return $this;
131+
break;
132+
case self::GCJ02:
133+
return $this->gcj02ToWgs84();
134+
break;
135+
case self::BD09:
136+
return $this->bd09ToWgs84();
137+
break;
138+
default:
139+
throw new UnknownTypeException($this->type);
140+
}
141+
}
142+
143+
public function toGcj02()
144+
{
145+
switch ($this->type) {
146+
case self::WGS84:
147+
return $this->wgs84ToGcj02();
148+
break;
149+
case self::GCJ02:
150+
return $this;
151+
break;
152+
case self::BD09:
153+
return $this->bd09ToGcj02();
154+
break;
155+
default:
156+
throw new UnknownTypeException($this->type);
157+
}
158+
}
159+
160+
public function toBd09()
161+
{
162+
switch ($this->type) {
163+
case self::WGS84:
164+
return $this->wgs84ToBd09();
165+
break;
166+
case self::GCJ02:
167+
return $this->gcj02ToBd09();
168+
break;
169+
case self::BD09:
170+
return $this;
171+
break;
172+
default:
173+
throw new UnknownTypeException($this->type);
174+
}
175+
}
176+
177+
public function to(int $type)
178+
{
179+
switch ($type) {
180+
case self::WGS84:
181+
return $this->toWgs84();
182+
break;
183+
case self::GCJ02:
184+
return $this->toGcj02();
185+
break;
186+
case self::BD09:
187+
return $this->toBd09();
188+
break;
189+
default:
190+
throw new UnknownTypeException($this->type);
191+
}
192+
}
193+
194+
public function distanceTo(Coord $destination)
195+
{
196+
$destination = $destination->to($this->type);
197+
198+
$latitudeRadA = deg2rad($this->latitude);
199+
$longitudeRadA = deg2rad($this->longitude);
200+
$latitudeRadB = deg2rad($destination->latitude);
201+
$longitudeRadB = deg2rad($destination->longitude);
202+
203+
return 2 * asin(sqrt(
204+
pow(sin(($latitudeRadA - $latitudeRadB) / 2), 2)
205+
+ cos($latitudeRadA) * cos($latitudeRadB)
206+
* pow(sin(($longitudeRadA - $longitudeRadB) / 2), 2)
207+
)) * 6378.137 * 1000;
208+
}
209+
210+
public function string()
211+
{
212+
return $this->longitude . ',' . $this->latitude;
213+
}
214+
13215
public function __toString()
14216
{
15-
return $this->type . ':' . $this->lng . ', ' . $this->lat . PHP_EOL;
217+
return $this->string();
16218
}
17-
}
219+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace labs7in0\coord\Exceptions;
4+
5+
class UnknownTypeException extends \Exception
6+
{
7+
public function __construct(int $type)
8+
{
9+
parent::__construct('Type [' . $type . '] unsupported.');
10+
}
11+
}

0 commit comments

Comments
 (0)