Esempio n. 1
0
async def eval_p_js_co(page: QtWebEngineWidgets.QWebEnginePage, js: str):
    fut = asyncio.get_event_loop().create_future()

    def ready(r):
        asyncio.get_event_loop().call_soon_threadsafe(fut.set_result, r)

    page.runJavaScript(js, ready)
    return await fut
Esempio n. 2
0
def run_js_code(page: QWebEnginePage, code: str) -> object:
    loop = QEventLoop()

    result_value = {'value': None}

    def _on_callback(result: object):
        result_value['value'] = result

        loop.quit()

    page.runJavaScript(code, _on_callback)

    loop.exec()

    return result_value['value']
Esempio n. 3
0
 def runJavaScript(self, script, worldId=-1, callback=None):
     """
     Public method to run a script in the context of the page.
     
     @param script JavaScript script source to be executed
     @type str
     @param worldId ID to run the script under
     @type int
     @param callback callback function to be executed when the script has
         ended
     @type function
     """
     if worldId > -1:
         if callback is None:
             QWebEnginePage.runJavaScript(self, script, worldId)
         else:
             QWebEnginePage.runJavaScript(self, script, worldId, callback)
     else:
         if callback is None:
             QWebEnginePage.runJavaScript(self, script)
         else:
             QWebEnginePage.runJavaScript(self, script, callback)
Esempio n. 4
0
    def test_qt(self):
        from PyQt5.QtCore import QTimer
        from PyQt5.QtWidgets import QApplication
        from PyQt5.QtWebEngineWidgets import QWebEnginePage
        from PyQt5.QtGui import QImageReader, QFontDatabase
        from PyQt5.QtNetwork import QNetworkAccessManager
        from calibre.utils.img import image_from_data, image_to_data, test
        # Ensure that images can be read before QApplication is constructed.
        # Note that this requires QCoreApplication.libraryPaths() to return the
        # path to the Qt plugins which it always does in the frozen build,
        # because Qt is patched to know the layout of the calibre application
        # package. On non-frozen builds, it should just work because the
        # hard-coded paths of the Qt installation should work. If they do not,
        # then it is a distro problem.
        fmts = set(map(lambda x: x.data().decode('utf-8'), QImageReader.supportedImageFormats()))  # no2to3
        testf = {'jpg', 'png', 'svg', 'ico', 'gif'}
        self.assertEqual(testf.intersection(fmts), testf, "Qt doesn't seem to be able to load some of its image plugins. Available plugins: %s" % fmts)
        data = P('images/blank.png', allow_user_override=False, data=True)
        img = image_from_data(data)
        image_from_data(P('catalog/mastheadImage.gif', allow_user_override=False, data=True))
        for fmt in 'png bmp jpeg'.split():
            d = image_to_data(img, fmt=fmt)
            image_from_data(d)
        # Run the imaging tests
        test()

        from calibre.gui2 import ensure_app, destroy_app
        display_env_var = os.environ.pop('DISPLAY', None)
        try:
            ensure_app()
            self.assertGreaterEqual(len(QFontDatabase().families()), 5, 'The QPA headless plugin is not able to locate enough system fonts via fontconfig')
            from calibre.ebooks.covers import create_cover
            create_cover('xxx', ['yyy'])
            na = QNetworkAccessManager()
            self.assertTrue(hasattr(na, 'sslErrors'), 'Qt not compiled with openssl')
            if iswindows:
                from PyQt5.Qt import QtWin
                QtWin
            p = QWebEnginePage()

            def callback(result):
                callback.result = result
                if hasattr(print_callback, 'result'):
                    QApplication.instance().quit()

            def print_callback(result):
                print_callback.result = result
                if hasattr(callback, 'result'):
                    QApplication.instance().quit()

            p.runJavaScript('1 + 1', callback)
            p.printToPdf(print_callback)
            QTimer.singleShot(5000, lambda: QApplication.instance().quit())
            QApplication.instance().exec_()
            test_flaky = ismacos and not is_ci
            if not test_flaky:
                self.assertEqual(callback.result, 2, 'Simple JS computation failed')
                self.assertIn(b'Skia/PDF', bytes(print_callback.result), 'Print to PDF failed')
            del p
            del na
            destroy_app()
            del QWebEnginePage
        finally:
            if display_env_var is not None:
                os.environ['DISPLAY'] = display_env_var
Esempio n. 5
0
class TestForm(QMainWindow, Ui_MainWindow):
    #생성자
    def __init__(self):
        super().__init__()
        self.init_my_location()
        self.setupUi(self)  # 초기화
        # self.url = "http://localhost:8080/umbrella"
        self.url = "http://localhost:8000/umbrella2.html"
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(QUrl(self.url))
        self.page.setView(self.webEngineView)

        chrome_option = Options()
        #headless 모드
        chrome_option.add_argument("--headless")
        #사운드 뮤트
        chrome_option.add_argument("--mute-audio")

        # webdriver 설정(chrome) --headless
        self.browser = webdriver.Chrome(
            chrome_options=chrome_option,
            executable_path="webdriver/Chrome/chromedriver.exe")

        self.browser.get(self.url)

        self.runner = Runner(self.page, self.browser)
        self.comboBox.addItem("키워드")
        self.comboBox.addItem("주소")

        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        # self.pushButton.clicked.connect(self.map_removeMarkers)

        # self.pushButton.clicked.connect(lambda: self.map_setLevel(random.randrange(7)))

        #현재위치
        #self.pushButton.clicked.connect(lambda: self.coord_to_address(37.62244036,127.072065, 0))
        #거리
        self.pushButton.clicked.connect(
            lambda: self.getDistance([33.450500, 126.569968], [[
                33.450500, 126.569968
            ], [35.404195, 126.886323], [39.668777, 126.065913]]))

        self.pushButton.clicked.connect(lambda: self.runner.coord_to_address(
            self.my_location_lat, self.my_location_lng, random.randrange(0, 5))
                                        )
        # self.pushButton.clicked.connect(lambda: self.getDistance([33.450500,126.569968],[[33.450500,126.569968],[35.404195,126.886323],[39.668777,126.065913]]))

        # self.pushButton.clicked.connect(self.test_a)
        # self.pushButton.clicked.connect(self.search)
        self.lineEdit.returnPressed.connect(self.search)
        self.page.loadFinished.connect(
            lambda: self.setMap(self.my_location_lat, self.my_location_lng))
        # self.setMap(self.my_location_lat, self.my_location_lng)

    #아이피로 현재 위치 받아오기(google api 사용)
    def init_my_location(self):
        url = 'https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyDQKxbTt0MrFNH85kTJXzickMD5s88UVaI'
        data = {
            'considerIp': True,
        }

        result = requests.post(url, data)

        my_location = json.loads(result.text)
        # print(my_location)
        # print("lat : ",my_location.get('location').get('lat'))
        # print("lon : ",my_location.get('location').get('lng'))
        self.my_location_lat = my_location.get('location').get('lat')
        self.my_location_lng = my_location.get('location').get('lng')

    def test_a(self):
        script = """
        return centerX.val()
        """
        centerX = self.run(script)
        print(centerX)

    #위치권한 요청이 왔을때 허용해줌
    def setPagePermission(self, url, feature):
        self.page.setFeaturePermission(url, feature,
                                       QWebEnginePage.PermissionGrantedByUser)

    def search(self):
        search_text = self.lineEdit.text().strip()

        if self.comboBox.currentIndex() == 0:
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 장소 검색 객체를 생성합니다
            var ps = new kakao.maps.services.Places();

            // 키워드로 장소를 검색합니다
            ps.keywordSearch('""" + search_text + """', placesSearchCB);

            function placesSearchCB (data, status, pagination) {
                if (status === kakao.maps.services.Status.OK) {

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
                    // LatLngBounds 객체에 좌표를 추가합니다
                    var bounds = new kakao.maps.LatLngBounds();

                    for (var i=0; i<data.length; i++) {
                        displayMarker(data[i]);
                        bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
                    }

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
                    map.setBounds(bounds);
                }
            }


            """
        elif self.comboBox.currentIndex():
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 주소로 좌표를 검색합니다
            geocoder.addressSearch('""" + search_text + """', function(result, status) {

                // 정상적으로 검색이 완료됐으면
                 if (status === kakao.maps.services.Status.OK) {

                    var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

                    // 결과값으로 받은 위치를 마커로 표시합니다
                    var marker = new kakao.maps.Marker({
                        map: map,
                        position: coords
                    });
                    //*** 마커 담기
                    markerList.push(marker)


                    // 인포윈도우로 장소에 대한 설명을 표시합니다

                    infowindow.open(map, marker);

                    // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                    map.setCenter(coords);
                }
            });    """

        else:
            return
        self.run(script)

    #거리 계산하는 메소드
    # center에는 기준좌표 [lat, lng]
    # pointList에는 측정할 좌표 리스트 [ [lat,lng]  ,  [lat,lng] .......  ]
    #리턴값은 측정한 거리(int값) list  ex) [ [0], [218667], [691542] ]
    #단위는 m
    def getDistance(self, center, pointList):

        # center가 None일 경우
        # 기본값으로 '내위치'의 좌표
        center = center or [self.my_location_lat, self.my_location_lng]

        script = """
        var tmp_point_arr = """ + str(pointList) + """
        var tmp_center = """ + str(center) + """
        var tmp_div = $('#tmp_div');
        var result_arr = new Array();
        for(var i=0; i < tmp_point_arr.length; i++){
            const polyline = new window.daum.maps.Polyline({
                map : map,
                path : [
                    new window.daum.maps.LatLng(tmp_center[0], tmp_center[1]),
                    new window.daum.maps.LatLng(tmp_point_arr[i][0], tmp_point_arr[i][1])
                ],
                strokeWeight : 0
            });
            result_arr.push(polyline.getLength());
        }
        return '['+result_arr.toString()+']';
        """
        result = list(map(int, eval(self.run(script))))
        print(result)
        for i in result:
            print(f"거리 : {i}m, type : {type(i)}")

        return result

    #좌표로 주소 얻기 idx
    #0 : 지번주소
    #1 : 지번주소 - 시도단위
    #2 : 지번주소 - 구 단위
    #3 : 지번주소 - 동 단위
    #4 : 지번주소 - 우편번호(6자리)
    #없을경우 ""
    def coord_to_address(self, lat, lng, idx):
        if not idx in (0, 1, 2, 3, 4):
            idx = 0
        result = ""
        print(lat)
        print(lng)
        script = """
        go_py_result = '대기중'
        var coord = new kakao.maps.LatLng(""" + str(lat) + """, """ + str(
            lng) + """);
        var c2a = function(result, status) {
            tmp_div.append("result0 -"+result[0].address.address_name);
            //go_py_result = result[0].address.address_name;
            var idx = """ + str(idx) + """


            if(idx === 0){
                go_py_result = result[0].address.address_name;
            }else if(idx === 1){
                go_py_result = result[0].address.region_1depth_name;
            }else if(idx === 2){
                go_py_result = result[0].address.region_2depth_name;
            }else if(idx === 3){
                go_py_result = result[0].address.region_3depth_name;
            }else if(idx === 4){
                go_py_result = result[0].address.zip_code;
            }else{
                go_py_result = result[0].address.address_name;
            }

        };
        geocoder.coord2Address(coord.getLng(), coord.getLat(), c2a);
        """
        script2 = "return go_py_result;"
        self.run(script)
        for i in range(50):
            result = self.run(script2)
            if result != "대기중":
                print("idx : ", idx, "c 2 a : ", result)
                return result
                break
        print("idx : ", idx, "c 2 a : ", result)
        return ""

    #지도 확대 레벨 설정
    def map_setLevel(self, level):
        script = """
        map.setLevel(""" + str(level) + """)
        """
        self.run(script)

    #마커 다 지우는 메소드
    def map_removeMarkers(self):
        script = """
        removeMarkers();
        """
        self.run(script)

    #맵 이동
    def setMap(self, lat, lng):
        script = """
        var umbrella_location = new kakao.maps.LatLng(""" + str(
            lat) + """, """ + str(lng) + """);
        map.setCenter(umbrella_location);
        """
        self.run(script)

    #스크립트 실행
    def run(self, script):
        # print("run runJavaScript")
        self.page.runJavaScript(script)
        # print("run execute_Script")
        result = self.browser.execute_script(script)
        return result

    def marking(self, data):
        typeP = ["", "약국", "우체국", "농협"]
        for item in data:
            addr = item.get('addr')
            code = item.get('code')
            created_at = item.get('created_at')
            lat = item.get('lat')
            lng = item.get('lng')
            name = item.get('name')
            remain_stat = item.get('remain_stat')
            stock_at = item.get('stock_at')
            type = typeP[int(item.get('type'))]
            print(
                f"addr = {addr}\ncode = {code}\ncreated_at = {created_at}\nlat = {lat}\nlng = {lng}\nname = {name}\nremain_stat = {remain_stat}\nstock_at = {stock_at}\ntype = {type}"
            )

            script = """










            """
            self.run(script)
