【问题标题】:How should I be using my Projection to draw points in the map?我应该如何使用我的投影在地图上绘制点?
【发布时间】:2022-12-17 11:47:45
【问题描述】:

我试图根据经度和纬度在地图上画一些圆圈,但是,我认为我的投影有问题,因为它没有画出我的任何东西。

我得到以下,

我有一个全局变量

变种投影= d3.geoMercator()

然后,我定义投影:

  projection.scale(1).translate([0, 0]);
      var b = path.bounds(data);
      var s = .95 / Math.max((b[1][0] - b[0][0]) / mwidth, (b[1][1] -
              b[0][1]) / mheight);
      var t = [(mwidth - s * (b[1][0] + b[0][0])) / 2, (mheight - s *
              (b[1][1] + b[0][1])) / 2+50];
      projection.scale(s).translate(t); 

这就是我试图实现我的圈子的方式,

 // Hospital points
     svg.selectAll('.hospital-circle')
        .data(hospitals)
        .enter()
        .append('circle')
        .attr('class', 'boundary')
        .attr('r', 5)
        .attr('cx', function(d) {
              var hospitalCoords = projection.scale(s).translate(t)([d.lon, d.lat])
              console.log(d)
              console.log(hospitalCoords);
              return hospitalCoords[0]
        })
        .attr('cy', function(d) {
              var hospitalCoords = projection.scale(s).translate(t)([d.lon, d.lat])
              console.log(d)
              console.log(hospitalCoords)
              return hospitalCoords[1]
        })

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    很难确定哪里出了问题,因为我们看不到您的数据,也不知道它与您的预测是否吻合。在我看来,您正确地呼叫了projection,但它可能与您所在的地区不相符。您可能应该使用projection.fitSize,而不是尝试手动执行此操作。我附上了一个完整的工作代码 sn-p 来说明

    let w = 500;
    let h = 300;
    let div = d3.select('#container');
    let svg = div.append('svg')
      .attr('width', w)
      .attr('height', h);
    let map = svg.append('g');
    
    let largest_cities = d3.csvParse(`name,population,lat,lon
    New York City,8550405,40.6642738,-73.9385004
    Los Angeles,3971883,34.0193936,-118.4108248
    Chicago,2720546,41.8375511,-87.6818441
    Houston,2296224,29.7804724,-95.3863425
    Phoenix,1563025,33.5721625,-112.0879662
    Philadelphia,1567442,40.0093755,-75.1333459
    San Antonio,1469845,29.4724026,-98.5251419
    San Diego,1394928,32.8152995,-117.134993
    Dallas,1300092,32.794176,-96.7655033
    San Jose,1026908,37.2968672,-121.8193058
    Austin,931830,30.3071816,-97.7559964
    Jacksonville,868031,30.3370193,-81.6613021
    San Francisco,864816,37.759881,-122.437392
    Columbus,850106,39.9847989,-82.9850438
    Fort Worth,833319,32.7795423,-97.3463354
    Indianapolis,858325,39.7779954,-86.1458378
    Charlotte,827097,35.2087069,-80.8307389
    Seattle,684451,47.6204993,-122.3508761
    Denver,682545,39.7618487,-104.8806251
    Washington,672228,38.9041485,-77.0170942
    `, d3.autoType);
    let max_pop = d3.max(largest_cities.map((c) => c.population));
      
    
    fetch('https://raw.githubusercontent.com/scdoshi/us-geojson/master/geojson/nation/US.geojson').then(async function(response) {
      let us = await response.json();
      let projection = d3.geoAlbersUsa().fitSize([w, h], us);
      let path = d3.geoPath().projection(projection);
      map
        .append('path')
        .attr("d", path(us))
        .attr("fill", "lightgray")
        .attr("stroke", "#fff")
        .attr("stroke-width", 1);
      largest_cities.forEach(function (c) {
        let xy = projection([c.lon, c.lat]);
        c.x = xy[0];
        c.y = xy[1];
      });
      map
        .selectAll("circle")
        .data(largest_cities)
        .join("circle")
        .attr("cx", (c) => c.x)
        .attr("cy", (c) => c.y)
        .attr("r", (c) => 5 * (c.population / max_pop) ** 0.3)
        .attr("fill", "black")
        .attr("fill-opacity", 0.5)
        .attr("stroke", "black")
    })
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <div id="container"></div>

    【讨论】:

      最近更新 更多