Published
Edited
Feb 10, 2021
Insert cell
md`# https://github.com/d3/d3-geo/issues/227`
Insert cell
draw(A)
Insert cell
draw(correction(A))
Insert cell
draw(B)
Insert cell
draw(correction(B))
Insert cell
// Draw the ploygon with the coordinates of C
function draw(C) {
let projection = d3
.geoMercator()
.fitExtent([[100, 40], [width - 150, height - 100]], {
type: "MultiPoint",
coordinates: C
})
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
const path = d3.geoPath(projection);

svg
.append("path")
.datum({ type: "Polygon", coordinates: [C] })
.attr("d", path)
.attr("fill", "lightblue");

svg
.append("g")
.selectAll()
.data(C.map(c => ({ type: "Point", coordinates: c })))
.join("path")
.attr("d", path);

svg
.append("g")
.selectAll()
.data(C)
.join("text")
.text((d, i) => `${i}: ${d.map(e => e.toFixed(2))}`)
.attr("transform", d => `translate(${projection(d)})`)
.attr("dy", (_, i) => (i >= 2 ? -10 : 20));

return svg.node();
}
Insert cell
d3 = require("d3@6")
Insert cell
A = [
[112.716747, 32.357612],
[112.735841, 32.356095],
[112.733993, 32.356601],
[112.724138, 32.358623],
[112.716747, 32.357612]
]
Insert cell
B = [
[112.902145, 29.79149],
[112.929246, 29.77383],
[112.923703, 29.766557],
[112.894138, 29.783699],
[112.902145, 29.79149],
]
Insert cell
// Compute the substraction of 2D vector a, b
function sub(a, b) {
return [a[0] - b[0], a[1] - b[1]];
}
Insert cell
// Compute the center point of 2D vector a, b
function mean(a, b) {
return [(a[0] + b[0])/2, (a[1] + b[1])/2];
}
Insert cell
// Compute the cross multiple of 2D vector a, b
function cross(a, b) {
return a[0]*b[1] - a[1]*b[0];
}
Insert cell
// Compute the order of vectors in x
//
// args:
// - @a: A list of 2D vectors, the coordinates of vertex of polygon
//
// outputs:
// Positive value for anticlock-wise order
// Negative value for clock-wise order
function order(x) {
var m = mean(x[0], x[2])
return cross(sub(x[1], x[0]), sub(m, x[0]));
}
Insert cell
// Return the correction of x
// Return its reversion, if it is anticlock-wise ordered
// Return its origin, if otherwise
function correction(x) {
if (order(x) > 0) {
return d3.reverse(x)
}
else {
return x
}
}
Insert cell
// The cross of A is positive,
// it refers the coordinates are in anticlock-wise order
// we can use its reverse to avoid rendering the global and a hole in the plot
order(A)
Insert cell
// The cross of A is positive,
// it refers the coordinates are in anticlock-wise order
// we can sasfely use it
order(B)
Insert cell
d3.geoArea({ type: "Polygon", coordinates: [A] })
Insert cell
d3.geoArea({ type: "Polygon", coordinates: [B] })
Insert cell
height = 500
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more