# -*- coding: utf-8 -*-
"""
/***************************************************************************
 Hqgis
                                 A QGIS plugin
 Access the HERE API in QGIS
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2018-12-22
        git sha              : $Format:%H$
        copyright            : (C) 2018 by Riccardo Klinger
        email                : riccardo.klinger@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, QUrl
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtWidgets import QAction, QFileDialog
from PyQt5 import QtGui, QtWidgets, QtNetwork
from functools import partial
# Initialize Qt resources from file resources.py
from .resources import *
from .GetMapCoordinates import GetMapCoordinates
# Import the code for the dialog
from .hqgis_dialog import HqgisDialog
import os.path
import requests
import json
import urllib
import os
from PyQt5.QtCore import QVariant, QDateTime
from qgis.core import (
    QgsApplication,
    QgsPoint,
    QgsSymbol,
    QgsRendererRange,
    QgsGraduatedSymbolRenderer,
    QgsPointXY,
    QgsGeometry,
    QgsMapLayerProxyModel,
    QgsVectorLayer,
    QgsProject,
    QgsCoordinateReferenceSystem,
    QgsCoordinateTransform,
    QgsFeature,
    QgsField,
    QgsMessageLog,
    QgsNetworkAccessManager,
    QgsSettings)
from qgis.PyQt.QtWidgets import QProgressBar
from qgis.PyQt.QtCore import *
from qgis.utils import iface
from Hqgis.HqgisProvider import HqgisProvider


class Hqgis:
    def __init__(self, iface):
        self.provider = HqgisProvider()
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'Hqgis_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Create the dialog (after translation) and keep reference
        self.dlg = HqgisDialog()

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Hqgis')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'Hqgis')
        self.toolbar.setObjectName(u'Hqgis')
        self.getMapCoordinates = GetMapCoordinates(self.iface)
        self.getMapCoordTool = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):

        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Hqgis', message)

    def add_action(
            self,
            icon_path,
            text,
            callback,
            enabled_flag=True,
            add_to_menu=True,
            add_to_toolbar=True,
            status_tip=None,
            whats_this=None,
            parent=None):
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToWebMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        QgsApplication.processingRegistry().addProvider(self.provider)
        icon_path = ':/plugins/hereqgis/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Access the HERE API'),
            callback=self.run,
            parent=self.iface.mainWindow())
        self.loadCredFunction()
        if self.dlg.AppId.text() == "":
            self.dlg.status2.setText(
                "No credentials in credentials tab found.")
            self.dlg.geocodeAddressButton.setEnabled(False)
            self.dlg.batchGeocodeFieldButton.setEnabled(False)
            self.dlg.batchGeocodeFieldsButton.setEnabled(False)
            self.dlg.calcRouteSingleButton.setEnabled(False)
            self.dlg.findPOISButton.setEnabled(False)
            self.dlg.findPOISButtonBatch.setEnabled(False)
            self.dlg.calcIsoButton.setEnabled(False)
            self.dlg.calcIsoButtonBatch.setEnabled(False)
        self.dlg.AppId.editingFinished.connect(self.enableButtons)
        # self.dlg.AppCode.editingFinished.connect(self.enableButtons)
        self.dlg.getCreds.clicked.connect(self.getCredFunction)
        self.dlg.saveCreds.clicked.connect(self.saveCredFunction)
        self.dlg.loadCreds.clicked.connect(self.loadCredFunction)
        self.dlg.mapLayerBox.setAllowEmptyLayer(False)
        self.dlg.mapLayerBox.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.dlg.mapLayerBox.currentIndexChanged.connect(self.loadField)
        self.loadField()
        self.dlg.mapLayerBox_2.setAllowEmptyLayer(False)
        self.dlg.mapLayerBox_2.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.loadFields()

        self.dlg.mapLayerBox_2.currentIndexChanged.connect(self.loadFields)
        self.dlg.geocodeAddressButton.clicked.connect(self.geocode)
        self.dlg.batchGeocodeFieldButton.clicked.connect(
            self.batchGeocodeField)
        self.dlg.batchGeocodeFieldsButton.clicked.connect(
            self.batchGeocodeFields)
        self.dlg.FindPOISLayer.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.dlg.IsoAddressBatch.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.dlg.calcRouteSingleButton.clicked.connect(
            self.calculateRouteSingle)

        # coordButton
        # Activate click tool in canvas.
        self.dlg.captureButton.setIcon(
            QIcon(
                os.path.join(
                    os.path.dirname(__file__),
                    "target.png")))
        self.dlg.captureButton_2.setIcon(
            QIcon(
                os.path.join(
                    os.path.dirname(__file__),
                    "target.png")))

        # self.dlg.captureButton.setChecked(True)

        self.dlg.toAddress.editingFinished .connect(
            partial(self.geocodeline, [self.dlg.toAddress, self.dlg.ToLabel]))
        # self.dlg.captureButton.setChecked(True)
        self.getMapCoordTool = self.getMapCoordinates
        self.getMapCoordTool.setButton(self.dlg.captureButton)
        self.getMapCoordTool.setButton(self.dlg.captureButton_2)
        self.getMapCoordTool.setButton(self.dlg.captureButton_4)
        self.getMapCoordTool.setButton(self.dlg.captureButton_3)
        self.getMapCoordTool.setWidget(self.dlg)
        self.iface.mapCanvas().setMapTool(self.getMapCoordTool)
        self.dlg.captureButton.pressed.connect(self.setGetMapToolCoordFrom)
        self.dlg.captureButton_2.pressed.connect(self.setGetMapToolCoordTo)
        self.dlg.fromAddress.editingFinished.connect(
            partial(self.geocodeline, [self.dlg.fromAddress, self.dlg.FromLabel]))
        self.dlg.captureButton_4.setIcon(
            QIcon(
                os.path.join(
                    os.path.dirname(__file__),
                    "target.png")))
        self.dlg.findPOISButton.setEnabled(False)
        self.dlg.captureButton_4.pressed.connect(self.setGetMapToolCoordPlace)
        self.dlg.captureButton_3.setIcon(
            QIcon(
                os.path.join(
                    os.path.dirname(__file__),
                    "target.png")))
        self.dlg.calcIsoButton.setEnabled(False)
        self.dlg.captureButton_3.pressed.connect(self.setGetMapToolCoordIso)

        self.dlg.findPOISButton.clicked.connect(self.getPlacesSingle)
        self.dlg.listWidget.sortItems(0)
        self.dlg.listWidget.itemSelectionChanged.connect(self.checkPlacesInput)
        self.dlg.findPOISButtonBatch.clicked.connect(self.getPlacesBatch)
        self.dlg.FindPOISLayer.setAllowEmptyLayer(False)
        self.dlg.FindPOISLayer.setFilters(QgsMapLayerProxyModel.PointLayer)
        self.dlg.findPOISButtonBatch.setEnabled(False)
        self.dlg.listWidgetBatch.sortItems(0)
        self.dlg.listWidgetBatch.itemSelectionChanged.connect(
            self.checkPlacesInputBatch)
        self.dlg.placesAddress.editingFinished.connect(
            partial(
                self.geocodeline, [
                    self.dlg.placesAddress, self.dlg.placeLabel, self.dlg.findPOISButton]))
        self.dlg.IsoAddress.editingFinished.connect(
            partial(
                self.geocodeline, [
                    self.dlg.IsoAddress, self.dlg.IsoLabel, self.dlg.calcIsoButton]))
        self.dlg.metric.currentTextChanged.connect(self.selectMetric)
        self.dlg.calcIsoButton.clicked.connect(self.getIsochronesSingle)
        self.dlg.calcIsoButtonBatch.setEnabled(False)
        self.dlg.travelTimesBatch.editingFinished.connect(self.enableBatchISO)
        self.dlg.travelDistancesBatch.editingFinished.connect(
            self.enableBatchISO)
        self.dlg.metricBatch.currentTextChanged.connect(self.selectMetricBatch)
        self.dlg.calcIsoButtonBatch.clicked.connect(self.getIsochronesBatch)
        self.dlg.trafficModeBatch.currentIndexChanged.connect(partial(
            self.enableTime, [self.dlg.trafficModeBatch, self.dlg.dateTimeEditBatch]))
        self.dlg.trafficMode_2.currentIndexChanged.connect(
            partial(self.enableTime, [self.dlg.trafficMode_2, self.dlg.dateTimeEdit_2]))
        self.dlg.trafficMode.currentIndexChanged.connect(
            partial(self.enableTime, [self.dlg.trafficMode, self.dlg.dateTimeEdit]))

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        print(self.provider)
        QgsApplication.processingRegistry().removeProvider(self.provider)
        for action in self.actions:
            self.iface.removePluginWebMenu(
                self.tr(u'&Hqgis'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def enableButtons(self):
        if self.dlg.AppId.text() != "":
            self.dlg.geocodeAddressButton.setEnabled(True)
            self.dlg.batchGeocodeFieldButton.setEnabled(True)
            self.dlg.batchGeocodeFieldsButton.setEnabled(True)
            self.dlg.calcRouteSingleButton.setEnabled(True)
            self.dlg.findPOISButton.setEnabled(True)
            self.dlg.findPOISButtonBatch.setEnabled(True)
            self.dlg.calcIsoButton.setEnabled(True)
            self.dlg.calcIsoButtonBatch.setEnabled(True)
            self.dlg.status2.setText("")

    def enableTime(self, lineEdits):
        if lineEdits[0].currentText() == "enabled":
            lineEdits[1].setEnabled(True)
            print("time enabled")
            # print(lineEdits[1].dateTime().toString("yyyy-MM-dd'T'hh:mm:ss'Z'"))
            # 2019-01-28T02:27:52Z
            # 2019-01-27T02:00:00Z
        else:
            lineEdits[1].setEnabled(False)
            print("time disabled")

    def enableBatchISO(self):
        if self.dlg.travelTimesBatch.text() != "" or self.dlg.travelDistancesBatch.text() != "":
            self.dlg.calcIsoButtonBatch.setEnabled(True)

    def convertGeocodeResponse(self, responseAddress):
        geocodeResponse = {}
        try:
            geocodeResponse["Label"] = responseAddress["Location"]["Address"]["Label"]
        except BaseException:
            geocodeResponse["Label"] = ""
        try:
            geocodeResponse["Country"] = responseAddress["Location"]["Address"]["Country"]
        except BaseException:
            geocodeResponse["Country"] = ""
        try:
            geocodeResponse["State"] = responseAddress["Location"]["Address"]["State"]
        except BaseException:
            geocodeResponse["State"] = ""
        try:
            geocodeResponse["County"] = responseAddress["Location"]["Address"]["County"]
        except BaseException:
            geocodeResponse["County"] = ""
        try:
            geocodeResponse["City"] = responseAddress["Location"]["Address"]["City"]
        except BaseException:
            geocodeResponse["City"] = ""
        try:
            geocodeResponse["District"] = responseAddress["Location"]["Address"]["District"]
        except BaseException:
            geocodeResponse["District"] = ""
        try:
            geocodeResponse["Street"] = responseAddress["Location"]["Address"]["Street"]
        except BaseException:
            geocodeResponse["Street"] = ""
        try:
            geocodeResponse["HouseNumber"] = responseAddress["Location"]["Address"]["HouseNumber"]
        except BaseException:
            geocodeResponse["HouseNumber"] = ""
        try:
            geocodeResponse["PostalCode"] = responseAddress["Location"]["Address"]["PostalCode"]
        except BaseException:
            geocodeResponse["PostalCode"] = ""
        try:
            geocodeResponse["Relevance"] = responseAddress["Relevance"]
        except BaseException:
            geocodeResponse["Relevance"] = None
        try:
            geocodeResponse["CountryQuality"] = responseAddress["MatchQuality"]["Country"]
        except BaseException:
            geocodeResponse["CountryQuality"] = None
        try:
            geocodeResponse["CityQuality"] = responseAddress["MatchQuality"]["City"]
        except BaseException:
            geocodeResponse["CityQuality"] = None
        try:
            geocodeResponse["StreetQuality"] = responseAddress["MatchQuality"]["Street"][0]
        except BaseException:
            geocodeResponse["StreetQuality"] = None
        try:
            geocodeResponse["NumberQuality"] = responseAddress["MatchQuality"]["HouseNumber"]
        except BaseException:
            geocodeResponse["NumberQuality"] = None
        try:
            geocodeResponse["MatchType"] = responseAddress["MatchType"]
        except BaseException:
            geocodeResponse["MatchType"] = ""
        return(geocodeResponse)

    def createGeocodedLayer(self):
        layer = QgsVectorLayer(
            "Point?crs=EPSG:4326",
            "AddressLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("oldAddress", QVariant.String),
            QgsField("address", QVariant.String),
            QgsField("country", QVariant.String),
            QgsField("state", QVariant.String),
            QgsField("county", QVariant.String),
            QgsField("city", QVariant.String),
            QgsField("district", QVariant.String),
            QgsField("street", QVariant.String),
            QgsField("number", QVariant.String),
            QgsField("zip", QVariant.String),
            QgsField("relevance", QVariant.Double),
            QgsField("qu_country", QVariant.Double),
            QgsField("qu_city", QVariant.Double),
            QgsField("qu_street", QVariant.Double),
            QgsField("qu_number", QVariant.Double),
            QgsField("matchtype", QVariant.String)
        ])
        layer.updateFields()
        return(layer)

    def createPlaceLayer(self):
        layer = QgsVectorLayer(
            "Point?crs=EPSG:4326",
            "PlaceLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.String),
            QgsField("title", QVariant.String),
            QgsField("label", QVariant.String),
            QgsField("distance", QVariant.Double),
            QgsField("categories", QVariant.String)
        ])
        layer.updateFields()
        return(layer)

    def createPlaceLayerBatch(self):
        layer = QgsVectorLayer(
            "Point?crs=EPSG:4326",
            "PlaceLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("origin_id", QVariant.Int),
            QgsField("title", QVariant.String),
            QgsField("label", QVariant.String),
            QgsField("distance", QVariant.Double),
            QgsField("categories", QVariant.String)
        ])
        layer.updateFields()
        return(layer)

    def createIsoLayer(self):
        layer = QgsVectorLayer(
            "Polygon?crs=EPSG:4326",
            "isoLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("range", QVariant.Int),
            QgsField("metric", QVariant.String),
            QgsField("mode", QVariant.String),
            QgsField("traffic", QVariant.String),
            QgsField("timestamp", QVariant.DateTime),
            QgsField("type", QVariant.String)
        ])
        layer.updateFields()

        return(layer)

    def createIsoLayerBatch(self):
        layer = QgsVectorLayer(
            "Polygon?crs=EPSG:4326",
            "isoLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("origin_id", QVariant.Int),
            QgsField("range", QVariant.Int),
            QgsField("metric", QVariant.String),
            QgsField("mode", QVariant.String),
            QgsField("traffic", QVariant.String),
            QgsField("timestamp", QVariant.DateTime),
            QgsField("type", QVariant.String)
        ])
        layer.updateFields()

        return(layer)

    def createRouteLayer(self):
        layer = QgsVectorLayer(
            "Linestring?crs=EPSG:4326",
            "RouteLayer",
            "memory"
        )
        layer.dataProvider().addAttributes([
            QgsField("id", QVariant.Int),
            QgsField("distance", QVariant.Double),
            QgsField("time", QVariant.Double),
            QgsField("mode", QVariant.String),
            QgsField("traffic", QVariant.String),
            QgsField("timestamp", QVariant.DateTime),
            QgsField("type", QVariant.String)
        ])
        layer.updateFields()
        return(layer)

    def messageShow(self, progress, count, max):
        if not progress:
            progressMessageBar = iface.messageBar().createMessage(
                "Looping through " + str(max) + " records ...")
            progress = QProgressBar()
            progress.setMaximum(max)
            progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            progressMessageBar.layout().addWidget(progress)
            iface.messageBar().pushWidget(progressMessageBar, level=1)
            iface.mainWindow().repaint()
        #    return progress
        if progress:
            progress.setValue(count)
        return(progress)

    def geocode(self):
        self.getCredentials()
        address = self.dlg.AddressInput.text()
        if address == "":
            address = "11 WallStreet, NewYork, USA"

        url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
            self.appId + "&searchtext=" + address
        r = requests.get(url)
        try:
            # ass the response may hold more than one result we only use the
            # best one:
            responseAddress = json.loads(
                r.text)["Response"]["View"][0]["Result"][0]
            geocodeResponse = self.convertGeocodeResponse(responseAddress)
            lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
            lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
            layer = self.createGeocodedLayer()
            fet = QgsFeature()
            fet.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(lng, lat)))
            fet.setAttributes([
                0,
                address,
                geocodeResponse["Label"],
                geocodeResponse["Country"],
                geocodeResponse["State"],
                geocodeResponse["County"],
                geocodeResponse["City"],
                geocodeResponse["District"],
                geocodeResponse["Street"],
                geocodeResponse["HouseNumber"],
                geocodeResponse["PostalCode"],
                geocodeResponse["Relevance"],
                geocodeResponse["CountryQuality"],
                geocodeResponse["CityQuality"],
                geocodeResponse["StreetQuality"],
                geocodeResponse["NumberQuality"],
                geocodeResponse["MatchType"]
            ])
            #print("feature set")
            pr = layer.dataProvider()
            pr.addFeatures([fet])
            QgsProject.instance().addMapLayer(layer)
        except Exception as e:
            print(e)

    def batchGeocodeField(self):
        import time
        self.getCredentials()
        Resultlayer = self.createGeocodedLayer()
        pr = Resultlayer.dataProvider()
        layer = self.dlg.mapLayerBox.currentLayer()
        features = layer.getFeatures()
        ResultFeatureList = []

        # let's create the progress bar already with the number of features in
        # the layer
        progressMessageBar = iface.messageBar().createMessage(
            "Looping through " + str(layer.featureCount()) + " records ...")
        progress = QProgressBar()
        progress.setMaximum(layer.featureCount())
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        iface.messageBar().pushWidget(progressMessageBar, level=0)
        i = 0
        for feature in layer.getFeatures():
            url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
                self.appId + "&searchtext=" + feature[self.dlg.fieldBox.currentField()]
            r = requests.get(url)
            try:
                responseAddress = json.loads(
                    r.text)["Response"]["View"][0]["Result"][0]
                geocodeResponse = self.convertGeocodeResponse(responseAddress)
                lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
                lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
                ResultFet = QgsFeature()
                ResultFet.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(
                            lng, lat)))
                ResultFet.setAttributes([
                    feature.id(),
                    feature[self.dlg.fieldBox.currentField()],
                    geocodeResponse["Label"],
                    geocodeResponse["Country"],
                    geocodeResponse["State"],
                    geocodeResponse["County"],
                    geocodeResponse["City"],
                    geocodeResponse["District"],
                    geocodeResponse["Street"],
                    geocodeResponse["HouseNumber"],
                    geocodeResponse["PostalCode"],
                    geocodeResponse["Relevance"],
                    geocodeResponse["CountryQuality"],
                    geocodeResponse["CityQuality"],
                    geocodeResponse["StreetQuality"],
                    geocodeResponse["NumberQuality"],
                    geocodeResponse["MatchType"]
                ])
                ResultFeatureList.append(ResultFet)
            except Exception as e:
                print(e)
            i += 1
            progress.setValue(i)

            # time.sleep(0.3)
            # time.sleep(0.3)
        pr.addFeatures(ResultFeatureList)
        iface.messageBar().clearWidgets()
        QgsProject.instance().addMapLayer(Resultlayer)

    def batchGeocodeFields(self):
        import time
        import sys
        self.getCredentials()
        # mapping from inputs:

        Resultlayer = self.createGeocodedLayer()
        pr = Resultlayer.dataProvider()
        indexer = {}
        layer = self.dlg.mapLayerBox_2.currentLayer()
        indexer["country"] = layer.fields().indexFromName(
            self.dlg.CountryBox.currentField())
        indexer["state"] = layer.fields().indexFromName(
            self.dlg.StateBox.currentField())
        indexer["county"] = layer.fields().indexFromName(
            self.dlg.CountyBox.currentField())
        indexer["zip"] = layer.fields().indexFromName(
            self.dlg.ZipBox.currentField())
        indexer["city"] = layer.fields().indexFromName(
            self.dlg.CityBox.currentField())
        indexer["street"] = layer.fields().indexFromName(
            self.dlg.StreetBox.currentField())
        indexer["number"] = layer.fields().indexFromName(
            self.dlg.NumberBox.currentField())
        ResultFeatureList = []  # got result storing
        # precreate field-lists for API call:
        addressLists = {}
        for key in indexer.keys():
            if indexer[key] != -1:
                parts = []
                oldIDs = []
                features = layer.getFeatures()
                for fet in features:
                    oldIDs.append(fet.id())
                    parts.append(str(fet.attributes()[indexer[key]]))
                addressLists[key] = parts
                addressLists["oldIds"] = oldIDs

        # let's create the progress bar already with the number of features in
        # the layer
        progressMessageBar = iface.messageBar().createMessage(
            "Looping through " + str(layer.featureCount()) + " records ...")
        progress = QProgressBar()
        progress.setMaximum(layer.featureCount())
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        iface.messageBar().pushWidget(progressMessageBar, level=0)

        for id in range(0, layer.featureCount()):
            urlPart = ""
            oldAddress = ""
            for key in addressLists.keys():
                if key != "oldIds":
                    urlPart += "&" + key + "=" + addressLists[key][id]
                    oldAddress += addressLists[key][id] + ","
            url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
                self.appId + urlPart
            r = requests.get(url)
            if r.status_code == 200:
                #sys.stdout.write("test" + url + "\\n")
                if len(json.loads(r.text)["Response"]["View"]) > 0:
                    # as the response may hold more than one result we only use
                    # the best one:
                    responseAddress = json.loads(
                        r.text)["Response"]["View"][0]["Result"][0]
                    geocodeResponse = self.convertGeocodeResponse(
                        responseAddress)
                    lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
                    lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
                    ResultFet = QgsFeature()
                    ResultFet.setGeometry(
                        QgsGeometry.fromPointXY(
                            QgsPointXY(
                                lng, lat)))
                    ResultFet.setAttributes([
                        addressLists["oldIds"][id],
                        oldAddress,
                        geocodeResponse["Label"],
                        geocodeResponse["Country"],
                        geocodeResponse["State"],
                        geocodeResponse["County"],
                        geocodeResponse["City"],
                        geocodeResponse["District"],
                        geocodeResponse["Street"],
                        geocodeResponse["HouseNumber"],
                        geocodeResponse["PostalCode"],
                        geocodeResponse["Relevance"],
                        geocodeResponse["CountryQuality"],
                        geocodeResponse["CityQuality"],
                        geocodeResponse["StreetQuality"],
                        geocodeResponse["NumberQuality"],
                        geocodeResponse["MatchType"]
                    ])
                    ResultFeatureList.append(ResultFet)
            time.sleep(0.5)
            progress.setValue(id)
            # iface.mainWindow().repaint()
            time.sleep(0.5)
        pr.addFeatures(ResultFeatureList)
        iface.messageBar().clearWidgets()
        QgsProject.instance().addMapLayer(Resultlayer)
        self.dlg.exec_()

    def getCredentials(self):
        s = QgsSettings()
        self.appId = s.value("HQGIS/api_key", None)

    def getCredFunction(self):
        import webbrowser
        webbrowser.open('https://developer.here.com/')

    def saveCredFunction(self):
        s = QgsSettings()
        s.setValue("HQGIS/api_key", self.dlg.AppId.text())
        print("save credits")
        self.dlg.credentialInteraction.setText("")
        self.dlg.credentialInteraction.setText(
            "credentials saved to QGIS Global Settings")

    def loadCredFunction(self):
        s = QgsSettings()
        try:
            apikey = s.value("HQGIS/api_key", None)
            self.dlg.credentialInteraction.setText(
                "credits used from QGIS global settings")
            self.dlg.AppId.setText(apikey)
        except BaseException:
            self.dlg.credentialInteraction.setText(
                "no credits found in qgis global settings. Please check settings or save a new key")
        # print(mytext)
        # print(myint)
        # print(myreal)
        # print(nonexistent)
        #fileLocation = QFileDialog.getOpenFileName(self.dlg, "JSON with credentials",os.path.dirname(os.path.realpath(__file__))+ os.sep + "creds", "JSON(*.JSON)")
        # print(fileLocation)
        #scriptDirectory = os.path.dirname(os.path.realpath(__file__))
        # self.dlg.credentialInteraction.setText("")
        # print(scriptDirectory)
        # try:
        #    import os
        #    scriptDirectory = os.path.dirname(os.path.realpath(__file__))
        #    with open(scriptDirectory + os.sep + 'creds' + os.sep + 'credentials.json') as f:
        #        data = json.load(f)
        #        self.dlg.AppId.setText(data["KEY"])
        #        #self.dlg.AppCode.setText(data["CODE"])
        #    self.dlg.credentialInteraction.setText("credits used from " + scriptDirectory + os.sep + 'creds' + os.sep + 'credentials.json')
        # except:
        #    self.dlg.credentialInteraction.setText("no credits found in. Check for file" + scriptDirectory + os.sep + 'creds' + os.sep + 'credentials.json')
            # self.dlg.geocodeButton.setEnabled(False)

    def loadFields(self):
        self.dlg.CountryBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.StateBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.CountyBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.ZipBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.CityBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.StreetBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.NumberBox.setLayer(self.dlg.mapLayerBox_2.currentLayer())
        self.dlg.CountryBox.setAllowEmptyFieldName(True)
        self.dlg.StateBox.setAllowEmptyFieldName(True)
        self.dlg.CountyBox.setAllowEmptyFieldName(True)
        self.dlg.ZipBox.setAllowEmptyFieldName(True)
        self.dlg.CityBox.setAllowEmptyFieldName(True)
        self.dlg.StreetBox.setAllowEmptyFieldName(True)
        self.dlg.NumberBox.setAllowEmptyFieldName(True)

    def loadField(self):
        self.dlg.fieldBox.setLayer(self.dlg.mapLayerBox.currentLayer())
        self.dlg.fieldBox.setAllowEmptyFieldName(True)

    def setGetMapToolCoordFrom(self):
        """ Method that is connected to the target button. Activates and deactivates map tool """
        if self.dlg.captureButton.isChecked():
            print("true FROM")
            self.iface.mapCanvas().unsetMapTool(self.getMapCoordTool)
            self.dlg.captureButton_2.setChecked(True)
            return
        if self.dlg.captureButton.isChecked() == False:
            self.iface.mapCanvas().setCursor(Qt.CrossCursor)
            print("false FROM")
            self.iface.mapCanvas().setMapTool(self.getMapCoordTool)
            self.dlg.captureButton_2.setChecked(False)
            return

    def setGetMapToolCoordTo(self):
        if self.dlg.captureButton_2.isChecked():
            print("true TO")
            self.dlg.captureButton.setChecked(True)
            self.iface.mapCanvas().unsetMapTool(self.getMapCoordTool)
            return
        if self.dlg.captureButton_2.isChecked() == False:
            print("false TO")
            self.iface.mapCanvas().setCursor(Qt.CrossCursor)
            self.dlg.captureButton.setChecked(False)
            self.iface.mapCanvas().setMapTool(self.getMapCoordTool)
            return

    def setGetMapToolCoordPlace(self):
        if self.dlg.captureButton_4.isChecked():
            self.iface.mapCanvas().unsetMapTool(self.getMapCoordTool)
            return
        if self.dlg.captureButton_4.isChecked() == False:
            self.iface.mapCanvas().setCursor(Qt.CrossCursor)
            self.iface.mapCanvas().setMapTool(self.getMapCoordTool)
            return

    def setGetMapToolCoordIso(self):
        if self.dlg.captureButton_3.isChecked():
            self.iface.mapCanvas().unsetMapTool(self.getMapCoordTool)
            return
        if self.dlg.captureButton_3.isChecked() == False:
            self.iface.mapCanvas().setCursor(Qt.CrossCursor)
            self.iface.mapCanvas().setMapTool(self.getMapCoordTool)
            return

    def geocodelineFrom(self):
        self.getCredentials()
        address = self.dlg.fromAddress.text()
        url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
            self.appId + "&searchtext=" + address
        r = requests.get(url)
        try:
            # ass the response may hold more than one result we only use the
            # best one:
            responseAddress = json.loads(
                r.text)["Response"]["View"][0]["Result"][0]
            #geocodeResponse = self.convertGeocodeResponse(responseAddress)
            lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
            lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
            self.dlg.FromLabel.setText(
                str("%.5f" % lat) + ',' + str("%.5f" % lng))
        except BaseException:
            print("something went wrong")

    def geocodeline(self, lineEdits):
        self.getCredentials()
        address = lineEdits[0].text()
        url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
            self.appId + "&searchtext=" + address
        r = requests.get(url)
        try:
            # ass the response may hold more than one result we only use the
            # best one:
            responseAddress = json.loads(
                r.text)["Response"]["View"][0]["Result"][0]
            #geocodeResponse = self.convertGeocodeResponse(responseAddress)
            lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
            lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
            lineEdits[1].setText(str("%.5f" % lat) + ',' + str("%.5f" % lng))
        except BaseException:
            print("something went wrong")
        try:
            if lineEdits[1].text() != "":
                lineEdits[2].setEnabled(True)
            else:
                lineEdits[2].setEnabled(False)
        except BaseException:
            print("routing")

    def geocodelinePlace(self):
        self.getCredentials()
        address = self.dlg.placesAddress.text()
        self.dlg.findPOISButton.setEnabled(True)
        print(self.dlg.findPOISButton.enabled())
        if address != "":
            url = "https://geocoder.ls.hereapi.com/search/6.2/geocode.json?apiKey=" + \
                self.appId + "&searchtext=" + address
            r = requests.get(url)
            try:
                # ass the response may hold more than one result we only use
                # the best one:
                responseAddress = json.loads(
                    r.text)["Response"]["View"][0]["Result"][0]
                #geocodeResponse = self.convertGeocodeResponse(responseAddress)
                lat = responseAddress["Location"]["DisplayPosition"]["Latitude"]
                lng = responseAddress["Location"]["DisplayPosition"]["Longitude"]
                self.dlg.placeLabel.setText(
                    str("%.5f" % lat) + ',' + str("%.5f" % lng))
            except BaseException:
                print("something went wrong")

    def checkPlacesInput(self):
        if self.dlg.placeLabel.text() != "" and len(
                self.dlg.listWidget.selectedItems()) > 0:
            self.dlg.findPOISButton.setEnabled(True)
        else:
            self.dlg.findPOISButton.setEnabled(False)

    def checkPlacesInputBatch(self):
        if len(self.dlg.listWidgetBatch.selectedItems()) > 0:
            self.dlg.findPOISButtonBatch.setEnabled(True)
        else:
            self.dlg.findPOISButtonBatch.setEnabled(False)

    def selectMetric(self):
        if self.dlg.metric.currentText() == "Time":
            self.dlg.travelDistances.setEnabled(False)
            self.dlg.travelTimes.setEnabled(True)
        else:
            self.dlg.travelDistances.setEnabled(True)
            self.dlg.travelTimes.setEnabled(False)

    def selectMetricBatch(self):
        if self.dlg.metricBatch.currentText() == "Time":
            self.dlg.travelDistancesBatch.setEnabled(False)
            self.dlg.travelTimesBatch.setEnabled(True)
        else:
            self.dlg.travelDistancesBatch.setEnabled(True)
            self.dlg.travelTimesBatch.setEnabled(False)

    def calculateRouteSingle(self):
        self.getCredentials()
        type = self.dlg.Type.currentText()
        mode = self.dlg.TransportMode.currentText()
        if mode == 'public transport':
            mode = 'publicTransport'
        traffic = self.dlg.trafficMode.currentText()
        url = "https://route.ls.hereapi.com/routing/7.2/calculateroute.json?apiKey=" + self.appId + "&routeAttributes=shape&mode=" + type + \
            ";" + mode + ";traffic:" + traffic + "&waypoint0=geo!" + self.dlg.FromLabel.text() + "&waypoint1=geo!" + self.dlg.ToLabel.text()
        if self.dlg.trafficMode.currentText() == "enabled":
            # print(self.dlg.dateTimeEditBatch.dateTime())
            url += "&departure=" + \
                self.dlg.dateTimeEdit.dateTime().toString("yyyy-MM-dd'T'hh:mm:ss'Z'")
            time2 = self.dlg.dateTimeEdit.dateTime().toString("yyyyMMdd-hh:mm:ss")
            timestamp = QDateTime.fromString(time2, "yyyyMMdd-hh:mm:ss")
        else:
            timestamp = None
        print(url)
        r = requests.get(url)

        if r.status_code == 200:
            try:
                self.dlg.status2.setText("distance: " +
                                         str(json.loads(r.text)["response"]["route"][0]["summary"]["distance"]) +
                                         " time: " +
                                         str(json.loads(r.text)["response"]["route"][0]["summary"]["travelTime"]))
                if self.dlg.routeLayerCheckBox.checkState():
                    layer = self.createRouteLayer()
                    responseRoute = json.loads(
                        r.text)["response"]["route"][0]["shape"]
                    vertices = []
                    for routePoint in responseRoute:
                        lat = float(routePoint.split(",")[0])
                        lng = float(routePoint.split(",")[1])
                        vertices.append(QgsPoint(lng, lat))
                    fet = QgsFeature()
                    fet.setGeometry(QgsGeometry.fromPolyline(vertices))
                    fet.setAttributes([
                        0,
                        json.loads(r.text)["response"]["route"][0]["summary"]["distance"],
                        json.loads(r.text)["response"]["route"][0]["summary"]["travelTime"],
                        mode,
                        traffic,
                        timestamp,
                        type
                    ])
                    pr = layer.dataProvider()
                    pr.addFeatures([fet])
                    QgsProject.instance().addMapLayer(layer)
            except Exception as e:
                print(e)

    def getPlacesSingle(self):
        self.getCredentials()
        #radius = self.dlg.RadiusBox.value()
        categories = self.dlg.listWidget.selectedItems()
        categoriesList = []
        for category in categories:
            categoriesList.append(category.text())
        categories = ",".join(categoriesList)
        coordinates = self.dlg.placeLabel.text()
        url = 'https://browse.search.hereapi.com/v1/browse?at=' + coordinates + \
            "&categories=" + categories + "&limit=100&apiKey=" + self.appId
        r = requests.get(url)
        print(url)
        if r.status_code == 200:
            if len(json.loads(r.text)["items"]) > 99:
                iface.messageBar().pushMessage(
                    "Warning",
                    "The maximum number of POIs for original address at " +
                    coordinates +
                    " of 100 POIs reached.",
                    level=1,
                    duration=5)
            if len(json.loads(r.text)["items"]) > 0:
                try:
                    # as the response may hold more than one result we only use
                    # the best one:
                    responsePlaces = json.loads(r.text)["items"]
                    layer = self.createPlaceLayer()
                    features = []
                    for place in responsePlaces:
                        lat = place["position"]["lat"]
                        lng = place["position"]["lng"]
                        # iterate over categories:
                        categoriesResp = []
                        for cat in place["categories"]:
                            categoriesResp.append(cat["id"])
                        fet = QgsFeature()
                        fet.setGeometry(
                            QgsGeometry.fromPointXY(
                                QgsPointXY(
                                    lng, lat)))
                        fet.setAttributes([
                            place["id"],
                            place["title"],
                            place["address"]["label"],
                            place["distance"],
                            ";".join(categoriesResp)
                        ])
                        features.append(fet)
                    pr = layer.dataProvider()
                    pr.addFeatures(features)
                    QgsProject.instance().addMapLayer(layer)
                except Exception as e:
                    print(e)

    def getPlacesBatch(self):
        self.getCredentials()
        #radius = self.dlg.RadiusBoxBatch.value()
        categories = self.dlg.listWidgetBatch.selectedItems()
        categoriesList = []
        for category in categories:
            categoriesList.append(category.text())
        categories = ",".join(categoriesList)
        layer = self.createPlaceLayerBatch()
        # allow only regular point layers. no Multipoints
        if (originLayer.wkbType() == 4
            or originLayer.wkbType() == 1004
                or originLayer.wkbType() == 3004):
            self.iface.messageBar().pushWarning(
                'Failed', 'Please convert MultiPoint layer to Point layer before usage')
            return
        originLayer = self.dlg.FindPOISLayer.currentLayer()
        originFeatures = originLayer.getFeatures()
        layerCRS = originLayer.crs()
        if layerCRS != QgsCoordinateReferenceSystem(4326):
            sourceCrs = layerCRS
            destCrs = QgsCoordinateReferenceSystem(4326)
            tr = QgsCoordinateTransform(
                sourceCrs, destCrs, QgsProject.instance())
        progressMessageBar = iface.messageBar().createMessage(
            "Looping through " + str(originLayer.featureCount()) + " records ...")
        progress = QProgressBar()
        progress.setMaximum(originLayer.featureCount())
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        iface.messageBar().pushWidget(progressMessageBar, level=0)
        i = 0
        for originFeature in originFeatures:
            if layerCRS != QgsCoordinateReferenceSystem(4326):
                # we reproject:
                geom = originFeature.geometry()
                newGeom = tr.transform(geom.asPoint())
                x = newGeom.x()
                y = newGeom.y()
            else:
                x = originFeature.geometry().asPoint().x()
                y = originFeature.geometry().asPoint().y()
            coordinates = str(y) + "," + str(x)
            url = 'https://browse.search.hereapi.com/v1/browse?at=' + coordinates + \
                "&categories=" + categories + "&limit=100&apiKey=" + self.appId
            r = requests.get(url)
            print(url)
            i += 1
            progress.setValue(i)
            iface.mainWindow().repaint()

            if r.status_code == 200:
                if len(json.loads(r.text)["items"]) > 0:
                    if len(json.loads(r.text)["items"]) > 99:
                        iface.messageBar().pushMessage("Warning", "The maximum number of POIs for original feature " +
                                                       str(originFeature.id()) + " of 100 POIs reached.", level=1, duration=5)
                    try:
                        # ass the response may hold more than one result we
                        # only use the best one:
                        responsePlaces = json.loads(r.text)["items"]
                        #layer = self.createPlaceLayer()
                        features = []
                        for place in responsePlaces:
                            lat = place["position"]["lat"]
                            lng = place["position"]["lng"]
                            # iterate over categories:
                            categoriesResp = []
                            for cat in place["categories"]:
                                categoriesResp.append(cat["id"])
                            fet = QgsFeature()
                            fet.setGeometry(
                                QgsGeometry.fromPointXY(
                                    QgsPointXY(
                                        lng, lat)))
                            fet.setAttributes([
                                place["id"],
                                originFeature.id(),
                                place["title"],
                                place["address"]["label"],
                                place["distance"],
                                ";".join(categoriesResp)
                            ])
                            features.append(fet)
                        pr = layer.dataProvider()
                        pr.addFeatures(features)
                        QgsProject.instance().addMapLayer(layer)
                    except Exception as e:
                        print(e)
        iface.messageBar().clearWidgets()

    def getIsochronesSingle(self):
        # print(self.dlg.dateTimeEditBatch.dateTime().toPyDate())
        print("get Isochrones")
        self.getCredentials()
        # getting intervals:
        if self.dlg.metric.currentText() == "Time":
            intervalArray = self.dlg.travelTimes.text().split(",")
        else:
            intervalArray = self.dlg.travelDistances.text().split(",")
        ranges = [int(x) for x in intervalArray]
        # create colors:
        layer = self.createIsoLayer()
        if len(ranges) > 1:
            ranges.sort()
            rangediff = ranges[-1] - ranges[0]
            sym = QgsSymbol.defaultSymbol(layer.geometryType())
            rngs = []
            sym.setColor(QColor(0, 255, 0, 255))
            rng = QgsRendererRange(
                0, ranges[0], sym, str(0) + " - " + str(ranges[0]))
            rngs.append(rng)
            for rangeItem in range(1, len(ranges) - 1):
                sym = QgsSymbol.defaultSymbol(layer.geometryType())
                # colors.append([int(0 +
                # ((255/range)*(rangeItem-ranges[0]))),int(255-((255/range)*(rangeItem-ranges[0])),0])
                sym.setColor(QColor(int(0 + ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), int(
                    255 - ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), 0, 255))
                print(int(0 + ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), int(
                    255 - ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), 0, 255)
                rng = QgsRendererRange(ranges[rangeItem - 1] + 1, ranges[rangeItem], sym, str(
                    ranges[rangeItem - 1] + 1) + " - " + str(ranges[rangeItem]))
                rngs.append(rng)
            sym = QgsSymbol.defaultSymbol(layer.geometryType())
            sym.setColor(QColor(255, 0, 0, 255))
            rng = QgsRendererRange(
                ranges[-2] + 1, ranges[-1], sym, str(ranges[-2] + 1) + " - " + str(ranges[-1]))
            rngs.append(rng)
            field = "range"
            renderer = QgsGraduatedSymbolRenderer(field, rngs)
        type = self.dlg.Type_2.currentText()
        mode = self.dlg.TransportMode_2.currentText()
        traffic = self.dlg.trafficMode_2.currentText()
        if mode == 'public transport':
            mode = 'publicTransport'
        url = "https://isoline.route.ls.hereapi.com/routing/7.2/calculateisoline.json?" + \
            "apiKey=" + self.appId + \
            "&range=" + ",".join(intervalArray) + \
            "&mode=" + type + ";" + mode + ";traffic:" + traffic + \
            "&rangetype=" + self.dlg.metric.currentText().lower() + \
            "&" + self.dlg.OriginDestination.currentText().lower() + "=geo!" + \
            self.dlg.IsoLabel.text()
        if self.dlg.trafficMode_2.currentText() == "enabled":
            # print(self.dlg.dateTimeEditBatch.dateTime())
            url += "&departure=" + \
                self.dlg.dateTimeEdit_2.dateTime().toString("yyyy-MM-dd'T'hh:mm:ss'Z'")
            time2 = self.dlg.dateTimeEdit_2.dateTime().toString("yyyyMMdd-hh:mm:ss")
            timestamp = QDateTime.fromString(time2, "yyyyMMdd-hh:mm:ss")
        else:
            timestamp = None
        r = requests.get(url)
        print(url)

        if r.status_code == 200:
            if len(json.loads(r.text)["response"]["isoline"]) > 0:
                try:

                    response = json.loads(r.text)["response"]["isoline"]
                    features = []
                    fid = 0
                    for poly in response:
                        coordinates = []
                        for vertex in poly["component"][0]["shape"]:
                            lat = float(vertex.split(",")[0])
                            lng = float(vertex.split(",")[1])
                            coordinates.append(QgsPointXY(lng, lat))
                        fet = QgsFeature()
                        fet.setGeometry(
                            QgsGeometry.fromPolygonXY(
                                [coordinates]))
                        fet.setAttributes([
                            fid,
                            poly["range"],
                            self.dlg.metric.currentText().lower(),
                            mode,
                            traffic,
                            timestamp,
                            type
                        ])
                        features.append(fet)
                        fid += 1
                    pr = layer.dataProvider()
                    pr.addFeatures(reversed(features))
                    if len(ranges) > 1:
                        layer.setRenderer(renderer)
                    layer.setOpacity(0.5)
                    QgsProject.instance().addMapLayer(layer)
                except Exception as e:
                    print(e)

    def getIsochronesBatch(self):
        print("get Isochrones")
        self.getCredentials()
        # getting intervals:
        if self.dlg.metricBatch.currentText() == "Time":
            intervalArray = self.dlg.travelTimesBatch.text().split(",")
        else:
            intervalArray = self.dlg.travelDistancesBatch.text().split(",")
        ranges = [int(x) for x in intervalArray]
        # create colors:
        layer = self.createIsoLayerBatch()
        if len(ranges) > 1:
            ranges.sort()
            rangediff = ranges[-1] - ranges[0]
            sym = QgsSymbol.defaultSymbol(layer.geometryType())
            rngs = []
            sym.setColor(QColor(0, 255, 0, 255))
            rng = QgsRendererRange(
                0, ranges[0], sym, str(0) + " - " + str(ranges[0]))
            rngs.append(rng)
            for rangeItem in range(1, len(ranges) - 1):
                sym = QgsSymbol.defaultSymbol(layer.geometryType())
                # colors.append([int(0 +
                # ((255/range)*(rangeItem-ranges[0]))),int(255-((255/range)*(rangeItem-ranges[0])),0])
                sym.setColor(QColor(int(0 + ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), int(
                    255 - ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), 0, 255))
                print(int(0 + ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), int(
                    255 - ((255 / rangediff) * (ranges[rangeItem] - ranges[0]))), 0, 255)
                rng = QgsRendererRange(ranges[rangeItem - 1] + 1, ranges[rangeItem], sym, str(
                    ranges[rangeItem - 1] + 1) + " - " + str(ranges[rangeItem]))
                rngs.append(rng)
            sym = QgsSymbol.defaultSymbol(layer.geometryType())
            sym.setColor(QColor(255, 0, 0, 255))
            rng = QgsRendererRange(
                ranges[-2] + 1, ranges[-1], sym, str(ranges[-2] + 1) + " - " + str(ranges[-1]))
            rngs.append(rng)
            field = "range"
            renderer = QgsGraduatedSymbolRenderer(field, rngs)
        type = self.dlg.TypeBatch.currentText()
        mode = self.dlg.TransportModeBatch.currentText()
        if mode == 'public transport':
            mode = 'publicTransport'
        traffic = self.dlg.trafficModeBatch.currentText()
        originLayer = self.dlg.IsoAddressBatch.currentLayer()
        # allow only regular point layers. no Multipoints
        if (originLayer.wkbType() == 4
            or originLayer.wkbType() == 1004
                or originLayer.wkbType() == 3004):
            self.iface.messageBar().pushWarning(
                'Failed', 'Please convert MultiPoint layer to Point layer before usage')
            return
        originFeatures = originLayer.getFeatures()
        layerCRS = originLayer.crs()
        if layerCRS != QgsCoordinateReferenceSystem(4326):
            sourceCrs = layerCRS
            destCrs = QgsCoordinateReferenceSystem(4326)
            tr = QgsCoordinateTransform(
                sourceCrs, destCrs, QgsProject.instance())
        progressMessageBar = iface.messageBar().createMessage(
            "Looping through " + str(originLayer.featureCount()) + " records ...")
        progress = QProgressBar()
        progress.setMaximum(originLayer.featureCount())
        progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        iface.messageBar().pushWidget(progressMessageBar, level=0)
        i = 0
        for originFeature in originFeatures:
            if layerCRS != QgsCoordinateReferenceSystem(4326):
                # we reproject:
                geom = originFeature.geometry()
                newGeom = tr.transform(geom.asPoint())
                x = newGeom.x()
                y = newGeom.y()
            else:
                x = originFeature.geometry().asPoint().x()
                y = originFeature.geometry().asPoint().y()
            coordinates = str(y) + "," + str(x)
            url = "https://isoline.route.ls.hereapi.com/routing/7.2/calculateisoline.json?" + \
                "apiKey=" + self.appId + \
                "&range=" + ",".join(intervalArray) + \
                "&mode=" + type + ";" + mode + ";traffic:" + traffic + \
                "&rangetype=" + self.dlg.metricBatch.currentText().lower() + \
                "&" + self.dlg.OriginDestinationBatch.currentText().lower() + "=geo!" + \
                coordinates
            if self.dlg.trafficModeBatch.currentText() == "enabled":
                time = self.dlg.dateTimeEditBatch.dateTime().toString("yyyy-MM-dd'T'hh:mm:ss'Z'")
                # print(self.dlg.dateTimeEditBatch.dateTime())
                url += "&departure=" + time
                time2 = self.dlg.dateTimeEditBatch.dateTime().toString("yyyyMMdd-hh:mm:ss")
                timestamp = QDateTime.fromString(time2, "yyyyMMdd-hh:mm:ss")
            else:
                timestamp = None
            r = requests.get(url)
            print(url)
            i += 1
            progress.setValue(i)
            iface.mainWindow().repaint()

            if r.status_code == 200:
                if len(json.loads(r.text)["response"]["isoline"]) > 0:
                    try:
                        response = json.loads(r.text)["response"]["isoline"]
                        features = []
                        fid = 0
                        for poly in response:
                            coordinates = []
                            for vertex in poly["component"][0]["shape"]:
                                lat = float(vertex.split(",")[0])
                                lng = float(vertex.split(",")[1])
                                coordinates.append(QgsPointXY(lng, lat))
                            fet = QgsFeature()
                            fet.setGeometry(
                                QgsGeometry.fromPolygonXY(
                                    [coordinates]))

                            fet.setAttributes([
                                fid,
                                originFeature.id(),
                                poly["range"],
                                self.dlg.metricBatch.currentText().lower(),
                                mode,
                                traffic,
                                timestamp,
                                type
                            ])
                            features.append(fet)
                            fid += 1
                        pr = layer.dataProvider()
                        pr.addFeatures(reversed(features))
                        if len(ranges) > 1:
                            layer.setRenderer(renderer)
                        layer.setOpacity(0.5)
                        QgsProject.instance().addMapLayer(layer)
                    except Exception as e:
                        print(e)
        iface.messageBar().clearWidgets()

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # try to load credentials:

        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # get app code/id

            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass