I am trying to create a video from a track in GPX or KML format from Google Street view images.
If I enter the data of the coordinates of a location, I can generate a JPG with that image.
My problem is that when I want it to be several points, then I can't do it.
I have tried to see if I can do it through the loaded page control, but it only does it with the last point that I send it.
I've also tried putting timeouts after asking for the page to load, but that doesn't work either.
Any idea how to do it?
from PyQt5.QtWidgets import QWidget, QApplication,QMainWindow,QFileDialog
from PyQt5.QtWidgets import QLineEdit, QVBoxLayout, QHBoxLayout,QSplitter,QPushButton
from PyQt5.QtCore import QUrl,QRect,QRectF
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView,QWebEngineProfile,QWebEngineSettings
import sys
import time
class Video_Google_Street(QMainWindow):
def __init__(self):
super().__init__()
self.showMaximized()
# Create GUI
self.centralwidget = QWidget(self)
self.layoutWidget = QWidget(self.centralwidget)
self.horizontalLayout = QVBoxLayout(self.centralwidget)
self.web_view=QWebEngineView(self.layoutWidget)
self.file_Gpx = QPushButton(self.layoutWidget)
self.file_Gpx.setText('GPX')
self.pb_fixed_point = QPushButton(self.layoutWidget)
self.pb_fixed_point.setText('Fixed Point')
self.pb_list_points = QPushButton(self.layoutWidget)
self.pb_list_points.setText('List of Points')
self.setCentralWidget(self.centralwidget)
self.horizontalLayout.addWidget(self.web_view)
self.horizontalLayout.addWidget(self.file_Gpx )
self.horizontalLayout.addWidget(self.pb_fixed_point)
self.horizontalLayout.addWidget(self.pb_list_points)
# Create Slots
# Slot when page is loaded
self.web_view.loadProgress.connect(self.webLoading)
self.file_Gpx.clicked.connect(self.select_track)
self.pb_fixed_point.clicked.connect(self.fixed_point)
self.pb_list_points.clicked.connect(self.list_points)
self.loaded=0 # For control how many times Google Street give page loaded. Give 4 or 6 times
def webLoading(self,event):
if event==100: # For control how many times Google Street give page loaded. Give 4 or 6 times
self.loaded+=1
print(self.loaded)
if self.loaded==6: # When give 6 loaded pages, then I grab the image
height=self.web_view.page().contentsSize().height()
width=self.web_view.page().contentsSize().width()
self.web_view.grab(QRect(0,0,width,height)).save(self.file_name_jpg, b'JPG')
self.loaded=0 # Restart Counter
def fixed_point(self):
# For test one fixed point
page='https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=42.2410144284368,0.965725583955646&heading=186.20048419497363&pitch=0'
url = QUrl(page)
self.file_name_jpg='c:/temp/jpg/Fixed_Point.jpg'
self.web_view.page().load(url)
def list_points(self):
# For test a list of points
points=[[42.2410144284368, 0.965725583955646], [42.2409574314952, 0.965720470994711], [42.240896243602, 0.965715777128935], [42.2408291045576, 0.965709993615747], [42.2407593671232, 0.965707311406732], [42.240682002157, 0.965706137940288], [42.2406058106571, 0.965705132111907], [42.2405290324241, 0.965702198445797], [42.2404542658478, 0.96570186316967], [42.2403736319393, 0.965694990009069], [42.2402878012508, 0.965689290314913], [42.2402046527714, 0.965683842077851], [42.2401182353497, 0.965680154040456], [42.2400250285864, 0.965676885098219], [42.2399284690619, 0.965670766308904], [42.239836268127, 0.965669928118587], [42.2397397086024, 0.965669760480523], [42.2396446578205, 0.965668670833111], [42.2395426500589, 0.965667329728603], [42.2394416481256, 0.965666742995381], [42.2393352817744, 0.965665988624096], [42.239225897938, 0.965662971138954], [42.2391161788255, 0.965662384405732], [42.2390032745898, 0.965660456568003], [42.238890286535, 0.965660959482193], [42.2387754544616, 0.965657522901893], [42.2386588621885, 0.965651236474514], [42.2385448683053, 0.965645201504231], [42.2384282760322, 0.965633047744632], [42.2383137792349, 0.965623240917921], [42.2381979413331, 0.965607399120927], [42.2380880545825, 0.965586444362998], [42.2379776649177, 0.965560711920261], [42.2378623299301, 0.965525507926941], [42.2377466596663, 0.965477395802736], [42.2376317437738, 0.965427858754992], [42.2375180851668, 0.965373795479536], [42.2374019119889, 0.965305985882878], [42.2372817993164, 0.965243289247155], [42.2371708229184, 0.965186543762684], [42.2370388079435, 0.965118734166026], [42.2369178570807, 0.965059977024794], [42.2367867641151, 0.965002393350005], [42.2366627119482, 0.964955454692245], [42.2365273442119, 0.964910443872213], [42.2363934852183, 0.96487800590694], [42.2362439520657, 0.964843891561031], [42.2360911499709, 0.964822098612785], [42.235938096419, 0.964814722537994], [42.2357739787549, 0.96481841057539], [42.2356092743576, 0.964833246544003], [42.2354392055422, 0.964861242100596], [42.235277434811, 0.96489611081779], [42.2350895125419, 0.964943552389741], [42.2349150013179, 0.964991580694914], [42.2347342036664, 0.965042291209102], [42.2345569264144, 0.965098952874541], [42.2343808226287, 0.965155195444822], [42.2342006955296, 0.965212108567357]]
self.file_name='List_Of_Points____' # Name used to save capture in JPG file
self.load_street_view(points)
def select_track(self):
# For test with a GPX or KML file
#self.file_name_gpx='c:/temp/jpg/GRMN6969.gpx'
self.file_name_gpx,_ = QFileDialog.getOpenFileName(self, 'Selecciona Fichero Track','c:/' , 'TRACK (*.gpx *.kml)')
self.read_track(self.file_name_gpx)
def read_track(self, file_name):
# Read a KML or GPX and convert in a list of points
from xml.dom import minidom
if file_name:
points=[]
doc = minidom.parse(file_name)
if file_name[-3:].upper()=='KML':
coordinates = doc.getElementsByTagName('coordinates')[0].firstChild.data
for element in coordinates.split():
lat=float(element.split(',')[0])
lon=float(element.split(',')[1])
points.append([lat,lon])
elif file_name[-3:].upper()=='GPX':
track = doc.getElementsByTagName("trkpt")
for punto in track:
lat=float(punto.getAttribute("lat"))
lon=float(punto.getAttribute("lon"))
points.append([lat,lon])
self.load_street_view(points)
def load_street_view(self, points):
# Read a list of points and
# Load a web page of Street view
for position in range(len(points)):
lat=points[position][0]
lon=points[position][1]
if not position==len(points)-1: # If it's the last point i can't calculate bearing
bearing=self.cal_bearing(lat,lon,points[position+1][0],points[position+1][1])
self.file_name_jpg=self.file_name[:-4]+"_"+str(position).zfill(5)+'.jpg'
# For testing use. See terms of use of Google
#page=('https://www.google.com/maps/@?api=1&map_action=pano&viewpoint={},{}&heading={}&pitch=0').format(str(lat),str(lon),bearing)
# Using Google API
page=('https://maps.googleapis.com/maps/api/streetview?size=600x300&location={},{}&heading={}&pitch=0&key=YOUR_API_KEY').format(str(lat),str(lon),bearing)
url = QUrl(page)
self.loaded=0
self.web_view.page().load(url)
def cal_bearing(self,lat1,lon1,lat2,lon2):
""" Calculate bearing between two coordinates """
from math import sin, cos, sqrt, atan2, radians, degrees
lat1 = radians(lat1)
lon1 = radians(lon1)
lat2 = radians(lat2)
lon2 = radians(lon2)
dLon = lon2 - lon1
y = sin(dLon) * cos(lat2)
x = cos(lat1)* sin(lat2) - sin(lat1)*cos(lat2)*cos(dLon)
initial_bearing = atan2(x, y)
# Now we have the initial bearing but math.atan2 return values
# from -180° to + 180° which is not what we want for a compass bearing
# The solution is to normalize the initial bearing as shown below
initial_bearing = degrees(initial_bearing)
compass_bearing = (initial_bearing + 360) % 360
compass_bearing -=80 # I don't know why, but I have to correct with -80
return compass_bearing
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Video_Google_Street()
win.show()
sys.exit(app.exec_())
I have found this somewhat homemade solution, but it works: