// ページの読み込みが終わったら、地図表示の処理を行う window.addEventListener("DOMContentLoaded", function () { var posts = JSON.parse(document.getElementById("data").innerHTML); // マーカーとツールチップを、店舗情報毎に設定するための overlay var overlay = new OpenLayers.Layer.Vector('Overlay', { styleMap: new OpenLayers.StyleMap({ externalGraphic: '${marker_image}', // ■(I)-1 graphicWidth: 21, graphicHeight: 25, graphicYOffset: -25, cursor: "pointer", title: '${tooltip}', // ■(J)-1 }) }); var icon_map = { 2: "http://dev.openlayers.org/img/marker.png", 3: "http://dev.openlayers.org/img/marker-blue.png", 4: "http://dev.openlayers.org/img/marker-gold.png", 5: "http://dev.openlayers.org/img/marker-green.png", }; var epsg4326 = new OpenLayers.Projection("EPSG:4326"); var epsg3857 = new OpenLayers.Projection("EPSG:3857"); // マーカーの生成 var features = []; for (var i in posts) { var post = posts[i]; features.push(new OpenLayers.Feature.Vector( // ■(H)-1 new OpenLayers.Geometry.Point(post.lng, post.lat) .transform(epsg4326, epsg3857), { tooltip: post.title, // ■(J)-2 marker_image: icon_map[ post.cat_id ], // ■(I)-2 post: post, } )); } overlay.addFeatures(features); // ■(H)-2 overlay.events.on({ // ■(L)-1 'featureclick': function(evt) { toggle_popup(evt.feature); }, }); // マップの生成 var map = new OpenLayers.Map("map"); // ■(A)、■(C) map.addLayers([ new OpenLayers.Layer.OSM(), // ■(A)、 overlay // ■(H)-3 ]); map.addControl(new OpenLayers.Control.ScaleLine({ // ■(E) bottomOutUnits: "", bottomInUnits: "" })); // マーカーのクリック状態を取得するために、SelectFeature なるものを作る var select = new OpenLayers.Control.SelectFeature(overlay); // ■(L)-2 map.addControl(select); select.activate(); // マーカーが含まれる範囲の Bounds と、それに合わせたズーミング var bounds = new OpenLayers.Bounds(); // ■(F)-2 for (var i in posts) { bounds.extend(new OpenLayers.LonLat(posts[i].lng, posts[i].lat)); } bounds.transform(epsg4326, epsg3857); map.zoomToExtent(bounds); // ■(F)-1、■(D) // ズームの最大値は 16 まで // ■(G) if (map.getZoom() > 16) { map.zoomTo(16); } // 吹き出しの「×」を押したときの処理 function close_popup(evt) { toggle_popup(this.feature); } // マーカーをクリックしたときに吹き出しの表示を切り替える function toggle_popup(feature) { if (! feature.popup) { var post = feature.attributes.post; var content = '<div>' + post.name + ':' + '<a href="' + post.link + '">' + post.title + '</a></div>'; var popup = new OpenLayers.Popup.FramedCloud( // ■(K) "featurePopup", feature.geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(100, 100), content, null, true, close_popup ); popup.calculateRelativePosition = function() { // ■(M) return "bl"; }; feature.popup = popup; popup.feature = feature; feature.layer.map.addPopup(popup); // ■(L)-3 } else { var popup = feature.popup; popup.feature = null; feature.layer.map.removePopup(feature.popup); // ■(L)-4 feature.popup.destroy(); feature.popup = null; } } });
<div id="map" style="width: 99%; height: 650px;"></div> <script id="data" type="text/json"> [ { "lat": 35.701418, "lng": 139.74787, "name": "和食料理店", "link": "http://www.google.com/search?q=%e5%92%8c%e9%a3%9f%e5%89%b2%e7%83%b9zen", "title": "和食割烹ZEN", "cat_id": "2" }, { "lat": 35.6950886, "lng": 139.74937320000004, "name": "犬猫病院", "link": "http://www.google.com/search?q=%e3%82%a2%e3%83%8b%e3%83%9e%e3%83%ab%e3%83%9b%e3%82%b9%e3%83%94%e3%82%bf%e3%83%ab", "title": "アニマルホスピタル", "cat_id": "5" }, { "lat": 35.67694669999999, "lng": 139.7635034, "name": "カフェ", "link": "http://www.google.com/search?q=%e3%82%b9%e3%82%a4%ef%bc%8d%e3%83%84%e3%83%99%e3%83%aa%ef%bc%8d", "title": "スイ-ツベリ-", "cat_id": "2" }, { "lat": 35.6964531, "lng": 139.77445769999997, "name": "服屋", "link": "http://www.google.com/search?q=%e3%83%a6%e3%83%8b%e3%82%b7%e3%83%ad", "title": "ユニシロ", "cat_id": "4" }, { "lat": 35.6964946, "lng": 139.77230780000002, "name": "不動産屋", "link": "http://www.google.com/search?q=%e3%82%a8%e3%82%b9%e3%83%86%ef%bc%8d%e3%83%88%e6%9d%b1%e4%ba%ac", "title": "エステ-ト東京", "cat_id": "3" }, { "lat": 35.6945504, "lng": 139.770258, "name": "たこ焼き屋", "link": "http://www.google.com/search?q=%e3%81%8f%e3%82%8b%e3%81%8f%e3%82%8b", "title": "くるくる", "cat_id": "2" }, { "lat": 35.6963474, "lng": 139.77209949999997, "name": "ペット", "link": "http://www.google.com/search?q=%e3%83%9a%e3%83%83%e3%83%88%e3%82%b7%e3%83%a7%e3%83%83%e3%83%97%e3%82%8f%e3%82%93%e3%81%ab%e3%82%83%e3%82%93", "title": "ペットショップわんにゃん", "cat_id": "5" }, { "lat": 35.6950947, "lng": 139.7685136, "name": "工務店", "link": "http://www.google.com/search?q=%e3%83%88%e3%83%b3%e3%82%ab%e3%83%81%e5%b7%a5%e5%8b%99%e5%ba%97", "title": "トンカチ工務店", "cat_id": "3" }, { "lat": 35.6971917, "lng": 139.76922739999998, "name": "お好み焼き", "link": "http://www.google.com/search?q=%e3%81%98%e3%82%85%e3%81%86%e3%81%98%e3%82%85%e3%81%86", "title": "じゅうじゅう", "cat_id": "2" }, { "lat": 35.6749887, "lng": 139.76436450000006, "name": "美容室", "link": "http://www.google.com/search?q=%e3%82%b5%e3%83%a9%e3%82%b5%e3%83%a9%e7%be%8e%e5%ae%b9%e5%ae%a4", "title": "サラサラキュ-ティクル", "cat_id": "4" }, { "lat": 35.6817879, "lng": 139.76676139999995, "name": "パン屋", "link": "http://www.google.com/search?q=%e3%83%91%e3%83%b3%e5%b1%8b%e3%82%a4%ef%bc%8d%e3%82%b9%e3%83%88", "title": "イ-ストパン", "cat_id": "2" } ] </script>
/* 地図領域と地図のサイズが合わないとき : Google Maps は API が設定する */ #map { position: relative; /* ■(N) */ overflow: hidden; } /* style.css の指定が影響して、吹き出しが正しく表示されない */ #map .olPopup img { max-width: none; }