2013-04-15 12 views
6

geoJSONファイルを使用して国を描​​画するマップがあります。私は各国を中心とした円を描きたいと思います。しかし、いくつかの境界地域を持つ国(米国は本土、ハワイ、アラスカを持っています)では、最大の境界地域に円が必要です。私は、さまざまな境界領域の領域を比較することでこれを実行しようとしていますが、理解できない理由で機能していません。D3:d3のジオポリゴンの領域を見つける

{"type":"Feature","properties":{"name":"Australia"},"geometry":{"type":"MultiPolygon","coordinates":[[[[145.397978,-40.792549],[146.364121,-41.137695],[146.908584,-41.000546],[147.689259,-40.808258],[148.289068,-40.875438],[148.359865,-42.062445],[148.017301,-42.407024],[147.914052,-43.211522],[147.564564,-42.937689],[146.870343,-43.634597],[146.663327,-43.580854],[146.048378,-43.549745],[145.43193,-42.693776],[145.29509,-42.03361],[144.718071,-41.162552],[144.743755,-40.703975],[145.397978,-40.792549]]],[[[143.561811,-13.763656],[143.922099,-14.548311],[144.563714,-14.171176],[144.894908,-14.594458],[145.374724,-14.984976],[145.271991,-15.428205],[145.48526,-16.285672],[145.637033,-16.784918],[145.888904,-16.906926],[146.160309,-17.761655],[146.063674,-18.280073],[146.387478,-18.958274],[147.471082,-19.480723],[148.177602,-19.955939],[148.848414,-20.39121],[148.717465,-20.633469],[149.28942,-21.260511],[149.678337,-22.342512],[150.077382,-22.122784],[150.482939,-22.556142],[150.727265,-22.402405],[150.899554,-23.462237],[151.609175,-24.076256],[152.07354,-24.457887],[152.855197,-25.267501],[153.136162,-26.071173],[153.161949,-26.641319],[153.092909,-27.2603],[153.569469,-28.110067],[153.512108,-28.995077],[153.339095,-29.458202],[153.069241,-30.35024],[153.089602,-30.923642],[152.891578,-31.640446],[152.450002,-32.550003],[151.709117,-33.041342],[151.343972,-33.816023],[151.010555,-34.31036],[150.714139,-35.17346],[150.32822,-35.671879],[150.075212,-36.420206],[149.946124,-37.109052],[149.997284,-37.425261],[149.423882,-37.772681],[148.304622,-37.809061],[147.381733,-38.219217],[146.922123,-38.606532],[146.317922,-39.035757],[145.489652,-38.593768],[144.876976,-38.417448],[145.032212,-37.896188],[144.485682,-38.085324],[143.609974,-38.809465],[142.745427,-38.538268],[142.17833,-38.380034],[141.606582,-38.308514],[140.638579,-38.019333],[139.992158,-37.402936],[139.806588,-36.643603],[139.574148,-36.138362],[139.082808,-35.732754],[138.120748,-35.612296],[138.449462,-35.127261],[138.207564,-34.384723],[137.71917,-35.076825],[136.829406,-35.260535],[137.352371,-34.707339],[137.503886,-34.130268],[137.890116,-33.640479],[137.810328,-32.900007],[136.996837,-33.752771],[136.372069,-34.094766],[135.989043,-34.890118],[135.208213,-34.47867],[135.239218,-33.947953],[134.613417,-33.222778],[134.085904,-32.848072],[134.273903,-32.617234],[132.990777,-32.011224],[132.288081,-31.982647],[131.326331,-31.495803],[129.535794,-31.590423],[128.240938,-31.948489],[127.102867,-32.282267],[126.148714,-32.215966],[125.088623,-32.728751],[124.221648,-32.959487],[124.028947,-33.483847],[123.659667,-33.890179],[122.811036,-33.914467],[122.183064,-34.003402],[121.299191,-33.821036],[120.580268,-33.930177],[119.893695,-33.976065],[119.298899,-34.509366],[119.007341,-34.464149],[118.505718,-34.746819],[118.024972,-35.064733],[117.295507,-35.025459],[116.625109,-35.025097],[115.564347,-34.386428],[115.026809,-34.196517],[115.048616,-33.623425],[115.545123,-33.487258],[115.714674,-33.259572],[115.679379,-32.900369],[115.801645,-32.205062],[115.689611,-31.612437],[115.160909,-30.601594],[114.997043,-30.030725],[115.040038,-29.461095],[114.641974,-28.810231],[114.616498,-28.516399],[114.173579,-28.118077],[114.048884,-27.334765],[113.477498,-26.543134],[113.338953,-26.116545],[113.778358,-26.549025],[113.440962,-25.621278],[113.936901,-25.911235],[114.232852,-26.298446],[114.216161,-25.786281],[113.721255,-24.998939],[113.625344,-24.683971],[113.393523,-24.384764],[113.502044,-23.80635],[113.706993,-23.560215],[113.843418,-23.059987],[113.736552,-22.475475],[114.149756,-21.755881],[114.225307,-22.517488],[114.647762,-21.82952],[115.460167,-21.495173],[115.947373,-21.068688],[116.711615,-20.701682],[117.166316,-20.623599],[117.441545,-20.746899],[118.229559,-20.374208],[118.836085,-20.263311],[118.987807,-20.044203],[119.252494,-19.952942],[119.805225,-19.976506],[120.85622,-19.683708],[121.399856,-19.239756],[121.655138,-18.705318],[122.241665,-18.197649],[122.286624,-17.798603],[122.312772,-17.254967],[123.012574,-16.4052],[123.433789,-17.268558],[123.859345,-17.069035],[123.503242,-16.596506],[123.817073,-16.111316],[124.258287,-16.327944],[124.379726,-15.56706],[124.926153,-15.0751],[125.167275,-14.680396],[125.670087,-14.51007],[125.685796,-14.230656],[126.125149,-14.347341],[126.142823,-14.095987],[126.582589,-13.952791],[127.065867,-13.817968],[127.804633,-14.276906],[128.35969,-14.86917],[128.985543,-14.875991],[129.621473,-14.969784],[129.4096,-14.42067],[129.888641,-13.618703],[130.339466,-13.357376],[130.183506,-13.10752],[130.617795,-12.536392],[131.223495,-12.183649],[131.735091,-12.302453],[132.575298,-12.114041],[132.557212,-11.603012],[131.824698,-11.273782],[132.357224,-11.128519],[133.019561,-11.376411],[133.550846,-11.786515],[134.393068,-12.042365],[134.678632,-11.941183],[135.298491,-12.248606],[135.882693,-11.962267],[136.258381,-12.049342],[136.492475,-11.857209],[136.95162,-12.351959],[136.685125,-12.887223],[136.305407,-13.29123],[135.961758,-13.324509],[136.077617,-13.724278],[135.783836,-14.223989],[135.428664,-14.715432],[135.500184,-14.997741],[136.295175,-15.550265],[137.06536,-15.870762],[137.580471,-16.215082],[138.303217,-16.807604],[138.585164,-16.806622],[139.108543,-17.062679],[139.260575,-17.371601],[140.215245,-17.710805],[140.875463,-17.369069],[141.07111,-16.832047],[141.274095,-16.38887],[141.398222,-15.840532],[141.702183,-15.044921],[141.56338,-14.561333],[141.63552,-14.270395],[141.519869,-13.698078],[141.65092,-12.944688],[141.842691,-12.741548],[141.68699,-12.407614],[141.928629,-11.877466],[142.118488,-11.328042],[142.143706,-11.042737],[142.51526,-10.668186],[142.79731,-11.157355],[142.866763,-11.784707],[143.115947,-11.90563],[143.158632,-12.325656],[143.522124,-12.834358],[143.597158,-13.400422],[143.561811,-13.763656]]]]},"id":"AUS"}, 

そして、ここで私は別の境界領域の面積を比較してみたコードです:

は、ここオーストラリアでは、複数の境界領域を持っているかを示す、にGeoJSONから例です。そのifの声明では、私は国が複数の境界領域(動作するように思われる)を持っているかどうかを確かめようとしています。そして、forブロックで最大のものを選んでください。

問題:私が得ている「面積」の値はすべて0で、最大値ではなく最初の境界領域から常にcoordsが選択されています。

function calculateCountryCenter(country) { 

    var coords; 

    //Check if the country has more than one bounding region. 
    if (country.geometry.coordinates.length > 1) { 

     coords = country.geometry.coordinates[0][0]; 

     var regionArea = path.area(country.geometry.coordinates[0]); 

     for (var i=0; i<country.geometry.coordinates.length; i++) { 
      if (path.area(country.geometry.coordinates[i]) > regionArea) { 

       coords = country.geometry.coordinates[i][0]; 
      } 
     }  

    } else {  
     coords = country.geometry.coordinates[0]; 
    } 

    var averageCoords = [0,0]; 
    coords.forEach(function(coord) { 
     averageCoords[0] += coord[0] 
     averageCoords[1] += coord[1] 
    }); 

    averageCoords[0] = averageCoords[0]/coords.length 
    averageCoords[1] = averageCoords[1]/coords.length 
    return averageCoords; 

} 

