ユニバーサル横メルカトル(UTM)座標系と平面直角座標系で投影した際の、指定した緯度経度における方位角と縮尺係数を求める計算フォームです。計算式は国土地理院の論文を参考にし、一部パラメーターを変更して UTM座標系にも対応させています。
計算フォーム
パラメーター入力
ユニバーサル横メルカトル座標系
平面直角座標系
座標帯番号
NS
度分秒(ddmmss.ssss)
十進経緯度(dd.ddddd)
緯度
経度
計算結果
座標帯番号 |
|
緯度 |
|
経度 |
|
X(横軸) |
|
Y(縦軸) |
|
γ(方位角) |
|
m(縮尺係数) |
|
function sinh(x) { return 0.5*(Math.exp(x)-Math.exp(-x)) }
function cosh(x) { return 0.5*(Math.exp(x)+Math.exp(-x)) }
function arctanh(x) { return 0.5*Math.log((1+x)/(1-x)) }
$(function($) {
// 数字のみ入力(0~9, テンキ―0~9 . , スペース, backspace, delete, →, ←, - Ctrl, Shift 以外は入力キャンセル)
function myRound(val, precision) {
digit = Math.pow(10, precision);
val = val * digit; val = Math.round(val);
val = val / digit; return val;
}
$("input[type='text'].dms2dd").on('keydown', function(e) {
var k = e.keyCode;
if (!((k >= 48 && k = 96 && k <= 105) || k == 32 || k == 8 || k == 46 || k == 39 || k == 37 || k == 189 || k == 9 || k == 16 || k == 67 || k == 86 || k == 88 || k == 109 || k == 110)) {
return false;
}
});
// UTM←→平面直角座標系 切り替え
$('input[name="type1"]:radio' ).change( function() {
if($(this).val() == "utm"){
$('#kei_name').val("utm");
$('#kei_name').text("座標帯番号");
$('#output0').text("座標帯番号");
$('#kei_no').val("54");
$('#ns').show();
}else{
$('#kei_name').val("19kei");
$('#kei_name').text("座標系番号");
$('#output0').text("座標系番号");
$('#kei_no').val("9");
$('#ns').hide();
}
});
// 初期化
$('#btn_clear').click(function() {
$('#lat_text').val('353929.1572');
$('#lon_text').val('1394428.8869');
$('input:radio[name="type1"]').val(["utm"]);
$('input:radio[name="type2"]').val(["nn"]);
$('input:radio[name="type3"]').val(["dms"]);
});
//計算 ボタンクリック
$('#submit').click(function() {
a=6378137; // 赤道半径
rf=298.257222101; // 扁平率の逆数
m0=0.9999; // 中央子午線の縮尺係数
s2r=Math.PI/648000 ;
if($('input:radio[name="type1"]:checked').val() == "utm"){
m0=0.9996; //中央子午線上の縮尺係数
// UTMの座標系原点の緯度を度単位で、経度を分単位で格納
phi0=[0];
lmbd0=[0];
for(let i=-177; i<178; i=i+6){
phi0.push(0);
lmbd0.push(i*60);
}
}
else{
m0=0.9999;//中央子午線上の縮尺係数
// 平面直角座標の座標系原点の緯度を度単位で、経度を分単位で格納
phi0=[0,33,33,36,33,36,36,36,36,36,40,44,44,44,26,26,26,26,20,26];
lmbd0=[0,7770,7860,7930,8010,8060,8160,8230,8310,8390,8450,8415,8535,8655,8520,7650,7440,7860,8160,9240];
}
n=0.5/(rf-0.5);
n15=1.5*n;
anh=0.5*a/(1+n);
nsq=n*n;
e2n=2*Math.sqrt(n)/(1+n);
ra=2*anh*m0*(1+nsq/4+nsq*nsq/64);
jt=5;
jt2=2*jt;
ep=1.0;
e=[]; s=[0.0]; t=[]; alp=[];
for(k=1; k<=jt; k++) { ep*=e[k]=n15/k-n ; e[k+jt]=n15/(k+jt)-n }
// 展開パラメータの事前入力
alp[1]=(1/2+(-2/3+(5/16+(41/180-127/288*n)*n)*n)*n)*n
alp[2]=(13/48+(-3/5+(557/1440+281/630*n)*n)*n)*nsq
alp[3]=(61/240+(-103/140+15061/26880*n)*n)*n*nsq
alp[4]=(49561/161280-179/168*n)*nsq*nsq
alp[5]=34729/80640*n*nsq*nsq
// 該当緯度の 2 倍角の入力により赤道からの子午線弧長を求める関数
function Merid(phi2) {
dc=2.0*Math.cos(phi2) ; s[1]=Math.sin(phi2);
for(i=1; i<=jt2; i++) { s[i+1]=dc*s[i]-s[i-1] ; t[i]=(1.0/i-4.0*i)*s[i] };
sum=0.0 ; c1=ep ; j=jt;
while(j) {
c2=phi2 ; c3=2.0 ; l=j ; m=0;
while(l) {
c2+=(c3/=e[l--])*t[++m]+(c3*=e[2*j-l])*t[++m]
}
sum+=c1*c1*c2 ; c1/=e[j--];
}
return anh*(sum+phi2)
}
// 与件入力
num= Number($('#kei_no').val()); // 座標帯/系番号
phi= Number($('#lat_text').val()); // 緯度 ddmmss.ssss
lmbd= Number($('#lon_text').val()); // 経度 dddmmss.ssss
if($('input:radio[name="type3"]:checked').val() == "dd"){
//十進経緯度
phirad=phi*3600*s2r;
lmbdsec = lmbd * 60 * 60;
}
else{
//度分秒
phideg=Math.floor(phi/10000);
phimin=Math.floor((phi-phideg*10000)/100);
lmbddeg=Math.floor(lmbd/10000);
lmbdmin=Math.floor((lmbd-lmbddeg*10000)/100);
phirad=(phideg*3600+phimin*60+phi-phideg*10000-phimin*100)*s2r;
lmbdsec=lmbddeg*3600+lmbdmin*60+lmbd-lmbddeg*10000-lmbdmin*100;
}
// 実際の計算実行部分
sphi=Math.sin(phirad);
nphi=(1-n)/(1+n)*Math.tan(phirad);
dlmbd=(lmbdsec-lmbd0[num]*60)*s2r;
sdlmbd=Math.sin(dlmbd);
cdlmbd=Math.cos(dlmbd);
tchi=sinh(arctanh(sphi)-e2n*arctanh(e2n*sphi)) ;
cchi=Math.sqrt(1+tchi*tchi);
xi=xip=Math.atan2(tchi, cdlmbd);
eta=etap=arctanh(sdlmbd/cchi);
sgm=1;
tau=0;
for(j=alp.length; --j; ) {
alsin=alp[j]*Math.sin(2*j*xip);
alcos=alp[j]*Math.cos(2*j*xip);
xi+=alsin*cosh(2*j*etap);
eta+=alcos*sinh(2*j*etap);
sgm+=2*j*alcos*cosh(2*j*etap);
tau+=2*j*alsin*sinh(2*j*etap);
}
x=ra*eta; // 平面直角座標系Y
y=ra*xi-m0*Merid(2*phi0[num]*3600*s2r); // 平面直角座標系X
gmm=Math.atan2(tau*cchi*cdlmbd+sgm*tchi*sdlmbd, sgm*cchi*cdlmbd-tau*tchi*sdlmbd);
m=ra/a*Math.sqrt((sgm*sgm+tau*tau)/(tchi*tchi+cdlmbd*cdlmbd)*(1+nphi*nphi));
// ラジアン → 度分秒変換
sgn=(gmm<0);
gdo=Math.floor(gmm/s2r/3600)+sgn;
gfun=Math.floor((gmm/s2r-gdo*3600)/60)+sgn;
gbyou=gmm/s2r-gdo*3600-gfun*60;
//UTM 東距
if($('input:radio[name="type1"]:checked').val() == "utm"){
x=x+500000;
if($('input:radio[name="type2"]:checked').val() == "ss"){
y=y+10000000;
}
}
// 結果表示
// $('#output').empty();
// $('#output').append("計算結果
");
// $('#output').append("座標帯/系番号:" + num + "
緯度:" + phi + "
経度:" + lmbd +"
");
// $('#output').append("X(横):" + x + " m
Y(縦):" + y + " m
");
// $('#output').append("γ(方位角):" + (sgn?"-":"+") + Math.abs(gdo) + "°" + Math.abs(gfun) + "′" + Math.abs(gbyou) + "″
");
// $('#output').append("m(縮尺係数):" + m);
$('#output0').text($('#kei_name').text());
$('#output1').text(num);
$('#output2').text(phi + " " + $('input:radio[name="type3"]:checked').val());
$('#output3').text(lmbd + " " +$('input:radio[name="type3"]:checked').val());
$('#output4').text(x+" m");
$('#output5').text(y+" m");
$('#output6').text((sgn?"-":"+") + Math.abs(gdo) + "°" + Math.abs(gfun) + "′" + Math.abs(gbyou));
$('#output7').text(m);
});
});
参考文献