PostGIS  2.1.10dev-r@@SVN_REVISION@@
int ShpLoaderOpenShape ( SHPLOADERSTATE state)

Definition at line 845 of file shp2pgsql-core.c.

References _, shp_loader_state::col_names, COLLECTIONTYPE, shp_loader_state::config, DBFGetFieldCount(), DBFGetFieldInfo(), DBFGetRecordCount(), DBFOpen(), shp_loader_config::encoding, shp_loader_state::field_names, shp_loader_config::force_output, FORCE_OUTPUT_2D, FORCE_OUTPUT_3DM, FORCE_OUTPUT_3DZ, FORCE_OUTPUT_4D, shp_loader_config::forceint4, shp_loader_state::geo_col, shp_loader_state::has_m, shp_loader_state::has_z, shp_loader_state::hDBFHandle, shp_loader_state::hSHPHandle, MAXFIELDNAMELEN, shp_loader_state::message, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, shp_loader_config::null_policy, shp_loader_state::num_entities, shp_loader_state::num_fields, shp_loader_state::num_records, SHPObject::nVertices, shp_loader_state::pgdims, shp_loader_state::pgfieldtypes, shp_loader_state::pgtype, POINTTYPE, POLICY_NULL_ABORT, shp_loader_state::precisions, shp_loader_config::quoteidentifiers, shp_loader_config::readshape, shp_loader_config::shp_file, SHPDestroyObject(), shp_loader_state::shpfiletype, SHPGetInfo(), SHPLOADERERR, SHPLOADERMSGLEN, SHPLOADEROK, SHPLOADERWARN, SHPOpen(), SHPReadObject(), SHPT_ARC, SHPT_ARCM, SHPT_ARCZ, SHPT_MULTIPOINT, SHPT_MULTIPOINTM, SHPT_MULTIPOINTZ, SHPT_POINT, SHPT_POINTM, SHPT_POINTZ, SHPT_POLYGON, SHPT_POLYGONM, SHPT_POLYGONZ, shp_loader_config::simple_geometries, strtolower(), shp_loader_state::types, utf8(), UTF8_BAD_RESULT, UTF8_GOOD_RESULT, UTF8_NO_RESULT, and shp_loader_state::widths.

Referenced by main(), pgui_action_import(), and validate_remote_loader_columns().

