4

メルカトル図法 (緯度/経度) の左下と右上の座標がわかっている画像があります。

ドイツの現在の気象条件のイメージ

としてGoogleマップに追加しましたgoogle.maps.GroundOverlay。これにより、正しい結果が得られます

ここに画像の説明を入力

画像の左上 (緑)、右上 (赤)、右下 (シアン)、左下 (赤) の各コーナーにカラー マーカーを追加しました。

d3ははるかに軽量で、Googleマップの機能は必要ないため、topojsonを使用してGoogleマップからd3に移行したいことを除いて、これはすべて問題ありません。

画像のコーナーのマーカーを含む d3 ベースのマップを作成しました。これが結果です。

ここに画像の説明を入力

2 つのウィンドウ (Google マップ マップを含むブラウザーと d3 マップを含むブラウザー) を重ね合わせると、国の境界線とコーナー ポイントを非常に正確に重ねることができます。

これは、Google マップ マップ ブラウザの上に d3-map ブラウザを重ねたアニメーション GIF です。d3-map ブラウザ ウィンドウの透明度は、ツールを使用して変更されています。完全に不透明から完全に透明になり、完全に不透明に戻ります。国名の画像はGoogleマップのものです。

ここに画像の説明を入力

ご覧のとおり、ポイントと国境は非常にうまく一致していますが、レーダー画像は一致していません。d3 イメージを少し下に移動すると問題は緩和されますが、正しい解決策ではありません。Google マップで表示されているのが であることは知っています。

私がやっていること: d3 マップで、投影を作成しています

projection = d3.geo.mercator().scale(scale).translate([width / 2, width / 2]).center(center);

次に、提供された画像の緯度経度コーナーの境界ボックスを作成します。

bb = {
  east:  16.0,
  west:   4.0,
  north: 56.0,
  south: 46.0,
}

そして、それらを緯度経度空間からキャンバスの x、y 座標に投影します。

p_ur = projection([bb.east, bb.north]).map(function(x) { return x; })
p_ll = projection([bb.west, bb.south]).map(function(x) { return x; })
p_ul = projection([bb.west, bb.north]).map(function(x) { return x; })
p_lr = projection([bb.east, bb.south]).map(function(x) { return x; })

円を描くと、位置が Google マップの位置と非常に正確に一致します。これは、投影が機能していることを意味します。

circle = svg.append("svg:circle").attr('cx',p_ll[0]).attr('cy',p_ll[1]).attr('r', 2).attr("class", "ll")
circle = svg.append("svg:circle").attr('cx',p_ur[0]).attr('cy',p_ur[1]).attr('r', 2).attr("class", "ur")
circle = svg.append("svg:circle").attr('cx',p_ul[0]).attr('cy',p_ul[1]).attr('r', 2).attr("class", "ul")
circle = svg.append("svg:circle").attr('cx',p_lr[0]).attr('cy',p_lr[1]).attr('r', 2).attr("class", "lr")

円を描く前に、topojson の国境を描いています。

path = d3.geo.path().projection(projection);
countries = svg.append("g");
// ...fetching the data from the web...
countries.selectAll('.country')
         .data(topojson.feature(data, data.objects.europe).features)
         .enter()
         .append('path')
         .attr('class', 'country')
         .attr('d', path);

ここで問題が発生します。非常に「安い」方法で画像を適用しています。左上の緯度経度をキャンバスの x、y 空間に投影し、それを の x、y 原点として使用しsvg:imageます。これらのポイントは、上記のカラー サークルに対して既に計算されているため、ここで再利用します。

image = svg.append("svg:image")
         .attr('x', p_ul[0])
         .attr('y', p_ul[1])
         .attr('width',  (p_lr[0] - p_ul[0]))
         .attr('height', (p_lr[1] - p_ul[1]))
         .attr('preserveAspectRatio', 'none')
         .attr("xlink:href","http://.../current.png")

どういうわけか、コーナーを使用して画像をマップの上に固定するだけで、画像の個々のピクセルデータの射影変換をスキップしています。

画像の各 x、y 位置を緯度/経度の位置として扱い、メルカトル図法を介して各ピクセルをマップに投影する必要があると想定しています。

しかし、私はそれを行う方法についての手がかりがありません。何か案は?d3.geo に似た単純なオーバーレイ プラグインはありgoogle.maps.GroundOverlayますか?

4

1 に答える 1

2

Google マップは WEB MERCATOR 投影法を使用します。これは、実際のメルカトル図法 (D3 で使用される) とは若干異なります。(ウィキペディアから引用: Web メルカトルは、主に Web ベースのマッピング プログラムで使用されるメルカトル図法のわずかな変形です。小規模な地図に使用される標準のメルカトルと同じ数式を使用します。ただし、Web メルカトルは、大縮尺のメルカトル図法は通常、楕円形の投影法を使用するのに対し、すべての縮尺で球形の式を使用します. この不一致は、地球規模では知覚できませんが、ローカル エリアの地図は、同じ縮尺の真の楕円メルカトル図法からわずかにずれます. このずれは次のようになります.赤道から離れるとより顕著になり、地上で 35 km の高さに達することがあります。

Web メルカトルの公式はメルカトルの球形を対象としていますが、地理座標は WGS 84 楕円体測地系である必要があります。この不一致により、投影がわずかに非等角になります。

D3 を使用したラスター イメージが含まれている場合にスケーリングが変更される理由について質問されたSOディスカッションがあります。繰り返しますが、これは D3 とメルカトルの違いによるものです。ラスター画像がGoogleマップで完全に整列している場合... Webメルカトルとメルカトルの微妙な違いにより、d3では決して整列しないでください。それが機能するには、ラスター画像を (再投影) する必要があると思いますこれが、d3 と Google マップで位置がずれている理由です。(私が間違った言葉を使用したことに注意するために編集しています。縮尺ではなく、むしろ再投影されています....)

これが少し役立つことを願っています。

実際、オープンソースでもある素敵な再投影ソフトウェアがここにあります: ( GDALプロジェクトの一部)。(それが少し役立つことを願っています。)

于 2016-11-05T13:46:15.500 に答える