LCOV - code coverage report
Current view: top level - shumate - shumate-raster-renderer.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 32 103 31.1 %
Date: 2024-05-11 21:41:31 Functions: 8 16 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 6 62 9.7 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2021 James Westman <james@jwestman.net>
       3                 :            :  *
       4                 :            :  * This library is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * This library is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :            :  * Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with this library; if not, see <https://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : 
      19                 :            : #include "shumate-data-source.h"
      20                 :            : #include "shumate-raster-renderer.h"
      21                 :            : #include "shumate-tile-downloader.h"
      22                 :            : 
      23                 :            : 
      24                 :            : struct _ShumateRasterRenderer
      25                 :            : {
      26                 :            :   ShumateMapSource parent_instance;
      27                 :            : 
      28                 :            :   ShumateDataSource *data_source;
      29                 :            : };
      30                 :            : 
      31   [ +  +  +  - ]:         36 : G_DEFINE_TYPE (ShumateRasterRenderer, shumate_raster_renderer, SHUMATE_TYPE_MAP_SOURCE)
      32                 :            : 
      33                 :            : enum {
      34                 :            :   PROP_0,
      35                 :            :   PROP_DATA_SOURCE,
      36                 :            :   N_PROPS
      37                 :            : };
      38                 :            : 
      39                 :            : static GParamSpec *properties [N_PROPS];
      40                 :            : 
      41                 :            : 
      42                 :            : /**
      43                 :            :  * shumate_raster_renderer_new:
      44                 :            :  * @data_source: a [class@DataSource] to provide tile image data
      45                 :            :  *
      46                 :            :  * Creates a new [class@RasterRenderer] that uses the given data source.
      47                 :            :  *
      48                 :            :  * Returns: (transfer full): a newly constructed [class@RasterRenderer]
      49                 :            :  */
      50                 :            : ShumateRasterRenderer *
      51                 :          0 : shumate_raster_renderer_new (ShumateDataSource *data_source)
      52                 :            : {
      53         [ #  # ]:          0 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE (data_source), NULL);
      54                 :          0 :   return g_object_new (SHUMATE_TYPE_RASTER_RENDERER,
      55                 :            :                        "data-source", data_source,
      56                 :            :                        NULL);
      57                 :            : }
      58                 :            : 
      59                 :            : /**
      60                 :            :  * shumate_raster_renderer_new_from_url:
      61                 :            :  * @url_template: a URL template to fetch tiles from
      62                 :            :  *
      63                 :            :  * Creates a new [class@RasterRenderer] that fetches tiles from the given URL
      64                 :            :  * using a [class@TileDownloader] data source.
      65                 :            :  *
      66                 :            :  * Equivalent to:
      67                 :            :  *
      68                 :            :  * ```c
      69                 :            :  * g_autoptr(ShumateTileDownloader) source = shumate_tile_downloader_new (url_template);
      70                 :            :  * ShumateRasterRenderer *renderer = shumate_raster_renderer_new (source);
      71                 :            :  * ```
      72                 :            :  *
      73                 :            :  * Returns: (transfer full): a newly constructed [class@RasterRenderer]
      74                 :            :  */
      75                 :            : ShumateRasterRenderer *
      76                 :          0 : shumate_raster_renderer_new_from_url (const char *url_template)
      77                 :            : {
      78                 :          0 :   g_autoptr(ShumateDataSource) data_source = NULL;
      79                 :            : 
      80         [ #  # ]:          0 :   g_return_val_if_fail (url_template != NULL, NULL);
      81                 :            : 
      82                 :          0 :   data_source = SHUMATE_DATA_SOURCE (shumate_tile_downloader_new (url_template));
      83                 :          0 :   return shumate_raster_renderer_new (data_source);
      84                 :            : }
      85                 :            : 
      86                 :            : 
      87                 :            : /**
      88                 :            :  * shumate_raster_renderer_new_full:
      89                 :            :  * @id: the map source's id
      90                 :            :  * @name: the map source's name
      91                 :            :  * @license: the map source's license
      92                 :            :  * @license_uri: the map source's license URI
      93                 :            :  * @min_zoom: the map source's minimum zoom level
      94                 :            :  * @max_zoom: the map source's maximum zoom level
      95                 :            :  * @tile_size: the map source's tile size (in pixels)
      96                 :            :  * @projection: the map source's projection
      97                 :            :  * @data_source: a [class@DataSource] to provide tile image data
      98                 :            :  *
      99                 :            :  * Creates a new [class@RasterRenderer] with the given details and a data
     100                 :            :  * source.
     101                 :            :  *
     102                 :            :  * Returns: a newly constructed [class@RasterRenderer]
     103                 :            :  */
     104                 :            : ShumateRasterRenderer *
     105                 :          0 : shumate_raster_renderer_new_full (const char           *id,
     106                 :            :                                   const char           *name,
     107                 :            :                                   const char           *license,
     108                 :            :                                   const char           *license_uri,
     109                 :            :                                   guint                 min_zoom,
     110                 :            :                                   guint                 max_zoom,
     111                 :            :                                   guint                 tile_size,
     112                 :            :                                   ShumateMapProjection  projection,
     113                 :            :                                   ShumateDataSource    *data_source)
     114                 :            : {
     115         [ #  # ]:          0 :   g_return_val_if_fail (SHUMATE_IS_DATA_SOURCE (data_source), NULL);
     116                 :            : 
     117                 :          0 :   return g_object_new (SHUMATE_TYPE_RASTER_RENDERER,
     118                 :            :                        "id", id,
     119                 :            :                        "name", name,
     120                 :            :                        "license", license,
     121                 :            :                        "license-uri", license_uri,
     122                 :            :                        "min-zoom-level", min_zoom,
     123                 :            :                        "max-zoom-level", max_zoom,
     124                 :            :                        "tile-size", tile_size,
     125                 :            :                        "projection", projection,
     126                 :            :                        "data-source", data_source,
     127                 :            :                        NULL);
     128                 :            : }
     129                 :            : 
     130                 :            : 
     131                 :            : /**
     132                 :            :  * shumate_raster_renderer_new_full_from_url:
     133                 :            :  * @id: the map source's id
     134                 :            :  * @name: the map source's name
     135                 :            :  * @license: the map source's license
     136                 :            :  * @license_uri: the map source's license URI
     137                 :            :  * @min_zoom: the map source's minimum zoom level
     138                 :            :  * @max_zoom: the map source's maximum zoom level
     139                 :            :  * @tile_size: the map source's tile size (in pixels)
     140                 :            :  * @projection: the map source's projection
     141                 :            :  * @url_template: a URL template to fetch tiles from
     142                 :            :  *
     143                 :            :  * Creates a new [class@RasterRenderer] with the given details and a data
     144                 :            :  * source.
     145                 :            :  *
     146                 :            :  * Returns: a newly constructed [class@RasterRenderer]
     147                 :            :  */
     148                 :            : ShumateRasterRenderer *
     149                 :         27 : shumate_raster_renderer_new_full_from_url (const char           *id,
     150                 :            :                                            const char           *name,
     151                 :            :                                            const char           *license,
     152                 :            :                                            const char           *license_uri,
     153                 :            :                                            guint                 min_zoom,
     154                 :            :                                            guint                 max_zoom,
     155                 :            :                                            guint                 tile_size,
     156                 :            :                                            ShumateMapProjection  projection,
     157                 :            :                                            const char           *url_template)
     158                 :            : {
     159                 :         54 :   g_autoptr(ShumateTileDownloader) data_source = NULL;
     160                 :            : 
     161         [ +  - ]:         27 :   g_return_val_if_fail (url_template != NULL, NULL);
     162                 :            : 
     163                 :         27 :   data_source = shumate_tile_downloader_new (url_template);
     164                 :            : 
     165                 :         27 :   return g_object_new (SHUMATE_TYPE_RASTER_RENDERER,
     166                 :            :                        "id", id,
     167                 :            :                        "name", name,
     168                 :            :                        "license", license,
     169                 :            :                        "license-uri", license_uri,
     170                 :            :                        "min-zoom-level", min_zoom,
     171                 :            :                        "max-zoom-level", max_zoom,
     172                 :            :                        "tile-size", tile_size,
     173                 :            :                        "projection", projection,
     174                 :            :                        "data-source", data_source,
     175                 :            :                        NULL);
     176                 :            : }
     177                 :            : 
     178                 :            : static void
     179                 :         27 : shumate_raster_renderer_finalize (GObject *object)
     180                 :            : {
     181                 :         27 :   ShumateRasterRenderer *self = (ShumateRasterRenderer *)object;
     182                 :            : 
     183         [ +  - ]:         27 :   g_clear_object (&self->data_source);
     184                 :            : 
     185                 :         27 :   G_OBJECT_CLASS (shumate_raster_renderer_parent_class)->finalize (object);
     186                 :         27 : }
     187                 :            : 
     188                 :            : static void
     189                 :          0 : shumate_raster_renderer_get_property (GObject    *object,
     190                 :            :                                       guint       prop_id,
     191                 :            :                                       GValue     *value,
     192                 :            :                                       GParamSpec *pspec)
     193                 :            : {
     194                 :          0 :   ShumateRasterRenderer *self = SHUMATE_RASTER_RENDERER (object);
     195                 :            : 
     196         [ #  # ]:          0 :   switch (prop_id)
     197                 :            :     {
     198                 :          0 :     case PROP_DATA_SOURCE:
     199                 :          0 :       g_value_set_object (value, self->data_source);
     200                 :          0 :       break;
     201                 :          0 :     default:
     202                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     203                 :            :     }
     204                 :          0 : }
     205                 :            : 
     206                 :            : static void
     207                 :         27 : shumate_raster_renderer_set_property (GObject      *object,
     208                 :            :                                       guint         prop_id,
     209                 :            :                                       const GValue *value,
     210                 :            :                                       GParamSpec   *pspec)
     211                 :            : {
     212                 :         27 :   ShumateRasterRenderer *self = SHUMATE_RASTER_RENDERER (object);
     213                 :            : 
     214         [ +  - ]:         27 :   switch (prop_id)
     215                 :            :     {
     216                 :         27 :     case PROP_DATA_SOURCE:
     217                 :         27 :       g_set_object (&self->data_source, g_value_get_object (value));
     218                 :         27 :       break;
     219                 :          0 :     default:
     220                 :          0 :       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     221                 :            :     }
     222                 :         27 : }
     223                 :            : 
     224                 :            : static void shumate_raster_renderer_fill_tile_async (ShumateMapSource    *map_source,
     225                 :            :                                                      ShumateTile         *tile,
     226                 :            :                                                      GCancellable        *cancellable,
     227                 :            :                                                      GAsyncReadyCallback  callback,
     228                 :            :                                                      gpointer             user_data);
     229                 :            : 
     230                 :            : static gboolean shumate_raster_renderer_fill_tile_finish (ShumateMapSource  *map_source,
     231                 :            :                                                           GAsyncResult      *result,
     232                 :            :                                                           GError           **error);
     233                 :            : 
     234                 :            : static void
     235                 :          4 : shumate_raster_renderer_class_init (ShumateRasterRendererClass *klass)
     236                 :            : {
     237                 :          4 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     238                 :          4 :   ShumateMapSourceClass *map_source_class = SHUMATE_MAP_SOURCE_CLASS (klass);
     239                 :            : 
     240                 :          4 :   object_class->finalize = shumate_raster_renderer_finalize;
     241                 :          4 :   object_class->get_property = shumate_raster_renderer_get_property;
     242                 :          4 :   object_class->set_property = shumate_raster_renderer_set_property;
     243                 :            : 
     244                 :          4 :   map_source_class->fill_tile_async = shumate_raster_renderer_fill_tile_async;
     245                 :          4 :   map_source_class->fill_tile_finish = shumate_raster_renderer_fill_tile_finish;
     246                 :            : 
     247                 :            :   /**
     248                 :            :    * ShumateRasterRenderer:data-source:
     249                 :            :    *
     250                 :            :    * The data source that provides image tiles to display. In most cases,
     251                 :            :    * a [class@TileDownloader] is sufficient.
     252                 :            :    */
     253                 :          8 :   properties[PROP_DATA_SOURCE] =
     254                 :          4 :     g_param_spec_object ("data-source",
     255                 :            :                          "Data source",
     256                 :            :                          "Data source",
     257                 :            :                          SHUMATE_TYPE_DATA_SOURCE,
     258                 :            :                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
     259                 :            : 
     260                 :          4 :   g_object_class_install_properties (object_class, N_PROPS, properties);
     261                 :          4 : }
     262                 :            : 
     263                 :            : static void
     264                 :         27 : shumate_raster_renderer_init (ShumateRasterRenderer *self)
     265                 :            : {
     266                 :         27 : }
     267                 :            : 
     268                 :            : 
     269                 :            : static void
     270                 :          0 : on_request_notify (ShumateDataSourceRequest *req,
     271                 :            :                    GParamSpec               *pspec,
     272                 :            :                    gpointer                  user_data)
     273                 :            : {
     274                 :          0 :   GTask *task = user_data;
     275                 :          0 :   GBytes *data;
     276                 :          0 :   ShumateTile *tile = g_task_get_task_data (task);
     277                 :            : 
     278         [ #  # ]:          0 :   if ((data = shumate_data_source_request_get_data (req)))
     279                 :            :     {
     280                 :          0 :       g_autoptr(GError) error = NULL;
     281   [ #  #  #  # ]:          0 :       g_autoptr(GdkPixbuf) pixbuf = NULL;
     282   [ #  #  #  # ]:          0 :       g_autoptr(GInputStream) stream = NULL;
     283   [ #  #  #  # ]:          0 :       g_autoptr(GdkTexture) texture = NULL;
     284                 :            : 
     285                 :          0 :       stream = g_memory_input_stream_new_from_bytes (data);
     286                 :          0 :       pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
     287         [ #  # ]:          0 :       if (error)
     288                 :            :         {
     289                 :          0 :           g_warning ("Failed to create texture from tile data (%d, %d @ %d): %s",
     290                 :            :                      shumate_tile_get_x (tile),
     291                 :            :                      shumate_tile_get_y (tile),
     292                 :            :                      shumate_tile_get_zoom_level (tile),
     293                 :            :                      error->message);
     294         [ #  # ]:          0 :           return;
     295                 :            :         }
     296                 :            : 
     297                 :          0 :       texture = gdk_texture_new_for_pixbuf (pixbuf);
     298         [ #  # ]:          0 :       shumate_tile_set_paintable (tile, GDK_PAINTABLE (texture));
     299                 :            :     }
     300                 :            : }
     301                 :            : 
     302                 :            : static void
     303                 :          0 : on_request_notify_completed (ShumateDataSourceRequest *req,
     304                 :            :                              GParamSpec               *pspec,
     305                 :            :                              gpointer                  user_data)
     306                 :            : {
     307                 :          0 :   g_autoptr(GTask) task = user_data;
     308                 :          0 :   GError *error;
     309                 :          0 :   ShumateTile *tile = g_task_get_task_data (task);
     310                 :            : 
     311                 :          0 :   shumate_tile_set_state (tile, SHUMATE_STATE_DONE);
     312                 :            : 
     313         [ #  # ]:          0 :   if ((error = shumate_data_source_request_get_error (req)))
     314                 :          0 :     g_task_return_error (task, g_error_copy (error));
     315                 :            :   else
     316                 :          0 :     g_task_return_boolean (task, TRUE);
     317                 :          0 : }
     318                 :            : 
     319                 :            : static void
     320                 :          0 : shumate_raster_renderer_fill_tile_async (ShumateMapSource    *map_source,
     321                 :            :                                          ShumateTile         *tile,
     322                 :            :                                          GCancellable        *cancellable,
     323                 :            :                                          GAsyncReadyCallback  callback,
     324                 :            :                                          gpointer             user_data)
     325                 :            : {
     326                 :          0 :   ShumateRasterRenderer *self = (ShumateRasterRenderer *)map_source;
     327                 :          0 :   g_autoptr(GTask) task = NULL;
     328         [ #  # ]:          0 :   g_autoptr(ShumateDataSourceRequest) req = NULL;
     329                 :            : 
     330         [ #  # ]:          0 :   g_return_if_fail (SHUMATE_IS_RASTER_RENDERER (self));
     331         [ #  # ]:          0 :   g_return_if_fail (SHUMATE_IS_TILE (tile));
     332   [ #  #  #  #  :          0 :   g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
             #  #  #  # ]
     333                 :            : 
     334                 :          0 :   task = g_task_new (self, cancellable, callback, user_data);
     335         [ #  # ]:          0 :   g_task_set_source_tag (task, shumate_raster_renderer_fill_tile_async);
     336                 :            : 
     337                 :          0 :   g_task_set_task_data (task, g_object_ref (tile), (GDestroyNotify)g_object_unref);
     338                 :            : 
     339                 :          0 :   req = shumate_data_source_start_request (self->data_source,
     340                 :          0 :                                            shumate_tile_get_x (tile),
     341                 :          0 :                                            shumate_tile_get_y (tile),
     342                 :          0 :                                            shumate_tile_get_zoom_level (tile),
     343                 :            :                                            cancellable);
     344                 :            : 
     345         [ #  # ]:          0 :   if (shumate_data_source_request_is_completed (req))
     346                 :            :     {
     347                 :          0 :       on_request_notify (req, NULL, task);
     348                 :          0 :       on_request_notify_completed (req, NULL, g_steal_pointer (&task));
     349                 :            :     }
     350                 :            :   else
     351                 :            :     {
     352                 :          0 :       g_signal_connect_object (req, "notify::data", (GCallback)on_request_notify, task, 0);
     353                 :          0 :       g_signal_connect_object (req, "notify::completed", (GCallback)on_request_notify_completed, g_object_ref (task), 0);
     354                 :            :     }
     355                 :            : }
     356                 :            : 
     357                 :            : static gboolean
     358                 :          0 : shumate_raster_renderer_fill_tile_finish (ShumateMapSource  *map_source,
     359                 :            :                                           GAsyncResult      *result,
     360                 :            :                                           GError           **error)
     361                 :            : {
     362                 :          0 :   ShumateRasterRenderer *self = (ShumateRasterRenderer *)map_source;
     363                 :            : 
     364         [ #  # ]:          0 :   g_return_val_if_fail (SHUMATE_IS_RASTER_RENDERER (self), FALSE);
     365         [ #  # ]:          0 :   g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
     366                 :            : 
     367                 :          0 :   return g_task_propagate_boolean (G_TASK (result), error);
     368                 :            : }

Generated by: LCOV version 1.14