Skip to content

Commit

Permalink
[TM-1425] dev monitoring indicators (#602)
Browse files Browse the repository at this point in the history
* changes

* fix

* add base line field

* []

* [TM-1425] Add delayed job to run analysis

* [TM-1425] changes

* fix lint

* [TM-1425] add data attribute

* fix lint

* [TM-1425] add data attibute to value years.

* fix lint

* fix lint

* fix lint

* [TM-1425] add script to restorationby indicators

* [TM-1425] add export indicator controller

* remove log

* [TM-1425] add helper tto restoration by ecoregion indicator

* lint fix

---------

Co-authored-by: cesarLima1 <[email protected]>
  • Loading branch information
LimberHope and cesarLima1 authored Dec 11, 2024
1 parent 94bef93 commit 00591ef
Show file tree
Hide file tree
Showing 32 changed files with 2,374 additions and 0 deletions.
37 changes: 37 additions & 0 deletions app/Helpers/GeometryHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,41 @@ public static function getSitePolygonsOfPolygons(array $polygonUuids)
{
return SitePolygon::whereIn('poly_id', $polygonUuids)->where('is_active', true)->get()->pluck('uuid');
}

public static function getMonitoredPolygonsGeojson($polygonUuid)
{
$polygonGeometry = PolygonGeometry::where('uuid', $polygonUuid)
->select('uuid', DB::raw('ST_AsGeoJSON(geom) AS geojsonGeometry'))
->first();

return [
'geometry' => $polygonGeometry,
'site_polygon_id' => $polygonGeometry->sitePolygon->id,
];
}

public static function getPolygonGeojson($uuid)
{
$polygonGeometry = PolygonGeometry::where('uuid', $uuid)
->select('uuid', DB::raw('ST_AsGeoJSON(geom) AS geojsonGeometry'))
->first();
$geometry = json_decode($polygonGeometry->geojsonGeometry, true);
$polygonData = $polygonGeometry->sitePolygon;

return [
'type' => 'Feature',
'properties' => [
'poly_id' => $polygonData->poly_id,
'poly_name' => $polygonData->poly_name ?? '',
'plantstart' => $polygonData->plantstart ?? '',
'plantend' => $polygonData->plantend ?? '',
'practice' => $polygonData->practice ?? '',
'target_sys' => $polygonData->target_sys ?? '',
'distr' => $polygonData->distr ?? '',
'num_trees' => $polygonData->num_trees ?? '',
'site_id' => $polygonData->site_id ?? '',
],
'geometry' => $geometry,
];
}
}
78 changes: 78 additions & 0 deletions app/Helpers/RestorationByEcoregionHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace App\Helpers;

class RestorationByEcoregionHelper
{
public static function getCategoryEcoRegion($value, ?bool $isExport = false)
{
$categoriesFromEcoRegion = [
'australasian' => [
'Southeast Australia temperate forests',
'Madeira-Tapajós moist forests',
'Tocantins/Pindare moist forests',
'Tapajós-Xingu moist forests',
'Mato Grosso seasonal forests',
'Mato Grosso seasonal forests, Xingu-Tocantins-Araguaia moist forests',
'Bahia coastal forests',
'Tonle Sap freshwater swamp forests',
],
'afrotropical' => [
'Sinú Valley dry forests',
'Santa Marta montane forests',
'Atlantic mixed forests',
'Petén-Veracruz moist forests',
'Central American Atlantic moist forests',
'Petén-Veracruz moist forests, Central American Atlantic moist forests',
'Central American montane forests',
'Central American Atlantic moist forests, Central American montane forests',
'Northern Acacia-Commiphora bushlands and thickets',
'Southern Rift montane forest-grassland mosaic',
'Sierra Madre de Chiapas moist forests',
'Iberian sclerophyllous and semi-deciduous forests',
'Northwest Iberian montane forests',
'Northwestern Congolian lowland forests',
'Albertine Rift montane forests',
'Sahelian Acacia savanna',
'Northern Congolian forest-savanna mosaic',
'Nigerian lowland forests',
'West Sudanian savanna',
'Northern Congolian forest-savanna mosaic, Northwestern Congolian lowland forests',
'Eastern Guinean forests',
'Victoria Basin forest-savanna mosaic',
'Guinean forest-savanna mosaic',
'East Sudanian savanna',
'Central Zambezian Miombo woodlands',
'Ethiopian montane grasslands and woodlands',
'Central African mangroves',
],
'paleartic' => [
'southern-zanzibar-inhambane-coastal-forest-mosaic',
],
];
$formatedValue = [];
foreach ($categoriesFromEcoRegion as $category => $values) {
$formatedValue[$category] = 0;
foreach ($value as $key => $val) {
if (in_array($key, $values)) {
$formatedValue[$category] = round((float) $val, 3);

break;
}
}
}

$result = array_filter($formatedValue, function ($val) {
return $val !== 0;
});

if (empty($result)) {
return $result;
}
if ($isExport) {
return $result;
} else {
return ['data' => $result];
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace App\Http\Controllers\V2\MonitoredData;

use App\Http\Controllers\Controller;
use App\Models\V2\EntityModel;
use App\Models\V2\Projects\Project;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SitePolygon;
use Illuminate\Support\Facades\Log;

class GetIndicatorPolygonStatusController extends Controller
{
public function __invoke(EntityModel $entity)
{
try {
$sitePolygonGroupByStatus = SitePolygon::whereHas('site', function ($query) use ($entity) {
if (get_class($entity) == Site::class) {
$query->where('uuid', $entity->uuid);
} elseif (get_class($entity) == Project::class) {
$query->where('project_id', $entity->project->id);
}
})
->select([
'id',
'status',
'is_active',
])
->where('is_active', 1)
->get()
->groupBy('status')
->map(function ($group) {
return $group->count();
});
$statuses = ['draft', 'submitted', 'needs-more-information', 'approved'];
$statusesByCount = [];

foreach ($statuses as $status) {
if (! isset($sitePolygonGroupByStatus[$status])) {
$statusesByCount[$status] = 0;
} else {
$statusesByCount[$status] = $sitePolygonGroupByStatus[$status];
}
}

return response()->json($statusesByCount);
} catch (\Exception $e) {
Log::info($e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace App\Http\Controllers\V2\MonitoredData;

use App\Helpers\RestorationByEcoregionHelper;
use App\Http\Controllers\Controller;
use App\Models\V2\EntityModel;
use App\Models\V2\Projects\Project;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SitePolygon;
use Illuminate\Support\Facades\Log;

class GetPolygonsIndicatorAnalysisController extends Controller
{
public function __invoke(EntityModel $entity, string $slug)
{
$slugMappings = [
'treeCoverLoss' => [
'relation_name' => 'treeCoverLossIndicator',
'extra_columns' => '',
],
'treeCoverLossFires' => [
'relation_name' => 'treeCoverLossIndicator',
],
'restorationByStrategy' => [
'relation_name' => 'hectaresIndicator',
],
'restorationByLandUse' => [
'relation_name' => 'hectaresIndicator',
],
'restorationByEcoRegion' => [
'relation_name' => 'hectaresIndicator',
],
];

try {
return SitePolygon::whereHas($slugMappings[$slug]['relation_name'], function ($query) use ($slug) {
$query->where('indicator_slug', $slug)
->where('year_of_analysis', date('Y'));
})
->whereHas('site', function ($query) use ($entity) {
if (get_class($entity) == Site::class) {
$query->where('uuid', $entity->uuid);
} elseif (get_class($entity) == Project::class) {
$query->where('project_id', $entity->project->id);
}
})
->select([
'id',
'poly_name',
'status',
'plantstart',
'site_id',
'is_active',
'poly_id',
'calc_area',
])
->where('is_active', 1)
->get()
->map(function ($polygon) use ($slugMappings, $slug) {
$indicator = $polygon->{$slugMappings[$slug]['relation_name']}()
->where('indicator_slug', $slug)
->select([
'indicator_slug',
'year_of_analysis',
'value',
'created_at',
])
->first();
$results = [
'id' => $polygon->id,
'poly_name' => $polygon->poly_name,
'poly_id' => $polygon->poly_id,
'site_id' => $polygon->site_id,
'status' => $polygon->status,
'plantstart' => $polygon->plantstart,
'site_name' => $polygon->site->name ?? '',
'size' => round($polygon->calc_area ?? 0, 3),
'indicator_slug' => $indicator->indicator_slug,
'year_of_analysis' => $indicator->year_of_analysis,
'created_at' => $indicator->created_at,
'base_line' => $indicator->created_at,
'data' => [],
];
if (str_contains($slug, 'treeCoverLoss')) {
$valueYears = json_decode($indicator->value, true);
$results['data']['2015'] = round((float) $valueYears['2015'], 3);
$results['data']['2016'] = round((float) $valueYears['2016'], 3);
$results['data']['2017'] = round((float) $valueYears['2017'], 3);
$results['data']['2018'] = round((float) $valueYears['2018'], 3);
$results['data']['2019'] = round((float) $valueYears['2019'], 3);
$results['data']['2020'] = round((float) $valueYears['2020'], 3);
$results['data']['2021'] = round((float) $valueYears['2021'], 3);
$results['data']['2022'] = round((float) $valueYears['2022'], 3);
$results['data']['2023'] = round((float) $valueYears['2023'], 3);
$results['data']['2024'] = round((float) $valueYears['2024'], 3);
}

if ($slug == 'restorationByEcoRegion') {
$values = json_decode($indicator->value, true);
$results = array_merge($results, RestorationByEcoregionHelper::getCategoryEcoRegion($values));
}

if ($slug == 'restorationByLandUse' || $slug == 'restorationByStrategy') {
$values = json_decode($indicator->value, true);
$results = array_merge($results, $this->processValuesHectares($values));
}

return $results;
});
} catch (\Exception $e) {
Log::info($e);
}
}

public function processValuesHectares($values)
{
$separateKeys = [];
foreach ($values as $key => $value) {
$array = explode(',', str_replace('-', '_', $key));
$arrayTrim = array_map('trim', $array);
foreach ($arrayTrim as $item) {
$separateKeys[$item] = round((float) $value, 3);
}
}

return ['data' => $separateKeys];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace App\Http\Controllers\V2\MonitoredData;

use App\Http\Controllers\Controller;
use App\Models\V2\EntityModel;
use App\Models\V2\Projects\Project;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SitePolygon;
use Illuminate\Support\Facades\Log;

class GetPolygonsIndicatorAnalysisVerifyController extends Controller
{
public function __invoke(EntityModel $entity, string $slug)
{
$slugMappings = [
'treeCoverLoss' => [
'relation_name' => 'treeCoverLossIndicator',
'indicator_title' => 'Tree Cover Loss',
],
'treeCoverLossFires' => [
'relation_name' => 'treeCoverLossIndicator',
'indicator_title' => 'Tree Cover Loss from Fire',
],
'restorationByStrategy' => [
'relation_name' => 'hectaresIndicator',
'indicator_title' => 'Hectares Under Restoration By Strategy',
],
'restorationByLandUse' => [
'relation_name' => 'hectaresIndicator',
'indicator_title' => 'Hectares Under Restoration By Target Land Use System',
],
'restorationByEcoRegion' => [
'relation_name' => 'hectaresIndicator',
'indicator_title' => 'Hectares Under Restoration By WWF EcoRegion',
],
];

try {
$polygonUuids = SitePolygon::whereHas('site', function ($query) use ($entity) {
if (get_class($entity) == Site::class) {
$query->where('uuid', $entity->uuid);
} elseif (get_class($entity) == Project::class) {
$query->where('project_id', $entity->project->id);
}
})
->select(['id', 'poly_id', 'is_active'])
->where('is_active', 1)
->get()
->map(function ($polygon) use ($slugMappings, $slug) {
$indicator = $polygon->{$slugMappings[$slug]['relation_name']}()
->where('indicator_slug', $slug)
->where('year_of_analysis', date('Y'))
->where('site_polygon_id', $polygon->id)
->first();
if (! $indicator) {
return $polygon->poly_id;
}

return null;
})
->filter();
if ($polygonUuids->isEmpty()) {
return response()->json(['message' => 'All polygons have already been analyzed to ' . $slugMappings[$slug]['indicator_title']], 200);
} else {
return response()->json($polygonUuids);

}
} catch (\Exception $e) {
Log::info($e);
}
}
}
Loading

0 comments on commit 00591ef

Please sign in to comment.