예제 #1
0
    void type_data()
    {
        QTest::addColumn<QGeoCoordinate>("c");
        QTest::addColumn<QGeoCoordinate::CoordinateType>("type");

        QGeoCoordinate c;

        QTest::newRow("no values set")  << c << QGeoCoordinate::InvalidCoordinate;

        c.setAltitude(1.0);
        QTest::newRow("only altitude is set")  << c << QGeoCoordinate::InvalidCoordinate;

        c.setLongitude(1.0);
        QTest::newRow("only latitude and altitude is set") << c << QGeoCoordinate::InvalidCoordinate;

        c.setLatitude(-1.0);
        QTest::newRow("all valid: 3D Coordinate") << c << QGeoCoordinate::Coordinate3D;

        c.setLatitude(-90.1);
        QTest::newRow("too low latitude and valid longitude") << c << QGeoCoordinate::InvalidCoordinate;

        c.setLongitude(-180.1);
        c.setLatitude(90.0);
        QTest::newRow("valid latitude and too low longitude") << c << QGeoCoordinate::InvalidCoordinate;

        c.setLatitude(90.1);
        c.setLongitude(-180.0);
        QTest::newRow("too high latitude and valid longitude") << c << QGeoCoordinate::InvalidCoordinate;

        c.setLatitude(-90.0);
        c.setLongitude(180.1);
        QTest::newRow("valid latitude and too high longitude") << c << QGeoCoordinate::InvalidCoordinate;
    }
/*!
    \internal
*/
void QDeclarativeRectangleMapItem::dragEnded()
{
    QPointF newTopLeftPoint = QPointF(x(),y());
    QGeoCoordinate newTopLeft = map()->screenPositionToCoordinate(newTopLeftPoint, false);
    if (newTopLeft.isValid()) {
        // calculate new geo width while checking for dateline crossing
        const double lonW = bottomRight_.longitude() > topLeft_.longitude() ?
                    bottomRight_.longitude() - topLeft_.longitude() :
                    bottomRight_.longitude() + 360 - topLeft_.longitude();
        const double latH = qAbs(bottomRight_.latitude() - topLeft_.latitude());
        QGeoCoordinate newBottomRight;
        // prevent dragging over valid min and max latitudes
        if (QLocationUtils::isValidLat(newTopLeft.latitude() - latH)) {
            newBottomRight.setLatitude(newTopLeft.latitude() - latH);
        } else {
            newBottomRight.setLatitude(QLocationUtils::clipLat(newTopLeft.latitude() - latH));
            newTopLeft.setLatitude(newBottomRight.latitude() + latH);
        }
        // handle dateline crossing
        newBottomRight.setLongitude(QLocationUtils::wrapLong(newTopLeft.longitude() + lonW));
        newBottomRight.setAltitude(newTopLeft.altitude());
        topLeft_ = newTopLeft;
        bottomRight_ = newBottomRight;
        geometry_.setPreserveGeometry(true, newTopLeft);
        borderGeometry_.setPreserveGeometry(true, newTopLeft);
        geometry_.markSourceDirty();
        borderGeometry_.markSourceDirty();
        updateMapItem();
        emit topLeftChanged(topLeft_);
        emit bottomRightChanged(bottomRight_);
    }
}
예제 #3
0
void GpsLocation::newPosition(QGeoPositionInfo pos)
{
	int64_t lastTime = 0;
	QGeoCoordinate lastCoord;
	int nr = m_trackers.count();
	if (nr) {
		gpsTracker gt = m_trackers.last();
		lastCoord.setLatitude(gt.latitude.udeg / 1000000.0);
		lastCoord.setLongitude(gt.longitude.udeg / 1000000.0);
		lastTime = gt.when;
	}
	// if we are waiting for a position update or
	// if we have no record stored or if at least the configured minimum
	// time has passed or we moved at least the configured minimum distance
	int64_t delta = (int64_t)pos.timestamp().toTime_t() + gettimezoneoffset() - lastTime;
	if (!nr || waitingForPosition || delta > prefs.time_threshold ||
	    lastCoord.distanceTo(pos.coordinate()) > prefs.distance_threshold) {
		QString msg("received new position %1 after delta %2 threshold %3 (now %4 last %5)");
		status(qPrintable(msg.arg(pos.coordinate().toString()).arg(delta).arg(prefs.time_threshold).arg(pos.timestamp().toString()).arg(QDateTime().fromMSecsSinceEpoch(lastTime * 1000).toString())));
		waitingForPosition = false;
		acquiredPosition();
		gpsTracker gt;
		gt.when = pos.timestamp().toTime_t();
		gt.when += gettimezoneoffset(gt.when);
		gt.latitude.udeg = lrint(pos.coordinate().latitude() * 1000000);
		gt.longitude.udeg = lrint(pos.coordinate().longitude() * 1000000);
		addFixToStorage(gt);
		gpsTracker gtNew = m_trackers.last();
		qDebug() << "newest fix is now at" << QDateTime().fromMSecsSinceEpoch(gtNew.when - gettimezoneoffset(gtNew.when) * 1000).toString();
	}
}
/*!
    \internal
*/
void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
        QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
        return;
    }

    QDoubleVector2D newPoint = QDoubleVector2D(x(),y()) + QDoubleVector2D(geometry_.firstPointOffset());
    QGeoCoordinate newCoordinate = map()->screenPositionToCoordinate(newPoint, false);
    if (newCoordinate.isValid()) {
        double firstLongitude = path_.at(0).longitude();
        double firstLatitude = path_.at(0).latitude();
        double minMaxLatitude = firstLatitude;
        // prevent dragging over valid min and max latitudes
        for (int i = 0; i < path_.count(); ++i) {
            double newLatitude = path_.at(i).latitude()
                    + newCoordinate.latitude() - firstLatitude;
            if (!QLocationUtils::isValidLat(newLatitude)) {
                if (qAbs(newLatitude) > qAbs(minMaxLatitude)) {
                    minMaxLatitude = newLatitude;
                }
            }
        }
        // calculate offset needed to re-position the item within map border
        double offsetLatitude = minMaxLatitude - QLocationUtils::clipLat(minMaxLatitude);
        for (int i = 0; i < path_.count(); ++i) {
            QGeoCoordinate coord = path_.at(i);
            // handle dateline crossing
            coord.setLongitude(QLocationUtils::wrapLong(coord.longitude()
                               + newCoordinate.longitude() - firstLongitude));
            coord.setLatitude(coord.latitude()
                              + newCoordinate.latitude() - firstLatitude - offsetLatitude);
            path_.replace(i, coord);
        }

        QGeoCoordinate leftBoundCoord = geometry_.geoLeftBound();
        leftBoundCoord.setLongitude(QLocationUtils::wrapLong(leftBoundCoord.longitude()
                           + newCoordinate.longitude() - firstLongitude));
        geometry_.setPreserveGeometry(true, leftBoundCoord);
        geometry_.markSourceDirty();
        updateMapItem();
        emit pathChanged();
    }

    // Not calling QDeclarativeGeoMapItemBase::geometryChanged() as it will be called from a nested
    // call to this function.
}
/*!
    \internal
*/
void QDeclarativePolygonMapItem::dragEnded()
{
    QPointF newPoint = QPointF(x(),y()) + geometry_.firstPointOffset();
    QGeoCoordinate newCoordinate = map()->screenPositionToCoordinate(newPoint, false);
    if (newCoordinate.isValid()) {
        double firstLongitude = path_.at(0).longitude();
        double firstLatitude = path_.at(0).latitude();
        double minMaxLatitude = firstLatitude;
        // prevent dragging over valid min and max latitudes
        for (int i = 0; i < path_.count(); ++i) {
            double newLatitude = path_.at(i).latitude()
                    + newCoordinate.latitude() - firstLatitude;
            if (!QLocationUtils::isValidLat(newLatitude)) {
                if (qAbs(newLatitude) > qAbs(minMaxLatitude)) {
                    minMaxLatitude = newLatitude;
                }
            }
        }
        // calculate offset needed to re-position the item within map border
        double offsetLatitude = minMaxLatitude - QLocationUtils::clipLat(minMaxLatitude);
        for (int i = 0; i < path_.count(); ++i) {
            QGeoCoordinate coord = path_.at(i);
            // handle dateline crossing
            coord.setLongitude(QLocationUtils::wrapLong(coord.longitude()
                               + newCoordinate.longitude() - firstLongitude));
            coord.setLatitude(coord.latitude()
                              + newCoordinate.latitude() - firstLatitude - offsetLatitude);

            path_.replace(i, coord);
        }

        QGeoCoordinate leftBoundCoord = geometry_.geoLeftBound();
        leftBoundCoord.setLongitude(QLocationUtils::wrapLong(leftBoundCoord.longitude()
                           + newCoordinate.longitude() - firstLongitude));
        geometry_.setPreserveGeometry(true, leftBoundCoord);
        borderGeometry_.setPreserveGeometry(true, leftBoundCoord);
        geometry_.markSourceDirty();
        borderGeometry_.markSourceDirty();
        updateMapItem();
        emit pathChanged();
    }
}
예제 #6
0
void CLbsPositionLogger::readNextPosition()
{
    QByteArray line = m_logFile.readLine().trimmed();
    if (line.isEmpty()) {
        LOG_MODEL_ERROR("CLbsPositionLogger", "no readlien");
        return;
    }
    
    QList<QByteArray> data = line.split(',');
    
    QGeoCoordinate coordinate;
    QGeoPositionInfo info;
    
    bool hasTimestamp = false;
    QDateTime timestamp = QDateTime::fromTime_t(data.value(0).toLong(&hasTimestamp), Qt::UTC);
    if(hasTimestamp && timestamp.isValid())
        info.setTimestamp(timestamp);
    double latitude;
    bool hasLatitude = false;
    latitude = data.value(1).toDouble(&hasLatitude);
    if(hasLatitude)
        coordinate.setLatitude(latitude);
    double longitude;
    bool hasLongitude = false;
    longitude = data.value(2).toDouble(&hasLongitude);
    if(hasLongitude)
        coordinate.setLongitude(longitude);
    double altitude;
    bool hasAltitude = false;
    altitude = data.value(3).toDouble(&hasAltitude);
    if(hasAltitude)
        coordinate.setAltitude(altitude);
    info.setCoordinate(coordinate);
    
    double HorizontalAccuracy;
    bool hasHorizontalAccuracy = false;
    HorizontalAccuracy = data.value(4).toDouble(&hasHorizontalAccuracy);
    if(hasHorizontalAccuracy)
        info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, HorizontalAccuracy);
    double Direction;
    bool hasDirection = false;
    Direction = data.value(5).toDouble(&hasDirection);
    if(hasDirection)
        info.setAttribute(QGeoPositionInfo::Direction, Direction);
    double GroundSpeed;
    bool hasGroundSpeed = false;
    GroundSpeed = data.value(6).toDouble(&hasGroundSpeed);
    if(hasGroundSpeed)
        info.setAttribute(QGeoPositionInfo::GroundSpeed, GroundSpeed);
    if (info.isValid()) {
        m_lastPosition = info;
        emit positionUpdated(info);
    }
}
예제 #7
0
    void longitude()
    {
        QFETCH(double, value);
        QGeoCoordinate c;
        c.setLongitude(value);
        QCOMPARE(c.longitude(), value);

        QGeoCoordinate c2 = c;
        QCOMPARE(c.longitude(), value);
        QCOMPARE(c2, c);
    }