Esempio n. 6
0
class POSM(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setLocale(QLocale(QLocale.English))
        self.initUI()
        self.setAttribute(Qt.WA_AlwaysShowToolTips)
        sizegrip = QtWidgets.QSizeGrip(self)
        self.layout.addWidget(sizegrip, 0,
                              QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight)

        self.record = [None]
        recordAction = QAction(datetime.datetime.now().strftime('%H:%M:%S'),
                               self)
        recordAction.triggered.connect(lambda: self.changeMap(0))
        self.recordMenu.addAction(recordAction)

    def initUI(self):
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.console = InformationalConsole(app)

        self.horSplitter = QSplitter(Qt.Horizontal)
        self.horSplitter.setChildrenCollapsible(False)
        self.editionSplitter = QSplitter(Qt.Vertical)
        self.editionSplitter.setChildrenCollapsible(False)

        self.queryUI = QueryUI()
        self.queryUI.setOnRequestChanged(self.changeCurrentMap)
        self.editionSplitter.addWidget(self.queryUI)

        self.queryWidget = QWidget()
        self.queryWidget.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Maximum)
        self.queryWidget.setLayout(QVBoxLayout())
        self.queryWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.queryWidget.layout().setSpacing(0)

        self.queryHeader = QLabel("Query")
        self.queryHeader.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Fixed)
        self.queryHeader.setFixedHeight(self.queryHeader.sizeHint().height() +
                                        10)
        self.queryHeader.setContentsMargins(5, 5, 0, 5)
        self.queryWidget.layout().addWidget(self.queryHeader)

        self.queryText = CodeEditor()
        self.qlHighlighter = OverpassQLHighlighter(self.queryText.document())
        self.queryText.setReadOnly(True)
        self.queryWidget.layout().addWidget(self.queryText)

        self.editionSplitter.addWidget(self.queryWidget)

        self.horSplitter.addWidget(self.editionSplitter)

        self.emptyMapPage = QWebEnginePage()
        self.emptyMapPage.setHtml(EMPTY_HTML)

        self.manualModePage = QWebEnginePage()
        soup = bs4.BeautifulSoup(EMPTY_HTML, features="html.parser")
        js = soup.new_tag("script")
        js.string = (MANUAL_MODE_JS_SCRIPT % (str([])))
        soup.append(js)

        self.manualModePage.setHtml(str(soup))

        self.mapRenderer = QWebEngineView()
        self.mapRenderer.setMinimumWidth(500)
        self.mapRenderer.setPage(self.emptyMapPage)

        self.consoleSplitter = QSplitter(Qt.Vertical)
        self.consoleSplitter.setChildrenCollapsible(False)
        self.consoleSplitter.addWidget(self.mapRenderer)

        self.consoleWidget = QWidget()
        self.consoleWidget.setLayout(QVBoxLayout())
        self.consoleWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.consoleWidget.layout().setSpacing(0)

        self.consoleHeader = QLabel("Console")
        self.consoleHeader.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Fixed)
        self.consoleHeader.setContentsMargins(5, 5, 0, 5)
        self.consoleWidget.layout().addWidget(self.consoleHeader)
        self.consoleWidget.layout().addWidget(self.console)

        self.consoleSplitter.addWidget(self.consoleWidget)

        self.horSplitter.addWidget(self.consoleSplitter)

        self.layout.addWidget(self.horSplitter)

        self.initMenuBar()

        centralWidget = QWidget(self)
        centralWidget.setLayout(self.layout)
        self.setCentralWidget(centralWidget)

        self.setWindowTitle('Python Open Street Map')

    def initMenuBar(self):
        menubar = self.menuBar()

        fileMenu = menubar.addMenu('File')

        openAct = QAction('Open netedit', self)
        openAct.triggered.connect(self.openNet)
        fileMenu.addAction(openAct)

        saveMenu = fileMenu.addMenu("Save")

        saveOutputAct = QAction('output', self)
        saveOutputAct.triggered.connect(self.saveNet)
        saveOutputAct.setShortcut('Ctrl+S')
        saveMenu.addAction(saveOutputAct)

        saveQueryAct = QAction('query', self)
        saveQueryAct.triggered.connect(self.saveQuery)
        saveQueryAct.setShortcut('Ctrl+Shift+S')
        saveMenu.addAction(saveQueryAct)

        saveInteractiveModeAct = QAction('interactive mode', self)
        saveInteractiveModeAct.triggered.connect(self.saveInteractiveQuery)
        saveMenu.addAction(saveInteractiveModeAct)

        openMenu = fileMenu.addMenu("Open")

        openQuery = QAction('query', self)
        openQuery.triggered.connect(self.openQuery)
        openQuery.setShortcut('Ctrl+O')
        openMenu.addAction(openQuery)

        openInteractiveMode = QAction('interactive mode', self)
        openInteractiveMode.triggered.connect(self.openInteractiveQuery)
        openMenu.addAction(openInteractiveMode)

        self.recordMenu = openMenu.addMenu("record")

        runMenu = menubar.addMenu('Run')

        playAct = QAction('Play', self)
        playAct.triggered.connect(self.playQuery)
        playAct.setShortcut('Ctrl+P')
        runMenu.addAction(playAct)

        playTableRowAct = QAction('Play row selection', self)
        playTableRowAct.triggered.connect(self.playTableRow)
        playTableRowAct.setShortcut('Ctrl+T')
        runMenu.addAction(playTableRowAct)

        self.requestMenu = menubar.addMenu('Request')

        addRequestAct = QAction('Add request', self)
        addRequestAct.triggered.connect(lambda b: self.addRequest())
        addRequestAct.setShortcut('Ctrl+A')
        self.requestMenu.addAction(addRequestAct)

        templatesMenu = self.requestMenu.addMenu("Add template")

        addRoadAct = QAction('Roads', self)
        addRoadAct.triggered.connect(lambda: self.addTemplate([
            OverpassFilter("highway", TagComparison.EQUAL, "", False, True),
            OverpassFilter("name", TagComparison.EQUAL, "", False, True),
            OverpassFilter("ref", TagComparison.EQUAL, "", False, True),
            OverpassFilter("maxspeed", TagComparison.AT_MOST, "120", False,
                           False),
            OverpassFilter("lanes", TagComparison.EQUAL, "", False, True),
            OverpassFilter("oneway", TagComparison.EQUAL, "", False, True)
        ]))
        templatesMenu.addAction(addRoadAct)

        addMainRoadAct = QAction('Main roads', self)
        mainHighways = "^(motorway|trunk|primary|secondary|residential)(_link)?$"
        everythingButYes = "^(y(e([^s]|$|s.)|[^e]|$)|[^y]|$).*"
        addMainRoadAct.triggered.connect(lambda: self.addTemplate([
            OverpassFilter("highway", TagComparison.EQUAL, mainHighways, False,
                           False),
            OverpassFilter("construction", TagComparison.HAS_NOT_KEY, "",
                           False, False),
            OverpassFilter("noexit", TagComparison.EQUAL, "yes", True, True),
            OverpassFilter("access", TagComparison.EQUAL, everythingButYes,
                           True, False)
        ]))
        templatesMenu.addAction(addMainRoadAct)

        addParkingAct = QAction('Parking', self)
        addParkingAct.triggered.connect(lambda: self.addTemplate([
            OverpassFilter("service", TagComparison.EQUAL, "parking", False,
                           False),
            OverpassFilter("highway", TagComparison.HAS_KEY, "", False, True)
        ]))
        templatesMenu.addAction(addParkingAct)

        addPedestriansAct = QAction('Pedestrians', self)
        pedestrianHighway = [
            "pedestrian", "footway", "path", "cycleway", "bridleway", "steps",
            "crossing"
        ]
        addPedestriansAct.triggered.connect(lambda: self.addTemplate([
            OverpassFilter("highway", TagComparison.IS_ONE_OF,
                           pedestrianHighway, False, True)
        ]))
        templatesMenu.addAction(addPedestriansAct)

        removeRequestAct = QAction('Remove current request', self)
        removeRequestAct.triggered.connect(self.removeRequest)
        removeRequestAct.setShortcut('Ctrl+R')
        self.requestMenu.addAction(removeRequestAct)

        self.manualModeAct = QAction(
            'Switch between interactive and manual mode', self)
        self.manualModeAct.triggered.connect(self.switchManualMode)
        self.requestMenu.addAction(self.manualModeAct)

        self.manualModeMenu = menubar.addMenu('Manual mode')
        self.manualModeMenu.setEnabled(False)

        manualModeCleanPolygonAct = QAction('Clean polygon', self)
        manualModeCleanPolygonAct.triggered.connect(
            self.cleanManualModePolygon)
        self.manualModeMenu.addAction(manualModeCleanPolygonAct)

        manualModeGetPolygonAct = QAction('Polygon coordinates', self)
        manualModeGetPolygonAct.triggered.connect(
            lambda: self.manualModePage.runJavaScript(
                "getPolygons();", self.logManualModePolygonCoords))
        self.manualModeMenu.addAction(manualModeGetPolygonAct)

        windowsMenu = menubar.addMenu('Windows')

        cleanMapAct = QAction('Clean map', self)
        cleanMapAct.triggered.connect(self.cleanMap)
        windowsMenu.addAction(cleanMapAct)

        self.showHideInteractiveModeAct = QAction('Interactive mode', self)
        self.showHideInteractiveModeAct.triggered.connect(
            self.showHideInteractiveMode)
        windowsMenu.addAction(self.showHideInteractiveModeAct)

        showHideConsole = QAction('Console', self)
        showHideConsole.triggered.connect(self.showHideConsole)
        windowsMenu.addAction(showHideConsole)

        showHideQuery = QAction('Query', self)
        showHideQuery.triggered.connect(self.showHideQuery)
        windowsMenu.addAction(showHideQuery)

    # ACTIONS
    def cleanMap(self):
        if self.queryText.isReadOnly():
            if self.queryUI.getCurrentMap() is not None:
                self.mapRenderer.setPage(self.queryUI.updateMaps(EMPTY_HTML))
        else:
            soup = bs4.BeautifulSoup(EMPTY_HTML, features="html.parser")
            js = soup.new_tag("script")
            js.string = (MANUAL_MODE_JS_SCRIPT % (str([])))
            soup.append(js)
            self.manualModePage.setHtml(str(soup))

        logging.info("Cleaning map")

    def changeMap(self, i):
        if i == 0:
            if not self.queryText.isReadOnly():
                self.switchManualMode()
            if self.queryText.isReadOnly():
                self.queryUI.reset()
                self.queryText.clear()
                self.mapRenderer.setPage(self.emptyMapPage)
                self.queryUI.updateMaps(EMPTY_HTML)
        elif self.record[i]["interactiveMode"]:
            if not self.queryText.isReadOnly():
                self.switchManualMode()
            if self.queryText.isReadOnly():
                self.queryUI.setQuery(self.record[i]["query"])
                self.queryText.setPlainText(self.record[i]["query"].getQL())
                self.mapRenderer.setPage(
                    self.queryUI.updateMaps(self.record[i]["html"]))
        else:
            if self.queryText.isReadOnly():
                self.switchManualMode()
            if not self.queryText.isReadOnly():
                self.queryUI.reset()
                self.queryText.setPlainText(self.record[i]["query"])
                self.manualModePage.setHtml(self.record[i]["html"])
                self.mapRenderer.setPage(self.manualModePage)

    def logManualModePolygonCoords(self, coords):
        coordsString = " ".join([str(c) for point in coords for c in point])
        logging.info("Polygon coordinates:\"{}\"".format(coordsString))
        pyperclip.copy(coordsString)
        logging.debug("LINE")

    def cleanManualModePolygon(self):
        logging.info("Cleaning polygon.")
        self.manualModePage.runJavaScript(
            "cleanPolygon();", lambda returnValue: logging.debug("LINE"))

    def showHideInteractiveMode(self):
        if self.queryUI.isHidden():
            if self.editionSplitter.isHidden():
                self.editionSplitter.show()
                self.queryText.hide()
            self.queryUI.show()
            logging.info("Showing 'Interactive mode' window.")
        else:
            if self.queryText.isHidden():
                self.editionSplitter.hide()
            self.queryUI.hide()
            logging.info("Hiding 'Interactive mode' window.")
        logging.debug("LINE")

    def showHideConsole(self):
        if self.console.isHidden():
            self.console.show()
            logging.info("Showing 'Console' window.")
            self.consoleWidget.setMaximumHeight(QWIDGETSIZE_MAX)
        else:
            self.console.hide()
            self.consoleWidget.setMaximumHeight(
                self.queryHeader.sizeHint().height())
            logging.info("Hiding 'Console' window.")
        logging.debug("LINE")

    def showHideQuery(self):
        if self.queryText.isHidden():
            if self.editionSplitter.isHidden():
                self.editionSplitter.show()
                self.queryUI.hide()
            self.queryText.show()
            logging.info("Showing 'Query' window.")
            self.queryWidget.setMaximumHeight(QWIDGETSIZE_MAX)
        else:
            if self.queryUI.isHidden():
                self.editionSplitter.hide()
            self.queryText.hide()
            self.queryWidget.setMaximumHeight(
                self.queryHeader.sizeHint().height())
            logging.info("Hiding 'Query' window.")
        logging.debug("LINE")

    def switchManualMode(self):
        if self.queryText.isReadOnly():
            reply = QMessageBox.question(
                self, "Manual mode",
                "Are you sure?\nThe interactive mode will remain as it is now."
            )

            if reply == QMessageBox.Yes:
                self.queryText.setReadOnly(False)

                self.queryUI.hide()
                for action in self.requestMenu.actions():
                    action.setEnabled(False)
                self.manualModeAct.setEnabled(True)
                self.manualModeMenu.setEnabled(True)
                self.showHideInteractiveModeAct.setEnabled(False)
                self.mapRenderer.setPage(self.manualModePage)

                logging.info("Switching to manual mode.")
            else:
                logging.info(
                    "'Switch between interactive and manual mode' cancelled.")
        else:
            reply = QMessageBox.question(
                self, "Interactive mode",
                "Are you sure?\nThe current query will be removed.")

            if reply == QMessageBox.Yes:
                try:
                    self.queryText.clear()
                    self.queryText.setPlainText(
                        self.queryUI.getQuery().getQL())
                except BadFilterAttributes as e:
                    logging.error(str(e))
                except RuntimeError:
                    logging.warning("Failed to write query.")
                    self.queryText.clear()
                    self.queryText.setPlainText("")

                self.queryText.setReadOnly(True)

                self.queryUI.show()
                for action in self.requestMenu.actions():
                    action.setEnabled(True)
                self.manualModeMenu.setEnabled(False)
                self.showHideInteractiveModeAct.setEnabled(True)
                self.changeCurrentMap(0)

                logging.info("Switching to interactive mode.")
            else:
                logging.info(
                    "'Switch between interactive and manual mode' cancelled.")

        logging.info("Showing 'manual mode' polygon.")

    def addRequest(self, filters=None):
        self.queryUI.addRequestByFilters(filters)
        logging.info("Request added.")
        logging.debug("LINE")

    def addTemplate(self, filters):
        logging.info("Template applied.")
        self.queryUI.addRequestByFilters(filters)

    def removeRequest(self):
        reply = QMessageBox.question(
            self, "Remove current request",
            "Are you sure? This option is not undoable.")

        if reply == QMessageBox.Yes:
            self.queryUI.removeRequest()
            logging.info("'Remove request' successfully executed.")
        else:
            logging.info("'Remove request' cancelled.")
        logging.debug("LINE")

    def saveQuery(self):
        filename, selectedFilter = QFileDialog.getSaveFileName(
            self, 'Save query', expanduser("~/filename.txt"),
            "Text files (*.txt)")

        if filename != "":
            if self.queryText.isReadOnly():
                try:
                    query = self.queryUI.getQuery().getQL()
                    f = open(filename, "w+")
                    f.seek(0)
                    f.truncate()
                    f.write(query)
                    f.close()

                    logging.info("Query saved successfully.")
                except (RuntimeError, BadFilterAttributes) as e:
                    logging.error(str(e))
                except OSError:
                    logging.error(
                        "There was a problem creating the file with the query."
                    )
            else:
                try:
                    f = open(filename, "w+")
                    f.seek(0)
                    f.truncate()
                    f.write(self.queryText.toPlainText())
                    f.close()

                    logging.info("Query saved successfully.")
                except OSError:
                    logging.error(
                        "There was a problem creating the file with the query."
                    )
        else:
            logging.info("\"Save query\" canceled.")

        logging.debug("LINE")

    def openQuery(self):
        filename, selectedFilter = QFileDialog.getOpenFileName(
            self, 'Open query', expanduser("~/filename.txt"))

        if filename != "":
            try:
                if self.queryText.isReadOnly():
                    self.switchManualMode()

                f = open(filename, "r")
                self.queryText.clear()
                self.queryText.setPlainText(f.read())
                f.close()

                logging.info("File read successfully.")
            except UnicodeDecodeError:
                logging.error("The given file is not readable as text.")
            except OSError:
                logging.error("There was a problem opening the query file.")
        else:
            logging.info("\"Open query\" canceled.")

        logging.debug("LINE")

    def saveInteractiveQuery(self):
        filename, selectedFilter = QFileDialog.getSaveFileName(
            self, 'Save query', expanduser("~/filename.json"),
            "JSON files (*.json)")

        if filename != "":
            try:
                query = self.queryUI.getQuery()
                query.saveToFile(filename)
                logging.info("Query saved successfully.")
            except (RuntimeError, BadFilterAttributes) as e:
                logging.error(str(e))
            except OSError:
                logging.error(
                    "There was a problem creating the file with the query.")
        else:
            logging.info("\"Save query\" canceled.")

        logging.debug("LINE")

    def openInteractiveQuery(self):
        filename, selectedFilter = QFileDialog.getOpenFileName(
            self, 'Open query', expanduser("~/filename.json"))

        if filename != "":
            try:
                self.queryUI.setQuery(OverpassQuery.getFromFile(filename))

                if not self.queryText.isReadOnly():
                    self.switchManualMode()
            except json.decoder.JSONDecodeError:
                logging.error(
                    "The given file has not the right format (json). The file could not be opened."
                )
            except UnicodeDecodeError:
                logging.error(
                    "The given file is not readable as text. The file could not be opened."
                )
            except (TypeError, KeyError):
                logging.error(
                    "Fields are missing from the file or there are fields with the wrong data type. "
                    "The file could not be opened.")
            except OSError:
                logging.error(
                    "There was a problem opening the query file. The file could not be opened."
                )
        else:
            logging.info("\"Open query\" canceled.")

        logging.debug("LINE")

    def saveNet(self):
        filename, selectedFilter = QFileDialog.getSaveFileName(
            self, 'Save File', expanduser("~/filenameWithoutExtension"))
        if filename != "":
            buildNet(filename)
        else:
            logging.info("\"Save File\" canceled.")
        logging.debug("LINE")
        return filename

    def openNet(self):
        try:
            filename = self.saveNet()
            if filename == "":
                logging.error("Can't open NETEDIT without a file.")
            else:
                openNetedit(filename + ".net.xml")
                logging.info("Opening NETEDIT.")
                logging.warning(
                    "If NETEDIT is not open in ten seconds, there was an unhandled problem."
                )
                logging.debug("LINE")
        except OSError:
            logging.error("Can't find NETEDIT.")
        except Exception:
            logging.error(traceback.format_exc())

    # POLYGONS
    def changeCurrentMap(self, i):
        if self.queryUI.getCurrentMap() is None:
            self.mapRenderer.setPage(self.emptyMapPage)
        else:
            self.mapRenderer.setPage(self.queryUI.getCurrentMap())

    def playQuery(self):
        newRecord = {
            "interactiveMode": self.queryText.isReadOnly(),
            "query": self.queryText.toPlainText(),
            "html": ""
        }

        if self.queryText.isReadOnly():
            try:
                query = self.queryUI.getQuery()
                newRecord["query"] = query
                self.queryText.setPlainText(query.getQL())
            except (RuntimeError, BadFilterAttributes) as e:
                logging.error(str(e))
                return
        try:
            html = buildHTMLWithQuery(self.queryText.toPlainText())
            if self.queryText.isReadOnly():
                self.mapRenderer.setPage(self.queryUI.updateMaps(html))
                newRecord["html"] = html
            else:
                soup = bs4.BeautifulSoup(html, features="html.parser")
                js = soup.new_tag("script")
                js.string = (MANUAL_MODE_JS_SCRIPT % (str([])))
                soup.append(js)

                self.manualModePage.setHtml(str(soup))
                newRecord["html"] = str(soup)
                self.mapRenderer.setPage(self.manualModePage)
            logging.info("Query drawn.")
            logging.debug("LINE")
            self.addRecord(newRecord)
        except (OverpassRequestException, OsmnxException) as e:
            logging.error(str(e))
        except ox.EmptyOverpassResponse:
            logging.error("There are no elements with the given query.")
        except OSError:
            logging.error(
                "There was a problem creating the file with the request response."
            )
        except Exception:
            logging.error(traceback.format_exc())

    def addRecord(self, newRecord):
        self.record.append(newRecord)
        index = len(self.record) - 1

        recordAction = QAction(datetime.datetime.now().strftime('%H:%M:%S'),
                               self)
        recordAction.triggered.connect(lambda: self.changeMap(index))
        self.recordMenu.addAction(recordAction)

    def playTableRow(self):
        try:
            self.mapRenderer.setPage(self.queryUI.updateMapFromRow())
        except (OverpassRequestException, OsmnxException) as e:
            logging.error(str(e))
            logging.warning(
                "Before open NETEDIT you must run a query with the row filters applied."
            )
        except ox.EmptyOverpassResponse:
            logging.error("There are no elements with the given row.")
        except OSError:
            logging.error(
                "There was a problem creating the file with the row selection."
            )
        except RuntimeError as e:
            logging.error(str(e))
        except Exception:
            logging.error(traceback.format_exc())
        logging.debug("LINE")

    # EVENTS
    def closeEvent(self, event):
        for f in os.listdir(tempDir):
            os.remove(os.path.join(tempDir, f))
        QMainWindow.closeEvent(self, event)
Esempio n. 7
0
class RequestWidget(QWidget):

    def __init__(self, parent, keyList, request=None):
        super().__init__(parent)

        self.keyList = keyList

        # INITIALIZE POLYGON MANAGEMENT

        self.polygonSettings = []
        self.polygonActivated = False
        self.html = ""
        self.webChannel = QWebChannel()
        self.webChannel.registerObject('request', self)
        self.polygonPage = QWebEnginePage()
        self.polygonPage.setWebChannel(self.webChannel)

        # INITIALIZE UI

        self.layout = self.__generateLayout__()
        self.setLayout(self.layout)

        elementsTypeGB, self.nodesCB, self.waysCB, self.relCB, self.areasCB = self.__generateTypeWidget__()
        self.layout.addRow("ELEMENTS TYPE", elementsTypeGB)
        self.layout.addRow(HorizontalLine(self))

        self.locationNameWidget = self.__generateLocationWidget__()
        self.layout.addRow("LOCATION", self.locationNameWidget)
        self.layout.addRow(HorizontalLine(self))

        filtersButtons, self.filtersWidget, self.filtersLayout = self.__generateFiltersWidget__()
        self.layout.addRow("FILTERS", filtersButtons)
        self.layout.addRow(self.filtersWidget)
        self.layout.addRow(HorizontalLine(self))

        polygonButtons = self.__generatePolygonWidget__()
        self.layout.addRow("POLYGON", polygonButtons)
        self.layout.addRow(HorizontalLine(self))

        self.surroundGB, self.aroundRadiusEdit = self.__generateSurroundingWidget__()
        self.layout.addRow("SURROUNDINGS", self.surroundGB)
        self.layout.addRow(HorizontalLine(self))

        self.idsWidget = self.__generateIdsWidget__()
        self.layout.addRow("IDS", self.idsWidget)

        # SETTING DATA

        if request is None:
            self.requestName = SetNameManagement.getUniqueSetName()
        else:
            self.__setRequest__(request)

    # UI COMPONENTS

    def __generateLayout__(self):
        layout = QFormLayout()
        layout.setContentsMargins(10, 10, 10, 10)

        layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
        layout.setLabelAlignment(Qt.AlignLeft)
        layout.setFormAlignment(Qt.AlignLeft | Qt.AlignTop)

        return layout

    def __generateLocationWidget__(self):
        locationNameWidget = QLineEdit()
        locationNameWidget.setPlaceholderText("Areas: 'New York', 'Italy'...")
        locationNameWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        return locationNameWidget

    def __generatePolygonWidget__(self):
        return WidgetFactory.buildIconButtonGroup([
            {"image": "polygon.png", "tooltip": "Draw polygon", "checkable": True, "action": self.enableDisablePolygon},
            {"image": "reset.png", "tooltip": "Remove polygon", "checkable": False, "action": self.clearPolygon}
        ])

    def __generateTypeWidget__(self):
        elementsTypeGB = QWidget()
        elementsTypeLayout = QVBoxLayout()
        elementsTypeGB.setLayout(elementsTypeLayout)
        elementsTypeLayout.setContentsMargins(10, 0, 0, 0)
        elementsTypeLayout.setSpacing(0)

        nodesCB = QCheckBox(self.tr("&Nodes"))
        elementsTypeLayout.addWidget(nodesCB)

        waysCB = QCheckBox(self.tr("&Ways"))
        waysCB.setChecked(True)
        elementsTypeLayout.addWidget(waysCB)

        relCB = QCheckBox(self.tr("&Relations"))
        elementsTypeLayout.addWidget(relCB)

        areasCB = QCheckBox(self.tr("&Areas"))
        areasCB.stateChanged.connect(self.__onAreaSelected__)
        elementsTypeLayout.addWidget(areasCB)

        nodesCB.stateChanged.connect(lambda b: self.areasCB.setChecked(False) if b else None)
        waysCB.stateChanged.connect(lambda b: self.areasCB.setChecked(False) if b else None)
        relCB.stateChanged.connect(lambda b: self.areasCB.setChecked(False) if b else None)

        return elementsTypeGB, nodesCB, waysCB, relCB, areasCB

    def __generateSurroundingWidget__(self):
        surroundGB = QGroupBox()
        surroundGB.setFlat(True)
        surroundLayout = QVBoxLayout()
        surroundLayout.setContentsMargins(0, 0, 0, 0)

        noneRB = QRadioButton(self.tr("&None"))
        noneRB.setObjectName("None")
        noneRB.setChecked(True)
        surroundLayout.addWidget(noneRB)

        adjacentRB = QRadioButton(self.tr("&Adjacent streets"))
        adjacentRB.setObjectName("Adjacent")
        surroundLayout.addWidget(adjacentRB)

        aroundRB = QRadioButton(self.tr("&Streets around"))
        aroundRB.setObjectName("Around")
        surroundLayout.addWidget(aroundRB)

        aroundRadiusEdit = QLineEdit("")
        aroundRadiusEdit.hide()
        aroundRadiusEdit.setPlaceholderText("Radius in meters")
        aroundRadiusEdit.setValidator(QIntValidator(0, 10000000, surroundGB))
        aroundRB.toggled.connect(lambda b: aroundRadiusEdit.show() if b else aroundRadiusEdit.hide())
        surroundLayout.addWidget(aroundRadiusEdit)

        surroundGB.setLayout(surroundLayout)

        return surroundGB, aroundRadiusEdit

    def __generateFiltersWidget__(self):
        filtersButtons = QWidget()
        filtersButtonsLayout = QHBoxLayout()
        filtersButtons.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        filtersButtonsLayout.setAlignment(Qt.AlignRight)
        filtersButtonsLayout.setSpacing(0)
        filtersButtonsLayout.setContentsMargins(0, 0, 0, 0)
        filtersButtons.setLayout(filtersButtonsLayout)

        addFilterButton = IconButton(QIcon(os.path.join(picturesDir, "add.png")),
                                     filtersButtons.windowHandle(),
                                     filtersButtons.height())
        addFilterButton.setToolTip("Add filter")
        addFilterButton.setFlat(True)
        addFilterButton.setStyleSheet("""QPushButton::menu-indicator{image: none;}""")

        filtersMenu = QMenu()

        equalAct = QAction('Equal', self)
        equalAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.EQUAL))
        filtersMenu.addAction(equalAct)

        maxAct = QAction('Maximum', self)
        maxAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.AT_MOST))
        filtersMenu.addAction(maxAct)

        minAct = QAction('Minimum', self)
        minAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.AT_LEAST))
        filtersMenu.addAction(minAct)

        containAllAct = QAction('Contain all', self)
        containAllAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.CONTAIN_ALL))
        filtersMenu.addAction(containAllAct)

        oneOfAct = QAction('Is one of', self)
        oneOfAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.IS_ONE_OF))
        filtersMenu.addAction(oneOfAct)

        hasKeyAct = QAction('Has key', self)
        hasKeyAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.HAS_KEY))
        filtersMenu.addAction(hasKeyAct)

        hasOneKeyAct = QAction('Has one key', self)
        hasOneKeyAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.HAS_ONE_KEY))
        filtersMenu.addAction(hasOneKeyAct)

        hasNotKeyAct = QAction('Has not key', self)
        hasNotKeyAct.triggered.connect(lambda: self.addFilterByComparison(comparison=TagComparison.HAS_NOT_KEY))
        filtersMenu.addAction(hasNotKeyAct)

        addFilterButton.setMenu(filtersMenu)

        filtersButtonsLayout.addWidget(addFilterButton)

        filtersWidget = QWidget(self)
        filtersLayout = QVBoxLayout()
        filtersLayout.setContentsMargins(10, 10, 10, 10)
        filtersWidget.setLayout(filtersLayout)

        return filtersButtons, filtersWidget, filtersLayout

    def __generateIdsWidget__(self):
        return VariableInputList(0, "Numeric id", QRegularExpressionValidator(QRegularExpression("^[0-9]+$")))

    # REQUEST GETTERS

    def __getLocationName__(self):
        return self.locationNameWidget.text()

    def __getType__(self):
        return OsmType.getType(self.nodesCB.isChecked(), self.waysCB.isChecked(),
                               self.relCB.isChecked(), self.areasCB.isChecked())

    def __getSelectedSurrounding__(self):
        switcher = {
            "Adjacent": Surround.ADJACENT,
            "Around": Surround.AROUND,
            "None": Surround.NONE
        }
        selectedSurrounding = [b for b in self.surroundGB.findChildren(QRadioButton) if b.isChecked()][0]
        return switcher.get(selectedSurrounding.objectName())

    @pyqtSlot(QJsonValue)
    def __setPolygons__(self, val):
        self.polygonSettings = []
        for point in val.toArray():
            self.polygonSettings.append([point["lat"].toDouble(), point["lng"].toDouble()])

    def __getPolygon__(self):
        return self.polygonSettings

    def getAroundRadius(self):
        return int(self.aroundRadiusEdit.text()) if len(self.aroundRadiusEdit.text()) > 0 else 100

    def getRequest(self):
        request = OverpassRequest(self.__getType__(),
                                  self.__getSelectedSurrounding__(),
                                  self.requestName,
                                  self.getAroundRadius())
        request.setLocationName(self.__getLocationName__())
        if request.locationId is None and request.locationName != "":
            logging.warning("Location name not found in the request '{}'. It will be ignored.".format(self.requestName))
        request.addPolygon(self.__getPolygon__())
        request.setIds(self.__getIds__())
        for filterWidget in self.filtersWidget.findChildren(FilterWidget):
            try:
                request.addFilter(filterWidget.getFilter())
            except BadFilterAttributes as e:
                raise BadFilterAttributes("Error in one of the filters of request '{}'. {}".format(self.requestName, str(e)))
        return request

    def getName(self):
        return self.requestName

    def getMap(self):
        return self.polygonPage

    def __getIds__(self):
        return self.idsWidget.getItems()

    # REQUEST SETTERS

    def addFilterByComparison(self, comparison):
        newFilterWidget = FilterWidget(self.filtersWidget, comparison, self.keyList)
        self.filtersLayout.addWidget(newFilterWidget)

    def addFilter(self, filter):
        currentKeys = {filter.getKey(): filter for filter in self.findChildren(FilterWidget)}
        if filter.key != "" and filter.key in currentKeys.keys():
            logging.warning("The key {} is used more than once in the set {}.".format(filter.key, self.getName()))
        newFilterWidget = FilterWidget(self.filtersWidget, filter.comparison, self.keyList)
        self.filtersLayout.addWidget(newFilterWidget)
        newFilterWidget.setFilter(filter)

    def __setLocationName__(self, locationName):
        self.locationNameWidget.setText(locationName)

    def __setType__(self, requestType):
        typeConfig = OsmType.getConfig(requestType)
        self.waysCB.setChecked(typeConfig["way"])
        self.nodesCB.setChecked(typeConfig["node"])
        self.relCB.setChecked(typeConfig["rel"])
        self.areasCB.setChecked(typeConfig["area"])

    def __setSelectedSurrounding__(self, surroundValue):
        if surroundValue == Surround.ADJACENT:
            self.surroundGB.findChild(QRadioButton, "Adjacent").setChecked(True)
        elif surroundValue == Surround.AROUND:
            self.surroundGB.findChild(QRadioButton, "Around").setChecked(True)
        elif surroundValue == Surround.NONE:
            self.surroundGB.findChild(QRadioButton, "None").setChecked(True)

    def changePolygon(self, coors):
        self.polygonSettings = coors
        if self.html != "":
            self.changePage(self.html)

    def setAroundRadius(self, radius):
        return self.aroundRadiusEdit.setText(str(radius))

    def __setRequest__(self, request):
        self.requestName = request.name
        self.__setType__(request.type)
        self.setAroundRadius(request.aroundRadius)
        self.__setSelectedSurrounding__(request.surrounding)
        for filterWidget in self.filtersWidget.findChildren(FilterWidget):
            filterWidget.deleteLater()
        for filter in request.filters:
            self.addFilter(filter)
        self.__setLocationName__(request.locationName)
        self.setIds(request.ids)
        self.changePolygon(request.polygon)

    def changePage(self, html):
        self.html = html
        soup = bs4.BeautifulSoup(html, features="html.parser")
        js = soup.new_tag("script")
        js.string = (JS_SCRIPT % (str(self.polygonSettings), str(self.polygonActivated).lower()))
        soup.append(js)
        soup.head.append(soup.new_tag("script", src="qrc:///qtwebchannel/qwebchannel.js"))
        htmlFileName = os.path.join(tempDir, "{}.html".format(self.requestName))
        with open(htmlFileName, "w+") as f:
            f.write(str(soup))

        self.polygonPage.load(QUrl.fromLocalFile(htmlFileName))

    def setIds(self, ids=None):
        self.idsWidget.setItems(ids)

    def addId(self, newId=0):
        self.idsWidget.addItem(newId)

    def __del__(self):
        SetNameManagement.releaseName(self.requestName)

    # SIGNALS

    def __onAreaSelected__(self):
        self.nodesCB.setChecked(False)
        self.waysCB.setChecked(False)
        self.relCB.setChecked(False)

    def clearPolygon(self):
        self.polygonPage.runJavaScript("cleanPolygon();", lambda x: logging.debug("LINE"))

    def enableDisablePolygon(self, checked):
        self.polygonActivated = checked
        self.polygonPage.runJavaScript("enablePolygon();" if checked else "disablePolygon();")
