Skip to content

Commit be741c9

Browse files
committed
[Map] Improve polygones-with-holes code and documentation
1 parent 5fc61db commit be741c9

File tree

3 files changed

+54
-29
lines changed

3 files changed

+54
-29
lines changed

src/Map/CHANGELOG.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,27 @@
22

33
## 2.26
44

5-
- Add MultiPolygon support. A MultiPolygon allows you to represent multiple polygons (possibly with holes or separate areas) as a single map element. See documentation for usage.
5+
- Add support for creating `Polygon` with holes, by passing an array of `array<Point>` as `points` parameter to the `Polygon` constructor, e.g.:
6+
```php
7+
// Draw a polygon with a hole in it, on the French map
8+
$map->addPolygon(new Polygon(points: [
9+
// First path, the outer boundary of the polygon
10+
[
11+
new Point(48.117266, -1.677792), // Rennes
12+
new Point(50.629250, 3.057256), // Lille
13+
new Point(48.573405, 7.752111), // Strasbourg
14+
new Point(43.296482, 5.369780), // Marseille
15+
new Point(44.837789, -0.579180), // Bordeaux
16+
],
17+
// Second path, it will make a hole in the previous one
18+
[
19+
new Point(45.833619, 1.261105), // Limoges
20+
new Point(45.764043, 4.835659), // Lyon
21+
new Point(49.258329, 4.031696), // Reims
22+
new Point(48.856613, 2.352222), // Paris
23+
],
24+
]));
25+
```
626

727
## 2.25
828

src/Map/doc/index.rst

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ Start by creating a new map instance::
7171
use Symfony\UX\Map\Map;
7272

7373
// Create a new map instance
74-
$myMap = (new Map());
74+
$map = new Map();
7575

7676
Center and zoom
7777
~~~~~~~~~~~~~~~
@@ -81,7 +81,7 @@ You can set the center and zoom of the map using the ``center()`` and ``zoom()``
8181
use Symfony\UX\Map\Map;
8282
use Symfony\UX\Map\Point;
8383

84-
$myMap
84+
$map
8585
// Explicitly set the center and zoom
8686
->center(new Point(46.903354, 1.888334))
8787
->zoom(6)
@@ -95,7 +95,7 @@ Add markers
9595

9696
You can add markers to a map using the ``addMarker()`` method::
9797

