1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
2# Copyright (C) 2016-2019 German Aerospace Center (DLR) and others.
3# SUMOPy module
4# Copyright (C) 2012-2017 University of Bologna - DICAM
5# This program and the accompanying materials
6# are made available under the terms of the Eclipse Public License v2.0
7# which accompanies this distribution, and is available at
8# http://www.eclipse.org/legal/epl-v20.html
9# SPDX-License-Identifier: EPL-2.0
10
11# @file    wxgui-01-brokesave.py
12# @author  Joerg Schweizer
13# @date
14# @version $Id$
15
16import os
17import wx
18import numpy as np
19
20from agilepy.lib_wx.modulegui import ModuleGui
21from agilepy.lib_wx.ogleditor import *
22from agilepy.lib_base.processes import Process
23from agilepy.lib_wx.processdialog import ProcessDialog
24
25from coremodules.network import routing
26from coremodules.demand import demand
27
28import mapmatching
29
30
31class WxGui(ModuleGui):
32    """Contains functions that communicate between the widgets of the main wx gui
33    and the functions of the plugin.
34    """
35
36    def __init__(self, ident):
37        self._mapmatching = None
38        self._demand = None
39        self._results = None
40        self._init_common(ident,  priority=100001,
41                          icondirpath=os.path.join(os.path.dirname(__file__), 'images'))
42
43    def get_module(self):
44        return self._mapmatching
45
46    def get_scenario(self):
47        return self._mainframe.get_modulegui('coremodules.scenario').get_scenario()
48
49    def get_neteditor(self):
50        return self._mainframe.get_modulegui('coremodules.network').get_neteditor()
51
52    def init_widgets(self, mainframe):
53        """
54        Set mainframe and initialize widgets to various places.
55        """
56        self._mainframe = mainframe
57        #self._neteditor = mainframe.add_view("Network", Neteditor)
58
59        # mainframe.browse_obj(self._module)
60        self.make_menu()
61        self.make_toolbar()
62
63    def refresh_widgets(self):
64        """
65        Check through mainframe what the state of the application is
66        and reset widgets. For exampe enable/disable widgets
67        dependent on the availability of data.
68        """
69        scenario = self.get_scenario()
70        # print 'demand refresh_widgets',scenario.net
71        is_refresh = False
72        if self._demand != scenario.demand:
73            del self._demand
74            del self._mapmatching
75            self._demand = scenario.demand
76            self._mapmatching = mapmatching.Mapmatching('mapmatching', self._demand)
77            #self._mapmatching = self._demand.add_demandobject(ident = 'mapmatching', DemandClass = mapmatching.Mapmatching)
78            is_refresh = True
79
80    def make_menu(self):
81        menubar = self._mainframe.menubar
82        menubar.append_menu('plugins/mapmatching',
83                            bitmap=self.get_icon("icon_gps.png"),
84                            )
85        menubar.append_item('plugins/mapmatching/browse',
86                            self.on_browse,  # common function in modulegui
87                            info='View and browse mapmatching in object panel.',
88                            bitmap=self.get_agileicon('icon_browse_24px.png'),  # ,
89                            )
90
91        menubar.append_menu('plugins/mapmatching/import',
92                            bitmap=self.get_agileicon("Document_Import_24px.png"),
93                            )
94
95        menubar.append_item('plugins/mapmatching/import/European cycling challange...',
96                            self.on_import_ecc,
97                            info=self.on_import_ecc.__doc__.strip(),
98                            bitmap=self.get_agileicon("Document_Import_24px.png"),
99                            )
100
101        menubar.append_item('plugins/mapmatching/project points',
102                            self.on_project_points,
103                            bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_MENU),
104                            )
105
106        menubar.append_item('plugins/mapmatching/safe as...',
107                            self.on_save_as,
108                            info='Save all mapmatching  data in a new Python binary file.',
109                            bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE_AS, wx.ART_MENU),
110                            )
111
112        menubar.append_item('plugins/mapmatching/open...',
113                            self.on_open,
114                            info='Open previousely saved mapmatching data from a Python binary file.',
115                            bitmap=wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_MENU),
116                            )
117
118    def on_import_ecc(self, event=None):
119        """
120        Import and filter data from a European cycling challange.
121        """
122        p = mapmatching.EccTracesImporter(self._mapmatching, logger=self._mainframe.get_logger())
123        dlg = ProcessDialog(self._mainframe, p, immediate_apply=True)
124
125        dlg.CenterOnScreen()
126
127        # this does not return until the dialog is closed.
128        val = dlg.ShowModal()
129        # print '  val,val == wx.ID_OK',val,wx.ID_OK,wx.ID_CANCEL,val == wx.ID_CANCEL
130        # print '  status =',dlg.get_status()
131        if dlg.get_status() != 'success':  # val == wx.ID_CANCEL:
132            # print ">>>>>>>>>Unsuccessful\n"
133            dlg.Destroy()
134
135        if dlg.get_status() == 'success':
136            # print ">>>>>>>>>successful\n"
137            # apply current widget values to scenario instance
138            dlg.apply()
139            dlg.Destroy()
140            self._mainframe.browse_obj(self._mapmatching.trips)
141
142    def on_project_points(self, event=None):
143        self._mapmatching.points.project()
144        self._mainframe.browse_obj(self._mapmatching.points)
145
146        if event:
147            event.Skip()
148
149    def on_browse(self, event=None):
150
151        self._mainframe.browse_obj(self._mapmatching)
152        if event:
153            event.Skip()
154
155    def on_save_as(self, event=None):
156        if self._mapmatching is None:
157            return
158        scenario = self.get_scenario()
159        wildcards_all = "All files (*.*)|*.*"
160        wildcards_obj = "Python binary result files (*.mmatch.obj)|*.mmatch.obj|Python binary files (*.obj)|*.obj"
161        wildcards = wildcards_obj+"|"+wildcards_all
162
163        # Finally, if the directory is changed in the process of getting files, this
164        # dialog is set up to change the current working directory to the path chosen.
165        dlg = wx.FileDialog(
166            self._mainframe, message="Save mapmatching to file",
167            defaultDir=scenario.get_workdirpath(),
168            defaultFile=scenario.get_rootfilepath()+'.mmatch.obj',
169            wildcard=wildcards,
170            style=wx.SAVE | wx.CHANGE_DIR
171        )
172        val = dlg.ShowModal()
173        # Show the dialog and retrieve the user response. If it is the OK response,
174        # process the data.
175        if val == wx.ID_OK:
176            # This returns a Python list of files that were selected.
177            filepath = dlg.GetPath()
178            if len(filepath) > 0:
179                # now set new filename and workdir
180                self._mapmatching.save(filepath)
181
182        # Destroy the dialog. Don't do this until you are done with it!
183        # BAD things can happen otherwise!
184        dlg.Destroy()
185
186    def on_open(self, event=None):
187
188        wildcards_all = "All files (*.*)|*.*"
189        wildcards_obj = "Python binary mapmatching files (*.mmatch.obj)|*.mmatch.obj|Python binary files (*.obj)|*.obj"
190        wildcards = wildcards_obj+"|"+wildcards_all
191
192        # Finally, if the directory is changed in the process of getting files, this
193        # dialog is set up to change the current working directory to the path chosen.
194        dlg = wx.FileDialog(
195            self._mainframe, message="Open mapmatching file",
196            defaultDir=self.get_scenario().get_workdirpath(),
197            #defaultFile = os.path.join(scenario.get_workdirpath(), scenario.format_ident()+'.obj'),
198            wildcard=wildcards,
199            style=wx.OPEN | wx.CHANGE_DIR
200        )
201
202        # Show the dialog and retrieve the user response. If it is the OK response,
203        # process the data.
204        is_new = False
205        if dlg.ShowModal() == wx.ID_OK:
206            # This returns a Python list of files that were selected.
207            filepath = dlg.GetPath()
208            if len(filepath) > 0:
209                if self._mapmatching is not None:
210                    # browse away from results
211                    # self._mainframe.browse_obj(self._results.get_scenario())
212                    del self._mapmatching
213
214                self._mapmatching = mapmatching.load_mapmatching(filepath,
215                                                                 self.get_scenario().demand,
216                                                                 logger=self._mainframe.get_logger()
217                                                                 )
218                is_new = True
219
220        # Destroy the dialog. Don't do this until you are done with it!
221        # BAD things can happen otherwise!
222        dlg.Destroy()
223
224        if is_new:
225            # this should update all widgets for the new scenario!!
226            # print 'call self._mainframe.refresh_moduleguis()'
227            self._mainframe.browse_obj(self._mapmatching)
228            self._mainframe.select_view(name="Network")  # !!!!!!!!tricky, crashes without
229            self.refresh_widgets()
230