tianqi22 / monav

Automatically exported from code.google.com/p/monav
0 stars 0 forks source link

Python bindings for Monav #55

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Write a Python program
2. Try to use Monav from the program

What is the expected output? What do you see instead?

import monav # import the bindings
d = monav.Daemon("/path/to/map/data") # get a daemon controlling object
instance & set the data folder path
d.start() # start the daemon
route = d.route(lat1,lon1,lat2,lon2) # get a route (maybe also specify
route type and output format ?)
d.stop() # stop the daemon

This is of course just a simplified example of how it could work. :)

What version of the product are you using? On what operating system?
Monav 0.3

Please provide any additional information below.
Hi,
you mentioned a possibility of Python bindings in your email. 
So I thought it might be also helpful to submit a formal feature request here, 
so that others who might be interested in using/implementing the binding can 
see this to. :)

I'm also appending the resources I have found regarding Python + Qt 
interoperability:

Extending Python with C/C++
http://docs.python.org/extending/extending.html

"ctypes is a foreign function library for Python. It provides C
compatible data types, and allows calling functions in DLLs or shared
libraries. It can be used to wrap these libraries in pure Python."
http://docs.python.org/library/ctypes.html

Looks like Swig can be used to build Python bindings
http://www.swig.org/

This also claims to enable C++ to Python interoperability, but might be
a little outdated (2003)
http://www.boost.org/doc/libs/1_46_1/libs/python/doc/index.html

Then there are the PyQt
http://www.riverbankcomputing.co.uk/software/pyqt/intro
and PySide
http://www.pyside.org/
that provide Python bindings for the Qt toolkit - don't know how
relevant is this to writing Python bindings for a Qt based application.

SIP
http://wiki.python.org/moin/SIP
Looks like this is used by KDE and PyQt and tohers to creating their
Python bindings.

KDE & Python
http://techbase.kde.org/Development/Languages/Python
http://quickgit.kde.org/?p=pykde4.git&a=tree

The Qt based Clementine music player also has (SIP based) Python
bindings
http://gitorious.net/clementine/clementine/trees/master/src/scripting/python

Also the Marble virtual globe has SIP based Python bindings
http://quickgit.kde.org/index.php?p=marble.git&a=tree&hb=0d8cac904c9846d2c36f617
58c9e506270672f93&h=256954b1796098f82bbe4880a9f1156747028768&f=src/bindings/pyth
on

Original issue reported on code.google.com by martin.k...@gmail.com on 10 Jun 2011 at 12:05

GoogleCodeExporter commented 9 years ago
Also looks like I have submitted this under Defects and not feature requests. 
Unfortunately it looks like I can't change the category post factum...

Original comment by martin.k...@gmail.com on 10 Jun 2011 at 12:08

GoogleCodeExporter commented 9 years ago
Thanks for filing this officially. Thomas Miedema is already working on this 
and has some python bindings working, so we will definitely have this in 0.4.

Original comment by veaac.fd...@gmail.com on 10 Jun 2011 at 8:21

GoogleCodeExporter commented 9 years ago
I have merged Thomas Miedema's changes into default. Does it fit your needs?

Original comment by veaac.fd...@gmail.com on 6 Jul 2011 at 8:11

GoogleCodeExporter commented 9 years ago
More changes, please merge these as well:

http://code.google.com/r/thomasmiedema-python/source/list

Original comment by thomasmi...@gmail.com on 6 Jul 2011 at 1:16

GoogleCodeExporter commented 9 years ago
Done

Original comment by veaac.fd...@gmail.com on 6 Jul 2011 at 6:52

GoogleCodeExporter commented 9 years ago
Nice ! I'm currently travelling but I'll check it out once I get back in a few 
days. :)

Original comment by martin.k...@gmail.com on 6 Jul 2011 at 11:34

GoogleCodeExporter commented 9 years ago
Do I understand it correctly that you are using tcp and protobuf?

