2

ウィキペディアのsvg世界地図に基づいて、すべての国の重心を計算する必要があります。d3ライブラリは、パスのcentoridメソッドをサポートしています。提供されているsvgファイルには、すべての国のパス座標が含まれています。たとえばドイツ:

svgデータの属性「d」を使用してD3構文の重心を計算するにはどうすればよいですか?すべての国の図心にポイントを配置するために必要です。

4

2 に答える 2

3

d3 の例はこれらの投影法とファイル用に準備されるため、Mike Bostock のライブラリからの世界地図ファイルの使用を検討する必要があります。いくつかの世界地図は、例の下にあります: https://github.com/mbostock/topojson

私はそれがあなたの人生を本当に簡素化すると思います.topojsonを使って次のようなコードを書くことができます:

var svg = d3.select('#yourmap').append('svg');

var g = svg.append('g')
    .style(//some styling, like stroke-width);

var projection = //your projection
    .scale(//your scale)
    .translate(//your width/2, height/2)
var path = d3.geo.path()
    .projection(projection

//read in your json file...

var world = topojson.feature(world.objects.countries).features //guessing at a potential structure of your file

g.selectAll('circle')
        .data(world)
      .enter().append('circle')
        .attr('transform', function(d) { return 'translate(' + path.centroid(d) + ')'; })
        .attr('r', //whatever you want your radius to be, in pixels);

ウィキペディアの SVG を使用している特別な理由がない限り?

于 2016-04-27T22:14:05.150 に答える
2

この質問から取得したこのに基づいて重心を計算できます。おそらくもっと簡単な方法がありますが、d3.jsでそれを使用すると次のようになります。

function area(pts) {
    var area=0;
    var nPts = pts.length;
    var j=nPts-1;
    var p1; var p2;

    for (var i=0;i<nPts;j=i++) {
        p1=pts[i]; p2=pts[j];
        area+=p1.x*p2.y;
        area-=p1.y*p2.x;
    }
    area/=2;
    return area;
};

function computeCentroid(pts) {
    var nPts = pts.length;
    var x=0; var y=0;
    var f;
    var j=nPts-1;
    var p1; var p2;

    for (var i=0;i<nPts;j=i++) {
        p1=pts[i]; p2=pts[j];
        f=p1.x*p2.y-p2.x*p1.y;
        x+=(p1.x+p2.x)*f;
        y+=(p1.y+p2.y)*f;
    }

    f=area(pts)*6;
    return [x/f,y/f];
};

var path = d3.geo.path().projection(projection);

var map = chartSvg.selectAll('path.feature')
    .data(mapFiltered);
map.enter().append('path')
    .attr('class', 'feature');
map.attr('d', function(d, i){
    var pathString = path(d,i);
    var pathStringTrimmed = pathString.substring(1, pathString.length-1);
    var pathArray = pathStringTrimmed.split('L').map(function(d, i){var xy = d.split(','); return {x: ~~xy[0], y: ~~xy[1]};});
    console.log(computeCentroid(pathArray));
    return path(d,i);})

編集:

この例は、正規化されたパスを持つGeoJSONファイルから開始しました。NormalizedPathSegList属性が設定されていないため、SVGからパスを自分で正規化する必要がありますたとえば、InkscapeでPDFに保存し、SVGファイルに再インポートすることでそれを行うことができます。これは、 javascriptを使用してすべての相対パスを絶対パスに変換する方法です。

ところで、生のd文字列を解析する代わりに、SVGPathSegList.getItem()を使用してすべての要素のSVGPathSegListをクエリすることもできます。

ただし、重心の読み込み、投影、検索にd3を実際に使用するには、デフォルトのGeoJSON世界地図から始めるか、見つけた別の世界地図から始めた方がはるかに簡単です。

于 2012-08-22T14:46:40.277 に答える