Esempio n. 8
0
class TestForm(QMainWindow, Ui_MainWindow):
    #생성자
    def __init__(self):
        super().__init__()
        self.setupUi(self)  # 초기화
        self.url = QUrl("http://localhost:8080/umbrella")
        self.webEngineView.load(QUrl(self.url))
        self.page = QWebEnginePage()
        self.page.setUrl(self.url)
        self.page.setView(self.webEngineView)

        self.comboBox.addItem("키워드")
        self.comboBox.addItem("주소")

        # self.page.featurePermissionRequested.connect(self.setPagePermission)

        self.pushButton.clicked.connect(self.search)
        self.lineEdit.returnPressed.connect(self.search)
        self.init_my_location()
        self.page.loadFinished.connect(
            lambda: self.setMap(self.my_location_lat, self.my_location_lng))
        # self.setMap(self.my_location_lat, self.my_location_lng)

    #아이피로 현재 위치 받아오기(google api 사용)
    def init_my_location(self):
        url = 'https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyDQKxbTt0MrFNH85kTJXzickMD5s88UVaI'
        data = {
            'considerIp': True,
        }

        result = requests.post(url, data)

        my_location = json.loads(result.text)
        # print(my_location)
        print("lat : ", my_location.get('location').get('lat'))
        print("lon : ", my_location.get('location').get('lng'))
        self.my_location_lat = my_location.get('location').get('lat')
        self.my_location_lng = my_location.get('location').get('lng')

    def setMap(self, lat, lng):
        script = """
        var umbrella_location = new kakao.maps.LatLng(""" + str(
            lat) + """, """ + str(lng) + """);
        map.setCenter(umbrella_location);
        """
        self.run(script)

    #위치권한 요청이 왔을때 허용해줌
    def setPagePermission(self, url, feature):
        self.page.setFeaturePermission(url, feature,
                                       QWebEnginePage.PermissionGrantedByUser)

    def search(self):

        search_text = self.lineEdit.text().strip()

        if self.comboBox.currentIndex() == 0:
            script = """
            removeMarkers();
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 장소 검색 객체를 생성합니다
            var ps = new kakao.maps.services.Places();

            // 키워드로 장소를 검색합니다
            ps.keywordSearch('""" + search_text + """', placesSearchCB);

            function placesSearchCB (data, status, pagination) {
                if (status === kakao.maps.services.Status.OK) {

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정하기위해
                    // LatLngBounds 객체에 좌표를 추가합니다
                    var bounds = new kakao.maps.LatLngBounds();

                    for (var i=0; i<data.length; i++) {
                        displayMarker(data[i]);
                        bounds.extend(new kakao.maps.LatLng(data[i].y, data[i].x));
                    }

                    // 검색된 장소 위치를 기준으로 지도 범위를 재설정합니다
                    map.setBounds(bounds);
                }
            }


            """
        elif self.comboBox.currentIndex():
            script = """

            removeMarkers();
            var positions = [];
            positions=Marker3.main3();
            for (var i=0; i<positions.length;i++){
                map:map,
                position:new kakao.maps.LatLng(positions[i].get('lat')+positions[i].get('lng'))
            }
            // 주소-좌표 변환 객체를 생성합니다
            var geocoder = new kakao.maps.services.Geocoder();

            // 주소로 좌표를 검색합니다
            geocoder.addressSearch('""" + search_text + """', function(result, status) {

                // 정상적으로 검색이 완료됐으면
                 if (status === kakao.maps.services.Status.OK) {

                    var coords = new kakao.maps.LatLng(result[0].y, result[0].x);

                    // 결과값으로 받은 위치를 마커로 표시합니다
                    var marker = new kakao.maps.Marker({
                        map: map,
                        position: coords
                    });



                    //*** 마커 담기
                    markerList.push(marker)


                    // 인포윈도우로 장소에 대한 설명을 표시합니다

                    infowindow.open(map, marker);

                    // 지도의 중심을 결과값으로 받은 위치로 이동시킵니다
                    map.setCenter(coords);
                }
            });    """

        else:

            return

        self.run(script)

    def run(self, script):
        self.page.runJavaScript(script)
Esempio n. 9
0
def eval_p_js_faf(page: QtWebEngineWidgets.QWebEnginePage, js: str):
    page.runJavaScript(js)