PostGIS  3.4.0dev-r@@SVN_REVISION@@
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages

◆ projFileCreate()

static int projFileCreate ( SHPDUMPERSTATE state)
static

Creates ESRI .prj file for this shp output It looks in the spatial_ref_sys table and outputs the srtext field for this data If data is a table will use geometry_columns, if a query or view will read SRID from query output.

Warning
Will give warning and not output a .prj file if SRID is -1, Unknown, mixed SRIDS or not found in spatial_ref_sys. The dbf and shp will still be output.

make our address space large enough to hold query with table/schema

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

720 {
721  FILE *fp;
722  char *pszFullname, *pszBasename;
723  int i;
724 
725  char *pszFilename = state->shp_file;
726  char *schema = state->schema;
727  char *table = state->table;
728  char *geo_col_name = state->geo_col_name;
729 
730  char *srtext;
731  char *query;
732  char esc_schema[1024];
733  char esc_table[1024];
734  char esc_geo_col_name[1024];
735 
736  int error, result;
737  PGresult *res;
738 
739  /***********
740  *** I'm multiplying by 2 instead of 3 because I am too lazy to figure out how many characters to add
741  *** after escaping if any **/
742  PQescapeStringConn(state->conn, esc_table, table, strlen(table), &error);
743  PQescapeStringConn(state->conn, esc_geo_col_name, geo_col_name, strlen(geo_col_name), &error);
744 
747  /**************************************************
748  * Get what kind of spatial ref is the selected geometry field
749  * We first check the geometry_columns table for a match and then if no match do a distinct against the table
750  * NOTE: COALESCE does a short-circuit check returning the faster query result and skipping the second if first returns something
751  * Escaping quotes in the schema and table in query may not be necessary except to prevent malicious attacks
752  * or should someone be crazy enough to have quotes or other weird character in their table, column or schema names
753  **************************************************/
754  if (schema)
755  {
756  PQescapeStringConn(state->conn, esc_schema, schema, strlen(schema), &error);
757  query = core_asprintf(
758  "SELECT COALESCE((SELECT sr.srtext "
759  " FROM geometry_columns As gc INNER JOIN spatial_ref_sys sr ON sr.srid = gc.srid "
760  " WHERE gc.f_table_schema = '%s' AND gc.f_table_name = '%s' AND gc.f_geometry_column = '%s' LIMIT 1), "
761  " (SELECT CASE WHEN COUNT(DISTINCT sr.srid) > 1 THEN 'm' ELSE MAX(sr.srtext) END As srtext "
762  " FROM \"%s\".\"%s\" As g INNER JOIN spatial_ref_sys sr ON sr.srid = ST_SRID((g.\"%s\")::geometry)) , ' ') As srtext ",
763  esc_schema, esc_table, esc_geo_col_name, schema, table, geo_col_name);
764  }
765  else
766  {
767  query = core_asprintf(
768  "SELECT COALESCE((SELECT sr.srtext "
769  " FROM geometry_columns As gc INNER JOIN spatial_ref_sys sr ON sr.srid = gc.srid "
770  " WHERE gc.f_table_name = '%s' AND gc.f_geometry_column = '%s' AND pg_table_is_visible((gc.f_table_schema || '.' || gc.f_table_name)::regclass) LIMIT 1), "
771  " (SELECT CASE WHEN COUNT(DISTINCT sr.srid) > 1 THEN 'm' ELSE MAX(sr.srtext) END as srtext "
772  " FROM \"%s\" As g INNER JOIN spatial_ref_sys sr ON sr.srid = ST_SRID((g.\"%s\")::geometry)), ' ') As srtext ",
773  esc_table, esc_geo_col_name, table, geo_col_name);
774  }
775 
776  LWDEBUGF(3,"%s\n", query);
777 
778  res = PQexec(state->conn, query);
779 
780  if ( ! res || PQresultStatus(res) != PGRES_TUPLES_OK )
781  {
782  snprintf(state->message, SHPDUMPERMSGLEN, _("WARNING: Could not execute prj query: %s"), PQresultErrorMessage(res));
783  PQclear(res);
784  free(query);
785  return SHPDUMPERWARN;
786  }
787 
788  for (i=0; i < PQntuples(res); i++)
789  {
790  srtext = PQgetvalue(res, i, 0);
791  if (strcmp(srtext,"m") == 0)
792  {
793  snprintf(state->message, SHPDUMPERMSGLEN, _("WARNING: Mixed set of spatial references. No prj file will be generated"));
794  PQclear(res);
795  free(query);
796  return SHPDUMPERWARN;
797  }
798  else
799  {
800  if (srtext[0] == ' ')
801  {
802  snprintf(state->message, SHPDUMPERMSGLEN, _("WARNING: Cannot determine spatial reference (empty table or unknown spatial ref). No prj file will be generated."));
803  PQclear(res);
804  free(query);
805  return SHPDUMPERWARN;
806  }
807  else
808  {
809  /* -------------------------------------------------------------------- */
810  /* Compute the base (layer) name. If there is any extension */
811  /* on the passed in filename we will strip it off. */
812  /* -------------------------------------------------------------------- */
813  pszBasename = (char *) malloc(strlen(pszFilename)+5);
814  strcpy( pszBasename, pszFilename );
815  for ( i = strlen(pszBasename)-1;
816  i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
817  && pszBasename[i] != '\\';
818  i-- ) {}
819 
820  if ( pszBasename[i] == '.' )
821  pszBasename[i] = '\0';
822 
823  pszFullname = core_asprintf("%s.prj", pszBasename);
824  free( pszBasename );
825 
826 
827  /* -------------------------------------------------------------------- */
828  /* Create the file. */
829  /* -------------------------------------------------------------------- */
830  fp = fopen( pszFullname, "wb" );
831  if ( fp == NULL )
832  {
833  free(pszFullname);
834  free(query);
835  return 0;
836  }
837  else
838  {
839  result = fputs (srtext,fp);
840  LWDEBUGF(3, "\n result %d proj SRText is %s .\n", result, srtext);
841  if (result == EOF)
842  {
843  fclose( fp );
844  free( pszFullname );
845  PQclear(res);
846  free(query);
847  return 0;
848  }
849  }
850  fclose( fp );
851  free( pszFullname );
852  }
853  }
854  }
855  PQclear(res);
856  free(query);
857  return SHPDUMPEROK;
858 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void * malloc(YYSIZE_T)
void free(void *)
tuple res
Definition: window.py:79
static char * core_asprintf(const char *format,...)
#define SHPDUMPERMSGLEN
#define SHPDUMPEROK
#define SHPDUMPERWARN
#define _(String)
Definition: shpcommon.h:24
char message[SHPDUMPERMSGLEN]

References _, shp_dumper_state::conn, core_asprintf(), free(), shp_dumper_state::geo_col_name, LWDEBUGF, malloc(), shp_dumper_state::message, window::res, result, shp_dumper_state::schema, shp_dumper_state::shp_file, SHPDUMPERMSGLEN, SHPDUMPEROK, SHPDUMPERWARN, and shp_dumper_state::table.

Referenced by ShpDumperCloseTable().

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