室蘭市の地理情報付きオープンデータ(選挙ポスター掲示場)を使ってみた
むろらんオープンデータライブラリにて、「選挙ポスター掲示場」というデータが公開されたという情報をFacebookで知ったので触ってみました。
例によってIE9以上、Chrome推奨です。
データに位置情報が付加されていると、簡単に地図上にプロットできて楽しいですね。
室蘭市では、公開されているその他のCSVファイルにも全て座標情報が追加されたそうです。すばらしい!
(個人的には、「X座標,Y座標」より「緯度,経度」情報の方が手軽に使いやすいんじゃないかと思ったりもしますが)
とりあえず、今回はShapeファイルのデータを使用しました。
掲示板の線データだけでは小さくて地図上では見えにくいのでcircle要素を重ねてます。ついでに投票区ごとに色分けしてみました。
他、Google MapsやD3.jsで表示するために行ったデータコンバート処理については、サンプルコードの後に簡単ですが手順を掲載しています。
サンプル
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 |
d3.json("senkyo.geojson", function(line) { d3.json("point.geojson", function(point) { main(line, point); }); }); function main(line, point) { //カラーリスト作成 var color =d3.scale.category20b(); var color2 = d3.scale.category20(); var color3 = d3.scale.category10(); var cl = color.range(); var colorList = cl.concat( color2.range() ); colorList = colorList.concat( color3.range() ); //ツールチップ var tooltip = d3.select("body") .append("div") .attr("class", "tooltip") .style("position", "absolute") .style("z-index", "10") .style("visibility", "hidden") //Google Map 初期化 var map = new google.maps.Map(document.getElementById('map'), { zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP, center: new google.maps.LatLng(42.3352306 , 140.97379909999995), }); //ストリートビュー初期化 var streetViewDiv = document.getElementById("streetview"); var stOptions = { pov: { heading: 00, pitch: 0, zoom: 2 } }; //ストリートビューオブジェクトの生成 var streetViewPanorama = new google.maps.StreetViewPanorama(streetViewDiv, stOptions); var streetViewService = new google.maps.StreetViewService(); //ストリートビューを表示 showStreetView = function(d){ var latlng = new google.maps.LatLng(d[1], d[0]); streetViewPanorama.setVisible(false); streetViewService.getPanoramaByLocation(latlng, 30, function(status){ if(status){ streetViewPanorama.setPosition(latlng); streetViewPanorama.setVisible(true); }else{ console.log(status); alert("StreetView 非対応エリアです"); }; }); } //OverLayオブジェクトの作成 var overlay = new google.maps.OverlayView(); overlay.onAdd = function () { //オーバーレイ設定 var layer = d3.select(this.getPanes().overlayMouseTarget).append("div").attr("class", "SvgOverlay"); var svg = layer.append("svg"); var svglayer = svg.append("g").attr("class", "svglayer"); var markerOverlay = this; var overlayProjection = markerOverlay.getProjection(); //Google Projection作成 var googleMapProjection = function (coordinates) { var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]); var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates); return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000]; } //パスジェネレーター作成 path = d3.geo.path().projection(googleMapProjection); overlay.draw = function () { var linedata = line.features; var pointdata = point.features; pointdata.forEach(function(d){ d.latlng = [ d.geometry.coordinates[0], d.geometry.coordinates[1] ]; var tmp = googleMapProjection(d.latlng); d.x = tmp[0]; d.y = tmp[1]; }) //地物(掲示板)描く svglayer.selectAll("path") .data(linedata) .attr("d", function(d){ return path(d) }) .enter() .append("path") .attr({ "d": function(d){ return path(d)}, "fill": "red", }); //サークルを重ねる var circleAttr = { "cx":function(d) { return d.x; }, "cy":function(d) { return d.y; }, "r":8, "stroke": "gray", "fill":function(d){ return colorList[+d.properties['投票区']] }, "fill-opacity":0.4 } svglayer.selectAll("circle") .data(pointdata) .attr(circleAttr) .enter() .append("svg:circle") .attr(circleAttr) .on("click", function(d){ showStreetView(d.latlng) }) .on("mouseover", function(d) { tooltip.style("visibility", "visible"); }) .on("mouseout", function(d) { tooltip.style("visibility", "hidden"); }) .on("mousemove", function(d){ var content = "投票:"+d.properties['投票区']+"区<br/>"; content += d.properties['住所'] tooltip .style("top", (d3.event.pageY-10)+"px") .style("left",(d3.event.pageX+10)+"px") .html(content); }); }; }; //作成したSVGを地図にオーバーレイする overlay.setMap(map); }; |
作業メモ
わりと四苦八苦したので、自分用に記録しておきます。
- QGISを使ってデータ内容の確認とGeoJSONへのコンバート。
- 元データがライン(線)データだったので、QGIS上で各線データの中心点を求めポイント(点)データを作成
(線データにバッファを作成し、その重心を点データとして出力) - GeoJSONの出力時にCRS(座標系)を「WGS84」に変換。
時間があったら、この辺の作業について別記事に詳細を書こうかと思います。