389bool QGeoPathPrivateBase::operator==(
const QGeoShapePrivate &other)
const
391 if (!QGeoShapePrivate::operator==(other))
394 const QGeoPathPrivateBase &otherBase =
static_cast<
const QGeoPathPrivateBase &>(other);
395 return m_path == otherBase.m_path;
414double QGeoPathPrivateBase::length(qsizetype indexFrom, qsizetype indexTo)
const
416 if (path().isEmpty())
419 bool wrap = indexTo == -1;
420 if (indexTo < 0 || indexTo >= path().size())
421 indexTo = path().size() - 1;
425 for (qsizetype i = indexFrom; i < indexTo; i++)
426 len += m_path[i].distanceTo(m_path[i + 1]);
428 len += m_path.last().distanceTo(m_path.first());
450void QGeoPathPrivateBase::translate(
double degreesLatitude,
double degreesLongitude)
453 QList<
double> deltaXs;
454 double minX, maxX, minLati, maxLati;
455 computeBBox(m_path, deltaXs, minX, maxX, minLati, maxLati, m_bbox);
457 if (degreesLatitude > 0.0)
458 degreesLatitude = qMin(degreesLatitude, 90.0 - maxLati);
460 degreesLatitude = qMax(degreesLatitude, -90.0 - minLati);
461 for (QGeoCoordinate &p: m_path) {
462 p.setLatitude(p.latitude() + degreesLatitude);
463 p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
465 m_bbox.translate(degreesLatitude, degreesLongitude);
467 m_bboxDirty.store(
false, std::memory_order_release);
494void QGeoPathPrivateBase::insertCoordinate(qsizetype index,
const QGeoCoordinate &coordinate)
496 if (index < 0 || index > m_path.size() || !coordinate.isValid())
498 m_path.insert(index, coordinate);
502void QGeoPathPrivateBase::replaceCoordinate(qsizetype index,
const QGeoCoordinate &coordinate)
504 if (index < 0 || index >= m_path.size() || !coordinate.isValid())
506 m_path[index] = coordinate;
529void QGeoPathPrivateBase::ensureBoundingBoxUpdated()
const
531 if (m_bboxDirty.load(std::memory_order_acquire)) {
532 const std::scoped_lock lock(globalPathMutex);
533 if (m_bboxDirty.load(std::memory_order_acquire)) {
534 QList<
double> deltaXs;
535 double minX, maxX, minLati, maxLati;
536 computeBBox(m_path, deltaXs, minX, maxX, minLati, maxLati, m_bbox);
537 m_bboxDirty.store(
false, std::memory_order_release);
563bool QGeoPathPrivate::operator==(
const QGeoShapePrivate &other)
const
565 if (!QGeoPathPrivateBase::operator==(other))
568 const QGeoPathPrivate &otherPath =
static_cast<
const QGeoPathPrivate &>(other);
569 return m_width == otherPath.m_width;
572bool QGeoPathPrivate::lineContains(
const QGeoCoordinate &coordinate)
const
589 double lineRadius = qMax(width() * 0.5, 0.2);
591 if (m_path.isEmpty())
593 else if (m_path.size() == 1)
594 return (m_path[0].distanceTo(coordinate) <= lineRadius);
596 Q_ASSERT(m_path.size() > 1);
597 const QDoubleVector2D pt = QWebMercator::coordToMercator(coordinate);
598 QDoubleVector2D last = QWebMercator::coordToMercator(m_path[0]);
599 for (qsizetype i = 1; i < m_path.size(); i++) {
600 const QDoubleVector2D here = QWebMercator::coordToMercator(m_path[i]);
602 if (here.x() > last.x() + 0.5)
603 last.setX(last.x() + 1.0);
604 else if (here.x() < last.x() - 0.5)
605 last.setX(last.x() - 1.0);
609 if (m_path[i].distanceTo(coordinate) <= lineRadius)
614 QDoubleVector2D p = pt;
616 QDoubleVector2D mid = (last + here) / 2.0;
618 if (p.x() > mid.x() + 0.5)
620 else if (p.x() < mid.x() - 0.5)
624 for (
int j = 0; j < 2; ++j) {
625 const QDoubleVector2D pml = p - last, hml = here - last;
626 const double u = (pml.x() * hml.x() + pml.y() * hml.y()) / hml.lengthSquared();
628 const QDoubleVector2D candidate = u > 0 ? u < 1 ? last + u * hml : here : last;
629 const double distance = coordinate.distanceTo(QWebMercator::mercatorToCoord(candidate));
630 if (distance <= lineRadius)
635
636
637
638
639
640
641
642
643
644
645
646 if (p.x() > qMin(last.x(), here.x()) + 0.5)
648 else if (p.x() < qMax(last.x(), here.x()) - 0.5)
690QGeoPathPrivateEager::QGeoPathPrivateEager(
const QList<QGeoCoordinate> &path,
const qreal width)
691: QGeoPathPrivate(path, width)
693 m_bboxDirty.store(
false, std::memory_order_relaxed);
714void QGeoPathPrivateEager::markDirty()
717 computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
720void QGeoPathPrivateEager::translate(
double degreesLatitude,
double degreesLongitude)
722 if (degreesLatitude > 0.0)
723 degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
725 degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati);
726 for (QGeoCoordinate &p: m_path) {
727 p.setLatitude(p.latitude() + degreesLatitude);
728 p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
730 m_bbox.translate(degreesLatitude, degreesLongitude);
731 m_minLati += degreesLatitude;
732 m_maxLati += degreesLatitude;
746 updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
754QGeoPathEager::QGeoPathEager(
const QList<QGeoCoordinate> &path,
const qreal &width) : QGeoPath()
756 d_ptr =
new QGeoPathPrivateEager(path, width);