Menu

#1 LineString::Touches is broken

0.9.8.0
closed
Markers (1)
5
2014-11-16
2011-01-06
Jon Schewe
No

LineString::Touches uses Point::Touches, which always returns false in this case because the point from the event has no pixmap and Point::Touches returns false if the pixmap is not specified.

Discussion

  • Jon Schewe

    Jon Schewe - 2011-01-06

    Furthermore, even if Point::Touches didn't always return false when there is no pixmap, the check is still wrong as you need to compute the bounding box of each segment of the line and then check if the point is within the bounding box.

     
  • Brad Grimmett

    Brad Grimmett - 2013-03-13
    • assigned_to: nobody --> plagued85
    • labels: --> Markers
    • status: open --> open-accepted
     
  • Brad Grimmett

    Brad Grimmett - 2013-03-13

    Thanks for submitting the bug. Sorry for the late response, i've just joined the project.

    I'll update this once i get a chance to confirm the bug

     
  • Brad Grimmett

    Brad Grimmett - 2013-10-06

    Just a note: This behaviour may have changed for you since i've removed the need to use QPixmap* in revision 41

    I'll keep this open until i've had a chance to verify/fix

     
  • Jon Schewe (BBN)

    The pixmap problem is fixed, however you're still just checking the points of the line rather than the bounding box created by the image. Here's an implementation that I've used in a subclass I created.

    bool BetterLineString::Touches(qmapcontrol::Point click,
    const qmapcontrol::MapAdapter
    mapadapter)
    {
    if (points().size() < 2)
    {
    // really shouldn't end up here since we always add 2 points
    return false;
    }

    // NOTE could check for overall bounding box
    
    QPointF clickPt = mapadapter->coordinateToDisplay(click->coordinate());
    
    qreal halfwidth = 2; // use 2 pixels by default
    if (mypen->width() > 0)
    {
        halfwidth = static_cast<qreal> (mypen->width())
                / static_cast<qreal> (2);
    }
    
    QPointF pt1 = mapadapter->coordinateToDisplay(points().at(0)->coordinate());
    qreal pt1x1 = pt1.x() - halfwidth;
    qreal pt1x2 = pt1.x() + halfwidth;
    qreal pt1y1 = pt1.y() - halfwidth;
    qreal pt1y2 = pt1.y() + halfwidth;
    for (int i = 1; i < points().size(); i++)
    {
        QPointF pt2 = mapadapter->coordinateToDisplay(
                points().at(i)->coordinate());
        qreal pt2x1 = pt2.x() - halfwidth;
        qreal pt2x2 = pt2.x() + halfwidth;
        qreal pt2y1 = pt2.y() - halfwidth;
        qreal pt2y2 = pt2.y() + halfwidth;
    
        // build lazy bounding box
        qreal upperLeftX = min(pt1x1, min(pt1x2, min(pt2x1, pt2x2)));
        qreal upperLeftY = min(pt1y1, min(pt1y2, min(pt2y1, pt2y2)));
        qreal lowerRightX = max(pt1x1, max(pt1x2, max(pt2x1, pt2x2)));
        qreal lowerRightY = max(pt1y1, max(pt1y2, max(pt2y1, pt2y2)));
        QRectF bounds(QPointF(upperLeftX, upperLeftY), QPointF(lowerRightX,
                lowerRightY));
    
        //NOTE not setting touched points
        if (bounds.contains(clickPt))
        {
            return true;
        }
    }
    
    return false;
    

    }

     
  • Brad Grimmett

    Brad Grimmett - 2014-02-15
    • Group: --> 0.9.7.0
     
  • Brad Grimmett

    Brad Grimmett - 2014-07-13
    • Group: 0.9.7.0 --> 0.9.8.0
     
  • Brad Grimmett

    Brad Grimmett - 2014-11-16

    added your changes to rev 56
    cheers mate

     
  • Brad Grimmett

    Brad Grimmett - 2014-11-16
    • status: open-accepted --> closed
     

Log in to post a comment.