2013-08-25 16 views
12

Gram w moduły geo D3. Mam pewne doświadczenie z D3, ale to pierwszy raz, kiedy wypróbowuję moduły geo. Brałem następujący kod (od https://github.com/alignedleft/d3-book/blob/master/chapter_12/04_fill.html), które pierwotnie wyświetla amerykańskiej mapy (https://github.com/alignedleft/d3-book/edit/master/chapter_12/us-states.json) edycji(pliki można teraz znaleźć w pobrania zip w https://github.com/alignedleft/d3-book/releases/tag/v1.0) w Albers projekcję i modyfikowane wziąć GeoJSON Indii (indiastates1. json poniżej). Kod działa dobrze z plikiem US, ale nie wyświetla niczego z indyjskim plikiem json. Czy czegoś tu brakuje. Każda pomoc jest doceniana. Zmieniłem jednak projekcję na merkator.Wyświetlanie mapy przy użyciu d3.js i geojson

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3: Setting path fills</title> 
     <script type="text/javascript" src="../d3/d3.v3.js"></script> 
     <style type="text/css"> 
      /* No style rules here yet */  
     </style> 
    </head> 
    <body> 
     <script type="text/javascript"> 

      //Width and height 
      var w = 500; 
      var h = 300; 

      //Define map projection 
      var projection = d3.geo.mercator() 
            .translate([w/2, h/2]) 
            .scale([500]); 

      //Define path generator 
      var path = d3.geo.path() 
          .projection(projection); 

      //Create SVG element 
      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      //Load in GeoJSON data 
      d3.json("indiastates1.json", function(json) { 

       //Bind data and create one path per GeoJSON feature 
       svg.selectAll("path") 
        .data(json.features) 
        .enter() 
        .append("path") 
        .attr("d", path) 
        .style("fill", "steelblue"); 

      }); 

     </script> 
    </body> 
</html> 

indiastates1.json

{"type":"FeatureCollection","features":[ 
{"type":"Feature","id":"IND","properties":{"name":"India"},"geometry":{"type":"Polygon","coordinates":[[[77.837451,35.49401],[78.912269,34.321936],[78.811086,33.506198],[79.208892,32.994395],[79.176129,32.48378],[78.458446,32.618164],[78.738894,31.515906],[79.721367,30.882715],[81.111256,30.183481],[80.476721,29.729865],[80.088425,28.79447],[81.057203,28.416095],[81.999987,27.925479],[83.304249,27.364506],[84.675018,27.234901],[85.251779,26.726198],[86.024393,26.630985],[87.227472,26.397898],[88.060238,26.414615],[88.174804,26.810405],[88.043133,27.445819],[88.120441,27.876542],[88.730326,28.086865],[88.814248,27.299316],[88.835643,27.098966],[89.744528,26.719403],[90.373275,26.875724],[91.217513,26.808648],[92.033484,26.83831],[92.103712,27.452614],[91.696657,27.771742],[92.503119,27.896876],[93.413348,28.640629],[94.56599,29.277438],[95.404802,29.031717],[96.117679,29.452802],[96.586591,28.83098],[96.248833,28.411031],[97.327114,28.261583],[97.402561,27.882536],[97.051989,27.699059],[97.133999,27.083774],[96.419366,27.264589],[95.124768,26.573572],[95.155153,26.001307],[94.603249,25.162495],[94.552658,24.675238],[94.106742,23.850741],[93.325188,24.078556],[93.286327,23.043658],[93.060294,22.703111],[93.166128,22.27846],[92.672721,22.041239],[92.146035,23.627499],[91.869928,23.624346],[91.706475,22.985264],[91.158963,23.503527],[91.46773,24.072639],[91.915093,24.130414],[92.376202,24.976693],[91.799596,25.147432],[90.872211,25.132601],[89.920693,25.26975],[89.832481,25.965082],[89.355094,26.014407],[88.563049,26.446526],[88.209789,25.768066],[88.931554,25.238692],[88.306373,24.866079],[88.084422,24.501657],[88.69994,24.233715],[88.52977,23.631142],[88.876312,22.879146],[89.031961,22.055708],[88.888766,21.690588],[88.208497,21.703172],[86.975704,21.495562],[87.033169,20.743308],[86.499351,20.151638],[85.060266,19.478579],[83.941006,18.30201],[83.189217,17.671221],[82.192792,17.016636],[82.191242,16.556664],[81.692719,16.310219],[80.791999,15.951972],[80.324896,15.899185],[80.025069,15.136415],[80.233274,13.835771],[80.286294,13.006261],[79.862547,12.056215],[79.857999,10.357275],[79.340512,10.308854],[78.885345,9.546136],[79.18972,9.216544],[78.277941,8.933047],[77.941165,8.252959],[77.539898,7.965535],[76.592979,8.899276],[76.130061,10.29963],[75.746467,11.308251],[75.396101,11.781245],[74.864816,12.741936],[74.616717,13.992583],[74.443859,14.617222],[73.534199,15.990652],[73.119909,17.92857],[72.820909,19.208234],[72.824475,20.419503],[72.630533,21.356009],[71.175273,20.757441],[70.470459,20.877331],[69.16413,22.089298],[69.644928,22.450775],[69.349597,22.84318],[68.176645,23.691965],[68.842599,24.359134],[71.04324,24.356524],[70.844699,25.215102],[70.282873,25.722229],[70.168927,26.491872],[69.514393,26.940966],[70.616496,27.989196],[71.777666,27.91318],[72.823752,28.961592],[73.450638,29.976413],[74.42138,30.979815],[74.405929,31.692639],[75.258642,32.271105],[74.451559,32.7649],[74.104294,33.441473],[73.749948,34.317699],[74.240203,34.748887],[75.757061,34.504923],[76.871722,34.653544],[77.837451,35.49401]]]}} 
]} 

Odpowiedz

10

Jesteś (lub przeglądarki) po prostu patrząc w niewłaściwym miejscu. Myślę, że d3 automatycznie centruje na terenie USA z tymi prognozami geo. Wszystko, co musisz zrobić, to użyć transformacji, aby przenieść "Indie" do ekranu podglądu svg. W szczególności musisz przetłumaczyć początek widoku na położenie określone współrzędnymi w pikselach x, y - lub przynajmniej tak myślę. Aby zobaczyć Indie, wypróbowałem:

.attr("transform", "translate(-800,200)") 

i wydawało się, że wykonuje to zadanie.

Łatwo wybrać te rzeczy, jeśli przejrzysz element, możesz wtedy użyć ścieżki, by dać ci wskazówki, gdzie się transformować.

UPDATE

Znacznie lepsze podejście do tego problemu byłoby obliczyć środek i skalę taką jak przedstawiona w niniejszym question and answer. W szczególności odpowiedź Jana i Mike'a jest znakomita. Istnieje również objaśnienie kodu w tym google groups discussion - drugi ostatni post.

+0

dzięki. Rozumiem. Podejrzewałem również na podobnych liniach, tak jak na chrome, ponieważ konsola nie rzuciła żadnych błędów, a kiedy kliknąłem na svg na elementach, wydaje się, że podświetla go gdzieś w przeglądarce, ale nie wiedział gdzie! Tak więc chodziło o znalezienie właściwej transformacji, aby ją przenieść. Czy chodziło o próbę i błąd w znalezieniu właściwych liczb dla transformacji? –

+1

Ścieżka (tj. Bit po d = to idzie M150.158 128.215, 486.1589Z) mówi, gdzie jest wyświetlana. Liczby podane w tym przykładzie wskazują, że ścieżka zaczyna się od 150, w twoim przykładzie myślę, że pierwsza liczba wynosiła około 900, więc przesunąłem tylko rzutnię -800 i nieco w dół, gdy inspektor pokazał ją tylko na górze ekranu. Aby uzyskać pełniejszą odpowiedź, wypróbuj [this] (http://stackoverflow.com/questions/14492284/center-a-map-in-d3-given-a-geojson-object) – user1614080

0

Ten problem występuje, ponieważ mapa USA jest ustawiona tak, aby centrum USA. Prawdopodobnie załadowałeś plik indyjski, ale może on być poza ekranem lub bardzo mały, aby go zobaczyć. Możesz ręcznie wykonać korektę, zmieniając wartości skali i środka i tłumacz. ale lepszym rozwiązaniem jest automatycznie znalezieniu skalę i tłumaczenie z kodu

var b = path.bounds(#data#), 
       s = .95/Math.max((b[1][0] - b[0][0])/width, (b[1][1] - b[0][1])/height), 
       //scaled the bounding box 
       t = [(width - s * (b[1][0] + b[0][0]))/2, (height - s * (b[1][1] + b[0][1]))/2]; 
// new projection 
       projection = d3.geo.mercator() 
          .scale(s).translate(t); 
       path = path.projection(projection); 
2

To jest prosty przykład pokazujący jak wyśrodkować odwzorowania wokół wszystkich funkcje w swoim zbiorze obiektów (a nie tylko jeden lub domyślna), jest oparta na linked Mike Bostock answer, co jest wspaniałe, ale oparte na powiększeniu tylko jednej funkcji, a także d3.js geoJSON and bounds, która pokazuje, że można wykorzystać całe kolekcje elementów.

Kluczowe zmiany w kodzie są:

  • Wymiana początkowa tłumaczyć i skala z neutralnym jednym:

    var projection = d3.geo.mercator() 
         .scale(1) 
         .translate([0, 0]); 
    
  • Po załadowaniu json, dodając kod dynamicznie aktualizować projekcję na podstawie ramki ograniczającej cała kolekcja elementów:

    var b = path.bounds(json), 
        s = .95/Math.max((b[1][0] - b[0][0])/w, (b[1][1] - b[0][1])/h), 
        t = [(w - s * (b[1][0] + b[0][0]))/2, (h - s * (b[1][1] + b[0][1]))/2]; 
    
        projection 
         .scale(s) 
         .translate(t); 
    

Więc zaktualizowany kompletny Przykładem może wyglądać następująco:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3: Setting path fills</title> 
     <script type="text/javascript" src="../d3/d3.v3.js"></script> 
     <style type="text/css"> 
      /* No style rules here yet */  
     </style> 
    </head> 
    <body> 
     <script type="text/javascript"> 

      //Width and height 
      var w = 500; 
      var h = 300; 

      //Define map projection 
      var projection = d3.geo.mercator() 
            .translate([0, 0]) 
            .scale(1); 

      //Define path generator 
      var path = d3.geo.path() 
          .projection(projection); 

      //Create SVG element 
      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      //Load in GeoJSON data 
      d3.json("indiastates1.json", function(json) { 

       // Calculate bounding box transforms for entire collection 
       var b = path.bounds(json), 
       s = .95/Math.max((b[1][0] - b[0][0])/w, (b[1][1] - b[0][1])/h), 
       t = [(w - s * (b[1][0] + b[0][0]))/2, (h - s * (b[1][1] + b[0][1]))/2]; 

       // Update the projection  
       projection 
        .scale(s) 
        .translate(t); 


       //Bind data and create one path per GeoJSON feature 
       svg.selectAll("path") 
        .data(json.features) 
        .enter() 
        .append("path") 
        .attr("d", path) 
        .style("fill", "steelblue"); 

      }); 

     </script> 
    </body> 
</html> 
Powiązane problemy