LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mvt - mvtutils.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 94 99 94.9 %
Date: 2024-11-21 22:18:42 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  MVT Translator
       4             :  * Purpose:  Mapbox Vector Tile decoder
       5             :  * Author:   Even Rouault, Even Rouault <even dot rouault at spatialys dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "mvtutils.h"
      14             : #include "ogr_api.h"
      15             : 
      16             : /************************************************************************/
      17             : /*                        OGRMVTInitFields()                            */
      18             : /************************************************************************/
      19             : 
      20        1110 : void OGRMVTInitFields(OGRFeatureDefn *poFeatureDefn,
      21             :                       const CPLJSONObject &oFields,
      22             :                       const CPLJSONArray &oAttributesFromTileStats)
      23             : {
      24             :     {
      25        2220 :         OGRFieldDefn oFieldDefnId("mvt_id", OFTInteger64);
      26        1110 :         poFeatureDefn->AddFieldDefn(&oFieldDefnId);
      27             :     }
      28             : 
      29        1110 :     if (oFields.IsValid())
      30             :     {
      31       19293 :         for (const auto &oField : oFields.GetChildren())
      32             :         {
      33       18262 :             if (oField.GetType() == CPLJSONObject::Type::String)
      34             :             {
      35       18262 :                 if (oField.ToString() == "Number")
      36             :                 {
      37       15744 :                     OGRFieldDefn oFieldDefn(oField.GetName().c_str(), OFTReal);
      38             : 
      39      197576 :                     for (int i = 0; i < oAttributesFromTileStats.Size(); ++i)
      40             :                     {
      41      392488 :                         if (oAttributesFromTileStats[i].GetString(
      42      595272 :                                 "attribute") == oField.GetName() &&
      43      202784 :                             oAttributesFromTileStats[i].GetString("type") ==
      44             :                                 "number")
      45             :                         {
      46             :                             const auto eMinType = oAttributesFromTileStats[i]
      47       13080 :                                                       .GetObj("min")
      48        6540 :                                                       .GetType();
      49             :                             const auto eMaxType = oAttributesFromTileStats[i]
      50       13080 :                                                       .GetObj("max")
      51        6540 :                                                       .GetType();
      52        6540 :                             if (eMinType == CPLJSONObject::Type::Integer &&
      53             :                                 eMaxType == CPLJSONObject::Type::Integer)
      54             :                             {
      55        6154 :                                 oFieldDefn.SetType(OFTInteger);
      56             :                             }
      57         386 :                             else if ((eMinType ==
      58         386 :                                           CPLJSONObject::Type::Integer ||
      59           5 :                                       eMinType == CPLJSONObject::Type::Long) &&
      60             :                                      eMaxType == CPLJSONObject::Type::Long)
      61             :                             {
      62           5 :                                 oFieldDefn.SetType(OFTInteger64);
      63             :                             }
      64        6540 :                             break;
      65             :                         }
      66             :                     }
      67             : 
      68        7872 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
      69             :                 }
      70       10390 :                 else if (oField.ToString() == "Integer")  // GDAL extension
      71             :                 {
      72           0 :                     OGRFieldDefn oFieldDefn(oField.GetName().c_str(),
      73           0 :                                             OFTInteger);
      74           0 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
      75             :                 }
      76       10390 :                 else if (oField.ToString() == "Boolean")
      77             :                 {
      78         111 :                     OGRFieldDefn oFieldDefn(oField.GetName().c_str(),
      79         222 :                                             OFTInteger);
      80         111 :                     oFieldDefn.SetSubType(OFSTBoolean);
      81         111 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
      82             :                 }
      83             :                 else
      84             :                 {
      85       10279 :                     OGRFieldDefn oFieldDefn(oField.GetName().c_str(),
      86       20558 :                                             OFTString);
      87       10279 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
      88             :                 }
      89             :             }
      90             :         }
      91             :     }
      92        1110 : }
      93             : 
      94             : /************************************************************************/
      95             : /*                     OGRMVTFindGeomTypeFromTileStat()                 */
      96             : /************************************************************************/
      97             : 
      98             : OGRwkbGeometryType
      99         628 : OGRMVTFindGeomTypeFromTileStat(const CPLJSONArray &oTileStatLayers,
     100             :                                const char *pszLayerName)
     101             : {
     102         628 :     OGRwkbGeometryType eGeomType = wkbUnknown;
     103         771 :     for (int i = 0; i < oTileStatLayers.Size(); i++)
     104             :     {
     105        1542 :         CPLJSONObject oId = oTileStatLayers[i].GetObj("layer");
     106         771 :         if (oId.IsValid() && oId.GetType() == CPLJSONObject::Type::String)
     107             :         {
     108         771 :             if (oId.ToString() == pszLayerName)
     109             :             {
     110        1884 :                 CPLJSONObject oGeom = oTileStatLayers[i].GetObj("geometry");
     111        1256 :                 if (oGeom.IsValid() &&
     112         628 :                     oGeom.GetType() == CPLJSONObject::Type::String)
     113             :                 {
     114        1884 :                     const std::string oGeomType(oGeom.ToString());
     115             :                     // Note: this information is not
     116             :                     // reliable in case
     117             :                     // of mix of geometry types
     118         628 :                     if (oGeomType == "Point")
     119             :                     {
     120         109 :                         eGeomType = wkbMultiPoint;
     121             :                     }
     122         519 :                     else if (oGeomType == "LineString")
     123             :                     {
     124          26 :                         eGeomType = wkbMultiLineString;
     125             :                     }
     126         493 :                     else if (oGeomType == "Polygon")
     127             :                     {
     128         493 :                         eGeomType = wkbMultiPolygon;
     129             :                     }
     130             :                 }
     131         628 :                 break;
     132             :             }
     133             :         }
     134             :     }
     135         628 :     return eGeomType;
     136             : }
     137             : 
     138             : /************************************************************************/
     139             : /*                     OGRMVTFindAttributesFromTileStat()               */
     140             : /************************************************************************/
     141             : 
     142             : CPLJSONArray
     143        1109 : OGRMVTFindAttributesFromTileStat(const CPLJSONArray &oTileStatLayers,
     144             :                                  const char *pszLayerName)
     145             : {
     146        1252 :     for (int i = 0; i < oTileStatLayers.Size(); i++)
     147             :     {
     148        1542 :         CPLJSONObject oId = oTileStatLayers[i].GetObj("layer");
     149         771 :         if (oId.IsValid() && oId.GetType() == CPLJSONObject::Type::String)
     150             :         {
     151         771 :             if (oId.ToString() == pszLayerName)
     152             :             {
     153             :                 CPLJSONObject oAttributes =
     154        1256 :                     oTileStatLayers[i].GetObj("attributes");
     155        1256 :                 if (oAttributes.IsValid() &&
     156         628 :                     oAttributes.GetType() == CPLJSONObject::Type::Array)
     157             :                 {
     158         628 :                     return oAttributes.ToArray();
     159             :                 }
     160           0 :                 break;
     161             :             }
     162             :         }
     163             :     }
     164         962 :     CPLJSONArray oAttributes;
     165         481 :     oAttributes.Deinit();
     166         481 :     return oAttributes;
     167             : }
     168             : 
     169             : /************************************************************************/
     170             : /*                     OGRMVTCreateFeatureFrom()                        */
     171             : /************************************************************************/
     172             : 
     173        1928 : OGRFeature *OGRMVTCreateFeatureFrom(OGRFeature *poSrcFeature,
     174             :                                     OGRFeatureDefn *poTargetFeatureDefn,
     175             :                                     bool bJsonField, OGRSpatialReference *poSRS)
     176             : {
     177        1928 :     OGRFeature *poFeature = new OGRFeature(poTargetFeatureDefn);
     178        1928 :     if (bJsonField)
     179             :     {
     180           8 :         CPLJSONObject oProperties;
     181           4 :         bool bEmpty = true;
     182          38 :         for (int i = 1; i < poSrcFeature->GetFieldCount(); i++)
     183             :         {
     184          34 :             if (poSrcFeature->IsFieldSet(i))
     185             :             {
     186          34 :                 bEmpty = false;
     187          34 :                 OGRFieldDefn *poFDefn = poSrcFeature->GetFieldDefnRef(i);
     188          34 :                 if (poSrcFeature->IsFieldNull(i))
     189             :                 {
     190           0 :                     oProperties.AddNull(poFDefn->GetNameRef());
     191             :                 }
     192          52 :                 else if (poFDefn->GetType() == OFTInteger ||
     193          18 :                          poFDefn->GetType() == OFTInteger64)
     194             :                 {
     195          23 :                     if (poFDefn->GetSubType() == OFSTBoolean)
     196             :                     {
     197           6 :                         oProperties.Add(poFDefn->GetNameRef(),
     198           6 :                                         poSrcFeature->GetFieldAsInteger(i) ==
     199             :                                             1);
     200             :                     }
     201             :                     else
     202             :                     {
     203          17 :                         oProperties.Add(poFDefn->GetNameRef(),
     204             :                                         poSrcFeature->GetFieldAsInteger64(i));
     205             :                     }
     206             :                 }
     207          11 :                 else if (poFDefn->GetType() == OFTReal)
     208             :                 {
     209           7 :                     oProperties.Add(poFDefn->GetNameRef(),
     210             :                                     poSrcFeature->GetFieldAsDouble(i));
     211             :                 }
     212             :                 else
     213             :                 {
     214           4 :                     oProperties.Add(poFDefn->GetNameRef(),
     215             :                                     poSrcFeature->GetFieldAsString(i));
     216             :                 }
     217             :             }
     218             :         }
     219           4 :         if (!bEmpty)
     220             :         {
     221           4 :             poFeature->SetField(
     222           8 :                 "json", oProperties.Format(CPLJSONObject::PrettyFormat::Pretty)
     223             :                             .c_str());
     224             :         }
     225             : 
     226           4 :         OGRGeometry *poSrcGeom = poSrcFeature->GetGeometryRef();
     227           4 :         if (poSrcGeom)
     228             :         {
     229           4 :             poFeature->SetGeometry(poSrcGeom);
     230             :         }
     231             : #ifdef nodef
     232             :         CPLJSONObject oObj;
     233             :         oObj.Add("type", "Feature");
     234             :         if (poSrcFeature->IsFieldSet(0))
     235             :             oObj.Add("id", poSrcFeature->GetFieldAsInteger64("mvt_id"));
     236             :         oObj.Add("properties", oProperties);
     237             :         if (poSrcGeom)
     238             :         {
     239             :             char *pszGeomJson =
     240             :                 OGR_G_ExportToJson(OGRGeometry::ToHandle(poSrcGeom));
     241             :             CPLJSONDocument oJSonDoc;
     242             :             oJSonDoc.LoadMemory(reinterpret_cast<const GByte *>(pszGeomJson));
     243             :             CPLFree(pszGeomJson);
     244             :             oObj.Add("geometry", oJSonDoc.GetRoot());
     245             :         }
     246             :         poFeature->SetNativeData(
     247             :             oObj.Format(CPLJSONObject::PrettyFormat::Pretty).c_str());
     248             :         poFeature->SetNativeMediaType("application/vnd.geo+json");
     249             : #endif
     250             :     }
     251             :     else
     252             :     {
     253        1924 :         poFeature->SetFrom(poSrcFeature);
     254             :     }
     255        1928 :     OGRGeometry *poGeom = poFeature->GetGeometryRef();
     256        1928 :     if (poGeom)
     257        1928 :         poGeom->assignSpatialReference(poSRS);
     258        1928 :     return poFeature;
     259             : }

Generated by: LCOV version 1.14