Shapefileをcanvasに描画する。
ShapefileをOpenLayersで表示する。[その2] に続いて、Shapefileを直接読み込んで、canvasに描画してみます。
元ネタは、shapefile-jsで公開されているJavaScriptを使いました。
開発環境は、Windows 7 32bit,Aptana Studio 3.4
Firefox 20.0とGoogle Chromeで確認しました。
必要なJavaScript
shapefile-jsからmasterのZIPをdownloadして、unzipします。 とりあえずDesktopでも大丈夫です。
kanagawa folderに表示させたいShapefile一式をcopy、その際にshp,shx、dbfの3つのファイルが必要になります。
canvasに描画してみる。
exampleのファイルを編集します。
HTML5で作成します。file名は、ol_simple.htmlとol_simple.jsです。
codeは簡単です。元のcodeを参考にして若干手を加えています。
<!DOCTYPE html> <html lang="ja"> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title>Javascript Shapefile and DBF Loader</title> <script type="text/javascript" src="lib/binaryajax.js"></script> <script type="text/javascript" src="src/binarywrapper.js"></script> <script type="text/javascript" src="src/shapefile.js"></script> <script type="text/javascript" src="src/dbf.js"></script> <!--[if IE]> <script src="lib/excanvas.js"></script><![endif]--> <script type="text/javascript"> //var shpURL = "thematicmapping/TM_WORLD_BORDERS_SIMPL-0.3.shp"; //var dbfURL = "thematicmapping/TM_WORLD_BORDERS_SIMPL-0.3.dbf"; var shpURL = "kanagawa/c14_region.shp"; //表示したいShape file名 var dbfURL = "kanagawa/c14_region.dbf"; //表示したいdbf file名 var shpFile; var dbfFile; window.onload = function() { var shpLoader = new BinaryAjax(shpURL, onShpComplete, onShpFail); var dbfLoader = new BinaryAjax(dbfURL, onDbfComplete, onDbfFail); } function onShpFail() { alert('failed to load ' + shpURL); } function onDbfFail() { alert('failed to load ' + dbfURL); } function onShpComplete(oHTTP) { var binFile = oHTTP.binaryResponse; if (window.console && window.console.log) console.log('got data, parsing shapefile'); shpFile = new ShpFile(binFile); if (shpFile.header.shapeType != ShpType.SHAPE_POLYGON && shpFile.header.shapeType != ShpType.SHAPE_POLYLINE) { alert("Shapefile does not contain Polygon records (found type: " + shpFile.header.shapeType + ")"); } //if (window.console && window.console.log) console.log(records); if (dbfFile) { render(shpFile.records, dbfFile.records); } } function onDbfComplete(oHTTP) { var binFile = oHTTP.binaryResponse; if (window.console && window.console.log) console.log('got data, parsing dbf file'); dbfFile = new DbfFile(binFile); if (shpFile) { render(shpFile.records, dbfFile.records); } } function render(records, data) { if (window.console && window.console.log) console.log('creating canvas and rendering'); var canvas = document.getElementById('map'); if (window.G_vmlCanvasManager) { G_vmlCanvasManager.initElement(canvas); } var t1 = new Date().getTime(); if (window.console && window.console.log) console.log('calculating bbox...'); var box; for (var i = 0; i < records.length; i++) { var record = records[i]; if (record.shapeType == ShpType.SHAPE_POLYGON || record.shapeType == ShpType.SHAPE_POLYLINE) { var shp = record.shape for (var j = 0; j < shp.rings.length; j++) { var ring = shp.rings[j]; for (var k = 0; k < ring.length; k++) { if (!box) { box = { x : ring[k].x, y : ring[k].y, width : 0, height : 0 }; } else { var l = Math.min(box.x, ring[k].x); var t = Math.min(box.y, ring[k].y); var r = Math.max(box.x + box.width, ring[k].x); var b = Math.max(box.y + box.height, ring[k].y); box.x = l; box.y = t; box.width = r - l; box.height = b - t; } } } } } var t2 = new Date().getTime(); if (window.console && window.console.log) console.log('found bbox in ' + (t2 - t1) + ' ms'); t1 = new Date().getTime(); if (window.console && window.console.log) console.log('starting rendering...'); var ctx = canvas.getContext('2d'); var sc = Math.min(600 / box.width, 400 / box.height); ctx.fillStyle = '#ccccff'; ctx.fillRect(0, 0, 600, 400); ctx.lineWidth = 0.5; //ctx.strokeStyle = '#ffffff'; ctx.strokeStyle = '#000000'; for (var i = 0; i < records.length; i++) { var record = records[i]; if (record.shapeType == ShpType.SHAPE_POLYGON || record.shapeType == ShpType.SHAPE_POLYLINE) { var shp = record.shape; for (var j = 0; j < shp.rings.length; j++) { var ring = shp.rings[j]; if (ring.length < 1) continue; ctx.fillStyle = rndColor(0); ctx.beginPath(); ctx.moveTo((ring[0].x - box.x) * sc, 400 - (ring[0].y - box.y) * sc); for (var k = 1; k < ring.length; k++) { ctx.lineTo((ring[k].x - box.x) * sc, 400 - (ring[k].y - box.y) * sc); } ctx.fill(); ctx.stroke(); } } } t2 = new Date().getTime(); if (window.console && window.console.log) console.log('done rendering in ' + (t2 - t1) + ' ms'); } function rndColor(start) { var base = 0; if (start == 1) { base = 40; } else { base = 127; } var r = base + Math.floor(128 * Math.random()); var g = base + Math.floor(128 * Math.random()); var b = base + Math.floor(128 * Math.random()); return '#' + r.toString(16) + g.toString(16) + b.toString(16); } </script> <style type="text/css"> body { background-color: #eeeeee; color: #000000; font: 12px sans-serif; margin: 20px; } canvas { background-color: #FFFFFF; padding: 10px; } </style> </head> <body> <h1>Javascript Shapefile and DBF Loader</h1> <h2>Shapefileを読み込んでcanvasに描画するサンプル (Firefox,Chrome)</h2> <p> Loading shapefile... uninformative errors may appear in the dark crevices of your browser. </p> <canvas id="map" width="600" height="400"></canvas> <p> See <a href="http://github.com/RandomEtc/shapefile-js">http://github.com/RandomEtc/shapefile-js</a> for more details. </p> </body> </html>
な感じで、Shapefileが表示されます。Good Job!!ですね。
ここでは、神奈川県の市区町村の行政界を表示しています。
これは、いろいろと使えますよね。
覚えておいて損はnice!!
最近のコメント