[GRASS-SVN] r71558 - in grass/trunk: raster/r.external raster/r.in.gdal vector/v.external vector/v.in.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Oct 15 09:43:51 PDT 2017
Author: mmetz
Date: 2017-10-15 09:43:51 -0700 (Sun, 15 Oct 2017)
New Revision: 71558
Added:
grass/trunk/raster/r.in.gdal/proj.c
grass/trunk/vector/v.in.ogr/proj.c
Modified:
grass/trunk/raster/r.external/main.c
grass/trunk/raster/r.external/proj.c
grass/trunk/raster/r.external/proto.h
grass/trunk/raster/r.in.gdal/main.c
grass/trunk/vector/v.external/args.c
grass/trunk/vector/v.external/dsn.c
grass/trunk/vector/v.external/local_proto.h
grass/trunk/vector/v.external/main.c
grass/trunk/vector/v.external/proj.c
grass/trunk/vector/v.in.ogr/global.h
grass/trunk/vector/v.in.ogr/main.c
Log:
sync projection check between r.in.gdal, r.external, v.in.ogr, v.external
Modified: grass/trunk/raster/r.external/main.c
===================================================================
--- grass/trunk/raster/r.external/main.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/raster/r.external/main.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -44,7 +44,7 @@
struct Option *input, *source, *output, *band, *title;
} parm;
struct {
- struct Flag *o, *f, *e, *h, *v, *t, *a;
+ struct Flag *o, *j, *f, *e, *h, *v, *t, *a;
} flag;
int min_band, max_band, band;
struct band_info info;
@@ -103,6 +103,12 @@
flag.o->description =
_("Assume that the dataset has same projection as the current location");
+ flag.j = G_define_flag();
+ flag.j->key = 'j';
+ flag.j->description =
+ _("Perform projection check only and exit");
+ flag.j->suppress_required = YES;
+
flag.e = G_define_flag();
flag.e->key = 'e';
flag.e->label = _("Extend region extents based on new dataset");
@@ -191,7 +197,7 @@
exit(EXIT_SUCCESS);
}
- check_projection(&cellhd, hDS, flag.o->answer);
+ check_projection(&cellhd, hDS, NULL, 0, flag.o->answer, flag.j->answer);
if (flag.a->answer && cellhd.proj == PROJECTION_LL) {
G_adjust_Cell_head(&cellhd, 1, 1);
Modified: grass/trunk/raster/r.external/proj.c
===================================================================
--- grass/trunk/raster/r.external/proj.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/raster/r.external/proj.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -3,26 +3,113 @@
#include <grass/glocale.h>
#include <gdal.h>
+#include <ogr_srs_api.h>
-void check_projection(struct Cell_head *cellhd, GDALDatasetH hDS, int override)
+/* keep in sync with r.in.gdal, v.in.ogr, v.external */
+void check_projection(struct Cell_head *cellhd, GDALDatasetH hDS,
+ char *outloc, int create_only, int override,
+ int check_only)
{
struct Cell_head loc_wind;
struct Key_Value *proj_info = NULL, *proj_units = NULL;
struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
- int projcomp_error = 0;
+ const char *wkt;
char error_msg[8096];
+ int proj_trouble;
+ /* -------------------------------------------------------------------- */
+ /* Fetch the projection in GRASS form. */
+ /* -------------------------------------------------------------------- */
+ proj_info = NULL;
+ proj_units = NULL;
+ wkt = GDALGetProjectionRef(hDS);
+ /* proj_trouble:
+ * 0: valid srs
+ * 1: no srs, default to xy
+ * 2: unreadable srs, default to xy
+ */
+
/* Projection only required for checking so convert non-interactively */
- if (GPJ_wkt_to_grass(cellhd, &proj_info,
- &proj_units, GDALGetProjectionRef(hDS), 0) < 0)
- G_warning(_("Unable to convert input raster map projection information to "
- "GRASS format for checking"));
+ proj_trouble = 0;
+ if (wkt && *wkt) {
+ OGRSpatialReferenceH hSRS;
+
+ hSRS = OSRNewSpatialReference(wkt);
+ GPJ_osr_to_grass(cellhd, &proj_info, &proj_units, hSRS, 0);
+
+ if (!OSRIsProjected(hSRS) && !OSRIsGeographic(hSRS)) {
+ G_important_message(_("Input contains an invalid SRS. "
+ "WKT definition:\n%s"), wkt);
+
+ proj_trouble = 2;
+ }
+ if (hSRS)
+ OSRDestroySpatialReference(hSRS);
+ }
else {
+ G_important_message(_("No projection information available"));
+ cellhd->proj = PROJECTION_XY;
+ cellhd->zone = 0;
+ proj_trouble = 1;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Do we need to create a new location? */
+ /* -------------------------------------------------------------------- */
+ if (outloc != NULL) {
+ /* do not create a xy location if an existing SRS was unreadable */
+ if (proj_trouble == 2) {
+ G_fatal_error(_("Unable to convert input map projection to GRASS "
+ "format; cannot create new location."));
+ }
+ else {
+ if (0 != G_make_location(outloc, cellhd,
+ proj_info, proj_units)) {
+ G_fatal_error(_("Unable to create new location <%s>"),
+ outloc);
+ }
+ G_message(_("Location <%s> created"), outloc);
+
+ G_unset_window(); /* new location, projection, and window */
+ G_get_window(cellhd);
+ }
+
+ /* If create only, clean up and exit here */
+ if (create_only) {
+ GDALClose(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else {
+ int err = 0;
+ void (*msg_fn)(const char *, ...);
+
+ if (check_only && override) {
+ /* can't check when over-riding check */
+ override = 0;
+ }
+
+ if (proj_trouble == 2) {
+ strcpy(error_msg, _("Unable to convert input map projection information "
+ "to GRASS format."));
+ if (override) {
+ msg_fn = G_warning;
+ }
+ else {
+ msg_fn = G_fatal_error;
+ }
+ msg_fn(error_msg);
+ if (!override) {
+ exit(EXIT_FAILURE);
+ }
+ }
+
/* -------------------------------------------------------------------- */
/* Does the projection of the current location match the */
/* dataset? */
/* -------------------------------------------------------------------- */
G_get_default_window(&loc_wind);
+ /* fetch LOCATION PROJ info */
if (loc_wind.proj != PROJECTION_XY) {
loc_proj_info = G_get_projinfo();
loc_proj_units = G_get_projunits();
@@ -31,11 +118,12 @@
if (override) {
cellhd->proj = loc_wind.proj;
cellhd->zone = loc_wind.zone;
- G_warning(_("Over-riding projection check"));
+ G_message(_("Over-riding projection check"));
}
- else if (loc_wind.proj != cellhd->proj ||
- (projcomp_error = G_compare_projections(
- loc_proj_info, loc_proj_units, proj_info, proj_units)) < 0) {
+ else if (loc_wind.proj != cellhd->proj
+ || (err =
+ G_compare_projections(loc_proj_info, loc_proj_units,
+ proj_info, proj_units)) != 1) {
int i_value;
strcpy(error_msg,
@@ -43,65 +131,100 @@
" appear to match current location.\n\n"));
/* TODO: output this info sorted by key: */
- if (loc_proj_info != NULL) {
- strcat(error_msg, _("Location PROJ_INFO is:\n"));
- for (i_value = 0;
- loc_proj_info != NULL &&
- i_value < loc_proj_info->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_info->key[i_value],
- loc_proj_info->value[i_value]);
- strcat(error_msg, "\n");
- }
+ if (loc_wind.proj != cellhd->proj || err != -2) {
+ /* error in proj_info */
+ if (loc_proj_info != NULL) {
+ strcat(error_msg, _("Location PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < loc_proj_info->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_info->key[i_value],
+ loc_proj_info->value[i_value]);
+ strcat(error_msg, "\n");
+ }
- if (proj_info != NULL) {
- strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
- for (i_value = 0;
- proj_info != NULL && i_value < proj_info->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_info->key[i_value],
- proj_info->value[i_value]);
- strcat(error_msg, "\nERROR: ");
- switch (projcomp_error) {
- case -1:
- strcat(error_msg, "proj\n");
- break;
- case -2:
- strcat(error_msg, "units\n");
- break;
- case -3:
- strcat(error_msg, "datum\n");
- break;
- case -4:
- strcat(error_msg, "ellps\n");
- break;
- case -5:
- strcat(error_msg, "zone\n");
- break;
+ if (proj_info != NULL) {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < proj_info->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_info->key[i_value],
+ proj_info->value[i_value]);
+ strcat(error_msg, "\nERROR: ");
+ switch (err) {
+ case -1:
+ strcat(error_msg, "proj\n");
+ break;
+ case -2:
+ strcat(error_msg, "units\n");
+ break;
+ case -3:
+ strcat(error_msg, "datum\n");
+ break;
+ case -4:
+ strcat(error_msg, "ellps, a, es\n");
+ break;
+ case -5:
+ strcat(error_msg, "zone\n");
+ break;
+ case -6:
+ strcat(error_msg, "south\n");
+ break;
+ case -7:
+ strcat(error_msg, "x_0\n");
+ break;
+ case -8:
+ strcat(error_msg, "y_0\n");
+ break;
+ case -9:
+ strcat(error_msg, "lon_0\n");
+ break;
+ case -10:
+ strcat(error_msg, "lat_0\n");
+ break;
+ case -11:
+ strcat(error_msg, "lat_1, lat2\n");
+ break;
+ }
}
+ else {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ if (cellhd->proj == PROJECTION_XY)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unreferenced/unknown)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_LL)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (lat/long)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_UTM)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (UTM), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ else
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unknown), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ }
}
else {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- if (cellhd->proj == PROJECTION_XY)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (unreferenced/unknown)\n",
- cellhd->proj);
- else if (cellhd->proj == PROJECTION_LL)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (lat/long)\n", cellhd->proj);
- else if (cellhd->proj == PROJECTION_UTM)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (UTM), zone = %d\n",
- cellhd->proj, cellhd->zone);
- else if (cellhd->proj == PROJECTION_SP)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (State Plane), zone = %d\n",
- cellhd->proj, cellhd->zone);
- else
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (unknown), zone = %d\n",
- cellhd->proj, cellhd->zone);
+ /* error in proj_units */
+ if (loc_proj_units != NULL) {
+ strcat(error_msg, "Location PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < loc_proj_units->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_units->key[i_value],
+ loc_proj_units->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_units != NULL) {
+ strcat(error_msg, "Dataset PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < proj_units->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_units->key[i_value],
+ proj_units->value[i_value]);
+ }
}
strcat(error_msg,
_("\nIn case of no significant differences in the projection definitions,"
@@ -109,12 +232,28 @@
" current location definition.\n"));
strcat(error_msg,
_("Consider generating a new location from the input dataset using "
- "the 'location' parameter.\n"));
- G_fatal_error("%s", error_msg);
+ "the 'location' parameter.\n"));
+
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_fatal_error;
+ msg_fn(error_msg);
+ if (check_only) {
+ exit(EXIT_FAILURE);
+ }
}
else {
- G_message(_("Projection of input dataset and current location "
- "appear to match"));
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_verbose_message;
+ msg_fn(_("Projection of input dataset and current location "
+ "appear to match"));
+ if (check_only) {
+ GDALClose(hDS);
+ exit(EXIT_SUCCESS);
+ }
}
}
}
Modified: grass/trunk/raster/r.external/proto.h
===================================================================
--- grass/trunk/raster/r.external/proto.h 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/raster/r.external/proto.h 2017-10-15 16:43:51 UTC (rev 71558)
@@ -38,7 +38,7 @@
void list_bands(struct Cell_head *, GDALDatasetH);
/* proj.c */
-void check_projection(struct Cell_head *, GDALDatasetH, int);
+void check_projection(struct Cell_head *, GDALDatasetH, char *, int, int, int);
/* window.c */
void setup_window(struct Cell_head *, GDALDatasetH, int *);
Modified: grass/trunk/raster/r.in.gdal/main.c
===================================================================
--- grass/trunk/raster/r.in.gdal/main.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/raster/r.in.gdal/main.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -29,14 +29,16 @@
#include <grass/gprojects.h>
#include <grass/glocale.h>
-#include "gdal.h"
-#include "ogr_srs_api.h"
+#include <gdal.h>
#undef MIN
#undef MAX
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
+void check_projection(struct Cell_head *cellhd, GDALDatasetH hDS,
+ char *outloc, int create_only, int override,
+ int check_only);
static void ImportBand(GDALRasterBandH hBand, const char *output,
struct Ref *group_ref, int *rowmap, int *colmap,
int col_offset);
@@ -56,17 +58,14 @@
char *input;
char *output;
char *title;
- struct Cell_head cellhd, loc_wind, cur_wind;
+ struct Cell_head cellhd, cur_wind;
struct Key_Value *proj_info = NULL, *proj_units = NULL;
- struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
GDALDatasetH hDS;
GDALDriverH hDriver;
GDALRasterBandH hBand;
double adfGeoTransform[6];
int n_bands;
int force_imagery = FALSE;
- char error_msg[8096];
- int projcomp_error = 0;
int overwrite;
int offset = 0;
char *suffix;
@@ -115,7 +114,9 @@
parm.memory->key = "memory";
parm.memory->type = TYPE_INTEGER;
parm.memory->required = NO;
+#if GDAL_VERSION_NUM < 1800
parm.memory->options = "0-2047";
+#endif
parm.memory->answer = "300";
parm.memory->label = _("Maximum memory to be used (in MB)");
parm.memory->description = _("Cache size for raster rows");
@@ -239,7 +240,13 @@
flag_p->guisection = _("Print");
flag_p->suppress_required = YES;
G_option_requires(flag_p, parm.input, NULL);
-
+
+ /* 1. list supported formats */
+ /* 2. print input bands */
+ /* 3. open input */
+ /* 4. check projection / create location */
+ /* 5. open output */
+
/* The parser checks if the map already exists in current mapset, this is
* wrong if location options is used, so we switch out the check and do it
* in the module after the parser */
@@ -248,6 +255,46 @@
if (G_parser(argc, argv))
exit(EXIT_FAILURE);
+ /* -------------------------------------------------------------------- */
+ /* Fire up the engines. */
+ /* -------------------------------------------------------------------- */
+ GDALAllRegister();
+
+ /* -------------------------------------------------------------------- */
+ /* List supported formats and exit. */
+ /* code from GDAL 1.2.5 gcore/gdal_misc.cpp */
+ /* Copyright (c) 1999, Frank Warmerdam */
+ /* -------------------------------------------------------------------- */
+ if (flag_f->answer) {
+ int iDr;
+
+ G_message(_("Supported formats:"));
+ for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) {
+ const char *pszRWFlag;
+
+ hDriver = GDALGetDriver(iDr);
+
+#ifdef GDAL_DCAP_RASTER
+ /* Starting with GDAL 2.0, vector drivers can also be returned */
+ /* Only keep raster drivers */
+ if (!GDALGetMetadataItem(hDriver, GDAL_DCAP_RASTER, NULL))
+ continue;
+#endif
+
+ if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL))
+ pszRWFlag = "rw+";
+ else if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL))
+ pszRWFlag = "rw";
+ else
+ pszRWFlag = "ro";
+
+ fprintf(stdout, " %s (%s): %s\n",
+ GDALGetDriverShortName(hDriver),
+ pszRWFlag, GDALGetDriverLongName(hDriver));
+ }
+ exit(EXIT_SUCCESS);
+ }
+
input = parm.input->answer;
output = parm.output->answer;
@@ -274,13 +321,14 @@
if (flag_l->answer && G_projection() != PROJECTION_LL)
G_fatal_error(_("The '-l' flag only works in Lat/Lon locations"));
- if(num_digits < 0)
+ if (num_digits < 0)
G_fatal_error(_("The number of digits for band numbering must be equal or greater than 0"));
/* Allocate the suffix string */
- if(num_digits > 0) {
+ if (num_digits > 0) {
suffix = G_calloc( num_digits + 1, sizeof(char));
- } else {
+ }
+ else {
/* Band number length should not exceed 64 digits */
suffix = G_calloc(65, sizeof(char));
}
@@ -291,49 +339,15 @@
croptoregion = 0;
}
- /* -------------------------------------------------------------------- */
- /* Fire up the engines. */
- /* -------------------------------------------------------------------- */
- GDALAllRegister();
/* default GDAL memory cache size appears to be only 40 MiB, slowing down r.in.gdal */
if (parm.memory->answer && *parm.memory->answer) {
- /* TODO: GDALGetCacheMax() overflows at 2GiB, implement use of GDALSetCacheMax64() */
+#if GDAL_VERSION_NUM >= 1800
+ GDALSetCacheMax64((GIntBig)atol(parm.memory->answer) * 1024 * 1024);
+ G_verbose_message(_("Using memory cache size: %.1f MiB"), GDALGetCacheMax64()/1024.0/1024.0);
+#else
GDALSetCacheMax(atol(parm.memory->answer) * 1024 * 1024);
G_verbose_message(_("Using memory cache size: %.1f MiB"), GDALGetCacheMax()/1024.0/1024.0);
- }
-
- /* -------------------------------------------------------------------- */
- /* List supported formats and exit. */
- /* code from GDAL 1.2.5 gcore/gdal_misc.cpp */
- /* Copyright (c) 1999, Frank Warmerdam */
- /* -------------------------------------------------------------------- */
- if (flag_f->answer) {
- int iDr;
-
- G_message(_("Supported formats:"));
- for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) {
- GDALDriverH hDriver = GDALGetDriver(iDr);
- const char *pszRWFlag;
-
-#ifdef GDAL_DCAP_RASTER
- /* Starting with GDAL 2.0, vector drivers can also be returned */
- /* Only keep raster drivers */
- if (!GDALGetMetadataItem(hDriver, GDAL_DCAP_RASTER, NULL))
- continue;
#endif
-
- if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL))
- pszRWFlag = "rw+";
- else if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL))
- pszRWFlag = "rw";
- else
- pszRWFlag = "ro";
-
- fprintf(stdout, " %s (%s): %s\n",
- GDALGetDriverShortName(hDriver),
- pszRWFlag, GDALGetDriverLongName(hDriver));
- }
- exit(EXIT_SUCCESS);
}
/* -------------------------------------------------------------------- */
@@ -444,170 +458,13 @@
"with r.region before going any further."));
}
- /* -------------------------------------------------------------------- */
- /* Fetch the projection in GRASS form. */
- /* -------------------------------------------------------------------- */
- proj_info = NULL;
- proj_units = NULL;
+ check_projection(&cellhd, hDS, parm.outloc->answer, flag_c->answer,
+ flag_o->answer, flag_j->answer);
- /* -------------------------------------------------------------------- */
- /* Do we need to create a new location? */
- /* -------------------------------------------------------------------- */
- if (parm.outloc->answer != NULL) {
- /* Convert projection information non-interactively as we can't
- * assume the user has a terminal open */
- if (GPJ_wkt_to_grass(&cellhd, &proj_info,
- &proj_units, GDALGetProjectionRef(hDS), 0) < 0) {
- G_fatal_error(_("Unable to convert input map projection to GRASS "
- "format; cannot create new location."));
- }
- else {
- if (0 != G_make_location(parm.outloc->answer, &cellhd,
- proj_info, proj_units)) {
- G_fatal_error(_("Unable to create new location <%s>"),
- parm.outloc->answer);
- }
- G_message(_("Location <%s> created"), parm.outloc->answer);
- }
-
- /* If the c flag is set, clean up? and exit here */
- if (flag_c->answer) {
- exit(EXIT_SUCCESS);
- }
- }
- else {
- /* Projection only required for checking so convert non-interactively */
- if (GPJ_wkt_to_grass(&cellhd, &proj_info,
- &proj_units, GDALGetProjectionRef(hDS), 0) < 0)
- G_warning(_("Unable to convert input raster map projection information to "
- "GRASS format for checking"));
- else {
- void (*msg_fn)(const char *, ...);
-
- /* -------------------------------------------------------------------- */
- /* Does the projection of the current location match the */
- /* dataset? */
- /* -------------------------------------------------------------------- */
- G_get_default_window(&loc_wind);
- if (loc_wind.proj != PROJECTION_XY) {
- loc_proj_info = G_get_projinfo();
- loc_proj_units = G_get_projunits();
- }
-
- if (flag_o->answer) {
- cellhd.proj = loc_wind.proj;
- cellhd.zone = loc_wind.zone;
- G_warning(_("Over-riding projection check"));
- }
- else if (loc_wind.proj != cellhd.proj
- || (projcomp_error = G_compare_projections(loc_proj_info,
- loc_proj_units,
- proj_info,
- proj_units)) < 0) {
- int i_value;
-
- strcpy(error_msg,
- _("Projection of dataset does not"
- " appear to match current location.\n\n"));
-
- /* TODO: output this info sorted by key: */
- if (loc_proj_info != NULL) {
- strcat(error_msg, _("Location PROJ_INFO is:\n"));
- for (i_value = 0;
- loc_proj_info != NULL &&
- i_value < loc_proj_info->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_info->key[i_value],
- loc_proj_info->value[i_value]);
- strcat(error_msg, "\n");
- }
-
- if (proj_info != NULL) {
- strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
- for (i_value = 0;
- proj_info != NULL && i_value < proj_info->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_info->key[i_value],
- proj_info->value[i_value]);
- strcat(error_msg, "\nERROR: ");
- switch (projcomp_error) {
- case -1:
- strcat(error_msg, "proj\n");
- break;
- case -2:
- strcat(error_msg, "units\n");
- break;
- case -3:
- strcat(error_msg, "datum\n");
- break;
- case -4:
- strcat(error_msg, "ellps\n");
- break;
- case -5:
- strcat(error_msg, "zone\n");
- break;
- case -6:
- strcat(error_msg, "south\n");
- break;
- case -7:
- strcat(error_msg, "x_0\n");
- break;
- case -8:
- strcat(error_msg, "y_0\n");
- break;
- }
- }
- else {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- if (cellhd.proj == PROJECTION_XY)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (unreferenced/unknown)\n",
- cellhd.proj);
- else if (cellhd.proj == PROJECTION_LL)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (lat/long)\n", cellhd.proj);
- else if (cellhd.proj == PROJECTION_UTM)
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (UTM), zone = %d\n",
- cellhd.proj, cellhd.zone);
- else
- sprintf(error_msg + strlen(error_msg),
- "cellhd.proj = %d (unknown), zone = %d\n",
- cellhd.proj, cellhd.zone);
- }
- strcat(error_msg,
- _("\nIn case of no significant differences in the projection definitions,"
- " use the -o flag to ignore them and use"
- " current location definition.\n"));
- strcat(error_msg,
- _("Consider generating a new location from the input dataset using "
- "the 'location' parameter.\n"));
-
- if (flag_j->answer)
- msg_fn = G_message;
- else
- msg_fn = G_fatal_error;
- msg_fn(error_msg);
- if (flag_j->answer)
- exit(EXIT_FAILURE);
- }
- else {
- if (flag_j->answer)
- msg_fn = G_message;
- else
- msg_fn = G_verbose_message;
- msg_fn(_("Projection of input dataset and current location "
- "appear to match"));
- if (flag_j->answer)
- exit(EXIT_SUCCESS);
- }
- }
- }
-
- if (GDALGetRasterCount(hDS) > 1)
+ if (GDALGetRasterCount(hDS) > 1) {
G_message(_("Importing %d raster bands..."),
GDALGetRasterCount(hDS));
+ }
/* -------------------------------------------------------------------- */
/* Set the active window to match the available data. */
Copied: grass/trunk/raster/r.in.gdal/proj.c (from rev 71498, grass/trunk/raster/r.external/proj.c)
===================================================================
--- grass/trunk/raster/r.in.gdal/proj.c (rev 0)
+++ grass/trunk/raster/r.in.gdal/proj.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -0,0 +1,259 @@
+#include <grass/gis.h>
+#include <grass/gprojects.h>
+#include <grass/glocale.h>
+
+#include <gdal.h>
+#include <ogr_srs_api.h>
+
+/* keep in sync with r.external, v.in.ogr, v.external */
+void check_projection(struct Cell_head *cellhd, GDALDatasetH hDS,
+ char *outloc, int create_only, int override,
+ int check_only)
+{
+ struct Cell_head loc_wind;
+ struct Key_Value *proj_info = NULL, *proj_units = NULL;
+ struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
+ const char *wkt;
+ char error_msg[8096];
+ int proj_trouble;
+
+ /* -------------------------------------------------------------------- */
+ /* Fetch the projection in GRASS form. */
+ /* -------------------------------------------------------------------- */
+ proj_info = NULL;
+ proj_units = NULL;
+ wkt = GDALGetProjectionRef(hDS);
+ /* proj_trouble:
+ * 0: valid srs
+ * 1: no srs, default to xy
+ * 2: unreadable srs, default to xy
+ */
+
+ /* Projection only required for checking so convert non-interactively */
+ proj_trouble = 0;
+ if (wkt && *wkt) {
+ OGRSpatialReferenceH hSRS;
+
+ hSRS = OSRNewSpatialReference(wkt);
+ GPJ_osr_to_grass(cellhd, &proj_info, &proj_units, hSRS, 0);
+
+ if (!OSRIsProjected(hSRS) && !OSRIsGeographic(hSRS)) {
+ G_important_message(_("Input contains an invalid SRS. "
+ "WKT definition:\n%s"), wkt);
+
+ proj_trouble = 2;
+ }
+ if (hSRS)
+ OSRDestroySpatialReference(hSRS);
+ }
+ else {
+ G_important_message(_("No projection information available"));
+ cellhd->proj = PROJECTION_XY;
+ cellhd->zone = 0;
+ proj_trouble = 1;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Do we need to create a new location? */
+ /* -------------------------------------------------------------------- */
+ if (outloc != NULL) {
+ /* do not create a xy location if an existing SRS was unreadable */
+ if (proj_trouble == 2) {
+ G_fatal_error(_("Unable to convert input map projection to GRASS "
+ "format; cannot create new location."));
+ }
+ else {
+ if (0 != G_make_location(outloc, cellhd,
+ proj_info, proj_units)) {
+ G_fatal_error(_("Unable to create new location <%s>"),
+ outloc);
+ }
+ G_message(_("Location <%s> created"), outloc);
+
+ G_unset_window(); /* new location, projection, and window */
+ G_get_window(cellhd);
+ }
+
+ /* If create only, clean up and exit here */
+ if (create_only) {
+ GDALClose(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else {
+ int err = 0;
+ void (*msg_fn)(const char *, ...);
+
+ if (check_only && override) {
+ /* can't check when over-riding check */
+ override = 0;
+ }
+
+ if (proj_trouble == 2) {
+ strcpy(error_msg, _("Unable to convert input map projection information "
+ "to GRASS format."));
+ if (override) {
+ msg_fn = G_warning;
+ }
+ else {
+ msg_fn = G_fatal_error;
+ }
+ msg_fn(error_msg);
+ if (!override) {
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Does the projection of the current location match the */
+ /* dataset? */
+ /* -------------------------------------------------------------------- */
+ G_get_default_window(&loc_wind);
+ /* fetch LOCATION PROJ info */
+ if (loc_wind.proj != PROJECTION_XY) {
+ loc_proj_info = G_get_projinfo();
+ loc_proj_units = G_get_projunits();
+ }
+
+ if (override) {
+ cellhd->proj = loc_wind.proj;
+ cellhd->zone = loc_wind.zone;
+ G_message(_("Over-riding projection check"));
+ }
+ else if (loc_wind.proj != cellhd->proj
+ || (err =
+ G_compare_projections(loc_proj_info, loc_proj_units,
+ proj_info, proj_units)) != 1) {
+ int i_value;
+
+ strcpy(error_msg,
+ _("Projection of dataset does not"
+ " appear to match current location.\n\n"));
+
+ /* TODO: output this info sorted by key: */
+ if (loc_wind.proj != cellhd->proj || err != -2) {
+ /* error in proj_info */
+ if (loc_proj_info != NULL) {
+ strcat(error_msg, _("Location PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < loc_proj_info->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_info->key[i_value],
+ loc_proj_info->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_info != NULL) {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < proj_info->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_info->key[i_value],
+ proj_info->value[i_value]);
+ strcat(error_msg, "\nERROR: ");
+ switch (err) {
+ case -1:
+ strcat(error_msg, "proj\n");
+ break;
+ case -2:
+ strcat(error_msg, "units\n");
+ break;
+ case -3:
+ strcat(error_msg, "datum\n");
+ break;
+ case -4:
+ strcat(error_msg, "ellps, a, es\n");
+ break;
+ case -5:
+ strcat(error_msg, "zone\n");
+ break;
+ case -6:
+ strcat(error_msg, "south\n");
+ break;
+ case -7:
+ strcat(error_msg, "x_0\n");
+ break;
+ case -8:
+ strcat(error_msg, "y_0\n");
+ break;
+ case -9:
+ strcat(error_msg, "lon_0\n");
+ break;
+ case -10:
+ strcat(error_msg, "lat_0\n");
+ break;
+ case -11:
+ strcat(error_msg, "lat_1, lat2\n");
+ break;
+ }
+ }
+ else {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ if (cellhd->proj == PROJECTION_XY)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unreferenced/unknown)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_LL)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (lat/long)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_UTM)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (UTM), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ else
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unknown), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ }
+ }
+ else {
+ /* error in proj_units */
+ if (loc_proj_units != NULL) {
+ strcat(error_msg, "Location PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < loc_proj_units->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_units->key[i_value],
+ loc_proj_units->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_units != NULL) {
+ strcat(error_msg, "Dataset PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < proj_units->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_units->key[i_value],
+ proj_units->value[i_value]);
+ }
+ }
+ strcat(error_msg,
+ _("\nIn case of no significant differences in the projection definitions,"
+ " use the -o flag to ignore them and use"
+ " current location definition.\n"));
+ strcat(error_msg,
+ _("Consider generating a new location from the input dataset using "
+ "the 'location' parameter.\n"));
+
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_fatal_error;
+ msg_fn(error_msg);
+ if (check_only) {
+ exit(EXIT_FAILURE);
+ }
+ }
+ else {
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_verbose_message;
+ msg_fn(_("Projection of input dataset and current location "
+ "appear to match"));
+ if (check_only) {
+ GDALClose(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ }
+}
Modified: grass/trunk/vector/v.external/args.c
===================================================================
--- grass/trunk/vector/v.external/args.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.external/args.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -46,6 +46,11 @@
flags->override->description =
_("Assume that the dataset has the same projection as the current location");
+ flags->proj = G_define_flag();
+ flags->proj->key = 'j';
+ flags->proj->description =
+ _("Perform projection check only and exit");
+
flags->format = G_define_flag();
flags->format->key = 'f';
flags->format->description = _("List supported formats and exit");
Modified: grass/trunk/vector/v.external/dsn.c
===================================================================
--- grass/trunk/vector/v.external/dsn.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.external/dsn.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -7,7 +7,7 @@
char *get_datasource_name(const char *opt_dsn, int use_ogr)
{
char *dsn;
-
+
if (G_strncasecmp(opt_dsn, "PG:", 3) == 0) {
/* PostgreSQL/PostGIS */
size_t i;
Modified: grass/trunk/vector/v.external/local_proto.h
===================================================================
--- grass/trunk/vector/v.external/local_proto.h 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.external/local_proto.h 2017-10-15 16:43:51 UTC (rev 71558)
@@ -6,7 +6,7 @@
};
struct _flags {
- struct Flag *format, *layer, *tlist, *topo, *list, *override;
+ struct Flag *format, *layer, *tlist, *topo, *list, *override, *proj;
};
/* args.c */
@@ -22,5 +22,6 @@
void get_table_name(const char *, char **, char **);
/* proj.c */
-void check_projection(const char *, int);
+void check_projection(struct Cell_head *, const char *, int, char *,
+ char *, int, int, int);
#endif
Modified: grass/trunk/vector/v.external/main.c
===================================================================
--- grass/trunk/vector/v.external/main.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.external/main.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -43,6 +43,7 @@
int ilayer, use_ogr;
char buf[GPATH_MAX], *dsn, *layer;
const char *output;
+ struct Cell_head cellhd;
G_gisinit(argv[0]);
@@ -62,7 +63,7 @@
use_ogr = TRUE;
G_debug(1, "GRASS_VECTOR_OGR defined? %s",
getenv("GRASS_VECTOR_OGR") ? "yes" : "no");
- if(options.dsn->answer &&
+ if (options.dsn->answer &&
G_strncasecmp(options.dsn->answer, "PG:", 3) == 0) {
/* -> PostgreSQL */
#if defined HAVE_OGR && defined HAVE_POSTGRES
@@ -137,21 +138,9 @@
}
/* check projection match */
- if (!flags.override->answer) {
- /* here must be used original dsn since check_projection() is
- * using GDAL library */
- char dsn_ogr[DB_SQL_MAX];
-
- if (!use_ogr && G_strncasecmp(options.dsn->answer, "PG:", 3) == 0) {
- /* make dsn OGR-compatible */
- strcpy(dsn_ogr, "PG:");
- strcat(dsn_ogr, dsn);
- }
- else {
- sprintf(dsn_ogr, "%s", dsn);
- }
- check_projection(dsn_ogr, ilayer);
- }
+ G_get_window(&cellhd);
+ check_projection(&cellhd, options.dsn->answer, ilayer, NULL, NULL, 0,
+ flags.override->answer, flags.proj->answer);
/* create new vector map */
putenv("GRASS_VECTOR_EXTERNAL_IGNORE=1");
Modified: grass/trunk/vector/v.external/proj.c
===================================================================
--- grass/trunk/vector/v.external/proj.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.external/proj.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -2,125 +2,380 @@
#include <grass/gprojects.h>
#include <grass/glocale.h>
-#ifdef HAVE_OGR
+#include <gdal.h>
+#include <gdal_version.h>
#include "ogr_api.h"
+
+/* define type of input datasource
+ * as of GDAL 2.2, all functions having as argument a GDAL/OGR dataset
+ * must use the GDAL version, not the OGR version */
+#if GDAL_VERSION_NUM >= 2020000
+typedef GDALDatasetH ds_t;
+#define ds_getlayerbyindex(ds, i) GDALDatasetGetLayer((ds), (i))
+#define ds_close(ds) GDALClose(ds)
+#else
+typedef OGRDataSourceH ds_t;
+#define ds_getlayerbyindex(ds, i) OGR_DS_GetLayer((ds), (i))
+#define ds_close(ds) OGR_DS_Destroy(ds)
#endif
-void check_projection(const char *dsn, int ilayer)
+/* get projection info of OGR layer in GRASS format
+ * return 0 on success (some non-xy SRS)
+ * return 1 if no SRS available
+ * return 2 if SRS available but unreadable */
+int get_layer_proj(OGRLayerH Ogr_layer, struct Cell_head *cellhd,
+ struct Key_Value **proj_info, struct Key_Value **proj_units,
+ char *geom_col, int verbose)
{
-#ifdef HAVE_OGR
- int err = 0;
- char error_msg[8192];
-
- struct Cell_head cellhd, loc_wind;
- struct Key_Value *loc_proj_info, *loc_proj_units;
- struct Key_Value *proj_info, *proj_units;
-
- OGRDataSourceH Ogr_ds;
- OGRLayerH Ogr_layer;
OGRSpatialReferenceH Ogr_projection;
-
- proj_info = proj_units = NULL;
- loc_proj_info = G_get_projinfo();
- loc_proj_units = G_get_projunits();
-
- G_get_default_window(&loc_wind);
- G_get_window(&cellhd);
-
- Ogr_ds = OGROpen(dsn, FALSE, NULL);
- if (!Ogr_ds) {
- G_fatal_error(_("Unable to open data source '%s'"), dsn);
+ char *pszProj4 = NULL;
+
+ Ogr_projection = NULL;
+ *proj_info = NULL;
+ *proj_units = NULL;
+ G_get_window(cellhd);
+
+ /* Fetch input layer projection in GRASS form. */
+#if GDAL_VERSION_NUM >= 1110000
+ if (geom_col) {
+ int igeom;
+ OGRGeomFieldDefnH Ogr_geomdefn;
+ OGRFeatureDefnH Ogr_featuredefn;
+
+ Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
+ igeom = OGR_FD_GetGeomFieldIndex(Ogr_featuredefn, geom_col);
+ if (igeom < 0)
+ G_fatal_error(_("Geometry column <%s> not found in input layer <%s>"),
+ geom_col, OGR_L_GetName(Ogr_layer));
+ Ogr_geomdefn = OGR_FD_GetGeomFieldDefn(Ogr_featuredefn, igeom);
+ Ogr_projection = OGR_GFld_GetSpatialRef(Ogr_geomdefn);
}
- if (ilayer > OGR_DS_GetLayerCount(Ogr_ds))
- return;
- Ogr_layer = OGR_DS_GetLayer(Ogr_ds, ilayer);
- Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);
-
- if (GPJ_osr_to_grass(&cellhd, &proj_info,
- &proj_units, Ogr_projection, 0) < 0)
- G_warning(_("Unable to convert input map projection information to "
- "GRASS format for checking"));
- OGR_DS_Destroy(Ogr_ds);
-
- if ((err =
- G_compare_projections(loc_proj_info, loc_proj_units,
- proj_info, proj_units)) != TRUE) {
- int i_value;
-
- strcpy(error_msg,
- _("Projection of dataset does not"
- " appear to match current location.\n\n"));
-
- /* TODO: output this info sorted by key: */
- if (loc_wind.proj != cellhd.proj || err != -2) {
- if (loc_proj_info != NULL) {
- strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n"));
- for (i_value = 0; i_value < loc_proj_info->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_info->key[i_value],
- loc_proj_info->value[i_value]);
- strcat(error_msg, "\n");
+ else {
+ Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);
+ }
+#else
+ Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer); /* should not be freed later */
+#endif
+
+ /* verbose is used only when comparing input SRS to GRASS projection,
+ * not when comparing SRS's of several input layers */
+ if (GPJ_osr_to_grass(cellhd, proj_info,
+ proj_units, Ogr_projection, 0) < 0) {
+ /* TODO: GPJ_osr_to_grass() does not return anything < 0
+ * check with GRASS 6 and GRASS 5 */
+ G_warning(_("Unable to convert input layer projection information to "
+ "GRASS format for checking"));
+ if (verbose && Ogr_projection != NULL) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_warning(_("Can't get WKT parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+ /* custom checks because if in doubt GPJ_osr_to_grass() returns a
+ * xy CRS */
+ if (Ogr_projection == NULL) {
+ if (verbose) {
+ G_important_message(_("No OGR projection available for layer <%s>"),
+ OGR_L_GetName(Ogr_layer));
+ }
+
+ return 1;
+ }
+
+ if (!OSRIsProjected(Ogr_projection) && !OSRIsGeographic(Ogr_projection)) {
+ G_important_message(_("OGR projection for layer <%s> does not contain a valid SRS"),
+ OGR_L_GetName(Ogr_layer));
+
+ if (verbose) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_important_message(_("Can't get WKT parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+
+ if (OSRExportToProj4(Ogr_projection, &pszProj4) != OGRERR_NONE) {
+ G_important_message(_("OGR projection for layer <%s> can not be converted to proj4"),
+ OGR_L_GetName(Ogr_layer));
+
+ if (verbose) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_important_message(_("Can't get WKT-style parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT-style definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+
+ return 0;
+}
+
+/* keep in sync with r.in.gdal, r.external, v.in.ogr */
+void check_projection(struct Cell_head *cellhd, char *dsn, int layer, char *geom_col,
+ char *outloc, int create_only, int override,
+ int check_only)
+{
+ struct Cell_head loc_wind;
+ struct Key_Value *proj_info = NULL, *proj_units = NULL;
+ struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
+ char error_msg[8096];
+ int proj_trouble;
+ ds_t hDS;
+ OGRLayerH Ogr_layer;
+
+ /* open OGR DSN (v.external does not open the datasource itself */
+ hDS = NULL;
+ if (strlen(dsn) > 0) {
+#if GDAL_VERSION_NUM >= 2020000
+ hDS = GDALOpenEx(dsn, GDAL_OF_VECTOR, NULL, NULL, NULL);
+#else
+ hDS = OGROpen(dsn, FALSE, NULL);
+#endif
+ }
+ if (hDS == NULL)
+ G_fatal_error(_("Unable to open data source <%s>"), dsn);
+
+ /* Get first layer to be imported to use for projection check */
+ Ogr_layer = ds_getlayerbyindex(hDS, layer);
+
+ /* -------------------------------------------------------------------- */
+ /* Fetch the projection in GRASS form. */
+ /* -------------------------------------------------------------------- */
+ proj_info = NULL;
+ proj_units = NULL;
+
+ /* proj_trouble:
+ * 0: valid srs
+ * 1: no srs, default to xy
+ * 2: unreadable srs, default to xy
+ */
+
+ /* Projection only required for checking so convert non-interactively */
+ proj_trouble = get_layer_proj(Ogr_layer, cellhd, &proj_info, &proj_units,
+ geom_col, 1);
+
+ /* -------------------------------------------------------------------- */
+ /* Do we need to create a new location? */
+ /* -------------------------------------------------------------------- */
+ if (outloc != NULL) {
+ /* do not create a xy location because this can mean that the
+ * real SRS has not been recognized or is missing */
+ if (proj_trouble) {
+ G_fatal_error(_("Unable to convert input map projection to GRASS "
+ "format; cannot create new location."));
+ }
+ else {
+ if (0 != G_make_location(outloc, cellhd,
+ proj_info, proj_units)) {
+ G_fatal_error(_("Unable to create new location <%s>"),
+ outloc);
}
-
- if (proj_info != NULL) {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- for (i_value = 0; i_value < proj_info->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_info->key[i_value],
- proj_info->value[i_value]);
- }
- else {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- if (cellhd.proj == PROJECTION_XY)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (unreferenced/unknown)\n",
- cellhd.proj);
- else if (cellhd.proj == PROJECTION_LL)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (lat/long)\n",
- cellhd.proj);
- else if (cellhd.proj == PROJECTION_UTM)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (UTM), zone = %d\n",
- cellhd.proj, cellhd.zone);
- else
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (unknown), zone = %d\n",
- cellhd.proj, cellhd.zone);
- }
+ G_message(_("Location <%s> created"), outloc);
+
+ G_unset_window(); /* new location, projection, and window */
+ G_get_window(cellhd);
+ }
+
+ /* If create only, clean up and exit here */
+ if (create_only) {
+ ds_close(hDS);
+ exit(EXIT_SUCCESS);
}
- else {
- if (loc_proj_units != NULL) {
- strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n");
- for (i_value = 0; i_value < loc_proj_units->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_units->key[i_value],
- loc_proj_units->value[i_value]);
- strcat(error_msg, "\n");
- }
-
- if (proj_units != NULL) {
- strcat(error_msg, "Import dataset PROJ_UNITS is:\n");
- for (i_value = 0; i_value < proj_units->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_units->key[i_value],
- proj_units->value[i_value]);
- }
- }
- sprintf(error_msg + strlen(error_msg),
- _("\nIn case of no significant differences in the projection definitions,"
- " use the -o flag to ignore them and use"
- " current location definition.\n"));
- strcat(error_msg,
- _("Consider generating a new location with 'location' parameter"
- " from input data set.\n"));
- G_fatal_error("%s", error_msg);
}
else {
- G_verbose_message(_("Projection of input dataset and current location "
- "appear to match"));
+ int err = 0;
+ void (*msg_fn)(const char *, ...);
+
+ if (check_only && override) {
+ /* can't check when over-riding check */
+ override = 0;
+ }
+
+ if (proj_trouble == 2) {
+ strcpy(error_msg, _("Unable to convert input map projection information "
+ "to GRASS format."));
+ if (override) {
+ msg_fn = G_warning;
+ }
+ else {
+ msg_fn = G_fatal_error;
+ ds_close(hDS);
+ }
+ msg_fn(error_msg);
+ if (!override) {
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Does the projection of the current location match the */
+ /* dataset? */
+ /* -------------------------------------------------------------------- */
+ G_get_default_window(&loc_wind);
+ /* fetch LOCATION PROJ info */
+ if (loc_wind.proj != PROJECTION_XY) {
+ loc_proj_info = G_get_projinfo();
+ loc_proj_units = G_get_projunits();
+ }
+
+ if (override) {
+ cellhd->proj = loc_wind.proj;
+ cellhd->zone = loc_wind.zone;
+ G_message(_("Over-riding projection check"));
+ }
+ else if (loc_wind.proj != cellhd->proj
+ || (err =
+ G_compare_projections(loc_proj_info, loc_proj_units,
+ proj_info, proj_units)) != 1) {
+ int i_value;
+
+ strcpy(error_msg,
+ _("Projection of dataset does not"
+ " appear to match current location.\n\n"));
+
+ /* TODO: output this info sorted by key: */
+ if (loc_wind.proj != cellhd->proj || err != -2) {
+ /* error in proj_info */
+ if (loc_proj_info != NULL) {
+ strcat(error_msg, _("Location PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < loc_proj_info->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_info->key[i_value],
+ loc_proj_info->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_info != NULL) {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < proj_info->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_info->key[i_value],
+ proj_info->value[i_value]);
+ strcat(error_msg, "\nERROR: ");
+ switch (err) {
+ case -1:
+ strcat(error_msg, "proj\n");
+ break;
+ case -2:
+ strcat(error_msg, "units\n");
+ break;
+ case -3:
+ strcat(error_msg, "datum\n");
+ break;
+ case -4:
+ strcat(error_msg, "ellps, a, es\n");
+ break;
+ case -5:
+ strcat(error_msg, "zone\n");
+ break;
+ case -6:
+ strcat(error_msg, "south\n");
+ break;
+ case -7:
+ strcat(error_msg, "x_0\n");
+ break;
+ case -8:
+ strcat(error_msg, "y_0\n");
+ break;
+ case -9:
+ strcat(error_msg, "lon_0\n");
+ break;
+ case -10:
+ strcat(error_msg, "lat_0\n");
+ break;
+ case -11:
+ strcat(error_msg, "lat_1, lat2\n");
+ break;
+ }
+ }
+ else {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ if (cellhd->proj == PROJECTION_XY)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unreferenced/unknown)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_LL)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (lat/long)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_UTM)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (UTM), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ else
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unknown), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ }
+ }
+ else {
+ /* error in proj_units */
+ if (loc_proj_units != NULL) {
+ strcat(error_msg, "Location PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < loc_proj_units->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_units->key[i_value],
+ loc_proj_units->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_units != NULL) {
+ strcat(error_msg, "Dataset PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < proj_units->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_units->key[i_value],
+ proj_units->value[i_value]);
+ }
+ }
+ strcat(error_msg,
+ _("\nIn case of no significant differences in the projection definitions,"
+ " use the -o flag to ignore them and use"
+ " current location definition.\n"));
+ strcat(error_msg,
+ _("Consider generating a new location from the input dataset using "
+ "the 'location' parameter.\n"));
+
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_fatal_error;
+ msg_fn(error_msg);
+ if (check_only) {
+ exit(EXIT_FAILURE);
+ }
+ }
+ else {
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_verbose_message;
+ msg_fn(_("Projection of input dataset and current location "
+ "appear to match"));
+ if (check_only) {
+ ds_close(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
}
-#endif
+ ds_close(hDS);
}
Modified: grass/trunk/vector/v.in.ogr/global.h
===================================================================
--- grass/trunk/vector/v.in.ogr/global.h 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.in.ogr/global.h 2017-10-15 16:43:51 UTC (rev 71558)
@@ -23,7 +23,23 @@
#ifndef __GLOBAL_H__
#define __GLOBAL_H__
+#include <gdal.h>
+#include <gdal_version.h>
+#include <ogr_api.h>
+/* define type of input datasource
+ * as of GDAL 2.2, all functions having as argument a GDAL/OGR dataset
+ * must use the GDAL version, not the OGR version */
+#if GDAL_VERSION_NUM >= 2020000
+typedef GDALDatasetH ds_t;
+#define ds_getlayerbyindex(ds, i) GDALDatasetGetLayer((ds), (i))
+#define ds_close(ds) GDALClose(ds)
+#else
+typedef OGRDataSourceH ds_t;
+#define ds_getlayerbyindex(ds, i) OGR_DS_GetLayer((ds), (i))
+#define ds_close(ds) OGR_DS_Destroy(ds)
+#endif
+
extern int n_polygons;
extern int n_polygon_boundaries;
extern double split_distance;
Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c 2017-10-15 14:21:28 UTC (rev 71557)
+++ grass/trunk/vector/v.in.ogr/main.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -29,9 +29,7 @@
#include <grass/gprojects.h>
#include <grass/glocale.h>
#include <gdal_version.h> /* needed for OFTDate */
-#include "gdal.h"
-#include "ogr_api.h"
-#include "cpl_conv.h"
+#include <cpl_conv.h>
#include "global.h"
#ifndef MAX
@@ -39,19 +37,6 @@
# define MAX(a,b) ((a>b) ? a : b)
#endif
-/* define type of input datasource
- * as of GDAL 2.2, all functions having as argument a GDAL/OGR dataset
- * must use the GDAL version, not the OGR version */
-#if GDAL_VERSION_NUM >= 2020000
-typedef GDALDatasetH ds_t;
-#define ds_getlayerbyindex(ds, i) GDALDatasetGetLayer((ds), (i))
-#define ds_close(ds) GDALClose(ds)
-#else
-typedef OGRDataSourceH ds_t;
-#define ds_getlayerbyindex(ds, i) OGR_DS_GetLayer((ds), (i))
-#define ds_close(ds) OGR_DS_Destroy(ds)
-#endif
-
int n_polygons;
int n_polygon_boundaries;
double split_distance;
@@ -65,9 +50,10 @@
char *get_datasource_name(const char *, int);
int cmp_layer_srs(ds_t, int, int *, char **, char *);
-int get_layer_proj(OGRLayerH, struct Cell_head *,
- struct Key_Value **, struct Key_Value **,
- char *, int);
+void check_projection(struct Cell_head *cellhd, ds_t hDS, int layer, char *geom_col,
+ char *outloc, int create_only, int override,
+ int check_only);
+
int create_spatial_filter(ds_t Ogr_ds, OGRGeometryH *,
int , int *, char **,
double *, double *,
@@ -118,12 +104,9 @@
double min_area, snap;
char buf[DB_SQL_MAX], namebuf[1024];
char *separator;
-
- struct Key_Value *loc_proj_info, *loc_proj_units;
- struct Key_Value *proj_info, *proj_units;
- struct Cell_head cellhd, loc_wind, cur_wind;
- char error_msg[8192];
+ struct Cell_head cellhd, cur_wind;
+
/* Vector */
struct Map_info Map, Tmp, *Out;
int cat;
@@ -150,7 +133,6 @@
OGRGeometryH Ogr_geometry, *poSpatialFilter;
const char *attr_filter;
struct OGR_iterator OGR_iter;
- int proj_trouble;
int OFTIntegerListlength;
@@ -174,7 +156,6 @@
xmin = ymin = 1.0;
xmax = ymax = 0.0;
- loc_proj_info = loc_proj_units = NULL;
Ogr_ds = NULL;
poSpatialFilter = NULL;
OFTIntegerListlength = 255; /* hack due to limitation in OGR */
@@ -617,17 +598,8 @@
"Input layers must be imported separately."));
}
- /* Get first imported layer to use for projection check */
- Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[0]);
-
- /* Fetch input projection in GRASS form. */
- proj_info = NULL;
- proj_units = NULL;
G_get_window(&cellhd);
- proj_trouble = get_layer_proj(Ogr_layer, &cellhd, &proj_info, &proj_units,
- param.geom->answer, 1);
-
cellhd.north = 1.;
cellhd.south = 0.;
cellhd.west = 0.;
@@ -645,169 +617,11 @@
cellhd.ew_res3 = 1.;
cellhd.tb_res = 1.;
- /* Do we need to create a new location? */
- if (param.outloc->answer != NULL) {
- /* Convert projection information non-interactively as we can't
- * assume the user has a terminal open */
+ check_projection(&cellhd, Ogr_ds, layers[0], param.geom->answer,
+ param.outloc->answer,
+ flag.no_import->answer, flag.over->answer,
+ flag.proj->answer);
- /* do not create a xy location because this can mean that the
- * real SRS has not been recognized */
- if (proj_trouble) {
- G_fatal_error(_("Unable to convert input map projection to GRASS "
- "format; cannot create new location."));
- }
- else {
- if (0 != G_make_location(param.outloc->answer, &cellhd,
- proj_info, proj_units)) {
- G_fatal_error(_("Unable to create new location <%s>"),
- param.outloc->answer);
- }
- G_message(_("Location <%s> created"), param.outloc->answer);
-
- G_unset_window(); /* new location, projection, and window */
- G_get_window(&cellhd);
- }
-
- /* If the i flag is set, clean up and exit here */
- if (flag.no_import->answer) {
- ds_close(Ogr_ds);
- exit(EXIT_SUCCESS);
- }
- }
- else {
- int err = 0;
- void (*msg_fn)(const char *, ...);
-
- /* Projection only required for checking so convert non-interactively */
- if (proj_trouble) {
- strcpy(error_msg, _("Unable to convert input map projection information "
- "to GRASS format."));
- if (flag.over->answer) {
- msg_fn = G_warning;
- }
- else {
- msg_fn = G_fatal_error;
- ds_close(Ogr_ds);
- }
- msg_fn(error_msg);
- if (!flag.over->answer) {
- exit(EXIT_FAILURE);
- }
- }
-
- /* Does the projection of the current location match the dataset? */
- /* G_get_window seems to be unreliable if the location has been changed */
- G_get_default_window(&loc_wind);
- /* fetch LOCATION PROJ info */
- if (loc_wind.proj != PROJECTION_XY) {
- loc_proj_info = G_get_projinfo();
- loc_proj_units = G_get_projunits();
- }
-
- if (flag.over->answer) {
- cellhd.proj = loc_wind.proj;
- cellhd.zone = loc_wind.zone;
- G_message(_("Over-riding projection check"));
- }
- else if (loc_wind.proj != cellhd.proj
- || (err =
- G_compare_projections(loc_proj_info, loc_proj_units,
- proj_info, proj_units)) != TRUE) {
- int i_value;
-
- strcpy(error_msg,
- _("Projection of dataset does not"
- " appear to match current location.\n\n"));
-
- /* TODO: output this info sorted by key: */
- if (loc_wind.proj != cellhd.proj || err != -2) {
- if (loc_proj_info != NULL) {
- strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n"));
- for (i_value = 0; i_value < loc_proj_info->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_info->key[i_value],
- loc_proj_info->value[i_value]);
- strcat(error_msg, "\n");
- }
-
- if (proj_info != NULL) {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- for (i_value = 0; i_value < proj_info->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_info->key[i_value],
- proj_info->value[i_value]);
- }
- else {
- strcat(error_msg, _("Import dataset PROJ_INFO is:\n"));
- if (cellhd.proj == PROJECTION_XY)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (unreferenced/unknown)\n",
- cellhd.proj);
- else if (cellhd.proj == PROJECTION_LL)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (lat/long)\n",
- cellhd.proj);
- else if (cellhd.proj == PROJECTION_UTM)
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (UTM), zone = %d\n",
- cellhd.proj, cellhd.zone);
- else
- sprintf(error_msg + strlen(error_msg),
- "Dataset proj = %d (unknown), zone = %d\n",
- cellhd.proj, cellhd.zone);
- }
- }
- else {
- if (loc_proj_units != NULL) {
- strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n");
- for (i_value = 0; i_value < loc_proj_units->nitems;
- i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- loc_proj_units->key[i_value],
- loc_proj_units->value[i_value]);
- strcat(error_msg, "\n");
- }
-
- if (proj_units != NULL) {
- strcat(error_msg, "Import dataset PROJ_UNITS is:\n");
- for (i_value = 0; i_value < proj_units->nitems; i_value++)
- sprintf(error_msg + strlen(error_msg), "%s: %s\n",
- proj_units->key[i_value],
- proj_units->value[i_value]);
- }
- }
- sprintf(error_msg + strlen(error_msg),
- _("\nIn case of no significant differences in the projection definitions,"
- " use the -o flag to ignore them and use"
- " current location definition.\n"));
- strcat(error_msg,
- _("Consider generating a new location with 'location' parameter"
- " from input data set.\n"));
- if (flag.proj->answer)
- msg_fn = G_message;
- else {
- msg_fn = G_fatal_error;
- ds_close(Ogr_ds);
- }
- msg_fn(error_msg);
- if (flag.proj->answer)
- exit(EXIT_FAILURE);
- }
- else {
- if (flag.proj->answer)
- msg_fn = G_message;
- else
- msg_fn = G_verbose_message;
- msg_fn(_("Projection of input dataset and current location "
- "appear to match"));
- if (flag.proj->answer) {
- ds_close(Ogr_ds);
- exit(EXIT_SUCCESS);
- }
- }
- }
-
/* get output name */
if (param.out->answer) {
output = G_store(param.out->answer);
@@ -2062,212 +1876,6 @@
return NULL;
}
-/* get projection info of OGR layer in GRASS format
- * return 0 on success (some non-xy SRS)
- * return 1 if no SRS available
- * return 2 if SRS available but unreadable */
-int get_layer_proj(OGRLayerH Ogr_layer, struct Cell_head *cellhd,
- struct Key_Value **proj_info, struct Key_Value **proj_units,
- char *geom_col, int verbose)
-{
- OGRSpatialReferenceH Ogr_projection;
-
- Ogr_projection = NULL;
- *proj_info = NULL;
- *proj_units = NULL;
- G_get_window(cellhd);
-
- /* Fetch input layer projection in GRASS form. */
-#if GDAL_VERSION_NUM >= 1110000
- if (geom_col) {
- int igeom;
- OGRGeomFieldDefnH Ogr_geomdefn;
- OGRFeatureDefnH Ogr_featuredefn;
-
- Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
- igeom = OGR_FD_GetGeomFieldIndex(Ogr_featuredefn, geom_col);
- if (igeom < 0)
- G_fatal_error(_("Geometry column <%s> not found in input layer <%s>"),
- geom_col, OGR_L_GetName(Ogr_layer));
- Ogr_geomdefn = OGR_FD_GetGeomFieldDefn(Ogr_featuredefn, igeom);
- Ogr_projection = OGR_GFld_GetSpatialRef(Ogr_geomdefn);
- }
- else {
- Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);
- }
-#else
- Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer); /* should not be freed later */
-#endif
-
- /* verbose is used only when comparing input SRS to GRASS projection,
- * not when comparing SRS's of several input layers */
- if (GPJ_osr_to_grass(cellhd, proj_info,
- proj_units, Ogr_projection, 0) < 0) {
- /* TODO: GPJ_osr_to_grass() does not return anything < 0
- * check with GRASS 6 and GRASS 5 */
- G_warning(_("Unable to convert input layer projection information to "
- "GRASS format for checking"));
- if (verbose && Ogr_projection != NULL) {
- char *wkt = NULL;
-
- if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
- G_warning(_("Can't get WKT-style parameter string"));
- }
- else if (wkt) {
- G_important_message(_("WKT-style definition:\n%s"), wkt);
- }
- }
-
- return 2;
- }
- /* custom checks because if in doubt GPJ_osr_to_grass() returns a
- * xy CRS */
- if (Ogr_projection == NULL) {
- if (verbose) {
- G_important_message(_("No OGR projection available for layer <%s>"),
- OGR_L_GetName(Ogr_layer));
- }
-
- return 1;
- }
-
- if (!OSRIsProjected(Ogr_projection) && !OSRIsGeographic(Ogr_projection)) {
- G_important_message(_("OGR projection for layer <%s> does not contain a valid SRS"),
- OGR_L_GetName(Ogr_layer));
-
- if (verbose) {
- char *wkt = NULL;
-
- if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
- G_important_message(_("Can't get WKT-style parameter string"));
- }
- else if (wkt) {
- G_important_message(_("WKT-style definition:\n%s"), wkt);
- }
- }
-
- return 2;
- }
-
- char *pszProj4 = NULL;
-
- if (OSRExportToProj4(Ogr_projection, &pszProj4) != OGRERR_NONE) {
- G_important_message(_("OGR projection for layer <%s> can not be converted to proj4"),
- OGR_L_GetName(Ogr_layer));
-
- if (verbose) {
- char *wkt = NULL;
-
- if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
- G_important_message(_("Can't get WKT-style parameter string"));
- }
- else if (wkt) {
- G_important_message(_("WKT-style definition:\n%s"), wkt);
- }
- }
-
- return 2;
- }
-
- return 0;
-}
-
-/* compare projections of all OGR layers
- * return 0 if all layers have the same projection
- * return 1 if layer projections differ */
-int cmp_layer_srs(ds_t Ogr_ds, int nlayers, int *layers,
- char **layer_names, char *geom_col)
-{
- int layer;
- struct Key_Value *proj_info1, *proj_units1;
- struct Key_Value *proj_info2, *proj_units2;
- struct Cell_head cellhd1, cellhd2;
- OGRLayerH Ogr_layer;
-
- if (nlayers == 1)
- return 0;
-
- proj_info1 = proj_units1 = NULL;
- proj_info2 = proj_units2 = NULL;
-
- layer = 0;
- do {
- /* Get first SRS */
- Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[layer]);
-
- if (get_layer_proj(Ogr_layer, &cellhd1, &proj_info1, &proj_units1,
- geom_col, 0) == 0) {
- break;
- }
- layer++;
- } while (layer < nlayers);
-
- if (layer == nlayers) {
- /* could not get layer proj in GRASS format for any of the layers
- * -> projections of all layers are the same, i.e. unreadable by GRASS */
- G_warning(_("Layer projections are unreadable"));
- if (proj_info1)
- G_free_key_value(proj_info1);
- if (proj_units1)
- G_free_key_value(proj_units1);
-
- return 0;
- }
- if (layer > 0) {
- /* could not get layer proj in GRASS format for at least one of the layers
- * -> mix of unreadable and readable projections */
- G_warning(_("Projection for layer <%s> is unreadable"),
- layer_names[layer]);
- if (proj_info1)
- G_free_key_value(proj_info1);
- if (proj_units1)
- G_free_key_value(proj_units1);
-
- return 1;
- }
-
- for (layer = 1; layer < nlayers; layer++) {
- /* Get SRS of other layer(s) */
- Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[layer]);
- if (get_layer_proj(Ogr_layer, &cellhd2, &proj_info2, &proj_units2,
- geom_col, 0) != 0) {
- G_free_key_value(proj_info1);
- G_free_key_value(proj_units1);
-
- return 1;
- }
-
- if (cellhd1.proj != cellhd2.proj
- || G_compare_projections(proj_info1, proj_units1,
- proj_info2, proj_units2) != TRUE) {
- if (proj_info1)
- G_free_key_value(proj_info1);
- if (proj_units1)
- G_free_key_value(proj_units1);
- if (proj_info2)
- G_free_key_value(proj_info2);
- if (proj_units2)
- G_free_key_value(proj_units2);
-
- G_warning(_("Projection of layer <%s> is different from "
- "projection of layer <%s>"),
- layer_names[layer], layer_names[layer - 1]);
-
- return 1;
- }
- if (proj_info2)
- G_free_key_value(proj_info2);
- if (proj_units2)
- G_free_key_value(proj_units2);
- }
- if (proj_info1)
- G_free_key_value(proj_info1);
- if (proj_units1)
- G_free_key_value(proj_units1);
-
- return 0;
-}
-
int create_spatial_filter(ds_t Ogr_ds, OGRGeometryH *poSpatialFilter,
int nlayers, int *layers, char **layer_names,
double *xmin, double *ymin,
Copied: grass/trunk/vector/v.in.ogr/proj.c (from rev 71498, grass/trunk/raster/r.external/proj.c)
===================================================================
--- grass/trunk/vector/v.in.ogr/proj.c (rev 0)
+++ grass/trunk/vector/v.in.ogr/proj.c 2017-10-15 16:43:51 UTC (rev 71558)
@@ -0,0 +1,450 @@
+#include <grass/gis.h>
+#include <grass/gprojects.h>
+#include <grass/glocale.h>
+
+#include <ogr_srs_api.h>
+#include "global.h"
+
+/* get projection info of OGR layer in GRASS format
+ * return 0 on success (some non-xy SRS)
+ * return 1 if no SRS available
+ * return 2 if SRS available but unreadable */
+int get_layer_proj(OGRLayerH Ogr_layer, struct Cell_head *cellhd,
+ struct Key_Value **proj_info, struct Key_Value **proj_units,
+ char *geom_col, int verbose)
+{
+ OGRSpatialReferenceH Ogr_projection;
+ char *pszProj4 = NULL;
+
+ Ogr_projection = NULL;
+ *proj_info = NULL;
+ *proj_units = NULL;
+ G_get_window(cellhd);
+
+ /* Fetch input layer projection in GRASS form. */
+#if GDAL_VERSION_NUM >= 1110000
+ if (geom_col) {
+ int igeom;
+ OGRGeomFieldDefnH Ogr_geomdefn;
+ OGRFeatureDefnH Ogr_featuredefn;
+
+ Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
+ igeom = OGR_FD_GetGeomFieldIndex(Ogr_featuredefn, geom_col);
+ if (igeom < 0)
+ G_fatal_error(_("Geometry column <%s> not found in input layer <%s>"),
+ geom_col, OGR_L_GetName(Ogr_layer));
+ Ogr_geomdefn = OGR_FD_GetGeomFieldDefn(Ogr_featuredefn, igeom);
+ Ogr_projection = OGR_GFld_GetSpatialRef(Ogr_geomdefn);
+ }
+ else {
+ Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer);
+ }
+#else
+ Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer); /* should not be freed later */
+#endif
+
+ /* verbose is used only when comparing input SRS to GRASS projection,
+ * not when comparing SRS's of several input layers */
+ if (GPJ_osr_to_grass(cellhd, proj_info,
+ proj_units, Ogr_projection, 0) < 0) {
+ /* TODO: GPJ_osr_to_grass() does not return anything < 0
+ * check with GRASS 6 and GRASS 5 */
+ G_warning(_("Unable to convert input layer projection information to "
+ "GRASS format for checking"));
+ if (verbose && Ogr_projection != NULL) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_warning(_("Can't get WKT parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+ /* custom checks because if in doubt GPJ_osr_to_grass() returns a
+ * xy CRS */
+ if (Ogr_projection == NULL) {
+ if (verbose) {
+ G_important_message(_("No OGR projection available for layer <%s>"),
+ OGR_L_GetName(Ogr_layer));
+ }
+
+ return 1;
+ }
+
+ if (!OSRIsProjected(Ogr_projection) && !OSRIsGeographic(Ogr_projection)) {
+ G_important_message(_("OGR projection for layer <%s> does not contain a valid SRS"),
+ OGR_L_GetName(Ogr_layer));
+
+ if (verbose) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_important_message(_("Can't get WKT parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+
+ if (OSRExportToProj4(Ogr_projection, &pszProj4) != OGRERR_NONE) {
+ G_important_message(_("OGR projection for layer <%s> can not be converted to proj4"),
+ OGR_L_GetName(Ogr_layer));
+
+ if (verbose) {
+ char *wkt = NULL;
+
+ if (OSRExportToPrettyWkt(Ogr_projection, &wkt, FALSE) != OGRERR_NONE) {
+ G_important_message(_("Can't get WKT-style parameter string"));
+ }
+ else if (wkt) {
+ G_important_message(_("WKT-style definition:\n%s"), wkt);
+ }
+ }
+
+ return 2;
+ }
+
+ return 0;
+}
+
+
+/* compare projections of all OGR layers
+ * return 0 if all layers have the same projection
+ * return 1 if layer projections differ */
+int cmp_layer_srs(ds_t Ogr_ds, int nlayers, int *layers,
+ char **layer_names, char *geom_col)
+{
+ int layer;
+ struct Key_Value *proj_info1, *proj_units1;
+ struct Key_Value *proj_info2, *proj_units2;
+ struct Cell_head cellhd1, cellhd2;
+ OGRLayerH Ogr_layer;
+
+ if (nlayers == 1)
+ return 0;
+
+ proj_info1 = proj_units1 = NULL;
+ proj_info2 = proj_units2 = NULL;
+
+ layer = 0;
+ do {
+ /* Get first SRS */
+ Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[layer]);
+
+ if (get_layer_proj(Ogr_layer, &cellhd1, &proj_info1, &proj_units1,
+ geom_col, 0) == 0) {
+ break;
+ }
+ layer++;
+ } while (layer < nlayers);
+
+ if (layer == nlayers) {
+ /* could not get layer proj in GRASS format for any of the layers
+ * -> projections of all layers are the same, i.e. unreadable by GRASS */
+ G_warning(_("Layer projections are unreadable"));
+ if (proj_info1)
+ G_free_key_value(proj_info1);
+ if (proj_units1)
+ G_free_key_value(proj_units1);
+
+ return 0;
+ }
+ if (layer > 0) {
+ /* could not get layer proj in GRASS format for at least one of the layers
+ * -> mix of unreadable and readable projections */
+ G_warning(_("Projection for layer <%s> is unreadable"),
+ layer_names[layer]);
+ if (proj_info1)
+ G_free_key_value(proj_info1);
+ if (proj_units1)
+ G_free_key_value(proj_units1);
+
+ return 1;
+ }
+
+ for (layer = 1; layer < nlayers; layer++) {
+ /* Get SRS of other layer(s) */
+ Ogr_layer = ds_getlayerbyindex(Ogr_ds, layers[layer]);
+ if (get_layer_proj(Ogr_layer, &cellhd2, &proj_info2, &proj_units2,
+ geom_col, 0) != 0) {
+ G_free_key_value(proj_info1);
+ G_free_key_value(proj_units1);
+
+ return 1;
+ }
+
+ if (cellhd1.proj != cellhd2.proj
+ || G_compare_projections(proj_info1, proj_units1,
+ proj_info2, proj_units2) < 0) {
+ if (proj_info1)
+ G_free_key_value(proj_info1);
+ if (proj_units1)
+ G_free_key_value(proj_units1);
+ if (proj_info2)
+ G_free_key_value(proj_info2);
+ if (proj_units2)
+ G_free_key_value(proj_units2);
+
+ G_warning(_("Projection of layer <%s> is different from "
+ "projection of layer <%s>"),
+ layer_names[layer], layer_names[layer - 1]);
+
+ return 1;
+ }
+ if (proj_info2)
+ G_free_key_value(proj_info2);
+ if (proj_units2)
+ G_free_key_value(proj_units2);
+ }
+ if (proj_info1)
+ G_free_key_value(proj_info1);
+ if (proj_units1)
+ G_free_key_value(proj_units1);
+
+ return 0;
+}
+
+/* keep in sync with r.in.gdal, r.external, v.external */
+void check_projection(struct Cell_head *cellhd, ds_t hDS, int layer, char *geom_col,
+ char *outloc, int create_only, int override,
+ int check_only)
+{
+ struct Cell_head loc_wind;
+ struct Key_Value *proj_info = NULL, *proj_units = NULL;
+ struct Key_Value *loc_proj_info = NULL, *loc_proj_units = NULL;
+ char error_msg[8096];
+ int proj_trouble;
+ OGRLayerH Ogr_layer;
+
+ /* Get first layer to be imported to use for projection check */
+ Ogr_layer = ds_getlayerbyindex(hDS, layer);
+
+ /* -------------------------------------------------------------------- */
+ /* Fetch the projection in GRASS form. */
+ /* -------------------------------------------------------------------- */
+ proj_info = NULL;
+ proj_units = NULL;
+
+ /* proj_trouble:
+ * 0: valid srs
+ * 1: no srs, default to xy
+ * 2: unreadable srs, default to xy
+ */
+
+ /* Projection only required for checking so convert non-interactively */
+ proj_trouble = get_layer_proj(Ogr_layer, cellhd, &proj_info, &proj_units,
+ geom_col, 1);
+
+ /* -------------------------------------------------------------------- */
+ /* Do we need to create a new location? */
+ /* -------------------------------------------------------------------- */
+ if (outloc != NULL) {
+ /* do not create a xy location because this can mean that the
+ * real SRS has not been recognized or is missing */
+ if (proj_trouble) {
+ G_fatal_error(_("Unable to convert input map projection to GRASS "
+ "format; cannot create new location."));
+ }
+ else {
+ if (0 != G_make_location(outloc, cellhd,
+ proj_info, proj_units)) {
+ G_fatal_error(_("Unable to create new location <%s>"),
+ outloc);
+ }
+ G_message(_("Location <%s> created"), outloc);
+
+ G_unset_window(); /* new location, projection, and window */
+ G_get_window(cellhd);
+ }
+
+ /* If create only, clean up and exit here */
+ if (create_only) {
+ ds_close(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else {
+ int err = 0;
+ void (*msg_fn)(const char *, ...);
+
+ if (check_only && override) {
+ /* can't check when over-riding check */
+ override = 0;
+ }
+
+ if (proj_trouble == 2) {
+ strcpy(error_msg, _("Unable to convert input map projection information "
+ "to GRASS format."));
+ if (override) {
+ msg_fn = G_warning;
+ }
+ else {
+ msg_fn = G_fatal_error;
+ ds_close(hDS);
+ }
+ msg_fn(error_msg);
+ if (!override) {
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Does the projection of the current location match the */
+ /* dataset? */
+ /* -------------------------------------------------------------------- */
+ G_get_default_window(&loc_wind);
+ /* fetch LOCATION PROJ info */
+ if (loc_wind.proj != PROJECTION_XY) {
+ loc_proj_info = G_get_projinfo();
+ loc_proj_units = G_get_projunits();
+ }
+
+ if (override) {
+ cellhd->proj = loc_wind.proj;
+ cellhd->zone = loc_wind.zone;
+ G_message(_("Over-riding projection check"));
+ }
+ else if (loc_wind.proj != cellhd->proj
+ || (err =
+ G_compare_projections(loc_proj_info, loc_proj_units,
+ proj_info, proj_units)) != 1) {
+ int i_value;
+
+ strcpy(error_msg,
+ _("Projection of dataset does not"
+ " appear to match current location.\n\n"));
+
+ /* TODO: output this info sorted by key: */
+ if (loc_wind.proj != cellhd->proj || err != -2) {
+ /* error in proj_info */
+ if (loc_proj_info != NULL) {
+ strcat(error_msg, _("Location PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < loc_proj_info->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_info->key[i_value],
+ loc_proj_info->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_info != NULL) {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ for (i_value = 0; i_value < proj_info->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_info->key[i_value],
+ proj_info->value[i_value]);
+ strcat(error_msg, "\nERROR: ");
+ switch (err) {
+ case -1:
+ strcat(error_msg, "proj\n");
+ break;
+ case -2:
+ strcat(error_msg, "units\n");
+ break;
+ case -3:
+ strcat(error_msg, "datum\n");
+ break;
+ case -4:
+ strcat(error_msg, "ellps, a, es\n");
+ break;
+ case -5:
+ strcat(error_msg, "zone\n");
+ break;
+ case -6:
+ strcat(error_msg, "south\n");
+ break;
+ case -7:
+ strcat(error_msg, "x_0\n");
+ break;
+ case -8:
+ strcat(error_msg, "y_0\n");
+ break;
+ case -9:
+ strcat(error_msg, "lon_0\n");
+ break;
+ case -10:
+ strcat(error_msg, "lat_0\n");
+ break;
+ case -11:
+ strcat(error_msg, "lat_1, lat2\n");
+ break;
+ }
+ }
+ else {
+ strcat(error_msg, _("Dataset PROJ_INFO is:\n"));
+ if (cellhd->proj == PROJECTION_XY)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unreferenced/unknown)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_LL)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (lat/long)\n",
+ cellhd->proj);
+ else if (cellhd->proj == PROJECTION_UTM)
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (UTM), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ else
+ sprintf(error_msg + strlen(error_msg),
+ "Dataset proj = %d (unknown), zone = %d\n",
+ cellhd->proj, cellhd->zone);
+ }
+ }
+ else {
+ /* error in proj_units */
+ if (loc_proj_units != NULL) {
+ strcat(error_msg, "Location PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < loc_proj_units->nitems;
+ i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ loc_proj_units->key[i_value],
+ loc_proj_units->value[i_value]);
+ strcat(error_msg, "\n");
+ }
+
+ if (proj_units != NULL) {
+ strcat(error_msg, "Dataset PROJ_UNITS is:\n");
+ for (i_value = 0; i_value < proj_units->nitems; i_value++)
+ sprintf(error_msg + strlen(error_msg), "%s: %s\n",
+ proj_units->key[i_value],
+ proj_units->value[i_value]);
+ }
+ }
+ strcat(error_msg,
+ _("\nIn case of no significant differences in the projection definitions,"
+ " use the -o flag to ignore them and use"
+ " current location definition.\n"));
+ strcat(error_msg,
+ _("Consider generating a new location from the input dataset using "
+ "the 'location' parameter.\n"));
+
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_fatal_error;
+ msg_fn(error_msg);
+ if (check_only) {
+ exit(EXIT_FAILURE);
+ }
+ }
+ else {
+ if (check_only)
+ msg_fn = G_message;
+ else
+ msg_fn = G_verbose_message;
+ msg_fn(_("Projection of input dataset and current location "
+ "appear to match"));
+ if (check_only) {
+ ds_close(hDS);
+ exit(EXIT_SUCCESS);
+ }
+ }
+ }
+}
More information about the grass-commit
mailing list