Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [SOLVED] Custom NonSattelite PositionSource
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Custom NonSattelite PositionSource

Scheduled Pinned Locked Moved QML and Qt Quick
13 Posts 4 Posters 6.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    cmer4
    wrote on last edited by
    #1

    Hi folks.

    Some of you aware that QML's PositionSource has got some issues currently with positioning indoors (http://bugreports.qt.nokia.com/browse/QTMOBILITY-1550 FYI). This will be possibly fixed by making methods writable from QML (http://bugreports.qt.nokia.com/browse/QTMOBILITY-1631) approx since Qt Mobility 1.3

    But since I have no time to wait for QtM 1.3 I would like to make it clear for myself is it possible to do a Qt C++ based snippet and expose it to QML which will be purely non-sattelite position method?

    I mean something like add to main.cpp a snippet of code with QGeoPositionInfoSource being set to nonsat method (via QGeoPositionInfoSource::setPreferredPositioningMethods) and make it "callable" from within QML? just like if it would be the PositionSource element that only works with non-sattelite method. (I hope I explained it clear enough:)

    Fact is - for me and many other developers GPS based methods are less important than non-GPS - as in many cases people use the apps indoors OR the precision of their location is not required to be a few meters (ok to have 1000m radius even)

    Please advise?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      conny
      wrote on last edited by
      #2

      I'm not exactly sure I understand what you're trying to do. But it's easy to create you own QGeoPositionInfoSource and use that from C++. Then you can expose the calculated position to QML.

      However that would mean you have to write you own positioning logic. Not sure that's what you want :)

      1 Reply Last reply
      0
      • C Offline
        C Offline
        cmer4
        wrote on last edited by
        #3

        Thanks Conny, I think you answered that...so in theory I am able to create my own nonsattelite source in C++ and expose the position to QML...

        My goal is to make geolocation available based on non-satellite method only since it is faster and precision is ok for the task...

        1 Reply Last reply
        0
        • C Offline
          C Offline
          conny
          wrote on last edited by
          #4

          Yes you can. But as I said, you then have to implement the source yourself. Where are you getting the non-satellite data from?

          1 Reply Last reply
          0
          • C Offline
            C Offline
            cmer4
            wrote on last edited by
            #5

            Hi Conny, not sure I quite understand what you mean by implement source?

            Current plan is:

            • take source code snippet from this example http://developer.qt.nokia.com/wiki/Retrieve_Location_Using_Qt_Mobility
            • find the way how to expose to QML the location data (latitude, longitude)

            SO eventually I should have longitude and latitude data available with updates in QML from non-sat source, isn't it?:)

            1 Reply Last reply
            0
            • C Offline
              C Offline
              cmer4
              wrote on last edited by
              #6

              Hmm, I had implemented the Qt C++ code from the examples, I learned a bit on how to expose Qt C++ data to QML, but seems I am not quite there to do it properly...

              The code in C++ actually "loads" data into m_pLabel (below)

              @QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
              qreal latitude = geoCoordinate.latitude();
              qreal longitude = geoCoordinate.longitude();

                  m_pLabel->setText( QString("Latitude: %1 \n Longitude: %2").arg(latitude).arg(longitude) );@
              

              But how can I refer to this text in C++ to get it passed as ContextProperty to QML??

              @QmlApplicationViewer viewer;
              viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockPortrait);
              viewer.rootContext()->setContextProperty("currentDateTime",m_pLabel.text );@

              What should be there in the code instead of m_pLabel.text?

              I know I am naive trying to apply QML approach;) Please help!

              1 Reply Last reply
              0
              • K Offline
                K Offline
                kkrzewniak
                wrote on last edited by
                #7

                A QObject subclass instance exposing the text via a property with a proper notify signal :P

                Me, Grimlock, not "nice dino". ME BASH BRAINS!

                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  cmer4
                  wrote on last edited by
                  #8

                  Hmm what do you mean?
                  Sorry I only started C++ "induction" :(

                  I got the idea - I need to set a NOTIFY property and signal for an object.
                  But what would be the best solution here - to create a new QObject, somehow pass to it the location data from the m_pLabel and then expose to QML??

                  [EDIT: fixed smiley that made "induction" a link :-), Volker]

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    kkrzewniak
                    wrote on last edited by
                    #9

                    You don't need the label at all.

                    Write your own QObject subclass, expose a QString(if you want the data to be exposed as text) property with READ and NOTIFY. And make sure to emit your NOTIFY signal whenever the value changes.

                    Just create an instance of your class and expose to QML as a context property.

                    "Exchanging data between QML and C++":http://developer.qt.nokia.com/doc/qt-4.7/qtbinding.html#id-1b3a8b62-0fb5-44c3-b68b-ee1cbf29d0c3

                    Me, Grimlock, not "nice dino". ME BASH BRAINS!

                    1 Reply Last reply
                    0
                    • C Offline
                      C Offline
                      cmer4
                      wrote on last edited by
                      #10

                      Thanks a lot;) !

                      I will try to post my code hereto for the others and put SOLVED afterwards

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        cmer4
                        wrote on last edited by
                        #11

                        Kkrzewniak, many thanks for your help, could you please validate the code a bit (I guess I am still missing the part with emiting signal and also seems like I haven't yet added important chunk of the code to the CPP file...

                        Header:

                        @class NonSatCoordsSource : public QObject
                        {
                        Q_OBJECT
                        Q_PROPERTY (QString text READ text WRITE setText NOTIFY textChanged)
                        public:
                        void positionUpdated(QGeoPositionInfo geoPositionInfo);
                        private:
                        void startLocationAPI();
                        QGeoPositionInfoSource* m_pLocationInfo;
                        QString* m_pString;
                        signals:
                        void textChanged();
                        };@

                        I declared the class and made one property there which could be read/written and notified.
                        I also declared the functions (at least I hope I did it correctly)

                        Now in CPP part I need to expose the class and describe these functions as I get it:

                        @NonSatCoordsSource::NonSatCoordsSource(QObject *parent) : m_pLocationInfo(NULL), m_pString(NULL)

                        NonSatCoordsSource::~NonSatCoordsSource()
                        {

                        }

                        void NonSatCoordsSource::startLocationAPI()
                        {
                        if (!m_pLocationInfo)
                        {
                        m_pLocationInfo =
                        QGeoPositionInfoSource::createDefaultSource(this);
                        m_pLocationInfo->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
                        connect(m_pLocationInfo, SIGNAL(positionUpdated(QGeoPositionInfo)),
                        this, SLOT(positionUpdated(QGeoPositionInfo)));
                        m_pLocationInfo->startUpdates();
                        }
                        }

                        void NonSatCoordsSource::positionUpdated(QGeoPositionInfo geoPositionInfo)
                        {
                        if (geoPositionInfo.isValid())
                        {
                        QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
                        qreal latitude = geoCoordinate.latitude();
                        qreal longitude = geoCoordinate.longitude();
                        m_pString->setText( QString("Lat: %1 Long: %2").arg(latitude).arg(longitude) );
                        }
                        }@

                        This is where I stuck basically for now just reading C++ for dummies further...But feels like I am close enough?:)

                        1 Reply Last reply
                        0
                        • C Offline
                          C Offline
                          cmer4
                          wrote on last edited by
                          #12

                          Here is the solution and final "code" (sorry if it is not high class code though as I only started to learn Qt). So basically I am able to turn it on off using nonsatdata.enable(), I can "read" the coordinates from within QML via nonsatdata.lat and nonsatdata.lon...

                          The problem I have below is that the signals are not working/firing off (onLatChanged and onLonChanged ) ;(
                          I kind of feel what the problem is but can't fix it...so any help is very appreciated!

                          1. Qml:

                          @import NonSatLocation 1.0
                          ...
                          NonSatLocation { // defined in nonsat.cpp & h, exposed to qml as a type
                          id: nonsatdata
                          onLatChanged: { console.log("signal nonsatdata.lat")}
                          onLonChanged: { console.log("signal nonsatdata.lon")}
                          }
                          @

                          1. main.cpp:

                          @...
                          qmlRegisterType<NonSatLocation> ("NonSatLocation", 1,0, "NonSatLocation");
                          ...@

                          1. nonsat.h:
                            @class NonSatLocation : public QObject
                            {
                            Q_OBJECT
                            Q_PROPERTY (double lat READ lat WRITE setLat NOTIFY latChanged)
                            Q_PROPERTY (double lon READ lon WRITE setLon NOTIFY lonChanged)

                          public:
                          NonSatLocation (QObject *parent = 0);
                          double lat () const {return m_lat;}
                          double lon () const {return m_lon;}
                          void setLat (double &lat)
                          {
                          m_lat = lat;
                          emit latChanged();
                          }
                          void setLon (double &lon)
                          {
                          m_lon = lon;
                          emit lonChanged();
                          }

                          Q_INVOKABLE void enable();
                          Q_INVOKABLE void disable();
                          

                          signals:
                          void latChanged();
                          void lonChanged();

                          private slots:
                          void positionUpdated(const QGeoPositionInfo &info);

                          private:
                          double m_lat;
                          double m_lon;
                          QGeoPositionInfoSource *source;
                          };@

                          1. nonsat.cpp:

                          @NonSatLocation::NonSatLocation (QObject *parent)
                          : QObject (parent)
                          {
                          source = QGeoPositionInfoSource::createDefaultSource(this);
                          if (source) {
                          source->setUpdateInterval(3000); // time in milliseconds
                          source->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
                          }
                          }

                          void NonSatLocation::enable()
                          {
                          if (source) {
                          connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
                          this, SLOT(positionUpdated(QGeoPositionInfo)));
                          source->startUpdates();
                          }
                          }
                          void NonSatLocation::disable()
                          {
                          if (source) {
                          source->stopUpdates();
                          disconnect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
                          this, SLOT(positionUpdated(QGeoPositionInfo)));
                          }
                          }
                          void NonSatLocation::positionUpdated(const QGeoPositionInfo &info)
                          {
                          if (info.isValid()) {

                              qDebug() << info.coordinate();
                              QGeoCoordinate geoCoordinate = info.coordinate();
                              double latitude = geoCoordinate.latitude();
                              double longitude = geoCoordinate.longitude();
                              m_lat = latitude;
                              m_lon = longitude;
                          }
                          

                          }@

                          1 Reply Last reply
                          0
                          • H Offline
                            H Offline
                            Hassan Kassem
                            wrote on last edited by
                            #13

                            Yes you are missing one more think:
                            instead of:
                            @m_lat = latitude;
                            m_lon = longitude;@
                            you should use your methods that call signals i.e :
                            @setLat(latitude);
                            setLon(longitude);@
                            And that's it, it works !!!
                            By the way thanks for sharing your code :)

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved