Monday, April 21, 2014

Adding Interactivity to a Map with Popovers

On Friday I started my app "GetThereDC". I started by adding the locations of all of the Bikeshare stations in DC to a map. Knowing where the stations are is great, but it's a bummer when you go to a station and there are no bikes, or there are no empty parking spots. Fortunately, that exact information is in the XML feed, so I just need a way to display it.  
The way I decided to do it is to make the POI (the little icons for each station on the map) clickable, and when the user clicks the POI to use the Popover feature in the Ubuntu Components toolkit to display the data.

Make the POI Clickable

When you want to make anyting "clickable" in QML, you just use a MouseArea component. Remember that each POI is constructed as a delegate in the MapItemView as an Image component. So all I have to do is add a MouseArea inside the Image and respond to the Click event. So, not my image looks like this:
           sourceItem: Image  
           {  
             id: poiImage  
             width: units.gu(2)  
             height: units.gu(2)  
             source: "images/bike_poi.png"  
             MouseArea  
             {  
               anchors.fill: parent  
               onClicked:  
               {  
                 print("The POI was clicked! ")  
               }  
             }  
           }  
This can be used anywhere in QML to make an image respond to a click. MouseArea, of course, has other useful events as well, for things like onPressed, onPressAndHold, etc...

Add the Roles to the XmlListModel

I already know that I'll want something to use for a title for each station, the address, as well as the number of bikes and the number of parking slots. Looking at the XML I can see that the "name" property is the address, so that's a bonus. Additionally, I can see the other properties I want are called "nbBikes" and "nbEmptyDocks". So, all I do is add those three new roles to the XmlListModel that I constructed before:
   XmlListModel  
   {  
     id: bikeStationModel  
     source: "https://www.capitalbikeshare.com/data/stations/bikeStations.xml"  
     query: "/stations/station"  
     XmlRole { name: "lat"; query: "lat/string()"; isKey: true }  
     XmlRole { name: "lng"; query: "long/string()"; isKey: true }  
     XmlRole {name: "name"; query: "name/string()"; isKey: true}  
     XmlRole {name: "available"; query: "nbBikes/string()"; isKey: true}  
     XmlRole {name: "freeSlots"; query: "nbEmptyDocks/string()"; isKey: true}  
   }  

Make a Popover Component

The Ubuntu SDK offers some options for displaying additional information. In old school applications these might be dialog boxes, or message boxes. For the purposes of this app, Popover looks like the best bet. I suspect that over time the popover code might get a little complex, so I don't want it to be too deeply nested inside the MapItemView, as the code will become unwieldy. So, instead I decided to add a file called BikeShareStationPopover.qml to the components sub-directory. Then I copy and pasted the sample code in the documentation to get started. 

To make a popover, you start with a Component tag, and then add a popover tag inside that. Then, you can put pretty much whatever you want into that Popover. I am going to go with a Column and use ListItem components because I think it will look nice, and it's the easiest way to get started. Since I already added the XmlRoles I'll just use those roles in the construction of each popover. 

