[解決済み] geoJSON オブジェクトを d3 でマップの中央に配置する
2022-05-30 19:46:08
質問
現在d3では、描画しようとするgeoJSONオブジェクトがある場合、それを望みのサイズにするためにスケーリングとトランスレートし、それを中心に置くためにトランスレートする必要があります。これは試行錯誤の非常に退屈な作業で、これらの値を取得するためのより良い方法を知っている人がいれば教えてください。
たとえば、次のようなコードがあるとします。
var path, vis, xy;
xy = d3.geo.mercator().scale(8500).translate([0, -1200]);
path = d3.geo.path().projection(xy);
vis = d3.select("#vis").append("svg:svg").attr("width", 960).attr("height", 600);
d3.json("../../data/ireland2.geojson", function(json) {
return vis.append("svg:g")
.attr("class", "tracts")
.selectAll("path")
.data(json.features).enter()
.append("svg:path")
.attr("d", path)
.attr("fill", "#85C3C0")
.attr("stroke", "#222");
});
.scale(8500) と .translate([0, -1200]) を少しずつでなく、一体どうやって取得するのでしょうか?
どうすれば解決するのでしょうか?
以下のようにすると、だいたい希望通りになるようです。スケーリングは大丈夫なようです。私のマップに適用すると、小さなオフセットがあります。この小さなオフセットは、おそらく center コマンドを使用する必要がある一方で、マップを中央に配置するために translate コマンドを使用したために発生したものです。
- 投影とd3.geo.pathを作成します。
- 現在の投影の境界を計算する
- これらの境界を使用して、スケールと平行移動を計算します。
- 投影を再作成する
コードでは
var width = 300;
var height = 400;
var vis = d3.select("#vis").append("svg")
.attr("width", width).attr("height", height)
d3.json("nld.json", function(json) {
// create a first guess for the projection
var center = d3.geo.centroid(json)
var scale = 150;
var offset = [width/2, height/2];
var projection = d3.geo.mercator().scale(scale).center(center)
.translate(offset);
// create the path
var path = d3.geo.path().projection(projection);
// using the path determine the bounds of the current map and use
// these to determine better values for the scale and translation
var bounds = path.bounds(json);
var hscale = scale*width / (bounds[1][0] - bounds[0][0]);
var vscale = scale*height / (bounds[1][1] - bounds[0][1]);
var scale = (hscale < vscale) ? hscale : vscale;
var offset = [width - (bounds[0][0] + bounds[1][0])/2,
height - (bounds[0][1] + bounds[1][1])/2];
// new projection
projection = d3.geo.mercator().center(center)
.scale(scale).translate(offset);
path = path.projection(projection);
// add a rectangle to see the bound of the svg
vis.append("rect").attr('width', width).attr('height', height)
.style('stroke', 'black').style('fill', 'none');
vis.selectAll("path").data(json.features).enter().append("path")
.attr("d", path)
.style("fill", "red")
.style("stroke-width", "1")
.style("stroke", "black")
});
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン