Skip to content

Commit 9d69732

Browse files
author
Your Name
committed
init
1 parent d556089 commit 9d69732

5 files changed

Lines changed: 246 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# coord-transform
2-
A simple coord transformer with BD09, WGS84, GCJ02.
2+
A simple coord transformer between BD09, WGS84, GCJ02.

composer.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "leoding86/coord-transform",
3+
"description": "A simple coord transformer with BD09, WGS84, GCJ02.",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Leo Ding",
9+
"email": "leoding86@msn.com"
10+
}
11+
],
12+
"minimum-stability": "dev",
13+
"require": {
14+
"php": ">=5.3",
15+
},
16+
"autoload": {
17+
"psr-4": {
18+
"leoding86\\CoordTransform\\": "src/"
19+
}
20+
}
21+
}

src/Coord.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
namespace leoding86\CoordTransform;
3+
4+
class Coord extends Transform
5+
{
6+
public function __construct($lng, $lat, $type)
7+
{
8+
$this->lng = $lng;
9+
$this->lat = $lat;
10+
$this->type = $type;
11+
}
12+
13+
public function __toString()
14+
{
15+
return $this->type . ':' . $this->lng . ', ' . $this->lat . PHP_EOL;
16+
}
17+
}

src/Transform.php

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?php
2+
namespace leoding86\CoordTransform;
3+
4+
abstract class Transform
5+
{
6+
const WGS84 = 1;
7+
const GCJ02 = 2;
8+
const BD09 = 3;
9+
const x_PI = 52.359877559829887333333333333333; // 3.14159265358979324 * 3000.0 / 180.0;
10+
const PI = 3.1415926535897932384626;
11+
const a = 6378245.0;
12+
const ee = 0.00669342162296594323;
13+
14+
protected $type;
15+
protected $lng;
16+
protected $lat;
17+
18+
private function gcj02towgs84()
19+
{
20+
if ($this->outOfChina($this->lng, $this->lat)) {
21+
// return $this;
22+
} else {
23+
$dlat = $this->transformlat($this->lng - 105.0, $this->lat - 35.0);
24+
$dlng = $this->transformlng($this->lng - 105.0, $this->lat - 35.0);
25+
$radlat = $this->lat / 180.0 * self::PI;
26+
$magic = sin($radlat);
27+
$magic = 1 - self::ee * $magic * $magic;
28+
$sqrtmagic = sqrt($magic);
29+
$dlat = ($dlat * 180.0) / ((self::a * (1 - self::ee)) / ($magic * $sqrtmagic) * self::PI);
30+
$dlng = ($dlng * 180.0) / (self::a / $sqrtmagic * cos($radlat) * self::PI);
31+
$mglat = $this->lat + $dlat;
32+
$mglng = $this->lng + $dlng;
33+
34+
$this->type = self::WGS84;
35+
$this->lng = $this->lng * 2 - $mglng;
36+
$this->lat = $this->lat * 2 - $mglat;
37+
}
38+
}
39+
40+
private function wgs84togcj02()
41+
{
42+
if ($this->outOfChina($this->lng, $this->lat)) {
43+
// return $this;
44+
} else {
45+
$dlat = $this->transformlat($this->lng - 105.0, $this->lat - 35.0);
46+
$dlng = $this->transformlng($this->lng - 105.0, $this->lat - 35.0);
47+
$radlat = $this->lat / 180.0 * self::PI;
48+
$magic = sin($radlat);
49+
$magic = 1 - self::ee * $magic * $magic;
50+
$sqrtmagic = sqrt($magic);
51+
$dlat = ($dlat * 180.0) / ((self::a * (1 - self::ee)) / ($magic * $sqrtmagic) * self::PI);
52+
$dlng = ($dlng * 180.0) / (self::a / $sqrtmagic * cos($radlat) * self::PI);
53+
$mglat = $this->lat + $dlat;
54+
$mglng = $this->lng + $dlng;
55+
56+
$this->type = self::GCJ02;
57+
$this->lng = $mglng;
58+
$this->lat = $mglat;
59+
}
60+
}
61+
62+
private function bd09togcj02()
63+
{
64+
$x = $this->lng - 0.0065;
65+
$y = $this->lat - 0.006;
66+
$z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * self::x_PI);
67+
$theta = atan2($y, $x) - 0.000003 * cos($x * self::x_PI);
68+
$gg_lng = $z * cos($theta);
69+
$gg_lat = $z * sin($theta);
70+
71+
$this->type = self::GCJ02;
72+
$this->lng = $gg_lng;
73+
$this->lat = $gg_lat;
74+
}
75+
76+
private function gcj02tobd09()
77+
{
78+
$z = sqrt($this->lng * $this->lng + $this->lat * $this->lat) + 0.00002 * sin($this->lat * self::x_PI);
79+
$theta = atan2($this->lat, $this->lng) + 0.000003 * cos($this->lng * self::x_PI);
80+
$bd_lng = $z * cos($theta) + 0.0065;
81+
$bd_lat = $z * sin($theta) + 0.006;
82+
83+
$this->type = self::BD09;
84+
$this->lng = $bd_lng;
85+
$this->lat = $bd_lat;
86+
}
87+
88+
private function transformlat($lng, $lat) {
89+
$ret = -100.0 + 2.0 * $lng + 3.0 * $lat + 0.2 * $lat * $lat + 0.1 * $lng * $lat + 0.2 * sqrt(abs($lng));
90+
$ret += (20.0 * sin(6.0 * $lng * self::PI) + 20.0 * sin(2.0 * $lng * self::PI)) * 2.0 / 3.0;
91+
$ret += (20.0 * sin($lat * self::PI) + 40.0 * sin($lat / 3.0 * self::PI)) * 2.0 / 3.0;
92+
$ret += (160.0 * sin($lat / 12.0 * self::PI) + 320 * sin($lat * self::PI / 30.0)) * 2.0 / 3.0;
93+
return $ret;
94+
}
95+
96+
private function transformlng($lng, $lat) {
97+
$ret = 300.0 + $lng + 2.0 * $lat + 0.1 * $lng * $lng + 0.1 * $lng * $lat + 0.1 * sqrt(abs($lng));
98+
$ret += (20.0 * sin(6.0 * $lng * self::PI) + 20.0 * sin(2.0 * $lng * self::PI)) * 2.0 / 3.0;
99+
$ret += (20.0 * sin($lng * self::PI) + 40.0 * sin($lng / 3.0 * self::PI)) * 2.0 / 3.0;
100+
$ret += (150.0 * sin($lng / 12.0 * self::PI) + 300.0 * sin($lng / 30.0 * self::PI)) * 2.0 / 3.0;
101+
return $ret;
102+
}
103+
104+
private function outOfChina($lng, $lat) {
105+
return ($lng < 72.004 || $lng > 137.8347) || (($lat < 0.8293 || $lat > 55.8271) || false);
106+
}
107+
108+
public function getType()
109+
{
110+
return $this->type;
111+
}
112+
113+
public function getLng()
114+
{
115+
return $this->lng;
116+
}
117+
118+
public function getLat()
119+
{
120+
return $this->lat;
121+
}
122+
123+
/**
124+
* 转化坐标到WGS84坐标系
125+
* @return object
126+
*/
127+
public function towgs84()
128+
{
129+
if ($this->type === self::BD09) {
130+
$this->bd09togcj02();
131+
}
132+
133+
$this->gcj02towgs84();
134+
135+
return $this;
136+
}
137+
138+
/**
139+
* 转化坐标到GCJ02坐标系
140+
* @return object
141+
*/
142+
public function togcj02()
143+
{
144+
if ($this->type === self::WGS84) {
145+
$this->wgs84togcj02();
146+
} else if ($this->type === self::BD09) {
147+
$this->bd09togcj02();
148+
}
149+
150+
return $this;
151+
}
152+
153+
/**
154+
* 转化坐标到BD09坐标系
155+
* @return object
156+
*/
157+
public function tobd09()
158+
{
159+
if ($this->type === self::WGS84) {
160+
$this->wgs84togcj02();
161+
}
162+
163+
$this->gcj02tobd09();
164+
165+
return $this;
166+
}
167+
168+
/**
169+
* 转化坐标到指定坐标系
170+
* @return object
171+
*/
172+
public function to($type)
173+
{
174+
if ($type === $this->type) {
175+
return $this;
176+
}
177+
178+
if ($type === self::WGS84) {
179+
return $this->towgs84();
180+
} else if ($type === self::GCJ02) {
181+
return $this->togcj02();
182+
} else if ($type === self::BD09) {
183+
return $this->tobd09();
184+
}
185+
186+
return $this;
187+
}
188+
}

test/index.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
require '../src/Transform.php';
3+
require '../src/Coord.php';
4+
5+
$coord = new \leoding86\CoordTransform\Coord(116.404, 39.915, \leoding86\CoordTransform\Transform::BD09);
6+
echo $coord->togcj02();
7+
// 2:116.39762729119, 39.908656739576
8+
9+
$coord = new \leoding86\CoordTransform\Coord(116.404, 39.915, \leoding86\CoordTransform\Transform::GCJ02);
10+
// 3:116.41036949371, 39.92133699351
11+
echo $coord->tobd09();
12+
13+
$coord = new \leoding86\CoordTransform\Coord(116.404, 39.915, \leoding86\CoordTransform\Transform::WGS84);
14+
echo $coord->togcj02();
15+
// 2:116.41024449917, 39.916404281502
16+
17+
$coord = new \leoding86\CoordTransform\Coord(116.404, 39.915, \leoding86\CoordTransform\Transform::GCJ02);
18+
echo $coord->towgs84();
19+
//1:116.39775550083, 39.913595718498

0 commit comments

Comments
 (0)