[gnome-maps/wip/jonasdn/vector-tiles] Add support to render with vector-tile-glib
- From: Jonas Danielsson <jonasdn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps/wip/jonasdn/vector-tiles] Add support to render with vector-tile-glib
- Date: Mon, 20 Apr 2015 20:55:18 +0000 (UTC)
commit d27ccd9b0f736aee832a9f991f2b400bcd9b1b2c
Author: Jonas Danielsson <jonas threetimestwo org>
Date: Sat Apr 18 12:22:51 2015 +0200
Add support to render with vector-tile-glib
configure.ac | 2 +
data/Makefile.am | 4 +-
data/gnome-maps.mapcss | 88 +++++++++++++++++
lib/Makefile.am | 28 ++++--
lib/maps-mapbox-renderer.c | 223 ++++++++++++++++++++++++++++++++++++++++++++
lib/maps-mapbox-renderer.h | 75 +++++++++++++++
src/mapView.js | 42 ++++++++-
7 files changed, 453 insertions(+), 9 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4d7b796..dced899 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,6 +50,8 @@ PKG_CHECK_MODULES(GNOME_MAPS_LIB, [
folks >= $FOLKS_MIN_VERSION
geocode-glib-1.0 >= $GEOCODE_MIN_VERSION
champlain-0.12 >= $CHAMPLAIN_MIN_VERSION
+ vector-tile-glib-1.0
+ cairo
])
AC_SUBST(GNOME_MAPS_LIB_CFLAGS)
AC_SUBST(GNOME_MAPS_LIB_LIBS)
diff --git a/data/Makefile.am b/data/Makefile.am
index e0ce3e9..9c7511e 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -12,7 +12,9 @@ org.gnome.Maps.data.gresource: org.gnome.Maps.data.gresource.xml $(app_resource_
--sourcedir=$(srcdir) $<
resourcedir = $(pkgdatadir)
-resource_DATA = org.gnome.Maps.data.gresource
+resource_DATA = \
+ org.gnome.Maps.data.gresource \
+ gnome-maps.mapcss
appsdir = $(datadir)/applications
apps_DATA = org.gnome.Maps.desktop
diff --git a/data/gnome-maps.mapcss b/data/gnome-maps.mapcss
new file mode 100644
index 0000000..ed2f0b7
--- /dev/null
+++ b/data/gnome-maps.mapcss
@@ -0,0 +1,88 @@
+canvas {
+ fill-color: #FAEBD7;
+}
+
+way {
+ color: #777777;
+ width: 1;
+ linecap: round;
+}
+
+way[highway] {
+ color: #ffffff;
+ linecap: round;
+ casing-linecap: round;
+ linejoin: miter;
+ casing-linejoin: miter;
+ casing-width: 1;
+ width: 5;
+ casing-color: #C7B8A4;
+}
+
+
+way[highway=motorway], way[highway=motorway_link],
+way[highway=trunk], way[highway=trunk_link] {
+ casing-width: 0.95;
+ color: #ff9966;
+ casing-color: #bb5500;
+ width: 5;
+}
+way[highway=primary], way[highway=primary_link] {
+ casing-width: 0.8;
+ width: 2;
+ color: #ffbb88;
+ casing-color: #cc6600;
+}
+
+way[highway=footway] {
+ color: #770000;
+ width: 1;
+ dashes: 2, 2;
+}
+
+way[highway=cycleway] {
+ color: #000077;
+ width: 1;
+ dashes: 2, 2;
+}
+
+area {
+ color: #FAEBD7;
+ fill-color: #FAEBD7;
+ width: 1;
+}
+
+area[landuse=park], area[landuse=playground], area[landuse=pitch] {
+ fill-color: #73D216;
+ color: #73D216;
+}
+
+area[landuse=wood], area[landuse=scrub] {
+ fill-color: #0D6C00;
+ color: #0D6C00;
+ z-index: 1;
+}
+
+area[water], way[water], area[natural=water] {
+ color: #4A90D9;
+ fill-color: #4A90D9;
+}
+
+area[building] {
+ color: #777777;
+ fill-color: #C7B8A4;
+}
+
+way[is_bridge=yes] {
+ color: #333333;
+ width: 2;
+}
+
+way[is_tunnel=yes] {
+ color: #333333;
+ width: 2;
+ dashes: 3, 3;
+}
+
+
+
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 35203da..f7e83f7 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -4,8 +4,17 @@ BUILT_SOURCES = \
maps-enum-types.c \
maps-enum-types.h
-libgnome_maps_headers_private = maps-contact-store.h maps-contact.h maps.h
-libgnome_maps_sources = maps-contact-store.c maps-contact.c
+libgnome_maps_headers_private = \
+ maps-contact-store.h \
+ maps-contact.h \
+ maps-mapbox-renderer.h \
+ maps.h
+
+libgnome_maps_sources = \
+ maps-contact-store.c \
+ maps-contact.c \
+ maps-mapbox-renderer.c
+
libgnome_maps_la_SOURCES = \
$(libgnome_maps_sources) \
$(libgnome_maps_headers_private) \
@@ -19,12 +28,12 @@ AM_CPPFLAGS = \
maps-enum-types.h: $(libgnome_maps_headers_private)
$(AM_V_GEN) ($(GLIB_MKENUMS) \
- --template $(srcdir)/maps-enum-types.h.template \
+ --template $(srcdir)/maps-enum-types.h.template \
$^ > xgen-$(@F) && mv -f xgen-$(@F) $@)
maps-enum-types.c: $(libgnome_maps_headers_private) maps-enum-types.h
$(AM_V_GEN) ($(GLIB_MKENUMS) \
- --template $(srcdir)/maps-enum-types.c.template \
+ --template $(srcdir)/maps-enum-types.c.template \
$^ > xgen-$(@F) && mv -f xgen-$(@F) $@)
if HAVE_INTROSPECTION
@@ -37,10 +46,15 @@ GnomeMaps_1_0_gir_INCLUDES = \
GObject-2.0 \
GeocodeGlib-1.0 \
Champlain-0.12
-GnomeMaps_1_0_gir_PACKAGES = gobject-2.0 geocode-glib-1.0
+GnomeMaps_1_0_gir_PACKAGES = gobject-2.0 geocode-glib-1.0 champlain-0.12 cairo
GnomeMaps_1_0_gir_FILES = $(libgnome_maps_la_SOURCES)
-GnomeMaps_1_0_gir_CFLAGS = $(MAPS_CFLAGS) -I$(top_srcdir) -I$(top_builddir) -I$(srcdir)
-GnomeMaps_1_0_gir_LIBS = libgnome-maps.la
+GnomeMaps_1_0_gir_CFLAGS = \
+ $(GNOME_MAPS_LIB_CFLAGS) \
+ $(GNOME_MAPS_LIB_LIBS) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(srcdir)
+GnomeMaps_1_0_gir_LIBS = libgnome-maps.la champlain-0.12
GnomeMaps_1_0_gir_EXPORT_PACKAGES = gnome-maps-1.0
GnomeMaps_1_0_gir_SCANNERFLAGS = \
--symbol-prefix=maps \
diff --git a/lib/maps-mapbox-renderer.c b/lib/maps-mapbox-renderer.c
new file mode 100644
index 0000000..adf148b
--- /dev/null
+++ b/lib/maps-mapbox-renderer.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2015 Jonas Danielsson
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+#include <vector-tile-mapbox.h>
+#include <cairo.h>
+
+#include "maps-mapbox-renderer.h"
+
+struct _MapsMapboxRendererPrivate
+{
+ gchar *data;
+ guint size;
+
+ VTileMapCSS *stylesheet;
+};
+
+typedef struct _RenderData
+{
+ ChamplainTile *tile;
+ ClutterContent *canvas;
+ gchar *data;
+ guint size;
+ VTileMapCSS *stylesheet;
+} RenderData;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsMapboxRenderer, maps_mapbox_renderer, CHAMPLAIN_TYPE_RENDERER)
+
+static void set_data (ChamplainRenderer *renderer,
+ const gchar *data,
+ guint size);
+static void render (ChamplainRenderer *renderer,
+ ChamplainTile *tile);
+
+static void
+maps_mapbox_renderer_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (maps_mapbox_renderer_parent_class)->dispose (object);
+}
+
+
+static void
+maps_mapbox_renderer_finalize (GObject *object)
+{
+ MapsMapboxRenderer *renderer = MAPS_MAPBOX_RENDERER (object);
+ g_free (renderer->priv->data);
+
+ G_OBJECT_CLASS (maps_mapbox_renderer_parent_class)->finalize (object);
+}
+
+
+static void
+maps_mapbox_renderer_class_init (MapsMapboxRendererClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ChamplainRendererClass *renderer_class = CHAMPLAIN_RENDERER_CLASS (klass);
+
+ object_class->finalize = maps_mapbox_renderer_finalize;
+ object_class->dispose = maps_mapbox_renderer_dispose;
+
+ renderer_class->set_data = set_data;
+ renderer_class->render = render;
+}
+
+
+static void
+maps_mapbox_renderer_init (MapsMapboxRenderer *renderer)
+{
+ renderer->priv = maps_mapbox_renderer_get_instance_private (renderer);
+ renderer->priv->data = NULL;
+ renderer->priv->size = 0;
+}
+
+
+/**
+ * maps_mapbox_renderer_new:
+ *
+ * Returns: (transfer full): a new #MapsMapboxRenderer object, use g_object_unref() when done.
+ *
+ */
+MapsMapboxRenderer *
+maps_mapbox_renderer_new (void)
+{
+ return g_object_new (MAPS_TYPE_MAPBOX_RENDERER, NULL);
+}
+
+void
+maps_mapbox_renderer_load_css (MapsMapboxRenderer *renderer,
+ const char *filename,
+ GError **error)
+{
+ renderer->priv->stylesheet = vtile_mapcss_new ();
+ vtile_mapcss_load (renderer->priv->stylesheet, filename, error);
+}
+
+
+static void
+set_data (ChamplainRenderer *renderer_base, const gchar *data, guint size)
+{
+ MapsMapboxRenderer *renderer = (MapsMapboxRenderer *) renderer_base;
+
+ if (renderer->priv->data)
+ g_free (renderer->priv->data);
+
+ renderer->priv->data = g_memdup (data, size);
+ renderer->priv->size = size;
+}
+
+static void
+on_mapbox_rendered (VTileMapbox *mapbox,
+ GAsyncResult *res,
+ RenderData *data)
+{
+
+}
+
+gboolean
+on_canvas_draw (ClutterCanvas *canvas,
+ cairo_t *cr,
+ gint width,
+ gint height,
+ RenderData *data)
+{
+ VTileMapbox *mapbox;
+ cairo_surface_t *surface;
+ char output[512];
+ ClutterActor *actor = NULL;
+ GError *error = NULL;
+ gboolean success;
+
+ mapbox = vtile_mapbox_new (data->data,
+ data->size,
+ width,
+ champlain_tile_get_zoom_level (data->tile));
+
+ vtile_mapbox_set_stylesheet (mapbox, data->stylesheet);
+
+
+ cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_restore (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ vtile_mapbox_render (mapbox, cr, NULL);
+
+ actor = clutter_actor_new ();
+ clutter_actor_set_size (actor,
+ champlain_tile_get_size (data->tile),
+ champlain_tile_get_size (data->tile));
+ clutter_actor_set_content (actor, data->canvas);
+ g_object_unref (data->canvas);
+
+ /* clutter_actor_set_offscreen_redirect (actor,
+ CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY); */
+
+ finish:
+ if (actor)
+ champlain_tile_set_content (data->tile, actor);
+
+ g_signal_emit_by_name (data->tile, "render-complete",
+ data->data, data->size, success);
+
+
+ g_object_unref (data->tile);
+ g_free (data->data);
+ g_free (data);
+
+ /*
+ sprintf (output, "%d-%d-%d.png\n",
+ champlain_tile_get_x (data->tile),
+ champlain_tile_get_y (data->tile),
+ champlain_tile_get_zoom_level (data->tile));
+ surface = cairo_get_target (cr);
+ cairo_surface_write_to_png (surface, output);
+ */
+
+
+ return TRUE;
+}
+
+static void
+render (ChamplainRenderer *renderer_base, ChamplainTile *tile)
+{
+ MapsMapboxRenderer *renderer = (MapsMapboxRenderer *) renderer_base;
+ RenderData *data;
+
+ if (!renderer->priv->data || renderer->priv->size == 0)
+ {
+ g_signal_emit_by_name (tile, "render-complete",
+ renderer->priv->data, renderer->priv->size, TRUE);
+ return;
+ }
+
+ data = g_new0 (RenderData, 1);
+ data->tile = g_object_ref (tile);
+ data->data = g_memdup (renderer->priv->data, renderer->priv->size);
+ data->size = renderer->priv->size;
+ data->stylesheet = renderer->priv->stylesheet;
+ data->canvas = clutter_canvas_new ();
+
+ clutter_canvas_set_size ((ClutterCanvas *) data->canvas,
+ champlain_tile_get_size (tile),
+ champlain_tile_get_size (tile));
+ g_signal_connect (data->canvas, "draw",
+ G_CALLBACK (on_canvas_draw), data);
+ clutter_content_invalidate (data->canvas);
+}
diff --git a/lib/maps-mapbox-renderer.h b/lib/maps-mapbox-renderer.h
new file mode 100644
index 0000000..d72fda4
--- /dev/null
+++ b/lib/maps-mapbox-renderer.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2015 Jonas Danielsson
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Jonas Danielsson <jonas threetimestwo org>
+ */
+
+#ifndef __MAPS_MAPBOX_RENDERER_H__
+#define __MAPS_MAPBOX_RENDERER_H__
+
+#include <champlain/champlain.h>
+
+G_BEGIN_DECLS
+
+#define MAPS_TYPE_MAPBOX_RENDERER maps_mapbox_renderer_get_type ()
+
+#define MAPS_MAPBOX_RENDERER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAPS_TYPE_MAPBOX_RENDERER, MapsMapboxRenderer))
+
+#define MAPS_MAPBOX_RENDERER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MAPS_TYPE_MAPBOX_RENDERER, MapsMapboxRendererClass))
+
+#define MAPS_IS_MAPBOX_RENDERER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAPS_TYPE_MAPBOX_RENDERER))
+
+#define MAPS_IS_MAPBOX_RENDERER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MAPS_TYPE_MAPBOX_RENDERER))
+
+#define MAPS_MAPBOX_RENDERER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MAPS_TYPE_MAPBOX_RENDERER, MapsMapboxRendererClass))
+
+typedef struct _MapsMapboxRendererPrivate MapsMapboxRendererPrivate;
+typedef struct _MapsMapboxRenderer MapsMapboxRenderer;
+typedef struct _MapsMapboxRendererClass MapsMapboxRendererClass;
+
+/**
+ * MapsMapboxRenderer:
+ *
+ * The #MapsMapboxRenderer structure contains only private data
+ * and should be accessed using the provided API
+ */
+struct _MapsMapboxRenderer
+{
+ ChamplainRenderer parent;
+
+ MapsMapboxRendererPrivate *priv;
+};
+
+struct _MapsMapboxRendererClass
+{
+ ChamplainRendererClass parent_class;
+};
+
+GType maps_mapbox_renderer_get_type (void);
+
+MapsMapboxRenderer *maps_mapbox_renderer_new (void);
+
+void maps_mapbox_renderer_load_css (MapsMapboxRenderer *renderer,
+ const char *filename,
+ GError **error);
+G_END_DECLS
+
+#endif /* __MAPS_MAPBOX_RENDERER_H__ */
diff --git a/src/mapView.js b/src/mapView.js
index 36c2b7c..2fb762f 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -21,6 +21,7 @@
const Champlain = imports.gi.Champlain;
const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Geocode = imports.gi.GeocodeGlib;
const GtkChamplain = imports.gi.GtkChamplain;
@@ -29,6 +30,7 @@ const Lang = imports.lang;
const Application = imports.application;
const ContactPlace = imports.contactPlace;
const Geoclue = imports.geoclue;
+const Maps = imports.gi.GnomeMaps;
const MapWalker = imports.mapWalker;
const Place = imports.place;
const PlaceMarker = imports.placeMarker;
@@ -144,11 +146,49 @@ const MapView = new Lang.Class({
}).bind(this));
},
+ _vectorSource: function() {
+ let id = 'vector-tile-glib';
+ let renderer = new Maps.MapboxRenderer();
+ renderer.load_css(GLib.build_filenamev([pkg.pkgdatadir,
+ 'gnome-maps.mapcss']));
+
+ let tile = Champlain.NetworkTileSource.new_full(
+ id,
+ 'OpenStreetMap Mapbox vector tiles',
+ 'Map Data ODBL OpenStreetMap Contributors',
+ 'http://creativecommons.org/licenses/by-sa/2.0/',
+ 2,
+ 17,
+ 256,
+ Champlain.MapProjection.MAP_PROJECTION_MERCATOR,
+ 'http://vector.mapzen.com/osm/all/#Z#/#X#/#Y#.mapbox',
+ renderer);
+
+ let error = this._factory.create_error_source(256);
+ let file = Champlain.FileCache.new_full(100000000,
+ null,
+ renderer);
+ let mem = Champlain.MemoryCache.new_full (100, renderer);
+ let chain = new Champlain.MapSourceChain();
+
+ chain.push(error);
+ chain.push(tile);
+ chain.push(file);
+ chain.push(mem);
+
+ return chain;
+ },
+
setMapType: function(mapType) {
if (this.view.map_source.id === mapType)
return;
- let source = this._factory.create_cached_source(mapType);
+ let source;
+ if (mapType === MapType.AERIAL)
+ source = this._vectorSource();
+ else
+ source = this._factory.create_cached_source(mapType);
+
this.view.map_source = source;
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]