如何在 D3.js 中的地图上绘制 lat/long 对

How to plot lat/long pairs over map in D3.js

我在使用 D3.js 在地图上绘制来自 geoJSON 文件的点时遇到问题。地图渲染良好,但点未显示。我目前没有收到任何错误消息。

我跟随 this tutorial 但使用我自己的 geoJSON 文件来绘制数据。

这是我的:

    var width = 960,
        height = 500;

    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    var g = svg.append("g");

    var projection = d3.geoAlbers()
        .scale(1000)
        .translate([width / 2, height / 2]);

    var path = d3.geoPath()
        .projection(projection);

    d3.queue()
        .defer(d3.json, 'states.json') // Load US States
        .defer(d3.json, 'trump_geoJson.json') // Load tweet lat/long data 
        .await(makeMyMap); // Run 'ready' when JSONs are loaded

    function makeMyMap(error,states,tweets) {
        svg.append('path')
            .datum(topojson.feature(states, states.objects.usStates))
            .attr('d', path)
            .attr('class', 'states');
        svg.selectAll('.tweets')
            .data(tweets.features)
            .enter()
            .append('path')
            .attr('d',path)
            .attr('class', 'tweets');
    }

我预计要绘制大约 600 个点,但得到 none。

json 文件 trump_geoJson 看起来像:

{
"type": "FeatureCollection",
"features": [
    {
        "type": "Feature",
        "id": 0,
        "properties": {
            "primary_geo": "Utah, USA",
            "tag": "#Bernie",
            "text": "text",
            "user_id": "id"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                39.32373809814453,
                -111.67823791503906
            ]
        }
    },
    {
        "type": "Feature",
        "id": 1,
        "properties": {
            "primary_geo": "New York, NY",
            "tag": "#Bernie",
            "text": "text",
            "user_id": "id"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                40.71455001831055,
                -74.00714111328125
            ]
        }
    },... ]

您的 geojson 使用了错误的坐标约定。你有:

"coordinates": [ latitude, longitude ]

但是,您必须使用:

"coordinates": [ longitude, latitude ]

来自spec

Point coordinates are in x, y order (easting, northing for projected coordinates, longitude, and latitude for geographic coordinates)

有趣的是,规范考虑了投影坐标的东向和北向,因为规范还规定 geojson 必须使用 WGS84 基准[未投影(lat/long)坐标=17=]

这是您的 geojson 特征集合中前两项的演示:

var data = {
  "type": "FeatureCollection",
  "features": [
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [-111.6782379150,39.32373809814]
        }
    },
    {
        "type": "Feature",
        "geometry": {
            "type": "Point",
            "coordinates": [-74.00714111328,40.71455001831]
        }
    }]};
    

var width = 500,
height = 300;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);
var projection = d3.geoAlbers()
    .scale(600)
    .translate([width / 2, height / 2]);

var path = d3.geoPath()
   .projection(projection);

d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(error, world) {
  if (error) throw error;

  svg.append("path")
    .attr("d", path(topojson.mesh(world)))
    .attr("fill","none")
    .attr("stroke","black")
    .attr("stroke-width",1);
    
  svg.selectAll('.tweets')
   .data(data.features)
   .enter()
   .append('path')
   .attr('d',path)
   .attr('class', 'tweets');
    
   
});
  .tweets {
      fill: red;
        opacity: 0.7;
    }
<script src="http://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="https://d3js.org/d3-queue.v2.min.js"></script>