
【D3.js】 SVGで地球儀を描く
データはNaturalEarthの「Admin 0 – Countries」から。
見づらくなるので南極大陸には消えていただいた。
消し方は、ダウンロードしたsahpeデータを Quantum GISに取り込んで、メニューの「レイヤー」から「属性テーブルのオープン」を選択。
属性テーブルの中から「sovereignt」の値が「Antractica」になっている行を選択し、下のほうにあるアイコンから「選択部分を反転する」をクリック。

南極大陸以外が選択されているのを確認して「レイヤー」から「選択部分をベクタファイルとして保存する」をクリック→「Geo JSON」形式で保存。
一応topojsonに変換して軽量化。
| 1 | $ topojson -o conuntries.topojson conuntries.geojson | 
以上で、地図データ作成終了。
あとは、D3の「Geo Projections」機能を使って表示するだけ。
この辺のデータ作成については、過去の記事に詳細を載せているので興味ある方はこちらを。
サンプルコード
| 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 | const stage = d3.select("svg"); const seaLayer = stage.append("g"); const landLayer = stage.append("g"); const projection = d3.geoOrthographic() //投影法を指定 const path = d3.geoPath()//geometryをsvgのパスに変換する関数 d3.json("conuntries.topojson", function(json){ //地図情報の読み込み   const  data = topojson.feature(json, json.objects.conuntries).features; //topojson->geojson変換   /*プロジェクション設定*/   projection     .rotate([0,0,0]) //x,y,z回転     .clipAngle(90); //表示する角度 180度を指定すると裏側の大陸まで表示される   /*パスジェネレーターにプロジェクションを設定*/   path.projection(projection);   /*海面を描画するためのパスをDOMに追加*/   seaLayer.append("path")     .datum({type: "Sphere"})     .attr("fill", "blue")    /*地図を表示するためのパスをDOMに追加*/   landLayer     .selectAll("path")     .data(data)      .enter()     .append("path")     .style("background-color", "blue")     .attr("fill", "green")     .attr("stroke", "#222")     .on("mouseover", function(){         d3.select(this).attr("fill", "red");     })     .on("mouseout", function(){         d3.select(this).transition().duration(500).attr("fill", "green");     }) }); /*地形を回転させる*/  const draw = () => {   let  i = 0;   return () => {     const w = stage.node().clientWidth;     const h = stage.node().clientHeight;     i = i+0.5;     projection       .rotate([i,0,0])  //rotateのx値を増やして横に回転させる       .scale(d3.min([w, h]) / 2) //画面サイズを元に地球儀の大きさを決定       .translate([w/2, h/2]) //画面中央に表示されるように移動する     path.projection(projection);    //path関数をアップデート     seaLayer.select("path").attr("d", path); //海面用パスを描画     landLayer.selectAll("path").attr("d", path); //地図用パスを描画   } } setInterval(draw(), 100); //定期的に回転させる |