如何为 geoAlbersUsa() 投影绘制经度纬度坐标?

如何解决如何为 geoAlbersUsa() 投影绘制经度纬度坐标?

我正在尝试创建一个简单的气泡图,该图使用美国国土安全部数据按一个县的许多招生人数绘制经纬度对。我的 CSV 文件包含县名、经度、纬度、录取类型、录取类别、录取人数和原籍国。我创建了一些复选框,让用户可以看到被美国录取的不同招生类别的气泡图。

我了解到 d3geoAlbersUsa 投影将美国地图投影在 [0,0] 处,位于非洲海岸附近。从下面的照片(请参阅 Imgur 链接),您可以看到我的点似乎绘制在正确的坐标处。但是,背景地图不可见。当我使用 d3.geoMercator() 并将投影居中于 [0,0] 时,我会看到地图。在这两种情况下,我都不知道如何让气泡出现在地图上。

我是 d3 的新手,所以我不知道该怎么做。如何使用长纬度坐标和 d3geoAlbersUsa 投影创建气泡图?感谢您的帮助。

这是我的 index.html:

var width = 750
var height = 750

// The svg
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width",width)
  .attr("height",height)

// Map and projection
// Map and projection
// var projection = d3.geoMercator()
//     //.center([-100,30])                // GPS of location to zoom on
//     .center([0,0]) 
//     .scale(200)                       // This is like the zoom
//     .translate([ width/2,height/2 ])

var projection = d3.geoAlbersUsa()
  //.center([0,0])
  .scale([1000]) // This is like the zoom
  .translate([width / 2,height / 2])

var data = d3.csv("sheet.csv",function(data) {

  var markers = data.filter(function(d) {

    if (
      (d["MajorClassAdmission"] == "EmploymentPreference1st" ||
        d["MajorClassAdmission"] == "EmploymentPreference2nd" ||
        d["MajorClassAdmission"] == "EmploymentPreference3rd") &&
      d["CountryofBirth"] == "Bangladesh" && d["Admissions"] != "D" && d["lon"] != "NA" && d["lat"] != "NA") {
      return d;
    }
  })
  //console.log(markers)

  // Load external data and boot
  //d3.json("projectedgeography.json",function(data){
  d3.json("projectedgeography.geojson",function(data) {
    //d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson",function(data){

    // Filter data
    //data.features = data.features.filter( function(d){return d.properties.name=="USA"} )
    //data.features = data.features.filter( function(d){return d.properties.name=="USA"} )

    // Create a color scale
    var color = d3.scaleOrdinal()
      .domain(["EmploymentPreference1st","EmploymentPreference2nd","EmploymentPreference3rd"])
      .range(["#402D54","#D18975","#8FD175"])

    // Add a scale for bubble size
    var size = d3.scaleLinear()
      .domain([1,100]) // What's in the data
      .range([4,50]) // Size in pixel

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

    //Draw the map
    svg.append("g")
      .selectAll("path")
      .data(data.features)
      .enter()
      .append("path")
      .style("stroke","#black")
      .style("opacity",.3)


    //create a tooltip (hover information)
    var Tooltip = d3.select("#my_dataviz")
      .append("div")
      .attr("class","tooltip")
      .style("opacity",1)
      .style("background-color","white")
      .style("border","solid")
      .style("border-width","2px")
      .style("border-radius","5px")
      .style("padding","5px")

    // Three function that change the tooltip when user hover / move / leave a cell
    var mouseover = function(d) {
      Tooltip.style("opacity",1)
    }
    var mousemove = function(d) {
      Tooltip
        .html(d.CountyState + "<br>" + "long: " + d.lon + "<br>" + "lat: " + d.lat + "<br>" + "Admissions: " + d.Admissions)
        .style("left",(d3.mouse(this)[0] + 10) + "px")
        .style("top",(d3.mouse(this)[1]) + "px")
    }
    var mouseleave = function(d) {
      Tooltip.style("opacity",0)
    }

    // Add circles:
    svg
      .selectAll("myCircles")
      .data(markers)
      .enter()
      .append("circle")
      .attr("class",function(d) {
        return (d.MajorClassAdmission)
      })
      .attr("cx",function(d) {
        return projection([d.lon,d.lat])[0]
      })
      .attr("cy",d.lat])[1]
      })
      .attr("r",function(d) {
        return d.Admissions
      })
      .style("fill",function(d) {
        return color(d.MajorClassAdmission)
      })
      .attr("stroke",function(d) {
        return color(d.MajorClassAdmission)
      })
      .attr("stroke-width",3)
      .attr("fill-opacity",.4)
      .on("mouseover",mouseover)
      .on("mousemove",mousemove)
      .on("mouseleave",mouseleave)

    // This function is gonna change the opacity and size of selected and unselected circles
    function update() {

      // For each check box:
      d3.selectAll(".checkbox").each(function(d) {
        cb = d3.select(this);
        group = cb.property("value")
        //console.log(group)

        // If the box is check,I show the group
        if (cb.property("checked")) {
          //console.log("checked")
          svg.selectAll("." + group).transition().duration(1000).style("opacity",1).attr("r",function(d) {
            return d.Admissions
          })

          // Otherwise I hide it
        } else {
          //console.log("unchecked")
          svg.selectAll("." + group).transition().duration(1000).style("opacity",0).attr("r",0)
        }
      })
    }

    // When a button change,I run the update function
    d3.selectAll(".checkbox").on("change",update)

    // And I initialize it at the beginning
    update()
  })

})
<!DOCTYPE html>
<html>

<meta charset="utf-8">
<style>
  .circle:hover {
    stroke: black;
    stroke-width: 4px;
  }
  
  .legend circle {
    fill: none;
    stroke: #ccc;
  }
  
  .legend text {
    fill: #777;
    font: 10px sans-serif;
    text-anchor: middle;
  }
</style>

<!-- Load d3.js and the geo projection plugin -->
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<!-- <script src="http://d3js.org/d3.geo.projection.v0.min.js"></script> optional,depending on projection -->

<h1>LPR Top 200 Bangladesh</h1>

<!-- Button -->
<div>
  <input type="checkbox" class="checkbox" value="EmploymentPreference1st" checked><label>Employment Preference 1</label>
  <input type="checkbox" class="checkbox" value="EmploymentPreference2nd" checked><label>Employment Preference 2</label>
  <input type="checkbox" class="checkbox" value="EmploymentPreference3rd" checked><label>Employment Preference 3</label>
</div>

<!-- Create an element where the map will take place -->
<!-- <svg id="my_dataviz" width="500" height="500"></svg> -->
<div id="my_dataviz"></div>

附上我的数据截图以及我的气泡图如何使用 d3.geoMercator() 和 d3.geoAlbersUsa()

以下是屏幕截图:https://imgur.com/gallery/dRghqAf

编辑:看起来我使用了一个糟糕的 geojson。我最初从美国人口普查局下载了 shapefile 并使用 Mapshaper 转换为 geojson 文件。使用那个 geojson,我使用了一个投影应用程序来创建一个带有 geoalbersUsa 投影的 geojson。实际上,我在已经转换为该投影的 geojson 上使用了 d3.geoAlbersUsa()。我误解了 geoAlbersUsa() 的工作原理。使用 Mapshaper 的原始 geojson,我得到了我正在寻找的地图:https://imgur.com/gallery/9sj68SM

解决方法

D3 投影都非常相似。如果一个投影正确地投影了一个给定的点,那么其他每个投影都有可能。他们以十进制度数为单位获取坐标,并以像素为单位输出坐标,其他的不多。因此,您的陈述是:“d3geoAlbersUsa 投影将美国地图投影在非洲海岸附近的 [0,0]。”是不正确的。以度为单位的 [0,0] 在非洲海岸附近,以像素为单位的 [0,0] 可以是任何地方。 D3 为您提供像素,而不是度数。

如果您的要素/图块/栅格显示了美国所在的非洲,反之亦然,则说明您的投影或坐标系存在冲突,而不是 d3.geoAlbersUsa 的失败。

此外,如果您将预投影几何体和未投影几何体混合在一起,这将变得太困难:您需要确保用于预投影一个几何体的投影与用于投影的投影相匹配第二个,除非你使用 d3 在某处离线预投影几何体,否则会让你头疼。

如果您有一个带有十进制度数坐标的 csv 和一个具有相同坐标的 geojson,您可以假设投影(以及因此,任何路径)将一致且正确地呈现(其中正确不一定等同于所需...).

现在 d3.geoAlbersUsa 是一个特殊的投影,因为它是一个复合投影,结合了几个不同的投影(都是阿尔伯斯,同时也将阿拉斯加缩小了几次)。假设屏幕尺寸为 960x600 像素,它被校准为以美国为中心。您不需要更改中心点,它已经为您设置好了。但是,必须在您的情况下修改平移,因为这会平移投影坐标。默认翻译需要 960x600 像素的容器。您希望翻译等于 width/2,height/2,正如您所拥有的。更棘手的是比例,默认比例是 1070,将美国扩展到 960 像素。这个比例因子是线性的,所以我们可以使用:1070/960*width 创建一个新的比例因子(假设宽度是限制因子)。

d3.geoMercator 更简单,但我们需要正确地将投影居中,因为默认情况下它不是以美国为中心。我们可以使用:

d3.geoMercator()
  .center([-100,30]) // as you had
  .scale(1000) // or whatever
  .translate([width/2,height/2])

我们仍然需要应用翻译,因为默认值不期望正方形 750x750 svg。

请注意,还有 projection.fitSize() 会自动调整比例并转换为以 geojson 功能为中心,如下所示:

 d3.geoMercator()
   .fitSize([width,height],geojson) // geojson must be a valid geojson object,not an array of geojson features.

我们将投影传递给路径生成器,然后相对简单地绘制点和geojson:

以下使用注释掉的行访问 geojson,如果您共享 projectedgeography.geojson,我可以为您提供一些有关为什么您的代码无法按预期工作的信息。但考虑到它的名字,它看起来肯定不是未投影的数据

AlbersUsa

var width = 750
var height = 400
    
// The svg
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width",width)
  .attr("height",height);
  
// Create a color scale
var color = d3.scaleOrdinal()
  .domain(["A","B","C" ])
  .range([ "#402D54","#D18975","#8FD175"])  
  
var projection = d3.geoAlbersUsa()
  .translate([width/2,height/2])
  .scale(1070/960*width); // scale the scale factor,otherwise map will overflow SVG bounds.
  
var path = d3.geoPath(projection);

d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson",function(geojson){

    geojson.features = geojson.features.filter( function(d){return d.properties.name=="USA"} )


 // d3.csv("file.csv",function(csv) {
 // As I cannot access your csv,I'm reproducing a few lines here:
    var csv = [
      {lon: -116.2,lat: 43.5,Admissions: 24,MajorClassAdmission: "A"},{lon: -81.7,lat: 41.4,Admissions: 13,MajorClassAdmission: "B"},{lon: -74.1,lat: 40.9,Admissions: 35,MajorClassAdmission: "C"},{lon: -121.6,lat: 37.3,Admissions: 14,{lon: -73.9,lat: 40.68,]
 
 
    svg.selectAll("path")
      .data(geojson.features)
      .enter()
      .append("path")
      .attr("d",path);

    svg.selectAll("circle")
      .data(csv)
      .enter()
      .append("circle")
      .attr("cx",function(d) {
         return projection([d.lon,d.lat])[0];
      })
      .attr("cy",function(d) {
        return projection([d.lon,d.lat])[1];
      })
      .attr("r",function(d) {
        return d.Admissions
      })
      .attr("fill",function(d) {
        return color(d.MajorClassAdmission);
      })
      // ...

//  })
})
.circle:hover{
    stroke: black;
    stroke-width: 1px;
}
path {
  fill: none;
  stroke: #ccc;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<div id="my_dataviz"></div>

墨卡托

var width = 750
var height = 400
    
// The svg
var svg = d3.select("#my_dataviz")
  .append("svg")
  .attr("width","#8FD175"])  
  
var projection = d3.geoMercator()
  
var path = d3.geoPath(projection);

d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson",function(geojson){

    geojson.features = geojson.features.filter( function(d){return d.properties.name=="USA"} )

   projection.fitSize([width,geojson)

 // d3.csv("file.csv",function(d) {
        return color(d.MajorClassAdmission);
      })
      // ...

//  })
})
.circle:hover{
    stroke: black;
    stroke-width: 1px;
}
path {
  fill: none;
  stroke: #ccc;
  stroke-width: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<div id="my_dataviz"></div>

虽然您的代码中的注释混淆了您用来生成有问题的地图的代码,但您的代码中有一些潜在的简化:鉴于使用 d3.geo,您似乎同时使用了 d3v4 和 d3v3。 path (v3) 而不是 d3.geoPath (v4+)。基础 d3 包包含您需要的所有地理功能,因此您无需导入 https://d3js.org/d3-geo-projection.v2.min.js 或任何其他模块。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res