// FIXME:
// - not left right / up down flicking, so if map is rotated, will act unintuitively
void QDeclarativeGeoMapGestureArea::startFlick(int dx, int dy, int timeMs)
{
    if (timeMs < 0)
        return;

    QGeoCoordinate animationStartCoordinate = map_->mapController()->center();

    if (pan_.animation_->state() == QPropertyAnimation::Running)
        pan_.animation_->stop();
    QGeoCoordinate animationEndCoordinate = map_->mapController()->center();
    pan_.animation_->setDuration(timeMs);
    animationEndCoordinate.setLongitude(animationStartCoordinate.longitude() - (dx / pow(2.0, map_->mapController()->zoom())));
    animationEndCoordinate.setLatitude(animationStartCoordinate.latitude() + (dy / pow(2.0, map_->mapController()->zoom())));
    pan_.animation_->setStartValue(QVariant::fromValue(animationStartCoordinate));
    pan_.animation_->setEndValue(QVariant::fromValue(animationEndCoordinate));
    pan_.animation_->start();
    emit flickStarted();
}
bool QGeoRouteXmlParser::parseCoordinates(QGeoCoordinate &coord)
{
    QString currentElement = m_reader->name().toString();
    m_reader->readNext();

    while (!(m_reader->tokenType() == QXmlStreamReader::EndElement && m_reader->name() == currentElement)) {
        if (m_reader->tokenType() == QXmlStreamReader::StartElement) {
            QString name = m_reader->name().toString();
            QString value = m_reader->readElementText();
            if (name == "Latitude")
                coord.setLatitude(value.toDouble());
            else if (name == "Longitude")
                coord.setLongitude(value.toDouble());
        }
        m_reader->readNext();
    }

    return true;
}
예제 #10
0
QList<QGeoPositionInfo> gpxfile::loadFrom(const QString fileName) {

  QFile file(fileName);
  if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
      qDebug() << "File open error:" << file.errorString();
//      return false;
  }
  QXmlStreamReader xml(&file);

  QList<QGeoPositionInfo> trackList;
  trackList.clear();

  QGeoPositionInfo tp;
  QGeoCoordinate coord;
  QDateTime ts;

  while (!xml.atEnd() && !xml.hasError())
  {
      xml.readNext();

      if (xml.isStartElement()) {
          if (xml.name() == "trkpt") {
              coord.setLongitude(xml.attributes().value("lon").toFloat());
              coord.setLatitude(xml.attributes().value("lat").toFloat());
              while (xml.readNextStartElement()) {
                if (xml.name() == "ele")
                   coord.setAltitude(xml.readElementText().toFloat());
                else if (xml.name() == "time")
                   ts = QDateTime::fromString(xml.readElementText(),"yyyy-MM-dd'T'hh:mm:ss'Z'");
              } //ele, time
              tp.setCoordinate(coord);
              tp.setTimestamp(ts);
              trackList.append(tp);
          } //trkpt
      } //content

  } //eof

  return(trackList);
}
/*!
    \internal
*/
void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
        QDeclarativeGeoMapItemBase::geometryChanged(newGeometry, oldGeometry);
        return;
    }

    QDoubleVector2D newTopLeftPoint = QDoubleVector2D(x(),y());
    QGeoCoordinate newTopLeft = map()->itemPositionToCoordinate(newTopLeftPoint, false);
    if (newTopLeft.isValid()) {
        // calculate new geo width while checking for dateline crossing
        const double lonW = bottomRight_.longitude() > topLeft_.longitude() ?
                    bottomRight_.longitude() - topLeft_.longitude() :
                    bottomRight_.longitude() + 360 - topLeft_.longitude();
        const double latH = qAbs(bottomRight_.latitude() - topLeft_.latitude());
        QGeoCoordinate newBottomRight;
        // prevent dragging over valid min and max latitudes
        if (QLocationUtils::isValidLat(newTopLeft.latitude() - latH)) {
            newBottomRight.setLatitude(newTopLeft.latitude() - latH);
        } else {
            newBottomRight.setLatitude(QLocationUtils::clipLat(newTopLeft.latitude() - latH));
            newTopLeft.setLatitude(newBottomRight.latitude() + latH);
        }
        // handle dateline crossing
        newBottomRight.setLongitude(QLocationUtils::wrapLong(newTopLeft.longitude() + lonW));
        newBottomRight.setAltitude(newTopLeft.altitude());
        topLeft_ = newTopLeft;
        bottomRight_ = newBottomRight;
        geometry_.setPreserveGeometry(true, newTopLeft);
        borderGeometry_.setPreserveGeometry(true, newTopLeft);
        markSourceDirtyAndUpdate();
        emit topLeftChanged(topLeft_);
        emit bottomRightChanged(bottomRight_);
    }

    // Not calling QDeclarativeGeoMapItemBase::geometryChanged() as it will be called from a nested
    // call to this function.
}
예제 #12
0
SensorData CzmlReader::writeToSensorData(QJsonObject& data)
{
    QJsonArray positionArray;
    QJsonObject positionObject;
    SensorData sensordata;

    QString id = data["id"].toString();
    sensordata.setId(getIdFromCzmlString(id));

    positionObject = data["position"].toObject();
    positionArray = positionObject["cartographicDegrees"].toArray();
    QGeoCoordinate parsedPosition;
    parsedPosition.setLatitude(positionArray[1].toDouble());
    parsedPosition.setLongitude(positionArray[0].toDouble());
    sensordata.setPosition(parsedPosition);
    sensordata.setHeight(positionArray[2].toDouble());

    if(data["sensorvalue"].isString())
        sensordata.setSensorValue(std::numeric_limits<double>::min());
    else
        sensordata.setSensorValue(data["sensorvalue"].toDouble());

    return sensordata;
}
예제 #13
0
bool QLandmarkFileHandlerGpx::readWaypoint(QLandmark &landmark, const QString &elementName)
{
    /*
    <xsd:complexType name="wptType">
        <xsd:sequence>
            <xsd:element name="ele" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="time" type="xsd:dateTime" minOccurs="0" />
            <xsd:element name="magvar" type="degreesType" minOccurs="0" />
            <xsd:element name="geoidheight" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="name" type="xsd:string" minOccurs="0" />
            <xsd:element name="cmt" type="xsd:string" minOccurs="0" />
            <xsd:element name="desc" type="xsd:string" minOccurs="0" />
            <xsd:element name="src" type="xsd:string" minOccurs="0" />
            <xsd:element name="link" type="linkType" minOccurs="0" maxOccurs="unbounded" />
            <xsd:element name="sym" type="xsd:string" minOccurs="0" />
            <xsd:element name="type" type="xsd:string" minOccurs="0" />
            <xsd:element name="fix" type="fixType" minOccurs="0" />
            <xsd:element name="sat" type="xsd:nonNegativeInteger" minOccurs="0" />
            <xsd:element name="hdop" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="vdop" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="pdop" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="ageofdgpsdata" type="xsd:decimal" minOccurs="0" />
            <xsd:element name="dgpsid" type="dgpsStationType" minOccurs="0" />
            <xsd:element name="extensions" type="extensionsType" minOccurs="0" />
        </xsd:sequence>
        <xsd:attribute name="lat" type="latitudeType" use="required" />
        <xsd:attribute name="lon" type="longitudeType" use="required" />
    </xsd:complexType>

    <xsd:simpleType name="latitudeType">
        <xsd:restriction base="xsd:decimal">
            <xsd:minInclusive value="-90.0"/>
            <xsd:maxInclusive value="90.0"/>
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:simpleType name="longitudeType">
        <xsd:restriction base="xsd:decimal">
            <xsd:minInclusive value="-180.0"/>
            <xsd:maxExclusive value="180.0"/>
        </xsd:restriction>
    </xsd:simpleType>
    */
    Q_ASSERT(m_reader->isStartElement()
             && (m_reader->name() == elementName));

    QGeoCoordinate coord;

    if (m_reader->attributes().hasAttribute("lat")) {
        bool ok = false;
        QString s = m_reader->attributes().value("lat").toString();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The attribute \"lat\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double lat = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The attribute \"lat\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        if (lat < -90.0 || 90.0 < lat) {
            m_reader->raiseError(QString("The attribute \"lat\" fell outside of the bounds -90.0 <= lat <= 90.0 (value was \"%1\").").arg(s));
            return false;
        }

        coord.setLatitude(lat);
    } else {
        m_reader->raiseError(QString("The element \"%1\" did not have the required attribute \"lat\".").arg(elementName));
        return false;
    }

    if (m_reader->attributes().hasAttribute("lon")) {
        bool ok = false;
        QString s = m_reader->attributes().value("lon").toString();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The attribute \"lon\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double lon = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The attribute \"lon\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        if (lon < -180.0 || 180.0 <= lon) {
            m_reader->raiseError(QString("The attribute \"lon\" fell outside of the bounds -180.0 <= lat < 180.0 (value was \"%1\").").arg(s));
            return false;
        }

        coord.setLongitude(lon);
    } else {
        m_reader->raiseError(QString("The element \"%1\" did not have the required attribute \"lon\".").arg(elementName));
        return false;
    }

    landmark.setCoordinate(coord);

    if (!m_reader->readNextStartElement())
        return true;

    if (m_reader->name() == "ele") {
        bool ok = false;
        QString s = m_reader->readElementText();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The element \"ele\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double alt = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The element \"ele\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        coord.setAltitude(alt);
        landmark.setCoordinate(coord);

        if (!m_reader->readNextStartElement())
            return true;
    }

    QList<QString> unusedNames1;
    unusedNames1 << "time";
    unusedNames1 << "magvar";
    unusedNames1 << "geoidheight";

    for (int i = 0; i < unusedNames1.size(); ++i) {
        if (m_reader->name() == unusedNames1.at(i)) {
            // Not used outside of schema compliance check
            m_reader->skipCurrentElement();
            if (!m_reader->readNextStartElement())
                return true;
        }
    }

    if (m_reader->name() == "name") {
        landmark.setName(m_reader->readElementText());
        if (!m_reader->readNextStartElement())
            return true;
    }

    if (m_reader->name() == "cmt") {
        // Not used outside of schema compliance check
        m_reader->skipCurrentElement();
        if (!m_reader->readNextStartElement())
            return true;
    }

    if (m_reader->name() == "desc") {
        landmark.setDescription(m_reader->readElementText());
        if (!m_reader->readNextStartElement())
            return true;
    }

    if (m_reader->name() == "src") {
        // Not used outside of schema compliance check
        m_reader->skipCurrentElement();
        if (!m_reader->readNextStartElement())
            return true;
    }

    while (m_reader->name() == "link") {
        // Not used outside of schema compliance check
        m_reader->skipCurrentElement();
        if (!m_reader->readNextStartElement())
            return true;
    }

    QList<QString> unusedNames2;
    unusedNames2 << "sym";
    unusedNames2 << "type";
    unusedNames2 << "fix";
    unusedNames2 << "sat";
    unusedNames2 << "hdop";
    unusedNames2 << "vdop";
    unusedNames2 << "pdop";
    unusedNames2 << "ageofdgpsdata";
    unusedNames2 << "dgpsid";
    unusedNames2 << "extensions";

    for (int i = 0; i < unusedNames2.size(); ++i) {
        if (m_reader->name() == unusedNames2.at(i)) {
            // Not used outside of schema compliance check
            m_reader->skipCurrentElement();
            if (!m_reader->readNextStartElement())
                return true;
        }
    }

    m_reader->raiseError(QString("The element \"%1\" did not expect a child element named \"%2\" at this point (unknown child element or child element out of order).").arg(elementName).arg(m_reader->name().toString()));
    return false;
}
예제 #14
0
void QDeclarativeGeoMap::fitViewportToGeoShape()
{
    int margins  = 10;
    if (!m_map || width() <= margins || height() <= margins)
        return;

    QGeoCoordinate topLeft;
    QGeoCoordinate bottomRight;

    switch (m_region.type()) {
    case QGeoShape::RectangleType:
    {
        QGeoRectangle rect = m_region;
        topLeft = rect.topLeft();
        bottomRight = rect.bottomRight();
        break;
    }
    case QGeoShape::CircleType:
    {
        const double pi = M_PI;
        QGeoCircle circle = m_region;
        QGeoCoordinate centerCoordinate = circle.center();

        // calculate geo bounding box of the circle
        // circle tangential points with meridians and the north pole create
        // spherical triangle, we use spherical law of sines
        // sin(lon_delta_in_rad)/sin(r_in_rad) =
        // sin(alpha_in_rad)/sin(pi/2 - lat_in_rad), where:
        // * lon_delta_in_rad - delta of longitudes of circle center
        //   and tangential points
        // * r_in_rad - angular radius of the circle
        // * lat_in_rad - latitude of circle center
        // * alpha_in_rad - angle between meridian and radius to the circle =>
        //   this is tangential point => sin(alpha) = 1
        // * lat_delta_in_rad - delta of latitudes of circle center and
        //   latitude of points where great circle (going through circle
        //   center) crosses circle and the pole

        double r_in_rad = circle.radius() / EARTH_MEAN_RADIUS; // angular r
        double lat_delta_in_deg = r_in_rad * 180 / pi;
        double lon_delta_in_deg = std::asin(std::sin(r_in_rad) /
               std::cos(centerCoordinate.latitude() * pi / 180)) * 180 / pi;

        topLeft.setLatitude(centerCoordinate.latitude() + lat_delta_in_deg);
        topLeft.setLongitude(centerCoordinate.longitude() - lon_delta_in_deg);
        bottomRight.setLatitude(centerCoordinate.latitude()
                                - lat_delta_in_deg);
        bottomRight.setLongitude(centerCoordinate.longitude()
                                 + lon_delta_in_deg);

        // adjust if circle reaches poles => cross all meridians and
        // fit into Mercator projection bounds
        if (topLeft.latitude() > 90 || bottomRight.latitude() < -90) {
            topLeft.setLatitude(qMin(topLeft.latitude(), 85.05113));
            topLeft.setLongitude(-180.0);
            bottomRight.setLatitude(qMax(bottomRight.latitude(),
                                                 -85.05113));
            bottomRight.setLongitude(180.0);
        }
        break;
    }
    case QGeoShape::UnknownType:
        //Fallthrough to default
    default:
        return;
    }

    // adjust zoom, use reference world to keep things simple
    // otherwise we would need to do the error prone longitudes
    // wrapping
    QDoubleVector2D topLeftPoint =
            m_map->referenceCoordinateToItemPosition(topLeft);
    QDoubleVector2D bottomRightPoint =
            m_map->referenceCoordinateToItemPosition(bottomRight);

    double bboxWidth = bottomRightPoint.x() - topLeftPoint.x();
    double bboxHeight = bottomRightPoint.y() - topLeftPoint.y();

    // find center of the bounding box
    QGeoCoordinate centerCoordinate =
            m_map->referenceItemPositionToCoordinate(
                (topLeftPoint + bottomRightPoint)/2);

    // position camera to the center of bounding box
    setCenter(centerCoordinate);

    // if the shape is empty we just change center position, not zoom
    if (bboxHeight == 0 && bboxWidth == 0)
        return;

    double zoomRatio = qMax(bboxWidth / (width() - margins),
                            bboxHeight / (height() - margins));
    // fixme: use log2 with c++11
    zoomRatio = std::log(zoomRatio) / std::log(2.0);
    double newZoom = qMax((double)minimumZoomLevel(), m_map->mapController()->zoom()
                          - zoomRatio);
    setZoomLevel(newZoom);
    m_validRegion = true;
}
예제 #15
0
QGeoPositionInfo LiblocationWrapper::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
{
    QGeoPositionInfo posInfo;
    QGeoCoordinate coordinate;
    double time;
    double latitude;
    double longitude;
    double altitude;
    double speed;
    double track;
    double climb;

    GConfItem lastKnownPositionTime("/system/nokia/location/lastknown/time");
    GConfItem lastKnownPositionLatitude("/system/nokia/location/lastknown/latitude");
    GConfItem lastKnownPositionLongitude("/system/nokia/location/lastknown/longitude");
    GConfItem lastKnownPositionAltitude("/system/nokia/location/lastknown/altitude");
    GConfItem lastKnownPositionSpeed("/system/nokia/location/lastknown/speed");
    GConfItem lastKnownPositionTrack("/system/nokia/location/lastknown/track");
    GConfItem lastKnownPositionClimb("/system/nokia/location/lastknown/climb");

    if (validLastSatUpdate)
        return lastSatUpdate;

    if (!fromSatellitePositioningMethodsOnly)
        if (validLastUpdate)
            return lastUpdate;

    time = lastKnownPositionTime.value().toDouble();
    latitude = lastKnownPositionLatitude.value().toDouble();
    longitude = lastKnownPositionLongitude.value().toDouble();
    altitude = lastKnownPositionAltitude.value().toDouble();
    speed = lastKnownPositionSpeed.value().toDouble();
    track = lastKnownPositionTrack.value().toDouble();
    climb = lastKnownPositionClimb.value().toDouble();

    if (longitude && latitude) {
        coordinate.setLongitude(longitude);
        coordinate.setLatitude(latitude);
        if (altitude) {
            coordinate.setAltitude(altitude);
        }
        posInfo.setCoordinate(coordinate);
    }

    if (speed) {
        posInfo.setAttribute(QGeoPositionInfo::GroundSpeed, speed);
    }

    if (track) {
        posInfo.setAttribute(QGeoPositionInfo::Direction, track);
    }

    if (climb) {
        posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, climb);
    }

    // Only positions with time (3D) are provided.
    if (time) {
        posInfo.setTimestamp(QDateTime::fromTime_t(time));
        return posInfo;
    }

    return QGeoPositionInfo();
}
예제 #16
0
void PsyUtils::TPositionInfo2QGeoPositionInfo(TPositionInfoBase &aPosInfoBase, QGeoPositionInfo& aQPosInfo)
{
    if (aPosInfoBase.PositionClassType() & EPositionInfoClass  ||
            aPosInfoBase.PositionClassType() & EPositionSatelliteInfoClass) {
        TPositionInfo *posInfo = static_cast<TPositionInfo*>(&aPosInfoBase);
        TPosition pos;
        QGeoCoordinate  coord;

        posInfo->GetPosition(pos);
        coord.setLatitude(pos.Latitude());
        coord.setLongitude(pos.Longitude());
        coord.setAltitude(pos.Altitude());

        //store the QGeoCoordinate values
        aQPosInfo.setCoordinate(coord);

        TDateTime datetime = pos.Time().DateTime();
        QDateTime dt(QDate(datetime.Year() , datetime.Month() + 1, datetime.Day() + 1),
                     QTime(datetime.Hour() , datetime.Minute(), datetime.Second(),
                           datetime.MicroSecond() / 1000),
                     Qt::UTC);

        //store the time stamp
        aQPosInfo.setTimestamp(dt);

        //store the horizontal accuracy
        aQPosInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy, pos.HorizontalAccuracy());

        //store the vertical accuracy
        aQPosInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, pos.VerticalAccuracy());

        if (aPosInfoBase.PositionClassType() & EPositionSatelliteInfoClass) {
            TCourse course;
            TPositionSatelliteInfo *satInfo = static_cast<TPositionSatelliteInfo*>(&aPosInfoBase);
            satInfo->GetCourse(course);
            aQPosInfo.setAttribute(QGeoPositionInfo::Direction, course.Heading());
            aQPosInfo.setAttribute(QGeoPositionInfo::GroundSpeed, course.Speed());
            aQPosInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, course.VerticalSpeed());
        }
    }

    if (aPosInfoBase.PositionClassType() & EPositionGenericInfoClass) {
        HPositionGenericInfo *genInfo = static_cast<HPositionGenericInfo*>(&aPosInfoBase);
        float val;
        //check for the horizontal speed
        if (genInfo->IsFieldAvailable(EPositionFieldHorizontalSpeed)) {
            genInfo->GetValue(EPositionFieldHorizontalSpeed, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::GroundSpeed, val);
        }
        //check for the vertcal speed
        if (genInfo->IsFieldAvailable(EPositionFieldVerticalSpeed)) {
            genInfo->GetValue(EPositionFieldVerticalSpeed, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, val);
        }

        //check for the magnetic variation
        if (genInfo->IsFieldAvailable(EPositionFieldMagneticCourseError)) {
            genInfo->GetValue(EPositionFieldMagneticCourseError, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::MagneticVariation, val);
        }

        //check for the heading
        if (genInfo->IsFieldAvailable(EPositionFieldHeading)) {
            genInfo->GetValue(EPositionFieldHeading, val);
            aQPosInfo.setAttribute(QGeoPositionInfo::Direction, val);
        }
    }
}
예제 #17
0
bool LandmarkFilterDialog::setupFetchRequest()
{
    if (filterAllCheckBox->checkState() == Qt::Checked) {
        fetchRequest->setFilter(QLandmarkFilter());
        fetchRequest->setSorting(QLandmarkNameSort());
    } else {
        QLandmarkIntersectionFilter filter;
        QLandmarkSortOrder sortOrder = QLandmarkNameSort();

        if (filterNameCheckBox->checkState() == Qt::Checked) {
            QLandmarkNameFilter nameFilter;
            nameFilter.setName(nameLineEdit->text());
            if (startsWithRadioButton->isChecked())
                nameFilter.setMatchFlags(QLandmarkFilter::MatchStartsWith);
            else
                nameFilter.setMatchFlags(QLandmarkFilter::MatchContains);
            filter.append(nameFilter);
        }

        if (filterCategoryCheckBox->checkState() == Qt::Checked) {
            QLandmarkCategoryFilter categoryFilter;
            if (categoryComboBox->count() > 0) {
                oldCategoryId = categoryComboBox->itemData(categoryComboBox->currentIndex())
                            .value<QLandmarkCategoryId>();
                categoryFilter.setCategoryId(oldCategoryId);
            }
            filter.append(categoryFilter);
        }

        if (filterBoxCheckBox->checkState() == Qt::Checked) {

            if (!isValidLatitude(boxTopLeftLatitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Top left latitude is invalid.  Must be between -90 and 90 (not inclusive)", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }
            else if (!isValidLongitude(boxTopLeftLongitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Top left longitude is invalid. Must be between -180 and 180 (inclusive) ", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }
            else if (!isValidLatitude(boxBottomRightLatitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Bottom right latitude is invalid. (Must be between -90 and 90 (not inclusive)", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }
            else if (!isValidLongitude(boxBottomRightLongitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Bottom right longitude is invalid. (Must be between -180 and 180 (inclusive)", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }

            QGeoCoordinate topLeft;
            topLeft.setLatitude(boxTopLeftLatitudeLineEdit->text().toDouble());
            topLeft.setLongitude(boxTopLeftLongitudeLineEdit->text().toDouble());
            QGeoCoordinate bottomRight;
            bottomRight.setLatitude(boxBottomRightLatitudeLineEdit->text().toDouble());
            bottomRight.setLongitude(boxBottomRightLongitudeLineEdit->text().toDouble());

            QGeoBoundingBox box;
            box.setTopLeft(topLeft);
            box.setBottomRight(bottomRight);
            QLandmarkBoxFilter boxFilter;
            boxFilter.setBoundingBox(box);
            filter.append(boxFilter);
        }

        if (filterProximityCheckBox->checkState() == Qt::Checked) {
            if (!isValidLatitude(proximityLatitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Proximity latitude is invalid.  It must be between -90 and 90 (not inclusive)", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            } else if (!isValidLongitude(proximityLongitudeLineEdit->text())) {
                QMessageBox::warning(this,"Warning", "Proximity longitude is invalid. It must be between -180 and 180 (inclusive) ", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }
            bool ok;
            qreal radius = radiusLineEdit->text().toDouble(&ok);
            if (!ok) {
                QMessageBox::warning(this,"Warning", "Proximity radius is invalid. It must be a number", QMessageBox::Ok, QMessageBox::NoButton);
                return false;
            }

            QLandmarkProximityFilter proximityFilter;
            QGeoCoordinate center;
            center.setLatitude(proximityLatitudeLineEdit->text().toDouble());
            center.setLongitude(proximityLongitudeLineEdit->text().toDouble());
            proximityFilter.setCenter(center);
            proximityFilter.setRadius(radiusLineEdit->text().toDouble());
            filter.append(proximityFilter);
            sortOrder = QLandmarkSortOrder();
        }

        fetchRequest->setFilter(filter);
        fetchRequest->setSorting(sortOrder);
    }
    return true;
}
예제 #18
0
void LiblocationWrapper::locationChanged(LocationGPSDevice *device,
        gpointer data)
{
    QGeoPositionInfo posInfo;
    QGeoCoordinate coordinate;
    QGeoSatelliteInfo satInfo;
    int satellitesInUseCount = 0;
    LiblocationWrapper *object;

    if (!data || !device) {
        return;
    }

    object = (LiblocationWrapper *)data;

    if (device) {
        if (device->fix) {
            if (device->fix->fields & LOCATION_GPS_DEVICE_TIME_SET) {
                posInfo.setTimestamp(QDateTime::fromTime_t(device->fix->time));
            }

            if (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) {
                coordinate.setLatitude(device->fix->latitude);
                coordinate.setLongitude(device->fix->longitude);
                posInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy,
                                     device->fix->eph / 100.0);
                posInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy,
                                     device->fix->epv);
            }

            if (device->fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) {
                coordinate.setAltitude(device->fix->altitude);
            }

            if (device->fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) {
                posInfo.setAttribute(QGeoPositionInfo::GroundSpeed,
                                     device->fix->speed / 3.6);
            }

            if (device->fix->fields & LOCATION_GPS_DEVICE_CLIMB_SET) {
                posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed,
                                     device->fix->climb);
            }

            if (device->fix->fields & LOCATION_GPS_DEVICE_TRACK_SET) {
                posInfo.setAttribute(QGeoPositionInfo::Direction,
                                     device->fix->track);
            }
        }

        if (device->satellites_in_view) {
            QList<QGeoSatelliteInfo> satsInView;
            QList<QGeoSatelliteInfo> satsInUse;
            unsigned int i;
            for (i = 0;i < device->satellites->len;i++) {
                LocationGPSDeviceSatellite *satData =
                    (LocationGPSDeviceSatellite *)g_ptr_array_index(device->satellites,
                            i);
                satInfo.setSignalStrength(satData->signal_strength);
                satInfo.setPrnNumber(satData->prn);
                satInfo.setAttribute(QGeoSatelliteInfo::Elevation,
                                     satData->elevation);
                satInfo.setAttribute(QGeoSatelliteInfo::Azimuth,
                                     satData->azimuth);

                satsInView.append(satInfo);
                if (satData->in_use) {
                    satellitesInUseCount++;
                    satsInUse.append(satInfo);
                }
            }

            if (!satsInView.isEmpty())
                object->satellitesInViewUpdated(satsInView);

            if (!satsInUse.isEmpty())
                object->satellitesInUseUpdated(satsInUse);
        }
    }

    posInfo.setCoordinate(coordinate);

    emit object->positionUpdated(posInfo);
}
예제 #19
0
void QGeoCodeReplyOsm::networkReplyFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError)
        return;

    QList<QGeoLocation> locations;
    QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());

    if (document.isObject()) {
        QJsonObject object = document.object();

        QGeoCoordinate coordinate;

        coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
        coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());

        QGeoLocation location;
        location.setCoordinate(coordinate);
        location.setAddress(parseAddressObject(object));

        locations.append(location);

        setLocations(locations);
    } else if (document.isArray()) {
        QJsonArray results = document.array();

        for (int i = 0; i < results.count(); ++i) {
            if (!results.at(i).isObject())
                continue;

            QJsonObject object = results.at(i).toObject();

            QGeoCoordinate coordinate;

            coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
            coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());

            QGeoRectangle rectangle;

            if (object.contains(QStringLiteral("boundingbox"))) {
                QJsonArray a = object.value(QStringLiteral("boundingbox")).toArray();
                if (a.count() == 4) {
                    rectangle.setTopLeft(QGeoCoordinate(a.at(1).toString().toDouble(),
                                                        a.at(2).toString().toDouble()));
                    rectangle.setBottomRight(QGeoCoordinate(a.at(0).toString().toDouble(),
                                                            a.at(3).toString().toDouble()));
                }
            }

            QGeoLocation location;
            location.setCoordinate(coordinate);
            location.setBoundingBox(rectangle);
            location.setAddress(parseAddressObject(object));
            locations.append(location);
        }

    }

    setLocations(locations);
    setFinished(true);

    m_reply->deleteLater();
    m_reply = 0;
}
예제 #20
0
void QGeoCodeReplyOsm::networkReplyFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError)
        return;

    QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());

    if (document.isObject()) {
        QJsonObject object = document.object();

        QGeoCoordinate coordinate;

        coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
        coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());

        QJsonObject ao = object.value(QStringLiteral("address")).toObject();

        QGeoAddress address;
        address.setText(object.value(QStringLiteral("display_name")).toString());
        address.setCountry(ao.value(QStringLiteral("country")).toString());
        address.setCountryCode(ao.value(QStringLiteral("country_code")).toString());
        address.setState(ao.value(QStringLiteral("state")).toString());
        address.setCity(ao.value(QStringLiteral("city")).toString());
        address.setDistrict(ao.value(QStringLiteral("suburb")).toString());
        address.setPostalCode(ao.value(QStringLiteral("postcode")).toString());
        address.setStreet(ao.value(QStringLiteral("road")).toString());

        QGeoLocation location;
        location.setCoordinate(coordinate);
        location.setAddress(address);

        QList<QGeoLocation> locations;
        locations.append(location);

        setLocations(locations);
        setFinished(true);
    } else if (document.isArray()) {
        QJsonArray results = document.array();

        QList<QGeoLocation> locations;

        for (int i = 0; i < results.count(); ++i) {
            if (!results.at(i).isObject())
                continue;

            QJsonObject object = results.at(i).toObject();

            QGeoCoordinate coordinate;

            coordinate.setLatitude(object.value(QStringLiteral("lat")).toString().toDouble());
            coordinate.setLongitude(object.value(QStringLiteral("lon")).toString().toDouble());

            QGeoRectangle rectangle;

            if (object.contains(QStringLiteral("boundingbox"))) {
                QJsonArray a = object.value(QStringLiteral("boundingbox")).toArray();
                if (a.count() == 4) {
                    rectangle.setTopLeft(QGeoCoordinate(a.at(1).toString().toDouble(),
                                                        a.at(2).toString().toDouble()));
                    rectangle.setBottomRight(QGeoCoordinate(a.at(0).toString().toDouble(),
                                                            a.at(3).toString().toDouble()));
                }
            }

            QJsonObject ao = object.value(QStringLiteral("address")).toObject();

            QGeoAddress address;
            address.setText(object.value(QStringLiteral("display_name")).toString());
            address.setCountry(ao.value(QStringLiteral("country")).toString());
            address.setCountryCode(ao.value(QStringLiteral("country_code")).toString());
            address.setState(ao.value(QStringLiteral("state")).toString());
            address.setCity(ao.value(QStringLiteral("city")).toString());
            address.setDistrict(ao.value(QStringLiteral("suburb")).toString());
            address.setPostalCode(ao.value(QStringLiteral("postcode")).toString());
            address.setStreet(ao.value(QStringLiteral("road")).toString());

            QGeoLocation location;
            location.setCoordinate(coordinate);
            location.setBoundingBox(rectangle);
            location.setAddress(address);
            locations.append(location);
        }

        setLocations(locations);
        setFinished(true);
    }

    m_reply->deleteLater();
    m_reply = 0;
}
예제 #21
0
void MapWidgetHelper::centerOnDiveSite(struct dive_site *ds)
{
	QVector<struct dive_site *> selDS;
	QVector<QGeoCoordinate> selGC;
	QGeoCoordinate dsCoord;

// selection of multiple dives is only possible on the desktop.
// in the case of the mobile version only handle the passed dive_site.
#ifndef SUBSURFACE_MOBILE
	int idx;
	struct dive *dive;
	for_each_dive (idx, dive) {
		struct dive_site *dss = get_dive_site_for_dive(dive);
		if (!dive_site_has_gps_location(dss) || !dive->selected)
			continue;
		// only store dive sites with GPS
		selDS.append(dss);
		selGC.append(QGeoCoordinate(dss->latitude.udeg * 0.000001,
		                            dss->longitude.udeg * 0.000001));
	}
#else
	if (dive_site_has_gps_location(ds)) {
		selDS.append(ds);
		selGC.append(QGeoCoordinate(ds->latitude.udeg * 0.000001,
		                            ds->longitude.udeg * 0.000001));
	}
#endif
	if (!dive_site_has_gps_location(ds) && !selDS.size()) {
		// only a single dive site with no GPS selected
		m_mapLocationModel->setSelectedUuid(ds ? ds->uuid : 0, false);
		QMetaObject::invokeMethod(m_map, "deselectMapLocation");

	} else if (selDS.size() == 1) {
		// a single dive site with GPS selected
		ds = selDS.at(0);
		m_mapLocationModel->setSelectedUuid(ds->uuid, false);
		dsCoord.setLatitude(ds->latitude.udeg * 0.000001);
		dsCoord.setLongitude(ds->longitude.udeg * 0.000001);
		QMetaObject::invokeMethod(m_map, "centerOnCoordinate", Q_ARG(QVariant, QVariant::fromValue(dsCoord)));
	} else if (selDS.size() > 1) {
		/* more than one dive sites with GPS selected.
		 * find the most top-left and bottom-right dive sites on the map coordinate system. */
		ds = selDS.at(0);
		m_mapLocationModel->setSelectedUuid(ds->uuid, false);
		qreal minLat = 0.0, minLon = 0.0, maxLat = 0.0, maxLon = 0.0;
		bool start = true;
		foreach(QGeoCoordinate gc, selGC) {
			qreal lat = gc.latitude();
			qreal lon = gc.longitude();
			if (start) {
				minLat = maxLat = lat;
				minLon = maxLon = lon;
				start = false;
				continue;
			}
			if (lat < minLat)
				minLat = lat;
			else if (lat > maxLat)
				maxLat = lat;
			if (lon < minLon)
				minLon = lon;
			else if (lon > maxLon)
				maxLon = lon;
		}
예제 #22
0
void QGeoCodeReplyQGC::networkReplyFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError)
        return;

    QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
    QJsonObject object = document.object();

    if (object.value(QStringLiteral("status")) != QStringLiteral("OK")) {
        QString error = object.value(QStringLiteral("status")).toString();
        qWarning() << m_reply->url() << "returned" << error;
        setError(QGeoCodeReply::CommunicationError, error);
        m_reply->deleteLater();
        m_reply = 0;
        return;
    }

    QList<QGeoLocation> locations;
    QJsonArray results = object.value(QStringLiteral("results")).toArray();
    for (int i=0; i<results.size(); ++i) {
        if (!results[i].isObject())
            continue;

        QJsonObject geocode = results[i].toObject();

        QGeoAddress address;
        if (geocode.contains(QStringLiteral("formatted_address"))) {
            address.setText(geocode.value(QStringLiteral("formatted_address")).toString());
        }


        if (geocode.contains(QStringLiteral("address_components"))) {
            QJsonArray ac = geocode.value(QStringLiteral("address_components")).toArray();

            for (int j=0; j<ac.size(); ++j) {
                if (!ac[j].isObject())
                    continue;

                QJsonObject c = ac[j].toObject();
                if (!c.contains(QStringLiteral("types")))
                    continue;

                QSet<int> types = kMonger.json2QGCGeoCodeType(c[QStringLiteral("types")].toArray());
                QString long_name = c[QStringLiteral("long_name")].toString();
                QString short_name = c[QStringLiteral("short_name")].toString();
                if (types.contains(Country)) {
                    address.setCountry(long_name);
                    address.setCountryCode(short_name);
                } else if (types.contains(AdministrativeAreaLevel1)) {
                    address.setState(long_name);
                } else if (types.contains(AdministrativeAreaLevel2)) {
                    address.setCounty(long_name);
                } else if (types.contains(Locality)) {
                    address.setCity(long_name);
                } else if (types.contains(Sublocality)) {
                    address.setDistrict(long_name);
                } else if (types.contains(PostalCode)) {
                    address.setPostalCode(long_name);
                } else if (types.contains(StreetAddress) || types.contains(Route) || types.contains(Intersection)) {
                    address.setStreet(long_name);
                }
            }
        }

        QGeoCoordinate coordinate;
        QGeoRectangle boundingBox;
        if (geocode.contains(QStringLiteral("geometry"))) {
            QJsonObject geom = geocode.value(QStringLiteral("geometry")).toObject();
            if (geom.contains(QStringLiteral("location"))) {
                QJsonObject location = geom.value(QStringLiteral("location")).toObject();
                coordinate.setLatitude(location.value(QStringLiteral("lat")).toDouble());
                coordinate.setLongitude(location.value(QStringLiteral("lng")).toDouble());
            }
            if (geom.contains(QStringLiteral("bounds"))) {
                QJsonObject bounds = geom.value(QStringLiteral("bounds")).toObject();
                QJsonObject northeast = bounds.value(QStringLiteral("northeast")).toObject();
                QJsonObject southwest = bounds.value(QStringLiteral("southwest")).toObject();
                QGeoCoordinate topRight(northeast.value(QStringLiteral("lat")).toDouble(),
                                        northeast.value(QStringLiteral("lng")).toDouble());
                QGeoCoordinate bottomLeft(southwest.value(QStringLiteral("lat")).toDouble(),
                                          southwest.value(QStringLiteral("lng")).toDouble());
                boundingBox.setTopRight(topRight);
                boundingBox.setBottomLeft(bottomLeft);
            }
        }

        QGeoLocation location;
        location.setAddress(address);
        location.setCoordinate(coordinate);
        location.setBoundingBox(boundingBox);

        locations << location;
    }

    setLocations(locations);
    setFinished(true);

    m_reply->deleteLater();
    m_reply = 0;
}
예제 #23
0
bool QLandmarkFileHandlerLmx::readCoordinates(QLandmark &landmark)
{
    /*
    <xsd:complexType name="coordinatesType">
        <xsd:sequence>
            <xsd:element name="latitude">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:double">
                        <xsd:minInclusive value="-90"/>
                        <xsd:maxInclusive value="90"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
            <xsd:element name="longitude">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:double">
                        <xsd:minInclusive value="-180"/>
                        <xsd:maxExclusive value="180"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
            <xsd:element name="altitude" type="xsd:float" minOccurs="0" />
            <xsd:element name="horizontalAccuracy" minOccurs="0">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:float">
                        <xsd:minInclusive value="0"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
            <xsd:element name="verticalAccuracy" minOccurs="0">
                <xsd:simpleType>
                    <xsd:restriction base="xsd:float">
                        <xsd:minInclusive value="0"/>
                    </xsd:restriction>
                </xsd:simpleType>
            </xsd:element>
            <xsd:element name="timeStamp" type="xsd:dateTime" minOccurs="0" />
        </xsd:sequence>
    </xsd:complexType>
    */

    Q_ASSERT(m_reader->isStartElement() &&
             (m_reader->name() == "coordinates"));

    if (!m_reader->readNextStartElement()) {
        m_reader->raiseError("The element \"coordinates\" did not have the required child element \"latitude\".");
        return false;
    }

    if (m_reader->name() == "latitude") {
        bool ok = false;
        QString s = m_reader->readElementText();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The element \"latitude\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double lat = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The element \"latitude\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        if (lat < -90.0 || 90.0 < lat) {
            m_reader->raiseError(QString("The element \"latitude\" fell outside of the bounds -90.0 <= latitude <= 90.0 (value was \"%1\").").arg(s));
            return false;
        }

        QGeoCoordinate coord = landmark.coordinate();
        coord.setLatitude(lat);
        landmark.setCoordinate(coord);

        if (!m_reader->readNextStartElement()) {
            m_reader->raiseError("The element \"coordinates\" did not have the required child element \"longitude\".");
            return false;
        }
    } else {
        m_reader->raiseError("The element \"coordinates\" did not have the required child element \"latitude\".");
        return false;
    }

    if (m_reader->name() == "longitude") {
        bool ok = false;
        QString s = m_reader->readElementText();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The element \"longitude\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double lon = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The element \"longitude\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        if (lon < -180.0 || 180.0 <= lon) {
            m_reader->raiseError(QString("The element \"longitude\" fell outside of the bounds -180.0 <= longitude < 180.0 (value was \"%1\").").arg(s));
            return false;
        }

        QGeoCoordinate coord = landmark.coordinate();
        coord.setLongitude(lon);
        landmark.setCoordinate(coord);

        if (!m_reader->readNextStartElement())
            return true;
    } else {
        m_reader->raiseError("The element \"coordinates\" did not have the required child element \"longitude\".");
        return false;
    }

    if (m_reader->name() == "altitude") {
        bool ok = false;
        QString s = m_reader->readElementText();

        if ((s == "INF") || (s == "-INF") || (s == "NaN")) {
            m_reader->raiseError(QString("The element \"altitude\" expected a value convertable to type double (value was \"%1\").").arg(s));
            return false;
        }

        double alt = s.toDouble(&ok);

        if (!ok) {
            m_reader->raiseError(QString("The element \"altitude\" expected a value convertable to type float (value was \"%1\").").arg(s));
            return false;
        }

        QGeoCoordinate coord = landmark.coordinate();
        coord.setAltitude(alt);
        landmark.setCoordinate(coord);

        if (!m_reader->readNextStartElement())
            return true;
    }

    QList<QString> names;
    names << "horizontalAccuracy";
    names << "verticalAccuracy";
    names << "timeStamp";

    for (int i = 0; i < names.size(); ++i) {
        // Not used outside of schema compliance check
        if (m_reader->name() == names.at(i)) {
           m_reader->skipCurrentElement();
           if (!m_reader->readNextStartElement())
               return true;
        }
    }

    m_reader->raiseError(QString("The element \"coordinate\" did not expect a child element named \"%1\" at this point (unknown child element or child element out of order).").arg(m_reader->name().toString()));
    return false;
}