[gnome-maps/wip/jonasdn/vector-tiles] Add text layer
- From: Jonas Danielsson <jonasdn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-maps/wip/jonasdn/vector-tiles] Add text layer
- Date: Sat, 25 Apr 2015 21:44:45 +0000 (UTC)
commit 2f3f2a1f8e1fad11000445184b73a58a52625731
Author: Jonas Danielsson <jonas threetimestwo org>
Date: Sat Apr 25 14:50:48 2015 +0200
Add text layer
data/gnome-maps.mapcss | 137 +++++++++++++++++++++++++--
lib/Makefile.am | 2 +
lib/maps-mapbox-renderer.c | 56 ++++++-----
lib/maps-mapbox-renderer.h | 7 ++
lib/maps-mapbox-text-layer.c | 216 ++++++++++++++++++++++++++++++++++++++++++
lib/maps-mapbox-text-layer.h | 56 +++++++++++
src/mapView.js | 2 +
7 files changed, 441 insertions(+), 35 deletions(-)
---
diff --git a/data/gnome-maps.mapcss b/data/gnome-maps.mapcss
index f72d7d5..57a5d1f 100644
--- a/data/gnome-maps.mapcss
+++ b/data/gnome-maps.mapcss
@@ -1,3 +1,19 @@
+node {
+ font-size: 10;
+ font-weight: bold;
+ font-variant: small-caps;
+ font-family: cantarell;
+}
+
+node|z5-10[place=country] {
+ text-color: #4A90D9;
+ text: name;
+}
+
+node|z5-10[place=sea] {
+ text-color: #770000;
+ text: name;
+}
/* This applies to the Map as a whole, renders first */
canvas {
@@ -13,6 +29,8 @@ way {
}
/* All lines with the tag 'highway' */
+
+
way[highway] {
color: #ffffff;
linecap: round;
@@ -24,8 +42,46 @@ way[highway] {
casing-color: #C7B8A4;
}
+way|z0-7[highway] {
+ width: 1;
+ color: #777777;
+ casing-width: 0;
+}
+
+way[highway=service] {
+ width: 2;
+}
+
+way[highway=living_street] {
+ width: 3;
+}
+
+way[highway=pedestrian] {
+ color: #dddddd;
+}
+
/* Applies to all lines drawn that passes these tests */
-way[highway=motorway], way[highway=motorway_link],
+way[highway=motorway] {
+ casing-width: 3;
+ casing-color: #ff9966;
+ color: #ffff00;
+ width: 2;
+}
+
+way|z15-18[highway=motorway] {
+ casing-width: 0.95;
+ casing-color: #774433;
+ color: #ff9966;
+ width: 5;
+}
+
+way[highway=motorway_link] {
+ casing-width: 0.95;
+ casing-color: #774433;
+ color: #ff9966;
+ width: 3;
+}
+
way[highway=trunk], way[highway=trunk_link] {
casing-width: 0.95;
color: #ff9966;
@@ -43,28 +99,79 @@ way[highway=footway] {
color: #770000;
width: 1;
dashes: 2, 2;
+ casing-width: 0;
}
way[highway=cycleway] {
color: #000077;
width: 1;
dashes: 2, 2;
+ casing-width: 0;
+}
+
+way[highway=path] {
+ color: #000000;
+ width: 0.5;
+ dashes: 5, 4;
+ casing-width: 0;
+}
+
+way[highway=steps] {
+ color: #a00000;
+ width: 2;
+ dashes: 1, 1;
+ casing-width: 0;
+}
+
+way[highway=track] {
+ color: #826a52;
+ width: 1;
+ dashes: 8, 8;
+ casing-width: 0;
+}
+
+way[railway=rail] {
+ color: #ffffff;
+ width: 2;
+ casing-color: #777777;
+ casing-width: 1;
+ dashes: 7, 10;
+}
+
+way[railway=tram], way[railway=lightrail] {
+ color: #000000;
+ width: 2;
+ casing-width: 0;
+}
+
+way[railway=preserved], way[railway=narrow_gauge] {
+ width: 1;
}
area {
- color: #FAEBD7;
+ color: #000000;
fill-color: #FAEBD7;
width: 1;
}
-area[landuse=park], area[landuse=playground], area[landuse=pitch] {
- fill-color: #73D216;
- color: #73D216;
+area|z14-19 {
+ text: name;
+ text-color: #222233;
+ font-size: 8;
+ font-family: cantarell;
+ font-weight: bold;
}
-area[landuse=wood], area[landuse=scrub] {
- fill-color: #0D6C00;
- color: #0D6C00;
+area[landuse=park], area[landuse=playground], area[landuse=pitch],
+area[leisure=park], area[leasure=playground], area[leisure=pitch] {
+ fill-color: #ABCA8A;
+ color: #ABCA8a;
+}
+
+area[landuse=forest], area[landuse=wood], area[landuse=scrub],
+area[natural=wood] {
+ fill-color: #56A900;
+ color: #56A900;
z-index: 1; /* z-index 0 is baseline */
}
@@ -78,13 +185,25 @@ area[building] {
fill-color: #C7B8A4;
}
+area[amenity=parking] {
+ color: #ffff77;
+ fill-color: #C7B8A4;
+}
+
+area[highway=pedestrian] {
+ color: #dddddd;
+ fill-color: #C7B8A4;
+}
+
+/*
way[is_bridge=yes] {
color: #333333;
width: 2;
}
+*/
way[is_tunnel=yes] {
- color: #333333;
+ color: #EEEEEC;
width: 2;
dashes: 3, 3;
}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f7e83f7..ff9dd16 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -8,11 +8,13 @@ libgnome_maps_headers_private = \
maps-contact-store.h \
maps-contact.h \
maps-mapbox-renderer.h \
+ maps-mapbox-text-layer.h \
maps.h
libgnome_maps_sources = \
maps-contact-store.c \
maps-contact.c \
+ maps-mapbox-text-layer.c \
maps-mapbox-renderer.c
libgnome_maps_la_SOURCES = \
diff --git a/lib/maps-mapbox-renderer.c b/lib/maps-mapbox-renderer.c
index adf148b..a1fbe34 100644
--- a/lib/maps-mapbox-renderer.c
+++ b/lib/maps-mapbox-renderer.c
@@ -21,11 +21,14 @@
#include <cairo.h>
#include "maps-mapbox-renderer.h"
+#include "maps-mapbox-text-layer.h"
struct _MapsMapboxRendererPrivate
{
gchar *data;
guint size;
+ MapsMapboxTextLayer *layer;
+ ChamplainView *view;
VTileMapCSS *stylesheet;
};
@@ -33,6 +36,8 @@ struct _MapsMapboxRendererPrivate
typedef struct _RenderData
{
ChamplainTile *tile;
+ MapsMapboxTextLayer *layer;
+ ChamplainView *view;
ClutterContent *canvas;
gchar *data;
guint size;
@@ -84,6 +89,7 @@ maps_mapbox_renderer_init (MapsMapboxRenderer *renderer)
renderer->priv = maps_mapbox_renderer_get_instance_private (renderer);
renderer->priv->data = NULL;
renderer->priv->size = 0;
+ renderer->priv->view = NULL;
}
@@ -94,21 +100,31 @@ maps_mapbox_renderer_init (MapsMapboxRenderer *renderer)
*
*/
MapsMapboxRenderer *
-maps_mapbox_renderer_new (void)
+maps_mapbox_renderer_new ()
{
- return g_object_new (MAPS_TYPE_MAPBOX_RENDERER, NULL);
+ MapsMapboxRenderer *renderer;
+ renderer = g_object_new (MAPS_TYPE_MAPBOX_RENDERER, NULL);
+}
+
+void
+maps_mapbox_renderer_set_view (MapsMapboxRenderer *renderer,
+ ChamplainView *view)
+{
+ renderer->priv->view = view;
+ renderer->priv->layer = maps_mapbox_text_layer_new ();
+
+ champlain_view_add_layer (view, (ChamplainLayer *) renderer->priv->layer);
}
void
maps_mapbox_renderer_load_css (MapsMapboxRenderer *renderer,
- const char *filename,
- GError **error)
+ 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)
{
@@ -121,13 +137,6 @@ set_data (ChamplainRenderer *renderer_base, const gchar *data, guint size)
renderer->priv->size = size;
}
-static void
-on_mapbox_rendered (VTileMapbox *mapbox,
- GAsyncResult *res,
- RenderData *data)
-{
-
-}
gboolean
on_canvas_draw (ClutterCanvas *canvas,
@@ -142,6 +151,7 @@ on_canvas_draw (ClutterCanvas *canvas,
ClutterActor *actor = NULL;
GError *error = NULL;
gboolean success;
+ GList *texts, *l;
mapbox = vtile_mapbox_new (data->data,
data->size,
@@ -150,24 +160,25 @@ on_canvas_draw (ClutterCanvas *canvas,
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);
+ g_object_unref (mapbox);
- /* clutter_actor_set_offscreen_redirect (actor,
- CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY); */
+ texts = vtile_mapbox_get_texts (mapbox);
+ for (l = texts; l != NULL; l = l->next) {
+ maps_mapbox_text_layer_add_text (data->layer, data->tile, l->data);
+ }
finish:
if (actor)
@@ -181,15 +192,6 @@ on_canvas_draw (ClutterCanvas *canvas,
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;
}
@@ -213,6 +215,8 @@ render (ChamplainRenderer *renderer_base, ChamplainTile *tile)
data->size = renderer->priv->size;
data->stylesheet = renderer->priv->stylesheet;
data->canvas = clutter_canvas_new ();
+ data->layer = renderer->priv->layer;
+ data->view = renderer->priv->view;
clutter_canvas_set_size ((ClutterCanvas *) data->canvas,
champlain_tile_get_size (tile),
diff --git a/lib/maps-mapbox-renderer.h b/lib/maps-mapbox-renderer.h
index d72fda4..7995f75 100644
--- a/lib/maps-mapbox-renderer.h
+++ b/lib/maps-mapbox-renderer.h
@@ -21,6 +21,7 @@
#define __MAPS_MAPBOX_RENDERER_H__
#include <champlain/champlain.h>
+#include <vector-tile-mapbox.h>
G_BEGIN_DECLS
@@ -66,10 +67,16 @@ struct _MapsMapboxRendererClass
GType maps_mapbox_renderer_get_type (void);
MapsMapboxRenderer *maps_mapbox_renderer_new (void);
+MapsMapboxRenderer *maps_mapbox_renderer_new_with_view (ChamplainView *view);
+
void maps_mapbox_renderer_load_css (MapsMapboxRenderer *renderer,
const char *filename,
GError **error);
+
+void maps_mapbox_renderer_set_view (MapsMapboxRenderer *renderer,
+ ChamplainView *view);
+
G_END_DECLS
#endif /* __MAPS_MAPBOX_RENDERER_H__ */
diff --git a/lib/maps-mapbox-text-layer.c b/lib/maps-mapbox-text-layer.c
new file mode 100644
index 0000000..2eb70d2
--- /dev/null
+++ b/lib/maps-mapbox-text-layer.c
@@ -0,0 +1,216 @@
+#include "maps-mapbox-text-layer.h"
+
+#include <clutter/clutter.h>
+#include <glib.h>
+
+struct _MapsMapboxTextLayerPrivate
+{
+ ChamplainView *view;
+ GHashTable *objects;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (MapsMapboxTextLayer, maps_mapbox_text_layer, CHAMPLAIN_TYPE_LAYER)
+
+static void set_view (ChamplainLayer *layer,
+ ChamplainView *view);
+
+static ChamplainBoundingBox *get_bounding_box (ChamplainLayer *layer);
+
+static void
+maps_mapbox_text_layer_dispose (GObject *object)
+{
+ MapsMapboxTextLayer *self = MAPS_MAPBOX_TEXT_LAYER (object);
+ MapsMapboxTextLayerPrivate *priv = self->priv;
+
+ if (priv->view != NULL)
+ set_view (CHAMPLAIN_LAYER (self), NULL);
+
+ G_OBJECT_CLASS (maps_mapbox_text_layer_parent_class)->dispose (object);
+}
+
+
+static void
+maps_mapbox_text_layer_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (maps_mapbox_text_layer_parent_class)->finalize (object);
+}
+
+
+static void
+maps_mapbox_text_layer_class_init (MapsMapboxTextLayerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ChamplainLayerClass *layer_class = CHAMPLAIN_LAYER_CLASS (klass);
+
+ object_class->finalize = maps_mapbox_text_layer_finalize;
+ object_class->dispose = maps_mapbox_text_layer_dispose;
+
+ layer_class->set_view = set_view;
+ layer_class->get_bounding_box = get_bounding_box;
+}
+
+
+static void
+maps_mapbox_text_layer_init (MapsMapboxTextLayer *self)
+{
+ MapsMapboxTextLayerPrivate *priv;
+
+ self->priv = maps_mapbox_text_layer_get_instance_private (self);
+ self->priv->objects = g_hash_table_new (g_str_hash, g_str_equal);
+ self->priv->view = NULL;
+}
+
+
+/**
+ * maps_mapbox_text_layer_new:
+ *
+ * Creates a new instance of #MapsMapboxTextLayer.
+ *
+ * Returns: a new #MapsMapboxTextLayer ready to be used as a container for text.
+ *
+ */
+MapsMapboxTextLayer *
+maps_mapbox_text_layer_new ()
+{
+ return g_object_new (MAPS_TYPE_MAPBOX_TEXT_LAYER, NULL);
+}
+
+gboolean
+on_text_draw (ClutterCanvas *canvas,
+ cairo_t *cr,
+ gint width,
+ gint height,
+ VTileMapboxText *text)
+{
+ cairo_surface_t *surface;
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_set_source_surface (cr, text->surface, 0, 0);
+ cairo_paint (cr);
+ surface = cairo_get_target (cr);
+ g_signal_handlers_disconnect_by_func (canvas, on_text_draw, text);
+
+ return TRUE;
+}
+
+
+void
+maps_mapbox_text_layer_add_text (MapsMapboxTextLayer *layer,
+ ChamplainTile *tile,
+ VTileMapboxText *text)
+{
+ g_return_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer));
+
+ ClutterContent *canvas;
+ ClutterActor *actor;
+ guint orig_x, orig_y;
+ gfloat tile_x, tile_y;
+
+ if (g_hash_table_lookup (layer->priv->objects, text->uid)) {
+ return;
+ } else {
+ g_hash_table_insert (layer->priv->objects, text->uid, text->uid);
+ }
+
+ canvas = clutter_canvas_new ();
+ clutter_canvas_set_size (CLUTTER_CANVAS (canvas), text->width, text->height);
+ g_signal_connect (canvas, "draw", G_CALLBACK (on_text_draw), text);
+ clutter_content_invalidate (canvas);
+
+ actor = clutter_actor_new ();
+ clutter_actor_set_size (actor, text->width, text->height);
+ clutter_actor_set_content (actor, canvas);
+ g_object_unref (canvas);
+
+ clutter_actor_get_position (tile, &tile_x, &tile_y);
+ champlain_view_get_viewport_origin (layer->priv->view, &orig_x, &orig_y);
+
+ clutter_actor_set_position (actor,
+ tile_x + text->offset_x,
+ tile_y + text->offset_y);
+
+ clutter_actor_add_child (CLUTTER_ACTOR (layer), actor);
+}
+
+
+/**
+ * maps_mapbox_text_layer_remove_all:
+ * @layer: a #MapsMapboxTextLayer
+ *
+ * Removes all texts from the layer.
+ *
+ * Since: 0.10
+ */
+void
+maps_mapbox_text_layer_remove_all (MapsMapboxTextLayer *layer)
+{
+ g_return_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer));
+
+ clutter_actor_remove_all_children (CLUTTER_ACTOR (layer));
+ g_hash_table_remove_all (layer->priv->objects);
+}
+
+static void
+relocate_cb (G_GNUC_UNUSED GObject *gobject,
+ MapsMapboxTextLayer *layer)
+{
+ g_return_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer));
+
+ maps_mapbox_text_layer_remove_all (layer);
+}
+
+
+static void
+zoom_reposition_cb (G_GNUC_UNUSED GObject *gobject,
+ G_GNUC_UNUSED GParamSpec *arg1,
+ MapsMapboxTextLayer *layer)
+{
+ g_return_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer));
+
+ maps_mapbox_text_layer_remove_all (layer);
+}
+
+static void
+set_view (ChamplainLayer *layer,
+ ChamplainView *view)
+{
+ g_return_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer) &&
+ (CHAMPLAIN_IS_VIEW (view) || view == NULL));
+
+ MapsMapboxTextLayer *text_layer = MAPS_MAPBOX_TEXT_LAYER (layer);
+
+ if (text_layer->priv->view != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (text_layer->priv->view,
+ G_CALLBACK (relocate_cb), text_layer);
+ g_object_unref (text_layer->priv->view);
+ }
+
+ text_layer->priv->view = view;
+
+ if (view != NULL)
+ {
+ g_object_ref (view);
+
+ g_signal_connect (view, "layer-relocated",
+ G_CALLBACK (relocate_cb), layer);
+
+ g_signal_connect (view, "notify::zoom-level",
+ G_CALLBACK (zoom_reposition_cb), layer);
+
+ maps_mapbox_text_layer_remove_all (text_layer);
+ }
+}
+
+static ChamplainBoundingBox *
+get_bounding_box (ChamplainLayer *layer)
+{
+ ChamplainBoundingBox *bbox;
+
+ g_return_val_if_fail (MAPS_IS_MAPBOX_TEXT_LAYER (layer), NULL);
+
+ return champlain_bounding_box_new ();
+}
diff --git a/lib/maps-mapbox-text-layer.h b/lib/maps-mapbox-text-layer.h
new file mode 100644
index 0000000..deb882c
--- /dev/null
+++ b/lib/maps-mapbox-text-layer.h
@@ -0,0 +1,56 @@
+#ifndef MAPS_MAPBOX_TEXT_LAYER_H
+#define MAPS_MAPBOX_TEXT_LAYER_H
+
+#include <champlain/champlain.h>
+#include <vector-tile-mapbox.h>
+
+#include <glib-object.h>
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define MAPS_TYPE_MAPBOX_TEXT_LAYER maps_mapbox_text_layer_get_type ()
+
+#define MAPS_MAPBOX_TEXT_LAYER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAPS_TYPE_MAPBOX_TEXT_LAYER, MapsMapboxTextLayer))
+
+#define MAPS_MAPBOX_TEXT_LAYER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MAPS_TYPE_MAPBOX_TEXT_LAYER, MapsMapboxTextLayerClass))
+
+#define MAPS_IS_MAPBOX_TEXT_LAYER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAPS_TYPE_MAPBOX_TEXT_LAYER))
+
+#define MAPS_IS_MAPBOX_TEXT_LAYER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MAPS_TYPE_MAPBOX_TEXT_LAYER))
+
+#define MAPS_MAPBOX_TEXT_LAYER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MAPS_TYPE_MAPBOX_TEXT_LAYER, MapsMapboxTextLayerClass))
+
+typedef struct _MapsMapboxTextLayerPrivate MapsMapboxTextLayerPrivate;
+typedef struct _MapsMapboxTextLayer MapsMapboxTextLayer;
+typedef struct _MapsMapboxTextLayerClass MapsMapboxTextLayerClass;
+
+struct _MapsMapboxTextLayer
+{
+ ChamplainLayer parent;
+
+ MapsMapboxTextLayerPrivate *priv;
+};
+
+struct _MapsMapboxTextLayerClass
+{
+ ChamplainLayerClass parent_class;
+};
+
+GType maps_mapbox_text_layer_get_type (void);
+
+MapsMapboxTextLayer *maps_mapbox_text_layer_new (void);
+void maps_mapbox_text_layer_add_text (MapsMapboxTextLayer *layer,
+ ChamplainTile *tile,
+ VTileMapboxText *mapbox_text);
+void maps_mapbox_text_layer_remove_all (MapsMapboxTextLayer *layer);
+
+
+G_END_DECLS
+
+#endif
diff --git a/src/mapView.js b/src/mapView.js
index 2fb762f..51f8b72 100644
--- a/src/mapView.js
+++ b/src/mapView.js
@@ -149,6 +149,8 @@ const MapView = new Lang.Class({
_vectorSource: function() {
let id = 'vector-tile-glib';
let renderer = new Maps.MapboxRenderer();
+ renderer.set_view(this.view);
+
renderer.load_css(GLib.build_filenamev([pkg.pkgdatadir,
'gnome-maps.mapcss']));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]