File: pc_pointlist.c

package info (click to toggle)
pgpointcloud 1.2.5-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,892 kB
  • sloc: sql: 40,767; ansic: 11,045; xml: 935; makefile: 297; cpp: 282; perl: 248; python: 178; sh: 92
file content (133 lines) | stat: -rw-r--r-- 3,132 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/***********************************************************************
 * pc_pointlist.c
 *
 *  Point list handling. Create, get and set values from the
 *  basic PCPOINTLIST structure.
 *
 *  PgSQL Pointcloud is free and open source software provided
 *  by the Government of Canada
 *  Copyright (c) 2013 Natural Resources Canada
 *
 ***********************************************************************/

#include "pc_api_internal.h"
#include <assert.h>

PCPOINTLIST *pc_pointlist_make(uint32_t npoints)
{
  PCPOINTLIST *pl = pcalloc(sizeof(PCPOINTLIST));
  pl->points = pcalloc(sizeof(PCPOINT *) * npoints);
  pl->maxpoints = npoints;
  pl->npoints = 0;
  pl->mem = NULL;
  return pl;
}

void pc_pointlist_free(PCPOINTLIST *pl)
{
  int i;
  for (i = 0; i < pl->npoints; i++)
  {
    pc_point_free(pl->points[i]);
  }
  if (pl->mem)
    pcfree(pl->mem);
  pcfree(pl->points);
  pcfree(pl);
  return;
}

void pc_pointlist_add_point(PCPOINTLIST *pl, PCPOINT *pt)
{
  if (pl->npoints >= pl->maxpoints)
  {
    if (pl->maxpoints < 1)
      pl->maxpoints = 1;
    pl->maxpoints *= 2;
    pl->points = pcrealloc(pl->points, pl->maxpoints * sizeof(PCPOINT *));
  }

  pl->points[pl->npoints] = pt;
  pl->npoints += 1;
  return;
}

PCPOINT *pc_pointlist_get_point(const PCPOINTLIST *pl, int i)
{
  return pl->points[i];
}

PCPOINTLIST *pc_pointlist_from_dimensional(const PCPATCH_DIMENSIONAL *pdl)
{
  PCPOINTLIST *pl;
  PCPATCH_DIMENSIONAL *pdl_uncompressed;
  const PCSCHEMA *schema = pdl->schema;
  int i, j, ndims, npoints;
  uint8_t *data;
  assert(pdl);

  pdl_uncompressed = pc_patch_dimensional_decompress(pdl);

  ndims = schema->ndims;
  npoints = pdl->npoints;
  pl = pc_pointlist_make(npoints);
  pl->mem = data = pcalloc(npoints * schema->size);

  for (i = 0; i < npoints; i++)
  {
    PCPOINT *pt = pc_point_from_data(schema, data);
    for (j = 0; j < ndims; j++)
    {
      PCDIMENSION *dim = pc_schema_get_dimension(schema, j);

      uint8_t *in = pdl_uncompressed->bytes[j].bytes + dim->size * i;
      uint8_t *out = data + dim->byteoffset;
      memcpy(out, in, dim->size);
    }
    pc_pointlist_add_point(pl, pt);
    data += schema->size;
  }
  pc_patch_dimensional_free(pdl_uncompressed);

  return pl;
}

PCPOINTLIST *pc_pointlist_from_uncompressed(const PCPATCH_UNCOMPRESSED *patch)
{
  int i;
  PCPOINTLIST *pl;
  size_t pt_size = patch->schema->size;
  uint32_t npoints = patch->npoints;

  pl = pc_pointlist_make(npoints);
  for (i = 0; i < npoints; i++)
  {
    pc_pointlist_add_point(
        pl, pc_point_from_data(patch->schema, patch->data + i * pt_size));
  }
  return pl;
}

PCPOINTLIST *pc_pointlist_from_patch(const PCPATCH *patch)
{
  switch (patch->type)
  {
  case PC_NONE:
  {
    return pc_pointlist_from_uncompressed((PCPATCH_UNCOMPRESSED *)patch);
  }
  case PC_DIMENSIONAL:
  {
    return pc_pointlist_from_dimensional((PCPATCH_DIMENSIONAL *)patch);
  }
  case PC_LAZPERF:
  {
    return pc_pointlist_from_lazperf((PCPATCH_LAZPERF *)patch);
  }
  }

  /* Don't get here */
  pcerror("pc_pointlist_from_patch: unsupported compression type %d",
          patch->type);
  return NULL;
}