ひつじかいさんの「ひつじかいの雑記帳」というブログを拝見し、その中に、地図の描写において色々と興味深い記事を拝読しました。これは自分でもやってみたい、そう思い、その記録を記載してみたいと思います。
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;
}
}
これを実行させると次の通りです。ひつじかいさんの内容通り、沖縄県の位置が配慮され、クリックすると指定した色で塗りつぶせます。

ひつじかいさんの内容におけるコピペでそのまま動きます。またプログラムの解説も、ひつじかいさんのブログに詳しく記載されています。参考になります。

