PostGIS  2.1.10dev-r@@SVN_REVISION@@
int ShpLoaderGenerateShapeRow ( SHPDUMPERSTATE state)

Definition at line 2036 of file pgsql2shp-core.c.

References _, shp_dumper_config::binary, shp_dumper_state::config, shp_dumper_state::conn, convert_bytes_to_hex(), create_linestring(), create_multilinestring(), create_multipoint(), create_multipolygon(), create_point(), create_polygon(), shp_dumper_state::currescount, shp_dumper_state::curresrow, shp_dumper_state::currow, shp_dumper_state::dbf, shp_dumper_state::dbffieldtypes, DBFWriteAttributeDirectly(), shp_dumper_state::fetch_query, shp_dumper_state::fetchres, shp_dumper_state::fieldcount, shp_dumper_state::geo_col_name, goodDBFValue(), LINETYPE, LW_PARSER_CHECK_NONE, LWDEBUG, LWDEBUGF, lwgeom_as_lwline(), lwgeom_as_lwmline(), lwgeom_as_lwmpoint(), lwgeom_as_lwmpoly(), lwgeom_as_lwpoint(), lwgeom_as_lwpoly(), lwgeom_free(), lwgeom_from_hexwkb(), lwtype_name(), shp_dumper_state::message, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, nullDBFValue(), shp_dumper_state::pgis_major_version, POINTTYPE, POLYGONTYPE, shp_dumper_state::rowcount, shp_dumper_state::shp, SHPCreateSimpleObject(), SHPDestroyObject(), SHPDUMPERERR, SHPDUMPERMSGLEN, SHPDUMPEROK, SHPT_NULL, SHPWriteObject(), and LWGEOM::type.

Referenced by main(), and pgui_action_export().