Since I know that I will be adding other kinds of POI, I decided to add a Capital Bike Share logo to the top of the list so users will know what kind of POI they clicked. I also added a close button just to be certain that users don't get confused about how to go back to the map. So, at the end of they day, I just have a column with ListItems:
 import QtQuick 2.0  
 import Ubuntu.Components 0.1  
 import Ubuntu.Components.ListItems 0.1 as ListItem  
 import Ubuntu.Components.Popups 0.1  
 Component  
 {  
   id: popoverComponent  
   Popover  
   {  
     id: popover  
     Column  
     {  
       id: containerLayout  
       anchors  
       {  
         left: parent.left  
         top: parent.top  
         right: parent.right  
       }  
       ListItem.SingleControl  
       {  
         control: Image  
         {  
           source: "../images/CapitalBikeshare_Logo.jpg"  
           height: units.gu(5)  
           width: units.gu(5)  
         }  
       }  
       ListItem.Header { text: name}  
       ListItem.Standard { text: available + " bikes available" }  
       ListItem.Standard { text: freeSlots + " parking spots available"}  
       ListItem.SingleControl  
       {  
         highlightWhenPressed: false  
         control: Button  
         {  
           text: "Close"  
           onClicked: PopupUtils.close(popover)  
         }  
     }  
   }  
 }  

Make the Popover Component Appear on Click

So, now that I made the component code, I just need to add it to the MapItemView and make it appear on click. So, I add the tag and give it an id to the MapQuickItem Delegate, and change the onClicked handler for the MouseArea to open the popover:
 delegate: MapQuickItem  
         {  
           id: poiItem  
           coordinate: QtPositioning.coordinate(lat,lng)  
           anchorPoint.x: poiImage.width * 0.5  
           anchorPoint.y: poiImage.height  
           z: 9  
           sourceItem: Image  
           {  
             id: poiImage  
             width: units.gu(2)  
             height: units.gu(2)  
             source: "images/bike_poi.png"  
             MouseArea  
             {  
               anchors.fill: parent  
               onClicked:  
               {  
                 PopupUtils.open(bikeSharePopover)  
               }  
             }  
           }  
           BikeShareStationPopover  
           {  
             id: bikeSharePopover  
           }  
         }  
And when I run the app, I can click on any POI and see the info I want! Easy!

Code is here

20 comments:

  1. Rick do you happen to know any website that offers the XML data for Movie Theatre locations in the world? I would love to add this functionality to my app Flashback.

    ReplyDelete
    Replies
    1. Big data is a term that describes the large volume of data – both structured and unstructured – that inundates a business on a day-to-day basis. big data projects for students But it’s not the amount of data that’s important.Project Center in Chennai

      Python Training in Chennai Python Training in Chennai The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training Project Centers in Chennai

      Delete
  2. So nice and great blog post it's also helpful information all of us so thanks a lot for sharing this tips with us
    clipping path service

    ReplyDelete
  3. This is a great post. i have more benefited from your website. thanks a lot for your performative idea
    clipping path service provider

    ReplyDelete
  4. Wow what a Great Information about World Day its very nice informative post. thanks for the post. https://view.ly/v/I6i2zHGxK4JY

    ReplyDelete
  5. I love this blog!! The flash up the top is awesome!! https://view.ly/v/anmlDCHg1JGS

    ReplyDelete
  6. If you are stuck with your marketing assignment then in this case you can opt for our Marketing Assignments. we provide the bestOnline marketing expert.We also provide Marketing Management Assignment for students across the globe. for more information contact us +16692714848.


    ReplyDelete
  7. All the articles here are informative. It is beneficial to the newcomers. Thanks for posting such a
    nice post.
    Clipping Path
    Image Masking Service

    ReplyDelete
  8. Do you find
    coursework help
    in AE ? we are running a e learning platform myassignmenthelp.com where we help all types of students to complete thier assignment and college works

    ReplyDelete
  9. click on one of the sites below to get a variety of the best tips and tricks in life.

    situs togel terpercaya

    ReplyDelete
  10. High emphasis on the design to improve the boating structure though multi-hulls and enhance travelling speed with over 20 nautical miles are expected to be among the prominent features fuelling the catamarans market growth.

    ReplyDelete
  11. Choose assignment help Service in New Zealand to buy the assistance of academic writing. Online Assignment Help connects you with professional writers so you can get requisite help for your Assignment.

    ReplyDelete
  12. We are providing CDR Writers Australia. If anybody requires to get CDR For Australia Immigration for successful visa migration approval in Australia, communicate with our experts and visit our website CDRAustralia.Org.
    Mail us at:Contact@CDRAustralia.Org.

    Our other Services:
    RPL Writing Services
    NER work experience statement
    Competency Based Assessment For Papua New Guinea
    RPEQ Australia
    IPENZ New Zealand
    P.Eng ( Canada) Competency Report Writing

    ReplyDelete
  13. At British Dissertation Consultations, our Accounting dissertation writing experts offer competent and expedited accounting dissertation help at British Dissertation Consultants in the UK.

    ReplyDelete
  14. With British Dissertation Consultants, you can manage and accomplish your Ph.D. Dissertation writing services with researchers published in internationally recognized journals.

    ReplyDelete