OGRErr AODataSource::DeleteLayer( int iLayer )
{
  if( iLayer < 0 || iLayer >= static_cast<int>(m_layers.size()) )
    return OGRERR_FAILURE;

  // Fetch ArObject Table before deleting OGR layer object

  ITablePtr ipTable;
  m_layers[iLayer]->GetTable(&ipTable);

  std::string name = m_layers[iLayer]->GetLayerDefn()->GetName();

  // delete OGR layer
  delete m_layers[iLayer];

  m_layers.erase(m_layers.begin() + iLayer);

  IDatasetPtr ipDataset = ipTable;

  HRESULT hr;
  
  if (FAILED(hr = ipDataset->Delete()))
  {
    CPLError( CE_Warning, CPLE_AppDefined, "%s was not deleted however it has been closed", name.c_str());
    AOErr(hr, "Failed deleting dataset");
   
    return OGRERR_FAILURE;
  }
  else
    return OGRERR_NONE;
}
int AODataSource::Open(IWorkspace* pWorkspace, const char * pszNewName, int bUpdate )
{
    CPLAssert( m_nLayers == 0 );

    if (bUpdate)
    {
      // Start Editing?
    }

    m_pszName = CPLStrdup( pszNewName );
    
    m_ipWorkspace = pWorkspace;

    HRESULT hr;

    // Anything will be fetched
    IEnumDatasetPtr ipEnumDataset;

    if (FAILED(hr = m_ipWorkspace->get_Datasets(esriDTAny, &ipEnumDataset)))
    {
      return AOErr(hr, "Failed Opening Workspace Layers");
    }


    return LoadLayers(ipEnumDataset);
}
Exemple #3
0
bool OGRGeometryToAOGeometry(OGRGeometry* pOGRGeom, esriGeometry::IGeometry** ppGeometry)
{
  HRESULT hr;

  *ppGeometry = NULL;

  GByte* pWKB = NULL;

  long wkbSize = pOGRGeom->WkbSize();
  pWKB = (GByte *) CPLMalloc(wkbSize);

  if( pOGRGeom->exportToWkb( wkbNDR, pWKB ) != OGRERR_NONE )
  {
    CPLFree (pWKB);
    CPLError( CE_Failure, CPLE_AppDefined, "Could not export OGR geometry to WKB");
    return false; 
  }

  long bytesRead;
  esriGeometry::IGeometryFactoryPtr ipGeomFact(esriGeometry::CLSID_GeometryEnvironment);
  hr = ipGeomFact->CreateGeometryFromWkb(&bytesRead, pWKB, ppGeometry);

  CPLFree (pWKB);

  if (FAILED(hr))
  {
    return AOErr(hr, "Failed translating OGR geometry to ESRI Geometry");
  }

  return true;
}
Exemple #4
0
bool AOToOGRSpatialReference(esriGeometry::ISpatialReference* pSR, OGRSpatialReference** ppSR)
{
  HRESULT hr;

  if (pSR == NULL)
  {
    CPLError( CE_Warning, CPLE_AppDefined, "ESRI Spatial Reference is NULL");
    return false;
  }

  esriGeometry::IESRISpatialReferenceGEN2Ptr ipSRGen = pSR;

  if (ipSRGen == NULL)
  {
    CPLError( CE_Warning, CPLE_AppDefined, "ESRI Spatial Reference is Unknown");
    return false;
  }

  long bufferSize = 0;
  if (FAILED(hr = ipSRGen->get_ESRISpatialReferenceSize(&bufferSize)) || bufferSize == 0)
    return false; //should never happen

  BSTR buffer = ::SysAllocStringLen(NULL,bufferSize);

  if (FAILED(hr = ipSRGen->ExportToESRISpatialReference2(&buffer, &bufferSize)))
  {
    ::SysFreeString(buffer);

    return AOErr(hr, "Failed to export ESRI string");
  }

  CW2A strESRIWKT(buffer);

  ::SysFreeString(buffer);

  if (strlen(strESRIWKT) <= 0)
  {
    CPLError( CE_Warning, CPLE_AppDefined, "ESRI Spatial Reference is NULL");
    return false; 
  }

  *ppSR = new OGRSpatialReference(strESRIWKT);

  OGRErr result = (*ppSR)->morphFromESRI();

  if (result == OGRERR_NONE)
  {
    return true;
  }
  else
  {
    delete *ppSR;
    *ppSR = NULL;

    CPLError( CE_Failure, CPLE_AppDefined,
              "Failed morphing from ESRI Geometry: %s", strESRIWKT);

    return false;
  }
}
Exemple #5
0
bool AOToOGRFields(IFields* pFields, OGRFeatureDefn* pOGRFeatureDef, std::vector<long> & ogrToESRIFieldMapping)
{
  HRESULT hr;

  long fieldCount;
  if (FAILED(hr = pFields->get_FieldCount(&fieldCount)))
    return false;

  ogrToESRIFieldMapping.clear();

  for (long i = 0; i < fieldCount; ++i)
  {

    IFieldPtr ipField;
    if (FAILED(hr = pFields->get_Field(i, &ipField)))
      return AOErr(hr, "Error getting field");

    CComBSTR name;
    if (FAILED(hr = ipField->get_Name(&name)))
      return AOErr(hr, "Could not get field name");

    esriFieldType fieldType;
    if (FAILED(hr = ipField->get_Type(&fieldType)))
      return AOErr(hr, "Error getting field type");

    //skip these
    if (fieldType == esriFieldTypeOID || fieldType == esriFieldTypeGeometry)
      continue;

    OGRFieldType ogrType;
    if (!AOToOGRFieldType(fieldType, &ogrType))
    {
      // field cannot be mapped, skipping it
      CPLError( CE_Warning, CPLE_AppDefined, "Skipping field %s", CW2A(name) );
      continue;
    }

    OGRFieldDefn fieldTemplate( CW2A(name), ogrType);
    pOGRFeatureDef->AddFieldDefn( &fieldTemplate );

    ogrToESRIFieldMapping.push_back(i);
  }

  CPLAssert(ogrToESRIFieldMapping.size() == pOGRFeatureDef->GetFieldCount());

  return true;
}
Exemple #6
0
void AOLayer::ResetReading()
{
  HRESULT hr;

  if (FAILED(hr = m_ipTable->Search(m_ipQF, VARIANT_TRUE, &m_ipCursor)))
    AOErr(hr, "Error Executing Query");

}
Exemple #7
0
OGRFeature* AOLayer::GetNextFeature()
{
  while (1) //want to skip errors
  {
    if (m_ipCursor == NULL)
      return NULL;

    HRESULT hr;

    IRowPtr ipRow;

    if (FAILED(hr = m_ipCursor->NextRow(&ipRow)))
    {
      AOErr(hr, "Failed fetching features");
      return NULL;
    }

    if (hr == S_FALSE || ipRow == NULL)
    {
      // It's OK, we are done fetching
      return NULL;
    }

    OGRFeature* pOGRFeature = NULL;

    if (!OGRFeatureFromAORow(ipRow,  &pOGRFeature))
    {
      long oid = -1;
      ipRow->get_OID(&oid);

      std::strstream msg;
      msg << "Failed translating ArcObjects row [" << oid << "] to OGR Feature";

      AOErr(hr, msg.str());
      
      //return NULL;
      continue; //skip feature
    }

    return pOGRFeature;
  }
}
bool AODataSource::LoadLayers(IEnumDataset* pEnumDataset)
{
  HRESULT hr;

  pEnumDataset->Reset();

  IDatasetPtr ipDataset;

  bool errEncountered = false;

  while ((S_OK == pEnumDataset->Next(&ipDataset)) && !(ipDataset == NULL))
  {
    IFeatureDatasetPtr ipFD = ipDataset;
    if (!(ipFD == NULL))
    {
      //We are dealing with a FeatureDataset, need to get
      IEnumDatasetPtr ipEnumDatasetSubset;
      if (FAILED(hr = ipFD->get_Subsets(&ipEnumDatasetSubset)))
      {
        AOErr(hr, "Failed getting dataset subsets");
        errEncountered = true;
        continue; //skipping
      }

      if (LoadLayers(ipEnumDatasetSubset) == false)
        errEncountered = true;

      continue;
    }

    IFeatureClassPtr ipFC = ipDataset;

    if (ipFC == NULL)
      continue; //skip

    AOLayer* pLayer = new AOLayer;
    
    ITablePtr ipTable = ipFC;

    if (!pLayer->Initialize(ipTable))
    {
      errEncountered = true;
      continue;
    }

    m_layers.push_back(pLayer);

  }

  if (errEncountered && m_layers.size() == 0)
    return false; //all of the ones we tried had errors
  else
    return true; //at least one worked
}
Exemple #9
0
OGRFeature *AOLayer::GetFeature( long oid )
{
  HRESULT hr;

  IRowPtr ipRow;
  if (FAILED(hr = m_ipTable->GetRow(oid, &ipRow)))
  {
    AOErr(hr, "Failed fetching row");
    return NULL;
  }

  OGRFeature* pOGRFeature = NULL;

  if (!OGRFeatureFromAORow(ipRow,  &pOGRFeature))
  {
    AOErr(hr, "Failed translating ArcObjects row to OGR Feature");
    return NULL;
  }

  return pOGRFeature;
}
Exemple #10
0
int AOLayer::GetFeatureCount( int bForce )
{
  HRESULT hr;

  long rowCount = -1;

  if (FAILED(hr = m_ipTable->RowCount(m_ipQF, &rowCount)))
  {
    AOErr(hr, "Failed calculating row count");

    return rowCount;
  }

  return static_cast<int>(rowCount);
}
Exemple #11
0
OGRErr AOLayer::GetExtent (OGREnvelope* psExtent, int bForce)
{

  if (bForce) 
  {
    return OGRLayer::GetExtent( psExtent, bForce );
  }

  HRESULT hr;

  IGeoDatasetPtr ipGeoDataset = m_ipTable;
  
  esriGeometry::IEnvelopePtr ipEnv = NULL;
  if (FAILED(hr = ipGeoDataset->get_Extent(&ipEnv)) || ipEnv == NULL)
  {
    AOErr(hr, "Failed retrieving extent");
    
    return OGRERR_FAILURE;
  }

  double temp;

  ipEnv->get_XMin(&temp);
  psExtent->MinX = temp;

  ipEnv->get_YMin(&temp);
  psExtent->MinY = temp;

  ipEnv->get_XMax(&temp);
  psExtent->MaxX = temp;

  ipEnv->get_YMax(&temp);
  psExtent->MaxY = temp;

  return OGRERR_NONE;
}
Exemple #12
0
bool AOGeometryToOGRGeometry(bool forceMulti, esriGeometry::IGeometry* pInAOGeo, OGRSpatialReference* pOGRSR, unsigned char* & pInOutWorkingBuffer, long & inOutBufferSize, OGRGeometry** ppOutGeometry)
{
  HRESULT hr;
  
  esriGeometry::IWkbPtr ipWkb = pInAOGeo;

  long reqSize = 0;

  if (FAILED(hr = ipWkb->get_WkbSize(&reqSize)))
  {
    AOErr(hr, "Error getting Wkb buffer size");
    return false;
  }

  if (reqSize > inOutBufferSize)
  {
    // resize working buffer
    delete [] pInOutWorkingBuffer;
    pInOutWorkingBuffer = new unsigned char[reqSize];
    inOutBufferSize = reqSize;
  }
  
  if (FAILED(hr = ipWkb->ExportToWkb(&reqSize, pInOutWorkingBuffer)))
  {
    AOErr(hr, "Error exporting to WKB buffer");
    return false;
  }

  OGRGeometry* pOGRGeometry = NULL;
  OGRErr eErr = OGRGeometryFactory::createFromWkb(pInOutWorkingBuffer, pOGRSR, &pOGRGeometry, reqSize);
  if (eErr != OGRERR_NONE)
  {
    CPLError( CE_Failure, CPLE_AppDefined, "Failed attempting to import ArcGIS WKB Geometry. OGRGeometryFactory err:%d", eErr);
    return false;
  }

  // force geometries to multi if requested


  // If it is a polygon, force to MultiPolygon since we always produce multipolygons
  if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbPolygon)
  {
    pOGRGeometry = OGRGeometryFactory::forceToMultiPolygon(pOGRGeometry);
  }
  else if (forceMulti)
  {
    if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbLineString)
    {
      pOGRGeometry = OGRGeometryFactory::forceToMultiLineString(pOGRGeometry);
    }
    else if (wkbFlatten(pOGRGeometry->getGeometryType()) == wkbPoint)
    {
      pOGRGeometry = OGRGeometryFactory::forceToMultiPoint(pOGRGeometry);
    } 
  }


  *ppOutGeometry = pOGRGeometry;
  
  return true;
}
Exemple #13
0
bool AOLayer::Initialize(ITable* pTable)
{
  HRESULT hr;

  m_ipTable = pTable;

  CComBSTR temp;

  IDatasetPtr ipDataset = m_ipTable;
  if (FAILED(hr = ipDataset->get_Name(&temp)))
    return false;

  m_pFeatureDefn = new OGRFeatureDefn(CW2A(temp)); //Should I "new" an OGR smart pointer - sample says so, but it doesn't seem right
                                                   //as long as we use the same compiler & settings in both the ogr build and this
                                                   //driver, we should be OK
  m_pFeatureDefn->Reference();

  IFeatureClassPtr ipFC = m_ipTable;

  VARIANT_BOOL hasOID = VARIANT_FALSE;
  ipFC->get_HasOID(&hasOID);

  if (hasOID == VARIANT_TRUE)
  {
    ipFC->get_OIDFieldName(&temp);
    m_strOIDFieldName = CW2A(temp);
  }

  if (FAILED(hr = ipFC->get_ShapeFieldName(&temp)))
    return AOErr(hr, "No shape field found!");

  m_strShapeFieldName = CW2A(temp);

  IFieldsPtr ipFields;
  if (FAILED(hr = ipFC->get_Fields(&ipFields)))
    return AOErr(hr, "Fields not found!");

  long shapeIndex = -1;
  if (FAILED(hr = ipFields->FindField(temp, &shapeIndex)))
    return AOErr(hr, "Shape field not found!");

  IFieldPtr ipShapeField;
  if (FAILED(hr = ipFields->get_Field(shapeIndex, &ipShapeField)))
    return false;
    
  // Use GeometryDef to set OGR shapetype and Spatial Reference information
  //

  IGeometryDefPtr ipGeoDef;
  if (FAILED(hr = ipShapeField->get_GeometryDef(&ipGeoDef)))
    return false;

  OGRwkbGeometryType ogrGeoType;
  if (!AOToOGRGeometry(ipGeoDef, &ogrGeoType))
    return false;

  m_pFeatureDefn->SetGeomType(ogrGeoType);

  if (wkbFlatten(ogrGeoType) == wkbMultiLineString || wkbFlatten(ogrGeoType) == wkbMultiPoint)
    m_forceMulti = true;

  
  // Mapping of Spatial Reference will be passive about errors
  // (it is possible we won't be able to map some ESRI-specific projections)

  esriGeometry::ISpatialReferencePtr ipSR = NULL;

  if (FAILED(hr = ipGeoDef->get_SpatialReference(&ipSR)))
  {
    AOErr(hr, "Failed Fetching ESRI spatial reference");
  }
  else
  {
    if (!AOToOGRSpatialReference(ipSR, &m_pSRS))
    {
      //report error, but be passive about it
      CPLError( CE_Warning, CPLE_AppDefined, "Failed Mapping ESRI Spatial Reference");
    }
  }


  // Map fields
  //
  return AOToOGRFields(ipFields, m_pFeatureDefn, m_OGRFieldToESRIField);
}
Exemple #14
0
bool AOLayer::OGRFeatureFromAORow(IRow* pRow, OGRFeature** ppFeature)
{
  HRESULT hr;

  OGRFeature* pOutFeature = new OGRFeature(m_pFeatureDefn);

  /////////////////////////////////////////////////////////
  // Translate OID
  //

  long oid = -1;
  if (FAILED(hr = pRow->get_OID(&oid)))
  {
    //this should never happen
    delete pOutFeature;
    return false;
  }
  pOutFeature->SetFID(oid);

  /////////////////////////////////////////////////////////
  // Translate Geometry
  //

  IFeaturePtr ipFeature = pRow;
  esriGeometry::IGeometryPtr ipGeometry = NULL;

  if (FAILED(hr = ipFeature->get_Shape(&ipGeometry)) || ipGeometry == NULL)
  {
    delete pOutFeature;
    return AOErr(hr, "Failed retrieving shape from ArcObjects");
  }

  OGRGeometry* pOGRGeo = NULL;

  if ((!AOGeometryToOGRGeometry(m_forceMulti, ipGeometry, m_pSRS, m_pBuffer, m_bufferSize, &pOGRGeo)) || pOGRGeo == NULL)
  {
    delete pOutFeature;
    return AOErr(hr, "Failed to translate ArcObjects Geometry to OGR Geometry");
  }

  pOutFeature->SetGeometryDirectly(pOGRGeo);


  //////////////////////////////////////////////////////////
  // Map fields
  //

  CComVariant val;
  size_t mappedFieldCount = m_OGRFieldToESRIField.size();

  bool foundBadColumn = false;

  for (size_t i = 0; i < mappedFieldCount; ++i)
  {
    long index = m_OGRFieldToESRIField[i];

    if (FAILED(hr = pRow->get_Value(index, &val)))
    {
      // this should not happen
      return AOErr(hr, "Failed retrieving row value");
    }

    if (val.vt == VT_NULL)
    {
      continue; //leave as unset
    }

    // 
    // NOTE: This switch statement needs to be kept in sync with AOToOGRGeometry
    //       since we are only checking for types we mapped in that utility function

    switch (m_pFeatureDefn->GetFieldDefn(i)->GetType())
    {

    case OFTInteger:
      {
        val.ChangeType(VT_I4);
        pOutFeature->SetField(i, val.intVal);
      }
      break;

    case OFTReal:
      {
        val.ChangeType(VT_R8);
        pOutFeature->SetField(i, val.dblVal);
      }
      break;
    case OFTString:
      {
        val.ChangeType(VT_BSTR);
        pOutFeature->SetField(i, CW2A(val.bstrVal));
      }
      break;

    /* TODO: Need to get test dataset to implement these leave it as NULL for now
    case OFTBinary:
      {
      // Access as SafeArray with SafeArrayAccessData perhaps?
      }
      break;
    case OFTDateTime:
      {
      // Examine test data to figure out how to extract that
      }
      break;
      */
    default:
      {
        if (!m_supressColumnMappingError)
        {
          foundBadColumn = true;
          CPLError( CE_Warning, CPLE_AppDefined, "Row id: %d col:%d has unhandled col type (%d). Setting to NULL.", oid, i, m_pFeatureDefn->GetFieldDefn(i)->GetType());
        }
      }
    }
  }
  
  if (foundBadColumn)
    m_supressColumnMappingError = true;
  

  *ppFeature = pOutFeature;

  return true;
}