LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gmt - ogrgmtdatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 95 101 94.1 %
Date: 2024-05-05 22:37:24 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Implements OGRGmtDataSource class.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.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             : #include "cpl_conv.h"
      30             : #include "cpl_string.h"
      31             : #include "ogr_gmt.h"
      32             : 
      33             : /************************************************************************/
      34             : /*                          OGRGmtDataSource()                          */
      35             : /************************************************************************/
      36             : 
      37         108 : OGRGmtDataSource::OGRGmtDataSource()
      38         108 :     : papoLayers(nullptr), nLayers(0), pszName(nullptr), bUpdate(false)
      39             : {
      40         108 : }
      41             : 
      42             : /************************************************************************/
      43             : /*                         ~OGRGmtDataSource()                          */
      44             : /************************************************************************/
      45             : 
      46         216 : OGRGmtDataSource::~OGRGmtDataSource()
      47             : 
      48             : {
      49         180 :     for (int i = 0; i < nLayers; i++)
      50          72 :         delete papoLayers[i];
      51         108 :     CPLFree(papoLayers);
      52         108 :     CPLFree(pszName);
      53         216 : }
      54             : 
      55             : /************************************************************************/
      56             : /*                                Open()                                */
      57             : /************************************************************************/
      58             : 
      59         107 : int OGRGmtDataSource::Open(const char *pszFilename, VSILFILE *fp,
      60             :                            const OGRSpatialReference *poSRS, int bUpdateIn)
      61             : 
      62             : {
      63         107 :     bUpdate = CPL_TO_BOOL(bUpdateIn);
      64             : 
      65             :     OGRGmtLayer *poLayer =
      66         107 :         new OGRGmtLayer(this, pszFilename, fp, poSRS, bUpdate);
      67         107 :     if (!poLayer->bValidFile)
      68             :     {
      69          35 :         delete poLayer;
      70          35 :         return FALSE;
      71             :     }
      72             : 
      73          72 :     papoLayers = static_cast<OGRGmtLayer **>(
      74          72 :         CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRGmtLayer *)));
      75          72 :     papoLayers[nLayers] = poLayer;
      76          72 :     nLayers++;
      77             : 
      78          72 :     CPLFree(pszName);
      79          72 :     pszName = CPLStrdup(pszFilename);
      80             : 
      81          72 :     return TRUE;
      82             : }
      83             : 
      84             : /************************************************************************/
      85             : /*                               Create()                               */
      86             : /*                                                                      */
      87             : /*      Create a new datasource.  This does not really do anything      */
      88             : /*      currently but save the name.                                    */
      89             : /************************************************************************/
      90             : 
      91          36 : int OGRGmtDataSource::Create(const char *pszDSName, char ** /* papszOptions */)
      92             : 
      93             : {
      94          36 :     pszName = CPLStrdup(pszDSName);
      95             : 
      96          36 :     return TRUE;
      97             : }
      98             : 
      99             : /************************************************************************/
     100             : /*                           ICreateLayer()                             */
     101             : /************************************************************************/
     102             : 
     103             : OGRLayer *
     104          52 : OGRGmtDataSource::ICreateLayer(const char *pszLayerName,
     105             :                                const OGRGeomFieldDefn *poGeomFieldDefn,
     106             :                                CSLConstList /*papszOptions*/)
     107             : {
     108          52 :     if (nLayers != 0)
     109          16 :         return nullptr;
     110             : 
     111          36 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
     112             :     const auto poSRS =
     113          36 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
     114             : 
     115             :     /* -------------------------------------------------------------------- */
     116             :     /*      Establish the geometry type.  Note this logic                   */
     117             :     /* -------------------------------------------------------------------- */
     118          36 :     const char *pszGeom = nullptr;
     119             : 
     120          36 :     switch (wkbFlatten(eType))
     121             :     {
     122           5 :         case wkbPoint:
     123           5 :             pszGeom = " @GPOINT";
     124           5 :             break;
     125           4 :         case wkbLineString:
     126           4 :             pszGeom = " @GLINESTRING";
     127           4 :             break;
     128           5 :         case wkbPolygon:
     129           5 :             pszGeom = " @GPOLYGON";
     130           5 :             break;
     131           4 :         case wkbMultiPoint:
     132           4 :             pszGeom = " @GMULTIPOINT";
     133           4 :             break;
     134           4 :         case wkbMultiLineString:
     135           4 :             pszGeom = " @GMULTILINESTRING";
     136           4 :             break;
     137           4 :         case wkbMultiPolygon:
     138           4 :             pszGeom = " @GMULTIPOLYGON";
     139           4 :             break;
     140          10 :         default:
     141          10 :             pszGeom = "";
     142          10 :             break;
     143             :     }
     144             : 
     145             :     /* -------------------------------------------------------------------- */
     146             :     /*      If this is the first layer for this datasource, and if the      */
     147             :     /*      datasource name ends in .gmt we will override the provided      */
     148             :     /*      layer name with the name from the gmt.                          */
     149             :     /* -------------------------------------------------------------------- */
     150             : 
     151          72 :     CPLString osPath = CPLGetPath(pszName);
     152          72 :     CPLString osFilename(pszName);
     153          36 :     const char *pszFlags = "wb+";
     154             : 
     155          36 :     if (osFilename == "/dev/stdout")
     156           0 :         osFilename = "/vsistdout";
     157             : 
     158          36 :     if (STARTS_WITH(osFilename, "/vsistdout"))
     159           1 :         pszFlags = "wb";
     160          35 :     else if (!EQUAL(CPLGetExtension(pszName), "gmt"))
     161           0 :         osFilename = CPLFormFilename(osPath, pszLayerName, "gmt");
     162             : 
     163             :     /* -------------------------------------------------------------------- */
     164             :     /*      Open the file.                                                  */
     165             :     /* -------------------------------------------------------------------- */
     166          36 :     VSILFILE *fp = VSIFOpenL(osFilename, pszFlags);
     167          36 :     if (fp == nullptr)
     168             :     {
     169           1 :         CPLError(CE_Failure, CPLE_OpenFailed, "open(%s) failed: %s",
     170           1 :                  osFilename.c_str(), VSIStrerror(errno));
     171           1 :         return nullptr;
     172             :     }
     173             : 
     174             :     /* -------------------------------------------------------------------- */
     175             :     /*      Write out header.                                               */
     176             :     /* -------------------------------------------------------------------- */
     177          35 :     VSIFPrintfL(fp, "# @VGMT1.0%s\n", pszGeom);
     178          35 :     if (!STARTS_WITH(osFilename, "/vsistdout"))
     179             :     {
     180          34 :         VSIFPrintfL(fp, "# REGION_STUB                                      "
     181             :                         "                       \n");
     182             :     }
     183             : 
     184             :     /* -------------------------------------------------------------------- */
     185             :     /*      Write the projection, if possible.                              */
     186             :     /* -------------------------------------------------------------------- */
     187          35 :     if (poSRS != nullptr)
     188             :     {
     189           2 :         if (poSRS->GetAuthorityName(nullptr) &&
     190           1 :             EQUAL(poSRS->GetAuthorityName(nullptr), "EPSG"))
     191             :         {
     192           1 :             VSIFPrintfL(fp, "# @Je%s\n", poSRS->GetAuthorityCode(nullptr));
     193             :         }
     194             : 
     195           1 :         char *pszValue = nullptr;
     196           1 :         if (poSRS->exportToProj4(&pszValue) == OGRERR_NONE)
     197             :         {
     198           1 :             VSIFPrintfL(fp, "# @Jp\"%s\"\n", pszValue);
     199             :         }
     200           1 :         CPLFree(pszValue);
     201           1 :         pszValue = nullptr;
     202             : 
     203           1 :         if (poSRS->exportToWkt(&pszValue) == OGRERR_NONE)
     204             :         {
     205             :             char *pszEscapedWkt =
     206           1 :                 CPLEscapeString(pszValue, -1, CPLES_BackslashQuotable);
     207             : 
     208           1 :             VSIFPrintfL(fp, "# @Jw\"%s\"\n", pszEscapedWkt);
     209           1 :             CPLFree(pszEscapedWkt);
     210             :         }
     211           1 :         CPLFree(pszValue);
     212             :     }
     213             : 
     214             :     /* -------------------------------------------------------------------- */
     215             :     /*      Return open layer handle.                                       */
     216             :     /* -------------------------------------------------------------------- */
     217          35 :     if (Open(osFilename, fp, poSRS, TRUE))
     218             :     {
     219          35 :         auto poLayer = papoLayers[nLayers - 1];
     220          35 :         if (strcmp(pszGeom, "") != 0)
     221             :         {
     222          25 :             poLayer->GetLayerDefn()->SetGeomType(wkbFlatten(eType));
     223             :         }
     224          35 :         return poLayer;
     225             :     }
     226             : 
     227           0 :     VSIFCloseL(fp);
     228           0 :     return nullptr;
     229             : }
     230             : 
     231             : /************************************************************************/
     232             : /*                           TestCapability()                           */
     233             : /************************************************************************/
     234             : 
     235          51 : int OGRGmtDataSource::TestCapability(const char *pszCap)
     236             : 
     237             : {
     238          51 :     if (EQUAL(pszCap, ODsCCreateLayer))
     239          33 :         return TRUE;
     240          18 :     else if (EQUAL(pszCap, ODsCZGeometries))
     241           0 :         return TRUE;
     242             : 
     243          18 :     return FALSE;
     244             : }
     245             : 
     246             : /************************************************************************/
     247             : /*                              GetLayer()                              */
     248             : /************************************************************************/
     249             : 
     250           6 : OGRLayer *OGRGmtDataSource::GetLayer(int iLayer)
     251             : 
     252             : {
     253           6 :     if (iLayer < 0 || iLayer >= nLayers)
     254           0 :         return nullptr;
     255             : 
     256           6 :     return papoLayers[iLayer];
     257             : }

Generated by: LCOV version 1.14