[libshumate] vector: Add background layer
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] vector: Add background layer
- Date: Mon, 1 Nov 2021 22:00:05 +0000 (UTC)
commit 8a04b0344b10511e94eb66d5e48f6d8350550259
Author: James Westman <james jwestman net>
Date: Mon Aug 23 00:56:21 2021 -0500
vector: Add background layer
Add layers to ShumateVectorStyle. It reads these layers from a Mapbox
Style Specification JSON file. So far, only background layers are
supported because there is no protobuf/MVT parsing capability yet.
demos/map-style.json | 11 +++
demos/org.gnome.Shumate.Demo.gresources.xml | 3 +
demos/shumate-demo-window.c | 6 +-
shumate/meson.build | 4 +
shumate/shumate-vector-style.c | 75 ++++++++++++--
shumate/shumate-vector-style.h | 3 +-
.../shumate-vector-background-layer-private.h | 32 ++++++
shumate/vector/shumate-vector-background-layer.c | 76 ++++++++++++++
shumate/vector/shumate-vector-layer-private.h | 41 ++++++++
shumate/vector/shumate-vector-layer.c | 110 +++++++++++++++++++++
tests/data/meson.build | 5 +
tests/data/style.json | 11 +++
tests/data/tests.gresource.xml | 6 ++
tests/meson.build | 4 +
tests/vector-style.c | 26 +++++
15 files changed, 405 insertions(+), 8 deletions(-)
---
diff --git a/demos/map-style.json b/demos/map-style.json
new file mode 100644
index 0000000..890e370
--- /dev/null
+++ b/demos/map-style.json
@@ -0,0 +1,11 @@
+{
+ "layers": [
+ {
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#f6f5f4"
+ }
+ }
+ ]
+}
diff --git a/demos/org.gnome.Shumate.Demo.gresources.xml b/demos/org.gnome.Shumate.Demo.gresources.xml
index 6446607..1ebd6cf 100644
--- a/demos/org.gnome.Shumate.Demo.gresources.xml
+++ b/demos/org.gnome.Shumate.Demo.gresources.xml
@@ -6,4 +6,7 @@
<gresource prefix="/org/gnome/Shumate/Demo/icons">
<file preprocess="xml-stripblanks">map-marker-symbolic.svg</file>
</gresource>
+ <gresource prefix="/org/gnome/Shumate/Demo/styles">
+ <file preprocess="json-stripblanks">map-style.json</file>
+ </gresource>
</gresources>
diff --git a/demos/shumate-demo-window.c b/demos/shumate-demo-window.c
index 311e42e..1d24f24 100644
--- a/demos/shumate-demo-window.c
+++ b/demos/shumate-demo-window.c
@@ -138,6 +138,8 @@ shumate_demo_window_init (ShumateDemoWindow *self)
{
ShumateViewport *viewport;
GtkExpression *expression;
+ g_autoptr(GBytes) bytes = NULL;
+ const char *style_json;
g_autoptr(ShumateVectorStyle) style = NULL;
ShumateMapSource *map_source = NULL;
@@ -150,7 +152,9 @@ shumate_demo_window_init (ShumateDemoWindow *self)
gtk_drop_down_set_expression (self->layers_dropdown, expression);
gtk_drop_down_set_model (self->layers_dropdown, G_LIST_MODEL (self->registry));
- style = shumate_vector_style_create ("{}", NULL);
+ bytes = g_resources_lookup_data ("/org/gnome/Shumate/Demo/styles/map-style.json",
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
+ style_json = g_bytes_get_data (bytes, NULL);
+ style = shumate_vector_style_create (style_json, NULL);
map_source = SHUMATE_MAP_SOURCE (shumate_network_tile_source_new_vector_full (
"vector-tiles",
diff --git a/shumate/meson.build b/shumate/meson.build
index 4cd3ccc..e49354a 100644
--- a/shumate/meson.build
+++ b/shumate/meson.build
@@ -26,6 +26,8 @@ libshumate_private_h = [
'shumate-kinetic-scrolling-private.h',
'shumate-marker-private.h',
+ 'vector/shumate-vector-background-layer-private.h',
+ 'vector/shumate-vector-layer-private.h',
'vector/shumate-vector-utils-private.h',
]
@@ -52,6 +54,8 @@ libshumate_sources = [
'shumate-vector-style.c',
'shumate-viewport.c',
+ 'vector/shumate-vector-background-layer.c',
+ 'vector/shumate-vector-layer.c',
'vector/shumate-vector-utils.c',
]
diff --git a/shumate/shumate-vector-style.c b/shumate/shumate-vector-style.c
index 8cc14a6..e6de875 100644
--- a/shumate/shumate-vector-style.c
+++ b/shumate/shumate-vector-style.c
@@ -15,8 +15,11 @@
* License along with this library; if not, see <https://www.gnu.org/licenses/>.
*/
+#include <json-glib/json-glib.h>
#include <cairo/cairo.h>
+#include "vector/shumate-vector-utils-private.h"
+#include "vector/shumate-vector-layer-private.h"
#include "shumate-vector-style.h"
struct _ShumateVectorStyle
@@ -24,9 +27,14 @@ struct _ShumateVectorStyle
GObject parent_instance;
char *style_json;
+
+ GPtrArray *layers;
};
-G_DEFINE_TYPE (ShumateVectorStyle, shumate_vector_style, G_TYPE_OBJECT)
+static void shumate_vector_style_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ShumateVectorStyle, shumate_vector_style, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, shumate_vector_style_initable_iface_init))
enum {
PROP_0,
@@ -52,9 +60,9 @@ shumate_vector_style_create (const char *style_json, GError **error)
{
g_return_val_if_fail (style_json != NULL, NULL);
- return g_object_new (SHUMATE_TYPE_VECTOR_STYLE,
- "style-json", style_json,
- NULL);
+ return g_initable_new (SHUMATE_TYPE_VECTOR_STYLE, NULL, error,
+ "style-json", style_json,
+ NULL);
}
@@ -63,6 +71,7 @@ shumate_vector_style_finalize (GObject *object)
{
ShumateVectorStyle *self = (ShumateVectorStyle *)object;
+ g_clear_pointer (&self->layers, g_ptr_array_unref);
g_clear_pointer (&self->style_json, g_free);
G_OBJECT_CLASS (shumate_vector_style_parent_class)->finalize (object);
@@ -126,6 +135,60 @@ shumate_vector_style_class_init (ShumateVectorStyleClass *klass)
}
+static gboolean
+shumate_vector_style_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ShumateVectorStyle *self = (ShumateVectorStyle *)initable;
+ g_autoptr(JsonNode) node = NULL;
+ JsonNode *layers_node;
+ JsonObject *object;
+
+ g_return_val_if_fail (SHUMATE_IS_VECTOR_STYLE (self), FALSE);
+ g_return_val_if_fail (self->style_json != NULL, FALSE);
+
+ if (!(node = json_from_string (self->style_json, error)))
+ return FALSE;
+
+ if (!shumate_vector_json_get_object (node, &object, error))
+ return FALSE;
+
+ self->layers = g_ptr_array_new_with_free_func (g_object_unref);
+ if ((layers_node = json_object_get_member (object, "layers")))
+ {
+ JsonArray *layers;
+
+ if (!shumate_vector_json_get_array (layers_node, &layers, error))
+ return FALSE;
+
+ for (int i = 0, n = json_array_get_length (layers); i < n; i ++)
+ {
+ JsonNode *layer_node = json_array_get_element (layers, i);
+ JsonObject *layer_obj;
+ ShumateVectorLayer *layer;
+
+ if (!shumate_vector_json_get_object (layer_node, &layer_obj, error))
+ return FALSE;
+
+ if (!(layer = shumate_vector_layer_create_from_json (layer_obj, error)))
+ return FALSE;
+
+ g_ptr_array_add (self->layers, layer);
+ }
+ }
+
+ return TRUE;
+}
+
+
+static void
+shumate_vector_style_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = shumate_vector_style_initable_init;
+}
+
+
static void
shumate_vector_style_init (ShumateVectorStyle *self)
{
@@ -195,8 +258,8 @@ shumate_vector_style_render (ShumateVectorStyle *self, int size)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size);
cr = cairo_create (surface);
- cairo_set_source_rgb (cr, 0, 0, 0);
- cairo_paint (cr);
+ for (int i = 0; i < self->layers->len; i ++)
+ shumate_vector_layer_render ((ShumateVectorLayer *)self->layers->pdata[i], cr);
texture = texture_new_for_surface (surface);
diff --git a/shumate/shumate-vector-style.h b/shumate/shumate-vector-style.h
index 9249903..48f7d75 100644
--- a/shumate/shumate-vector-style.h
+++ b/shumate/shumate-vector-style.h
@@ -54,7 +54,8 @@ G_DECLARE_FINAL_TYPE (ShumateVectorStyle, shumate_vector_style, SHUMATE, VECTOR_
ShumateVectorStyle *shumate_vector_style_create (const char *style_json, GError **error);
+const char *shumate_vector_style_get_style_json (ShumateVectorStyle *self);
+
GdkTexture *shumate_vector_style_render (ShumateVectorStyle *self, int size);
G_END_DECLS
-
diff --git a/shumate/vector/shumate-vector-background-layer-private.h
b/shumate/vector/shumate-vector-background-layer-private.h
new file mode 100644
index 0000000..b5dd1ab
--- /dev/null
+++ b/shumate/vector/shumate-vector-background-layer-private.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 James Westman <james jwestman net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <json-glib/json-glib.h>
+
+#include "shumate-vector-layer-private.h"
+
+G_BEGIN_DECLS
+
+#define SHUMATE_TYPE_VECTOR_BACKGROUND_LAYER (shumate_vector_background_layer_get_type())
+
+G_DECLARE_FINAL_TYPE (ShumateVectorBackgroundLayer, shumate_vector_background_layer, SHUMATE,
VECTOR_BACKGROUND_LAYER, ShumateVectorLayer)
+
+ShumateVectorLayer *shumate_vector_background_layer_create_from_json (JsonObject *object, GError **error);
+
+G_END_DECLS
diff --git a/shumate/vector/shumate-vector-background-layer.c
b/shumate/vector/shumate-vector-background-layer.c
new file mode 100644
index 0000000..bc427a0
--- /dev/null
+++ b/shumate/vector/shumate-vector-background-layer.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2021 James Westman <james jwestman net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <gtk/gtk.h>
+#include "shumate-vector-background-layer-private.h"
+#include "shumate-vector-utils-private.h"
+
+struct _ShumateVectorBackgroundLayer
+{
+ ShumateVectorLayer parent_instance;
+
+ GdkRGBA color;
+ double opacity;
+};
+
+G_DEFINE_TYPE (ShumateVectorBackgroundLayer, shumate_vector_background_layer, SHUMATE_TYPE_VECTOR_LAYER)
+
+
+ShumateVectorLayer *
+shumate_vector_background_layer_create_from_json (JsonObject *object, GError **error)
+{
+ ShumateVectorBackgroundLayer *layer = g_object_new (SHUMATE_TYPE_VECTOR_BACKGROUND_LAYER, NULL);
+ JsonNode *paint_node;
+
+ if ((paint_node = json_object_get_member (object, "paint")))
+ {
+ JsonObject *paint;
+
+ if (!shumate_vector_json_get_object (paint_node, &paint, error))
+ return NULL;
+
+ gdk_rgba_parse (&layer->color, json_object_get_string_member_with_default (paint, "background-color",
"#000000"));
+ layer->opacity = json_object_get_double_member_with_default (paint, "background-opacity", 1.0);
+ }
+
+ return (ShumateVectorLayer *)layer;
+}
+
+
+static void
+shumate_vector_background_layer_render (ShumateVectorLayer *layer, cairo_t *cr)
+{
+ ShumateVectorBackgroundLayer *self = SHUMATE_VECTOR_BACKGROUND_LAYER (layer);
+
+ gdk_cairo_set_source_rgba (cr, &self->color);
+ cairo_paint_with_alpha (cr, self->opacity);
+}
+
+
+static void
+shumate_vector_background_layer_class_init (ShumateVectorBackgroundLayerClass *klass)
+{
+ ShumateVectorLayerClass *layer_class = SHUMATE_VECTOR_LAYER_CLASS (klass);
+
+ layer_class->render = shumate_vector_background_layer_render;
+}
+
+
+static void
+shumate_vector_background_layer_init (ShumateVectorBackgroundLayer *self)
+{
+}
diff --git a/shumate/vector/shumate-vector-layer-private.h b/shumate/vector/shumate-vector-layer-private.h
new file mode 100644
index 0000000..9252bdc
--- /dev/null
+++ b/shumate/vector/shumate-vector-layer-private.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 James Westman <james jwestman net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <json-glib/json-glib.h>
+#include <cairo/cairo.h>
+
+G_BEGIN_DECLS
+
+#define SHUMATE_TYPE_VECTOR_LAYER (shumate_vector_layer_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (ShumateVectorLayer, shumate_vector_layer, SHUMATE, VECTOR_LAYER, GObject)
+
+struct _ShumateVectorLayerClass
+{
+ GObjectClass parent_class;
+
+ void (*render) (ShumateVectorLayer *self, cairo_t *cr);
+};
+
+ShumateVectorLayer *shumate_vector_layer_create_from_json (JsonObject *object, GError **error);
+
+void shumate_vector_layer_render (ShumateVectorLayer *self, cairo_t *cr);
+
+G_END_DECLS
diff --git a/shumate/vector/shumate-vector-layer.c b/shumate/vector/shumate-vector-layer.c
new file mode 100644
index 0000000..89064a2
--- /dev/null
+++ b/shumate/vector/shumate-vector-layer.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2021 James Westman <james jwestman net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <json-glib/json-glib.h>
+#include "shumate-vector-background-layer-private.h"
+#include "shumate-vector-layer-private.h"
+
+typedef struct
+{
+ GObject parent_instance;
+
+ double minzoom;
+ double maxzoom;
+ char *source_layer;
+} ShumateVectorLayerPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (ShumateVectorLayer, shumate_vector_layer, G_TYPE_OBJECT)
+
+
+ShumateVectorLayer *
+shumate_vector_layer_create_from_json (JsonObject *object, GError **error)
+{
+ ShumateVectorLayer *layer;
+ ShumateVectorLayerPrivate *priv;
+ const char *type = json_object_get_string_member_with_default (object, "type", NULL);
+
+ if (type == NULL)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Expected element of \"layer\" to have a string
member \"type\"");
+ return NULL;
+ }
+
+ if (g_strcmp0 (type, "background") == 0)
+ layer = shumate_vector_background_layer_create_from_json (object, error);
+ else
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unsupported layer type \"%s\"", type);
+ return NULL;
+ }
+
+ if (layer == NULL)
+ /* A problem occurred in one of the constructors above, and error is already
+ * set */
+ return NULL;
+
+ priv = shumate_vector_layer_get_instance_private (layer);
+ priv->minzoom = json_object_get_double_member_with_default (object, "minzoom", 0.0);
+ priv->maxzoom = json_object_get_double_member_with_default (object, "maxzoom", 1000000000.0);
+ priv->source_layer = g_strdup (json_object_get_string_member_with_default (object, "source-layer", NULL));
+
+ return layer;
+}
+
+
+static void
+shumate_vector_layer_finalize (GObject *object)
+{
+ ShumateVectorLayer *self = (ShumateVectorLayer *)object;
+ ShumateVectorLayerPrivate *priv = shumate_vector_layer_get_instance_private (self);
+
+ g_clear_pointer (&priv->source_layer, g_free);
+
+ G_OBJECT_CLASS (shumate_vector_layer_parent_class)->finalize (object);
+}
+
+
+static void
+shumate_vector_layer_class_init (ShumateVectorLayerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ShumateVectorLayerClass *layer_class = SHUMATE_VECTOR_LAYER_CLASS (klass);
+
+ object_class->finalize = shumate_vector_layer_finalize;
+
+ layer_class->render = NULL;
+}
+
+static void
+shumate_vector_layer_init (ShumateVectorLayer *self)
+{
+}
+
+
+/**
+ * shumate_vector_layer_render:
+ * @self: a [class@VectorLayer]
+ *
+ * Renders the layer by calling the [vfunc@VectorLayer.render] virtual method.
+ */
+void
+shumate_vector_layer_render (ShumateVectorLayer *self, cairo_t *cr)
+{
+ g_return_if_fail (SHUMATE_IS_VECTOR_LAYER (self));
+
+ SHUMATE_VECTOR_LAYER_GET_CLASS (self)->render (self, cr);
+}
diff --git a/tests/data/meson.build b/tests/data/meson.build
new file mode 100644
index 0000000..6c31843
--- /dev/null
+++ b/tests/data/meson.build
@@ -0,0 +1,5 @@
+test_resources = gnome.compile_resources(
+ 'shumate-test-resources',
+ 'tests.gresource.xml',
+ c_name: 'shumate_tests'
+)
diff --git a/tests/data/style.json b/tests/data/style.json
new file mode 100644
index 0000000..af145a4
--- /dev/null
+++ b/tests/data/style.json
@@ -0,0 +1,11 @@
+{
+ "layers": [
+ {
+ "type": "background",
+ "paint": {
+ "background-color": "goldenrod",
+ "background-opacity": 0.5
+ }
+ }
+ ]
+}
diff --git a/tests/data/tests.gresource.xml b/tests/data/tests.gresource.xml
new file mode 100644
index 0000000..6359a7a
--- /dev/null
+++ b/tests/data/tests.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/shumate/Tests">
+ <file>style.json</file>
+ </gresource>
+</gresources>
diff --git a/tests/meson.build b/tests/meson.build
index 0212112..a12e451 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -14,9 +14,12 @@ tests = [
'marker-layer',
'memory-cache',
'network-tile-source',
+ 'vector-style',
'viewport',
]
+subdir('data')
+
test_utils_sources = [
'test-tile-server.c',
]
@@ -34,6 +37,7 @@ testutils_dep = declare_dependency(
foreach test : tests
executable = executable(
test,
+ test_resources,
'@0@.c'.format(test),
dependencies: [libshumate_dep, testutils_dep],
)
diff --git a/tests/vector-style.c b/tests/vector-style.c
new file mode 100644
index 0000000..0739cb3
--- /dev/null
+++ b/tests/vector-style.c
@@ -0,0 +1,26 @@
+#include <gtk/gtk.h>
+#include <shumate/shumate.h>
+
+static void
+test_vector_style_create (void)
+{
+ GError *error = NULL;
+ g_autoptr(GBytes) style_json = NULL;
+ g_autoptr(ShumateVectorStyle) style = NULL;
+
+ style_json = g_resources_lookup_data ("/org/gnome/shumate/Tests/style.json", G_RESOURCE_LOOKUP_FLAGS_NONE,
NULL);
+ g_assert_no_error (error);
+
+ style = shumate_vector_style_create (g_bytes_get_data (style_json, NULL), &error);
+ g_assert_no_error (error);
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/vector-style/create", test_vector_style_create);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]