2037 {
2038  char *hexewkb = NULL;
2039  unsigned char *hexewkb_binary = NULL;
2040  size_t hexewkb_len;
2041  char *val;
2042  SHPObject *obj = NULL;
2043  LWGEOM *lwgeom;
2044 
2045  int i, geocolnum = 0;
2046 
2047  /* If we try to go pass the end of the table, fail immediately */
2048  if (state->currow > state->rowcount)
2049  {
2050  snprintf(state->message, SHPDUMPERMSGLEN, _("Tried to read past end of table!"));
2051  PQclear(state->fetchres);
2052  return SHPDUMPERERR;
2053  }
2054 
2055  /* If we have reached the end of the current batch, fetch a new one */
2056  if (state->curresrow == state->currescount && state->currow < state->rowcount)
2057  {
2058  /* Clear the previous batch results */
2059  if (state->fetchres)
2060  PQclear(state->fetchres);
2061 
2062  state->fetchres = PQexec(state->conn, state->fetch_query);
2063  if (PQresultStatus(state->fetchres) != PGRES_TUPLES_OK)
2064  {
2065  snprintf(state->message, SHPDUMPERMSGLEN, _("Error executing fetch query: %s"), PQresultErrorMessage(state->fetchres));
2066  PQclear(state->fetchres);
2067  return SHPDUMPERERR;
2068  }
2069 
2070  state->curresrow = 0;
2071  state->currescount = PQntuples(state->fetchres);
2072  }
2073 
2074  /* Grab the id of the geo column if we have one */
2075  if (state->geo_col_name)
2076  geocolnum = PQfnumber(state->fetchres, "_geoX");
2077 
2078  /* Process the next record within the batch. First write out all of
2079  the non-geo fields */
2080  for (i = 0; i < state->fieldcount; i++)
2081  {
2082  /*
2083  * Transform NULL numbers to '0'
2084  * This is because the shapelib
2085  * won't easly take care of setting
2086  * nulls unless paying the acquisition
2087  * of a bug in long integer values
2088  */
2089  if (PQgetisnull(state->fetchres, state->curresrow, i))
2090  {
2091  val = nullDBFValue(state->dbffieldtypes[i]);
2092  }
2093  else
2094  {
2095  val = PQgetvalue(state->fetchres, state->curresrow, i);
2096  val = goodDBFValue(val, state->dbffieldtypes[i]);
2097  }
2098 
2099  /* Write it to the DBF file */
2100  if (!DBFWriteAttributeDirectly(state->dbf, state->currow, i, val))
2101  {
2102  snprintf(state->message, SHPDUMPERMSGLEN, _("Error: record %d could not be created"), state->currow);
2103  PQclear(state->fetchres);
2104  return SHPDUMPERERR;
2105  }
2106  }
2107 
2108  /* Now process the geo field, if present */
2109  if (state->geo_col_name)
2110  {
2111  /* Handle NULL shapes */
2112  if (PQgetisnull(state->fetchres, state->curresrow, geocolnum))
2113  {
2114  obj = SHPCreateSimpleObject(SHPT_NULL, 0, NULL, NULL, NULL);
2115  if (SHPWriteObject(state->shp, -1, obj) == -1)
2116  {
2117  snprintf(state->message, SHPDUMPERMSGLEN, _("Error writing NULL shape for record %d"), state->currow);
2118  PQclear(state->fetchres);
2119  SHPDestroyObject(obj);
2120  return SHPDUMPERERR;
2121  }
2122  SHPDestroyObject(obj);
2123  }
2124  else
2125  {
2126  /* Get the value from the result set */
2127  val = PQgetvalue(state->fetchres, state->curresrow, geocolnum);
2128 
2129  if (!state->config->binary)
2130  {
2131  if (state->pgis_major_version > 0)
2132  {
2133  LWDEBUG(4, "PostGIS >= 1.0, non-binary cursor");
2134 
2135  /* Input is bytea encoded text field, so it must be unescaped and
2136  then converted to hexewkb string */
2137  hexewkb_binary = PQunescapeBytea((unsigned char *)val, &hexewkb_len);
2138  hexewkb = convert_bytes_to_hex(hexewkb_binary, hexewkb_len);
2139  }
2140  else
2141  {
2142  LWDEBUG(4, "PostGIS < 1.0, non-binary cursor");
2143 
2144  /* Input is already hexewkb string, so we can just
2145  copy directly to hexewkb */
2146  hexewkb_len = PQgetlength(state->fetchres, state->curresrow, geocolnum);
2147  hexewkb = malloc(hexewkb_len + 1);
2148  strncpy(hexewkb, val, hexewkb_len + 1);
2149  }
2150  }
2151  else /* binary */
2152  {
2153  LWDEBUG(4, "PostGIS (any version) using binary cursor");
2154 
2155  /* Input is binary field - must convert to hexewkb string */
2156  hexewkb_len = PQgetlength(state->fetchres, state->curresrow, geocolnum);
2157  hexewkb = convert_bytes_to_hex((unsigned char *)val, hexewkb_len);
2158  }
2159 
2160  LWDEBUGF(4, "HexEWKB - length: %d value: %s", strlen(hexewkb), hexewkb);
2161 
2162  /* Deserialize the LWGEOM */
2163  lwgeom = lwgeom_from_hexwkb(hexewkb, LW_PARSER_CHECK_NONE);
2164  if (!lwgeom)
2165  {
2166  snprintf(state->message, SHPDUMPERMSGLEN, _("Error parsing HEXEWKB for record %d"), state->currow);
2167  PQclear(state->fetchres);
2168  free(hexewkb);
2169  return SHPDUMPERERR;
2170  }
2171 
2172  /* Call the relevant method depending upon the geometry type */
2173  LWDEBUGF(4, "geomtype: %s\n", lwtype_name(lwgeom->type));
2174 
2175  switch (lwgeom->type)
2176  {
2177  case POINTTYPE:
2178  obj = create_point(state, lwgeom_as_lwpoint(lwgeom));
2179  break;
2180 
2181  case MULTIPOINTTYPE:
2182  obj = create_multipoint(state, lwgeom_as_lwmpoint(lwgeom));
2183  break;
2184 
2185  case POLYGONTYPE:
2186  obj = create_polygon(state, lwgeom_as_lwpoly(lwgeom));
2187  break;
2188 
2189  case MULTIPOLYGONTYPE:
2190  obj = create_multipolygon(state, lwgeom_as_lwmpoly(lwgeom));
2191  break;
2192 
2193  case LINETYPE:
2194  obj = create_linestring(state, lwgeom_as_lwline(lwgeom));
2195  break;
2196 
2197  case MULTILINETYPE:
2198  obj = create_multilinestring(state, lwgeom_as_lwmline(lwgeom));
2199  break;
2200 
2201  default:
2202  snprintf(state->message, SHPDUMPERMSGLEN, _("Unknown WKB type (%d) for record %d"), lwgeom->type, state->currow);
2203  PQclear(state->fetchres);
2204  SHPDestroyObject(obj);
2205  return SHPDUMPERERR;
2206  }
2207 
2208  /* Free both the original and geometries */
2209  lwgeom_free(lwgeom);
2210 
2211  /* Write the shape out to the file */
2212  if (SHPWriteObject(state->shp, -1, obj) == -1)
2213  {
2214  snprintf(state->message, SHPDUMPERMSGLEN, _("Error writing shape %d"), state->currow);
2215  PQclear(state->fetchres);
2216  SHPDestroyObject(obj);
2217  return SHPDUMPERERR;
2218  }
2219 
2220  SHPDestroyObject(obj);
2221 
2222  /* Free the hexewkb (and temporary bytea unescaped string if used) */
2223  if (hexewkb) free(hexewkb);
2224  if (hexewkb_binary) PQfreemem(hexewkb_binary);
2225  }
2226  }
2227 
2228  /* Increment ready for next time */
2229  state->curresrow++;
2230  state->currow++;
2231 
2232  return SHPDUMPEROK;
2233 }
static SHPObject * create_point(SHPDUMPERSTATE *state, LWPOINT *lwpoint)
#define LINETYPE
Definition: liblwgeom.h:61
static SHPObject * create_polygon(SHPDUMPERSTATE *state, LWPOLY *lwpolygon)
char * convert_bytes_to_hex(uint8_t *ewkb, size_t size)
Binary to hexewkb conversion function.
static SHPObject * create_multilinestring(SHPDUMPERSTATE *state, LWMLINE *lwmultilinestring)
#define POLYGONTYPE
Definition: liblwgeom.h:62
#define _(String)
Definition: shpcommon.h:23
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1006
#define MULTIPOINTTYPE
Definition: liblwgeom.h:63
static char * goodDBFValue(char *in, char fieldType)
Make appropriate formatting of a DBF value based on type.
int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, void *pValue)
Definition: dbfopen.c:1407
SHPDUMPERCONFIG * config
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject)
Definition: shpopen.c:2183
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:125
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:80
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:170
#define LW_PARSER_CHECK_NONE
Definition: liblwgeom.h:1706
static SHPObject * create_linestring(SHPDUMPERSTATE *state, LWLINE *lwlinestring)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:164
#define SHPDUMPERERR
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition: lwgeom.c:161
static SHPObject * create_multipoint(SHPDUMPERSTATE *state, LWMPOINT *lwmultipoint)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:89
#define SHPDUMPERMSGLEN
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
Definition: lwin_wkb.c:753
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:65
#define SHPT_NULL
Definition: shapefil.h:307
int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject *psObject)
Definition: shpopen.c:1171
#define SHPDUMPEROK
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:152
static char * nullDBFValue(char fieldType)
uint8_t type
Definition: liblwgeom.h:352
static SHPObject * create_multipolygon(SHPDUMPERSTATE *state, LWMPOLY *lwmultipolygon)
SHPObject SHPAPI_CALL1 * SHPCreateSimpleObject(int nSHPType, int nVertices, const double *padfX, const double *padfY, const double *padfZ){return(SHPCreateObject(nSHPType,-1, 0, NULL, NULL, nVertices, padfX, padfY, padfZ, NULL)
char message[SHPDUMPERMSGLEN]
#define MULTILINETYPE
Definition: liblwgeom.h:64
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
PGresult * fetchres

Here is the call graph for this function:

Here is the caller graph for this function: