Example that shows how to integrate Google Maps within a Kivy application. Currently works only on Android.
Work in progress
-
Configure your
package.name
andpackage.domain
. The sum of both should not be more than 20 characters, or Google Maps API will not work:package.name = kivygmaps package.domain = com.mr
-
Follow the Android Maps API v2 documentation to get your Android Maps API key
-
Put your API Key into buildozer.spec in
[app:android.meta_data]
section ascom.google.android.maps.v2.API_KEY
:[app:android.meta_data] com.google.android.maps.v2.API_KEY = YOURAPIKEYHERE
The gmaps
module provide a GMap
widget that you can directly use into your
application. Right now, you can add only one GMap per application, on an
transparent background. If you cover the background, the widget will not be
shown. Here is an hello world example:
import gmaps
from kivy.app import App
class HelloGmaps(App):
def build(self):
self.map_widget = GMap()
self.map_widget.bind(on_ready=self.create_some_markers)
return self.map_widget
def create_some_markers(self, map_widget):
# get the google map interface
sydney = map_widget.create_latlng(-33.867, 151.206)
marker = map_widget.create_marker(
title='Sydney',
snippet='The most populous city in Autralia',
position=sydney)
map_widget.map.addMarker(marker)
if __name__ == '__main__':
HelloGmaps().run()
All the operation done on the map must be done within the internal thread of the android widget. It means, you cannot interact directly from Kivy. You can create object (LatLng, Marker..), but interact with the map must stay in the map thread.
All the event fired by the GMap
are happening in the map thread. For example,
if you bind to the GMap.on_map_click
, your callback will be already in the
map thread. If you want to call a method within the map thread, you can use
GMap.execute()
method. You cannot return values from it, and the call
will be asynchronous:
map = GMap()
def my_func(...):
pass
map.execute(my_func)
You can also decorate your function with android.runnable.run_on_ui_thread
, or GMap.run_on_ui_thread
:
from android.runnable import run_on_ui_thread
@run_on_ui_thread
def set_position(self, lat, lng):
pos = self.map_widget.create_latlng(lat, lng)
self.map_widget.map.moveCamera(
self.map_widget.camera_update_factory.newLatLngZoom(
pos, 13))
When the Android Google Maps widget is created, it will fire an event name
on_ready
. This is where you can create markers, change the camera, and so on.
Supported Google Maps events are:
on_camera_change(CameraPosition)
(not working yet)on_info_window_click(Marker)
on_map_click(LatLng)
on_map_loaded()
(not working yet)on_map_long_click(Marker)
on_marker_click(Marker)
on_marker_drag(Marker)
on_marker_drag_end(Marker)
on_marker_drag_start(Marker)
on_my_location_button_click
All the events are dispatched in the map thread, not the kivy main thread.
The GMap have some methods to create java object easily, such as:
GMap.create_latlng(lat, lng)
- Create a LatLng objectGMap.create_marker(**options)
Create a Marker object, with all the key=value in options
- Mathieu Virbel, Melting Rocks
- Thomas Hansen, Fresk