Street Watch is geo service application for Ubuntu touch developed using qml. Here you can search for famous venues near a given place. This app searches for places in 12 different categories.
1. Restaurant
2. Cafe
3. Bar
4. Shops
5. Arts
6. Museum
7. ATM
8. Park
9. Zoo
10. Movie
11. Night Club
12. Doctor
This app is your perfect companion when you are on a vacation or trying to figure out which places to visit on a vacation.
This app returns the result based on the importance of the place. Ex: A famous restaurant will appear first.
This app gives the address, latitude, longitude of the place
This app even shows the location of the place on a map.
Source Code:
import QtQuick 2.0
import QtLocation 5.0
import QtQuick.XmlListModel 2.0
import Ubuntu.Components 0.1
import Ubuntu.Components.Popups 0.1
import Ubuntu.Components.Extras.Browser 0.1
import "components"
import "icons"
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
id: root
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "com.ubuntu.developer.karthik.upadya1.streetwatch"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
property string secondaryTitle: ""
property string latlng: ""
property bool validated: false
property bool geocoded: false
property int typeNum: -1
property string selectedType: ""
property string cName: ""
property string vicinity: ""
property string latitude: ""
property string longitude: ""
function getSelectedType () {
switch(root.typeNum) {
case 0: root.selectedType = "restaurant";
break;
case 1: root.selectedType = "cafe";
break;
case 2: root.selectedType = "bar";
break;
case 3: root.selectedType = "shopping_mall";
break;
case 4: root.selectedType = "art_gallery";
break;
case 5: root.selectedType = "museum";
break;
case 6: root.selectedType = "atm";
break;
case 7: root.selectedType = "park";
break;
case 8: root.selectedType = "zoo";
break;
case 9: root.selectedType = "movie_theater";
break;
case 10: root.selectedType = "night_club";
break;
case 11: root.selectedType = "doctor";
break;
}
}
backgroundColor: "#222930"
width: units.gu(40)
height: units.gu(75)
PageStack {
id: pageStack
Component.onCompleted: {
push(mainPage)
}
Page {
id: mainPage
title: i18n.tr("Street Watch")
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
Row {
id: line1
spacing: units.gu(2)
TextField {
id: cityName
color: UbuntuColors.orange
placeholderText: "Enter city name"
width: root.width * 0.6
onTextChanged: {
if (cityName.text.length == 0 || root.validated) {
root.latlng = "";
root.geocoded = false;
root.validated = false;
}
}
}
Button {
text: i18n.tr("Find")
onClicked: {
if (cityName.text.length > 0) {
root.validated = true;
}
else {
PopupUtils.open(dialog, null);
}
}
}
Component {
id: dialog
Dialog {
id: dialogue
title: i18n.tr("Please enter city name")
Button {
text: i18n.tr("OK")
onClicked: PopupUtils.close(dialogue)
}
}
}
}
Row {
id: line4
spacing: units.gu(2)
Label {
id: resultText
fontSize: "large"
color: "#4EB1BA"
text: qsTr("Categories")
}
ActivityIndicator {
id: activity
running: (root.validated) && (geoCodeData.status === XmlListModel.Loading)
Text {
id: activityText
anchors.centerIn: activity
color: "#4EB1BA"
text: (activity.running) ? qsTr("\t\tLoading. Please wait!") : ""
}
}
Text {
color: "#4EB1BA"
text: (geoCodeData.status === XmlListModel.Error) ? qsTr("Error loading data.") : ""
}
}
Row {
id: line2
spacing: units.gu(2)
width: root.width
ListModel {
id: menus
ListElement {
name: "Restaurant"
icon: "icons/restaurant-71.png"
}
ListElement {
name: "Cafe"
icon: "icons/cafe-71.png"
}
ListElement {
name: "Bar"
icon: "icons/bar-71.png"
}
ListElement {
name: "Shops"
icon: "icons/generic_business-71.png"
}
ListElement {
name: "Arts"
icon: "icons/art_gallery-71.png"
}
ListElement {
name: "Museum"
icon: "icons/museum-71.png"
}
ListElement {
name: "ATM"
icon: "icons/atm-71.png"
}
ListElement {
name: "Park"
icon: "icons/camping-71.png"
}
ListElement {
name: "Zoo"
icon: "icons/zoo-71.png"
}
ListElement {
name: "Movies"
icon: "icons/movies-71.png"
}
ListElement {
name: "Night Club"
icon: "icons/Night_Club-71.png"
}
ListElement {
name: "Doctor"
icon: "icons/doctor-71.png"
}
}
GridView {
id: gridView
width: root.width
height: units.gu(60)
cellWidth: root.width * 0.3
cellHeight: root.height * 0.16
currentIndex: -1
Component {
id: gridDelegate
Item {
id: wrapper
width: root.width * 0.3
height: gridView.cellHeight
UbuntuShape {
anchors.fill: wrapper
color: "#4EB1BA"
}
Image {
source: icon
anchors {
fill: wrapper
topMargin: units.gu(2)
rightMargin: units.gu(2)
leftMargin: units.gu(2)
bottomMargin: units.gu(2)
}
fillMode: Image.PreserveAspectFit
}
Text {
color: "#E9E9E9"
text: name
anchors.horizontalCenter: wrapper.horizontalCenter
anchors.bottom: wrapper.bottom
}
}
}
model: menus
delegate: gridDelegate
focus: true
onCurrentIndexChanged: {
if (cityName.text.length > 0 && root.geocoded && root.latlng.length > 2 && gridView.currentIndex >= 0) {
root.typeNum = currentIndex;
root.getSelectedType();
pageStack.push(secondaryPage, { title: menus.get(currentIndex).name });
}
else if(gridView.currentIndex >= 0){
PopupUtils.open(dialog2, null);
}
gridView.currentIndex = -1;
}
MouseArea {
id: gridArea
anchors.fill: parent
preventStealing: true
property int index: gridView.indexAt(mouseX, mouseY)
onClicked: {
gridView.currentIndex = gridArea.index;
}
}
Component {
id: dialog2
Dialog {
id: dialogue2
title: i18n.tr("Error!")
text: {
if (cityName.text.length == 0) {
i18n.tr("Please enter city name");
}
else {
i18n.tr("Unable to find your location.\nPlease use nearby area for searching.")
}
}
Button {
text: i18n.tr("OK")
onClicked: PopupUtils.close(dialogue2)
}
}
}
}
}
}
tools: ToolbarItems {
ToolbarButton {
id: actionsButton
text: "Options"
iconSource: "icons/option.png"
onTriggered: PopupUtils.open(actionSelectionPopover, actionsButton)
visible: true
}
locked: false
opened: true
}
Item {
Component {
id: actionSelectionPopover
ActionSelectionPopover {
actions: ActionList {
Action {
text: i18n.tr("About me")
onTriggered: PopupUtils.open(defaultSheet, null)
}
Action {
text: i18n.tr("Quit")
onTriggered: Qt.quit()
}
}
}
}
}
Component {
id: defaultSheet
DefaultSheet {
id: aboutme
title: i18n.tr("About me")
Label {
anchors.fill: parent
color: UbuntuColors.orange
fontSize: "small"
wrapMode: Text.WordWrap
text: "Developed by: <b>KARTHIK</b><br/>" +
"Tested by: <b>KARTHIK</b><br/>" +
"Email: <b>karthik.upadya1@gmail.com</b><br/>" +
"Country: <b>INDIA</b><br/>" +
"This is Geo service application designed for Ubuntu and Ubuntu Touch.<br/>" +
"Please mail me to get source code.<br/>" +
"Please give credit to me if you use this application as part of your project.<br/>" +
"<b>Check out my other apps \"Daily Karma\" and \"Weather Forecast\"</b><br/>"+
"If you have android device you can download my apps from SlideMe.<br/>"+
"1. Bumpy Adventures I<br/>2. Dude! Escape<br/>3. Auto Call Blocker<br/>4. Snake<br/>5. Millenium alien<br/>"+
"My developer name in the site is \"developerKASS013\" Thanks :)"
}
}
}
XmlListModel {
id: geoCodeData
source: {
if (root.validated) {
"https://maps.googleapis.com/maps/api/geocode/xml?address=" + cityName.text + "&sensor=false";
}
else {
"";
}
}
query: "/GeocodeResponse/result"
XmlRole { name: "Lat"; query: "geometry/location/lat/string()" }
XmlRole { name: "Lng"; query: "geometry/location/lng/string()" }
onStatusChanged: {
if (status === XmlListModel.Ready) {
root.latlng = get(0).Lat + "," + get(0).Lng
if (root.latlng.length > 2) {
root.geocoded = true;
}
}
else {
root.latlng = "NO";
}
}
}
}
Page {
id: secondaryPage
property alias title: secondaryPage.title
visible: false
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
Row {
id: sline1
spacing: units.gu(2)
width: root.width
visible: true
OptionSelector {
id: nearselect
width: root.width * 0.88
expanded: true
selectedIndex: -1
model: placesnear
delegate: placesnearDelegate
containerHeight: itemHeight * 7
onSelectedIndexChanged: {
root.cName = placesnear.get(nearselect.selectedIndex).Name;
root.vicinity = placesnear.get(nearselect.selectedIndex).Address
root.latitude = placesnear.get(nearselect.selectedIndex).Latitude
root.longitude = placesnear.get(nearselect.selectedIndex).Longitude
root.latlng = root.latitude + "," + root.longitude
PopupUtils.open(dialog3, null)
nearselect.selectedIndex = -1;
}
}
ActivityIndicator {
id: activity2
running: (placesnear.status === XmlListModel.Loading)
Text {
id: activityText2
anchors.centerIn: activity2
color: "#4EB1BA"
text: (activity2.running) ? qsTr("\t\tLoading. Please wait!") : ""
}
}
Text {
color: "#4EB1BA"
text: (placesnear.status === XmlListModel.Error) ? qsTr("Error loading data.") : ""
}
}
Component {
id: dialog3
Dialog {
id: dialogue3
title: i18n.tr("Details")
text: root.cName + "\n" +
root.vicinity + "\n" +
"Latitude: " + root.latitude + "\n" +
"Longitude: " + root.longitude
Button {
text: i18n.tr("View on map")
onClicked: {
PopupUtils.close(dialogue3)
pageStack.push(mapPage, null)
}
}
Button {
text: i18n.tr("Back to list")
onClicked: PopupUtils.close(dialogue3)
}
}
}
}
XmlListModel {
id: placesnear
source: "https://maps.googleapis.com/maps/api/place/nearbysearch/xml" +
"?key=AIzaSyBIBbmCktqpdALis32jSCGr-UlXcuCeU8Q&sensor=false&location=" + root.latlng +
"&rankby=distance&types=" + root.selectedType
query: "/PlaceSearchResponse/result"
XmlRole { name: "Name"; query: "name/string()" }
XmlRole { name: "Address"; query: "vicinity/string()" }
XmlRole { name: "Latitude"; query: "geometry/location/lat/string()" }
XmlRole { name: "Longitude"; query: "geometry/location/lng/string()" }
}
Component {
id: placesnearDelegate
OptionSelectorDelegate {
Text {
width: root.width * 0.8
elide: Text.ElideRight
wrapMode: Text.WordWrap
color: "#4EB1BA"
text: {
i18n.tr("\n " + model.Name);
}
}
}
}
}
Page {
id: mapPage
title: i18n.tr("Map")
visible: false
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
UbuntuWebView {
id: webview
url: "https://maps.google.com/?q=" + root.latlng
width: parent.width
height: parent.height
}
}
}
}
}
Screenshots:
1. Restaurant
2. Cafe
3. Bar
4. Shops
5. Arts
6. Museum
7. ATM
8. Park
9. Zoo
10. Movie
11. Night Club
12. Doctor
This app is your perfect companion when you are on a vacation or trying to figure out which places to visit on a vacation.
This app returns the result based on the importance of the place. Ex: A famous restaurant will appear first.
This app gives the address, latitude, longitude of the place
This app even shows the location of the place on a map.
Source Code:
import QtQuick 2.0
import QtLocation 5.0
import QtQuick.XmlListModel 2.0
import Ubuntu.Components 0.1
import Ubuntu.Components.Popups 0.1
import Ubuntu.Components.Extras.Browser 0.1
import "components"
import "icons"
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
id: root
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "com.ubuntu.developer.karthik.upadya1.streetwatch"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
property string secondaryTitle: ""
property string latlng: ""
property bool validated: false
property bool geocoded: false
property int typeNum: -1
property string selectedType: ""
property string cName: ""
property string vicinity: ""
property string latitude: ""
property string longitude: ""
function getSelectedType () {
switch(root.typeNum) {
case 0: root.selectedType = "restaurant";
break;
case 1: root.selectedType = "cafe";
break;
case 2: root.selectedType = "bar";
break;
case 3: root.selectedType = "shopping_mall";
break;
case 4: root.selectedType = "art_gallery";
break;
case 5: root.selectedType = "museum";
break;
case 6: root.selectedType = "atm";
break;
case 7: root.selectedType = "park";
break;
case 8: root.selectedType = "zoo";
break;
case 9: root.selectedType = "movie_theater";
break;
case 10: root.selectedType = "night_club";
break;
case 11: root.selectedType = "doctor";
break;
}
}
backgroundColor: "#222930"
width: units.gu(40)
height: units.gu(75)
PageStack {
id: pageStack
Component.onCompleted: {
push(mainPage)
}
Page {
id: mainPage
title: i18n.tr("Street Watch")
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
Row {
id: line1
spacing: units.gu(2)
TextField {
id: cityName
color: UbuntuColors.orange
placeholderText: "Enter city name"
width: root.width * 0.6
onTextChanged: {
if (cityName.text.length == 0 || root.validated) {
root.latlng = "";
root.geocoded = false;
root.validated = false;
}
}
}
Button {
text: i18n.tr("Find")
onClicked: {
if (cityName.text.length > 0) {
root.validated = true;
}
else {
PopupUtils.open(dialog, null);
}
}
}
Component {
id: dialog
Dialog {
id: dialogue
title: i18n.tr("Please enter city name")
Button {
text: i18n.tr("OK")
onClicked: PopupUtils.close(dialogue)
}
}
}
}
Row {
id: line4
spacing: units.gu(2)
Label {
id: resultText
fontSize: "large"
color: "#4EB1BA"
text: qsTr("Categories")
}
ActivityIndicator {
id: activity
running: (root.validated) && (geoCodeData.status === XmlListModel.Loading)
Text {
id: activityText
anchors.centerIn: activity
color: "#4EB1BA"
text: (activity.running) ? qsTr("\t\tLoading. Please wait!") : ""
}
}
Text {
color: "#4EB1BA"
text: (geoCodeData.status === XmlListModel.Error) ? qsTr("Error loading data.") : ""
}
}
Row {
id: line2
spacing: units.gu(2)
width: root.width
ListModel {
id: menus
ListElement {
name: "Restaurant"
icon: "icons/restaurant-71.png"
}
ListElement {
name: "Cafe"
icon: "icons/cafe-71.png"
}
ListElement {
name: "Bar"
icon: "icons/bar-71.png"
}
ListElement {
name: "Shops"
icon: "icons/generic_business-71.png"
}
ListElement {
name: "Arts"
icon: "icons/art_gallery-71.png"
}
ListElement {
name: "Museum"
icon: "icons/museum-71.png"
}
ListElement {
name: "ATM"
icon: "icons/atm-71.png"
}
ListElement {
name: "Park"
icon: "icons/camping-71.png"
}
ListElement {
name: "Zoo"
icon: "icons/zoo-71.png"
}
ListElement {
name: "Movies"
icon: "icons/movies-71.png"
}
ListElement {
name: "Night Club"
icon: "icons/Night_Club-71.png"
}
ListElement {
name: "Doctor"
icon: "icons/doctor-71.png"
}
}
GridView {
id: gridView
width: root.width
height: units.gu(60)
cellWidth: root.width * 0.3
cellHeight: root.height * 0.16
currentIndex: -1
Component {
id: gridDelegate
Item {
id: wrapper
width: root.width * 0.3
height: gridView.cellHeight
UbuntuShape {
anchors.fill: wrapper
color: "#4EB1BA"
}
Image {
source: icon
anchors {
fill: wrapper
topMargin: units.gu(2)
rightMargin: units.gu(2)
leftMargin: units.gu(2)
bottomMargin: units.gu(2)
}
fillMode: Image.PreserveAspectFit
}
Text {
color: "#E9E9E9"
text: name
anchors.horizontalCenter: wrapper.horizontalCenter
anchors.bottom: wrapper.bottom
}
}
}
model: menus
delegate: gridDelegate
focus: true
onCurrentIndexChanged: {
if (cityName.text.length > 0 && root.geocoded && root.latlng.length > 2 && gridView.currentIndex >= 0) {
root.typeNum = currentIndex;
root.getSelectedType();
pageStack.push(secondaryPage, { title: menus.get(currentIndex).name });
}
else if(gridView.currentIndex >= 0){
PopupUtils.open(dialog2, null);
}
gridView.currentIndex = -1;
}
MouseArea {
id: gridArea
anchors.fill: parent
preventStealing: true
property int index: gridView.indexAt(mouseX, mouseY)
onClicked: {
gridView.currentIndex = gridArea.index;
}
}
Component {
id: dialog2
Dialog {
id: dialogue2
title: i18n.tr("Error!")
text: {
if (cityName.text.length == 0) {
i18n.tr("Please enter city name");
}
else {
i18n.tr("Unable to find your location.\nPlease use nearby area for searching.")
}
}
Button {
text: i18n.tr("OK")
onClicked: PopupUtils.close(dialogue2)
}
}
}
}
}
}
tools: ToolbarItems {
ToolbarButton {
id: actionsButton
text: "Options"
iconSource: "icons/option.png"
onTriggered: PopupUtils.open(actionSelectionPopover, actionsButton)
visible: true
}
locked: false
opened: true
}
Item {
Component {
id: actionSelectionPopover
ActionSelectionPopover {
actions: ActionList {
Action {
text: i18n.tr("About me")
onTriggered: PopupUtils.open(defaultSheet, null)
}
Action {
text: i18n.tr("Quit")
onTriggered: Qt.quit()
}
}
}
}
}
Component {
id: defaultSheet
DefaultSheet {
id: aboutme
title: i18n.tr("About me")
Label {
anchors.fill: parent
color: UbuntuColors.orange
fontSize: "small"
wrapMode: Text.WordWrap
text: "Developed by: <b>KARTHIK</b><br/>" +
"Tested by: <b>KARTHIK</b><br/>" +
"Email: <b>karthik.upadya1@gmail.com</b><br/>" +
"Country: <b>INDIA</b><br/>" +
"This is Geo service application designed for Ubuntu and Ubuntu Touch.<br/>" +
"Please mail me to get source code.<br/>" +
"Please give credit to me if you use this application as part of your project.<br/>" +
"<b>Check out my other apps \"Daily Karma\" and \"Weather Forecast\"</b><br/>"+
"If you have android device you can download my apps from SlideMe.<br/>"+
"1. Bumpy Adventures I<br/>2. Dude! Escape<br/>3. Auto Call Blocker<br/>4. Snake<br/>5. Millenium alien<br/>"+
"My developer name in the site is \"developerKASS013\" Thanks :)"
}
}
}
XmlListModel {
id: geoCodeData
source: {
if (root.validated) {
"https://maps.googleapis.com/maps/api/geocode/xml?address=" + cityName.text + "&sensor=false";
}
else {
"";
}
}
query: "/GeocodeResponse/result"
XmlRole { name: "Lat"; query: "geometry/location/lat/string()" }
XmlRole { name: "Lng"; query: "geometry/location/lng/string()" }
onStatusChanged: {
if (status === XmlListModel.Ready) {
root.latlng = get(0).Lat + "," + get(0).Lng
if (root.latlng.length > 2) {
root.geocoded = true;
}
}
else {
root.latlng = "NO";
}
}
}
}
Page {
id: secondaryPage
property alias title: secondaryPage.title
visible: false
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
Row {
id: sline1
spacing: units.gu(2)
width: root.width
visible: true
OptionSelector {
id: nearselect
width: root.width * 0.88
expanded: true
selectedIndex: -1
model: placesnear
delegate: placesnearDelegate
containerHeight: itemHeight * 7
onSelectedIndexChanged: {
root.cName = placesnear.get(nearselect.selectedIndex).Name;
root.vicinity = placesnear.get(nearselect.selectedIndex).Address
root.latitude = placesnear.get(nearselect.selectedIndex).Latitude
root.longitude = placesnear.get(nearselect.selectedIndex).Longitude
root.latlng = root.latitude + "," + root.longitude
PopupUtils.open(dialog3, null)
nearselect.selectedIndex = -1;
}
}
ActivityIndicator {
id: activity2
running: (placesnear.status === XmlListModel.Loading)
Text {
id: activityText2
anchors.centerIn: activity2
color: "#4EB1BA"
text: (activity2.running) ? qsTr("\t\tLoading. Please wait!") : ""
}
}
Text {
color: "#4EB1BA"
text: (placesnear.status === XmlListModel.Error) ? qsTr("Error loading data.") : ""
}
}
Component {
id: dialog3
Dialog {
id: dialogue3
title: i18n.tr("Details")
text: root.cName + "\n" +
root.vicinity + "\n" +
"Latitude: " + root.latitude + "\n" +
"Longitude: " + root.longitude
Button {
text: i18n.tr("View on map")
onClicked: {
PopupUtils.close(dialogue3)
pageStack.push(mapPage, null)
}
}
Button {
text: i18n.tr("Back to list")
onClicked: PopupUtils.close(dialogue3)
}
}
}
}
XmlListModel {
id: placesnear
source: "https://maps.googleapis.com/maps/api/place/nearbysearch/xml" +
"?key=AIzaSyBIBbmCktqpdALis32jSCGr-UlXcuCeU8Q&sensor=false&location=" + root.latlng +
"&rankby=distance&types=" + root.selectedType
query: "/PlaceSearchResponse/result"
XmlRole { name: "Name"; query: "name/string()" }
XmlRole { name: "Address"; query: "vicinity/string()" }
XmlRole { name: "Latitude"; query: "geometry/location/lat/string()" }
XmlRole { name: "Longitude"; query: "geometry/location/lng/string()" }
}
Component {
id: placesnearDelegate
OptionSelectorDelegate {
Text {
width: root.width * 0.8
elide: Text.ElideRight
wrapMode: Text.WordWrap
color: "#4EB1BA"
text: {
i18n.tr("\n " + model.Name);
}
}
}
}
}
Page {
id: mapPage
title: i18n.tr("Map")
visible: false
Column {
spacing: units.gu(1)
anchors {
margins: units.gu(2)
fill: parent
}
UbuntuWebView {
id: webview
url: "https://maps.google.com/?q=" + root.latlng
width: parent.width
height: parent.height
}
}
}
}
}
Screenshots:
No comments:
Post a Comment