Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
J
jr
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jiří Kalvoda
jr
Commits
7812cd3c
Commit
7812cd3c
authored
Jul 2, 2024
by
Jiří Kalvoda
Browse files
Options
Downloads
Patches
Plain Diff
QGIS: Reorganization and init of clickable vehicles
parent
1e39503e
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
prog/main.py
+278
-88
278 additions, 88 deletions
prog/main.py
with
278 additions
and
88 deletions
prog/main.py
+
278
−
88
View file @
7812cd3c
...
...
@@ -5,6 +5,8 @@ from qgis.gui import *
from
qgis.PyQt.QtXml
import
QDomDocument
,
QDomElement
from
qgis.PyQt.QtWidgets
import
*
from
qgis.PyQt.QtCore
import
*
from
qgis.PyQt.QtGui
import
*
import
sip
from
qasync
import
QEventLoop
,
asyncClose
,
asyncSlot
,
QApplication
import
asyncio
...
...
@@ -14,6 +16,7 @@ from communication import dt_to_path
import
datetime
import
json
import
sys
,
os
import
pprint
QgsApplication
.
setPrefixPath
(
"
/usr/
"
,
True
)
...
...
@@ -24,11 +27,274 @@ crs_wgs=QgsCoordinateReferenceSystem(4326)
crs_wgs_mercator
=
QgsCoordinateReferenceSystem
(
3857
)
crs_transform
=
QgsCoordinateTransform
(
crs_wgs
,
crs_wgs_mercator
,
QgsProject
.
instance
())
class
ClickableLabel
(
QLabel
):
clicked
=
pyqtSignal
()
def
mouseReleaseEvent
(
self
,
event
):
super
(
ClickableLabel
,
self
).
mouseReleaseEvent
(
event
)
if
event
.
button
()
==
Qt
.
LeftButton
and
event
.
pos
()
in
self
.
rect
():
self
.
clicked
.
emit
()
communications
=
{}
async
def
get_communication
(
cmd
=
'
ssh hluk.fnuk.eu /mnt/jr/prog/run_py server.py
'
):
if
cmd
not
in
communications
:
s
=
await
communication
.
SSHRunSocket
().
connect
(
cmd
)
communications
[
cmd
]
=
communication
.
DownloadServer
(
s
)
return
communications
[
cmd
]
class
Vehicle
:
def
__init__
(
self
,
json
):
self
.
json
=
json
class
MainWind
(
QMainWindow
):
def
__init__
(
self
):
self
.
map
=
MapWidget
()
QMainWindow
.
__init__
(
self
)
self
.
setCentralWidget
(
self
.
map
)
self
.
_menu_data
=
self
.
menuBar
().
addMenu
(
self
.
tr
(
"
&Data
"
))
self
.
_menu_data
.
addAction
(
"
Set date/time
"
,
self
.
set_date_time
)
uri
=
"
Point?field=vehicle_type:string(100)&field=route_short_name:string(20)&index=yes
"
self
.
data_layer
=
QgsVectorLayer
(
uri
,
'
PID realtime
'
,
'
memory
'
)
# self.data_layer.setAutoRefreshEnabled(True)
# self.data_layer.setAutoRefreshInterval(500)
d
=
QDomDocument
()
d
.
setContent
(
open
(
"
labeling.xml
"
).
read
())
labeling
=
QgsAbstractVectorLayerLabeling
.
create
(
d
.
documentElement
(),
QgsReadWriteContext
())
self
.
data_layer
.
setLabeling
(
labeling
)
self
.
data_layer
.
setLabelsEnabled
(
True
)
self
.
data_prov
=
self
.
data_layer
.
dataProvider
()
# set the map canvas layer set
self
.
map
.
canvas
.
setLayers
([
self
.
data_layer
,
orm
,
mapy_cz
])
self
.
feature_identifier
=
MainTool
(
self
,
self
.
map
.
canvas
)
#self.feature_identifier.setLayer(self.data_layer)
#self.feature_identifier.featureIdentified.connect(self.feature_clicked)
self
.
map
.
canvas
.
setMapTool
(
self
.
feature_identifier
)
self
.
current_data
=
[]
def
set_date_time
(
self
):
self
.
window_set_date_time
=
SetDateTimeWind
(
self
)
self
.
window_set_date_time
.
show
()
def
tool_identifier
(
self
):
self
.
map
.
canvas
.
setMapTool
(
feature_identifier
)
def
feature_clicked
(
self
,
feature
):
print
(
f
"
You clicked on feature
{
feature
}
"
)
async
def
load_data
(
self
,
dt
):
c
=
await
get_communication
()
for
fname
,
data
in
(
await
c
.
get_data
(
dt
)).
items
():
proc
=
await
asyncio
.
create_subprocess_exec
(
"
gunzip
"
,
stdout
=
asyncio
.
subprocess
.
PIPE
,
stdin
=
asyncio
.
subprocess
.
PIPE
)
stdout
,
stderr
=
await
proc
.
communicate
(
data
)
self
.
show_data
(
stdout
)
return
def
show_data
(
self
,
source_json
):
current_data
=
[]
feats
=
[]
data
=
json
.
loads
(
source_json
)
layer_fields
=
self
.
data_layer
.
fields
()
for
i
,
dato
in
enumerate
(
data
[
"
features
"
]):
feat
=
QgsFeature
(
layer_fields
)
coord
=
dato
[
"
geometry
"
][
"
coordinates
"
]
point
=
QgsPointXY
(
coord
[
0
],
coord
[
1
])
geometry
=
QgsGeometry
.
fromPointXY
(
point
)
# geometry = QgsGeometry.fromPointXY(QgsPointXY(coord[0]*130000, coord[1]*130000))
feat
.
setGeometry
(
geometry
)
dato_route_short_name
=
dato
[
"
properties
"
][
"
trip
"
][
"
gtfs
"
][
"
route_short_name
"
]
feat
[
"
route_short_name
"
]
=
str
(
dato_route_short_name
)
dato_vehicle_type
=
dato
[
"
properties
"
][
"
trip
"
][
"
vehicle_type
"
]
if
dato_vehicle_type
is
None
:
if
len
(
dato_route_short_name
)
and
dato_route_short_name
[
0
]
in
"
RSLUV
"
:
feat
[
"
vehicle_type
"
]
=
"
vlak
"
else
:
feat
[
"
vehicle_type
"
]
=
"
None
"
else
:
feat
[
"
vehicle_type
"
]
=
str
(
dato_vehicle_type
[
"
description_cs
"
])
feats
.
append
(
feat
)
vehicle
=
Vehicle
(
json
=
dato
)
vehicle
.
point
=
point
current_data
.
append
(
vehicle
)
self
.
current_data
=
current_data
self
.
data_prov
.
truncate
()
self
.
data_prov
.
addFeatures
(
feats
)
self
.
data_prov
.
reloadData
()
print
(
"
reloadData done
"
)
self
.
data_layer
.
triggerRepaint
()
print
(
"
repaintRequested done
"
)
class
SetDateTimeCaptureLabel
(
ClickableLabel
):
def
__init__
(
self
,
dt
,
window_set_date_time
):
QLabel
.
__init__
(
self
,
str
(
dt
.
second
))
self
.
window_set_date_time
=
window_set_date_time
self
.
dt
=
dt
self
.
setStyleSheet
(
"
color: green;
"
)
self
.
clicked
.
connect
(
self
.
on_click
)
@asyncSlot
()
async
def
on_click
(
self
):
print
(
self
.
dt
)
self
.
window_set_date_time
.
hide
()
await
self
.
window_set_date_time
.
window_main
.
load_data
(
self
.
dt
)
self
.
window_set_date_time
.
window_main
=
None
class
SetDateTimeHour
(
ClickableLabel
):
def
__init__
(
self
,
hour
,
window_set_date_time
):
QLabel
.
__init__
(
self
,
str
(
hour
))
self
.
window_set_date_time
=
window_set_date_time
self
.
hour
=
hour
self
.
clicked
.
connect
(
self
.
on_click
)
self
.
restyle
()
def
restyle
(
self
):
self
.
setStyleSheet
(
"
font-weight: bold;
"
if
self
.
hour
==
self
.
window_set_date_time
.
hour
else
""
)
print
(
self
.
hour
,
self
.
window_set_date_time
.
hour
)
def
on_click
(
self
):
self
.
window_set_date_time
.
hour
=
self
.
hour
self
.
window_set_date_time
.
master_changed
()
def
clearlayout
(
layout
):
for
i
in
reversed
(
range
(
layout
.
count
())):
layout
.
removeItem
(
layout
.
itemAt
(
i
))
class
SetDateTimeWind
(
QWidget
):
def
__init__
(
self
,
window_main
):
QWidget
.
__init__
(
self
)
self
.
window_main
=
window_main
self
.
hour
=
0
self
.
_calendar
=
QCalendarWidget
()
self
.
_calendar
.
setFirstDayOfWeek
(
Qt
.
Monday
)
self
.
_calendar
.
selectionChanged
.
connect
(
self
.
master_changed
)
self
.
_hour_layout
=
QGridLayout
()
self
.
_hours
=
[
SetDateTimeHour
(
i
,
self
)
for
i
in
range
(
24
)]
for
i
,
x
in
enumerate
(
self
.
_hours
):
self
.
_hour_layout
.
addWidget
(
x
,
i
//
6
,
i
%
6
)
self
.
_layout
=
QVBoxLayout
()
self
.
setLayout
(
self
.
_layout
)
self
.
_layout_calendar
=
QHBoxLayout
()
self
.
_layout
.
addWidget
(
self
.
_calendar
)
self
.
_layout
.
addLayout
(
self
.
_layout_calendar
)
self
.
_layout_calendar
.
addWidget
(
self
.
_calendar
)
self
.
_layout_calendar
.
addLayout
(
self
.
_hour_layout
)
self
.
_scroll
=
QScrollArea
()
self
.
_scroll
.
setWidgetResizable
(
True
)
self
.
_layout
.
addWidget
(
self
.
_scroll
)
self
.
_scroll_widget
=
QWidget
()
self
.
_scroll
.
setWidget
(
self
.
_scroll_widget
)
self
.
_scroll_layout
=
QGridLayout
()
self
.
_scroll_widget
.
setLayout
(
self
.
_scroll_layout
)
# self._layout.addLayout(self._scroll_layout)
self
.
_minutes_labels
=
[
QLabel
(
str
(
i
))
for
i
in
range
(
60
)]
for
x
in
self
.
_minutes_labels
:
x
.
setStyleSheet
(
"
font-weight: bold;
"
)
for
i
,
x
in
enumerate
(
self
.
_minutes_labels
):
self
.
_scroll_layout
.
addWidget
(
x
,
i
,
0
)
self
.
_10s_layouts
=
[[
QHBoxLayout
()
for
_
in
range
(
6
)]
for
_
in
range
(
60
)]
for
i
,
x
in
enumerate
(
self
.
_10s_layouts
):
for
j
,
y
in
enumerate
(
x
):
self
.
_scroll_layout
.
addLayout
(
y
,
i
,
j
+
1
)
self
.
_10s_labels
=
[[[]
for
j
in
range
(
6
)]
for
_
in
range
(
60
)]
self
.
master_changed
()
def
update_10s_layouts
(
self
,
_10s_labels
):
for
xa
,
xb
in
zip
(
self
.
_10s_layouts
,
self
.
_10s_labels
):
for
ya
,
yb
in
zip
(
xa
,
xb
):
for
z
in
yb
:
z
.
clear
()
clearlayout
(
ya
)
self
.
_10s_labels
=
_10s_labels
for
xa
,
xb
in
zip
(
self
.
_10s_layouts
,
self
.
_10s_labels
):
for
ya
,
yb
in
zip
(
xa
,
xb
):
for
z
in
yb
:
ya
.
addWidget
(
z
)
@asyncSlot
()
async
def
master_changed
(
self
):
for
x
in
self
.
_hours
:
x
.
restyle
()
date
=
datetime
.
datetime
.
combine
(
self
.
_calendar
.
selectedDate
().
toPyDate
(),
datetime
.
time
(
self
.
hour
,
0
,
0
))
self
.
update_10s_layouts
([[[
QLabel
(
f
"
{
j
}
0
"
)]
for
j
in
range
(
6
)]
for
_
in
range
(
60
)])
c
=
await
get_communication
()
_10s_labels
=
[[[]
for
j
in
range
(
6
)]
for
_
in
range
(
60
)]
dts
=
await
c
.
list_realtime_data
(
date
,
date
+
datetime
.
timedelta
(
hours
=
1
))
# TODO Check změny
for
dt
in
dts
:
_10s_labels
[
dt
.
minute
][
dt
.
second
//
10
].
append
(
SetDateTimeCaptureLabel
(
dt
,
self
))
self
.
update_10s_layouts
(
_10s_labels
)
class
MainTool
(
QgsMapTool
):
def
__init__
(
self
,
wnd
,
canvas
):
QgsMapTool
.
__init__
(
self
,
canvas
)
self
.
wnd
=
wnd
def
canvasClicked
(
self
,
e
):
pt
=
e
.
mapPoint
()
data_by_dist
=
sorted
([(
crs_transform
.
transform
(
x
.
point
).
distance
(
pt
),
x
)
for
x
in
self
.
wnd
.
current_data
],
key
=
lambda
x
:
x
[
0
])[:
10
]
for
d
,
x
in
data_by_dist
:
print
(
d
,
pt
,
x
.
point
)
pprint
.
pp
(
x
.
json
)
def
canvasMoveEvent
(
self
,
e
):
print
(
"
canvasMoveEvent
"
,
e
)
def
canvasPressEvent
(
self
,
e
):
print
(
"
canvasPressEvent
"
,
e
)
self
.
canvasClicked
(
e
)
def
canvasReleaseEvent
(
self
,
e
):
print
(
"
canvasReleaseEvent
"
,
e
)
class
MapWidget
(
QWidget
):
def
__init__
(
self
):
...
...
@@ -55,6 +321,7 @@ class MapWidget(QWidget):
#self.canvas.xyCoordinates.connect(self.xyCoordinates)
self
.
actionPan
.
triggered
.
connect
(
self
.
pan
)
#self.toolbar = self.addToolBar("Canvas actions")
#self.toolbar.addAction(self.actionZoomIn)
#self.toolbar.addAction(self.actionZoomOut)
...
...
@@ -70,114 +337,39 @@ class MapWidget(QWidget):
self
.
pan
()
@asyncSlot
()
async
def
zoomIn
(
self
):
# self.canvas.setMapTool(self.toolZoomIn)
s
=
await
communication
.
SSHRunSocket
().
connect
(
'
ssh hluk.fnuk.eu /mnt/jr/prog/run_py server.py
'
)
c
=
communication
.
DownloadServer
(
s
)
#await s.write(b"Ahoj!")
for
dt
in
await
c
.
list_realtime_data
(
datetime
.
datetime
(
2023
,
1
,
1
,
0
,
0
),
datetime
.
datetime
(
2100
,
1
,
1
,
0
,
0
)):
for
fname
,
data
in
(
await
c
.
get_data
(
dt
)).
items
():
print
(
fname
)
proc
=
await
asyncio
.
create_subprocess_exec
(
"
gunzip
"
,
stdout
=
asyncio
.
subprocess
.
PIPE
,
stdin
=
asyncio
.
subprocess
.
PIPE
)
stdout
,
stderr
=
await
proc
.
communicate
(
data
)
self
.
show_data
(
stdout
)
return
self
.
canvas
.
setExtent
(
QgsRectangle
(
crs_transform
.
transform
(
QgsPointXY
(
14.373
,
50.034
)),
crs_transform
.
transform
(
QgsPointXY
(
14.500
,
50.103
)))
)
def
show_data
(
self
,
source_json
):
feats
=
[]
self
.
canvas
.
setDestinationCrs
(
mapy_cz
.
crs
())
print
(
source_json
)
data
=
json
.
loads
(
source_json
)
for
i
,
dato
in
enumerate
(
data
[
"
features
"
]):
feat
=
QgsFeature
(
layer_fields
)
coord
=
dato
[
"
geometry
"
][
"
coordinates
"
]
geometry
=
QgsGeometry
.
fromPointXY
(
QgsPointXY
(
coord
[
0
],
coord
[
1
]))
# geometry = QgsGeometry.fromPointXY(QgsPointXY(coord[0]*130000, coord[1]*130000))
print
(
geometry
)
feat
.
setGeometry
(
geometry
)
dato_route_short_name
=
dato
[
"
properties
"
][
"
trip
"
][
"
gtfs
"
][
"
route_short_name
"
]
feat
[
"
route_short_name
"
]
=
str
(
dato_route_short_name
)
dato_vehicle_type
=
dato
[
"
properties
"
][
"
trip
"
][
"
vehicle_type
"
]
if
dato_vehicle_type
is
None
:
if
len
(
dato_route_short_name
)
and
dato_route_short_name
[
0
]
in
"
RSLUV
"
:
feat
[
"
vehicle_type
"
]
=
"
vlak
"
else
:
feat
[
"
vehicle_type
"
]
=
"
None
"
else
:
feat
[
"
vehicle_type
"
]
=
str
(
dato_vehicle_type
[
"
description_cs
"
])
feats
.
append
(
feat
)
prov
.
truncate
()
prov
.
addFeatures
(
feats
)
prov
.
reloadData
()
print
(
"
reloadData done
"
)
mem_layer
.
triggerRepaint
()
print
(
"
repaintRequested done
"
)
async
def
zoomIn
(
self
):
self
.
canvas
.
setMapTool
(
self
.
toolZoomIn
)
def
zoomOut
(
self
):
self
.
canvas
.
setMapTool
(
self
.
toolZoomOut
)
canvas
.
setMapTool
(
feature_identifier
)
print
(
mem_layer
,
mem_layer
.
crs
())
print
(
mapy_cz
,
mapy_cz
.
crs
())
print
(
orm
,
orm
.
crs
())
def
xyCoordinates
(
self
,
x
):
print
(
x
)
def
pan
(
self
):
self
.
canvas
.
setMapTool
(
self
.
toolPan
)
def
tool_identifier
(
self
):
canvas
.
setMapTool
(
feature_identifier
)
def
callback
(
self
,
feature
):
print
(
f
"
You clicked on feature
{
feature
}
"
)
# create Qt application
app
=
QApplication
([])
# create main window
wnd
=
MainWind
()
canvas
=
wnd
.
map
.
canvas
# Move the app window to upper left
wnd
.
size
()
wnd
.
show
()
orm
=
QgsRasterLayer
(
'
crs=EPSG:4326&format&type=xyz&url=https://a.tiles.openrailwaymap.org/standard/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0
'
,
'
ORM-standard
'
,
'
wms
'
)
osm
=
QgsRasterLayer
(
'
crs=EPSG:4326&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0
'
,
'
ORM-standard
'
,
'
wms
'
)
mapy_cz
=
QgsRasterLayer
(
'
http-header:referer=https://mapy.cz/ &referer=https://mapy.cz/ &type=xyz&url=https://mapserver.mapy.cz/base-m/%7Bz%7D-%7Bx%7D-%7By%7D
'
,
'
mapycz-standard
'
,
'
wms
'
)
# create main window
wnd
=
MainWind
()
canvas
=
wnd
.
map
.
canvas
wnd
.
show
()
uri
=
"
Point?field=vehicle_type:string(100)&field=route_short_name:string(20)&index=yes
"
mem_layer
=
QgsVectorLayer
(
uri
,
'
PID realtime
'
,
'
memory
'
)
# mem_layer.setAutoRefreshEnabled(True)
# mem_layer.setAutoRefreshInterval(500)
d
=
QDomDocument
()
d
.
setContent
(
open
(
"
labeling.xml
"
).
read
())
labeling
=
QgsAbstractVectorLayerLabeling
.
create
(
d
.
documentElement
(),
QgsReadWriteContext
())
mem_layer
.
setLabeling
(
labeling
)
mem_layer
.
setLabelsEnabled
(
True
)
prov
=
mem_layer
.
dataProvider
()
layer_fields
=
mem_layer
.
fields
()
canvas
.
setExtent
(
QgsRectangle
(
crs_transform
.
transform
(
QgsPointXY
(
14.373
,
50.034
)),
crs_transform
.
transform
(
QgsPointXY
(
14.500
,
50.103
)))
)
# set the map canvas layer set
canvas
.
setLayers
([
mem_layer
,
orm
,
mapy_cz
])
feature_identifier
=
QgsMapToolIdentifyFeature
(
canvas
)
feature_identifier
.
featureIdentified
.
connect
(
wnd
.
map
.
callback
)
canvas
.
setDestinationCrs
(
mapy_cz
.
crs
())
# run!
event_loop
=
QEventLoop
(
app
)
...
...
@@ -185,8 +377,6 @@ asyncio.set_event_loop(event_loop)
app_close_event
=
asyncio
.
Event
()
app
.
aboutToQuit
.
connect
(
app_close_event
.
set
)
print
(
mem_layer
,
mem_layer
.
crs
())
with
event_loop
:
event_loop
.
run_until_complete
(
app_close_event
.
wait
())
#retval = app.exec_()
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment