void QDeclarativePosition::setCoordinate(const QGeoCoordinate &coordinate) { if (m_coordinate == coordinate) return; m_coordinate = coordinate; if (coordinate.type() == QGeoCoordinate::Coordinate3D && !m_altitudeValid) { m_altitudeValid = true; emit altitudeValidChanged(); } else if (m_altitudeValid) { m_altitudeValid = false; emit altitudeValidChanged(); } if (coordinate.isValid()) { if (!m_longitudeValid) { m_longitudeValid = true; emit longitudeValidChanged(); } if (!m_latitudeValid) { m_latitudeValid = true; emit latitudeValidChanged(); } } else { if (m_longitudeValid) { m_longitudeValid = false; emit longitudeValidChanged(); } if (m_latitudeValid) { m_latitudeValid = false; emit latitudeValidChanged(); } } emit coordinateChanged(); }
/*! Returns the distance (in meters) from this coordinate to the coordinate specified by \a other. Altitude is not used in the calculation. This calculation returns the great-circle distance between the two coordinates, with an assumption that the Earth is spherical for the purpose of this calculation. Returns 0 if the type of this coordinate or the type of \a other is QGeoCoordinate::InvalidCoordinate. */ qreal QGeoCoordinate::distanceTo(const QGeoCoordinate &other) const { if (type() == QGeoCoordinate::InvalidCoordinate || other.type() == QGeoCoordinate::InvalidCoordinate) { return 0; } // Haversine formula double dlat = qgeocoordinate_degToRad(other.d->lat - d->lat); double dlon = qgeocoordinate_degToRad(other.d->lng - d->lng); double y = sin(dlat / 2.0) * sin(dlat / 2.0) + cos(qgeocoordinate_degToRad(d->lat)) * cos(qgeocoordinate_degToRad(other.d->lat)) * sin(dlon / 2.0) * sin(dlon / 2.0); double x = 2 * atan2(sqrt(y), sqrt(1 - y)); return qreal(x * qgeocoordinate_EARTH_MEAN_RADIUS * 1000); }
/*! Returns the azimuth (or bearing) in degrees from this coordinate to the coordinate specified by \a other. Altitude is not used in the calculation. There is an assumption that the Earth is spherical for the purpose of this calculation. Returns 0 if the type of this coordinate or the type of \a other is QGeoCoordinate::InvalidCoordinate. */ qreal QGeoCoordinate::azimuthTo(const QGeoCoordinate &other) const { if (type() == QGeoCoordinate::InvalidCoordinate || other.type() == QGeoCoordinate::InvalidCoordinate) { return 0; } double dlon = qgeocoordinate_degToRad(other.d->lng - d->lng); double lat1Rad = qgeocoordinate_degToRad(d->lat); double lat2Rad = qgeocoordinate_degToRad(other.d->lat); double y = sin(dlon) * cos(lat2Rad); double x = cos(lat1Rad) * sin(lat2Rad) - sin(lat1Rad) * cos(lat2Rad) * cos(dlon); double whole; double fraction = modf(qgeocoordinate_radToDeg(atan2(y, x)), &whole); return qreal((int(whole + 360) % 360) + fraction); }
QDebug operator<<(QDebug dbg, const QGeoCoordinate &coord) { double lat = coord.latitude(); double lng = coord.longitude(); dbg.nospace() << "QGeoCoordinate("; if (qIsNaN(lat)) dbg.nospace() << '?'; else dbg.nospace() << lat; dbg.nospace() << ", "; if (qIsNaN(lng)) dbg.nospace() << '?'; else dbg.nospace() << lng; if (coord.type() == QGeoCoordinate::Coordinate3D) { dbg.nospace() << ", "; dbg.nospace() << coord.altitude(); } dbg.nospace() << ')'; return dbg; }