Have you considered using D-Bus? It would have bindings for many languages 
already.

I would like to implement speech output as a separate process that'd query 
monav for driving directions ;-) Speech output is one of the only missing 
pieces that I need from monav. I think it would be easier to prototype as a 
separate process.

Navit calls festival here but I'm not sure if that is a good way. Festival is 
very slow and often I miss the turning because navit is not able to tell 
festival in advance what to say. If monav had a D-Bus interface that would let 
me fetch the instructions in advance I could synthesise the speech in advance.

Original comment by timo.lin...@gmail.com on 21 Jul 2011 at 6:21

GoogleCodeExporter commented 9 years ago
Currently this interface is TCP + protobuffer or local sockets + protobuffer. 
It's intended to be used with the routing-daemon and not for the full-fledged 
Monav application.

Original comment by veaac.fd...@gmail.com on 22 Jul 2011 at 10:47

GoogleCodeExporter commented 9 years ago
So I finally got to testing the Python bindings (after more than a year...) and 
can report that they indeed WORK ! yay ! :)

This is how I tested them:

I have compiled the routing daemon first, like this:

qmake CONFIG+=release monavroutingdaemon.pro && make

then I went to the bin directory and started the monav-server:

cd bin
./monav-server

then I have downloaded & extracted data for the Czech Republic:

wget http://monav.openstreetmap.de/mapsets/Czech_Republic.zip
unzip Czech_Republic.zip

for the actual testing, this short Python script was used:

#!/usr/bin/env python

import monav

c = monav.TcpConnection()
print monav.get_version(c)

# Brno
lat1, lon1 = 49.2, 16.616667
# Prague
lat2, lon2 = 50.083333, 14.416667

# data for Czech Republic
dataPath = "Czech_Republic/routing_car"

waypoints = [(lat1, lon1),(lat2, lon2)]

route = monav.get_route(dataPath, waypoints, lookup_edge_names=False)
print route

The only issue is, that with lookup_edge_names=True, route lookup dies with 
this (probably caused by Czech street names that contain non-ASCII characters):

Traceback (most recent call last):
  File "./test.py", line 21, in <module>
    route = monav.get_route(dataPath, waypoints, lookup_edge_names=True)
  File "/home/melf-san/data/coding/gps/piskoviste/monav/fresh/monav/bin/monav.py", line 146, in get_route
    connection.read(result)
  File "/home/melf-san/data/coding/gps/piskoviste/monav/fresh/monav/bin/monav.py", line 78, in read
    message.ParseFromString(buf)
  File "/usr/lib/python2.7/dist-packages/google/protobuf/message.py", line 179, in ParseFromString
    self.MergeFromString(serialized)
  File "/usr/lib/python2.7/dist-packages/google/protobuf/internal/python_message.py", line 755, in MergeFromString
    if self._InternalParse(serialized, 0, length) != length:
  File "/usr/lib/python2.7/dist-packages/google/protobuf/internal/python_message.py", line 782, in InternalParse
    pos = field_decoder(buffer, new_pos, end, self, field_dict)
  File "/usr/lib/python2.7/dist-packages/google/protobuf/internal/decoder.py", line 397, in DecodeRepeatedField
    value.append(local_unicode(buffer[pos:new_pos], 'utf-8'))
UnicodeDecodeError: 'utf8' codec can't decode byte 0xed in position 2: invalid 
continuation byte

Original comment by martin.k...@gmail.com on 13 Aug 2012 at 11:57

GoogleCodeExporter commented 9 years ago
Christian, this unicode problem is also present in the routing daemon and was 
introduced with the protocol buffers changes. I fixed it in the following 
commit:
http://code.google.com/r/thomasmiedema-python/source/detail?r=909677b5e57b15c95c
ffc0ecad56e2a006eff684

Martin, you can try to use my clone, it should work now:
http://code.google.com/r/thomasmiedema-python/source/checkout
(you need to have mercurial installed)

