LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/elastic - ogrelasticlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 138 99 71.7 %
Date: 2012-04-28 Functions: 17 10 58.8 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrelasticlayer.cpp 23836 2012-01-31 19:32:04Z rouault $
       3                 :  *
       4                 :  * Project:  ElasticSearch Translator
       5                 :  * Purpose:
       6                 :  * Author:
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Adam Estrada
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_elastic.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_minixml.h"
      33                 : #include "ogr_api.h"
      34                 : #include "ogr_p.h"
      35                 : #include <jsonc/json.h> // JSON-C
      36                 : 
      37                 : CPL_CVSID("$Id: ogrelasticlayer.cpp 23836 2012-01-31 19:32:04Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                           OGRElasticLayer()                          */
      41                 : /************************************************************************/
      42                 : 
      43               4 : OGRElasticLayer::OGRElasticLayer(const char* pszFilename,
      44                 :         const char* pszLayerName,
      45                 :         OGRElasticDataSource* poDS,
      46                 :         OGRSpatialReference *poSRSIn,
      47               4 :         int bWriteMode) {
      48               4 :     this->pszLayerName = CPLStrdup(pszLayerName);
      49               4 :     this->poDS = poDS;
      50               4 :     this->pAttributes = NULL;
      51                 : 
      52                 :     // If we are overwriting, then delete the current index if it exists
      53               4 :     if (poDS->bOverwrite) {
      54               4 :         poDS->DeleteIndex(CPLSPrintf("%s/%s", poDS->GetName(), pszLayerName));
      55                 :     }
      56                 : 
      57                 :     // Create the index
      58               4 :     poDS->UploadFile(CPLSPrintf("%s/%s", poDS->GetName(), pszLayerName), "");
      59                 : 
      60                 :     // If we have a user specified mapping, then go ahead and update it now
      61               4 :     if (poDS->pszMapping != NULL) {
      62               0 :         poDS->UploadFile(CPLSPrintf("%s/%s/FeatureCollection/_mapping", poDS->GetName(), pszLayerName),
      63               0 :                 poDS->pszMapping);
      64                 :     }
      65                 : 
      66               4 :     poFeatureDefn = new OGRFeatureDefn(pszLayerName);
      67               4 :     poFeatureDefn->Reference();
      68                 : 
      69               4 :     poSRS = poSRSIn;
      70               4 :     if (poSRS)
      71               0 :         poSRS->Reference();
      72                 : 
      73               4 :     ResetReading();
      74                 :     return;
      75               0 : }
      76                 : 
      77                 : /************************************************************************/
      78                 : /*                         ~OGRElasticLayer()                           */
      79                 : /************************************************************************/
      80                 : 
      81               4 : OGRElasticLayer::~OGRElasticLayer() {
      82               4 :     PushIndex();
      83                 : 
      84               4 :     CPLFree(pszLayerName);
      85                 : 
      86               4 :     poFeatureDefn->Release();
      87                 : 
      88               4 :     if (poSRS != NULL)
      89               0 :         poSRS->Release();
      90               4 : }
      91                 : 
      92                 : 
      93                 : /************************************************************************/
      94                 : /*                            GetLayerDefn()                            */
      95                 : /************************************************************************/
      96                 : 
      97               4 : OGRFeatureDefn * OGRElasticLayer::GetLayerDefn() {
      98               4 :     return poFeatureDefn;
      99                 : }
     100                 : 
     101                 : /************************************************************************/
     102                 : /*                            ResetReading()                            */
     103                 : /************************************************************************/
     104                 : 
     105               4 : void OGRElasticLayer::ResetReading() {
     106                 :     return;
     107                 : }
     108                 : 
     109                 : /************************************************************************/
     110                 : /*                           GetNextFeature()                           */
     111                 : /************************************************************************/
     112                 : 
     113               0 : OGRFeature *OGRElasticLayer::GetNextFeature() {
     114                 :     CPLError(CE_Failure, CPLE_NotSupported,
     115               0 :             "Cannot read features when writing a Elastic file");
     116               0 :     return NULL;
     117                 : }
     118                 : 
     119                 : /************************************************************************/
     120                 : /*                           GetSpatialRef()                            */
     121                 : /************************************************************************/
     122                 : 
     123               0 : OGRSpatialReference *OGRElasticLayer::GetSpatialRef() {
     124               0 :     return poSRS;
     125                 : }
     126                 : 
     127                 : /************************************************************************/
     128                 : /*                            AppendGroup()                             */
     129                 : /************************************************************************/
     130                 : 
     131               4 : json_object *AppendGroup(json_object *parent, const CPLString &name) {
     132               4 :     json_object *obj = json_object_new_object();
     133               4 :     json_object *properties = json_object_new_object();
     134               4 :     json_object_object_add(parent, name, obj);
     135               4 :     json_object_object_add(obj, "properties", properties);
     136               4 :     return properties;
     137                 : }
     138                 : 
     139                 : /************************************************************************/
     140                 : /*                           AddPropertyMap()                           */
     141                 : /************************************************************************/
     142                 : 
     143              14 : json_object *AddPropertyMap(const CPLString &type, const CPLString &format = "") {
     144              14 :     json_object *obj = json_object_new_object();
     145              14 :     json_object_object_add(obj, "store", json_object_new_string("yes"));
     146              14 :     json_object_object_add(obj, "type", json_object_new_string(type.c_str()));
     147              14 :     if (!format.empty()) {
     148               0 :         json_object_object_add(obj, "format", json_object_new_string(format.c_str()));
     149                 :     }
     150              14 :     return obj;
     151                 : }
     152                 : 
     153                 : /************************************************************************/
     154                 : /*                             BuildMap()                               */
     155                 : /************************************************************************/
     156                 : 
     157               2 : CPLString OGRElasticLayer::BuildMap() {
     158               2 :     json_object *map = json_object_new_object();
     159               2 :     json_object *properties = json_object_new_object();
     160                 : 
     161               2 :     json_object *Feature = AppendGroup(map, "FeatureCollection");
     162               4 :     json_object_object_add(Feature, "type", AddPropertyMap("string"));
     163               2 :     json_object_object_add(Feature, "properties", properties);
     164               4 :     if (pAttributes) json_object_object_add(properties, "properties", (json_object *) pAttributes);
     165               2 :     json_object *geometry = AppendGroup(Feature, "geometry");
     166               4 :     json_object_object_add(geometry, "type", AddPropertyMap("string"));
     167               4 :     json_object_object_add(geometry, "coordinates", AddPropertyMap("geo_point"));
     168                 : 
     169               2 :     CPLString jsonMap(json_object_to_json_string(map));
     170               2 :     json_object_put(map);
     171                 : 
     172                 :     // The attribute's were freed from the deletion of the map object
     173                 :   // because we added it as a child of one of the map object attributes
     174               2 :     if (pAttributes) {
     175               2 :         pAttributes = NULL;
     176                 :     }
     177                 : 
     178               0 :     return jsonMap;
     179                 : }
     180                 : 
     181                 : /************************************************************************/
     182                 : /*                           CreateFeature()                            */
     183                 : /************************************************************************/
     184                 : 
     185               4 : OGRErr OGRElasticLayer::CreateFeature(OGRFeature *poFeature) {
     186                 : 
     187                 :     // Check to see if the user has elected to only write out the mapping file
     188                 :     // This method will only write out one layer from the vector file in cases where there are multiple layers
     189               4 :     if (poDS->pszWriteMap != NULL) {
     190               0 :         if (pAttributes) {
     191               0 :             CPLString map = BuildMap();
     192                 : 
     193                 :             // Write the map to a file
     194               0 :             FILE *f = fopen(poDS->pszWriteMap, "wb");
     195               0 :             if (f) {
     196               0 :                 fwrite(map.c_str(), 1, map.length(), f);
     197               0 :                 fclose(f);
     198               0 :             }
     199                 :         }
     200               0 :         return OGRERR_NONE;
     201                 :     }
     202                 : 
     203                 :     // Check to see if we have any fields to upload to this index
     204               4 :     if (poDS->pszMapping == NULL && pAttributes) {
     205               2 :         poDS->UploadFile(CPLSPrintf("%s/%s/FeatureCollection/_mapping", poDS->GetName(), pszLayerName), BuildMap());
     206                 :     }
     207                 : 
     208                 :     // Get the center point of the geometry
     209               4 :     OGREnvelope env;
     210               4 :   if (!poFeature->GetGeometryRef()) {
     211               2 :     return OGRERR_FAILURE;
     212                 :   }
     213               2 :     poFeature->GetGeometryRef()->getEnvelope(&env);
     214                 : 
     215               2 :     json_object *fieldObject = json_object_new_object();
     216               2 :     json_object *geometry = json_object_new_object();
     217               2 :     json_object *coordinates = json_object_new_array();
     218               2 :     json_object *properties = json_object_new_object();
     219                 : 
     220               2 :     json_object_object_add(fieldObject, "geometry", geometry);
     221               2 :     json_object_object_add(geometry, "type", json_object_new_string("POINT"));
     222               2 :     json_object_object_add(geometry, "coordinates", coordinates);
     223               2 :     json_object_array_add(coordinates, json_object_new_double((env.MaxX + env.MinX)*0.5));
     224               2 :     json_object_array_add(coordinates, json_object_new_double((env.MaxY + env.MinY)*0.5));
     225               2 :     json_object_object_add(fieldObject, "type", json_object_new_string("Feature"));
     226               2 :     json_object_object_add(fieldObject, "properties", properties);
     227                 : 
     228                 :     // For every field that
     229               2 :     int fieldCount = poFeatureDefn->GetFieldCount();
     230              10 :     for (int i = 0; i < fieldCount; i++) {
     231               8 :     if(!poFeature->IsFieldSet( i ) ) {
     232               2 :       continue;
     233                 :     }
     234               6 :         switch (poFeatureDefn->GetFieldDefn(i)->GetType()) {
     235                 :             case OFTInteger:
     236                 :                 json_object_object_add(properties,
     237                 :                         poFeatureDefn->GetFieldDefn(i)->GetNameRef(),
     238               2 :                         json_object_new_int(poFeature->GetFieldAsInteger(i)));
     239               2 :                 break;
     240                 :             case OFTReal:
     241                 :                 json_object_object_add(properties,
     242                 :                         poFeatureDefn->GetFieldDefn(i)->GetNameRef(),
     243               2 :                         json_object_new_double(poFeature->GetFieldAsDouble(i)));
     244               2 :                 break;
     245                 :             default:
     246                 :             {
     247               2 :                 CPLString tmp = poFeature->GetFieldAsString(i);
     248                 :                 json_object_object_add(properties,
     249                 :                         poFeatureDefn->GetFieldDefn(i)->GetNameRef(),
     250               2 :                         json_object_new_string(tmp));
     251                 :             }
     252                 :         }
     253                 :     }
     254                 : 
     255                 :     // Build the field string
     256               2 :     CPLString fields(json_object_to_json_string(fieldObject));
     257               2 :     json_object_put(fieldObject);
     258                 : 
     259                 :     // Check to see if we're using bulk uploading
     260               2 :     if (poDS->nBulkUpload > 0) {
     261                 :         sIndex += CPLSPrintf("{\"index\" :{\"_index\":\"%s\", \"_type\":\"FeatureCollection\"}}\n", pszLayerName) +
     262               0 :                 fields + "\n\n";
     263                 : 
     264                 :         // Only push the data if we are over our bulk upload limit
     265               0 :         if ((int) sIndex.length() > poDS->nBulkUpload) {
     266               0 :             PushIndex();
     267                 :         }
     268                 : 
     269                 :     } else { // Fall back to using single item upload for every feature
     270               2 :         poDS->UploadFile(CPLSPrintf("%s/%s/FeatureCollection/", poDS->GetName(), pszLayerName), fields);
     271                 :     }
     272                 : 
     273               2 :     return OGRERR_NONE;
     274                 : }
     275                 : 
     276                 : /************************************************************************/
     277                 : /*                             PushIndex()                              */
     278                 : /************************************************************************/
     279                 : 
     280               4 : void OGRElasticLayer::PushIndex() {
     281               4 :     if (sIndex.empty()) {
     282               4 :         return;
     283                 :     }
     284                 : 
     285               0 :     poDS->UploadFile(CPLSPrintf("%s/_bulk", poDS->GetName()), sIndex);
     286               0 :     sIndex.clear();
     287                 : }
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                            CreateField()                             */
     291                 : /************************************************************************/
     292                 : 
     293               8 : OGRErr OGRElasticLayer::CreateField(OGRFieldDefn *poFieldDefn, int bApproxOK) {
     294               8 :     if (!pAttributes) {
     295               2 :         pAttributes = json_object_new_object();
     296                 :     }
     297                 : 
     298               8 :     switch (poFieldDefn->GetType()) {
     299                 :         case OFTInteger:
     300               2 :             json_object_object_add((json_object *) pAttributes, poFieldDefn->GetNameRef(), AddPropertyMap("integer"));
     301               2 :             break;
     302                 :         case OFTReal:
     303               4 :             json_object_object_add((json_object *) pAttributes, poFieldDefn->GetNameRef(), AddPropertyMap("float"));
     304               4 :             break;
     305                 :         case OFTString:
     306               2 :             json_object_object_add((json_object *) pAttributes, poFieldDefn->GetNameRef(), AddPropertyMap("string"));
     307               2 :             break;
     308                 :         case OFTDateTime:
     309                 :         case OFTDate:
     310               0 :             json_object_object_add((json_object *) pAttributes, poFieldDefn->GetNameRef(), AddPropertyMap("date", "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd"));
     311               0 :             break;
     312                 :         default:
     313                 : 
     314                 :             // These types are mapped as strings and may not be correct
     315                 :             /*
     316                 :                             OFTTime:
     317                 :                             OFTIntegerList = 1,
     318                 :                             OFTRealList = 3,
     319                 :                             OFTStringList = 5,
     320                 :                             OFTWideString = 6,
     321                 :                             OFTWideStringList = 7,
     322                 :                             OFTBinary = 8,
     323                 :                             OFTMaxType = 11
     324                 :              */
     325               0 :             json_object_object_add((json_object *) pAttributes, poFieldDefn->GetNameRef(), AddPropertyMap("string"));
     326                 :     }
     327                 : 
     328               8 :     poFeatureDefn->AddFieldDefn(poFieldDefn);
     329               8 :     return OGRERR_NONE;
     330                 : }
     331                 : 
     332                 : /************************************************************************/
     333                 : /*                           TestCapability()                           */
     334                 : /************************************************************************/
     335                 : 
     336               0 : int OGRElasticLayer::TestCapability(const char * pszCap) {
     337               0 :     if (EQUAL(pszCap, OLCFastFeatureCount))
     338               0 :         return FALSE;
     339                 : 
     340               0 :     else if (EQUAL(pszCap, OLCStringsAsUTF8))
     341               0 :         return TRUE;
     342                 : 
     343               0 :     else if (EQUAL(pszCap, OLCSequentialWrite))
     344               0 :         return TRUE;
     345                 :     else
     346               0 :         return FALSE;
     347                 : }
     348                 : 
     349                 : /************************************************************************/
     350                 : /*                          GetFeatureCount()                           */
     351                 : /************************************************************************/
     352                 : 
     353               0 : int OGRElasticLayer::GetFeatureCount(int bForce) {
     354                 :     CPLError(CE_Failure, CPLE_NotSupported,
     355               0 :             "Cannot read features when writing a Elastic file");
     356               0 :     return 0;
     357                 : }

Generated by: LCOV version 1.7