846 {
847  SHPObject *obj = NULL;
848  int j, z;
849  int ret = SHPLOADEROK;
850 
851  int field_precision, field_width;
852  char name[MAXFIELDNAMELEN];
853  char name2[MAXFIELDNAMELEN];
854  DBFFieldType type = -1;
855  char *utf8str;
856 
857  /* If we are reading the entire shapefile, open it */
858  if (state->config->readshape == 1)
859  {
860  state->hSHPHandle = SHPOpen(state->config->shp_file, "rb");
861 
862  if (state->hSHPHandle == NULL)
863  {
864  snprintf(state->message, SHPLOADERMSGLEN, _("%s: shape (.shp) or index files (.shx) can not be opened, will just import attribute data."), state->config->shp_file);
865  state->config->readshape = 0;
866 
867  ret = SHPLOADERWARN;
868  }
869  }
870 
871  /* Open the DBF (attributes) file */
872  state->hDBFHandle = DBFOpen(state->config->shp_file, "rb");
873  if ((state->hSHPHandle == NULL && state->config->readshape == 1) || state->hDBFHandle == NULL)
874  {
875  snprintf(state->message, SHPLOADERMSGLEN, _("%s: dbf file (.dbf) can not be opened."), state->config->shp_file);
876 
877  return SHPLOADERERR;
878  }
879 
880  /* If reading the whole shapefile (not just attributes)... */
881  if (state->config->readshape == 1)
882  {
883  SHPGetInfo(state->hSHPHandle, &state->num_entities, &state->shpfiletype, NULL, NULL);
884 
885  /* If null_policy is set to abort, check for NULLs */
886  if (state->config->null_policy == POLICY_NULL_ABORT)
887  {
888  /* If we abort on null items, scan the entire file for NULLs */
889  for (j = 0; j < state->num_entities; j++)
890  {
891  obj = SHPReadObject(state->hSHPHandle, j);
892 
893  if (!obj)
894  {
895  snprintf(state->message, SHPLOADERMSGLEN, _("Error reading shape object %d"), j);
896  return SHPLOADERERR;
897  }
898 
899  if (obj->nVertices == 0)
900  {
901  snprintf(state->message, SHPLOADERMSGLEN, _("Empty geometries found, aborted.)"));
902  return SHPLOADERERR;
903  }
904 
905  SHPDestroyObject(obj);
906  }
907  }
908 
909  /* Check the shapefile type */
910  int geomtype = 0;
911  switch (state->shpfiletype)
912  {
913  case SHPT_POINT:
914  /* Point */
915  state->pgtype = "POINT";
916  geomtype = POINTTYPE;
917  state->pgdims = 2;
918  break;
919 
920  case SHPT_ARC:
921  /* PolyLine */
922  state->pgtype = "MULTILINESTRING";
923  geomtype = MULTILINETYPE ;
924  state->pgdims = 2;
925  break;
926 
927  case SHPT_POLYGON:
928  /* Polygon */
929  state->pgtype = "MULTIPOLYGON";
930  geomtype = MULTIPOLYGONTYPE;
931  state->pgdims = 2;
932  break;
933 
934  case SHPT_MULTIPOINT:
935  /* MultiPoint */
936  state->pgtype = "MULTIPOINT";
937  geomtype = MULTIPOINTTYPE;
938  state->pgdims = 2;
939  break;
940 
941  case SHPT_POINTM:
942  /* PointM */
943  geomtype = POINTTYPE;
944  state->has_m = 1;
945  state->pgtype = "POINTM";
946  state->pgdims = 3;
947  break;
948 
949  case SHPT_ARCM:
950  /* PolyLineM */
951  geomtype = MULTILINETYPE;
952  state->has_m = 1;
953  state->pgtype = "MULTILINESTRINGM";
954  state->pgdims = 3;
955  break;
956 
957  case SHPT_POLYGONM:
958  /* PolygonM */
959  geomtype = MULTIPOLYGONTYPE;
960  state->has_m = 1;
961  state->pgtype = "MULTIPOLYGONM";
962  state->pgdims = 3;
963  break;
964 
965  case SHPT_MULTIPOINTM:
966  /* MultiPointM */
967  geomtype = MULTIPOINTTYPE;
968  state->has_m = 1;
969  state->pgtype = "MULTIPOINTM";
970  state->pgdims = 3;
971  break;
972 
973  case SHPT_POINTZ:
974  /* PointZ */
975  geomtype = POINTTYPE;
976  state->has_m = 1;
977  state->has_z = 1;
978  state->pgtype = "POINT";
979  state->pgdims = 4;
980  break;
981 
982  case SHPT_ARCZ:
983  /* PolyLineZ */
984  state->pgtype = "MULTILINESTRING";
985  geomtype = MULTILINETYPE;
986  state->has_z = 1;
987  state->has_m = 1;
988  state->pgdims = 4;
989  break;
990 
991  case SHPT_POLYGONZ:
992  /* MultiPolygonZ */
993  state->pgtype = "MULTIPOLYGON";
994  geomtype = MULTIPOLYGONTYPE;
995  state->has_z = 1;
996  state->has_m = 1;
997  state->pgdims = 4;
998  break;
999 
1000  case SHPT_MULTIPOINTZ:
1001  /* MultiPointZ */
1002  state->pgtype = "MULTIPOINT";
1003  geomtype = MULTIPOINTTYPE;
1004  state->has_z = 1;
1005  state->has_m = 1;
1006  state->pgdims = 4;
1007  break;
1008 
1009  default:
1010  state->pgtype = "GEOMETRY";
1011  geomtype = COLLECTIONTYPE;
1012  state->has_z = 1;
1013  state->has_m = 1;
1014  state->pgdims = 4;
1015 
1016  snprintf(state->message, SHPLOADERMSGLEN, _("Unknown geometry type: %d\n"), state->shpfiletype);
1017  return SHPLOADERERR;
1018 
1019  break;
1020  }
1021 
1022  /* Force Z/M-handling if configured to do so */
1023  switch(state->config->force_output)
1024  {
1025  case FORCE_OUTPUT_2D:
1026  state->has_z = 0;
1027  state->has_m = 0;
1028  state->pgdims = 2;
1029  break;
1030 
1031  case FORCE_OUTPUT_3DZ:
1032  state->has_z = 1;
1033  state->has_m = 0;
1034  state->pgdims = 3;
1035  break;
1036 
1037  case FORCE_OUTPUT_3DM:
1038  state->has_z = 0;
1039  state->has_m = 1;
1040  state->pgdims = 3;
1041  break;
1042 
1043  case FORCE_OUTPUT_4D:
1044  state->has_z = 1;
1045  state->has_m = 1;
1046  state->pgdims = 4;
1047  break;
1048  default:
1049  /* Simply use the auto-detected values above */
1050  break;
1051  }
1052 
1053  /* If in simple geometry mode, alter names for CREATE TABLE by skipping MULTI */
1054  if (state->config->simple_geometries)
1055  {
1056  if ((geomtype == MULTIPOLYGONTYPE) || (geomtype == MULTILINETYPE) || (geomtype == MULTIPOINTTYPE))
1057  {
1058  /* Chop off the "MULTI" from the string. */
1059  state->pgtype += 5;
1060  }
1061  }
1062 
1063  }
1064  else
1065  {
1066  /* Otherwise just count the number of records in the DBF */
1067  state->num_entities = DBFGetRecordCount(state->hDBFHandle);
1068  }
1069 
1070 
1071  /* Get the field information from the DBF */
1072  state->num_fields = DBFGetFieldCount(state->hDBFHandle);
1073  state->num_records = DBFGetRecordCount(state->hDBFHandle);
1074 
1075  /* Allocate storage for field information */
1076  state->field_names = malloc(state->num_fields * sizeof(char*));
1077  state->types = (DBFFieldType *)malloc(state->num_fields * sizeof(int));
1078  state->widths = malloc(state->num_fields * sizeof(int));
1079  state->precisions = malloc(state->num_fields * sizeof(int));
1080  state->pgfieldtypes = malloc(state->num_fields * sizeof(char *));
1081  state->col_names = malloc((state->num_fields + 2) * sizeof(char) * MAXFIELDNAMELEN);
1082 
1083  /* Generate a string of comma separated column names of the form "(col1, col2 ... colN)" for the SQL
1084  insertion string */
1085  strcpy(state->col_names, "(" );
1086 
1087  for (j = 0; j < state->num_fields; j++)
1088  {
1089  type = DBFGetFieldInfo(state->hDBFHandle, j, name, &field_width, &field_precision);
1090 
1091  state->types[j] = type;
1092  state->widths[j] = field_width;
1093  state->precisions[j] = field_precision;
1094 
1095  if (state->config->encoding)
1096  {
1097  char *encoding_msg = _("Try \"LATIN1\" (Western European), or one of the values described at http://www.gnu.org/software/libiconv/.");
1098 
1099  int rv = utf8(state->config->encoding, name, &utf8str);
1100 
1101  if (rv != UTF8_GOOD_RESULT)
1102  {
1103  if ( rv == UTF8_BAD_RESULT )
1104  snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert field name \"%s\" to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), utf8str, strerror(errno), state->config->encoding, encoding_msg);
1105  else if ( rv == UTF8_NO_RESULT )
1106  snprintf(state->message, SHPLOADERMSGLEN, _("Unable to convert field name to UTF-8 (iconv reports \"%s\"). Current encoding is \"%s\". %s"), strerror(errno), state->config->encoding, encoding_msg);
1107  else
1108  snprintf(state->message, SHPLOADERMSGLEN, _("Unexpected return value from utf8()"));
1109 
1110  if ( rv == UTF8_BAD_RESULT )
1111  free(utf8str);
1112 
1113  return SHPLOADERERR;
1114  }
1115 
1116  strncpy(name, utf8str, MAXFIELDNAMELEN);
1117  free(utf8str);
1118  }
1119 
1120  /*
1121  * Make field names lowercase unless asked to
1122  * keep identifiers case.
1123  */
1124  if (!state->config->quoteidentifiers)
1125  strtolower(name);
1126 
1127  /*
1128  * Escape names starting with the
1129  * escape char (_), those named 'gid'
1130  * or after pgsql reserved attribute names
1131  */
1132  if (name[0] == '_' ||
1133  ! strcmp(name, "gid") || ! strcmp(name, "tableoid") ||
1134  ! strcmp(name, "cmin") ||
1135  ! strcmp(name, "cmax") ||
1136  ! strcmp(name, "xmin") ||
1137  ! strcmp(name, "xmax") ||
1138  ! strcmp(name, "primary") ||
1139  ! strcmp(name, "oid") || ! strcmp(name, "ctid"))
1140  {
1141  strncpy(name2 + 2, name, MAXFIELDNAMELEN - 2);
1142  name2[0] = '_';
1143  name2[1] = '_';
1144  strcpy(name, name2);
1145  }
1146 
1147  /* Avoid duplicating field names */
1148  for (z = 0; z < j ; z++)
1149  {
1150  if (strcmp(state->field_names[z], name) == 0)
1151  {
1152  strncat(name, "__", MAXFIELDNAMELEN);
1153  snprintf(name + strlen(name), MAXFIELDNAMELEN, "%i", j);
1154  break;
1155  }
1156  }
1157 
1158  state->field_names[j] = malloc(strlen(name) + 1);
1159  strcpy(state->field_names[j], name);
1160 
1161  /* Now generate the PostgreSQL type name string and width based upon the shapefile type */
1162  switch (state->types[j])
1163  {
1164  case FTString:
1165  state->pgfieldtypes[j] = malloc(strlen("varchar") + 1);
1166  strcpy(state->pgfieldtypes[j], "varchar");
1167  break;
1168 
1169  case FTDate:
1170  state->pgfieldtypes[j] = malloc(strlen("date") + 1);
1171  strcpy(state->pgfieldtypes[j], "date");
1172  break;
1173 
1174  case FTInteger:
1175  /* Determine exact type based upon field width */
1176  if (state->config->forceint4 || (state->widths[j] >=5 && state->widths[j] < 10))
1177  {
1178  state->pgfieldtypes[j] = malloc(strlen("int4") + 1);
1179  strcpy(state->pgfieldtypes[j], "int4");
1180  }
1181  else if (state->widths[j] < 5)
1182  {
1183  state->pgfieldtypes[j] = malloc(strlen("int2") + 1);
1184  strcpy(state->pgfieldtypes[j], "int2");
1185  }
1186  else
1187  {
1188  state->pgfieldtypes[j] = malloc(strlen("numeric") + 1);
1189  strcpy(state->pgfieldtypes[j], "numeric");
1190  }
1191  break;
1192 
1193  case FTDouble:
1194  /* Determine exact type based upon field width */
1195  if (state->widths[j] > 18)
1196  {
1197  state->pgfieldtypes[j] = malloc(strlen("numeric") + 1);
1198  strcpy(state->pgfieldtypes[j], "numeric");
1199  }
1200  else
1201  {
1202  state->pgfieldtypes[j] = malloc(strlen("float8") + 1);
1203  strcpy(state->pgfieldtypes[j], "float8");
1204  }
1205  break;
1206 
1207  case FTLogical:
1208  state->pgfieldtypes[j] = malloc(strlen("boolean") + 1);
1209  strcpy(state->pgfieldtypes[j], "boolean");
1210  break;
1211 
1212  default:
1213  snprintf(state->message, SHPLOADERMSGLEN, _("Invalid type %x in DBF file"), state->types[j]);
1214  return SHPLOADERERR;
1215  }
1216 
1217  strcat(state->col_names, "\"");
1218  strcat(state->col_names, name);
1219 
1220  if (state->config->readshape == 1 || j < (state->num_fields - 1))
1221  {
1222  /* Don't include last comma if its the last field and no geometry field will follow */
1223  strcat(state->col_names, "\",");
1224  }
1225  else
1226  {
1227  strcat(state->col_names, "\"");
1228  }
1229  }
1230 
1231  /* Append the geometry column if required */
1232  if (state->config->readshape == 1)
1233  strcat(state->col_names, state->geo_col);
1234 
1235  strcat(state->col_names, ")");
1236 
1237 
1238  /* Return status */
1239  return ret;
1240 }
SHPObject SHPAPI_CALL1 * SHPReadObject(SHPHandle hSHP, int iShape);int SHPAPI_CALLSHPWriteObject(SHPHandle hSHP, int iShape, SHPObject *psObject
SHPLOADERCONFIG * config
#define SHPT_ARCM
Definition: shapefil.h:317
DBFFieldType * types
#define FORCE_OUTPUT_3DM
#define SHPT_POLYGONM
Definition: shapefil.h:318
#define FORCE_OUTPUT_3DZ
int nVertices
Definition: shapefil.h:349
#define _(String)
Definition: shpcommon.h:23
#define UTF8_BAD_RESULT
#define MULTIPOINTTYPE
Definition: liblwgeom.h:63
#define SHPLOADERWARN
#define SHPT_MULTIPOINT
Definition: shapefil.h:311
#define SHPT_POLYGON
Definition: shapefil.h:310
void SHPAPI_CALL SHPDestroyObject(SHPObject *psObject)
Definition: shpopen.c:2183
#define SHPT_MULTIPOINTZ
Definition: shapefil.h:315
DBFHandle hDBFHandle
#define UTF8_GOOD_RESULT
int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
Definition: dbfopen.c:1205
#define SHPT_ARCZ
Definition: shapefil.h:313
void SHPAPI_CALL SHPGetInfo(SHPHandle hSHP, int *pnEntities, int *pnShapeType, double *padfMinBound, double *padfMaxBound)
Definition: shpopen.c:797
int utf8(const char *fromcode, char *inputbuf, char **outputbuf)
#define POLICY_NULL_ABORT
SHPHandle SHPAPI_CALL SHPOpen(const char *pszShapeFile, const char *pszAccess)
Definition: shpopen.c:465
DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField, char *pszFieldName, int *pnWidth, int *pnDecimals)
Definition: dbfopen.c:1218
#define MAXFIELDNAMELEN
int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
Definition: dbfopen.c:1192
DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess)
Definition: dbfopen.c:366
#define FORCE_OUTPUT_2D
#define SHPLOADEROK
#define UTF8_NO_RESULT
#define SHPT_MULTIPOINTM
Definition: shapefil.h:319
#define FORCE_OUTPUT_4D
#define SHPT_POINTZ
Definition: shapefil.h:312
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:65
SHPHandle hSHPHandle
#define SHPT_POINTM
Definition: shapefil.h:316
#define SHPT_POLYGONZ
Definition: shapefil.h:314
char message[SHPLOADERMSGLEN]
#define SHPT_POINT
Definition: shapefil.h:308
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
void strtolower(char *s)
#define SHPLOADERERR
#define MULTILINETYPE
Definition: liblwgeom.h:64
#define SHPT_ARC
Definition: shapefil.h:309
#define SHPLOADERMSGLEN
#define COLLECTIONTYPE
Definition: liblwgeom.h:66

Here is the call graph for this function:

Here is the caller graph for this function: