Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inefficient #10

Open
remster opened this issue Feb 14, 2017 · 0 comments
Open

inefficient #10

remster opened this issue Feb 14, 2017 · 0 comments

Comments

@remster
Copy link

remster commented Feb 14, 2017

Turf says: "Fast
Takes advantage of the newest algorithms and doesn't require you to send data to a server"
whereas little has been done to make this code efficient.

  • distances are calculated in spherical coordinates, whereas for comparison - squared distances would suffice
  • same distances are recalculated
  • i have improved this at least two-fold by simply projecting the point in question onto consecutive line segments like so:

`
function dot(v1,v2) {
return (v1.xv2.x)+(v1.yv2.y);
}

function project(line, point, force) {
    var vline =             {
        x : line[1].x-line[0].x,
        y : line[1].y-line[0].y
    };
    var vlineLengthSqrd = Math.pow(vline.x, 2)+Math.pow(vline.y,2);
    if (vlineLengthSqrd == 0) {
        //0-lenght segment => point
        return force ? line[0] : undefined;
    }
    var projectionRatio = dot(
        vline,
        {
            x : point.x - line[0].x,
            y : point.y - line[0].y
        }
    )/vlineLengthSqrd;

    if (projectionRatio < 0) {
        //beyond the mStart end of the segment
        return force ? line[0] : undefined;
    } else if (projectionRatio > 1) {
        //beyond the mEnd end of the segment
        return force ? line[1] : undefined;
    }
    return {
        x: line[0].x + (projectionRatio * vline.x),
        y: line[0].y + (projectionRatio * vline.y)
    };
}

function comparableDistance(a,b) {
    return Math.pow(a.x-b.x, 2) + Math.pow(a.y-b.y, 2);
}

class GeoLineString {
    constructor(points) {
        this.mPoints = points;
    }

    projectOnto(point) {
        var best =  undefined;
        for (var i = 1; i < this.mPoints.length; i++) {
            var projection = project(
                [ this.mPoints[i-1], this.mPoints[i]],
                point,
                true
            );
            var distance = comparableDistance(projection, point);
            if (!best || best.comparableDistance > distance) {
                best = {
                    projection : projection,
                    comparableDistance : distance,
                    index : {
                        start : i-1,
                        stop  : i
                    }
                }
            }
        }
        if (best) {
            best.projection = new LatLng(projection.y, projection.x);
            best = {
                projection  : best.projection,
                distanceMts : best.projection.distanceTo(point),
                index       : best.index
            }
        }

        return best;
    }
}`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant