| 2438 | } |
| 2439 | |
| 2440 | int PathObject::isPointOnPath( |
| 2441 | const MapCoordF& coord, |
| 2442 | qreal tolerance, |
| 2443 | bool treat_areas_as_paths, |
| 2444 | bool extended_selection) const |
| 2445 | { |
| 2446 | auto side_tolerance = tolerance; |
| 2447 | if (extended_selection && map && (symbol->getType() == Symbol::Line || symbol->getType() == Symbol::Combined)) |
| 2448 | { |
| 2449 | // TODO: precalculate largest line extent for all symbols to move it out of this time critical method? |
| 2450 | side_tolerance += symbol->calculateLargestLineExtent(); |
| 2451 | } |
| 2452 | |
| 2453 | auto contained_types = symbol->getContainedTypes(); |
| 2454 | if ((contained_types & Symbol::Line || treat_areas_as_paths) && tolerance > 0) |
| 2455 | { |
| 2456 | update(); |
| 2457 | for (const auto& part : path_parts) |
| 2458 | { |
| 2459 | const auto& path_coords = part.path_coords; |
| 2460 | auto size = path_coords.size(); |
| 2461 | for (PathCoordVector::size_type i = 0; i < size - 1; ++i) |
| 2462 | { |
| 2463 | Q_ASSERT(path_coords[i].index < coords.size()); |
| 2464 | if (coords[path_coords[i].index].isHolePoint()) |
| 2465 | continue; |
| 2466 | |
| 2467 | MapCoordF to_coord = coord - path_coords[i].pos; |
| 2468 | MapCoordF to_next = path_coords[i+1].pos - path_coords[i].pos; |
| 2469 | MapCoordF tangent = to_next; |
| 2470 | tangent.normalize(); |
| 2471 | |
| 2472 | auto dist_along_line = MapCoordF::dotProduct(to_coord, tangent); |
| 2473 | if (dist_along_line < -tolerance) |
| 2474 | continue; |
| 2475 | |
| 2476 | if (dist_along_line < 0 && to_coord.lengthSquared() <= tolerance*tolerance) |
| 2477 | return Symbol::Line; |
| 2478 | |
| 2479 | auto line_length = qreal(path_coords[i+1].clen) - qreal(path_coords[i].clen); |
| 2480 | if (line_length < 1e-7) |
| 2481 | continue; |
| 2482 | |
| 2483 | if (dist_along_line > line_length + tolerance) |
| 2484 | continue; |
| 2485 | |
| 2486 | if (dist_along_line > line_length && coord.distanceSquaredTo(path_coords[i+1].pos) <= tolerance*tolerance) |
| 2487 | return Symbol::Line; |
| 2488 | |
| 2489 | auto right = tangent.perpRight(); |
| 2490 | |
| 2491 | auto dist_from_line = qAbs(MapCoordF::dotProduct(right, to_coord)); |
| 2492 | if (dist_from_line <= side_tolerance) |
| 2493 | return Symbol::Line; |
| 2494 | } |
| 2495 | } |
| 2496 | } |
| 2497 |
no test coverage detected