opensciencemap / vtm

a vector-tile map library written in java - running on android, desktop and within the browser
GNU Lesser General Public License v3.0
238 stars 176 forks source link

Draw Line #136

Open Bezzu opened 9 years ago

Bezzu commented 9 years ago

Hi, I would like to know if you have any suggestions for my problem. I use the class PathLayer to draw a red line above a blue line added with a VectorTileLayer and a specific VtmTheme over a standard map. Everything works fine until zoom 18 device-2014-12-05-093116

A more high zoom the red line disappared in some places device-2014-12-05-093100

Do you have any idea to resolve mu problem?

Thanks.

hjanetzek commented 9 years ago

I know that the clipping code of PathLayer is suboptimal and could lead to missing segments. But in this case I'm not sure - Is it an end-segment that is missing or do both red lines belong to the same PathLayer?

Bezzu commented 9 years ago

Red lines belong to the same PathLayer. By thew way, in the case I posted above the segment is not an end-segment

Bezzu commented 8 years ago

Hi, this issue appears only when there is a line with the first point outside the clipping view and the end point inside. In the code if a line is clipped the the visible segment is added to the bucket but the end point isn't added though it is inside. To solve this problem I have modified the clipping process in the "doWork" function of the Task class in the PathLayer file and I have added a method in the LineClipper class.

//LineClipperc class

public int getPrevOutcode() { return mPrevOutcode; }

//PathLayer - Task class - doWork function

int clip = mClipper.clipNext(x, y); if (clip < 1) { if (i > 2) ll.addLine(projected, i, false); if (clip < 0) { /* add line segment */ segment = mClipper.getLine(segment, 0); ll.addLine(segment, 4, false); //the prev point is the real point not the clipped point //prevX = mClipper.outX2; //prevY = mClipper.outY2; prevX=x; prevY=y; } i = 0; //if the end point is inside, add it if(mClipper.getPrevOutcode()==0){ projected[i++] = prevX; projected[i++] = prevY; } // continue; } float dx = x - prevX; float dy = y - prevY; if ((i == 0) || FastMath.absMaxCmp(dx, dy, MIN_DIST)) { projected[i++] = prevX = x; projected[i++] = prevY = y; }

The new method of the LineClipper class return the state of the end point of the line (if is inside or outside). If the end point of the line is inside (state == 0) I have added the point to the projection array.

devemux86 commented 7 years ago

In the fork by Mapsforge I merged @Bezzu 's fix.

See https://github.com/mapsforge/vtm/issues/108