パスの定義は次のとおりです。

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

ご指摘いただければ幸いです。どうもありがとう。

+0

「働いていない」とはどういう意味ですか?エラーメッセージが表示されますか? –

+0

申し訳ありませんが、良い質問、私は元の投稿を編集します。何がうまくいかないのは、私がこれらの面積計算のために得ている価値がゼロであると思われることです。そして、サークルは何があっても最初の境界領域に描かれています。 – ACPrice

+0

'path'の定義も表示できますか? –

答えて

1

path.area関数は機能を必要とし、座標のリストだけでは機能しません。それを動作させる最も簡単な方法は、元のオブジェクトをコピーし、関心のない座標をすべて削除し、path.areaに渡すことです。コードは次のようになります

for (var i=0; i<country.geometry.coordinates.length; i++) { 
    var copy = JSON.parse(JSON.stringify(country)); 
    copy.geometry.coordinates = [copy.geometry.coordinates[i]]; 
    path.area(copy); 
    ... 
} 
+0

ねえ、ありがとう。私は昨夜少し明示的なソリューションを実装しました。ちょうど別の答えとしてそれを追加しました。あなたのアプローチはもう少し合理化されるかもしれません。どの単位で – ACPrice

4

誰も完全に実装された回答をまだ追加していないため、私は自分の質問に答えることにしました。ここでは、元の質問で指定されたgeoJSONを使用し、複数の境界領域を持つ国の最大境界領域の座標を返します。境界領域が1つのみの国では、境界領域の座標を返します。 (私はここに、スタンドアロン方式にするために、コードを少し変更する必要がありましたが、私はそれがエラーフリーのだと確信しています。)

function getLargestBoundingRegion(country) { 

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

//Check if the country has more than one bounding region. 
if (country.geometry.coordinates.length > 1) { 

    var regionToReturn = {   
     "type": "Feature", 
     "geometry": { 
      "type": "Polygon", 
      "coordinates": country.geometry.coordinates[0]},    
     }; 

    for (var i=1; i<country.geometry.coordinates.length; i++) { 

     var testRegion = {   
        "type": "Feature", 
       "geometry": { 
        "type": "Polygon", 
        "coordinates": country.geometry.coordinates[i]},    
      }; 

     if (path.area(testRegion) > path.area(regionToReturn)) { 
      regionToReturn = testRegion;  
      largestRegionCoords = country.geometry.coordinates[i][0];  
      } 
     } 

    } else {  
     largestRegionCoords = country.geometry.coordinates[0]; 
    } 

return largestRegionCoords; 
7

あなたはShoelace algorithmを使用して、任意の多角形の面積を計算することができます。

function polygonArea(points) { 
    var sum = 0.0; 
    var length = points.length; 
    if (length < 3) { 
    return sum; 
    } 
    points.forEach(function(d1, i1) { 
    i2 = (i1 + 1) % length; 
    d2 = points[i2]; 
    sum += (d2[1] * d1[0]) - (d1[1] * d2[0]); 
    }); 
    return sum/2; 
} 

polygonArea([[0,0], [4,0], [4,3]]); // 6 

反時計回りにポリゴンが正の面積を持っていることに注意してください、と時計回りのポリゴンは負の面積を持つことになります。自己交差するポリゴンは通常、時計回りと反時計回りの両方の領域を持ち、その領域は相殺されます。

+0

が結果になりますか? –

+0

@PaulVidal、入力として使用されるポイント座標と同じ単位。 –

関連する問題