ShapefileをOpenLayersで表示する。[1]

ShapefileをOpenLayersで表示する。[その1]

Shapefileを直接読み込んで、OpenLayer上で表示してみます。
元ネタは、js-shapefile-to-geojsonで公開されているJavaScriptを使いました。

開発環境は、Windows 7 32bit,Aptana Studio 3.4
Firefox 20.0とGoogle Chromeで確認しました。IE9では表示できないみたいです。

必要なJavaScript

js-shapefile-to-geojsonからmasterのZIPをdownloadして、unzipします。 とりあえずDesktopでも大丈夫です。
後は、OpenLayersをここから2.12をdownloadして解凍しておきます。

Folder,Fileの構成は
blog.godo-tys.jp_wp-content_gallery_shapefile_1_image01.jpg
な感じです。

testdata folderに表示させてたいShapefile一式をcopy、その際にshp,shx、dbfの3つのファイルが必要になります。

ここで、htmlファイルは、私が作成したものです。また、ecl.js,encoding.js,utf8.jsは書き加えたものです。OpenLayers-Proj4.jsは必要ありません。

Shapefileを表示してみる。

HTML5で作成します。file名は、shp2json.htmlです。
codeは簡単です。exmaple folderをhtmlを参考にして若干手を加えています。

<!doctype html>
<html>
	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
		<title>js-shapefile-to-geojson Demo Page</title>
		<script src="lib/OpenLayers/OpenLayers.js"></script>
		<script src="stream.js"></script>
		<script src="shapefile.js"></script>
		<script src="dbf.js"></script>
		<link rel="stylesheet" href="lib/OpenLayers/theme/default/style.css" type="text/css" />
		<script type="text/javascript">
			var map;
 
			function init() {
 
				map = new OpenLayers.Map("map", {
					allOverlays : true
				}), parser = new OpenLayers.Format.GeoJSON(),
						vector = new OpenLayers.Layer.Vector("Converted"),
						shapefile = new Shapefile({
							shp : "testdata/c14_region.shp",
							dbf : "testdata/c14_region.dbf"
				}, function(data) {
					var features = parser.read(data.geojson);
					vector.addFeatures(features);
					map.zoomToExtent(vector.getDataExtent());
				})
				map.addLayer(vector);
 
				map.addControl(new OpenLayers.Control.LayerSwitcher());
				map.addControl(new OpenLayers.Control.Attribution());
				map.addControl(new OpenLayers.Control.ScaleLine());
				map.addControl(new OpenLayers.Control.MousePosition());
 
				// Interaction; not needed for initial display.
				selectControl = new OpenLayers.Control.SelectFeature(vector);
				map.addControl(selectControl);
				selectControl.activate();
				vector.events.on({
					'featureselected' : onFeatureSelect,
					'featureunselected' : onFeatureUnselect
				});
			}
 
			// Needed only for interaction, not for the display.
			function onPopupClose(evt) {
				// 'this' is the popup.
				var feature = this.feature;
				if (feature.layer) {// The feature is not destroyed
					selectControl.unselect(feature);
				} else {// After "moveend" or "refresh" events on POIs layer all
					//     features have been destroyed by the Strategy.BBOX
					this.destroy();
				}
			}
 
			function onFeatureSelect(evt) {
				feature = evt.feature;
				var table = '<table>';
				table += '<p>属性値</p>';
				for (var attr in feature.attributes) {
					table += '<tr><td>' + attr + '</td><td>' + feature.attributes[attr] + '</td></tr>';
				}
				table += '</table>';
				popup = new OpenLayers.Popup.FramedCloud("featurePopup", feature.geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(100, 100), table, null, true, onPopupClose);
				feature.popup = popup;
				popup.feature = feature;
				map.addPopup(popup, true);
			}
 
			function onFeatureUnselect(evt) {
				feature = evt.feature;
				if (feature.popup) {
					popup.feature = null;
					map.removePopup(feature.popup);
					feature.popup.destroy();
					feature.popup = null;
				}
			}
 
		</script>
		<style type="text/css">
			html, body {
				height: 100%;
				width: 100%;
			}
			#map {
				height: 400px;
				width: 600px;
				background-color: #eee;
			}
		</style>
	</head>
	<body  onload="init()">
		<div id="map"></div>
		<p>
			View project at <a href="http://github.com/wavded/js-shapefile-to-geojson">
				http://github.com/wavded/js-shapefile-to-geojson</a>.
	</body>
</html>

要するに、Shapefileを読み込んで、GeoJSONにして、OpenLayers上にVectorのfeatureを作成すると言うことです。

shpとdbfのbinary dataをstream.jsで読み込んで、GeoJSONを作成します。

FireFoxで実行させると、
blog.godo-tys.jp_wp-content_gallery_shapefile_1_image02.jpg

な感じで、Shapefileが表示されます。Good Job!!ですね。
ここでは、神奈川県の市区町村の行政界を表示しています。

また、GeoJSONに変換して表示されたfeatureをクリックすると属性値が表示されます。
blog.godo-tys.jp_wp-content_gallery_shapefile_1_image03.jpg

な感じです。

が。。。。 みての通り、nameが日本語表示されません。
どうやっても、属性データが文字化けしてしまいます。
これは、2byte codeで表現される日本語が化けるのです。

utf8変換のjsを利用したり、encodingを試したのですが。。。
問題点は、このbainaryをstream.jsで呼び出す際に1byteごと読み出して、code変換しているため文字化けすることはわかったのですが。Firebugで追っかけてもみました。
いかんせん、力量不足。。。

問題点と修正

またもや、2byteの日本語の壁にぶち当たりました。
変更すべき点は、

  1. binary dataをdbfのfield.lengthで一度に呼び込む
  2. 1byteか2byteかの判断をする。
  3. 2byteならば、encodingでutf8へ変換する。

これでいけるんじゃない? だからそのcodeは?

何か良い知恵はないでしょうか? ぜひお知恵を拝借させてください。

次回は、https://github.com/RandomEtc/shapefile-jsを使ったexampleについて書きます。
が。。。ここにも問題が。

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

WP-SpamFree by Pole Position Marketing

Social Widgets powered by AB-WebLog.com.