Home > OS >  d3 choropleth - issue plotting from osm / overpass api xml file
d3 choropleth - issue plotting from osm / overpass api xml file

Time:11-08

I'm trying to plot circles using d3 from an xml file (xml osm generated by the overpass api). I'm getting an error TypeError: null is not an object (evaluating 'node.getAttribute'). I've been able to plot geometry with geojson & csv data, but am simply struggling with the xml. What am I missing?

Of course I am aiming to have the 4 nodes in the xml file displayed.

HTML:

<!DOCTYPE html>
<html>
<meta charset="utf-8">

<head>
    <script type="text/javascript" src="https://d3js.org/d3.v4.js"></script>
</head>

<body>
    <script>
        var svg = d3.select("svg"),
            width =  svg.attr("width"),
            height =  svg.attr("height");

        var projection = d3.geoMercator()
            .scale(21000000) 
            .center([-122.29576905, 37.890256])
            .translate([width / 3, height / 4])

        d3.xml("entrance-exit.xml", function ready(error, xml) {
            svg
                .selectAll("myCircles")
                .data(xml.documentElement.getElementsByTagName("node"))
                .enter()
                .append("myCircles")
                .attr("cx", function(d) { return d.getAttribute("lon"); })
                .attr("cy", function(d) { return d.getAttribute("lat"); })
                .attr("r", 8)
                .style("fill", "blue")
                .attr("stroke", "black")
                .attr("stroke-width", 1)
                .attr("fill-opacity", 1);
            })
    </script>
</body>
</html>

XML:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API 0.7.59 e21c39fe">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2022-11-01T11:22:37Z"/>

  <bounds minlat="37.8885000" minlon="-122.2966000" maxlat="37.8906000" maxlon="-122.2945000"/>

  <node id="10054221950" lat="37.8899635" lon="-122.2960219">
    <tag k="entrance" v="yes"/>
  </node>
  <node id="10054221951" lat="37.8894885" lon="-122.2951210">
    <tag k="entrance" v="yes"/>
    <tag k="wheelchair" v="yes"/>
  </node>
  <node id="10091017732" lat="37.8894072" lon="-122.2952833">
    <tag k="entrance" v="yes"/>
    <tag k="ref" v="25"/>
  </node>
  <node id="10091017733" lat="37.8894276" lon="-122.2951869">
    <tag k="entrance" v="yes"/>
    <tag k="ref" v="26"/>
  </node>

</osm>

CodePudding user response:

I didn't get your error when trying to reproduce your case using your code but I found several mistakes that should be fixed in order to display the points.

First I replaced the myCircles tag by a simple SVG circle element and then I set the cx and cy attributes by using the result of the projection (which you haven't used apparently):

svg
  .selectAll("circle")
  .data(xml.documentElement.getElementsByTagName("node"))
  .enter()
  .append("circle")
  .each(function (d) {
    const projected = projection([
      d.getAttribute("lon"),
      d.getAttribute("lat"),
    ]);
    d3.select(this).attr("cx", projected[0]).attr("cy", projected[1]);
  })
  ...

Then depending on your SVG element size, the points may be out of bound so adjust the scale accordingly to see them.

  • Related