0

I am having a hard time drawing a symbol (star) at a given location [lan, lon] on a topojson map.

How can I translate the coordinate pairs into the SVG pixel coordinate system?

I am using a basic map example from the Eurostat NUTS dataset, with a single location, ultimately I want to draw many different locations on the map:

d3.json("https://raw.githubusercontent.com/eurostat/Nuts2json/master/pub/v1/2016/3035/20M/3.json",
function(error, nuts) {
if (error) throw error;

//prepare SVG element
var width = 700, height = width*(nuts.bbox[3]-nuts.bbox[1])/(nuts.bbox[2]-nuts.bbox[0]),
svg = d3.select("svg").attr("width", width).attr("height", height)
        path = d3.geoPath().projection(d3.geoIdentity()
         .reflectY(true).fitSize([width,height], topojson.feature(nuts, nuts.objects.gra)));
    //draw boundaries
    //countries
    svg.append("g").selectAll("path").data(topojson.feature(nuts, nuts.objects.cntbn).features)
        .enter().append("path").attr("d", path)
        .attr("class",function(bn) { return "cntbn" + (bn.properties.co==="T"?" coastal":""); });
    //nuts
    svg.append("g").selectAll("path").data(topojson.feature(nuts, nuts.objects.nutsbn).features)
        .enter().append("path").attr("d", path)
        .attr("class",function(bn) {
            return "nutsbn" + (bn.properties.co==="T"?" coastal":"")
                + ((bn.properties.oth==="T" || bn.properties.lvl==0)?" white":"")
                + (bn.properties.lvl==3?" thin":"");
        });

  var coords = [48, 9]; // example of lat|lon 
  var sym = d3.symbol().type(d3.symbolStar).size(500);
  svg.append("g")
    .append("path")
    .attr("d",sym)
    .attr("transform", "translate(" + path(coords) + ")")
    .attr("class","location")

});
.graticule {
    fill: none;
    stroke-width: 2px;
    stroke: lightgray;
}

.cntrg {
    fill: lightgray;
}
.cntrg:hover { 
    fill: darkgray;
}

.nutsrg {
    fill: #fdbf6f;
}
.nutsrg:hover { 
    fill: #ff7f00;
}

.cntbn {
    fill: none;
    stroke-width: 1px;
    stroke: white;
}
.nutsbn {
    fill: none;
    stroke-width: 1px;
    stroke: #333;
}
.white { stroke: white; }
.thin { stroke-width: 0.5px; }
.coastal { stroke: #1f78b4; }
<!DOCTYPE html>
<svg></svg>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://d3js.org/d3-request.v1.min.js"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
isherwood
  • 58,414
  • 16
  • 114
  • 157
SdBBdS
  • 1

1 Answers1

0

The answer was almost there.

the projection is created by the topojson dataset with geoIdentity():

projection = d3.geoIdentity()
  .reflectY(true)
  .fitSize([width,height], topojson.feature(nuts, nuts.objects.gra))

Giving the coordinates in the right order:

var loc = [9.211367,48.8056];

Allows a translation of the symbol to the given location:

var sym = d3.symbol().type(d3.symbolStar).size(100);
mapSVG.append("g")
  .append("path")
  .attr("d",sym)
  .attr("transform", "translate(" + myProj(loc)[0] + "," + myProj(loc)[1]+ ")")

© EuroGeographics for the administrative boundaries

SdBBdS
  • 1