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; }
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); } }
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; } }
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 {}; } }
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; }