前回までで各県の輪郭は作れる様になりました。前の記事では北海道だけやりましたが、これを47都道府県全てを対象に行います。そして描画のたび毎にこの処理を毎回やるのは時間がかかりすぎます。そこで計算結果をXMLに書き出す事にします。日本地図を描画するには新しく作るXMLから読み出してSVGに描画という流れにします。
1. ディレクトリの準備
SVGを保存するSVGフォルダ、XMLを保存するXMLフォルダを用意します。ディレクトリは次の様になります。
国土数値情報行政区域フォルダにはダンロードしたデータが入っています。SVGとXMLは空のフォルダでplotPrefData3.phpを走らせると各県のSVGとXMLが保存されます。
2. XMLを作成するPHP
plotPrefData3.php
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
<?php //ダウンロードした数値地図から都道府県の輪郭のXMLを作成するためのPHP $startTime = microtime(true); ini_set('memory_limit', '640M'); mb_language("Japanese");//文字コードの設定 mb_internal_encoding("UTF-8"); $loadXML[1] = "./国土数値情報行政区域/N03-170101_01_GML/N03-17_01_170101.xml"; $saveFile[1] ="hokkaido"; $loadXML[2] = "./国土数値情報行政区域/N03-170101_02_GML/N03-17_02_170101.xml"; $saveFile[2] ="aomori"; $loadXML[3] = "./国土数値情報行政区域/N03-170101_03_GML/N03-17_03_170101.xml"; $saveFile[3] ="iwate"; $loadXML[4] = "./国土数値情報行政区域/N03-170101_04_GML/N03-17_04_170101.xml"; $saveFile[4] ="miyagi"; $loadXML[5] = "./国土数値情報行政区域/N03-170101_05_GML/N03-17_05_170101.xml"; $saveFile[5] ="akita"; $loadXML[6] = "./国土数値情報行政区域/N03-170101_06_GML/N03-17_06_170101.xml"; $saveFile[6] ="yamagata"; $loadXML[7] = "./国土数値情報行政区域/N03-170101_07_GML/N03-17_07_170101.xml"; $saveFile[7] ="fukushima"; $loadXML[8] = "./国土数値情報行政区域/N03-170101_08_GML/N03-17_08_170101.xml"; $saveFile[8] ="ibaraki"; $loadXML[9] = "./国土数値情報行政区域/N03-170101_09_GML/N03-17_09_170101.xml"; $saveFile[9] ="tochigi"; $loadXML[10] = "./国土数値情報行政区域/N03-170101_10_GML/N03-17_10_170101.xml"; $saveFile[10] ="gunnma"; $loadXML[11] = "./国土数値情報行政区域/N03-170101_11_GML/N03-17_11_170101.xml"; $saveFile[11] ="saitama"; $loadXML[12] = "./国土数値情報行政区域/N03-170101_12_GML/N03-17_12_170101.xml"; $saveFile[12] ="chiba"; $loadXML[13] = "./国土数値情報行政区域/N03-170101_13_GML/N03-17_13_170101.xml"; $saveFile[13] ="tokyo"; $loadXML[14] = "./国土数値情報行政区域/N03-170101_14_GML/N03-17_14_170101.xml"; $saveFile[14] ="kanagawa"; $loadXML[15] = "./国土数値情報行政区域/N03-170101_15_GML/N03-17_15_170101.xml"; $saveFile[15] ="niigata"; $loadXML[16] = "./国土数値情報行政区域/N03-170101_16_GML/N03-17_16_170101.xml"; $saveFile[16] ="toyama"; $loadXML[17] = "./国土数値情報行政区域/N03-170101_17_GML/N03-17_17_170101.xml"; $saveFile[17] ="isihikawa"; $loadXML[18] = "./国土数値情報行政区域/N03-170101_18_GML/N03-17_18_170101.xml"; $saveFile[18] ="fukui"; $loadXML[19] = "./国土数値情報行政区域/N03-170101_19_GML/N03-17_19_170101.xml"; $saveFile[19] ="yamanashi"; $loadXML[20] = "./国土数値情報行政区域/N03-170101_20_GML/N03-17_20_170101.xml"; $saveFile[20] ="nagano"; $loadXML[21] = "./国土数値情報行政区域/N03-170101_21_GML/N03-17_21_170101.xml"; $saveFile[21] ="gifu"; $loadXML[22] = "./国土数値情報行政区域/N03-170101_22_GML/N03-17_22_170101.xml"; $saveFile[22] ="sizuoka"; $loadXML[23] = "./国土数値情報行政区域/N03-170101_23_GML/N03-17_23_170101.xml"; $saveFile[23] ="aiti"; $loadXML[24] = "./国土数値情報行政区域/N03-170101_24_GML/N03-17_24_170101.xml"; $saveFile[24] ="mie"; $loadXML[25] = "./国土数値情報行政区域/N03-170101_25_GML/N03-17_25_170101.xml"; $saveFile[25] ="shiga"; $loadXML[26] = "./国土数値情報行政区域/N03-170101_26_GML/N03-17_26_170101.xml"; $saveFile[26] ="kyoto"; $loadXML[27] = "./国土数値情報行政区域/N03-170101_27_GML/N03-17_27_170101.xml"; $saveFile[27] ="osaka"; $loadXML[28] = "./国土数値情報行政区域/N03-170101_28_GML/N03-17_28_170101.xml"; $saveFile[28] ="hyougo"; $loadXML[29] = "./国土数値情報行政区域/N03-170101_29_GML/N03-17_29_170101.xml"; $saveFile[29] ="nara"; $loadXML[30] = "./国土数値情報行政区域/N03-170101_30_GML/N03-17_30_170101.xml"; $saveFile[30] ="wakayama"; $loadXML[31] = "./国土数値情報行政区域/N03-170101_31_GML/N03-17_31_170101.xml"; $saveFile[31] ="tottori"; $loadXML[32] = "./国土数値情報行政区域/N03-170101_32_GML/N03-17_32_170101.xml"; $saveFile[32] ="shimane"; $loadXML[33] = "./国土数値情報行政区域/N03-170101_33_GML/N03-17_33_170101.xml"; $saveFile[33] ="okayama"; $loadXML[34] = "./国土数値情報行政区域/N03-170101_34_GML/N03-17_34_170101.xml"; $saveFile[34] ="hiroshima"; $loadXML[35] = "./国土数値情報行政区域/N03-170101_35_GML/N03-17_35_170101.xml"; $saveFile[35] ="yamaguchi"; $loadXML[36] = "./国土数値情報行政区域/N03-170101_36_GML/N03-17_36_170101.xml"; $saveFile[36] ="tokushima"; $loadXML[37] = "./国土数値情報行政区域/N03-170101_37_GML/N03-17_37_170101.xml"; $saveFile[37] ="kagawa"; $loadXML[38] = "./国土数値情報行政区域/N03-170101_38_GML/N03-17_38_170101.xml"; $saveFile[38] ="ehime"; $loadXML[39] = "./国土数値情報行政区域/N03-170101_39_GML/N03-17_39_170101.xml"; $saveFile[39] ="kouchi"; $loadXML[40] = "./国土数値情報行政区域/N03-170101_40_GML/N03-17_40_170101.xml"; $saveFile[40] ="fukuoka"; $loadXML[41] = "./国土数値情報行政区域/N03-170101_41_GML/N03-17_41_170101.xml"; $saveFile[41] ="saga"; $loadXML[42] = "./国土数値情報行政区域/N03-170101_42_GML/N03-17_42_170101.xml"; $saveFile[42] ="nagasaki"; $loadXML[43] = "./国土数値情報行政区域/N03-170101_43_GML/N03-17_43_170101.xml"; $saveFile[43] ="kumamoto"; $loadXML[44] = "./国土数値情報行政区域/N03-170101_44_GML/N03-17_44_170101.xml"; $saveFile[44] ="ooita"; $loadXML[45] = "./国土数値情報行政区域/N03-170101_45_GML/N03-17_45_170101.xml"; $saveFile[45] ="miyazaki"; $loadXML[46] = "./国土数値情報行政区域/N03-170101_46_GML/N03-17_46_170101.xml"; $saveFile[46] ="kagoshima"; $loadXML[47] = "./国土数値情報行政区域/N03-170101_47_GML/N03-17_47_170101.xml"; $saveFile[47] ="okinawa"; for ($i = 1 ; $i<47+1 ; $i++){ $saveSVG= "./SVG/" . $saveFile[$i] . ".svg";//SVGファイルのファイル名 $saveXML= "./XML/" . $saveFile[$i] . ".xml";//xmlファイル print("file=".$saveFile[$i] ."\n"); loadXMLsaveSVGXML($loadXML[$i],$saveXML,$saveSVG); } $endTime = microtime(true); $exeTime = $endTime - $startTime; print("exe Time=".$exeTime . "\n"); function loadXMLsaveSVGXML($loadXML,$saveXML,$saveSVG){ $startTime = microtime(true); //重複したデータを配列から取り除き県境と海岸線だけのデータにする。 //数が10個(?)以下のデータは削除。小さい小島とかは省略する。 print("XML file loading..."); $dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->load($loadXML); $root = $dom->getElementsByTagName("*")->item(0);//最初の要素の中身を取り出す $i = 0; foreach( $root->getElementsByTagNameNS("*","Curve") as $itemGML ){//これでgml:Curveのところが取れるらしい。 $dataArray = explode("\n",$itemGML->nodeValue);//改行コードで配列にわける $j=0; foreach ($dataArray as $item) {//各要素ごとに繰り返す $item = trim($item); if($item != ""){//空白文字列の時には処理をしない。 $coordinate[$i][$j]=$item; $j++; } } $i++; } $i = 0; foreach( $root->getElementsByTagNameNS("*","Curve") as $itemGML ){//これでgml:Curveのところが取れるらしい。 $dataArray = explode("\n",$itemGML->nodeValue);//改行コードで配列にわける $j=0; foreach ($dataArray as $item) {//各要素ごとに繰り返す $item = trim($item); if($item != ""){//空白文字列の時には処理をしない。 $coordinate[$i][$j]=$item; $j++; } } $i++; } print("\n"); //行政区域の重なりを調べ、重なっている場合にはかさなっている座標を削除する。 $figMax = count($coordinate); for ($fig1=0 ;$fig1<$figMax ; $fig1++){ print(" ($fig1/$figMax)\r"); for ($fig2=$fig1+1 ;$fig2<$figMax ; $fig2++){ $checkArray = array(); $checkArray = array_intersect($coordinate[$fig1],$coordinate[$fig2]);//2つの配列で重なった部分をしらべる if (count($checkArray) !== 0){//重なりがある場合 $doublePoint = array();//重なっている座標を入れる配列。 $doublePoint = array_intersect($coordinate[$fig1],$coordinate[$fig2]);//重なった値を返す $doublePoint = array_values($doublePoint);//キーをつめる //$coordinate[$fig1]と$doublePointで共通する値を削除する。 $coordinate[$fig1] = array_diff($coordinate[$fig1],$doublePoint);//配列の差を求める。$coordinate[$fig1]から共通の項目を引く //$fig2について $coordinate[$fig2] = array_diff($coordinate[$fig2],$doublePoint); $coordinate[$fig1] = array_values($coordinate[$fig1]);//キーをつめる $coordinate[$fig2] = array_values($coordinate[$fig2]);//キーをつめる } } } //削除してなくなった行政区域を調べる for ($fig1=0 ;$fig1<$figMax ; $fig1++){ $dataCount = count($coordinate[$fig1]);//その行政区域の座標データ数を調べる if ($dataCount < 10){ unset($coordinate[$fig1]);//座標データが0だったらその配列を削除 } } $coordinate = array_values($coordinate);//キーをつめる $deleteCount = count($coordinate); print("deleted($deleteCount/$figMax)\n"); //======================距離を調べて点と点が離れている時には別の配列データにする。 $m = 0; $figMax = count($coordinate); for ($i=0 ;$i<$figMax ; $i++){ $jmax = count($coordinate[$i]); $n = 0;//新しい配列に入れるためにnを0にする。 for ($j=0 ;$j<$jmax-1 ; $j++){ $latilongArray = explode(" ",$coordinate[$i][$j]);//空白区切りでデータを取り出す $latitude1String = $latilongArray[0];//各要素を取り出す $longitude1String = $latilongArray[1]; $latilongArray = explode(" ",$coordinate[$i][$j+1]);//空白区切りでデータを取り出す $latitude2String = $latilongArray[0];//各要素を取り出す $longitude2String = $latilongArray[1]; $x1 = floatval($latitude1String);//文字列のデータをfloatに変換する。 $y1 = floatval($longitude1String); $x2 = floatval($latitude2String); $y2 = floatval($longitude2String); $dx = $x2 - $x1; $dy = $y2 - $y1; $s = $dx * $dx + $dy * $dy;//$jと$j+1の距離の二乗 この値で判定する。 $temp[$m][$n] = $coordinate[$i][$j];//$jのデータを配列に入れる。tempは作業用の仮の配列 $n++;//次のためにnをひとつ進める。 if (($s > 1.0E-4) || ($n > 30000)){//$j+1が遠くにあるときの処理 もしくは一つの図形が大きくなりすぎた時に分割する。 $m++;//新規の図形 新しい配列に入れる。 $n = 0;//新しい配列の先頭から //$temp[$m][$n] = $coordinate[$i][$j+1]; } }// for $j $m++;//元の配列が一つ終わったら次の配列にする。 }// for $i $temp = array_values($temp);//キーをつめる $coordinate = $temp;//元の配列に戻す。 // $figMax = count($coordinate); for ($fig1=0 ;$fig1<$figMax ; $fig1++){ $dataCount = count($coordinate[$fig1]);//その行政区域の座標データ数を調べる if ($dataCount < 10){ unset($coordinate[$fig1]);//座標データが0だったらその配列を削除 } } $coordinate = array_values($coordinate);//キーをつめる $deleteCount = count($coordinate); print("deleted($deleteCount/$figMax)\n"); //=========================XMLで図形を書き出す $contents='<?xml version="1.0" encoding="UTF-8"?>'; $contents .="\n"; $contents .='<ksj>' . "\n"; //境界線データの書き出し polylineでデータで書き出す。 $imax = count($coordinate); for ($i=0 ;$i<$imax ; $i++){ $contents .='<gml>'. "\n";//図形の書き出し $jmax = count($coordinate[$i]); for ($j=0 ;$j<$jmax ; $j++){ $contents .= $coordinate[$i][$j] . "\n"; } $contents .= '</gml>' . "\n"; } $contents .='</ksj>' . "\n"; file_put_contents($saveXML, $contents); //=========================SVGで書き出す //スクリーンサイズ $screenWidth = 4000; $screenHeight = 4000; /*日本地図を描くための範囲を決める。 最北端:北緯45度33分28秒 東経148度45分14秒 46.0 最南端:北緯20度25分30.6585秒 東経136度4分11.1766秒 20.0 最東端:北緯24度17分12秒 東経153度58分50秒 154.0 最西端:北緯24度26分58秒 東経122度56分01秒 122.0 */ $north_max = 46.0; $south_max = 20.0; $east_max = 154.0; $west_max = 122.0; $y_max = log(tan(pi()/4.0 + deg2rad($north_max)/2.0)); $y_min = log(tan(pi()/4.0 + deg2rad($south_max)/2.0)); $x_max = deg2rad($east_max);//横方向 $x_min= deg2rad($west_max); print("x min=" . $x_min . " x max=" . $x_max . " : y min=" . $y_min . " y max=".$y_max ."\n"); $cLo = ($x_max - $x_min)/2 + $x_min; $dx = $x_max - $x_min; $dy = $y_max - $y_min; $mX = $screenWidth/$dx; $mY = $screenHeight/$dy; if ($mX < $mY){ $multiple = $mX; } else { $multiple = $mY; } //y軸の描画用の定数 $yOffset = $y_max; print("multiple=" . $multiple ."\n"); //==========================SVGファイルを書き出す $contents='<?xml version="1.0" standalone="no"?>'; $contents .="\n"; $contents .='<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'; $contents .="\n"; $contents .='<svg width="40cm" height="40cm" viewBox="0 0 4000 4000" xmlns="http://www.w3.org/2000/svg" version="1.1">'; $contents .="\n"; $contents .='<desc>都道府県の境界線データ</desc>'; $contents .="\n"; $contents .='<polyline fill="none" stroke="black" stroke-width="1" points="0,0 4000,0 4000,4000,0,4000" />';//図形の書き出し //境界線データの書き出し polylineでデータで書き出す。 $imax = count($coordinate); print("imax=$imax\n"); for ($i=0 ;$i<$imax ; $i++){ $jmax = count($coordinate[$i]); //print("jmax=$jmax\n"); $svgData = ""; for ($j= 0;$j<$jmax ; $j++){ //メルカトル図法による計算。 $latilongArray = explode(" ",$coordinate[$i][$j]);//空白で区切る //print("strring=" . $coordinate[$i][$j] . "\n"); $latitude1String = $latilongArray[0];//各要素を取り出す $longitude1String = $latilongArray[1]; $radian = deg2rad(floatval($latitude1String)); $x = deg2rad(floatval($longitude1String)) - $cLo;//横方向 $y = log(tan(pi()/4.0 + $radian/2.0));//縦方向 $x = $multiple * $x + $screenWidth/2; $y = $multiple * (1.0 - $y) - ($multiple * (1.0-$yOffset)); $svgData .= $x . "," . $y . " "; } $contents .='<polyline fill="none" stroke="blue" stroke-width="1" points="';//図形の書き出し $contents .= $svgData . '" />' . "\n"; } $contents .="</svg>"; file_put_contents($saveSVG, $contents); $endTime = microtime(true); $exeTime = $endTime - $startTime; print("exe Time=".$exeTime . "\n"); } |
ちょっと長いコードになってきました。実行時間もかなりかかります。私のMacBook Pro(macOS Sierra 2.9 GHz Intel Core i5)では12096秒(201分)かかりました。
3. PHPのバージョンについて
余談ですがPHPのバージョンは7.0を使っています。
標準で入っているPHPは5.0系だと思いますが7.0系にすると処理速度が格段に上がります。だいたい2倍ぐらいに速度あがります。
PHPのバージョンアップは「MacをPHP7へバージョンアップする」あたりを参考にどうぞ。
4. XMLからSVGを作成するPHP
次に書き出したXMLから47都道府県を1枚のSVGに描画するPHPが必要になります。
plotXML2JapanPrefBound.php
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
<?php //XMLフォルダに保存した各県のデータを読み取りSVGを描画 ini_set('memory_limit', '2540M'); mb_language("Japanese");//文字コードの設定 mb_internal_encoding("UTF-8"); //ファイルリスト $xmlFile[1] ="./XML/hokkaido.xml"; $xmlFile[2] ="./XML/aomori.xml"; $xmlFile[3] ="./XML/iwate.xml"; $xmlFile[4] ="./XML/miyagi.xml"; $xmlFile[5] ="./XML/akita.xml"; $xmlFile[6] ="./XML/yamagata.xml"; $xmlFile[7] ="./XML/fukushima.xml"; $xmlFile[8] ="./XML/ibaraki.xml"; $xmlFile[9] ="./XML/tochigi.xml"; $xmlFile[10] ="./XML/gunnma.xml"; $xmlFile[11] ="./XML/saitama.xml"; $xmlFile[12] ="./XML/chiba.xml"; $xmlFile[13] ="./XML/tokyo.xml"; $xmlFile[14] ="./XML/kanagawa.xml"; $xmlFile[15] ="./XML/niigata.xml"; $xmlFile[16] ="./XML/toyama.xml"; $xmlFile[17] ="./XML/isihikawa.xml"; $xmlFile[18] ="./XML/fukui.xml"; $xmlFile[19] ="./XML/yamanashi.xml"; $xmlFile[20] ="./XML/nagano.xml"; $xmlFile[21] ="./XML/gifu.xml"; $xmlFile[22] ="./XML/sizuoka.xml"; $xmlFile[23] ="./XML/aiti.xml"; $xmlFile[24] ="./XML/mie.xml"; $xmlFile[25] ="./XML/shiga.xml"; $xmlFile[26] ="./XML/kyoto.xml"; $xmlFile[27] ="./XML/osaka.xml"; $xmlFile[28] ="./XML/hyougo.xml"; $xmlFile[29] ="./XML/nara.xml"; $xmlFile[30] ="./XML/wakayama.xml"; $xmlFile[31] ="./XML/tottori.xml"; $xmlFile[32] ="./XML/shimane.xml"; $xmlFile[33] ="./XML/okayama.xml"; $xmlFile[34] ="./XML/hiroshima.xml"; $xmlFile[35] ="./XML/yamaguchi.xml"; $xmlFile[36] ="./XML/tokushima.xml"; $xmlFile[37] ="./XML/kagawa.xml"; $xmlFile[38] ="./XML/ehime.xml"; $xmlFile[39] ="./XML/kouchi.xml"; $xmlFile[40] ="./XML/fukuoka.xml"; $xmlFile[41] ="./XML/saga.xml"; $xmlFile[42] ="./XML/nagasaki.xml"; $xmlFile[43] ="./XML/kumamoto.xml"; $xmlFile[44] ="./XML/ooita.xml"; $xmlFile[45] ="./XML/miyazaki.xml"; $xmlFile[46] ="./XML/kagoshima.xml"; $xmlFile[47] ="./XML/okinawa.xml"; $saveSVG = "./japanPrefBound.svg"; readXMLmakeOutline($xmlFile,$saveSVG); function readXMLmakeOutline($xmlFile,$saveSVG){ $startKenNo = 1; $endKenNo = 47; for ($ken=$startKenNo; $ken<$endKenNo+1; $ken++){ //XMLの読み込み $dom = new DOMDocument('1.0', 'UTF-8'); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->load($xmlFile[$ken]); $root = $dom->getElementsByTagName("*")->item(0);//最初の要素の中身を取り出す //読み込んだxmlの中身を$coordinateStringに展開する。 $j = 0; foreach( $root->getElementsByTagName("gml") as $itemGML ){//これでgmlの中身を$itemに取れる。 $dataArray = explode("\n",$itemGML->nodeValue);//改行コードで配列にわける $i=0; foreach ($dataArray as $item) {//各要素ごとに繰り返す $item = trim($item); if($item != ""){//空白文字列の時には処理をしない。 $coordinate[$ken][$j][$i]=$item; $i++; }//if }//foreach $j++; }//foreach( $root-> }//for ($ken=$startKenNo; $ken<$endKenNo+1; $ken++) XMLの読み込み完了 //=========================SVGで書き出す //スクリーンサイズ $screenWidth = 4000; $screenHeight = 4000; //日本地図を描くための範囲を決める。 $north_max = 46.0;//最北端:北緯45度33分28秒 東経148度45分14秒 46.0 $south_max = 20.0;//最南端:北緯20度25分30.6585秒 東経136度4分11.1766秒 20.0 $east_max = 154.0;//最東端:北緯24度17分12秒 東経153度58分50秒 154.0 $west_max = 122.0;//最西端:北緯24度26分58秒 東経122度56分01秒 122.0 $y_max = log(tan(pi()/4.0 + deg2rad($north_max)/2.0)); $y_min = log(tan(pi()/4.0 + deg2rad($south_max)/2.0)); $x_max = deg2rad($east_max);//横方向 $x_min= deg2rad($west_max); $cLo = ($x_max - $x_min)/2 + $x_min; $dx = $x_max - $x_min; $dy = $y_max - $y_min; $mX = $screenWidth/$dx; $mY = $screenHeight/$dy; if ($mX < $mY){ $multiple = $mX; } else { $multiple = $mY; } //y軸の描画用の定数 $yOffset = $y_max; print("multiple=" . $multiple ."\n"); //==========================SVGファイルを書き出す $contents='<?xml version="1.0" standalone="no"?>'; $contents .="\n"; $contents .='<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'; $contents .="\n"; $contents .='<svg width="40cm" height="40cm" viewBox="0 0 4000 4000" xmlns="http://www.w3.org/2000/svg" version="1.1">'; $contents .="\n"; $contents .='<desc>都道府県の境界線データ</desc>'; $contents .="\n"; $contents .='<polyline fill="none" stroke="black" stroke-width="1" points="0,0 4000,0 4000,4000,0,4000" />';//図形の書き出し //境界線データの書き出し polylineでデータで書き出す。 for ($ken=$startKenNo; $ken<$endKenNo+1; $ken++){ $imax = count($coordinate[$ken]); print("imax=$imax\n"); for ($i=0 ;$i<$imax ; $i++){ $jmax = count($coordinate[$ken][$i]); //print("jmax=$jmax\n"); $svgData = ""; for ($j= 0;$j<$jmax ; $j++){ //メルカトル図法による計算。 $latilongArray = explode(" ",$coordinate[$ken][$i][$j]);//空白で区切る $latitude1String = $latilongArray[0];//各要素を取り出す $longitude1String = $latilongArray[1]; $radian = deg2rad(floatval($latitude1String)); $x = deg2rad(floatval($longitude1String)) - $cLo;//横方向 $y = log(tan(pi()/4.0 + $radian/2.0));//縦方向 $x = $multiple * $x + $screenWidth/2; $y = $multiple * (1.0 - $y) - ($multiple * (1.0-$yOffset)); $svgData .= $x . "," . $y . " "; } $contents .='<polyline fill="none" stroke="blue" stroke-width="1" points="';//図形の書き出し $contents .= $svgData . '" />' . "\n"; } } $contents .="</svg>"; file_put_contents($saveSVG, $contents); }// end of function |
このスクリプトでjapanPrefBound.svgというファイルが出来上がります。このファイルをSVGを表示できるアプリで開けば県別の白地図になっています。が、、、このファイル266.6MBもあって簡単には開けません。Illustratorでは無理。Safariも開けませんでした。Chromeで開けますが全体を描画し終わるまでに時間がかかります。ゆっくりと描画していく様子を見ながら待ちましょう。
とりあえず出来ましたが、このままでは使い勝手が悪すぎるのでファイルサイズを軽くするために以下の事を考えます。
・小さい島は描画しない。
・点と点の間隔を調整する。広げる。
これは次の記事で。