2121
2222#include " NetcdfGeoMatrixInterpretor.h"
2323
24+ #include < algorithm>
2425#include < limits>
2526
2627#include " ContourLibrary.h"
@@ -53,8 +54,43 @@ string NetcdfGeoMatrixInterpretor::proj4Detected(Netcdf& netcdf) {
5354
5455
5556 string mapping = netcdf.getVariableAttribute (field_, " grid_mapping" , string (" " ));
56- if (mapping.size ())
57- return netcdf.getVariableAttribute (mapping, " proj4_params" , string (" " ));
57+ if (mapping.size ()) {
58+ proj4 = netcdf.getVariableAttribute (mapping, " proj4_params" , string (" " ));
59+ if (proj4.size ())
60+ return proj4;
61+ }
62+
63+ // Extended detection: standard "proj4" attribute names
64+ proj4 = netcdf.getAttribute (" proj4" , string (" " ));
65+ if (proj4.size ())
66+ return proj4;
67+
68+ if (!field_.empty ()) {
69+ proj4 = netcdf.getVariableAttribute (field_, " proj4" , string (" " ));
70+ if (proj4.size ())
71+ return proj4;
72+ }
73+
74+ if (mapping.size ()) {
75+ proj4 = netcdf.getVariableAttribute (mapping, " proj4" , string (" " ));
76+ if (proj4.size ())
77+ return proj4;
78+ }
79+
80+ // Dedicated scalar variable named "proj4"
81+ try {
82+ NetVariable v = netcdf.getVariable (" proj4" );
83+ if (v.type () == NC_CHAR || v.type () == NC_STRING ) {
84+ size_t len = v.getSize ();
85+ if (len > 0 ) {
86+ vector<char > buf (len + 1 , ' \0 ' );
87+ nc_get_var_text (v.netcdf_ , v.id_ , buf.data ());
88+ return string (buf.data ());
89+ }
90+ }
91+ }
92+ catch (...) {}
93+
5894 return " " ;
5995}
6096
@@ -65,7 +101,7 @@ bool NetcdfGeoMatrixInterpretor::interpretAsMatrix(Matrix** matrix) {
65101 Netcdf netcdf (path_, dimension_method_);
66102
67103 string proj4 = proj4Detected (netcdf);
68-
104+ proj4_ = proj4;
69105
70106 if (proj4.empty ()) {
71107 matrix_.reset (new Matrix ());
@@ -172,18 +208,38 @@ UserPoint* NetcdfGeoMatrixInterpretor::newPoint(double lon, double lat, double v
172208}
173209
174210void NetcdfGeoMatrixInterpretor::visit (Transformation& transformation) {
175- // Here are in a dump ode .. the coordinates are pixels.
176- if (transformation.getAutomaticX ()) {
177- transformation.setMinMaxX (matrix_->columnsAxis ().front (), matrix_->columnsAxis ().back ());
178- }
179- if (transformation.getAutomaticY ()) {
180- transformation.setMinMaxY (matrix_->rowsAxis ().front (), matrix_->rowsAxis ().back ());
211+ double minX = matrix_->columnsAxis ().front ();
212+ double maxX = matrix_->columnsAxis ().back ();
213+ double minY = matrix_->rowsAxis ().front ();
214+ double maxY = matrix_->rowsAxis ().back ();
215+
216+ if (!proj4_.empty ()) {
217+ // Projected grid: revert the four corners to lat/lon so the transformation
218+ // receives geographic bounds instead of projection-space coordinates.
219+ LatLonProjP projHelper (proj4_);
220+ double lons[4 ] = {minX, maxX, minX, maxX};
221+ double lats[4 ] = {minY, minY, maxY, maxY};
222+ bool ok = true ;
223+ for (int k = 0 ; k < 4 && ok; ++k)
224+ ok = (projHelper.revert (lons[k], lats[k]) == 0 );
225+ if (ok) {
226+ minX = *std::min_element (lons, lons + 4 );
227+ maxX = *std::max_element (lons, lons + 4 );
228+ minY = *std::min_element (lats, lats + 4 );
229+ maxY = *std::max_element (lats, lats + 4 );
230+ }
181231 }
232+
233+ if (transformation.getAutomaticX ())
234+ transformation.setMinMaxX (minX, maxX);
235+ if (transformation.getAutomaticY ())
236+ transformation.setMinMaxY (minY, maxY);
182237}
183238
184239bool NetcdfGeoMatrixInterpretor::interpretAsPoints (PointsList& list) {
185240 Netcdf netcdf (path_, dimension_method_);
186241 string proj4 = proj4Detected (netcdf);
242+ proj4_ = proj4;
187243
188244 if (!proj4.empty ()) {
189245 projection_ = new LatLonProjP (proj4);
@@ -364,7 +420,7 @@ NetcdfInterpretor* NetcdfGeoMatrixInterpretor::guess(const NetcdfInterpretor& fr
364420 string projection_y_coordinate = netcdf.detect (variable, " projection_y_coordinate" , use_cache);
365421 string projection_x_coordinate = netcdf.detect (variable, " projection_x_coordinate" , use_cache);
366422
367- if (projection_y_coordinate.size () && projection_y_coordinate .size ()) {
423+ if (projection_y_coordinate.size () && projection_x_coordinate .size ()) {
368424 NetcdfGeoMatrixInterpretor* interpretor = new NetcdfGeoMatrixInterpretor ();
369425 interpretor->NetcdfInterpretor ::copy (from);
370426
@@ -376,6 +432,22 @@ NetcdfInterpretor* NetcdfGeoMatrixInterpretor::guess(const NetcdfInterpretor& fr
376432 interpretor->number_variable_ = netcdf.detect (variable, " number" , use_cache);
377433 return interpretor;
378434 }
435+ delete interpretor;
436+ }
437+
438+ // No CF axis variables found — if a proj4 string is present fall back to bare x/y dims.
439+ {
440+ NetcdfGeoMatrixInterpretor* interpretor = new NetcdfGeoMatrixInterpretor ();
441+ interpretor->NetcdfInterpretor ::copy (from);
442+ if (interpretor->proj4Detected (netcdf).size ()) {
443+ interpretor->latitude_ = " y" ;
444+ interpretor->longitude_ = " x" ;
445+ interpretor->time_variable_ = netcdf.detect (variable, " time" , use_cache);
446+ interpretor->level_variable_ = netcdf.detect (variable, " level" , use_cache);
447+ interpretor->number_variable_ = netcdf.detect (variable, " number" , use_cache);
448+ return interpretor;
449+ }
450+ delete interpretor;
379451 }
380452
381453 return 0 ;
0 commit comments