PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ 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 717 of file pgsql2shp-core.c.

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

Referenced by ShpDumperCloseTable().

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