2
* GPS Navigation http://launchpad.net/unav
3
* Copyright (C) 2015-2016 Marcos Alvarez Costales https://launchpad.net/~costales
4
* Copyright (C) 2015-2016 JkB https://launchpad.net/~joergberroth
6
* GPS Navigation is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 3 of the License, or
9
* (at your option) any later version.
11
* GPS Navigation is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
18
import QtQuick.Layouts 1.1
19
import Ubuntu.Components 1.3
20
import Ubuntu.Components.Popups 1.3
21
import Ubuntu.Components.ListItems 1.3 as ListItems
22
import QtQuick.XmlListModel 2.0
23
import "js/utils.js" as QmlJs
32
property string poiType: ""
33
property string clause: ""
35
property double geoDistFactor: 1.0
40
Component.onCompleted: {
41
resultsListView.visible = false
42
if (poiListPage.lat !== "null" && poiListPage.lng !== "null") {
45
statusLabel.text = i18n.tr("Unknown current position")
46
statusLabel.visible = true;
51
id: headerContentsItem
54
Label { // Show number of poi in header
58
rightMargin: units.gu(-1)
59
verticalCenter: parent.verticalCenter
63
visible: sortedPoiModel.count !== 0
64
horizontalAlignment: Text.AlignRight
65
text: (sortedPoiModel.count !== 50 ? i18n.tr("%1 POIs").arg(sortedPoiModel.count) : i18n.tr("First %1 POIs").arg(sortedPoiModel.count)) + " "
67
color: UbuntuColors.purple
73
verticalCenter: parent.verticalCenter
80
head.actions: Action {
82
iconSource: "../nav/img/header/poimap.svg"
83
text: i18n.tr("Show POIs on map")
84
visible: sortedPoiModel.count !== 0
86
if (mainPageStack.center_onpos === 2)
87
mainPageStack.center_onpos = 1;
88
mainPageStack.executeJavaScript("ui.markers_POI_set(" + JSON.stringify(sortedPoiModel.allPOI()) + ");")
89
mainPageStack.pop(poiListPage.fromPage)
90
mainPageStack.pop(poiListPage)
98
horizontalCenter: parent.horizontalCenter
99
verticalCenter: parent.verticalCenter
101
width: parent.width - units.gu(4)
102
visible: poiXmlModel.status === XmlListModel.Loading
103
wrapMode: Text.WordWrap
104
horizontalAlignment: Text.AlignHCenter
105
text: i18n.tr("Something was wrong. Please, try again…")
108
// Indicator to show load activity
112
bottom: statusLabel.top
113
bottomMargin: units.gu (1)
114
horizontalCenter: parent.horizontalCenter
116
running: poiXmlModel.status === XmlListModel.Loading
121
width: parent.width - units.gu(4)
123
top: statusLabel.bottom
124
topMargin: units.gu (4)
125
horizontalCenter: parent.horizontalCenter
130
function formatValue(v) {
131
return v.toFixed(0).toString() + (navApp.settings.unit === 0 ? " km" : " mi" )
135
value: geoDistFactor <= 25 ? 25.0 : geoDistFactor
144
top: distSlider.bottom
145
topMargin: units.gu (1)
146
horizontalCenter: parent.horizontalCenter
150
poiListPage.geoDistFactor = distSlider.value
152
distButton.visible = false;
153
distSlider.visible = false;
158
//OSMTouch (lp:osmtouch) POIModel:
164
if (status === XmlListModel.Error) {
165
console.log(errorString())
166
statusLabel.text = i18n.tr("Time out! Please try again");
167
statusLabel.visible = true;
168
resultsListView.visible = false;
171
if (status === XmlListModel.Ready && count === 0) {
172
//TRANSLATORS: The Argument is the POI type. E.G. a pub, station....
173
statusLabel.text = i18n.tr("Sorry, no %1 found nearby. Try again with another radius").arg(poiType);
174
statusLabel.visible = true;
175
distButton.visible = true;
176
distSlider.visible = true;
177
resultsListView.visible = false;
179
if (status === XmlListModel.Ready && count >> 0) {
180
statusLabel.visible = false;
181
sortedPoiModel.sortXmlList();
183
if (status === XmlListModel.Loading) { statusLabel.text = i18n.tr("Searching…") }
186
readonly property string baseUrl: "http://nominatim.openstreetmap.org/search?format=xml&bounded=1&limit=50&email=costales.marcos@gmail.com&extratags=1"
187
readonly property double geoDist: navApp.settings.unit === 0 ? 0.01 : 0.01 / 0.621371192
188
// geographic distance ~1.1km / ~1.1mi
189
// rough estimation only. Could be redefined.
191
// Boxed area in which to search for PoI
192
var bbox = ( Number(poiListPage.lng) - geoDist*geoDistFactor).toString() + ","
193
+ ( Number(poiListPage.lat) - geoDist*geoDistFactor).toString() + ","
194
+ ( Number(poiListPage.lng) + geoDist*geoDistFactor).toString() + ","
195
+ ( Number(poiListPage.lat) + geoDist*geoDistFactor).toString();
196
source = (baseUrl + "&q=" + clause + "&viewbox=" + bbox);
203
query: "/searchresults/place"
205
XmlRole { name: "osm_id"; query: "@place_id/string()"; }
206
XmlRole { name: "name"; query: "@display_name/string()"; }
207
XmlRole { name: "phone"; query: "extratags/tag[@key='phone']/@value/string()"; }
208
XmlRole { name: "website"; query: "extratags/tag[@key='website']/@value/string()"; }
209
// XmlRole { name: "cuisine"; query: "extratags/tag[@key='cuisine']/@value/string()"; }
210
XmlRole { name: "wheelchair"; query: "extratags/tag[@key='wheelchair']/@value/string()"; }
211
XmlRole { name: "openinghours"; query: "extratags/tag[@key='opening_hours']/@value/string()"; }
212
XmlRole { name: "lat"; query: "@lat/string()"; }
213
XmlRole { name: "lng"; query: "@lon/string()"; }
221
for (var i = 0; i < sortedPoiModel.count; i++) {
223
title: sortedPoiModel.get(i).name,
224
lat: parseFloat(sortedPoiModel.get(i).lat),
225
lng: parseFloat(sortedPoiModel.get(i).lng),
226
website: sortedPoiModel.get(i).website,
227
phone: sortedPoiModel.get(i).phone
233
function sortXmlList (){
235
for (var i = 0; i < poiXmlModel.count; i++) {
236
item = {"osmid": poiXmlModel.get(i).osm_id,
237
"name": poiXmlModel.get(i).name.split(',')[0],
238
"phone": poiXmlModel.get(i).phone,
239
"website": poiXmlModel.get(i).website,
240
// "cuisine": poiXmlModel.get(i).cuisine,
241
"wheelchair": poiXmlModel.get(i).wheelchair,
242
"openinghours": poiXmlModel.get(i).openinghours,
243
"lat": poiXmlModel.get(i).lat,
244
"lng": poiXmlModel.get(i).lng,
245
"distance": QmlJs.calcPoiDistance(
248
poiXmlModel.get(i).lat,
249
poiXmlModel.get(i).lng,
254
sortedPoiModel.append(item)
255
} else { // sort model by distance
257
while (j <= sortedPoiModel.count) {
258
if (j === sortedPoiModel.count) {
259
sortedPoiModel.append(item)
261
} else if (item.distance < sortedPoiModel.get(j).distance){
262
sortedPoiModel.insert(j,item)
270
resultsListView.visible = true;
277
model: sortedPoiModel
282
trailingActions: ListItemActions {
287
mainPageStack.pop(poiListPage.fromPage)
288
mainPageStack.pop(poiListPage)
289
mainPageStack.center_onpos = 2;
290
mainPageStack.routeState = 'yes'
291
mainPageStack.executeJavaScript("calc2coord("+ model.lat + "," + model.lng + ");");
295
iconName: "non-starred"
297
mainPageStack.pop(poiListPage.fromPage)
298
mainPageStack.pop(poiListPage)
299
mainPageStack.push(Qt.resolvedUrl("FavoritesPage.qml"), {state:"adding", lat: model.lat, lng: model.lng, favName: model.name})
305
PopupUtils.open(Qt.resolvedUrl("./Share.qml"), navApp, {"lat": model.lat, "lon": model.lng})
309
iconName: "external-link"
310
visible: (model.website !== "" && model.website.substring(0, 4) === "http")
312
Qt.openUrlExternally(website)
316
iconName: "call-start"
317
visible: model.phone !== ""
319
Qt.openUrlExternally("tel:///"+ phone)
326
mainPageStack.pop(poiListPage.fromPage)
327
mainPageStack.pop(poiListPage);
328
mainPageStack.executeJavaScript("ui.markers_POI_set([{title: \"" + model.name + "\", lat: " + model.lat + ", lng: " + model.lng + ", website: \"" + model.website + "\", phone: \"" + model.phone + "\"}]);");
331
contentItem.anchors {
332
leftMargin: units.gu(1)
333
rightMargin: units.gu(1)
334
topMargin: units.gu(0.5)
335
bottomMargin: units.gu(0.5)
343
right: acessibilityIcon.left
345
text: model.name !== "" ? model.name : poiListPage.poiType
346
font.weight: Font.DemiBold
348
elide: Text.ElideRight
352
anchors.bottom: parent.bottom
353
width: parent.width *4/5
355
text: model.openinghours !== "" ?
356
//TRANSLATORS: abbreviation for Monday
357
model.openinghours.replace("Mo", Qt.locale().dayName(1, Locale.ShortFormat)).
358
//TRANSLATORS: abbreviation for Tuesday
359
replace("Tu", Qt.locale().dayName(2, Locale.ShortFormat)).
360
//TRANSLATORS: abbreviation for Wednesday
361
replace("We", Qt.locale().dayName(3, Locale.ShortFormat)).
362
//TRANSLATORS: abbreviation for Thursday
363
replace("Th", Qt.locale().dayName(4, Locale.ShortFormat)).
364
//TRANSLATORS: abbreviation for Friday
365
replace("Fr", Qt.locale().dayName(5, Locale.ShortFormat)).
366
//TRANSLATORS: abbreviation for Saturday
367
replace("Sa", Qt.locale().dayName(6, Locale.ShortFormat)).
368
//TRANSLATORS: abbreviation for Sunday
369
replace("Su", Qt.locale().dayName(0, Locale.ShortFormat)).
370
//TRANSLATORS: abbreviation for Public Holiday
371
replace("PH", i18n.tr("PH") ).
372
//TRANSLATORS: "closed"
373
replace("off", i18n.tr("off") ) : ""
375
elide: Text.ElideRight
376
wrapMode: Text.WordWrap
381
anchors.bottom: parent.bottom
382
width: parent.width /5
383
anchors.right: parent.right
384
horizontalAlignment: Text.AlignRight
386
text: QmlJs.formatDistance(model.distance, navApp.settings.unit)
392
name: "preferences-desktop-accessibility-symbolic"
394
visible: model.wheelchair === "yes" || model.wheelchair === "limited" // is limited enought as criteria?
395
anchors.top: parent.top
396
anchors.right: parent.right
397
width: parent.height /2