Code Monkey home page Code Monkey logo

Comments (2)

jharrison avatar jharrison commented on August 12, 2024

I solved the problem myself. Hopeful this will be useful to someone else and perhaps even make it into the code:

// the arrowhead is a triangle that comes to a fine point. We don't 
// want the line of the arrow extending all the way to that point or
// it messes up the tip. The solution is to stop the line at the back 
// of the arrowhead. 
const backOfArrowHead = calcBackOfArrowHead(map, tail, tip, arrowHeadSize, arrowHeadAngle);
polyline = L.polyline([tail, backOfArrowHead], { color: 'blue' }).addTo(map);

// Add the arrowhead using Leaflet.PolylineDecorator
arrowHead = L.polylineDecorator([tail, tip], {
    patterns: [
        {
            offset: "100%",
            repeat: 0,
            symbol: L.Symbol.arrowHead({ pixelSize:arrowHeadSize, pathOptions: { fillOpacity: 1, weight: 0, color: 'blue' } })
        }
    ]
}).addTo(map);

The calcBackOfArrowHead() function looks like this:

calcBackOfArrowHead(map, tail, tip, arrowHeadSize, arrowHeadAngle) {
    // Project LatLng points to pixel coordinates
    var tailP = map.project(tail);
    var tipP = map.project(tip);

    // Calculate the vector from tail to tip in pixel coordinates
    var vector = tipP.subtract(tailP);

    // Normalize the vector to a unit vector (length 1)
    var unitVector = vector.divideBy(vector.distanceTo([0, 0]));

    // Calculate a new point some distance back from the tip
    // The distance is the length of the adjacent side of a right triangle.
    // This is the right half of the arrowhead, pointing up and scaled to the unit circle.
    // We need the ratio d to help us find the bottom left corner, which is where
    // the line of the arrow needs to stop drawing.
    //   |\
    //   |θ\
    //   |  \ 1
    // d |   \
    //   |    \
    //   |_____\
    //

    const halfArrowHeadAngleRadians = arrowHeadAngle / 2 * (Math.PI / 180); // θ        
    const arrowHeadRatio = arrowHeadSize * Math.cos(halfArrowHeadAngleRadians); // d
    var newTipP = tipP.subtract(unitVector.multiplyBy(arrowHeadRatio));

    // Unproject the new pixel point back to LatLng coordinates
    var newTipLatLng = map.unproject(newTipP);

    return newTipLatLng;
}

from leaflet.polylinedecorator.

jules43 avatar jules43 commented on August 12, 2024

Out of interest, another thing that can help with this problem is to change the linecap to butt, removing the rounded tip from the line.

from leaflet.polylinedecorator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.