LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/gmt - ogrgmtdatasource.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 89 95 93.7 %
Date: 2024-11-21 22:18:42 Functions: 7 7 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             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_conv.h"
      14             : #include "cpl_string.h"
      15             : #include "ogr_gmt.h"
      16             : 
      17             : /************************************************************************/
      18             : /*                          OGRGmtDataSource()                          */
      19             : /************************************************************************/
      20             : 
      21         108 : OGRGmtDataSource::OGRGmtDataSource()
      22         108 :     : papoLayers(nullptr), nLayers(0), bUpdate(false)
      23             : {
      24         108 : }
      25             : 
      26             : /************************************************************************/
      27             : /*                         ~OGRGmtDataSource()                          */
      28             : /************************************************************************/
      29             : 
      30         216 : OGRGmtDataSource::~OGRGmtDataSource()
      31             : 
      32             : {
      33         180 :     for (int i = 0; i < nLayers; i++)
      34          72 :         delete papoLayers[i];
      35         108 :     CPLFree(papoLayers);
      36         216 : }
      37             : 
      38             : /************************************************************************/
      39             : /*                                Open()                                */
      40             : /************************************************************************/
      41             : 
      42         107 : int OGRGmtDataSource::Open(const char *pszFilename, VSILFILE *fp,
      43             :                            const OGRSpatialReference *poSRS, int bUpdateIn)
      44             : 
      45             : {
      46         107 :     bUpdate = CPL_TO_BOOL(bUpdateIn);
      47             : 
      48             :     OGRGmtLayer *poLayer =
      49         107 :         new OGRGmtLayer(this, pszFilename, fp, poSRS, bUpdate);
      50         107 :     if (!poLayer->bValidFile)
      51             :     {
      52          35 :         delete poLayer;
      53          35 :         return FALSE;
      54             :     }
      55             : 
      56          72 :     papoLayers = static_cast<OGRGmtLayer **>(
      57          72 :         CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRGmtLayer *)));
      58          72 :     papoLayers[nLayers] = poLayer;
      59          72 :     nLayers++;
      60             : 
      61          72 :     return TRUE;
      62             : }
      63             : 
      64             : /************************************************************************/
      65             : /*                           ICreateLayer()                             */
      66             : /************************************************************************/
      67             : 
      68             : OGRLayer *
      69          52 : OGRGmtDataSource::ICreateLayer(const char *pszLayerName,
      70             :                                const OGRGeomFieldDefn *poGeomFieldDefn,
      71             :                                CSLConstList /*papszOptions*/)
      72             : {
      73          52 :     if (nLayers != 0)
      74          16 :         return nullptr;
      75             : 
      76          36 :     const auto eType = poGeomFieldDefn ? poGeomFieldDefn->GetType() : wkbNone;
      77             :     const auto poSRS =
      78          36 :         poGeomFieldDefn ? poGeomFieldDefn->GetSpatialRef() : nullptr;
      79             : 
      80             :     /* -------------------------------------------------------------------- */
      81             :     /*      Establish the geometry type.  Note this logic                   */
      82             :     /* -------------------------------------------------------------------- */
      83          36 :     const char *pszGeom = nullptr;
      84             : 
      85          36 :     switch (wkbFlatten(eType))
      86             :     {
      87           5 :         case wkbPoint:
      88           5 :             pszGeom = " @GPOINT";
      89           5 :             break;
      90           4 :         case wkbLineString:
      91           4 :             pszGeom = " @GLINESTRING";
      92           4 :             break;
      93           5 :         case wkbPolygon:
      94           5 :             pszGeom = " @GPOLYGON";
      95           5 :             break;
      96           4 :         case wkbMultiPoint:
      97           4 :             pszGeom = " @GMULTIPOINT";
      98           4 :             break;
      99           4 :         case wkbMultiLineString:
     100           4 :             pszGeom = " @GMULTILINESTRING";
     101           4 :             break;
     102           4 :         case wkbMultiPolygon:
     103           4 :             pszGeom = " @GMULTIPOLYGON";
     104           4 :             break;
     105          10 :         default:
     106          10 :             pszGeom = "";
     107          10 :             break;
     108             :     }
     109             : 
     110             :     /* -------------------------------------------------------------------- */
     111             :     /*      If this is the first layer for this datasource, and if the      */
     112             :     /*      datasource name ends in .gmt we will override the provided      */
     113             :     /*      layer name with the name from the gmt.                          */
     114             :     /* -------------------------------------------------------------------- */
     115             : 
     116          72 :     CPLString osPath = CPLGetPath(GetDescription());
     117          72 :     CPLString osFilename(GetDescription());
     118          36 :     const char *pszFlags = "wb+";
     119             : 
     120          36 :     if (osFilename == "/dev/stdout")
     121           0 :         osFilename = "/vsistdout";
     122             : 
     123          36 :     if (STARTS_WITH(osFilename, "/vsistdout"))
     124           1 :         pszFlags = "wb";
     125          35 :     else if (!EQUAL(CPLGetExtension(GetDescription()), "gmt"))
     126           0 :         osFilename = CPLFormFilename(osPath, pszLayerName, "gmt");
     127             : 
     128             :     /* -------------------------------------------------------------------- */
     129             :     /*      Open the file.                                                  */
     130             :     /* -------------------------------------------------------------------- */
     131          36 :     VSILFILE *fp = VSIFOpenL(osFilename, pszFlags);
     132          36 :     if (fp == nullptr)
     133             :     {
     134           1 :         CPLError(CE_Failure, CPLE_OpenFailed, "open(%s) failed: %s",
     135           1 :                  osFilename.c_str(), VSIStrerror(errno));
     136           1 :         return nullptr;
     137             :     }
     138             : 
     139             :     /* -------------------------------------------------------------------- */
     140             :     /*      Write out header.                                               */
     141             :     /* -------------------------------------------------------------------- */
     142          35 :     VSIFPrintfL(fp, "# @VGMT1.0%s\n", pszGeom);
     143          35 :     if (!STARTS_WITH(osFilename, "/vsistdout"))
     144             :     {
     145          34 :         VSIFPrintfL(fp, "# REGION_STUB                                      "
     146             :                         "                       \n");
     147             :     }
     148             : 
     149             :     /* -------------------------------------------------------------------- */
     150             :     /*      Write the projection, if possible.                              */
     151             :     /* -------------------------------------------------------------------- */
     152          35 :     if (poSRS != nullptr)
     153             :     {
     154           2 :         if (poSRS->GetAuthorityName(nullptr) &&
     155           1 :             EQUAL(poSRS->GetAuthorityName(nullptr), "EPSG"))
     156             :         {
     157           1 :             VSIFPrintfL(fp, "# @Je%s\n", poSRS->GetAuthorityCode(nullptr));
     158             :         }
     159             : 
     160           1 :         char *pszValue = nullptr;
     161           1 :         if (poSRS->exportToProj4(&pszValue) == OGRERR_NONE)
     162             :         {
     163           1 :             VSIFPrintfL(fp, "# @Jp\"%s\"\n", pszValue);
     164             :         }
     165           1 :         CPLFree(pszValue);
     166           1 :         pszValue = nullptr;
     167             : 
     168           1 :         if (poSRS->exportToWkt(&pszValue) == OGRERR_NONE)
     169             :         {
     170             :             char *pszEscapedWkt =
     171           1 :                 CPLEscapeString(pszValue, -1, CPLES_BackslashQuotable);
     172             : 
     173           1 :             VSIFPrintfL(fp, "# @Jw\"%s\"\n", pszEscapedWkt);
     174           1 :             CPLFree(pszEscapedWkt);
     175             :         }
     176           1 :         CPLFree(pszValue);
     177             :     }
     178             : 
     179             :     /* -------------------------------------------------------------------- */
     180             :     /*      Return open layer handle.                                       */
     181             :     /* -------------------------------------------------------------------- */
     182          35 :     if (Open(osFilename, fp, poSRS, TRUE))
     183             :     {
     184          35 :         auto poLayer = papoLayers[nLayers - 1];
     185          35 :         if (strcmp(pszGeom, "") != 0)
     186             :         {
     187          25 :             poLayer->GetLayerDefn()->SetGeomType(wkbFlatten(eType));
     188             :         }
     189          35 :         return poLayer;
     190             :     }
     191             : 
     192           0 :     VSIFCloseL(fp);
     193           0 :     return nullptr;
     194             : }
     195             : 
     196             : /************************************************************************/
     197             : /*                           TestCapability()                           */
     198             : /************************************************************************/
     199             : 
     200          51 : int OGRGmtDataSource::TestCapability(const char *pszCap)
     201             : 
     202             : {
     203          51 :     if (EQUAL(pszCap, ODsCCreateLayer))
     204          33 :         return TRUE;
     205          18 :     else if (EQUAL(pszCap, ODsCZGeometries))
     206           0 :         return TRUE;
     207             : 
     208          18 :     return FALSE;
     209             : }
     210             : 
     211             : /************************************************************************/
     212             : /*                              GetLayer()                              */
     213             : /************************************************************************/
     214             : 
     215           6 : OGRLayer *OGRGmtDataSource::GetLayer(int iLayer)
     216             : 
     217             : {
     218           6 :     if (iLayer < 0 || iLayer >= nLayers)
     219           0 :         return nullptr;
     220             : 
     221           6 :     return papoLayers[iLayer];
     222             : }

Generated by: LCOV version 1.14