Map navigation (drag) with mapbox static tiles, d3js and topojson

41 views Asked by At

I would like to create a simple map using Canvas. I have a TopoJson file with the geo object that needs to be displayed. I use D3js to work with the geo-coordinates. Behind the object, I would like to put the Mapbox tiles. And I have actually done this. However, I also need to be able to move the map with a mouse to be able to see other objects around. The problem is that the Mapbox tiles do not load dynamically. I know that I need to handle the 'zoom' event but I can't figure out what exactly should I do...

const width = 960;
const height = 500;

d3.json('test.json').then((topojsonData) => {
    var feature = topojson.feature(topojsonData, topojsonData.objects.foo);
    var projection = d3.geoMercator().fitSize([width, height], feature);
    var path = d3.geoPath(projection);
    var svgCanvas = d3.create("svg").attr("viewBox", [0, 0, width, height]);
    var group = svgCanvas.append("g");
    var tile = d3.tile().size([width, height]).scale(projection.scale() * 2 * Math.PI).translate(projection([0, 0])).tileSize(512);
    var url = (x, y, z) => `https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/${z}/${x}/${y}${devicePixelRatio > 1 ? "@2x" : ""}?access_token=MAPBOX_KEY`;
    tile().map(([x, y, z], i, {translate: [tx, ty], scale: k}) =>
    {
        group.append("image")
            .attr("href", url(x, y, z))
            .attr("x", Math.round((x + tx) * k))
            .attr("y", Math.round((y + ty) * k))
            .attr("width", k)
            .attr("height", k);
    });
    group.append("path")
        .attr("fill", "red")
        .attr("stroke", "red")
        .attr("fill-opacity", 0.03)
        .attr("stroke-opacity", 0.5)
        .attr("d", path(feature));
    

    function zoomed(event) {
        const {transform} = event;
        group.attr("transform", transform);
        group.attr("stroke-width", 1 / transform.k);
    }

    const zoom = d3.zoom().scaleExtent([1, 1]).on("zoom", zoomed);
    svgCanvas.call(zoom);

    document.getElementById('map').appendChild(svgCanvas.node());
});

The interactive version is available here: https://observablehq.com/d/22ac89fa043e05c3 Are there any specialists around who can help me please?

0

There are 0 answers