diff options
Diffstat (limited to 'Widgets/NavPage.py')
-rw-r--r-- | Widgets/NavPage.py | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/Widgets/NavPage.py b/Widgets/NavPage.py new file mode 100644 index 0000000..61d63aa --- /dev/null +++ b/Widgets/NavPage.py @@ -0,0 +1,179 @@ +""" + Copyright 2023 Suchinton Chakravarty + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import extras.Kuksa_Instance as kuksa_instance +import os +import sys +import requests +import folium +from PyQt5 import uic, QtCore + +from PyQt5.QtCore import QUrl, QObject +from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot +from PyQt5.QtWebEngineWidgets import QWebEngineView +from PyQt5.QtWidgets import QApplication, QListWidget, QLineEdit, QCompleter, QListView +from PyQt5.QtGui import QPainterPath, QRegion, QStandardItemModel, QStandardItem +from PyQt5.QtCore import QRectF +from PyQt5.QtCore import QTimer +from PyQt5.QtCore import Qt + +current_dir = os.path.dirname(os.path.abspath(__file__)) + +# ======================================== + +sys.path.append(os.path.dirname(current_dir)) + + +Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/Nav.ui")) + +# ======================================== + + +class Nav_Paths(): + def __init__(self): + self.currLat = "Vehicle.CurrentLocation.Latitude" + self.currLng = "Vehicle.CurrentLocation.Longitude" + self.desLat = "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude" + self.desLng = "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude" + + +class NavWidget(Base, Form): + suggestionsUpdated = pyqtSignal(list) + + def __init__(self, parent=None): + super(self.__class__, self).__init__(parent) + self.setupUi(self) + + self.From_address = self.findChild(QLineEdit, "From_address") + self.To_address = self.findChild(QLineEdit, "To_address") + self.map_view = self.findChild(QWebEngineView, "map_view") + + path = QPainterPath() + path.addRoundedRect(QRectF(self.map_view.rect()), 10, 10) + mask = QRegion(path.toFillPolygon().toPolygon()) + self.map_view.setMask(mask) + + self.searching_thread = QThread() + + self.suggested_addresses = QStandardItemModel() + completer = CustomCompleter(self.suggested_addresses) + self.From_address.setCompleter(completer) + + self.From_address.textChanged.connect(self.delayed_search) + # self.To_address.textChanged.connect(lambda: self.start_search(self.To_address.text())) + + self.suggestionsUpdated.connect(self.update_suggestions) + + self.timer = QTimer() + self.timer.setInterval(500) # Adjust delay as needed + self.timer.setSingleShot(True) + self.timer.timeout.connect(self.start_search) + + def delayed_search(self): + self.timer.start() + + def start_search(self): + query = self.From_address.text().strip() + if query: + self.searching_thread.run = lambda: self.search_address(query) + self.searching_thread.start() + + def search_address(self, query): + options = self.fetch_address_suggestions(query) + self.suggestionsUpdated.emit(options) + + def fetch_address_suggestions(self, query): + url = f"https://nominatim.openstreetmap.org/search?format=json&limit=5&q={requests.utils.quote(query)}" + response = requests.get(url) + if response.status_code == 200: + return response.json() + else: + return [] + + def show_suggestions(self, options): + current_query = self.From_address.text().strip() + if current_query: + self.suggested_addresses.clear() + for suggestion in options: + address = suggestion.get("display_name", "") + self.suggested_addresses.appendRow(QStandardItem(address)) + + @pyqtSlot(list) + def update_suggestions(self, options): + self.show_suggestions(options) + + def select_suggestion(self, item): + address = item.text() + # self.address_input.setText(address) + coordinates = self.show_location(address) + + def show_location(self, query): + url = f"https://nominatim.openstreetmap.org/search?format=json&limit=1&q={requests.utils.quote(query)}" + response = requests.get(url) + if response.status_code == 200: + data = response.json() + if data: + lat = data[0]["lat"] + lon = data[0]["lon"] + location = [float(lat), float(lon)] + + self.update_map(location) + return location + + def update_map(self, location): + map_html = self.create_map_html(location) + file_path = os.path.abspath("map.html") + with open(file_path, "w") as f: + f.write(map_html) + self.map_view.load(QUrl.fromLocalFile(file_path)) + + def create_map_html(self, location): + map = folium.Map(location=location, zoom_start=15) + marker = folium.Marker(location=location) + marker.add_to(map) + return map._repr_html_() + + +class CustomCompleter(QCompleter): + def __init__(self, parent=None): + super().__init__(parent) + self.setPopup(QListView()) + self.popup().setStyleSheet(""" + QListView { + background-color: #131313 ; /* black */ + color: #fff; + border: 1px solid #4BD7D6 ; /* light blue */ + border-radius: 2px; + padding: 10px; + margin: 2px; + } + """) + + self.popup().setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) + self.popup().setUniformItemSizes(True) + self.popup().setWordWrap(True) + self.popup().setSpacing(1) + self.popup().setFrameShape(QListView.NoFrame) + self.popup().setFrameShadow(QListView.Plain) + self.popup().setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + + +if __name__ == '__main__': + import sys + app = QApplication(sys.argv) + w = NavWidget() + w.show() + sys.exit(app.exec_()) |