Original comment by thomasmi...@gmail.com on 14 Aug 2012 at 5:30

GoogleCodeExporter commented 9 years ago
Thanks! I've pulled & compiled your clone and the issue seems too be fixed ! :) 
(The search finishes successfully and returns valid looking results with 
correct encoding.)

I had problems with the compile at first, but then found out the compile guide 
(http://code.google.com/p/monav/wiki/CompileGuide)is wrong - the correct syntax 
is CONFIG+=NOGUI, not CONFIG+=nogui. So the correct command for only compiling 
the routing daemon is:

qmake CONFIG+=release DEFINES+=NOGUI monavroutingdaemon.pro && make

Anyway, I'll make sure to let you know if I hit any other issues that show up 
while integrating the routing daemon & its Python bindings with modRana. :)

Original comment by martin.k...@gmail.com on 14 Aug 2012 at 8:01

GoogleCodeExporter commented 9 years ago
So I've successfully integrated Monav routing to modRana and even created a 
global up-to-date Monav routing data repository:
http://data.modrana.org/monav/
And repository generator:
https://github.com/M4rtinK/modrana-data-repository

But when I tried to route with more than 2 waypoints (eq. more than start & 
destination), the Monav server doesn't return any results and segfaults with a 
serialization error:

Starting MoNav TcpServer on port 8040 
Reading message of size: 2
Reading message of size: 0
Posting message of size: 5
Reading message of size: 2
Reading message of size: 99
found plugin: "Contraction Hierarchies" 
found plugin: "GPS Grid" 
loaded: "Car" "" 
GPS Lookup: 1 ms 
GPS Lookup: 1 ms 
Routing: 1 ms 
GPS Lookup: 0 ms 
GPS Lookup: 1 ms 
Routing: 2 ms 
libprotobuf FATAL google/protobuf/message_lite.cc:273] CHECK failed: 
IsInitialized(): Can't serialize message of type "MoNav.RoutingResult" because 
it is missing required fields: nodes[672].latitude, nodes[672].longitude
Qt has caught an exception thrown from an event handler. Throwing
exceptions from an event handler is not supported in Qt. You must
reimplement QApplication::notify() and catch all exceptions there.

terminate called after throwing an instance of 
'google::protobuf::FatalException'
  what():  CHECK failed: IsInitialized(): Can't serialize message of type "MoNav.RoutingResult" because it is missing required fields: nodes[672].latitude, nodes[672].longitude
Aborted (core dumped)

test.py (modified to use 3 waypoints) output:

0.4
Traceback (most recent call last):
  File "./test.py", line 24, in <module>
    route = monav.get_route(dataPath, waypoints)
  File "/home/melf-san/data/coding/gps/piskoviste/monav/fresh/thomasmiedema-python/bin/monav.py", line 146, in get_route
    connection.read(result)
  File "/home/melf-san/data/coding/gps/piskoviste/monav/fresh/thomasmiedema-python/bin/monav.py", line 62, in read
    size = struct.unpack("I", self._socket.recv(struct.calcsize("I")))[0]
struct.error: unpack requires a string argument of length 4

I'm attaching the modified test.py.

As the monav-server error message mentions "nodes[672]" the routing was most 
probably successful and the error is somewhere in the serialization or result 
generation code.

Please let me know if you need any more info. :)

Original comment by martin.k...@gmail.com on 8 Nov 2012 at 12:46

Attachments:

GoogleCodeExporter commented 9 years ago
I face the same problem as martin.k
I have problems when generating route for more than 2 waypoints.
There is a bug in server code in routingcommon.h file. I fixed it for my 
purposes so maybe someone can confirm that I fixed it...
I attached fixed file. There is also additional debug messages in this file to 
help me track the error. If everything is ok the debug messages should be 
removed.

By the way... This is great piece of software and very fast... Take care :)

Original comment by Kapusta....@gmail.com on 26 Jan 2013 at 7:41

Attachments: