11

Well in my project I create river lines from pathes. And due to my kind of big stroke-width it is very ragged:

enter image description here

I already searched around. But the only thing I found was stroke-linejoin: round;. As you can see here:

enter image description here

it is way better but I'm still not satisfied.

Is there any way to get a really smooth line. Or let's say too have a even "rounder" linejoin?

kwoxer
  • 3,734
  • 4
  • 40
  • 70

3 Answers3

8

An interesting direction is to leverage d3.svg.line to generate paths from the coordinates of your geoJSON feature, at which point you would be able to use D3's interpolate methods.

See D3js-Topojson : how to move from pixelized to Bézier curves? and Geodata to d3.svg.line interpolation by E. Meeks, and Crispy edges with topojson? .


Edit: There is a minimal stand alone case study for line smoothing that you can fork via its associated gist's git repository. The idea of d3.svg.line together with interpolations of y coordinates for lines smoothing is from E.Meeks. E. Meeks explains his approach here.


Edit2 & solution: Í suddenly remembered where topojson is converted into geojson on the fly. Doing the following, you can work with topojson files and eventually get bezier curves, with the extrapolation of your choice. The following will work:

d3.json("./world-110m.json", function(data){
    console.log(data)
    var geojson = topojson.feature(data, data.objects.countries);
    var newJson = newgeoson(geojson);
    console.log(JSON.stringify(newJson))

    d3.select("body").append("svg").attr("id","world")
      .selectAll("path")
        .data(newJson)
      .enter()
        .append("path")
        .style("stroke-width", 1)
        .style("stroke", "black")
        .style("fill-opacity", .5)
        .attr("d", d3.svg.line()
          .x(function(d){ return d[0] })
          .y(function(d){ return d[1] }).interpolate("cardinal"))
        .style("fill", "#7fc97f");
})

Live demo : Minimal d3js line smoothing, topojson version

enter image description here

Community
  • 1
  • 1
Hugolpz
  • 17,296
  • 26
  • 100
  • 187
  • Yeah that looks good. Will bookmark and trying when I have some time for this. Thank you. – kwoxer Feb 25 '15 at 19:33
  • 2
    I myself eventually chose to rather use a more subtile topojson simplification via topojson command line tool. But this @Emeeks way attracted my eyes as well. – Hugolpz Feb 25 '15 at 19:56
  • 2
    But simplification means that I loose data. But I want it printed as deatailed as I drawed it =) So that's no solution for me. As I said coming back when working or having issues =) Thanks. – kwoxer Feb 25 '15 at 21:05
  • Mhh well I have no idea how to use the code from emeeks on http://jsfiddle.net/kwoxer/kpL1uyy2/6/ Already tried a bit around on that simple case. But none were succesful. Could you maybe help me =/ – kwoxer Feb 26 '15 at 15:40
  • Okay so that would be no way for me. Even my topojson file ist 500kB big. So there is no way for me right? Except the one from my question itself. – kwoxer Feb 26 '15 at 18:07
  • 2
    I'am merely a pointer here. You must read E.Meeks explanations and all the thanks should go to him. D3js also convert topojson into geojson on the fly. I don't know at which level, tho. Point is, it should be possible, but it will indeed require to ask some further questions on Stackoverflow, and to dig for a topojson data => line smoothing answer. I quickly (past hour) made a minimal stand alone version of E.Meek code, this new version will be simplier to hack. See my answer. – Hugolpz Feb 26 '15 at 18:24
  • Well I found this one here. Looks like Raphael would be easy to use: http://jsfiddle.net/ry8kT/ isn't it? – kwoxer Feb 26 '15 at 19:15
  • My fail that is just showing the SVG with Raphael. I will open a question on that. Because I still don't know how to create a geojson from my topojson in the browser. – kwoxer Feb 26 '15 at 19:23
  • 2
    @kwoxer: just added a topojson solution which may deserve a try. Cheer. – Hugolpz Feb 28 '15 at 12:02
  • Mhh but I have the path thing on the d value. I'm not sure how to replace with yours. But indded you stuff is looking great. So could you maybe show it on my jsfiddle? Would be awesome. – kwoxer Feb 28 '15 at 16:53
  • 2
    Check out my blocks code, fork, put some `console.log(JSON.stringify(d))` and inspect the data. General solution is done, your code is at reach. – Hugolpz Feb 28 '15 at 17:02
  • I'm just getting null values: http://jsfiddle.net/kwoxer/g83ee4xf/ is that correct? What am I do wrong? – kwoxer Feb 28 '15 at 18:10
  • I can's tell what, but your topojson data has something wrong. I reorganized your code and mixed it with what I previously provided to you. Your data fails http://jsfiddle.net/g83ee4xf/4/, my data works http://jsfiddle.net/g83ee4xf/5/ . – Hugolpz Feb 28 '15 at 19:03
  • I produce the topojson on my PC from many different geojson files. Maybe here is the reason? – kwoxer Feb 28 '15 at 19:08
  • Actually I think I have another issue Hugo. So first of all I would like to check that because it not only the smoothing that could help me. I need more details. http://gis.stackexchange.com/questions/137173/why-is-my-map-zoomed-in-so-ragged-compared-to-what-i-actually-drawed-in-qgis – kwoxer Mar 01 '15 at 07:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71975/discussion-between-kwoxer-and-hugolpz). – kwoxer Mar 01 '15 at 09:33
3

If you're not satisfied with stroke-linejoin:round you could look into creating the path outline ,

but maybe it would be easier if you try to smooth out your path with cubic beziers.

Community
  • 1
  • 1
maioman
  • 18,154
  • 4
  • 36
  • 42
  • Cubic beziers are not really an option, I need to take the path for some reasons. And the other example looks quite difficult uff but interesting =/ But no idea how to start and a css solution would be way better. – kwoxer Feb 20 '15 at 21:32
2

If you are unsatisfied with how it looks, then is seems to me that the problem is that your river is defined with too few points.

Any technique you use to smooth out the path, such as a curve fitting algorithm, will probably result in a representation of your river that is even less accurate than what you have now.

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Actually it is topojson and the original river has really many different point in the line of the river. So it could be the topojson that it is reducing the points somehow to get a smaller file. – kwoxer Feb 21 '15 at 07:25