Reputation:
I'm struggling to plot a line from latitude & longitude in D3, specifically when projecting the y values.
I draw the line using the following code & sample json array.
var json_str = [
{
"lng1": 53.587,
"lat1": -2.159,
"lng2": 53.587,
"lat2": -2.159,
},
{
"lng1": 53.587,
"lat1": -2.159,
"lng2": 53.587,
"lat2": -2.157,
}
];
d3.select("#lines").selectAll("line")
.data(json_str)
.enter()
.append("line")
.attr("x1", function (d) { return projection([d.lat1])[0]; })
.attr("y1", function (d) { return projection([d.lng1])[0]; })
.attr("x2", function (d) { return projection([d.lat2])[0]; })
.attr("y2", function (d) { return projection([d.lng2])[0]; })
.style("stroke", "black")
.style("stroke-width", 5);
When I project the x values, it comes out with the correct value & projects on my map correctly, however when I project Y, using the same functions but on a different field, it gives me crazy values and therefore isn't plotting within the bounds of my SVG. Somewhere in the region of 1299***.
I've used the same function to project x & y values for point data no problem.
d3.select("#points").selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function (d) { return projection([d.y, d.x])[0] })
.attr("cy", function (d) { return projection([d.y, d.x])[1] })
EDIT: Marks answer below gets me close, but the projection is still out of shape.
I've created a Plunker showing my problem, which incorporates Marks answer below. Essentially the 'lines' SVG plots 90 degrees out & I can;t fathom why..
Upvotes: 1
Views: 360
Reputation: 108512
The documentation states that (bolding mine):
projection(point)
Returns a new array [x, y] (typically in pixels) representing the projected point of the given point. The point must be specified as a two-element array [longitude, latitude] in degrees. May return null if the specified point has no defined projected position, such as when the point is outside the clipping bounds of the projection.
You are passing a singular lat/long values in return projection([d.lat1])[0];
. This won't work.
I'd refactor it as:
var json_str = [
{
"lng1": 53.587,
"lat1": -2.159,
"lng2": 53.587,
"lat2": -2.159,
},
{
"lng1": 53.587,
"lat1": -2.159,
"lng2": 53.587,
"lat2": -2.157,
}
];
d3.select("#lines").selectAll("line")
.data(json_str)
.enter()
.append("line")
.each(function(d){
d.p1 = projection([d.lng1, d.lat1]);
d.p2 = projection([d.lng2, d.lat2]);
})
.attr("x1", function (d) { return d.p1[0]; })
.attr("y1", function (d) { return d.p1[1]; })
.attr("x2", function (d) { return d.p2[0]; })
.attr("y2", function (d) { return d.p2[1]; })
.style("stroke", "black")
.style("stroke-width", 5);
Upvotes: 1