GEO <-> KATEC 변환
페이지 정보
작성자 MintState 댓글 0건 조회 12,516회 작성일 11-02-21 11:17본문
GEO <-> KATEC 변환
PHP 방법
Javascript 방법
기타 참고 URL
http://aero.sarang.net/map/analysis.html
http://aero.sarang.net/map/coordinate_naver.html
http://code.google.com/intl/ko/apis/maps/
http://dev.naver.com/openapi/apis/map/javascript/reference
PHP 방법
<?php
class GeoTrans{
var $srctype;
var $dsttype;
var $m_Ind, $m_Es, $m_Esp, $src_m, $dst_m;
var $EPSLN = 0.0000000001;
var $m_arMajor = 6378137.0;
var $m_arMinor = 6356752.3142;
var $m_arScaleFactor = array();
var $m_arLonCenter = array();
var $m_arLatCenter = array();
var $m_arFalseNorthing = array();
var $m_arFalseEasting = array();
function GeoTrans($srctype = "katec", $dsttype = "geo")
{
$this->m_arScaleFactor["geo"] = 1;
$this->m_arLonCenter["geo"] = 0.0;
$this->m_arLatCenter["geo"] = 0.0;
$this->m_arFalseNorthing["geo"] = 0.0;
$this->m_arFalseEasting["geo"] = 0.0;
$this->m_arScaleFactor["katec"] = 0.9999;
$this->m_arLonCenter["katec"] = 2.23402144255274;
$this->m_arLatCenter["katec"] = 0.663225115757845;
$this->m_arFalseNorthing["katec"] = 600000.0;
$this->m_arFalseEasting["katec"] = 400000.0;
$this->srctype = $srctype;
$this->dsttype = $dsttype;
$temp = $this->m_arMinor / $this->m_arMajor;
$this->m_Es = 1.0 - $temp * $temp;
$this->m_Esp = $this->m_Es / (1.0 - $this->m_Es);
if ($this->m_Es < 0.00001) {
$this->m_Ind = 1.0;
}
else {
$this->m_Ind = 0.0;
}
$this->src_m = $this->m_arMajor * $this->mlfn($this->e0fn($this->m_Es), $this->e1fn($this->m_Es), $this->e2fn($this->m_Es), $this->e3fn($this->m_Es), $this->m_arLatCenter[$srctype]);
$this->dst_m = $this->m_arMajor * $this->mlfn($this->e0fn($this->m_Es), $this->e1fn($this->m_Es), $this->e2fn($this->m_Es), $this->e3fn($this->m_Es), $this->m_arLatCenter[$dsttype]);
}
function D2R($degree)
{
return $degree * M_PI / 180.0;
}
function R2D($radian)
{
return $radian * 180.0 / M_PI;
}
function e0fn($x)
{
return 1.0 - 0.25 * $x * (1.0 + $x / 16.0 * (3.0 + 1.25 * $x));
}
function e1fn($x)
{
return 0.375 * $x * (1.0 + 0.25 * $x * (1.0 + 0.46875 * $x));
}
function e2fn($x)
{
return 0.05859375 * $x * $x * (1.0 + 0.75 * $x);
}
function e3fn($x)
{
return $x * $x * $x * (35.0 / 3072.0);
}
function mlfn($e0, $e1, $e2, $e3, $phi)
{
return $e0 * $phi - $e1 * sin(2.0 * $phi) + $e2 * sin(4.0 * $phi) - $e3 * sin(6.0 * $phi);
}
function asinz($value)
{
if (abs($value) > 1.0) $value = ($value > 0 ? 1 : -1);
return asin($value);
}
function conv($in_x, $in_y, &$out_x, &$out_y)
{
if ($this->srctype == "geo") {
$inlon = $this->D2R($in_x);
$inlat = $this->D2R($in_y);
}
else {
$this->tm2geo($in_x, $in_y, $inlon, $inlat);
}
$outlon = $inlon;
$outlat = $inlat;
if ($this->dsttype == "geo") {
$out_x = $this->R2D($outlon);
$out_y = $this->R2D($outlat);
}
else {
$this->geo2tm($outlon, $outlat, $out_x, $out_y);
$out_x = round($out_x);
$out_y = round($out_y);
}
}
function geo2tm($lon, $lat, &$x, &$y)
{
$delta_lon = $lon - $this->m_arLonCenter[$this->dsttype];
$sin_phi = sin($lat);
$cos_phi = cos($lat);
if ($this->m_Ind != 0) {
$b = $cos_phi * sin($delta_lon);
if ((abs(abs($b) - 1.0)) < $this->EPSLN) {
echo ("geo2tm: 무한대 에러");
}
}
else {
$b = 0;
$x = 0.5 * $this->m_arMajor * $this->m_arScaleFactor[$this->dsttype] * log((1.0 + $b) / (1.0 - $b));
$con = acos($cos_phi * cos($delta_lon) / sqrt(1.0 - $b * $b));
if ($lat < 0) {
$con = $con * -1;
$y = $this->m_arMajor * $this->m_arScaleFactor[$this->dsttype] * ($con - $this->m_arLatCenter[$this->dsttype]);
}
}
$al = $cos_phi * $delta_lon;
$als = $al * $al;
$c = $this->m_Esp * $cos_phi * $cos_phi;
$tq = tan($lat);
$t = $tq * $tq;
$con = 1.0 - $this->m_Es * $sin_phi * $sin_phi;
$n = $this->m_arMajor / sqrt($con);
$ml = $this->m_arMajor * $this->mlfn($this->e0fn($this->m_Es), $this->e1fn($this->m_Es), $this->e2fn($this->m_Es), $this->e3fn($this->m_Es), $lat);
$x = $this->m_arScaleFactor[$this->dsttype] * $n * $al * (1.0 + $als / 6.0 * (1.0 - $t + $c + $als / 20.0 * (5.0 - 18.0 * $t + $t * $t + 72.0 * $c - 58.0 * $this->m_Esp))) + $this->m_arFalseEasting[$this->dsttype];
$y = $this->m_arScaleFactor[$this->dsttype] * ($ml - $this->dst_m + $n * $tq * ($als * (0.5 + $als / 24.0 * (5.0 - $t + 9.0 * $c + 4.0 * $c * $c + $als / 30.0 * (61.0 - 58.0 * $t + $t * $t + 600.0 * $c - 330.0 * $this->m_Esp))))) + $this->m_arFalseNorthing[$this->dsttype];
}
function tm2geo($x, $y, &$lon, &$lat)
{
$max_iter = 6;
if ($this->m_Ind != 0) {
$f = exp($x / ($this->m_arMajor * $this->m_arScaleFactor[$this->srctype]));
$g = 0.5 * ($f - 1.0 / $f);
$temp = $this->m_arLatCenter[$this->srctype] + $y / ($this->m_arMajor * $this->m_arScaleFactor[$this->srctype]);
$h = cos($temp);
$con = sqrt((1.0 - $h * $h) / (1.0 + $g * $g));
$lat = asinz($con);
if ($temp < 0) $lat *= -1;
if (($g == 0) && ($h == 0))
$lon = $this->m_arLonCenter[$this->srctype];
else
$lon = atan($g / $h) + $this->m_arLonCenter[$this->srctype];
}
$x -= $this->m_arFalseEasting[$this->srctype];
$y -= $this->m_arFalseNorthing[$this->srctype];
$con = ($this->src_m + $y / $this->m_arScaleFactor[$this->srctype]) / $this->m_arMajor;
$phi = $con;
$i = 0;
while (true) {
$delta_Phi = (($con + $this->e1fn($this->m_Es) * sin(2.0 * $phi) - $this->e2fn($this->m_Es) * sin(4.0 * $phi) + $this->e3fn($this->m_Es) * sin(6.0 * $phi)) / $this->e0fn($this->m_Es)) - $phi;
$phi = $phi + $delta_Phi;
if (abs($delta_Phi) <= $this->EPSLN) break;
if ($i >= $max_iter)
echo ("tm2geo: 무한대 에러");
$i++;
}
if (abs($phi) < (M_PI / 2)) {
$sin_phi = sin($phi);
$cos_phi = cos($phi);
$tan_phi = tan($phi);
$c = $this->m_Esp * $cos_phi * $cos_phi;
$cs = $c * $c;
$t = $tan_phi * $tan_phi;
$ts = $t * $t;
$con = 1.0 - $this->m_Es * $sin_phi * $sin_phi;
$n = $this->m_arMajor / sqrt($con);
$r = $n * (1.0 - $this->m_Es) / $con;
$d = $x / ($n * $this->m_arScaleFactor[$this->srctype]);
$ds = $d * $d;
$lat = $phi - ($n * $tan_phi * $ds / $r) * (0.5 - $ds / 24.0 * (5.0 + 3.0 * $t + 10.0 * $c - 4.0 * $cs - 9.0 * $this->m_Esp - $ds / 30.0 * (61.0 + 90.0 * $t + 298.0 * $c + 45.0 * $ts - 252.0 * $this->m_Esp - 3.0 * $cs)));
$lon = $this->m_arLonCenter[$this->srctype] + ($d * (1.0 - $ds / 6.0 * (1.0 + 2.0 * $t + $c - $ds / 20.0 * (5.0 - 2.0 * $c + 28.0 * $t - 3.0 * $cs + 8.0 * $this->m_Esp + 24.0 * $ts))) / $cos_phi);
}
else {
$lat = M_PI * 0.5 * sin($y);
$lon = $this->m_arLonCenter[$this->srctype];
}
}
function getDistancebyGeo($lon1, $lat1, $lon2, $lat2)
{
$lat1 = $this->D2R($lat1);
$lon1 = $this->D2R($lon1);
$lat2 = $this->D2R($lat2);
$lon2 = $this->D2R($lon2);
$longitude = $lon2 - $lon1;
$latitude = $lat2 - $lat1;
$a = pow(sin($latitude / 2.0), 2) + cos($lat1) * cos($lat2) * pow(sin($longitude / 2.0), 2);
return 6376.5 * 2.0 * atan2(sqrt($a), sqrt(1.0 - $a));
}
function getDistancebyKatec($x1, $y1, $x2, $y2)
{
$geo = new GeoTrans;
$geo->conv($x1, $y1, $lon1, $lat1);
$geo->conv($x2, $y2, $lon2, $lat2);
return $this->getDistancebyGeo($lon1, $lat1, $lon2, $lat2);
}
function getTimebySec($distance)
{
return round(3600 * $distance / 4);
}
function getTimebyMin($distance)
{
return (int)ceil($this->getTimebySec($distance) / 60);
}
}
$naverx = "306151";
$navery = "556443";
$geo = new GeoTrans;
$geo->conv($naverx,$navery,$x,$y);
echo("======input naver postion=======\n");
echo("naver x: ".$naverx);
echo("\n");
echo("naver y: ".$navery);
echo("\n");
echo("======convert naver to google=======\n");
echo("google lng: ".$x);
echo("\n");
echo("google lat: ".$y);
echo("\n");
$geo = new GeoTrans("geo","katec");
$geo->conv($x,$y,$final_naverx,$final_navery);
echo("======convert google to naver=======\n");
echo("final naver x: ".$final_naverx);
echo("\n");
echo("final naver y: ".$final_navery);
echo("\n");
?>
Javascript 방법
var Point = function(x, y) {
this.x = x;
this.y = y;
}
var GeoTrans = function() {
this.srctype = "katec";
this.dsttype = "geo";
this.m_Ind = 0;
this.m_Es = 0;
this.m_Esp = 0;
this.src_m = 0;
this.dst_m = 0;
this.EPSLN = 0.0000000001;
this.m_arMajor = 6378137.0;
this.m_arMinor = 6356752.3142;
this.m_arScaleFactor = new Array();
this.m_arLonCenter = new Array();
this.m_arLatCenter = new Array();
this.m_arFalseNorthing = new Array();
this.m_arFalseEasting = new Array();
};
GeoTrans.prototype.init = function(srctype, dsttype) {
this.m_arScaleFactor["geo"] = 1;
this.m_arLonCenter["geo"] = 0.0;
this.m_arLatCenter["geo"] = 0.0;
this.m_arFalseNorthing["geo"] = 0.0;
this.m_arFalseEasting["geo"] = 0.0;
this.m_arScaleFactor["katec"] = 0.9999;
this.m_arLonCenter["katec"] = 2.23402144255274;
this.m_arLatCenter["katec"] = 0.663225115757845;
this.m_arFalseNorthing["katec"] = 600000.0;
this.m_arFalseEasting["katec"] = 400000.0;
this.srctype = srctype;
this.dsttype = dsttype;
var tmp = this.m_arMinor / this.m_arMajor;
this.m_Es = 1.0 - tmp * tmp;
this.m_Esp = this.m_Es / (1.0 - this.m_Es);
if(this.m_Es < 0.00001) {
this.m_Ind = 1.0;
} else {
this.m_Ind = 0.0;
}
this.src_m = this.m_arMajor * this.mlfn(this.e0fn(this.m_Es), this.e1fn(this.m_Es), this.e2fn(this.m_Es), this.e3fn(this.m_Es), this.m_arLatCenter[srctype]);
this.dst_m = this.m_arMajor * this.mlfn(this.e0fn(this.m_Es), this.e1fn(this.m_Es), this.e2fn(this.m_Es), this.e3fn(this.m_Es), this.m_arLatCenter[dsttype]);
}
GeoTrans.prototype.D2R = function(degree) {
return degree* Math.PI / 180.0;
}
GeoTrans.prototype.R2D = function(radian) {
return radian * 180.0 / Math.PI;
}
GeoTrans.prototype.e0fn = function(x) {
return 1.0 - 0.25 * x * (1.0 + x / 16.0 * (3.0 + 1.25 * x));
}
GeoTrans.prototype.e1fn = function(x) {
return 0.375 * x * (1.0 + 0.25 * x * (1.0 + 0.46875 * x));
}
GeoTrans.prototype.e2fn = function(x) {
return 0.05859375 * x * x * (1.0 + 0.75 * x);
}
GeoTrans.prototype.e3fn = function(x) {
return x * x * x * (35.0 / 3072.0);
}
GeoTrans.prototype.mlfn = function(e0, e1, e2, e3, phi) {
return e0 * phi - e1 * Math.sin(2.0 * phi) + e2 * Math.sin(4.0 * phi) - e3 * Math.sin(6.0 * phi);
}
GeoTrans.prototype.asinz = function(value) {
if(Math.abs(value) > 1.0) value = (value > 0 ? 1: -1);
return Math.asin(value);
}
GeoTrans.prototype.conv = function(in_pt) {
var inlon, inlat, outlon, outlat;
var tmpPt = new Point();
var out_pt = new Point();
if(this.srctype == "geo") {
tmpPt.x = this.D2R(in_pt.x);
tmpPt.y = this.D2R(in_pt.y);
} else {
this.tm2geo(in_pt, tmpPt);
}
outlon = inlon;
outlat = inlat;
if(this.dsttype == "geo") {
out_pt.x = this.R2D(tmpPt.x);
out_pt.y = this.R2D(tmpPt.y);
} else {
this.geo2tm(tmpPt, out_pt);
out_pt.x = Math.round(out_pt.x);
out_pt.y = Math.round(out_pt.y);
}
return out_pt;
}
GeoTrans.prototype.geo2tm = function(in_pt, out_pt) {
var delta_lon = in_pt.x - this.m_arLonCenter[this.dsttype];
var sin_phi = Math.sin(in_pt.y);
var cos_phi = Math.cos(in_pt.y);
if(this.m_Ind != 0) {
var b = cos_phi * Math.sin(delta_lon);
if((Math.abs(Math.abs(b) - 1.0)) < this.EPSLN) {
alert("무한대 에러");
}
} else {
var b = 0;
x = 0.5 * this.m_arMajor * this.m_arScaleFactor[this.dsttype] * Math.log((1.0 + b) / (1.0 - b));
var con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1.0 - b * b));
if(in_pt.y < 0) {
con = con * -1;
y = this.m_arMajor * this.m_arScaleFactor[this.dsttype] * (con - this.m_arLatCenter[this.dsttype]);
}
}
var al = cos_phi * delta_lon;
var als = al * al;
var c = this.m_Esp * cos_phi * cos_phi;
var tq = Math.tan(in_pt.y);
var t = tq * tq;
var con = 1.0 - this.m_Es * sin_phi * sin_phi;
var n = this.m_arMajor / Math.sqrt(con);
var ml = this.m_arMajor * this.mlfn(this.e0fn(this.m_Es), this.e1fn(this.m_Es), this.e2fn(this.m_Es), this.e3fn(this.m_Es), in_pt.y);
out_pt.x = this.m_arScaleFactor[this.dsttype] * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + t * t + 72.0 * c - 58.0 * this.m_Esp))) + this.m_arFalseEasting[this.dsttype];
out_pt.y = this.m_arScaleFactor[this.dsttype] * (ml - this.dst_m + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * c * c + als / 30.0 * (61.0 - 58.0 * t + t * t + 600.0 * c - 330.0 * this.m_Esp))))) + this.m_arFalseNorthing[this.dsttype];
}
GeoTrans.prototype.tm2geo = function(in_pt, out_pt) {
var max_iter = 6;
if(this.m_Ind != 0) {
var f = Math.exp(in_pt.x / (this.m_arMajor * this.m_arScaleFactor[this.srctype]));
var g = 0.5 * (f - 1.0 / f);
var temp = this.m_arLatCenter[this.srctype] + in_pt.y / (this.m_arMajor * this.m_arScaleFactor[this.srctype]);
var h = Math.cos(temp);
var con = Math.sqrt((1.0 - h * h) / (1.0 + g * g));
out_pt.y = asinz(con);
if(temp < 0) out_pt.y *= -1;
if((g == 0) && (h == 0)) {
out_pt.x = this.m_arLonCenter[this.srctype];
} else {
out_pt.x = Math.atan(g / h) + this.m_arLonCenter[this.srctype];
}
}
in_pt.x -= this.m_arFalseEasting[this.srctype];
in_pt.y -= this.m_arFalseNorthing[this.srctype];
var con = (this.src_m + in_pt.y / this.m_arScaleFactor[this.srctype]) / this.m_arMajor;
var phi = con;
var i = 0;
while(true) {
var delta_Phi = ((con + this.e1fn(this.m_Es) * Math.sin(2.0 * phi) - this.e2fn(this.m_Es) * Math.sin(4.0 * phi) + this.e3fn(this.m_Es) * Math.sin(6.0 * phi)) / this.e0fn(this.m_Es)) - phi;
phi = phi + delta_Phi;
if(Math.abs(delta_Phi) <= this.EPSLN) break;
if(i >= max_iter) {
alert("무한대 에러");
break;
}
i++;
}
if(Math.abs(phi) < (Math.PI / 2)) {
var sin_phi = Math.sin(phi);
var cos_phi = Math.cos(phi);
var tan_phi = Math.tan(phi);
var c = this.m_Esp * cos_phi * cos_phi;
var cs = c * c;
var t = tan_phi * tan_phi;
var ts = t * t;
var con = 1.0 - this.m_Es * sin_phi * sin_phi;
var n = this.m_arMajor / Math.sqrt(con);
var r = n * (1.0 - this.m_Es) / con;
var d = in_pt.x / (n * this.m_arScaleFactor[this.srctype]);
var ds = d * d;
out_pt.y = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * this.m_Esp - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * this.m_Esp - 3.0 * cs)));
out_pt.x = this.m_arLonCenter[this.srctype] + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * this.m_Esp + 24.0 * ts))) / cos_phi);
} else {
out_pt.y = Math.PI * 0.5 * Math.sin(in_pt.y);
out_pt.x = this.m_arLonCenter[this.srctype];
}
}
GeoTrans.prototype.getDistancebyGeo = function(pt1, pt2) {
var lat1 = this.D2R(pt1.y);
var lon1 = this.D2R(pt1.x);
var lat2 = this.D2R(pt2.y);
var lon2 = this.D2R(pt2.x);
var longitude = lon2 - lon1;
var latitude = lat2 - lat1;
var a = Math.pow(Math.sin(latitude / 2.0), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(longitude / 2.0), 2);
return 6376.5 * 2.0 * Math.atan2(Math.sqrt(a), Math.sqrt(1.0 - a));
}
GeoTrans.prototype.getDistancebyKatec = function(pt1, pt2) {
var geo = new GeoTrans("katec", "geo");
pt1 = geo.conv(pt1);
pt2 = geo.conv(pt2);
return this.getDistancebyGeo(pt1, pt2);
}
GeoTrans.prototype.getTimebySec = function(distance) {
return Math.round(3600 * distance / 4);
}
GeoTrans.prototype.getTimebyMin = function(distance) {
return Number(Math.ceil(this.getTimebySec(distance) / 60));
}
var geo = new GeoTrans();
geo.init("katec", "geo");
var pt = new Point(306151, 556443);
var out_pt = geo.conv(pt);
alert("경도 : "+out_pt.x+"\n위도 : "+out_pt.y);
//역변환
geo.init("geo", "katec");
out_pt = geo.conv(out_pt);
alert("[KATEC 좌표]\nx : "+out_pt.x+"\ny : "+out_pt.y);
기타 참고 URL
http://aero.sarang.net/map/analysis.html
http://aero.sarang.net/map/coordinate_naver.html
http://code.google.com/intl/ko/apis/maps/
http://dev.naver.com/openapi/apis/map/javascript/reference
|
|
댓글목록
등록된 댓글이 없습니다.





GEO <-> KATEC 변환