Jan Seipel
Jan Seipel

Reputation: 119

d3.js: mix projected and unprojected geodata

I made a map out of a custom geojson-file made with qgis. It has projected geodata instead of lat-long-values but didn't fit into the svg container automatically. So I moved it to the right place with the transform attribute. Here's my code so far:

var height = 800,
    width = 800;

var svg = d3.select("#map-container")
    .append("svg")
    .attr("width",width)
    .attr("height",height);

d3.queue()
    .defer(d3.json,"./data/Shapefiles_simplyfied_20.json")
    .await(drawMap);

function drawMap(error,bw) {

    if (error) throw error;

    var features = bw.features;

    var map = svg.append("g")
        .attr("class", "kommunen")
        .attr("id","karte-rdb");

    map
        .selectAll("path")
        .data(features)
        .enter().append("path")
        .attr("d", d3.geoPath(null))
        .attr("transform","scale(1,-1)")

    //make the map fit to svg container
    var bbox = d3.select("#karte-rdb")._groups[0][0].getBBox();
    var scaleFactor = d3.min([width / bbox.width, height / bbox.height]);
    var translation = [width - bbox.x,height - bbox.y];

    map
        .attr("transform","scale("+scaleFactor+","+scaleFactor+") translate("+ translation[0] +","+ translation[1] +")")

}

The (truncated) geojson looks like this:

{
"type": "FeatureCollection",
"name": "Shapefiles",
"crs": {
    "type": "name",
    "properties": {
        "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
    }
},
"features": [{
    "type": "Feature",
    "properties": {
        "GEN": "Area1",
        "BEZ": "RDB-RP"
    },
    "geometry": {
        "type": "MultiPolygon",
        "coordinates": [[[[393361.666451968252659,
        5504072.610383642837405],
        [393366.833893342292868,
        5503968.659385782666504],
        ...

enter image description here

Now I would like to display some points that are in a csv file with lat-lon-pairs.

Name    lat lon
A   7.601581    49.203633
B   8.008745    50.374521
C   8.11676     49.746425
D   6.657145    50.221658
E   6.942947    49.654687
F   9.62743     51.196755

How can I display them together with the projected geodata without a d3.geoProject-function?

Upvotes: 2

Views: 226

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38171

Short answer, not easily, there are alternatives.

The projected data you are using is projected onto a grid of meters or yards or whatever. To project latitude longitude points onto that grid, you need to translate your latitude longitude points to that grid using a projection (you also need depending on map scale, the same datum, but let's assume all your geographic data uses the same datum). The formula to project your points will be dependent on the projection you are using for your already projected layer. This is more complex than the alternatives:

  1. As most projections in QGIS can be converted fairly easily, you could convert your latitude longitude coordinates (if placed in geojson or other geographical format) into projected points that share the same projection as your data.

  2. The other option would be to "unproject" your already projected data so that it comprises lat long pairs (generally you would use the datum WGS84 if using d3), and then project all your data with d3. You indicated that you didn't want to use a d3.projection, however, so this might not be ideal.

Either of these options would play well with d3. Conversely, combining a geoProjection with a geoTransform or a null projection, will lead to a lot of headache when rescaling, zooming, etc. Also, you can use a .geoTransform with your projected data, which may offer some advantages as compared with scaling and translating the svg directly.

Upvotes: 1

Related Questions