Nokia Mapsに基づくマッシュアップのトピックを継続することにしました。本日は、Nokia Maps JS API + Twitter Search APIを使用して、Twitterのさまざまなハッシュタグの使用の強度を地図上に表示する方法を示します。 このようなマッシュアップは、次の画像のようになります。
伝統的に、私たちはマップを初期化するindex.htmlを作成することから始めます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Nokia Maps Heatmap demo</title> <link rel="stylesheet" href="main.css"> </head> <body> <div id="annotations"> <h2></h2> </div> <div id="map" class="map"><div id="map-loading" class="map-loading"></div></div> <script src="http://api.maps.nokia.com/2.2.1/jsl.js?with=all"></script> <script src="places-heatmap.js"></script> <script src="process-tweets.js"></script> </body> </html>
ご覧のとおり、3つのjavascriptスクリプトをすぐに特定しました。 最初のスクリプト
api.maps.nokia.com/2.2.1/jsl.js
api.maps.nokia.com/2.2.1/jsl.js
は、 前回の投稿で既におなじみかもしれません
api.maps.nokia.com/2.2.1/jsl.js
Maps JS APIをロードします。
places-heatmap.js
は、オーバーレイマップへの強度マップのレンダリングと追加を担当します。 次の
process-tweets.js
スクリプト
process-tweets.js
、特定のハッシュタグを使用して位置情報データを含むツイートを
process-tweets.js
し、これらのツイートを強度マップのデータ構造内の記録情報(緯度/経度、都市)でジオコーディングします。
これらのスクリプトの説明は、コードへのコメントで直接提供されます。
places-heatmap.js
var HH = {}; // Nokia Maps JS API nokia.Settings.set("appId", "_peU-uCkp-j8ovkzFGNU"); nokia.Settings.set("authenticationToken", "gBoUkAMoxoqIWfxWA5DuMQ"); nokia.Settings.set("defaultLanguage", "ru-RU"); HH.HeatmapLoader = function () { var self = this, map, mapLoad, heatmapLoad, heatmapProvider; // , mapLoad = function () { var mapContainer = document.getElementById("map"); self.map = new nokia.maps.map.Display(mapContainer, { // , zoomLevel: 3 center: [55, 37], zoomLevel: 3, components: [ new nokia.maps.map.component.Behavior() ] }); }; // , heatmapLoad = function () { var color_range = { // . // 1, — 0. stops: { // , — , "0": "rgba(0, 0, 64, 1)", "0.15": "rgba(0, 0, 64, 1)", "0.3": "rgb(32, 32, 96)", "0.4": "rgb(96, 96, 128)", "0.5": "rgb(255, 255, 255)" }, // , interpolate: true }; try { if(!self.heatmapProvider) { // heatmapProvider = new nokia.maps.heatmap.Overlay({ // colors: color_range, // , max: 20, // , opacity: 1, // type: "density", // coarseness: 1, // , , , assumeValues: true }); } } catch (e) { // , // canvas alert(e); } // if (heatmapProvider && HH.tweetheatmap) { // heatmapProvider.clear(); heatmapProvider.addData(HH.tweetheatmap.allPlaces); // self.map.overlays.add(heatmapProvider); } }; // return { map: map, mapLoad: mapLoad, heatmapLoad: heatmapLoad, heatmapProvider: heatmapProvider }; }; // HeatmapLoader HH.heatmap = new HH.HeatmapLoader();
Nokia Maps API Reference Webサイトで使用されている
nokia.maps.heatmap.Overlay
クラスの詳細を読むことができますが、コードへのコメントでは、 nokia.maps.heatmap.Overlay.Optionsで設定されるオーバーレイ自体の一部の設定を除き、すべてのパラメーターがリストされています。 。
process-tweets.js
HH.TweetHeatmap = function () { "use strict"; var self, init, pageSetup, switchInput, changeHash, allPlaces = [], addPlaces, addSearch, tweetPlace, getLocation, addToPlace, futureCheck, futureCount = 0, rendered = false, locationsObj = {}, locationsTweets = [], displayHeatmap; init = function () { var locations, i; self = this; // , if (nokia.maps && HH.heatmap) { HH.heatmap.mapLoad(); } // , #nokia if (window.location.hash === '') { window.location.hash = 'nokia'; } pageSetup(); // Twitter Search API , locations = [[55.75697, 37.61502], [0, 100], [0, 50], [0, 0], [0, -50], [0, -100], [0, -150], [50, 150], [50, 100], [50, 50], [50, 0], [50, -50], [50, -100], [50, -150], [-50, 150], [-50, 100], [-50, 50], [-50, 0], [-50, -50], [-50, -100], [-50, -150]]; // , , document.getElementById('map-loading').style.display = 'block'; // , locations, Twitter Search API for (i in locations) { self.addSearch(locations[i], window.location.hash.substring(1)); } // , // , , setTimeout(displayHeatmap, 8000); }; // JSONP- , Twitter Search API // addPlaces addSearch = function (location, hashtag) { // Twitter Search API : https://dev.twitter.com/docs/api/1/get/search var url = 'http://search.twitter.com/search.json?geocode=' + location[0] + ',' + location[1] + ',8000km&q=%23' + hashtag + '&rpp=100&callback= HH.tweetheatmap.addPlaces', script = document.createElement("script"); script.setAttribute("src", url); document.body.appendChild(script); }; // , addPlaces = function (data) { var i; if (data && data.results && data.results.length) { // . self.futureCount += data.results.length; for (i = data.results.length - 1; i >= 0; i--) { var location = data.results[i].location if (location) { location = location.replace('iPhone: ','') self.getLocation(location); } else { // , self.futureCount--; } }; } }; // JSONP- Nokia Maps geocode API Twitter getLocation = function (location) { // q — , vi — , dv — , to — var url = 'http://where.desktop.mos.svc.ovi.com/json?q=' + encodeURI(location) + '&to=1&vi=address&dv=NokiaMapsAPI&callback_func=HH.tweetheatmap.addToPlace', script = document.createElement("script"); script.setAttribute("src", url); document.body.appendChild(script); }; // , // addToPlace = function (data) { if (data.results && data.results.length) { var location_title = data.results[0].properties.title, type = data.results[0].properties.type, lon = data.results[0].properties.geoLongitude, lat = data.results[0].properties.geoLatitude; if (type != 'Country' && type != 'State' && type != 'Continent'){ if (locationsObj[location_title]) { locationsTweets[locationsObj[location_title]].tweets += 1; } else { locationsObj[location_title] = locationsTweets.length locationsTweets.push({ 'city': location_title, 'tweets': 1, 'longitude': lon, 'latitude': lat }); } } if (!rendered) { allPlaces.push({ "latitude" : lat, "longitude" : lon, "city" : location_title, "country" : data.results[0].properties.addrCountryName }); } } self.futureCheck(); }; // , . // , futureCheck = function () { self.futureCount--; if (self.futureCount<=0) { displayHeatmap(); } }; // , displayHeatmap = function() { if(!rendered) { rendered = true; document.getElementById('map-loading').style.display = 'none'; HH.heatmap.heatmapLoad(); } }; // , switchInput = function(e){ this.style.display='none'; var h = document.createElement('input');h.setAttribute('type', 'text'); this.parentNode.insertBefore(h,this); h.focus(); h.addEventListener('keydown', changeHash, false); }; changeHash = function(e){ if(e.keyCode===13) { window.location.hash='#'+e.target.value.replace('#',''); } else if(e.keyCode===27) { e.target.parentNode.removeChild(e.target); document.getElementsByTagName('h2')[0].style.display='block'; } }; pageSetup = function() { if (!(document.getElementsByTagName('body')[0].classList.length === 1)) { // URL document.getElementsByTagName('h2')[0].innerHTML = '#' + window.location.hash.substring(1); // event listener document.getElementsByTagName('h2')[0].addEventListener('click', switchInput, false) // event listener window.addEventListener("hashchange", function (e) {window.location.reload(); }, false); } }; // return { init: init, addSearch: addSearch, addPlaces : addPlaces, addToPlace : addToPlace, getLocation: getLocation, futureCount : futureCount, futureCheck : futureCheck, allPlaces : allPlaces, locationsTweets : locationsTweets }; }; HH.tweetheatmap = new HH.TweetHeatmap(); HH.tweetheatmap.init();
Twitter Search APIを使用する場合、ツイートを検索する価値のある任意の半径(地球の半径に等しいこともあります)を設定することは可能ですが、この問題では100を超えないツイートを考慮する必要があります。 したがって、多くのポイントの座標を示すことをお勧めします。そうしないと、多数のメッセージが検索から除外されます。
process-tweets.js
最後で、Twitter Search APIに直接関連しない機能に気付く場合があります。 マップのインターフェイスを担当し、現在のハッシュタグ(左上隅)をクリックして、検索用の新しいハッシュタグを決定できます。 via
document.getElementsByTagName('h2')[0].innerHTML = '#' + window.location.hash.substring(1);
URLを介してハッシュタグを定義します-これにより、index.htmlを任意のサイトに任意のハッシュタグを使用してiframeとして挿入できます。
ソースを見る
こちらのライブ例をご覧ください 。 ソースはgithubからダウンロードできます。