ひつじかいさんの「ひつじかいの雑記帳」というブログを拝見し、その中に、地図の描写において色々と興味深い記事を拝読しました。これは自分でもやってみたい、そう思い、その記録を記載してみたいと思います。
Web上で操作可能な日本の白地図(都道府県別)を作る(5) ― クリックした都道府県をペイント ―
前回までの情報をもとに、GoogleMap上に日本の白地図を描いていきます。
まずMapOptionsオブジェクトの.stylesプロパティを記載通りに設定してみます。
これは問題なく上手く行くのですが、Optionの[backgroundColor]設定ではほんの一瞬、白くなるのですが、その後に背景が表示されていまうようです(このキャプチャを撮るのに苦労しました…)。
ひつじかいさんの内容に従い、大きい白い土台を記載し、その上に日本地図を記載していきます。またクリック時に、その対象都道府県を塗りつぶしていきます。
色の指定は、[Spectrum]を用いています。サンプルを拝見しますと、これは簡単そうです。としてHTMLとしては次の通りです。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>都道府県の輪郭表示 ~Web上で操作可能な日本の白地図(都道府県別)を作る~</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <meta http-equiv="Content-Style-Type" content="text/css"> <!-- Google map--> <script src="http://maps.google.com/maps/api/js?key=[your_key]&language=ja&libraries=geometry"></script> <script type="text/javascript" src="http://code.google.com/apis/gears/gears_init.js"></script> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/spectrum.js"></script> <link rel='stylesheet' href='css/spectrum.css'> <script type="text/javascript" src="js/blankmap.js"></script> </head> <body style="margin:0px;" onload="initialize()"> <div id="top_bar" style="background-color:#333399;padding:5px;"> <table> <tr> <th class="map_title" id="map_title" name="map_title" style="font-size: 16px;color: #FFFFFF;"> 都道府県の輪郭を指定した色でペイント ~Web上で操作可能な日本の白地図(都道府県別)を作る~</td> </tr> </table> <form id="f_paintmenu" name="f_paintmenu"> <table> <tr> <td style="font-size:12px;color:#FFFFFF;padding-left:10px;">都道府県: <select id="f_pref" name="f_pref" style="width:100px;font-size:12px;"> </select> </td> <td style="font-size:12px;color:#FFFFFF;padding-left:10px;">色の指定: <input type='text' id="f_colorpicker" value="#FF0000"> </td> <td style="padding-left:10px;"> <input type="button" style="width:80px;font-size:14px;" id="btnPaintPref" name="btnPaintPref" onclick="paintPref(document.getElementById('f_pref').value,document.getElementById('f_colorpicker').value)" value="ペイント"> </td> </tr> </table> </form> </div> <div id="map_canvas" style="margin:5px;"></div> </body> </html>
JavaScriptであるblankmap.jsは次の通り。
// *************************************************************** // ~Web上で操作可能な日本の白地図(都道府県別)を作る~ // // テスト:都道府県ポリゴンを指定した色でペイント // // *************************************************************** var map; var myPolyPref = new Array(); var OkinawaLine; function initialize() { setDivSize(); getPrefList(); setColorPicker(); var iniCenter = new google.maps.LatLng(37,138); var iniZoom = 6; var styleAllOFF = [ { featureType: 'all', stylers: [ {visibility: 'off'}, ], } ]; var myOptions = { zoom: iniZoom, center: iniCenter, backgroundColor: '#ffffff', styles: styleAllOFF }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); drawRectangle(); getPrefBorder(); } //ウィンドウサイズに合わせて地図サイズを調整 function setDivSize() { var w = 1024; //デフォルト値 var h = 768; //デフォルト値 if (window.innerWidth) { w = window.innerWidth; h = window.innerHeight; } else if (document.all) { if (document.documentElement.clientWidth) { w = document.documentElement.clientWidth; h = document.documentElement.clientHeight; } else if (document.body.clientWidth) { w = document.body.clientWidth; h = document.body.clientHeight; } } else { return false; } var divTop = document.getElementById("top_bar").style; var divMain = document.getElementById("map_canvas").style; var divHeightTop = 60; divTop.height = divHeightTop + "px"; divMain.width = (w - 20) + "px"; divMain.height = (h - divHeightTop - 20) + "px"; } //都道府県リストの取得 function getPrefList() { var fldPref = document.getElementById("f_pref"); var txtOption = "<option value='0' SELECTED >--------</option>"; var json; jQuery.ajax({ url : "getdatajson.php?", type : "get", async : false, data: "mode=preflist", success: function(request){ var res = request; if (res.substring(0,4) == "err:"){ alert("エラー:"+res.substring(4)); }else{ json = JSON.parse(res); for (var i = 0; i < json.length; i++) { txtOption += "<option value='"+json[i].PrefectureCode+"'" if (fldPref.value == json[i].PrefectureCode) { txtOption += " SELECTED"; } txtOption += " >"+json[i].PrefectureName+"</option>" } } }, error: function() { alert('都道府県リストの取得に失敗しました'); } }); fldPref.innerHTML = txtOption; } //都道府県輪郭データの取得 function getPrefBorder() { var json; jQuery.ajax({ url : "getdatajson.php?", type : "get", async : false, data: "mode=border", success: function(request){ var res = request; if (res.substring(0,4) == "err:"){ alert("エラー:"+res.substring(4)); }else{ json = JSON.parse(res); setPolygon(json); } }, error: function() { alert('都道府県輪郭データの取得に失敗しました'); } }); } //ポリゴン描画 function setPolygon(myBorderPoints) { var polyCoordsArray = new google.maps.MVCArray(); myPolyPref.length = 0; var polyCoordsPref = new Array(); for (var i = 1; i <= 47; i++) { polyCoordsPref[i] = new google.maps.MVCArray(); } for (var p = 0; p < myBorderPoints.length; p++) { var prefCode = parseInt(myBorderPoints[p][0].PrefectureCode); var polyCoords = new google.maps.MVCArray(); if (prefCode == 47) { moveLocation(myBorderPoints[p],5,15); } for (var i = 0; i < myBorderPoints[p].length; i++) { polyCoords.push( new google.maps.LatLng(myBorderPoints[p][i].Lat, myBorderPoints[p][i].Lng)); } polyCoordsArray.push(polyCoords); polyCoordsPref[prefCode].push(polyCoords); } for (var i = 1; i <= 47; i++) { myPolyPref[i] = new google.maps.Polygon({ paths: polyCoordsPref[i], strokeColor: "#666666", strokeOpacity: 1.0, strokeWeight: 1, fillColor: "#FFFFFF", zIndex: 1, fillOpacity: 1.0 }); myPolyPref[i].setMap(map); myPolyPref[i].set("PrefectureCode", i); google.maps.event.addListener(myPolyPref[i], "click", function(event) { var prefFld = document.getElementById("f_pref"); for(var j = 0; j < prefFld.length; j++) { if (parseInt(prefFld.options[j].value) == this.PrefectureCode) { prefFld.options[j].selected = true; } else { prefFld.options[j].selected = false; } } var fColor = document.getElementById("f_colorpicker").value; paintPref(this.PrefectureCode,fColor); }); google.maps.event.addListener(myPolyPref[i], "rightclick", function(event) { var fColor = "#ffffff"; paintPref(this.PrefectureCode,fColor); }); google.maps.event.addListener(myPolyPref[i], "mouseover", function(event) { this.setOptions({strokeWeight: 2.0}); }); google.maps.event.addListener(myPolyPref[i], "mouseout", function(event) { this.setOptions({strokeWeight: 1.0}); }); } } //沖縄県の場所を移動(スペースの都合。白地図によくあるケース) function moveLocation(myPoints,my,mx) { for (var i = 0; i < myPoints.length; i++) { myPoints[i].Lat = parseFloat(myPoints[i].Lat) + my; myPoints[i].Lng = parseFloat(myPoints[i].Lng) + mx; } //実際の位置から移動していることを示すライン if (!OkinawaLine && parseInt(myPoints[0].PrefectureCode)==47) { var OkinawaLineCoords = [ new google.maps.LatLng(25.7+my, 126.3+mx), new google.maps.LatLng(26.7+my, 126.3+mx), new google.maps.LatLng(27.7+my, 127.8+mx), new google.maps.LatLng(27.7+my, 129.3+mx) ]; OkinawaLine = new google.maps.Polyline({ path: OkinawaLineCoords, strokeColor: "#808080", strokeOpacity: 1.0, strokeWeight: 1.5, zIndex: 1 }); OkinawaLine.setMap(map); } } //都道府県の領域(ポリゴン)を指定した色でペイント function paintPref(prefcode,fcolor) { if (parseInt(prefcode) > 0) { myPolyPref[parseInt(prefcode)].setOptions({fillColor: fcolor}); } } //巨大な矩形で地図全体を覆う(背景の設定) function drawRectangle() { var rectangle = new google.maps.Rectangle(); var rectBounds = new google.maps.LatLngBounds( new google.maps.LatLng(-90.0, -180), new google.maps.LatLng(90.0, 180)); var rectOptions = { strokeColor: "#FFFFFF", strokeOpacity: 1.0, strokeWeight: 0.0, fillColor: "#FFFFFF", fillOpacity: 1.0, zIndex: 0, map: map, bounds: rectBounds }; rectangle.setOptions(rectOptions); } //カラーピッカー(Spectrum)の設定 function setColorPicker() { var fld = document.getElementById("f_colorpicker"); $(function(){ $("#f_colorpicker").spectrum({ color: fld.value, showInput: true, showInitial: true, showPalette: true, showSelectionPalette: true, preferredFormat: "hex", chooseText: "OK", cancelText: "Cancel", palette: [ ["#000000", "#434343", "#666666", "#999999", "#b7b7b7", "#cccccc", "#d9d9d9", "#efefef", "#f3f3f3", "#ffffff"], ["#980000", "#ff0000", "#ff9900", "#ffff00", "#00ff00", "#00ffff", "#4a86e8", "#0000ff", "#9900ff", "#ff00ff"], ["#e6b8af", "#f4cccc", "#fce5cd", "#fff2cc", "#d9ead3", "#d9ead3", "#c9daf8", "#cfe2f3", "#d9d2e9", "#ead1dc"], ["#dd7e6b", "#ea9999", "#f9cb9c", "#ffe599", "#b6d7a8", "#a2c4c9", "#a4c2f4", "#9fc5e8", "#b4a7d6", "#d5a6bd"], ["#cc4125", "#e06666", "#f6b26b", "#ffd966", "#93c47d", "#76a5af", "#6d9eeb", "#6fa8dc", "#8e7cc3", "#c27ba0"], ["#a61c00", "#cc0000", "#e69138", "#f1c232", "#6aa84f", "#45818e", "#3c78d8", "#3d85c6", "#674ea7", "#a64d79"], ["#85200c", "#990000", "#b45f06", "#bf9000", "#38761d", "#134f5c", "#1155cc", "#0b5394", "#351c75", "#741b47"], ["#5b0f00", "#660000", "#783f04", "#7f6000", "#274e13", "#0c343d", "#1c4587", "#073763", "#20124d", "#4c1130"] ] }); }) }
そしてJavaScriptからaJaxで呼び出されているPHPスクリプトである[getdatajson.php]は次の通り。
<?php ini_set('memory_limit', '1024M'); $msg = ""; $jsondata = ""; $mysqli = connectDBi($msg); if ($mysqli) { if (isset($_REQUEST["mode"])) { if ($_REQUEST["mode"] == "border") { if (getPrefBorderJSON($mysqli, $jsondata)) { header("Content-Type: text/javascript; charset=utf-8"); print $jsondata; } else { print "err:都道府県輪郭線データの取得に失敗しました。"; } } else if ($_REQUEST["mode"] == "preflist") { if (getPrefListJSON($mysqli, $jsondata)) { header("Content-Type: text/javascript; charset=utf-8"); print $jsondata; } else { print "err:都道府県リストの取得に失敗しました。"; } } else { print "err:モード設定エラー"; } } else { print "err:モードが設定されていません"; } $mysqli->close(); } else { print $msg; } ini_restore('memory_limit'); exit(); function getPrefBorderJSON($mysqli, &$jsondata) { $p = array(); $strSQL = "SELECT *"; $strSQL .= " FROM t_JapanPrefectureBorder"; $strSQL .= " ORDER BY PrefectureCode, BorderCode, PointNo"; $former = array(); $rst = $mysqli->query($strSQL); $rcount = $rst->num_rows; if ($rcount > 0) { while ($col = $rst->fetch_array(MYSQLI_ASSOC)) { if ( !isset($former["PrefectureCode"]) || $col["PrefectureCode"] <> $former["PrefectureCode"] || $col["BorderCode"] <> $former["BorderCode"] ) { if (!isset($cNo)) { $cNo = 0; } else { $cNo++; } $p[$cNo] = array(); } array_push($p[$cNo], $col); $former = $col; } } is_null($rst) or $rst->free(); $jsondata = json_encode($p); return true; } function getPrefListJSON($mysqli, &$jsondata) { $strSQL = "SELECT PrefectureCode, PrefectureName FROM t_Prefecture"; $strSQL .= " ORDER BY PrefectureCode"; $rst = $mysqli->query($strSQL); $rcount = $rst->num_rows; $pref = array(); if ($rcount > 0) { while ($col = $rst->fetch_array(MYSQLI_ASSOC)) { array_push($pref, $col); } } $jsondata = json_encode($pref); is_null($rst) or $rst->free(); return true; } //MySQLへ接続 function connectDBi(&$err) { //MySQL 接続情報 $MySQL_SERVER = "localhost"; $MySQL_USER = "[user_name]"; $MySQL_PASSWORD = "[password]"; $MySQL_DBNAME = "map"; $err = ""; $mysqli = new mysqli($MySQL_SERVER, $MySQL_USER, $MySQL_PASSWORD, $MySQL_DBNAME); if ($mysqli->connect_errno) { $err = "データベース接続に失敗しました。"; } if (strlen($err) > 0) { return false; } else { return $mysqli; } }
これを実行させると次の通りです。ひつじかいさんの内容通り、沖縄県の位置が配慮され、クリックすると指定した色で塗りつぶせます。
ひつじかいさんの内容におけるコピペでそのまま動きます。またプログラムの解説も、ひつじかいさんのブログに詳しく記載されています。参考になります。