Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Map] markers, polygons and polylines removal #2547

Open
wants to merge 1 commit into
base: 2.x
Choose a base branch
from

Conversation

sblondeau
Copy link
Contributor

@sblondeau sblondeau commented Feb 2, 2025

Q A
Bug fix? no
New feature? yes
Issues Fix #...
License MIT

Add new methods to remove markers, polygons or polylines (map elements)
Map elements will be store in SplObjectStorage instead of arrays.

When create a map element, you can now add an optional identfier (string).
New methods getMarker(string identifier), getPolygon(string identifier) and getPolyline(string $identifier) car retreive a map element from its identfiier.

example
$departureMarker = new Marker (
position: new Point(45.7640, 4.8357),
title: 'Lyon',
identifier: 'departure'
)

$map->addMarker($departureMarker);

// remove marker with
$map->removeMarker($departureMarker)
// or 
$map->removeMarker($map->getMarker('departure'));

@sblondeau sblondeau requested a review from Kocal as a code owner February 2, 2025 15:03
@carsonbot carsonbot added Status: Needs Review Needs to be reviewed Feature New Feature Map labels Feb 2, 2025
Copy link
Member

@Kocal Kocal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sblondeau and thanks for your suggestion, I was waiting for someone to open it! :D

It's a very, very good start, but there are still things to refactor and simplify:

  1. I believe Map::remove*() methods must accept Marker|string $markerOrId as parameter, so we can remove methods Map::get*()
  2. Map::get*() methods do not really make sense to me, since there is no modifiers on Marker/Polygon/Polyline. Once you construct them, you can't alter them, so not point for Map::get*().
  3. Some architecture things can be improved, see review comments
  4. Types definitions in assets/ must be updated to, since you added a new property identifier (which can be shortened and changed to id)
  5. Also, please apply Fapbot's suggestions

Thanks, and do not hesitate if necessary! :)



## 2.23
- Add property `$identifier` to marker, polygon and polyline
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Add property `$identifier` to marker, polygon and polyline
- Add property `$identifier` to `Marker`, `Polygon` and `Polyline` constructors

Comment on lines +142 to +161
You can remove markers, polygons and polylines from a map using the ``removeMarker(Marker $marker)``, ``removePolyline(Polyline $polyline)`` and ``removePolygon(Polygon $polygon)`` methods::

When you create Marker, Polygon or Polyne, you can add an identifier in construct :

$departureMarker = new Marker (
position: new Point(45.7640, 4.8357),
title: 'Lyon',
identifier: 'departure'
)

then retrieve the marker with ``Map::getMarker(string $identifier)``, also works with ``Map::getPolygon(string $identifier)`` and ``Map::getPolyline(string $identifier)``. It can be useful to remove an element from its identifier.

$map->addMarker($departureMarker);

// remove marker with
$map->removeMarker($departureMarker)
// or
$map->removeMarker($map->getMarker('departure'));


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You can remove markers, polygons and polylines from a map using the ``removeMarker(Marker $marker)``, ``removePolyline(Polyline $polyline)`` and ``removePolygon(Polygon $polygon)`` methods::
When you create Marker, Polygon or Polyne, you can add an identifier in construct :
$departureMarker = new Marker (
position: new Point(45.7640, 4.8357),
title: 'Lyon',
identifier: 'departure'
)
then retrieve the marker with ``Map::getMarker(string $identifier)``, also works with ``Map::getPolygon(string $identifier)`` and ``Map::getPolyline(string $identifier)``. It can be useful to remove an element from its identifier.
$map->addMarker($departureMarker);
// remove marker with
$map->removeMarker($departureMarker)
// or
$map->removeMarker($map->getMarker('departure'));
It is possible to remove elements like ``Marker``, ``Polygon`` and ``Polyline`` instances by using methods ``Map::remove*()``::
// Add elements
$map->addMarker($marker = new Marker(/* ... */));
$map->addPolygon($polygon = new Polygon(/* ... */));
$map->addPolyline($polyline = new Polyline(/* ... */));
// And later, remove those elements
$map->removeMarker($marker);
$map->removePolygon($polygon);
$map->removePolyline($polyline);
If unfortunately you were unable to store an element instance, you can still remove them by passing the identifier string::
$map = new Map(/* ... */);
// Add elements
$map->addMarker(new Marker(identifier: 'my-marker', /* ... */));
$map->addPolygon(new Polygon(identifier: 'my-polygon', /* ... */));
$map->addPolyline(new Polyline(identifier: 'my-marker', /* ... */));
// And later, remove those elements
$map->removeMarker('my-marker');
$map->removePolygon('my-polygon');
$map->removePolyline('my-marker');

