2012-08-22 4 views
1

svg world map from wikipedia을 기반으로 모든 국가의 중심을 계산해야합니다. d3 라이브러리는 centorid method for paths을 지원합니다. 제공된 svg 파일에는 모든 국가의 경로 좌표가 포함되어 있습니다. 예 : 독일 :centroid d3을 계산하십시오

svg 데이터의 특성 "d"를 사용하여 D3 구문의 중심을 계산하려면 어떻게해야합니까? 모든 국가의 중심에 지점을 배치해야합니다.

+0

가능한 [D3.js가 포함 된 SVG 경로 중심 계산] (0120-385-303) – nrabinowitz

+0

가능한 복제본 : http :// /stackoverflow.com/questions/12062561/calculate-svg-path-centroid-with-d3-js – nrabinowitz

답변

0

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); 

을 Wikipedia SVG를 사용하고 있습니까?

2

this question에서 가져온이 example에 기초하여 중심을 계산할 수 있습니다. 이 쉬운 방법은 아마도,하지만 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 파일을 시작했다. SVG에서 normalizedPathSegList 속성이 채워지지 않으므로 경로를 직접 정규화해야합니다. Inkscape를 사용하여 PDF로 저장 한 다음 SVG 파일로 다시 가져 오는 등의 작업을 수행 할 수 있습니다. Here은 javascript를 사용하여 모든 상대 경로를 절대 경로로 변환하는 방법입니다.

BTW, 원시 d 문자열을 구문 분석하는 대신 SVGPathSegList.getItem()을 사용하여 모든 요소의 SVGPathSegList를 쿼리 할 수 ​​있습니다.

그러나 실제로 GeoJSON 세계지도를 시작하거나 찾거나 만들면 d3을 사용하여 중심을로드하고 투영하고 찾을 수 있습니다.

+0

computeCentroid 메서드가 유용합니다. 그러나 제공된 worldmap.svg 파일에는 GeoJSON 표기법이 포함되어 있지 않습니다. 이는 피처 (예 : 다각형)를 지원하지 않는다는 의미입니다. 예를 들어 독일에는 L 매개 변수뿐 아니라 다음 추출과 같은 v 및 h도 포함됩니다. ' ' – Oliver

관련 문제