LCOV - code coverage report
Current view: top level - tests - vector-reader.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 199 199 100.0 %
Date: 2024-05-11 21:41:31 Functions: 9 9 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 84 164 51.2 %

           Branch data     Line data    Source code
       1                 :            : #undef G_DISABLE_ASSERT
       2                 :            : 
       3                 :            : #include <shumate/shumate.h>
       4                 :            : #include "shumate/vector/vector_tile.pb-c.h"
       5                 :            : 
       6                 :            : #define MOVE_TO 1
       7                 :            : #define LINE_TO 2
       8                 :            : #define CLOSE_PATH 7
       9                 :            : #define CMD(op, rep) ((op & 7) | ((rep) << 3))
      10                 :            : #define POINT(x, y) unzigzag (x), unzigzag (y)
      11                 :            : 
      12                 :            : static uint32_t
      13                 :            : unzigzag (int value)
      14                 :            : {
      15                 :            :   return (value << 1) ^ (value >> 31);
      16                 :            : }
      17                 :            : 
      18                 :            : static VectorTile__Tile__Value *
      19                 :          9 : new_string_value (const char *value)
      20                 :            : {
      21                 :          9 :   VectorTile__Tile__Value *v = g_new0 (VectorTile__Tile__Value, 1);
      22                 :          9 :   vector_tile__tile__value__init (v);
      23         [ +  - ]:          9 :   v->string_value = g_strdup (value);
      24                 :          9 :   return v;
      25                 :            : }
      26                 :            : 
      27                 :            : static void
      28                 :         54 : set_feature_geometry (VectorTile__Tile__Feature *feature, VectorTile__Tile__GeomType geom_type, const uint32_t *geometry)
      29                 :            : {
      30                 :         54 :   feature->type = geom_type;
      31                 :         54 :   feature->has_type = TRUE;
      32         [ +  + ]:        837 :   for (int i = 0; geometry[i] != G_MAXUINT32; i++)
      33                 :        783 :     feature->n_geometry++;
      34   [ -  +  -  - ]:         54 :   feature->geometry = g_new0 (uint32_t, feature->n_geometry);
      35         [ +  + ]:        837 :   for (int i = 0; i < feature->n_geometry; i++)
      36                 :        783 :     feature->geometry[i] = geometry[i];
      37                 :         54 : }
      38                 :            : 
      39                 :            : static VectorTile__Tile__Feature *
      40                 :         54 : add_feature (VectorTile__Tile__Layer *layer, uint32_t id, uint32_t *tags, uint32_t n_tags)
      41                 :            : {
      42                 :         54 :   VectorTile__Tile__Feature *feature = g_new0 (VectorTile__Tile__Feature, 1);
      43                 :         54 :   vector_tile__tile__feature__init (feature);
      44                 :         54 :   feature->id = id;
      45                 :         54 :   feature->has_id = TRUE;
      46                 :         54 :   feature->n_tags = n_tags;
      47         [ -  + ]:         54 :   feature->tags = g_new0 (uint32_t, n_tags);
      48         [ +  + ]:         72 :   for (int i = 0; i < n_tags; i++)
      49                 :         18 :     feature->tags[i] = tags[i];
      50                 :         54 :   layer->n_features++;
      51   [ -  +  -  - ]:         54 :   layer->features = g_renew (VectorTile__Tile__Feature *, layer->features, layer->n_features);
      52                 :         54 :   layer->features[layer->n_features - 1] = feature;
      53                 :         54 :   return feature;
      54                 :            : }
      55                 :            : 
      56                 :            : static VectorTile__Tile__Layer *
      57                 :         18 : add_layer (VectorTile__Tile *tile, char *name, int extent, char **keys, VectorTile__Tile__Value **values)
      58                 :            : {
      59                 :         18 :   VectorTile__Tile__Layer *layer = g_new0 (VectorTile__Tile__Layer, 1);
      60                 :         18 :   vector_tile__tile__layer__init (layer);
      61         [ +  - ]:         18 :   layer->name = g_strdup (name);
      62                 :         18 :   layer->extent = extent;
      63                 :         18 :   layer->has_extent = TRUE;
      64                 :         18 :   layer->version = 2;
      65                 :         18 :   layer->n_keys = g_strv_length (keys);
      66         [ -  + ]:         18 :   layer->keys = g_new0 (char *, layer->n_keys);
      67         [ +  + ]:         27 :   for (int i = 0; i < layer->n_keys; i++)
      68         [ -  + ]:         18 :     layer->keys[i] = g_strdup (keys[i]);
      69                 :         18 :   layer->n_values = g_strv_length ((char **)values);
      70         [ -  + ]:         18 :   layer->values = g_new0 (VectorTile__Tile__Value *, layer->n_values);
      71         [ +  + ]:         27 :   for (int i = 0; i < layer->n_values; i++)
      72                 :          9 :     layer->values[i] = values[i];
      73                 :         18 :   tile->n_layers++;
      74   [ -  +  -  - ]:         18 :   tile->layers = g_renew (VectorTile__Tile__Layer *, tile->layers, tile->n_layers);
      75                 :         18 :   tile->layers[tile->n_layers - 1] = layer;
      76                 :         18 :   return layer;
      77                 :            : }
      78                 :            : 
      79                 :            : static GBytes *
      80                 :          9 : create_test_tile (void)
      81                 :            : {
      82                 :          9 :   VectorTile__Tile *tile;
      83                 :          9 :   VectorTile__Tile__Layer *layer;
      84                 :          9 :   VectorTile__Tile__Feature *feature;
      85                 :          9 :   uint8_t *out;
      86                 :          9 :   size_t out_len;
      87                 :            : 
      88                 :          9 :   tile = g_new0 (VectorTile__Tile, 1);
      89                 :          9 :   vector_tile__tile__init (tile);
      90                 :            : 
      91                 :         27 :   layer = add_layer (tile, "helloworld", 4096,
      92                 :          9 :     (char*[]){"hello", NULL},
      93                 :          9 :     (VectorTile__Tile__Value*[]){new_string_value ("world"), NULL}
      94                 :            :   );
      95                 :            : 
      96                 :            :   /* Point feature*/
      97                 :          9 :   feature = add_feature (layer, 1, (uint32_t[]){0, 0}, 2);
      98                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__POINT, (uint32_t[]){CMD (MOVE_TO, 1), POINT (1, 2), G_MAXUINT32});
      99                 :            : 
     100                 :            :   /* MultiPoint feature */
     101                 :          9 :   feature = add_feature (layer, 2, (uint32_t[]){}, 0);
     102                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__POINT, (uint32_t[]){
     103                 :            :       CMD (MOVE_TO, 2),
     104                 :          9 :       POINT (100, 200),
     105                 :          9 :       POINT (300, 400),
     106                 :            :       G_MAXUINT32,
     107                 :            :   });
     108                 :            : 
     109                 :            :   /* LineString feature */
     110                 :          9 :   feature = add_feature (layer, 3, (uint32_t[]){}, 0);
     111                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__LINESTRING, (uint32_t[]){
     112                 :            :       CMD (MOVE_TO, 1),
     113                 :          9 :       POINT (100, 200),
     114                 :            :       CMD (LINE_TO, 2),
     115                 :          9 :       POINT (300, 400),
     116                 :          9 :       POINT (500, 600),
     117                 :            :       G_MAXUINT32,
     118                 :            :   });
     119                 :            : 
     120                 :            :   /* MultiLineString feature */
     121                 :          9 :   feature = add_feature (layer, 4, (uint32_t[]){}, 0);
     122                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__LINESTRING, (uint32_t[]){
     123                 :            :       CMD (MOVE_TO, 1),
     124                 :          9 :       POINT (100, 200),
     125                 :            :       CMD (LINE_TO, 2),
     126                 :          9 :       POINT (300, 400),
     127                 :          9 :       POINT (500, 600),
     128                 :            :       CMD (MOVE_TO, 1),
     129                 :          9 :       POINT (100, 200),
     130                 :            :       CMD (LINE_TO, 2),
     131                 :          9 :       POINT (300, 400),
     132                 :          9 :       POINT (500, 600),
     133                 :            :       G_MAXUINT32,
     134                 :            :   });
     135                 :            : 
     136                 :            :   /* Polygon feature */
     137                 :          9 :   feature = add_feature (layer, 5, (uint32_t[]){}, 0);
     138                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__POLYGON, (uint32_t[]){
     139                 :            :       /* Exterior ring */
     140                 :            :       CMD (MOVE_TO, 1),
     141                 :          9 :       POINT (100, 200),
     142                 :            :       CMD (LINE_TO, 3),
     143                 :          9 :       POINT (200, 0),
     144                 :          9 :       POINT (0, 200),
     145                 :          9 :       POINT (-200, 0),
     146                 :            :       CMD (CLOSE_PATH, 1),
     147                 :            :       /* Interior ring */
     148                 :            :       CMD (MOVE_TO, 1),
     149                 :          9 :       POINT (50, -50),
     150                 :            :       CMD (LINE_TO, 3),
     151                 :          9 :       POINT (100, 0),
     152                 :          9 :       POINT (0, -100),
     153                 :          9 :       POINT (-100, 0),
     154                 :            :       CMD (CLOSE_PATH, 1),
     155                 :            :       G_MAXUINT32,
     156                 :            :   });
     157                 :            : 
     158                 :            :   /* MultiPolygon feature */
     159                 :          9 :   feature = add_feature (layer, 6, (uint32_t[]){}, 0);
     160                 :          9 :   set_feature_geometry (feature, VECTOR_TILE__TILE__GEOM_TYPE__POLYGON, (uint32_t[]){
     161                 :            :       /* Exterior ring 1 (a square) */
     162                 :            :       CMD (MOVE_TO, 1),
     163                 :          9 :       POINT (100, 200),
     164                 :            :       CMD (LINE_TO, 3),
     165                 :          9 :       POINT (200, 0),
     166                 :          9 :       POINT (0, 200),
     167                 :          9 :       POINT (-200, 0),
     168                 :            :       CMD (CLOSE_PATH, 1),
     169                 :            :       /* Interior ring (another square)*/
     170                 :            :       CMD (MOVE_TO, 1),
     171                 :          9 :       POINT (50, -50),
     172                 :            :       CMD (LINE_TO, 3),
     173                 :          9 :       POINT (100, 0),
     174                 :          9 :       POINT (0, -100),
     175                 :          9 :       POINT (-100, 0),
     176                 :            :       CMD (CLOSE_PATH, 1),
     177                 :            :       /* Exterior ring 2 (square rotated 45 degrees, overlapping ring 1) */
     178                 :            :       CMD (MOVE_TO, 1),
     179                 :          9 :       POINT (51, 51),
     180                 :            :       CMD (LINE_TO, 3),
     181                 :          9 :       POINT (49, -51),
     182                 :          9 :       POINT (100, 50),
     183                 :          9 :       POINT (-100, 50),
     184                 :            :       CMD (CLOSE_PATH, 1),
     185                 :            :       G_MAXUINT32,
     186                 :            :   });
     187                 :            : 
     188                 :            : 
     189                 :         18 :   layer = add_layer (tile, "helloworld2", 100,
     190                 :          9 :     (char*[]){NULL},
     191                 :          9 :     (VectorTile__Tile__Value*[]){NULL}
     192                 :            :   );
     193                 :            : 
     194                 :          9 :   out_len = vector_tile__tile__get_packed_size (tile);
     195                 :          9 :   out = g_new0 (uint8_t, out_len);
     196                 :          9 :   vector_tile__tile__pack (tile, out);
     197                 :            : 
     198                 :          9 :   vector_tile__tile__free_unpacked (tile, NULL);
     199                 :            : 
     200                 :          9 :   return g_bytes_new_take (out, out_len);
     201                 :            : }
     202                 :            : 
     203                 :            : static void
     204                 :          3 : test_vector_reader_layers (void)
     205                 :            : {
     206                 :          6 :   g_autoptr(ShumateVectorReader) reader = NULL;
     207         [ +  - ]:          3 :   g_autoptr(ShumateVectorReaderIter) iter = NULL;
     208         [ +  - ]:          6 :   g_autoptr(GBytes) tile_data = create_test_tile ();
     209         [ +  - ]:          3 :   g_auto(GValue) value = G_VALUE_INIT;
     210                 :            : 
     211         [ -  + ]:          3 :   g_assert_nonnull (tile_data);
     212                 :            : 
     213                 :          3 :   reader = shumate_vector_reader_new (tile_data);
     214         [ -  + ]:          3 :   g_assert_nonnull (reader);
     215                 :            : 
     216                 :          3 :   iter = shumate_vector_reader_iterate (reader);
     217         [ -  + ]:          3 :   g_assert_nonnull (iter);
     218                 :            : 
     219         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_layer_count (iter), ==, 2);
     220                 :            : 
     221                 :          3 :   shumate_vector_reader_iter_read_layer (iter, 0);
     222         [ -  + ]:          3 :   g_assert_cmpstr (shumate_vector_reader_iter_get_layer_name (iter), ==, "helloworld");
     223         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_layer_extent (iter), ==, 4096);
     224         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_layer_feature_count (iter), ==, 6);
     225                 :            : 
     226                 :          3 :   shumate_vector_reader_iter_read_layer (iter, 1);
     227         [ -  + ]:          3 :   g_assert_cmpstr (shumate_vector_reader_iter_get_layer_name (iter), ==, "helloworld2");
     228         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_layer_extent (iter), ==, 100);
     229         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_layer_feature_count (iter), ==, 0);
     230                 :          3 : }
     231                 :            : 
     232                 :            : static void
     233                 :          3 : test_vector_reader_tags (void)
     234                 :            : {
     235                 :          6 :   g_autoptr(ShumateVectorReader) reader = NULL;
     236         [ +  - ]:          3 :   g_autoptr(ShumateVectorReaderIter) iter = NULL;
     237         [ +  - ]:          6 :   g_autoptr(GBytes) tile_data = create_test_tile ();
     238         [ +  - ]:          3 :   g_auto(GValue) value = G_VALUE_INIT;
     239                 :          3 :   g_autofree const char **keys;
     240                 :            : 
     241         [ -  + ]:          3 :   g_assert_nonnull (tile_data);
     242                 :            : 
     243                 :          3 :   reader = shumate_vector_reader_new (tile_data);
     244         [ -  + ]:          3 :   g_assert_nonnull (reader);
     245                 :            : 
     246                 :          3 :   iter = shumate_vector_reader_iterate (reader);
     247         [ -  + ]:          3 :   g_assert_nonnull (iter);
     248                 :            : 
     249         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_read_layer_by_name (iter, "helloworld"));
     250         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     251         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_id (iter), ==, 1);
     252         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_get_feature_tag (iter, "hello", &value));
     253                 :            : 
     254                 :          3 :   keys = shumate_vector_reader_iter_get_feature_keys (iter);
     255         [ -  + ]:          3 :   g_assert_cmpint (g_strv_length ((char **)keys), ==, 1);
     256         [ -  + ]:          3 :   g_assert_cmpstr (keys[0], ==, "hello");
     257         [ -  + ]:          3 :   g_assert_null (keys[1]);
     258                 :            : 
     259         [ -  + ]:          3 :   g_assert_cmpstr (g_value_get_string (&value), ==, "world");
     260                 :          3 : }
     261                 :            : 
     262                 :            : static void
     263                 :          3 : test_vector_reader_geometry (void)
     264                 :            : {
     265                 :          6 :   g_autoptr(ShumateVectorReader) reader = NULL;
     266         [ +  - ]:          3 :   g_autoptr(ShumateVectorReaderIter) iter = NULL;
     267         [ +  - ]:          6 :   g_autoptr(GBytes) tile_data = create_test_tile ();
     268         [ +  - ]:          3 :   g_auto(GValue) value = G_VALUE_INIT;
     269                 :          3 :   double x, y;
     270                 :            : 
     271         [ -  + ]:          3 :   g_assert_nonnull (tile_data);
     272                 :            : 
     273                 :          3 :   reader = shumate_vector_reader_new (tile_data);
     274         [ -  + ]:          3 :   g_assert_nonnull (reader);
     275                 :            : 
     276                 :          3 :   iter = shumate_vector_reader_iterate (reader);
     277         [ -  + ]:          3 :   g_assert_nonnull (iter);
     278                 :            : 
     279         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_read_layer_by_name (iter, "helloworld"));
     280                 :            : 
     281                 :            :   /* Point */
     282         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     283         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_POINT);
     284         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_get_feature_point (iter, &x, &y));
     285         [ -  + ]:          3 :   g_assert_cmpfloat (x, ==, 1.0);
     286         [ -  + ]:          3 :   g_assert_cmpfloat (y, ==, 2.0);
     287                 :            : 
     288                 :            :   /* MultiPoint */
     289         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     290         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_MULTIPOINT);
     291                 :            : 
     292                 :            :   /* LineString */
     293         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     294         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_LINESTRING);
     295                 :            : 
     296                 :            :   /* MultiLineString */
     297         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     298         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_MULTILINESTRING);
     299                 :            : 
     300                 :            :   /* Polygon */
     301         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     302         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_POLYGON);
     303         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_feature_contains_point (iter, 105, 205));
     304         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 175, 300));
     305         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 0, 0));
     306                 :            : 
     307                 :            :   /* Multipolygon */
     308         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_next_feature (iter));
     309         [ -  + ]:          3 :   g_assert_cmpint (shumate_vector_reader_iter_get_feature_geometry_type (iter), ==, SHUMATE_GEOMETRY_TYPE_MULTIPOLYGON);
     310                 :            :   /* Simple case */
     311         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_feature_contains_point (iter, 105, 205));
     312                 :            :   /* Overlap */
     313         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_feature_contains_point (iter, 275, 300));
     314                 :            :   /* Interior ring + overlap*/
     315         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_feature_contains_point (iter, 225, 300));
     316                 :            :   /* Interior ring */
     317         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 175, 300));
     318                 :            :   /* Outside */
     319         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 0, 0));
     320                 :            :   /* Ray might pass through a corner */
     321         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 350, 299));
     322         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 350, 301));
     323         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 351, 300));
     324         [ -  + ]:          3 :   g_assert_true (shumate_vector_reader_iter_feature_contains_point (iter, 349, 300));
     325                 :            :   /* Horizontal/vertical edges */
     326         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 99, 200));
     327         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 301, 200));
     328         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 100, 199));
     329         [ -  + ]:          3 :   g_assert_false (shumate_vector_reader_iter_feature_contains_point (iter, 100, 401));
     330                 :          3 : }
     331                 :            : 
     332                 :            : int
     333                 :          3 : main (int argc, char *argv[])
     334                 :            : {
     335                 :          3 :   g_test_init (&argc, &argv, NULL);
     336                 :            : 
     337                 :          3 :   g_test_add_func ("/vector-reader/layers", test_vector_reader_layers);
     338                 :          3 :   g_test_add_func ("/vector-reader/tags", test_vector_reader_tags);
     339                 :          3 :   g_test_add_func ("/vector-reader/geometry", test_vector_reader_geometry);
     340                 :            : 
     341                 :          3 :   return g_test_run ();
     342                 :            : }

Generated by: LCOV version 1.14