PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ parse_marc21()

static LWGEOM * parse_marc21 ( xmlNodePtr  xnode)
static

MARC21/XML documents must have <record> as top level element. https://www.loc.gov/standards/marcxml/xml/spy/spy.html

If the coordinates are given in terms of a center point rather than outside limits, the longitude and latitude which form the central axis are recorded twice (in subfields $d and $e and in $f and $g, respectively).

MARC21/XML Document has a <record> but no <datafield:034>

Definition at line 364 of file lwgeom_in_marc21.c.

364  {
365 
366  int ngeoms;
367  int i;
368  xmlNodePtr datafield;
369  xmlNodePtr subfield;
370  LWGEOM *result;
371  LWGEOM **lwgeoms = (LWGEOM**) lwalloc(sizeof(LWGEOM*));
372  uint8_t geometry_type;
373  uint8_t result_type;
374  char *code;
375  char *literal;
376 
377  POSTGIS_DEBUGF(2, "parse_marc21 called: root '<%s>'", xnode->name);
378 
384  if (xmlStrcmp(xnode->name, (xmlChar*) "record")) lwpgerror("invalid MARC21/XML document. Root element <record> expected but <%s> found.",xnode->name);
385 
386  result_type = 0;
387  ngeoms = 0;
388 
389  for (datafield = xnode->children; datafield != NULL; datafield = datafield->next) {
390 
391  char *lw = NULL;
392  char *le = NULL;
393  char *ln = NULL;
394  char *ls = NULL;
395 
396  if (datafield->type != XML_ELEMENT_NODE) continue;
397 
398  if (xmlStrcmp(datafield->name, (xmlChar*) "datafield") != 0 || xmlStrcmp(xmlGetProp(datafield, (xmlChar*) "tag"),(xmlChar*) "034") != 0) continue;
399 
400  POSTGIS_DEBUG(3, " datafield found");
401 
402  for (subfield = datafield->children; subfield != NULL; subfield = subfield->next) {
403 
404  if (subfield->type != XML_ELEMENT_NODE) continue;
405  if (xmlStrcmp(subfield->name, (xmlChar*) "subfield") != 0) continue;
406 
407  code = (char*) xmlGetProp(subfield, (xmlChar*) "code");
408 
409  if ((strcmp(code, "d") != 0 && strcmp(code, "e") != 0 && strcmp(code, "f") != 0 && strcmp(code, "g")) != 0) continue;
410 
411  literal = (char*) xmlNodeGetContent(subfield);
412 
413  POSTGIS_DEBUGF(3, " subfield code '%s': %s", code, literal);
414 
415  if (is_literal_valid(literal) == LW_TRUE) {
416 
417  if (strcmp(code, "d") == 0) lw = literal;
418  else if (strcmp(code, "e") == 0) le = literal;
419  else if (strcmp(code, "f") == 0) ln = literal;
420  else if (strcmp(code, "g") == 0) ls = literal;
421 
422  } else {
423 
424  lwpgerror("parse error - invalid literal at 034$%s: \"%s\"", code, literal);
425 
426  }
427 
428  }
429 
430  xmlFreeNode(subfield);
431 
432  if (lw && le && ln && ls) {
433 
434  double w = parse_geo_literal(lw);
435  double e = parse_geo_literal(le);
436  double n = parse_geo_literal(ln);
437  double s = parse_geo_literal(ls);
438  geometry_type = 0;
439 
440  if (ngeoms > 0) lwgeoms = (LWGEOM**) lwrealloc(lwgeoms, sizeof(LWGEOM*) * (ngeoms + 1));
441 
442  if (fabs(w - e) < 0.0000001f && fabs(n - s) < 0.0000001f) {
443 
450  lwgeoms[ngeoms] = (LWGEOM*) lwpoint_make2d(SRID_UNKNOWN, w, s);
451  geometry_type = MULTIPOINTTYPE;
452 
453  } else {
454 
455  lwgeoms[ngeoms] = (LWGEOM*) lwpoly_construct_envelope(SRID_UNKNOWN, w, n, e, s);
456  geometry_type = MULTIPOLYGONTYPE;
457 
458  }
459 
460  if (ngeoms && result_type != geometry_type) {
461  result_type = COLLECTIONTYPE;
462  } else {
463  result_type = geometry_type;
464  }
465 
466  ngeoms++;
467 
468  } else {
469 
470  if (lw || le || ln || ls) {
471 
472  lwpgerror("parse error - the Coded Cartographic Mathematical Data (datafield:034) in the given MARC21/XML is incomplete. Coordinates for subfields \"$d\",\"$e\",\"$f\" and \"$g\" are expected.");
473  }
474 
475  }
476 
477  }
478 
479  POSTGIS_DEBUG(5, " xmlFreeNode(datafield)");
480  xmlFreeNode(datafield);
481 
482  if (ngeoms == 1) {
483 
484  POSTGIS_DEBUGF(2, "=> parse_marc21 returns single geometry: %s",lwtype_name(lwgeom_get_type(lwgeoms[0])));
485  lwgeom_force_clockwise(lwgeoms[0]);
486  return lwgeoms[0];
487 
488  } else if (ngeoms > 1) {
489 
490  result = (LWGEOM*) lwcollection_construct_empty(result_type,SRID_UNKNOWN, 0, 0);
491 
492  for (i = 0; i < ngeoms; i++) {
493 
494  POSTGIS_DEBUGF(3, " adding geometry to result set: %s",lwtype_name(lwgeom_get_type(lwgeoms[i])));
495  lwgeom_force_clockwise(lwgeoms[i]);
497 
498  }
499 
500  POSTGIS_DEBUGF(2, "=> parse_marc21 returns a collection: %s", lwtype_name(lwgeom_get_type(result)));
501  return result;
502 
503  }
504 
508  POSTGIS_DEBUG(2, "=> parse_marc21 returns NULL");
509  return NULL;
510 
511 }
char * s
Definition: cu_in_wkt.c:23
static char * w
Definition: cu_out_twkb.c:25
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
LWPOINT * lwpoint_make2d(int32_t srid, double x, double y)
Definition: lwpoint.c:163
#define MULTIPOINTTYPE
Definition: liblwgeom.h:105
LWPOLY * lwpoly_construct_envelope(int32_t srid, double x1, double y1, double x2, double y2)
Definition: lwpoly.c:98
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwcollection.c:92
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
void lwgeom_force_clockwise(LWGEOM *lwgeom)
Force Right-hand-rule on LWGEOM polygons.
Definition: lwgeom.c:38
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:188
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
static double parse_geo_literal(char *literal)
static int is_literal_valid(const char *literal)
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwinline.h:145

References COLLECTIONTYPE, is_literal_valid(), LW_TRUE, lwalloc(), lwcollection_add_lwgeom(), lwcollection_construct_empty(), lwgeom_force_clockwise(), lwgeom_get_type(), lwpoint_make2d(), lwpoly_construct_envelope(), lwrealloc(), lwtype_name(), MULTIPOINTTYPE, MULTIPOLYGONTYPE, parse_geo_literal(), result, s, SRID_UNKNOWN, and w.

Referenced by ST_GeomFromMARC21().

Here is the call graph for this function:
Here is the caller graph for this function: