Skip to content

Commit

Permalink
Merge branch 'staging' into TM-1536_delayed_job_progress
Browse files Browse the repository at this point in the history
  • Loading branch information
LimberHope committed Dec 2, 2024
2 parents 09f671f + 7873ac9 commit 020b67a
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,46 @@ public function clipOverlappingPolygonsOfProjectBySite(string $uuid)
$user = Auth::user();
$sitePolygon = Site::isUuid($uuid)->first();
$projectId = $sitePolygon->project_id ?? null;

if (! $projectId) {
return response()->json(['error' => 'Project not found for the given site UUID.'], 404);
}

$polygonUuids = GeometryHelper::getProjectPolygonsUuids($projectId);

if (empty($polygonUuids)) {
return response()->json(['message' => 'No polygons found for the project.'], 204);
}

$allPolygonUuids = [];
foreach ($polygonUuids as $uuid) {
$polygonOverlappingExtraInfo = CriteriaSite::forCriteria(PolygonService::OVERLAPPING_CRITERIA_ID)
->where('polygon_id', $uuid)
->first()
->extra_info ?? null;

if ($polygonOverlappingExtraInfo) {
$decodedInfo = json_decode($polygonOverlappingExtraInfo, true);
$polygonUuidsOverlapping = array_map(function ($item) {
return $item['poly_uuid'] ?? null;
}, $decodedInfo);
$polygonUuidsFiltered = array_filter($polygonUuidsOverlapping);

array_unshift($polygonUuidsFiltered, $uuid);
$allPolygonUuids = array_merge($allPolygonUuids, $polygonUuidsFiltered);
}
}

$uniquePolygonUuids = array_unique($allPolygonUuids);

if (empty($uniquePolygonUuids)) {
return response()->json(['message' => 'No overlapping polygons found for the project.'], 204);
}

$delayedJob = DelayedJobProgress::create([
'processed_content' => 0,
]);
$job = new FixPolygonOverlapJob($delayedJob->id, $polygonUuids, $user->id);
'processed_content' => 0,
]);
$job = new FixPolygonOverlapJob($delayedJob->id, $uniquePolygonUuids, $user->id);
dispatch($job);

return new DelayedJobResource($delayedJob);
Expand Down
20 changes: 13 additions & 7 deletions app/Http/Resources/V2/Dashboard/ProjectProfileDetailsResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@

namespace App\Http\Resources\V2\Dashboard;

use App\Models\Traits\HasProjectCoverImage;
use App\Models\V2\Forms\FormOptionListOption;
use Illuminate\Http\Resources\Json\JsonResource;

class ProjectProfileDetailsResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
use HasProjectCoverImage;

public function toArray($request)
{
$coverImage = $this->getProjectCoverImage($this->resource);

$data = [
'name' => $this->name,
'descriptionObjetive' => $this->objectives,
Expand All @@ -26,9 +25,16 @@ public function toArray($request)
'targetLandUse' => $this->land_use_types,
'landTenure' => $this->land_tenure_project_area,
'framework' => $this->framework_key,
'cover_image' => $coverImage ? [
'id' => $coverImage->id,
'url' => $coverImage->getUrl(),
'thumbnail' => $coverImage->getUrl('thumbnail'),
'is_cover' => $coverImage->is_cover,
'mime_type' => $coverImage->mime_type,
] : null,
];

return $this->appendFilesToResource($data);
return $data;
}

public function getCountryLabel($slug)
Expand Down
57 changes: 57 additions & 0 deletions app/Models/Traits/HasProjectCoverImage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace App\Models\Traits;

use App\Models\V2\Nurseries\Nursery;
use App\Models\V2\Nurseries\NurseryReport;
use App\Models\V2\Projects\Project;
use App\Models\V2\Projects\ProjectReport;
use App\Models\V2\Sites\Site;
use App\Models\V2\Sites\SiteReport;
use Spatie\MediaLibrary\MediaCollections\Models\Media;

trait HasProjectCoverImage
{
public function getProjectCoverImage(Project $project): ?Media
{
$models = [
['type' => get_class($project), 'ids' => [$project->id]],
['type' => Site::class, 'ids' => $project->sites->pluck('id')->toArray()],
['type' => Nursery::class, 'ids' => $project->nurseries->pluck('id')->toArray()],
['type' => ProjectReport::class, 'ids' => $project->reports->pluck('id')->toArray()],
['type' => SiteReport::class, 'ids' => $project->siteReports->pluck('id')->toArray()],
['type' => NurseryReport::class, 'ids' => $project->nurseryReports->pluck('id')->toArray()],
];

$coverMedia = Media::where(function ($query) use ($models) {
foreach ($models as $model) {
$query->orWhere(function ($query) use ($model) {
$query->where('model_type', $model['type'])
->whereIn('model_id', $model['ids']);
});
}
})
->where('is_cover', true)
->first();

if ($coverMedia) {
return $coverMedia;
}

// If no cover image found, the latest image is sent
return Media::where(function ($query) use ($models) {
foreach ($models as $model) {
$query->orWhere(function ($query) use ($model) {
$query->where('model_type', $model['type'])
->whereIn('model_id', $model['ids']);
});
}
})
->where(function ($query) {
$query->where('mime_type', 'like', 'image/jpeg')
->orWhere('mime_type', 'like', 'image/png');
})
->latest()
->first();
}
}
43 changes: 22 additions & 21 deletions app/Validators/Extensions/Polygons/NotOverlapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,21 @@ public static function passes($attribute, $value, $parameters, $validator): bool
public static function getIntersectionData(string $polygonUuid): array
{
$sitePolygon = SitePolygon::forPolygonGeometry($polygonUuid)->first();
if ($sitePolygon === null) {
return [
'valid' => false,
'error' => 'Site polygon not found for the given polygon ID',
'status' => 404,
];
if (! $sitePolygon) {
return ['valid' => false, 'error' => 'Site polygon not found', 'status' => 404];
}

$relatedPolyIds = $sitePolygon->project->sitePolygons()
->where('poly_id', '!=', $polygonUuid)
->pluck('poly_id');
$intersects = PolygonGeometry::join('site_polygon', 'polygon_geometry.uuid', '=', 'site_polygon.poly_id')

$bboxFilteredPolyIds = PolygonGeometry::join('site_polygon', 'polygon_geometry.uuid', '=', 'site_polygon.poly_id')
->whereIn('polygon_geometry.uuid', $relatedPolyIds)
->whereRaw('ST_Intersects(ST_Envelope(polygon_geometry.geom), (SELECT ST_Envelope(geom) FROM polygon_geometry WHERE uuid = ?))', [$polygonUuid])
->pluck('polygon_geometry.uuid');

$intersects = PolygonGeometry::join('site_polygon', 'polygon_geometry.uuid', '=', 'site_polygon.poly_id')
->whereIn('polygon_geometry.uuid', $bboxFilteredPolyIds)
->select([
'polygon_geometry.uuid',
'site_polygon.poly_name',
Expand All @@ -50,28 +52,27 @@ public static function getIntersectionData(string $polygonUuid): array

$mainPolygonArea = PolygonGeometry::where('uuid', $polygonUuid)
->value(DB::raw('ST_Area(geom)'));
$extra_info = [];
foreach ($intersects as $intersect) {
if ($intersect->intersects) {

$extra_info = $intersects
->filter(fn ($intersect) => $intersect->intersects)
->map(function ($intersect) use ($mainPolygonArea) {
$minArea = min($mainPolygonArea, $intersect->area);
if ($minArea > 0) {
$percentage = ($intersect->intersection_area / $minArea) * 100;
$percentage = round($percentage, 2);
} else {
$percentage = 100;
}
$extra_info[] = [
$percentage = $minArea > 0
? round(($intersect->intersection_area / $minArea) * 100, 2)
: 100;

return [
'poly_uuid' => $intersect->uuid,
'poly_name' => $intersect->poly_name,
'percentage' => $percentage,
'intersectSmaller' => ($intersect->area < $mainPolygonArea),
];
}
}

})
->values()
->toArray();

return [
'valid' => ! $intersects->contains('intersects', 1),
'valid' => empty($extra_info),
'uuid' => $polygonUuid,
'project_id' => $sitePolygon->project_id,
'extra_info' => $extra_info,
Expand Down
9 changes: 6 additions & 3 deletions database/factories/V2/PolygonGeometryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ public function definition()

public function geojson(string|array $geojson)
{
$geom = DB::raw("ST_GeomFromGeoJSON('$geojson')");
if (is_array($geojson)) {
$geojson = json_encode($geojson);
}
$geomExpression = DB::raw("ST_GeomFromGeoJSON('$geojson')");

return $this->state(function (array $attributes) use ($geom) {
return $this->state(function (array $attributes) use ($geomExpression) {
return [
'geom' => $geom,
'geom' => $geomExpression,
];
});
}
Expand Down
18 changes: 17 additions & 1 deletion database/factories/V2/Sites/SitePolygonFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,24 @@ class SitePolygonFactory extends Factory
{
public function definition()
{
$geojson = [
'type' => 'Polygon',
'coordinates' => [
[
[0, 0],
[1, 0],
[1, 1],
[0, 1],
[0, 0],
],
],
];

return [
'poly_id' => PolygonGeometry::factory()->create()->uuid,
'poly_id' => PolygonGeometry::factory()
->geojson($geojson)
->create()
->uuid,
'site_id' => Site::factory()->create()->uuid,
'calc_area' => $this->faker->numberBetween(2.0, 50.0),
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class AddSpatialIndexToPolygonGeometry extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('polygon_geometry', function (Blueprint $table) {
DB::statement('ALTER TABLE polygon_geometry MODIFY COLUMN geom GEOMETRY NOT NULL');
DB::statement('CREATE SPATIAL INDEX polygon_geometry_geom_spatial_idx ON polygon_geometry (geom)');
});
}

public function down()
{
Schema::table('polygon_geometry', function (Blueprint $table) {
DB::statement('DROP INDEX polygon_geometry_geom_spatial_idx ON polygon_geometry');
DB::statement('ALTER TABLE polygon_geometry MODIFY COLUMN geom GEOMETRY NULL');
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
public function up(): void
{
Schema::table('site_polygon', function (Blueprint $table) {
$table->index('poly_id', 'idx_site_polygon_poly_id');
});
}

public function down(): void
{
Schema::table('site_polygon', function (Blueprint $table) {
$table->dropIndex('idx_site_polygon_poly_id');
});
}
};

0 comments on commit 020b67a

Please sign in to comment.