@@ -29,19 +30,18 @@ public function __construct(
/**
* @var array<Marker>
*/
private array $markers = [],
private SplObjectStorage $markers = new SplObjectStorage(),
Copy link
Member

@Kocal Kocal Feb 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a nice improvement, but I would like to see this logic (with methods *fromArray() and *toArray()) extracted from Map to an other class.

Something like:

  • abstract class Elements, with methods like add, remove, toArray and fromArray
  • class Markers extends Elements
  • class Polygons extends Elements
  • class Polylines extends Elements

Anyway, changing things like that is a BC for users using new Map(markers: [new Marker()]:

We can change it to this, which is BC compatbile:

Suggested change
private SplObjectStorage $markers = new SplObjectStorage(),
array $markers = [],

Then, add a new property private Markers $markers.

Comment on lines +90 to +99
public function getMarker(string $identifier): ?Marker
{
foreach ($this->markers as $marker) {
if ($this->markers->offsetGet($marker) === $identifier) {
return $marker;
}
}

return null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove (and similar methods too)

Comment on lines +109 to 120
public function removeMarker(?Marker $marker): self
{
if ($marker === null) {
return $this;
}

if ($this->markers->contains($marker)) {
$this->markers->detach($marker);
}

return $this;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To apply to similar methods too:

Suggested change
public function removeMarker(?Marker $marker): self
{
if ($marker === null) {
return $this;
}
if ($this->markers->contains($marker)) {
$this->markers->detach($marker);
}
return $this;
}
public function removeMarker(Marker|string $markerOrId): self
{
$this->markers->remove($markerOrId);
return $this;
}

Comment on lines +209 to +268
private function markersToArray(): array
{
foreach ($this->markers as $marker) {
$markers[] = $marker->toArray();
}

return $markers ?? [];
}

private static function markersFromArray(array $markers): SplObjectStorage
{
$markerObjects = new SplObjectStorage();
foreach ($markers as $marker) {
$markerObject = Marker::fromArray($marker);
$markerObjects->attach($markerObject, $markerObject->identifier);
}

return $markerObjects;
}

private function polygonsToArray(): array
{
foreach ($this->polygons as $polygon) {
$polygons[] = $polygon->toArray();
}

return $polygons ?? [];
}

private static function polygonsFromArray(array $polygons): SplObjectStorage
{
$polygonObjects = new SplObjectStorage();
foreach ($polygons as $polygon) {
$polygonObject = Polygon::fromArray($polygon);
$polygonObjects->attach($polygonObject, $polygonObject->identifier);
}

return $polygonObjects;
}

private function polylinesToArray(): array
{
foreach ($this->polylines as $polyline) {
$polylines[] = $polyline->toArray();
}

return $polylines ?? [];
}

private static function polylinesFromArray(array $polylines): SplObjectStorage
{
$polylineObjects = new SplObjectStorage();
foreach ($polylines as $polyline) {
$polylineObject = Polyline::fromArray($polyline);
$polylineObjects->attach($polylineObject, $polylineObject->identifier);
}

return $polylineObjects;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remove / externalize into Elements class

@@ -159,23 +296,23 @@ public static function fromArray(array $map): self
$map['fitBoundsToMarkers'] = false;
}

$map['markers'] ??= [];
$map['markers'] ??= new SplObjectStorage();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be reverted, $map['markers'] has not the same goal than Map::$markers. Same thing for similar code below

if (!\is_array($map['markers'])) {
throw new InvalidArgumentException('The "markers" parameter must be an array.');
}
$map['markers'] = array_map(Marker::fromArray(...), $map['markers']);
$map['markers'] = self::markersFromArray($map['markers']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$map['markers'] = self::markersFromArray($map['markers']);
$map['markers'] = Markers::fromArray($map['markers']);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And same below

public ?string $title = null,
public ?InfoWindow $infoWindow = null,
public array $extra = [],
public ?string $identifier = null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public ?string $identifier = null,
public ?string $id = null,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for other elements

@@ -47,6 +49,7 @@ public function toArray(): array
'title' => $this->title,
'infoWindow' => $this->infoWindow?->toArray(),
'extra' => $this->extra,
'identifier' => $this->identifier,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'identifier' => $this->identifier,
'id' => $this->id,

You must also update TypeScript types definition to reflect this change.

@carsonbot carsonbot added Status: Needs Work Additional work is needed and removed Status: Needs Review Needs to be reviewed labels Feb 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New Feature Map Status: Needs Work Additional work is needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants