LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/openfilegdb - filegdb_coordprec_write.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 52 54 96.3 %
Date: 2024-05-02 22:57:13 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements Open FileGDB OGR driver.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #ifndef FILEGDB_COORDPREC_WRITE_H
      30             : #define FILEGDB_COORDPREC_WRITE_H
      31             : 
      32             : #include "ogr_spatialref.h"
      33             : #include "ogr_geomcoordinateprecision.h"
      34             : 
      35             : /*************************************************************************/
      36             : /*                      GDBGridSettingsFromOGR()                         */
      37             : /*************************************************************************/
      38             : 
      39             : /** Compute grid settings from coordinate precision of source geometry field
      40             :  * and layer creation options.
      41             :  * The "FileGeodatabase" key of the output oFormatSpecificOptions will be
      42             :  * set with the values.
      43             :  */
      44             : static OGRGeomCoordinatePrecision
      45         331 : GDBGridSettingsFromOGR(const OGRGeomFieldDefn *poSrcGeomFieldDefn,
      46             :                        CSLConstList aosLayerCreationOptions)
      47             : {
      48         331 :     const auto poSRS = poSrcGeomFieldDefn->GetSpatialRef();
      49             : 
      50             :     double dfXOrigin;
      51             :     double dfYOrigin;
      52             :     double dfXYScale;
      53         331 :     double dfZOrigin = -100000;
      54         331 :     double dfMOrigin = -100000;
      55         331 :     double dfMScale = 10000;
      56             :     double dfXYTolerance;
      57             :     // default tolerance is 1mm in the units of the coordinate system
      58             :     double dfZTolerance =
      59         331 :         0.001 * (poSRS ? poSRS->GetTargetLinearUnits("VERT_CS") : 1.0);
      60         331 :     double dfZScale = 1 / dfZTolerance * 10;
      61         331 :     double dfMTolerance = 0.001;
      62             : 
      63         331 :     if (poSRS == nullptr || poSRS->IsProjected())
      64             :     {
      65             :         // default tolerance is 1mm in the units of the coordinate system
      66         196 :         dfXYTolerance =
      67         196 :             0.001 * (poSRS ? poSRS->GetTargetLinearUnits("PROJCS") : 1.0);
      68             :         // default scale is 10x the tolerance
      69         196 :         dfXYScale = 1 / dfXYTolerance * 10;
      70             : 
      71             :         // Ideally we would use the same X/Y origins as ArcGIS, but we need
      72             :         // the algorithm they use.
      73         196 :         dfXOrigin = -2147483647;
      74         196 :         dfYOrigin = -2147483647;
      75             :     }
      76             :     else
      77             :     {
      78         135 :         dfXOrigin = -400;
      79         135 :         dfYOrigin = -400;
      80         135 :         dfXYScale = 1000000000;
      81         135 :         dfXYTolerance = 0.000000008983153;
      82             :     }
      83             : 
      84         331 :     const auto &oSrcCoordPrec = poSrcGeomFieldDefn->GetCoordinatePrecision();
      85             : 
      86         331 :     if (oSrcCoordPrec.dfXYResolution != OGRGeomCoordinatePrecision::UNKNOWN)
      87             :     {
      88           9 :         dfXYScale = 1.0 / oSrcCoordPrec.dfXYResolution;
      89           9 :         dfXYTolerance = oSrcCoordPrec.dfXYResolution / 10.0;
      90             :     }
      91             : 
      92         331 :     if (oSrcCoordPrec.dfZResolution != OGRGeomCoordinatePrecision::UNKNOWN)
      93             :     {
      94           9 :         dfZScale = 1.0 / oSrcCoordPrec.dfZResolution;
      95           9 :         dfZTolerance = oSrcCoordPrec.dfZResolution / 10.0;
      96             :     }
      97             : 
      98         331 :     if (oSrcCoordPrec.dfMResolution != OGRGeomCoordinatePrecision::UNKNOWN)
      99             :     {
     100           9 :         dfMScale = 1.0 / oSrcCoordPrec.dfMResolution;
     101           9 :         dfMTolerance = oSrcCoordPrec.dfMResolution / 10.0;
     102             :     }
     103             : 
     104         331 :     const char *const paramNames[] = {
     105             :         "XOrigin", "YOrigin", "XYScale",     "ZOrigin",    "ZScale",
     106             :         "MOrigin", "MScale",  "XYTolerance", "ZTolerance", "MTolerance"};
     107             :     double *pGridValues[] = {
     108             :         &dfXOrigin, &dfYOrigin, &dfXYScale,     &dfZOrigin,    &dfZScale,
     109         331 :         &dfMOrigin, &dfMScale,  &dfXYTolerance, &dfZTolerance, &dfMTolerance};
     110             :     static_assert(CPL_ARRAYSIZE(paramNames) == CPL_ARRAYSIZE(pGridValues));
     111             : 
     112             :     const auto oIterCoordPrecFileGeodatabase =
     113         331 :         oSrcCoordPrec.oFormatSpecificOptions.find("FileGeodatabase");
     114             : 
     115             :     /*
     116             :      * Use coordinate precision layer creation options in priority.
     117             :      * Otherwise use the settings from the "FileGeodatabase" entry in
     118             :      * oSrcCoordPrec.oFormatSpecificOptions when set.
     119             :      * Otherwise, use above defaults.
     120             :      */
     121         662 :     CPLStringList aosCoordinatePrecisionOptions;
     122        3641 :     for (size_t i = 0; i < CPL_ARRAYSIZE(paramNames); i++)
     123             :     {
     124        3310 :         const char *pszVal = CSLFetchNameValueDef(
     125        3310 :             aosLayerCreationOptions, paramNames[i],
     126        3310 :             oIterCoordPrecFileGeodatabase !=
     127        3310 :                     oSrcCoordPrec.oFormatSpecificOptions.end()
     128         140 :                 ? oIterCoordPrecFileGeodatabase->second.FetchNameValue(
     129          70 :                       paramNames[i])
     130             :                 : nullptr);
     131        3310 :         if (pszVal)
     132             :         {
     133         282 :             *(pGridValues[i]) = CPLAtof(pszVal);
     134         282 :             if (strstr(paramNames[i], "Scale") ||
     135         208 :                 strstr(paramNames[i], "Tolerance"))
     136             :             {
     137         148 :                 if (*(pGridValues[i]) <= 0)
     138             :                 {
     139           0 :                     CPLError(CE_Warning, CPLE_AppDefined,
     140             :                              "%s should be strictly greater than zero",
     141           0 :                              paramNames[i]);
     142             :                 }
     143             :             }
     144             :         }
     145             :         aosCoordinatePrecisionOptions.SetNameValue(
     146        3310 :             paramNames[i], CPLSPrintf("%.15g", *(pGridValues[i])));
     147             :     }
     148             : 
     149         331 :     OGRGeomCoordinatePrecision oCoordPrec;
     150         331 :     oCoordPrec.dfXYResolution = 1.0 / dfXYScale;
     151         331 :     oCoordPrec.dfZResolution = 1.0 / dfZScale;
     152         331 :     oCoordPrec.dfMResolution = 1.0 / dfMScale;
     153         662 :     oCoordPrec.oFormatSpecificOptions["FileGeodatabase"] =
     154         662 :         std::move(aosCoordinatePrecisionOptions);
     155             : 
     156         662 :     return oCoordPrec;
     157             : }
     158             : 
     159             : #endif /* FILEGDB_COORDPREC_WRITE_H */

Generated by: LCOV version 1.14