Repository navigation
Expand file tree
/
Copy pathSimpleLineStringValidator.php
More file actions
79 lines (71 loc) · 2.99 KB
/
Copy pathSimpleLineStringValidator.php
File metadata and controls
79 lines (71 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
/**
* This file is part of the spatial project.
*
* PHP 8.4 | 8.5
*
* Copyright Alexandre Tranchant <alexandre.tranchant@gmail.com> 2024-2026
* Copyright Longitude One 2024-2026
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace LongitudeOne\SpatialValidator\Validator\Constraints;
use LongitudeOne\Core\Enum\GeometryTypeEnum;
use LongitudeOne\Core\Enum\SpatialModelEnum;
use LongitudeOne\SpatialTypes\Interfaces\LineStringInterface;
use LongitudeOne\SpatialValidator\Internal\PointCoordinates;
use LongitudeOne\SpatialValidator\Internal\SegmentIntersections;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\UnexpectedValueException;
/** Explicitly check line simplicity in XY or XYZ according to the declared variant. */
final class SimpleLineStringValidator extends ConstraintValidator
{
public function validate(mixed $value, Constraint $constraint): void
{
if (!$constraint instanceof SimpleLineString) {
throw new UnexpectedTypeException($constraint, SimpleLineString::class);
}
if (null === $value) {
return;
}
if (!$value instanceof LineStringInterface || GeometryTypeEnum::LINESTRING !== $value->getType()) {
throw new UnexpectedValueException($value, LineStringInterface::class);
}
$before = count($this->context->getViolations());
$this->context->getValidator()->inContext($this->context)->validate(
$value,
new LineString(groups: $constraint->groups, payload: $constraint->payload),
$this->context->getGroup()
);
if ($before !== count($this->context->getViolations()) || [] === $value->getPoints()) {
return;
}
if (SpatialModelEnum::GEOGRAPHY === $value->getFamily()) {
$this->unavailable($constraint);
return;
}
$positions = array_values(array_filter(array_map(PointCoordinates::position(...), $value->getPoints())));
if (!SegmentIntersections::simple($positions)) {
$this->context->buildViolation('The line has a forbidden segment intersection or overlap.')
->setCode(SimpleLineString::INVALID_ERROR)->addViolation()
;
}
}
private function unavailable(SimpleLineString $constraint): void
{
$warning = clone $constraint;
$warning->payload = $constraint->payload ?? ['severity' => 'warning'];
$this->context->setConstraint($warning);
try {
$this->context->buildViolation('Geography LineString simplicity is not implemented yet.')
->setCode(SimpleLineString::UNAVAILABLE_ERROR)->addViolation()
;
} finally {
$this->context->setConstraint($constraint);
}
}
}