dots and dashes

6 views
Skip to first unread message

Harri

unread,
Jul 8, 2011, 1:04:21 PM7/8/11
to Cartagen
Hi all,

I added support for dashed and dotted lines, now one can say to way-
elements that lineStyle is either solid, dot or dash. There is also a
half-baked support for pattern (i.e. it would repeat the same picture
as the "dots" with rotating the image according to the line direction)
but it does not work correctly. The dash and dots use a code example
found at http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas

Harri

5431c5431
< properties: ['fillStyle', 'pattern', 'strokeStyle', 'opacity',
'lineWidth', 'outlineColor',
---
> properties: ['fillStyle', 'pattern', 'strokeStyle', 'lineStyle', 'opacity', 'lineWidth', 'outlineColor',
5635a5636
> this.lineStyle = 'solid'
5852c5853,5862
< else $C.line_to(node.x,node.y)
---
> else {
>
> if (this.lineStyle == "dot") {
> $C.dashed_line_to(node.x,node.y, [1,8])
> } else if (this.lineStyle == "dash") {
> $C.dashed_line_to(node.x,node.y, [10,5])
> } else {
> $C.line_to(node.x,node.y)
> }
> }
5859a5870,5906
> var pattern = this.pattern
> var nodes = this.nodes
> if (this.lineStyle == "pattern") {
> this.nodes.each(function(node,index){
> var nextIndex = index + 1
> if (nodes.size() != index) {
> var x2 = nodes[nextIndex].x
> var y2 = nodes[nextIndex].y
> var dx = (x2-node.x), dy = (y2-node.y);
> var len = Math.sqrt(dx*dx + dy*dy);
> var rot = Math.atan2(dy, dx);
> var width = 5
> var height = 5
> x = node.x - width/2
> y = node.y - height/2
> /*var draw = true;
> var helper = 0
> var parts = len / width
> while (len > helper) {
> helper += width;
> if (helper + width > len) helper = len;
> if (draw) { */
> $C.save()
> $C.translate(x, y)
> $C.translate(width/2, height/2)
> $C.rotate(rot)
> $C.translate((width/2) * (-1), (height/2) * (-1))
> $C.draw_image(pattern, 0, 0, width, height)
> $C.restore()
> /* }
> x += width
> y += width
> //draw = !draw
> }*/
> }
> })
> }
6919a6967,6968
> prevX: 0,
> prevY: 0,
6922a6972,6994
> var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
> if (CP.lineTo) {
> CP.dashedLine = function(x, y, x2, y2, da) {
> if (!da) da = [10,5];
> this.save();
> var dx = (x2-x), dy = (y2-y);
> var len = Math.sqrt(dx*dx + dy*dy);
> var rot = Math.atan2(dy, dx);
> this.translate(x, y);
> this.moveTo(0, 0);
> this.rotate(rot);
> var dc = da.length;
> var di = 0, draw = true;
> x = 0;
> while (len > x) {
> x += da[di++ % dc];
> if (x > len) x = len;
> draw ? this.lineTo(x, 0): this.moveTo(x, 0);
> draw = !draw;
> }
> this.restore();
> }
> }
6936a7009,7011
> draw_image: function(image, x,y, w, h) {
> try { $C.canvas.drawImage(image, x, y, w, h) } catch(e) {$l(e)}
> },
6981a7057,7058
> this.prevX = x
> this.prevY = y
6985,6986c7062,7063
< line_to: function(x, y){
< $C.canvas.lineTo(x, y)
---
> line_to: function(x, y){
> $C.canvas.lineTo(x,y)
6987a7065,7071
>
> dashed_line_to: function(x, y, da) {
> //da = [1, 2]
> $C.canvas.dashedLine(this.prevX, this.prevY, x, y, da)
> this.prevX = x
> this.prevY = y
> },

Jeffrey Warren

unread,
Jul 8, 2011, 5:09:10 PM7/8/11
to cartag...@googlegroups.com
wow, do you have this in a git repo I could pull from?


--
You received this message because you are subscribed to the Google Groups "Cartagen" group.
To post to this group, send email to cartag...@googlegroups.com.
To unsubscribe from this group, send email to cartagen-dev...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cartagen-dev?hl=en.


Harri

unread,
Jul 9, 2011, 6:49:20 AM7/9/11
to Cartagen
No, not as of now, I'll look into that as well.

Btw. If the ways are drawn as dots or dashes the fill doesn't work
(understandably because it is no longer a closed polygon). One could
work around by drawing a solid line first with the background color,
fill that polygon and then overlay the dashed or dotted line. However,
there is no mechanism to force the draw order, they are not even drawn
in the read order.

Harri

Jeffrey Warren

unread,
Jul 9, 2011, 3:13:17 PM7/9/11
to cartag...@googlegroups.com
Cool - yeah - while not having explicit write order makes the rendering more efficient (it follows a "dump it all in a list and render it as fast as you can" rule), it is troublesome sometimes. Right now as I recall it sorts by feature bounding box, with the largest bounding boxes at the bottom. 

I wonder if we allowed "grouping" - kind of like pseudo-Relations (the OSM meaning of a relation being a collection of ways and nodes) which are sorted in a group, if we could avoid these things. They could even be ordered inside their Group. But yes, then we could simply fill a non-stroked poly before doing the dotted lines. A quick fix is to detect dotted lines and have the renderer draw those ways twice, once without stroke. 

I've been committing lots of changes to the Knitter -- the georectification system I wrote with Cartagen (cartagen.org/maps) -- and am strongly considering not only separating it into its own repo/source tree, but splitting the server-side Cartagen off into a "cartagen-server" repo. That way the main Cartagen project would be only the client-side scripts in a folder, and those looking for the odd but powerful additional functions of cartagen-server would go to that separate repo. Just FYI.

Jeff
Reply all
Reply to author
Forward
0 new messages