int main(int argc, char* argv[])
{
  terrama2::core::TerraMA2Init terramaRaii("example", 0);

  {
    //DataProvider information
    terrama2::core::DataProvider* dataProvider = new terrama2::core::DataProvider();
    terrama2::core::DataProviderPtr dataProviderPtr(dataProvider);
    dataProvider->uri = "file://";
    dataProvider->uri += TERRAMA2_DATA_DIR;
    dataProvider->uri += "/geotiff";

    dataProvider->intent = terrama2::core::DataProviderIntent::COLLECTOR_INTENT;
    dataProvider->dataProviderType = "FILE";
    dataProvider->active = true;


    auto& semanticsManager = terrama2::core::SemanticsManager::getInstance();

    //DataSeries information
    terrama2::core::DataSeries* dataSeries = new terrama2::core::DataSeries();
    terrama2::core::DataSeriesPtr dataSeriesPtr(dataSeries);
    dataSeries->semantics = semanticsManager.getSemantics("GRID-geotiff");

    terrama2::core::DataSetGrid* dataSet = new terrama2::core::DataSetGrid();
    dataSet->active = true;
    dataSet->format.emplace("mask", "L5219076_07620040908_r3g2b1.tif");

    dataSeries->datasetList.emplace_back(dataSet);

    //empty filter
    terrama2::core::Filter filter;
    //accessing data
    terrama2::core::DataAccessorGeoTiff accessor(dataProviderPtr, dataSeriesPtr);
    auto remover = std::make_shared<terrama2::core::FileRemover>();
    terrama2::core::GridSeriesPtr gridSeries = accessor.getGridSeries(filter, remover);

    assert(gridSeries->gridMap().size() == 1);

auto raster = gridSeries->gridMap().begin()->second;
    assert(raster->getSRID() != 0);

    std::cout << "SRID: " << raster->getSRID() << std::endl;

    std::string output = TERRAMA2_DATA_DIR;
    output+="/grid_output.tif";

    te::rp::Copy2DiskRaster(*raster, output);

    std::cout << "Tiff file copied to " << output << std::endl;
  }

  

  return 0;
}
Esempio n. 2
0
void terrama2::services::view::core::drawSeriesList(ViewId viewId, std::shared_ptr< terrama2::services::view::core::ViewLogger > logger, std::vector<std::unordered_map<terrama2::core::DataSetPtr, terrama2::core::DataSetSeries>>& seriesList, uint32_t resolutionWidth, uint32_t resolutionHeigth, uint32_t srid)
{
  std::vector< std::shared_ptr<te::map::MemoryDataSetLayer> > layersList;
  uint32_t layerID = 0;

  if(resolutionWidth == 0 ||  resolutionHeigth == 0)
  {
    QString message = QObject::tr("Invalid resolution for View %1.").arg(viewId);
    logger->error(message.toStdString(), viewId);
    throw Exception() << ErrorDescription(message);
  }

  // Create layers from series
  for(auto& series : seriesList)
  {
    for(auto& serie : series)
    {
      terrama2::core::DataSetPtr dataset = serie.first;
      std::shared_ptr<te::da::DataSet> teDataSet = serie.second.syncDataSet->dataset();
      std::shared_ptr<te::da::DataSetType> teDataSetType = serie.second.teDataSetType;

      if(!teDataSetType->hasRaster() && !teDataSetType->hasGeom())
      {
        QString message = QObject::tr("DataSet %1 has no drawable data.").arg(QString::fromStdString(teDataSetType->getDatasetName()));
        logger->error(message.toStdString(), viewId);
      }

      if(teDataSetType->hasRaster())
      {
        // TODO: A terralib dataset can have more than one raster field in it?
        std::size_t rpos = te::da::GetFirstPropertyPos(teDataSet.get(), te::dt::RASTER_TYPE);

        if(!teDataSet->moveFirst())
        {
          QString message = QObject::tr("Can not access DataSet %1 raster data.").arg(QString::fromStdString(teDataSetType->getDatasetName()));
          logger->error(message.toStdString(), viewId);
        }
        else
        {
          auto raster(teDataSet->getRaster(rpos));

          te::gm::Envelope* extent = raster->getExtent();

          // Creates a DataSetLayer of raster
          std::shared_ptr<te::map::MemoryDataSetLayer> rasterLayer(new te::map::MemoryDataSetLayer(te::common::Convert2String(++layerID), raster->getName(), teDataSet, teDataSetType));
          rasterLayer->setDataSetName(teDataSetType->getDatasetName());
          rasterLayer->setExtent(*extent);
          rasterLayer->setRendererType("ABSTRACT_LAYER_RENDERER");

          // if dataset SRID is not setted, try to use the SRID from layer
          if(dataset->format.find("srid") == dataset->format.end())
            rasterLayer->setSRID(raster->getSRID());
          else
            rasterLayer->setSRID(std::stoi(dataset->format.at("srid")));

          // VINICIUS: Set Style
          MONO_0_Style(rasterLayer);

          layersList.push_back(rasterLayer);
        }
      }

      if(teDataSetType->hasGeom())
      {
        // TODO: A terralib dataset can have more than one geometry field in it?
        auto geomProperty = te::da::GetFirstGeomProperty(teDataSetType.get());

        if(!teDataSet->moveFirst())
        {
          QString message = QObject::tr("Can not access DataSet %1 geometry data.").arg(QString::fromStdString(teDataSetType->getDatasetName()));
          logger->error(message.toStdString(), viewId);
        }
        else
        {
          std::shared_ptr< te::gm::Envelope > extent(teDataSet->getExtent(teDataSetType->getPropertyPosition(geomProperty)));

          // Creates a Layer
          std::shared_ptr< te::map::MemoryDataSetLayer > geomLayer(new te::map::MemoryDataSetLayer(te::common::Convert2String(++layerID), geomProperty->getName(), teDataSet, teDataSetType));
          geomLayer->setDataSetName(teDataSetType->getName());
          geomLayer->setVisibility(te::map::VISIBLE);
          geomLayer->setExtent(*extent);
          geomLayer->setRendererType("ABSTRACT_LAYER_RENDERER");

          // if dataset SRID is not setted, try to use the SRID from layer
          if(dataset->format.find("srid") == dataset->format.end())
            geomLayer->setSRID(geomProperty->getSRID());
          else
            geomLayer->setSRID(std::stoi(dataset->format.at("srid")));

          // VINICIUS: set style
          geomLayer->setStyle(CreateFeatureTypeStyle(geomProperty->getGeometryType()));

          layersList.push_back(geomLayer);
        }
      }
    }
  }

  // Draw layers

  if(layersList.size() > 0)
  {
    te::gm::Envelope extent;

    for(auto& layer : layersList)
    {
      if(!extent.isValid())
        extent = layer->getExtent();
      else
        extent.Union(layer->getExtent());

      // If the SRID was not setted, use the SRID from the first layer
      if(srid == 0)
        srid = layer->getSRID();
    }

    // Creates a canvas
    double llx = extent.m_llx;
    double lly = extent.m_lly;
    double urx = extent.m_urx;
    double ury = extent.m_ury;

    std::unique_ptr<te::qt::widgets::Canvas> canvas(new te::qt::widgets::Canvas(resolutionWidth, resolutionHeigth));
    canvas->calcAspectRatio(llx, lly, urx, ury);
    canvas->setWindow(llx, lly, urx, ury);
    canvas->setBackgroundColor(te::color::RGBAColor(255, 255, 255, TE_OPAQUE));

    bool cancel = false;

    for(auto& layer : layersList)
    {
      layer->draw(canvas.get(), extent, srid, 0, &cancel);
    }

    // Save view

    canvas->save("GeneretadImage", te::map::PNG);

    canvas->clear();
  }
  else
  {
    QString message = QObject::tr("View %1 could not find any data.").arg(viewId);
    logger->error(message.toStdString(), viewId);
    throw Exception() << ErrorDescription(message);
  }
}
Esempio n. 3
0
double terrama2::services::analysis::core::grid::zonal::forecast::accum::operatorImpl(terrama2::services::analysis::core::StatisticOperation statisticOperation,
    const std::string& dataSeriesName, const std::string& dateDiscardBefore, const std::string& dateDiscardAfter, const size_t band, terrama2::services::analysis::core::Buffer buffer)
{
  OperatorCache cache;
  terrama2::services::analysis::core::python::readInfoFromDict(cache);
  // After the operator lock is released it's not allowed to return any value because it doesn' have the interpreter lock.
  // In case an exception is thrown, we need to set this boolean. Once the code left the lock is acquired we should return NAN.
  bool exceptionOccurred = false;

  auto& contextManager = ContextManager::getInstance();
  auto analysis = cache.analysisPtr;

  try
  {
    terrama2::core::verify::analysisMonitoredObject(analysis);
  }
  catch(const terrama2::core::VerifyException&)
  {
    contextManager.addError(cache.analysisHashCode, QObject::tr("Use of invalid operator for analysis %1.").arg(analysis->id).toStdString());
    return NAN;
  }

  terrama2::services::analysis::core::MonitoredObjectContextPtr context;
  try
  {
    context = ContextManager::getInstance().getMonitoredObjectContext(cache.analysisHashCode);
  }
  catch(const terrama2::Exception& e)
  {
    TERRAMA2_LOG_ERROR() << boost::get_error_info<terrama2::ErrorDescription>(e)->toStdString();
    return NAN;
  }


  try
  {
    // In case an error has already occurred, there is nothing to be done
    if(!context->getErrors().empty())
      return NAN;

    bool hasData = false;

    auto dataManagerPtr = context->getDataManager().lock();
    if(!dataManagerPtr)
    {
      QString errMsg(QObject::tr("Invalid data manager."));
      throw terrama2::core::InvalidDataManagerException() << terrama2::ErrorDescription(errMsg);
    }

    std::shared_ptr<ContextDataSeries> moDsContext = context->getMonitoredObjectContextDataSeries(dataManagerPtr);
    if(!moDsContext)
    {
      QString errMsg(QObject::tr("Could not recover monitored object data series."));
      throw InvalidDataSeriesException() << terrama2::ErrorDescription(errMsg);
    }

    if(moDsContext->series.syncDataSet->size() == 0)
    {
      QString errMsg(QObject::tr("Could not recover monitored object data series."));
      throw InvalidDataSeriesException() << terrama2::ErrorDescription(errMsg);
    }

    auto moGeom = moDsContext->series.syncDataSet->getGeometry(cache.index, moDsContext->geometryPos);
    if(!moGeom.get())
    {
      QString errMsg(QObject::tr("Could not recover monitored object geometry."));
      throw InvalidDataSetException() << terrama2::ErrorDescription(errMsg);
    }
    auto geomResult = createBuffer(buffer, moGeom);

    auto dataSeries = context->findDataSeries(dataSeriesName);

    /////////////////////////////////////////////////////////////////
    //map of sum of values for each pixel
    std::unordered_map<std::pair<int, int>, std::pair<double, int>, boost::hash<std::pair<int, int> > > valuesMap;

    auto datasets = dataSeries->datasetList;
    for(const auto& dataset : datasets)
    {
      auto rasterList = context->getRasterList(dataSeries, dataset->id, dateDiscardBefore, dateDiscardAfter);
      //sanity check, if no date range only the last raster should be returned
      if(dateDiscardBefore.empty() && rasterList.size() > 1)
      {
        QString errMsg(QObject::tr("Invalid list of raster for dataset: %1").arg(dataset->id));
        throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
      }

      if(rasterList.empty())
      {
        QString errMsg(QObject::tr("Invalid raster for dataset: %1").arg(dataset->id));
        throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
      }

      auto firstRaster = rasterList.front();

      //no intersection between the raster and the object geometry
      if(!firstRaster->getExtent()->intersects(*geomResult->getMBR()))
        continue;

      geomResult->transform(firstRaster->getSRID());
      prec::appendValues(rasterList, band, geomResult.get() , valuesMap);

      if(!valuesMap.empty())
      {
        hasData = true;
        break;
      }
    }

    if(exceptionOccurred)
      return NAN;

    if(!hasData && statisticOperation != StatisticOperation::COUNT)
    {
      return NAN;
    }
    std::vector<double> values;
    values.reserve(valuesMap.size());

    for(const auto& pair : valuesMap)
      values.push_back(pair.second.first);

    terrama2::services::analysis::core::calculateStatistics(values, cache);
    return terrama2::services::analysis::core::getOperationResult(cache, statisticOperation);
  }
  catch(const terrama2::Exception& e)
  {
    context->addError(boost::get_error_info<terrama2::ErrorDescription>(e)->toStdString());
    return NAN;
  }
  catch(const std::exception& e)
  {
    context->addError(e.what());
    return NAN;
  }
  catch(...)
  {
    QString errMsg = QObject::tr("An unknown exception occurred.");
    context->addError(errMsg.toStdString());
    return NAN;
  }
}
Esempio n. 4
0
std::vector<double> terrama2::services::analysis::core::grid::history::sample(const OperatorCache& cache,
                                                                              const std::string& dataSeriesName,
                                                                              const std::string& dateFilterBegin,
                                                                              const std::string& dateFilterEnd,
                                                                              const size_t band)
{
  auto& contextManager = ContextManager::getInstance();
  auto analysis = contextManager.getAnalysis(cache.analysisHashCode);
  try
  {
    terrama2::services::analysis::core::verify::analysisGrid(analysis);
  }
  catch (const terrama2::core::VerifyException&)
  {
    contextManager.addError(cache.analysisHashCode, QObject::tr("Use of invalid operator for analysis %1.").arg(analysis->id).toStdString());
    return {};
  }

  terrama2::services::analysis::core::GridContextPtr context;
  try
  {
    context = ContextManager::getInstance().getGridContext(cache.analysisHashCode);
  }
  catch(const terrama2::Exception& e)
  {
    TERRAMA2_LOG_ERROR() << boost::get_error_info<terrama2::ErrorDescription>(e)->toStdString();
    return {};
  }

  try
  {
// In case an error has already occurred, there is nothing to do.
    if(context->hasError())
    {
      return {};
    }

    auto dataSeries = context->findDataSeries(dataSeriesName);

    auto outputRaster = context->getOutputRaster();
    if(!outputRaster)
    {
      QString errMsg(QObject::tr("Invalid output raster"));
      throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
    }

    auto grid = outputRaster->getGrid();
    auto coord = grid->gridToGeo(cache.column, cache.row);

    terrama2::core::Filter filter;
    filter.discardBefore = context->getTimeFromString(dateFilterBegin);
    filter.discardAfter = context->getTimeFromString(dateFilterEnd);

    auto datasets = dataSeries->datasetList;
    for(const auto& dataset : datasets)
    {

      auto rasterList = context->getRasterList(dataSeries, dataset->id, filter);
      if(rasterList.empty())
      {
        QString errMsg(QObject::tr("Invalid raster for dataset: %1").arg(dataset->id));
        throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
      }

      std::vector<double> samples;
      samples.reserve(rasterList.size());
      for(const auto& raster : rasterList)
      {
        if(band >= raster->getNumberOfBands())
        {
          QString errMsg(QObject::tr("Invalid band index for dataset: %1").arg(dataset->id));
          throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
        }

        auto dsGrid = raster->getGrid();
        if(!dsGrid)
        {
          QString errMsg(QObject::tr("Invalid grid for dataset: %1").arg(dataset->id));
          throw terrama2::InvalidArgumentException() << terrama2::ErrorDescription(errMsg);
        }

        // Transform the coordinate from the output srid to the  source srid
        // so we can get the row and column of the source data.
        auto point = context->convertoTo(coord, dsGrid->getSRID());

        double column, row;
        dsGrid->geoToGrid(point.x, point.y, column, row);

        auto interpolator = context->getInterpolator(raster);

        double value = getValue(raster, interpolator, column, row, band);
        if(!std::isnan(value))
          samples.push_back(value);
      }

      if(!samples.empty())
        return samples;
    }

    return {};
  }
  catch(const terrama2::Exception& e)
  {
    context->addLogMessage(BaseContext::MessageType::ERROR_MESSAGE, boost::get_error_info<terrama2::ErrorDescription>(e)->toStdString());
    return {};
  }
  catch(const std::exception& e)
  {
    context->addLogMessage(BaseContext::MessageType::ERROR_MESSAGE, e.what());
    return {};
  }
  catch(...)
  {
    QString errMsg = QObject::tr("An unknown exception occurred.");
    context->addLogMessage(BaseContext::MessageType::ERROR_MESSAGE, errMsg.toStdString());
    return {};
  }
}
Esempio n. 5
0
std::shared_ptr<te::mem::DataSet> terrama2::services::analysis::core::createAggregationBuffer(
        std::vector<uint32_t>& indexes, std::shared_ptr<ContextDataSeries> contextDataSeries, Buffer buffer,
        StatisticOperation aggregationStatisticOperation,
        const std::string& attribute)
{
  std::shared_ptr<te::mem::DataSet> dsOut;
  if(indexes.empty())
    return dsOut;



  // Creates memory dataset for buffer
  te::da::DataSetType* dt = new te::da::DataSetType("buffer");

  auto syncDs = contextDataSeries->series.syncDataSet;
  auto sampleGeom = syncDs->getGeometry(0, contextDataSeries->geometryPos);
  int geomSampleSrid = sampleGeom->getSRID();

  te::gm::GeometryProperty* prop = new te::gm::GeometryProperty("geom", 0, te::gm::MultiPolygonType, true);
  prop->setSRID(geomSampleSrid);
  dt->add(prop);


  te::dt::SimpleProperty* prop02 = new te::dt::SimpleProperty("attribute", te::dt::DOUBLE_TYPE, true);
  dt->add(prop02);

  dsOut.reset(new te::mem::DataSet(dt));


  std::shared_ptr<te::gm::Envelope> box(syncDs->getExtent(contextDataSeries->geometryPos));


  if(buffer.unit.empty())
    buffer.unit = "m";

  // Inserts each geometry in the rtree, if there is a conflict, it makes the union of the two geometries
  te::sam::rtree::Index<OccurrenceAggregation*, 4> rtree;

  for(size_t i = 0; i < indexes.size(); ++i)
  {
    auto geom = syncDs->getGeometry(indexes[i], contextDataSeries->geometryPos);


    double distance = terrama2::core::convertDistanceUnit(buffer.distance, buffer.unit, "METER");

    std::unique_ptr<te::gm::Geometry> tempGeom(dynamic_cast<te::gm::Geometry*>(geom.get()->clone()));
    if(!tempGeom)
    {
      QString errMsg(QObject::tr("Invalid geometry in dataset: ").arg(contextDataSeries->series.dataSet->id));
      throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg);
    }
    int utmSrid = terrama2::core::getUTMSrid(tempGeom.get());

    // Converts to UTM in order to create buffer in meters
    if(tempGeom->getSRID() != utmSrid)
    {
      tempGeom->transform(utmSrid);
    }
    std::unique_ptr<te::gm::Geometry> aggBuffer(tempGeom->buffer(distance, 16, te::gm::CapButtType));
    aggBuffer->setSRID(utmSrid);

    // Converts buffer to DataSet SRID in order to compare with the occurrences in the rtree
    aggBuffer->transform(geomSampleSrid);


    std::vector<OccurrenceAggregation*> vec;
    bool aggregated = false;

    // Search for occurrences in the same area
    rtree.search(*(aggBuffer->getMBR()), vec);
    for(std::size_t t = 0; t < vec.size(); ++t)
    {
      OccurrenceAggregation* occurrenceAggregation = vec[t];

      // If the an intersection is found, makes the union of the two geometries and mark the index.
      if(aggBuffer->intersects(occurrenceAggregation->buffer.get()))
      {
        rtree.remove(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation);
        occurrenceAggregation->buffer.reset(aggBuffer->Union(occurrenceAggregation->buffer.get()));
        occurrenceAggregation->indexes.push_back(i);
        rtree.insert(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation);
        aggregated = true;
      }
    }

    if(!aggregated)
    {
      OccurrenceAggregation* occurrenceAggregation = new OccurrenceAggregation();
      occurrenceAggregation->buffer.reset(aggBuffer.release());
      occurrenceAggregation->indexes.push_back(i);
      rtree.insert(*(occurrenceAggregation->buffer->getMBR()), occurrenceAggregation);
    }
  }

  // Fills the memory dataset with the geometries
  std::vector<OccurrenceAggregation*> occurrenceAggVec;

  rtree.search(*(box.get()), occurrenceAggVec);

  int attributeType = -1;

  if(aggregationStatisticOperation != StatisticOperation::COUNT)
  {
    auto property = contextDataSeries->series.teDataSetType->getProperty(attribute);

    if(!property)
    {
      QString errMsg(QObject::tr("Invalid attribute: %1").arg(QString::fromStdString(attribute)));
      throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg);
    }
    attributeType = property->getType();
  }


  for(size_t i = 0; i < occurrenceAggVec.size(); i++)
  {
    OccurrenceAggregation* occurrenceAggregation = occurrenceAggVec[i];

    OperatorCache cache;
    std::vector<double> values;
    values.reserve(occurrenceAggregation->indexes.size());
    for(unsigned int j = 0; j < occurrenceAggregation->indexes.size(); ++j)
    {
      cache.count++;

      if(aggregationStatisticOperation != StatisticOperation::COUNT)
      {
        if(attribute.empty())
        {
          QString errMsg(QObject::tr("Invalid attribute"));
          throw terrama2::InvalidArgumentException() << ErrorDescription(errMsg);
        }

        double value = getValue(syncDs, attribute, occurrenceAggregation->indexes[j], attributeType);
        values.push_back(value);
        cache.sum += value;
        if(value > cache.max)
          cache.max = value;
        if(value < cache.min)
          cache.min = value;
      }
    }

    calculateStatistics(values, cache);

    auto item = new te::mem::DataSetItem(dsOut.get());
    item->setGeometry(0, dynamic_cast<te::gm::Geometry*>(occurrenceAggregation->buffer->clone()));
    item->setDouble(1, getOperationResult(cache, aggregationStatisticOperation));
    dsOut->add(item);
  }


  return dsOut;

}