CINXE.COM
地理院地図3D
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>地理院地図3D</title> <!-- jquery --> <script type="text/javascript" src="https://cyberjapandata.gsi.go.jp/3d/site/jquery-1.9.1.js"></script> <!-- jquery UI --> <script type="text/javascript" src="https://cyberjapandata.gsi.go.jp/3d/site/jquery-ui.js"></script> <link rel="stylesheet" href="https://cyberjapandata.gsi.go.jp/3d/site/jquery-ui.css"> <link rel="stylesheet" href="https://cyberjapandata.gsi.go.jp/3d/site/style.css"> <!-- leaflet --> <script type="text/javascript" src="./leaflet/leaflet.js"></script> <link rel="stylesheet" href="./leaflet/leaflet.css"> <!--[if lte IE 8]><link rel="stylesheet" href="./leaflet/leaflet.ie.css" /><![endif]--> <!-- three.js --> <script type="text/javascript" src="https://cyberjapandata.gsi.go.jp/3d/three.min.js"></script> <script type="text/javascript" src="https://cyberjapandata.gsi.go.jp/3d/TrackballControls.js"></script> <!-- proj4js.js --> <script type="text/javascript" src="https://cyberjapandata.gsi.go.jp/3d/site/proj4js-combined.js"></script> <style> body {padding: 0; margin: 0} html, body, #canvas4map {height: 100%; width: 100%;} .leaflet-container {background: #fff;} .ui-dialog {z-index: 65535;} </style> <script type="text/javascript"> //Proj4js用 var s_EPSG = new Proj4js.Proj('EPSG:4326'); var t_EPSG = new Proj4js.Proj('EPSG:900913'); //var tileBaseURL4dem = "http://geolib.gsi.go.jp/tiles3d/xyz/"; //var tileBaseURL4img = "http://geolib.gsi.go.jp/tiles3d/xyz/"; var tileBaseURL4dem = "https://cyberjapandata.gsi.go.jp/xyz/" var tileBaseURL4img = "https://cyberjapandata.gsi.go.jp/xyz/" var map; var currentLayerUrlTemplate; var tileURL_cjp = tileBaseURL4img + "std/{z}/{x}/{y}.png"; // 標準地図 var tile_cjp = L.tileLayer(tileURL_cjp, { attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>国土地理院</a>", errorTileUrl:'./no_image.png', maxZoom: 14 // ズームレベル14を最大に設定 }); var tileURL_ort = tileBaseURL4img + "ort/{z}/{x}/{y}.jpg"; // オルソ画像 var tile_ort = L.tileLayer(tileURL_ort, { attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>国土地理院</a>", errorTileUrl:'./no_image.png', maxZoom: 14 // ズームレベル14を最大に設定 }); var tileURL_cjp = tileBaseURL4img + "gazo1/{z}/{x}/{y}.jpg"; // 国土画像情報(第一期:1974~1978年撮影) var tile_gazo1 = L.tileLayer(tileURL_cjp, { attribution: "<a href='http://portal.cyberjapan.jp/help/termsofuse.html' target='_blank'>国土地理院</a>", errorTileUrl:'./no_image.png', maxZoom: 14 // ズームレベル14を最大に設定 }); var kvp; function GetKVP(){ if (1 < document.location.search.length) { var query = document.location.search.substring(1); var parameters = query.split('&'); var res = new Object(); for (var i = 0; i < parameters.length; i++) { var element = parameters[i].split('='); var paramName = decodeURIComponent(element[0]); var paramValue = decodeURIComponent(element[1]); res[paramName] = decodeURIComponent(paramValue); } return res; } return null; } function init_map(){ kvp = GetKVP(); map = L.map('canvas4map'); map.addEventListener("baselayerchange", function(e){ currentLayerUrlTemplate = e.layer._url; }); if( kvp ){ map.setView([parseFloat(kvp["lat"]), parseFloat(kvp["lon"])], parseInt(kvp["z"])); if( kvp["did"] == "gazo1" ){ tile_gazo1.addTo(map); currentLayerUrlTemplate = tile_gazo1._url; } else if( kvp["did"] == "ort" ){ tile_ort.addTo(map); currentLayerUrlTemplate = tile_ort._url; } else{ tile_cjp.addTo(map); currentLayerUrlTemplate = tile_cjp._url; } } else{ map.setView([36.225415, 140.106726], 14); // 筑波山 tile_cjp.addTo(map); currentLayerUrlTemplate = tile_cjp._url; } var baseLayers = { "標準地図": tile_cjp, "写真(最新)": tile_ort, "写真(1974~1978年撮影)":tile_gazo1 }; L.control.layers(baseLayers, null).addTo(map); L.control.scale().addTo(map); // leafletのレイヤパネルを非表示にする。 //$(".leaflet-control-layers").css("display", "none"); Init3DFrame(); if( kvp ){ s = 1; Show3DModel(); } } ////////////////////////// // 地図計算関係 function GetTileIDX(zoom, longitude){ var lng_rad = longitude * Math.PI / 180; var R = 128 / Math.PI; var worldCoordX = R * (lng_rad + Math.PI); var pixelCoordX = worldCoordX * Math.pow(2, zoom); var tileCoordX = Math.floor( pixelCoordX / 256); return tileCoordX; } function GetTileIDY(zoom, latitude){ var lat_rad = latitude * Math.PI / 180; var R = 128 / Math.PI; var worldCoordY = - R / 2 * Math.log( (1 + Math.sin(lat_rad)) / (1 - Math.sin(lat_rad)) ) +128; var pixelCoordY = worldCoordY * Math.pow(2, zoom); var tileCoordY = Math.floor( pixelCoordY / 256); return tileCoordY; } function GetTile2Lng(x,z) { return (x/Math.pow(2,z)*360-180); } function GetTile2Lat(y,z) { var n=Math.PI-2*Math.PI*y/Math.pow(2,z); return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n)))); } function CalcLatitudinallyDistance(lng1, lng2, lat){ R = 6378137.0; return 2*Math.PI*R * (Math.abs(lng1-lng2)/360.0) * Math.cos(lat/180.0*Math.PI); } //////////////////////////////////////////////////// // HTTP経由のテキストファイル読出し function getTextFile(fname){ var text=null; var ajax=new XMLHttpRequest(); with(ajax){ onload = function () { readyState==4 && status==200 && (text=responseText); }; open('GET',fname,false); send(null); }; return text; } //////////////////////////////////////////////////// // 標高タイルを配列に格納 function SetArrayOfDemVals(z, ltX, ltY, nTilesX, nTilesY, exLat, exLng){ /** プログレスバーの初期値 **/ pStart = $( "#progressbar" ).progressbar( "option", "value" ); var texts = ""; var nTilesOTS = nTilesX; var demVals = new Array(256*nTilesOTS*256*nTilesOTS); var arrayOfDemTile; for(i=0; i<nTilesOTS; i++){ for(j=0; j<nTilesOTS; j++){ /** プログレスバーを進める **/ var p = pStart + (i*nTilesOTS+j)/(nTilesOTS*nTilesOTS)*60; $( "#progressbar" ).progressbar("value", p); yTile = i + ltY; xTile = j + ltX; try{ // 標準の標高タイルを読み込む。 texts = getTextFile(tileBaseURL4dem + "dem/" + z + "/" + xTile + "/" + yTile + ".txt"); texts = texts.replace(/\n/g,","); arrayOfDemTile = texts.split(","); for(k=0; k<256; k++){ for(l=0; l<256; l++){ valDem = arrayOfDemTile[256*k+l]; if(valDem == "e"){ valDem = 0; } demVals[256*nTilesOTS*(256*i+k)+(256*j+l)] = valDem; } } } catch(e){ // 標準の標高タイルがない場合の例外処理 // 結局タイルが見つからない場合は、標高値を0とする。 for(k=0; k<256; k++){ for(l=0; l<256; l++){ demVals[256*nTilesOTS*(256*i+k)+(256*j+l)] = 0; } } } } } return demVals; } //////////////////////////////////////////////////// // 標高タイルを正規化(一定のメッシュに間引く)。 // ・頂点配列を257x257で固定 // ・縦横257列目は256列目をコピー function NormarizeArrayOfDemVals257(arrayOfDemVals, nTilesX, nTilesY){ var nTilesOTS = nTilesX; var arrayOfMesh = new Array(257*257); for(n=0; n<=256; n++){ for(m=0; m<=256; m++){ if( m == 256 ){ arrayOfMesh[n*257+m] = arrayOfMesh[n*257+m-1]; } else if( n == 256 ){ arrayOfMesh[n*257+m] = arrayOfMesh[(n-1)*257+m]; } else{ arrayOfMesh[n*257+m] = arrayOfDemVals[n*nTilesOTS*256*nTilesOTS+m*nTilesOTS]; } } } return arrayOfMesh; } ////////////////////////// // 3Dモデル用外部パラメータ var widthFrame; var heightFrame; var renderer = null; var scene = null; var camera = null; var light = null; var mesh = null; var meshBase = null; var meshSide1 = null; var meshSide2 = null; var meshSide3 = null; var meshSide4 = null; var ratioDd; var arrayOfMesh = null; var controls = null; var camPosX, camPosY, camPosZ, camUpX, camUpY, camUpZ, camRotX, camRotY, camRotZ; //////////////////////////////////////////////// // 標高値に合わせてジオメトリの形状を変更する。 function SetGeometryZ(arrayOfMesh, ratioDd, a){ for(k=0; k<=256; k++){ for(l=0; l<=256; l++){ mesh.geometry.vertices[k*257+l].z = arrayOfMesh[k*257+l] * ratioDd * a; } } mesh.geometry.computeFaceNormals(); mesh.geometry.computeVertexNormals(); mesh.geometry.dynamic = true; mesh.geometry.verticesNeedUpdate = true; for(i=0; i<257; i++){ meshSide1.geometry.vertices[i].z = mesh.geometry.vertices[257*256+i].z; } meshSide1.geometry.verticesNeedUpdate = true; meshSide1.geometry.computeFaceNormals(); meshSide1.geometry.computeVertexNormals(); meshSide1.geometry.dynamic = true; for(i=0; i<257; i++){ meshSide2.geometry.vertices[i].z = mesh.geometry.vertices[257*i].z; } meshSide2.geometry.verticesNeedUpdate = true; meshSide2.geometry.computeFaceNormals(); meshSide2.geometry.computeVertexNormals(); meshSide2.geometry.dynamic = true; for(i=0; i<257; i++){ meshSide3.geometry.vertices[i].z = mesh.geometry.vertices[257*(256-i)+256].z; } meshSide3.geometry.verticesNeedUpdate = true; meshSide3.geometry.computeFaceNormals(); meshSide3.geometry.computeVertexNormals(); meshSide3.geometry.dynamic = true; for(i=0; i<257; i++){ meshSide4.geometry.vertices[i].z = mesh.geometry.vertices[256-i].z; } meshSide4.geometry.verticesNeedUpdate = true; meshSide4.geometry.computeFaceNormals(); meshSide4.geometry.computeVertexNormals(); meshSide4.geometry.dynamic = true; } //////////////////////////////////////////////// // 箱のメッシュを設定する。 function SetBox(){ var material = new THREE.MeshPhongMaterial({color: 0xffffff, ambient: 0xffffff, specular: 0xcccccc, shininess:50, metal:true}); // 底面を追加 var geometry = new THREE.PlaneGeometry( 100, 100, 1, 1 ); for(i=0; i<geometry.vertices.length; i++){ geometry.vertices[i].z = -1 * ratioDd * 100; } geometry.vertices[0].y = -50; geometry.vertices[1].y = -50; geometry.vertices[2].y = 50; geometry.vertices[3].y = 50; geometry.computeFaceNormals(); geometry.computeVertexNormals(); geometry.dynamic = true; geometry.verticesNeedUpdate = true; meshBase = new THREE.Mesh( geometry, material ) scene.add(meshBase); // 側面1を追加 geometry = new THREE.PlaneGeometry( 100, 1, 256, 1 ); for(i=0; i<geometry.vertices.length; i++){ if((0 <= i) && (i <= 256)){ geometry.vertices[i].z = mesh.geometry.vertices[257*256+i].z; } else{ geometry.vertices[i].z = -1 * ratioDd * 100; } geometry.vertices[i].y = -50; } meshSide1 = new THREE.Mesh( geometry, material ) scene.add(meshSide1); // 側面2を追加 geometry = new THREE.PlaneGeometry( 100, 1, 256, 1 ); for(i=0; i<geometry.vertices.length; i++){ if((0 <= i) && (i <= 256)){ geometry.vertices[i].z = mesh.geometry.vertices[i*257].z; } else{ geometry.vertices[i].z = -1 * ratioDd * 100; } geometry.vertices[i].x = -50; geometry.vertices[i].y = 50-100/256*(i%257); } meshSide2 = new THREE.Mesh( geometry, material ) scene.add(meshSide2); // 側面3を追加 geometry = new THREE.PlaneGeometry( 100, 1, 256, 1 ); for(i=0; i<geometry.vertices.length; i++){ if((0 <= i) && (i <= 256)){ geometry.vertices[i].z = mesh.geometry.vertices[257*(256-i)+256].z; } else{ geometry.vertices[i].z = -1 * ratioDd * 100; } geometry.vertices[i].x = 50; geometry.vertices[i].y = -50+100/256*(i%257); } meshSide3 = new THREE.Mesh( geometry, material ) scene.add(meshSide3); // 側面4を追加 geometry = new THREE.PlaneGeometry( 100, 1, 256, 1 ); for(i=0; i<geometry.vertices.length; i++){ if((0 <= i) && (i <= 256)){ geometry.vertices[i].z = mesh.geometry.vertices[256-i].z; } else{ geometry.vertices[i].z = -1 * ratioDd * 100; } geometry.vertices[i].x = 50-100/256*(i%257); geometry.vertices[i].y = 50; } meshSide4 = new THREE.Mesh( geometry, material ) scene.add(meshSide4); } //////////////////////////////////////////////// // 3Dモデル(レンダラ―)の初期化 function Init3DFrame(){ widthFrame = $(document).width()-100; heightFrame = $(document).height()-220; document.getElementById("canvas4frame").style.width = widthFrame + "px"; document.getElementById("canvas4frame").style.height = heightFrame + "px"; renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(widthFrame, heightFrame); renderer.setClearColorHex(0xe6e6fa); //renderer.shadowMapEnabled = true; document.getElementById('canvas4frame').appendChild(renderer.domElement); } var centerLat, centerLng; var z; var ltLat; var ltLng; var rbLat; var rbLng; var ltX; var ltY; var rbX; var rbY; var nTilesOTS; var distBLine; var s; //////////////////////////////////////////////// // 3Dモデル(レンダラ―)の表示 function Show3DFrame(){ var centerPos = map.getCenter(); centerLat = centerPos.lat; centerLng = centerPos.lng; /** プログレスバーを初期化 **/ $( "#progressbar" ).show(); $( "#progressbar" ).progressbar("value", 0); // 3Dモデル化のタイル範囲を決める。 // 表示している地図の範囲のタイルを並べたものの長辺を基準とした正方形を範囲とする。 var bbox = map.getBounds(); z = map.getZoom(); var ltLat = bbox.getNorthEast().lat; var ltLng = bbox.getSouthWest().lng; var rbLat = bbox.getSouthWest().lat; var rbLng = bbox.getNorthEast().lng; ltX = GetTileIDX(z, ltLng); ltY = GetTileIDY(z, ltLat); rbX = GetTileIDX(z, rbLng); rbY = GetTileIDY(z, rbLat); var nTilesX = rbX - ltX + 1; var nTilesY = rbY - ltY + 1; nTilesOTS = Math.max(nTilesX, nTilesY); nTilesOTS = 4; //4で固定 //nTilesOTSによってタイル番号等を再計算 rbLng = GetTile2Lng(ltX + nTilesOTS - 1, z); rbLat = GetTile2Lat(ltY + nTilesOTS - 1, z); rbX = GetTileIDX(z, rbLng); rbY = GetTileIDY(z, rbLat); // 高さ方向の倍率計算の為、3Dモデル下辺の実距離を求める。 var lng1 = GetTile2Lng(ltX ,z); var lng2 = GetTile2Lng(ltX+nTilesOTS,z); var lat = GetTile2Lat(ltY+nTilesOTS,z); distBLine = CalcLatitudinallyDistance(lng1,lng2,lat); // キャンバスへの画像取り込み処理1 ProcTextureImg2Canvas1(); } function ProcTextureImg2Canvas1(){ // 読み込むテクスチャ画像のズームレベルのシフト量 // ・一つ大きいのズームレベルのものを使う場合は1 // 例: 標高のズームレベル=14、テクスチャ画像のズームレベル=16の場合は、シフト量=2 // 現在は、"{z}/{x}/{y}"形式のURLのみ対応。 // タイル画像を読み込む。 LoadTiles4TextureImage(z+s, ltX*Math.pow(2,s), ltY*Math.pow(2,s), nTilesOTS*Math.pow(2,s)); // 画像タイルの読み込み完了を待つ。 var intv = setInterval(function(){ if( nTilesOTS*Math.pow(2,s)*nTilesOTS*Math.pow(2,s) <= arrayOfImages.length ){ // もし画像が全て読み込みを完了したら、タイマーをリセットし、次の処理へ進む。 clearInterval(intv); ProcTextureImg2Canvas2(z+s, ltX*Math.pow(2,s), ltY*Math.pow(2,s), nTilesOTS*Math.pow(2,s)); } else{ } }, 100); } var arrayOfImages = []; function LoadTiles4TextureImage(z, ltX, ltY, nTilesOTS){ arrayOfImages = []; // テクスチャ画像を読み取り先URLの前準備 // 現在は、"{z}/{x}/{y}"形式のURLのみ対応。 var imgURLTemplate = currentLayerUrlTemplate; // 現在表示しているレイヤの情報を取得する。 var arrayOfImgURLtemplate = imgURLTemplate.replace("\{z\}\/\{x\}\/\{y\}", "*").split("*"); var imgURLbase = arrayOfImgURLtemplate[0]; // タイル画像の読み込み先URLを設定する。 var imgURLext = arrayOfImgURLtemplate[1]; // タイル画像の拡張子を設定する。 for(var n=0; n<nTilesOTS; n++){ for(var m=0; m<nTilesOTS; m++){ var XX = ltX + m; var YY = ltY + n; var imgURL = imgURLbase + z + "/" + XX + "/" + YY + imgURLext; var img = new Image(); img.src = imgURL; //img.crossOrigin = ""; img.crossOrigin = "anonymous"; img.onload = function(){ arrayOfImages.push(this); } img.onerror = function(){ arrayOfImages.push(this); } } } } function ProcTextureImg2Canvas2(z, ltX, ltY, nTilesOTS){ var cvs4imgproc = document.getElementById("canvas4imgproc"); var cvsWidth = cvs4imgproc.width; var cvsHeight = cvs4imgproc.height; cvs4imgproc.onchange = function(){ alert("canvas"); } var ctx4imgproc = cvs4imgproc.getContext("2d"); ctx4imgproc.fillStyle = "rgb(255, 255, 255)"; ctx4imgproc.fillRect(0, 0, cvsWidth, cvsHeight); var wTileImg = cvsWidth / nTilesOTS; var hTileImg = cvsHeight / nTilesOTS; var strRgx = currentLayerUrlTemplate; strRgx = strRgx.replace("{z}", "(\\d\+)"); strRgx = strRgx.replace("{x}", "\\d\+"); strRgx = strRgx.replace("{y}", "\\d\+"); var rgxZfromURL = new RegExp(strRgx); var strRgx = currentLayerUrlTemplate; strRgx = strRgx.replace("{z}", "\\d\+"); strRgx = strRgx.replace("{x}", "(\\d\+)"); strRgx = strRgx.replace("{y}", "\\d\+"); var rgxXfromURL = new RegExp(strRgx); var strRgx = currentLayerUrlTemplate; strRgx = strRgx.replace("{z}", "\\d\+"); strRgx = strRgx.replace("{x}", "\\d\+"); strRgx = strRgx.replace("{y}", "(\\d\+)"); var rgxYfromURL = new RegExp(strRgx); for(var i=0; i<arrayOfImages.length; i++){ var imgURL = arrayOfImages[i].src; var zz = -1; var xx = -1; var yy = -1; if( rgxZfromURL.test(imgURL) ){ zz = RegExp.$1; } if( rgxXfromURL.test(imgURL) ){ xx = RegExp.$1; } if( rgxYfromURL.test(imgURL) ){ yy = RegExp.$1; } var n = xx - ltX; var m = yy - ltY; try{ ctx4imgproc.drawImage(arrayOfImages[i], 0,0,256,256,n*wTileImg,m*hTileImg,wTileImg,hTileImg); } catch(e){ } } //ctx4imgproc.save(); //ctx4imgproc.restore(); //cvs4imgproc.style.display = "block"; Show3DFrame2(); } function Show3DFrame2(){ // シーンの設定 scene = new THREE.Scene(); // 環境光の設置 scene.add(new THREE.AmbientLight(0x111111)); // 平行光源の設置 light = new THREE.DirectionalLight(0xFFFFFF, 1.0, 0); light.position.set(100, -200, 200); scene.add(light); // カメラ(視点)の設定 camera = new THREE.PerspectiveCamera(45, widthFrame/heightFrame, 1, 10000); if( kvp && kvp["cpx"] ){ camera.position.set(parseFloat(kvp["cpx"]), parseFloat(kvp["cpy"]), parseFloat(kvp["cpz"])); camera.up.set(parseFloat(kvp["cux"]), parseFloat(kvp["cuy"]), parseFloat(kvp["cuz"])); } else{ camera.position.set(0, -100, 100); camera.up.set(0, 0, 1); camera.lookAt( {x:0, y:0, z:0 } ); } // 高さ方向の倍率の計算 document.getElementById("ratioZ").value = 1.0; // デフォルトを1とする。 ratioDd = 100 / distBLine; // 実距離1mの3D空間上の長さ var a = 1; // 高さ方向の倍率 if( kvp && kvp["a"] ){ a = parseFloat(kvp["a"]); document.getElementById("ratioZ").value = a; } else{ a = parseFloat(document.getElementById("ratioZ").value); } /** プログレスバーを進める **/ $( "#progressbar" ).progressbar("value", 10); // 範囲内の標高タイルを配列に読み込む。 var arrayOfDemVals = SetArrayOfDemVals(z, ltX, ltY, nTilesOTS, nTilesOTS, rbLat, ltLng); // 標高タイルを正規化する(一定のメッシュに間引く)。 // 計算が簡単になるよう、256x256のメッシュ(頂点は257x257)とする。 arrayOfMesh = NormarizeArrayOfDemVals257(arrayOfDemVals, nTilesOTS, nTilesOTS); // メッシュ状ジオメトリを作成する。 var geometry = new THREE.PlaneGeometry( 100, 100, 256, 256 ); var cvs4imgproc = document.getElementById("canvas4imgproc"); var texture = new THREE.Texture(cvs4imgproc); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({map: texture}); // 地形表面のメッシュを作成、登録する。 mesh = new THREE.Mesh( geometry, material ) scene.add(mesh); // 箱を付ける。 SetBox(); // 標高値に合わせてメッシュ形状を変化させる。 SetGeometryZ(arrayOfMesh, ratioDd, a); // マウス操作のためのプラグイン controls = new THREE.TrackballControls(camera, document.getElementById("canvas4frame")); if( kvp && kvp["ctx"] ){ controls.target.x = parseFloat(kvp["ctx"]); controls.target.y = parseFloat(kvp["cty"]); controls.target.z = parseFloat(kvp["ctz"]); } /** プログレスバーを消去 **/ $( "#progressbar" ).hide(); // 表示用ウィンドウのUIを設定 $( "#canvas4frame4dlg" ).dialog({ width: widthFrame + 30, height: heightFrame + 220, modal: true, resizable: true, resizeStop: function( event, ui ) { widthFrame = ui.size.width - 30; heightFrame = ui.size.height - 220; // 表示用キャンバスサイズの再設定 document.getElementById("canvas4frame").style.width = widthFrame + "px"; document.getElementById("canvas4frame").style.height = heightFrame + "px"; renderer.setSize(widthFrame, heightFrame); // レンダラ―画面の再設定 camera.aspect = widthFrame/heightFrame; // カメラのアスペクト比の再調整 camera.updateProjectionMatrix(); render(); // 再描画 }, close: function( event, ui ) { document.getElementById('urlHttpLink').innerHTML = ""; // オブジェクトの破棄 if( mesh ){ if (mesh.geometry) { mesh.geometry.dispose(); } if (mesh.materials) { for(var i=0; i<scene.material.materials.length; i++){ mesh.material.materials[i].dispose(); } mesh.material.dispose(); } } if( meshBase ){ if (meshBase.geometry) { meshBase.geometry.dispose(); } } if( meshSide1 ){ if (meshSide1.geometry) { meshSide1.geometry.dispose(); } } if( meshSide2 ){ if (meshSide2.geometry) { meshSide2.geometry.dispose(); } } if( meshSide3 ){ if (meshSide3.geometry) { meshSide3.geometry.dispose(); } } if( meshSide4 ){ if (meshSide4.geometry) { meshSide4.geometry.dispose(); } } } }); // 高さ方向調整用スライダーバーを設定 $( "#slider_ratioZ" ).slider({ value:1, min: 0, max: 10, step: 0.1, slide: function( event, ui ) { document.getElementById("ratioZ").value = ui.value; ChangeZratio(); }, stop: function( event, ui ) { document.getElementById("ratioZ").value = ui.value; ChangeZratio(); } }); // 高さ方向調整用テキストボックスにフォーカスが当たってしまうのを防止 document.getElementById("ratioZ").blur(); render(); // IEの背景色フリッカーを回避 render(); } function render(){ controls.update(); requestAnimationFrame(render); renderer.render(scene, camera); } function Show3DModel(){ Show3DFrame(); } function ChangeZratio(){ var strA = document.getElementById("ratioZ").value; if( isFinite(strA) ){ var a = parseFloat(strA); SetGeometryZ(arrayOfMesh, ratioDd, a); render(); $( "#slider_ratioZ" ).slider( "option", "value", a ); } else{ alert("数値を入力ください。"); } } // 処理状況を示すプログレスバーを用意 $(function() { $( "#progressbar" ).progressbar({ value: 0 }); $( "#progressbar" ).hide(); }); var urlhttplink = ""; function ShowUrlHttpLink(){ var imgURLTemplate = currentLayerUrlTemplate; // 現在表示しているレイヤの情報を取得する。 var strDid = ""; imgURLTemplate.match(/\/xyz\/(.+?)\/\{z\}\/\{x\}\/\{y\}/); strDid = RegExp.$1; camPosX = camera.position.x.toFixed(3); camPosY = camera.position.y.toFixed(3); camPosZ = camera.position.z.toFixed(3); camUpX = camera.up.x.toFixed(3); camUpY = camera.up.y.toFixed(3); camUpZ = camera.up.z.toFixed(3); camTgtX = controls.target.x.toFixed(3); camTgtY = controls.target.y.toFixed(3); camTgtZ = controls.target.z.toFixed(3); var a = parseFloat(document.getElementById("ratioZ").value); // 高さ方向の倍率 urlhttplink = "https://cyberjapandata.gsi.go.jp/3d/site/index.html?" + "did=" + strDid + "&lat=" + centerLat + "&lon=" + centerLng + "&z=" + z + "&cpx=" + camPosX + "&cpy=" + camPosY + "&cpz=" + camPosZ + "&cux=" + camUpX + "&cuy=" + camUpY + "&cuz=" + camUpZ + "&ctx=" + camTgtX + "&cty=" + camTgtY + "&ctz=" + camTgtZ + "&a=" + a; document.getElementById('urlHttpLink').innerHTML = urlhttplink; } //3Dデータの作成とダウンロード function dl_3D_Data(type) { document.getElementById('dl_three').disabled = true; var fileTypes = currentLayerUrlTemplate.split("."); var len = fileTypes.length; var aVal = document.getElementById('ratioZ').value; var textureZ = z + 1; //正方形にするためにタイルを増やす if((rbX - ltX) < (rbY - ltY)) rbX = rbX + ((rbY - ltY) - (rbX - ltX)); if((rbX - ltX) > (rbY - ltY)) rbY = rbY + ((rbX - ltX) - (rbY - ltY)); var ltMer = new Proj4js.Point(GetTile2Lng(ltX,z),GetTile2Lat(ltY,z)); Proj4js.transform(s_EPSG, t_EPSG, ltMer); var rbMer = new Proj4js.Point(GetTile2Lng(rbX + 1,z),GetTile2Lat(rbY + 1,z)); Proj4js.transform(s_EPSG, t_EPSG, rbMer); document.getElementById('wait').style.visibility = "visible"; $.ajax({ dataType: "jsonp", url: "http://gliservice.gsi.go.jp/gsimaps3d/create_webgl.php", data: { ltX : ltX, ltY : ltY, rbX : rbX, rbY : rbY, ltMerX : Math.round(ltMer.x), ltMerY : Math.round(ltMer.y), rbMerX : Math.round(rbMer.x), rbMerY : Math.round(rbMer.y), z : z, textureZ : textureZ, a : aVal, distance : Math.round(distBLine), texture : currentLayerUrlTemplate.substring(0,this.currentLayerUrlTemplate.indexOf('{z}')), imgURLext : fileTypes[len - 1], type : type }, success: function(data) { window.open("http://gliservice.gsi.go.jp/gsimaps3d/data/" + data.key1 + "/3d/index2.html","_blank"); document.getElementById('wait').style.visibility = "hidden"; document.getElementById('dl_three').disabled = false; } }); } //「しばらくお待ちください」を点滅させる $(function(){ setInterval(function(){ $('div#wait').fadeOut(800,function(){$(this).fadeIn(800)}); },1600); }); </script> <body onload="init_map();" style="margin:0 auto; width:600px;"> <div style="margin:0 auto; width:600px; font-size:18px;text-align:right;"><a href="../index.html" >立体地図トップへ</a></div> <div id="header" style="margin:0 auto; width:600px;"> <div style="margin:0 auto; width:600px; position:absolute;top:30px;font-size:22px;font-weight:bold;text-align:right;z-index:1;"><a href="./help/help.html" style="color:#ffffff;">ヘルプ</a></div> <h1 style="margin:0 auto;font-size:30px; width:600px;height:40px; background-color:#0099ff; color:#ffffff; text-align:center;z-index:2;">地理院地図3D</h1> </div> <div id="canvas4map" style="margin:0 auto; width:600px; height:600px;"> <div id="progressbar" style="position:relative; top:300px; margin:0 auto; width:300px; height:20px; z-index:256;"></div> </div> <div id="canvas4frame4dlg" style="display:none;" title="回転や拡大・縮小することができます。"> <div id="canvas4frame" style="margin:0 auto; width:500px; height:500px;"></div> <div style="margin-top:3px;"> <div style="float:left;">高さ方向の倍率=<input type="text" id="ratioZ" value="1.0" style="width:2em;" onChange="ChangeZratio();"/></div> <div id="slider_ratioZ" style="width: 300px; float:left; margin-top:5px; margin-left:10px;"></div> </div> <br><br><br> <div> <div><input type="button" id="showUrlHttpLink" style="width:80px;height:20px;font-size:10px;" value="共有用URL" onclick="ShowUrlHttpLink();"/><span id="urlHttpLink" style="border:solid #0000ee; margin:0px; padding: 0px;"></span></div> </div> <br><br> </div> <div style="margin:0 auto; width:600px; text-align:center;"><input type="button" style="width:300px;height:50px;font-size:20px;" value="この地図を3Dで表示" onclick="s=1; Show3DModel();"/></div> <canvas id="canvas4imgproc" width="2048" height="2048" style="display:none;"></canvas> </body> </html>