98-
$myMap
98+
$map
9999
->addMarker(new Marker(
100100
position: new Point(48.8566, 2.3522),
101101
title: 'Paris'
@@ -154,7 +154,7 @@ Add Polygons
154154

155155
You can also add Polygons, which represents an area enclosed by a series of ``Point`` instances::
156156

157-
$myMap->addPolygon(new Polygon(
157+
$map->addPolygon(new Polygon(
158158
points: [
159159
new Point(48.8566, 2.3522),
160160
new Point(45.7640, 4.8357),
@@ -168,33 +168,35 @@ You can also add Polygons, which represents an area enclosed by a series of ``Po
168168

169169
.. versionadded:: 2.26
170170

171-
``MultiPolygon`` is available since UX Map 2.26.
171+
`Polygon` with holes is available since UX Map 2.26.
172172

173-
You can also add a MultiPolygon. A MultiPolygon allows you to represent multiple polygons (possibly with holes or separate areas) as a single map element::
173+
Since UX Map 2.26, you can also create polygons with holes in them, by passing an array of `array<Point>` to `points` parameter::
174174

175-
$myMap->addPolygon(new Polygon(
176-
points: [
177-
[
178-
new Point(-180, 90),
179-
new Point(180, 90),
180-
new Point(180, -90),
181-
new Point(-180, -90),
182-
],
183-
[
184-
new Point(48.8566, 2.3522),
185-
new Point(45.7640, 4.8357),
186-
new Point(43.2965, 5.3698),
187-
new Point(44.8378, -0.5792),
188-
]
175+
// Draw a polygon with a hole in it, on the French map
176+
$map->addPolygon(new Polygon(points: [
177+
// First path, the outer boundary of the polygon
178+
[
179+
new Point(48.117266, -1.677792), // Rennes
180+
new Point(50.629250, 3.057256), // Lille
181+
new Point(48.573405, 7.752111), // Strasbourg
182+
new Point(43.296482, 5.369780), // Marseille
183+
new Point(44.837789, -0.579180), // Bordeaux
189184
],
190-
));
185+
// Second path, it will make a hole in the previous one
186+
[
187+
new Point(45.833619, 1.261105), // Limoges
188+
new Point(45.764043, 4.835659), // Lyon
189+
new Point(49.258329, 4.031696), // Reims
190+
new Point(48.856613, 2.352222), // Paris
191+
],
192+
]));
191193

192194
Add Polylines
193195
~~~~~~~~~~~~~
194196

195197
You can add Polylines, which represents a path made by a series of ``Point`` instances::
196198

197-
$myMap->addPolyline(new Polyline(
199+
$map->addPolyline(new Polyline(
198200
points: [
199201
new Point(48.8566, 2.3522),
200202
new Point(45.7640, 4.8357),

src/Map/src/Polygon.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
final class Polygon implements Element
2222
{
2323
/**
24-
* @param array<array<Point>|array<array<Point>>> $points Points of the polygon. Each point can be a single Point or an array of Points.
25-
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
24+
* @param array<Point>|array<array<Point>> $points A list of point representing the polygon, or a list of paths (each path is an array of points) representing a polygon with holes.
25+
* @param array<string, mixed> $extra Extra data, can be used by the developer to store additional information and use them later JavaScript side
2626
*/
2727
public function __construct(
2828
private readonly array $points,
@@ -37,7 +37,7 @@ public function __construct(
3737
* Convert the polygon to an array representation.
3838
*
3939
* @return array{
40-
* points: array<array{lat: float, lng: float}|array<array{lat: float, lng: float}>>,
40+
* points: array<array{lat: float, lng: float}>|array<array{lat: float, lng: float}>,
4141
* title: string|null,
4242
* infoWindow: array<string, mixed>|null,
4343
* extra: array,
@@ -47,7 +47,9 @@ public function __construct(
4747
public function toArray(): array
4848
{
4949
return [
50-
'points' => array_map(fn ($pointOrList) => \is_array($pointOrList) ? array_map(fn (Point $point) => $point->toArray(), $pointOrList) : $pointOrList->toArray(), $this->points),
50+
'points' => current($this->points) instanceof Point
51+
? array_map(fn (Point $point) => $point->toArray(), $this->points)
52+
: array_map(fn (array $path) => array_map(fn (Point $point) => $point->toArray(), $path), $this->points),
5153
'title' => $this->title,
5254
'infoWindow' => $this->infoWindow?->toArray(),
5355
'extra' => $this->extra,
@@ -72,8 +74,9 @@ public static function fromArray(array $polygon): self
7274
throw new InvalidArgumentException('The "points" parameter is required.');
7375
}
7476

75-
$isSinglePoint = isset($polygon['points'][0]['lat'], $polygon['points'][0]['lng']);
76-
$polygon['points'] = array_map(fn ($pointOrList) => $isSinglePoint ? Point::fromArray($pointOrList) : array_map(Point::fromArray(...), $pointOrList), $polygon['points']);
77+
$polygon['points'] = isset($polygon['points'][0]['lat'], $polygon['points'][0]['lng'])
78+
? array_map(Point::fromArray(...), $polygon['points'])
79+
: array_map(fn(array $points) => array_map(Point::fromArray(...), $points), $polygon['points']);
7780

7881
if (isset($polygon['infoWindow'])) {
7982
$polygon['infoWindow'] = InfoWindow::fromArray($polygon['infoWindow']);

0 commit comments

Comments
 (0)