ストリートビューのカメラの向きを自動的に調整する
まぁ、上記の画像で全て説明しているのですが。
Google のストリートビューは緯度経度を渡すと、その位置から一番近いストリートビュー対応エリアを検出します。
その時、カメラはデフォルトの方向を向いているので、対象物が写っているとは限らず、マウスでグリグリ動かして見ないと対象物が見えません。
これを、検出された対応エリアから元の対象物への緯度経度の方向へ、ストビューのカメラを自働的に向けるようにしてみました。
Google Maps APIのジオメトリライブラリを使用して2地点間の方向を計算し、ストリートビューのカメラの向きを対象物へと向けています。
作ってみた物
オープンデータとして公開されている室蘭市の「砂箱」の位置情報を使ってデモをつくってみました。
ストリートビューから取得した画像に砂箱が映っていれば、カメラが正しく対象物の方向へ向いています。
砂箱はこれ↓
検出されるストリートビュー対応ポイント場所によっては、対象物とストリートビューポイントの間に地物が挟まってて、見えなかったりします。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
window.onhashchange = getSubakoPhoto; getSubakoPhoto(); function getSubakoPhoto() { d3.selectAll(".pagerlink").remove(); d3.selectAll(".subakoraw").remove(); //pager処理 var page = +location.hash.replace("#", ""); if (typeof page != "number") page = 0; var endpage = page+20; d3.json("subako.geojson", function(geojson){ var sbako_table = d3.select('#stage'); var pageNumber = d3.range(0, geojson.features.length, 20); //pager設置 d3.select("#pager") .selectAll("pagerlink") .data(pageNumber) .enter() .append("a") .attr({ "class":"pagerlink", "href": function(d){ return "http://shimz.me/example/gmapv3/streetview/muroran_sbako/index.html#" + d } }) .style("margin", "5px") .text(function(d, i){ return i }) .on("click", function(d){ location.href = "http://shimz.me/example/gmapv3/streetview/muroran_sbako/index.html#" + d ; }) setTimeout(function(){ loop(geojson.features.slice(page, endpage)) } , 500); function loop(features){ var div = sbako_table.append("div").attr("class", "subakoraw"); var raw = features.pop(); var latlng = raw.geometry.coordinates; getStreetViewPov( { lat:latlng[1] , lng:latlng[0] }, function(stv){ //street view image url を取得しimgのsrcに設定 div.append("img") .attr("src", "http://maps.googleapis.com/maps/api/streetview?size=300x200&location="+stv.lat+","+stv.lng+"&heading="+stv.heading+"&pitch="+stv.pov.pitch+"&sensor=false"); div.append("p").text(raw.properties["整理番号"]); div.append("a") .attr({ "href": "https://www.google.com/maps/place/"+latlng[1]+","+latlng[0], "target": "_blank" }) .text("lat:"+latlng[1]+" lng:"+latlng[0]); } ); if (features.length > 0) setTimeout(function(){ loop(features); }, 500); } }) /* street view 初期化 */ var panoOptions = { panControl: false, addressControl: false, linksControl: false, zoomControlOptions: false }; var pano = new google.maps.StreetViewPanorama(document.getElementById('streetview'), panoOptions); var service = new google.maps.StreetViewService; //heading,pov取得 function getStreetViewPov(arg , callback) { //対象物緯度経度設定 var lookTo = new google.maps.LatLng(arg.lat, arg.lng); pano.setPosition(lookTo); service.getPanoramaByLocation(pano.getPosition(), 50, function(panoData) { if (panoData != null) { //検出されたstreetview対応位置(緯度経度)を取得 var panoCenter = panoData.location.latLng; //2地点間(streetview対応位置と対象物の緯度経度)の方向を計算 var heading = google.maps.geometry.spherical.computeHeading(panoCenter, lookTo); //povを取得 var pov = pano.getPov(); //コールバックの引数として取得した値を渡す callback({heading:heading, pov:pov, lat:arg.lat, lng:arg.lng}); } else { console.log('not found StreetView point'); } }); } }; |