Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ux Map Laravel Package

symfony/ux-map

Symfony UX Map integrates interactive maps like Leaflet and Google Maps into Symfony apps, letting you render and configure maps with PHP and Twig.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require symfony/ux-map
    npm install @symfony/ux-map
    

    Ensure your importmap.json includes:

    {
      "imports": {
        "@symfony/ux-map": "node_modules/@symfony/ux-map/dist"
      }
    }
    
  2. Basic Twig Usage:

    <twig:ux:map
        id="map"
        center="{{ [48.856613, 2.352222] }}"
        zoom="12"
        renderer="leaflet"
    />
    
  3. First Map Interaction (PHP):

    use Symfony\UX\Map\Map;
    use Symfony\UX\Map\Point;
    use Symfony\UX\Map\Marker;
    
    $map = new Map();
    $map->addMarker(new Marker(
        new Point(48.856613, 2.352222),
        'Paris'
    ));
    return $this->render('map.html.twig', ['map' => $map]);
    
  4. Live Component Integration:

    use Symfony\UX\Map\ComponentWithMapTrait;
    
    class MapComponent extends AbstractController
    {
        use ComponentWithMapTrait;
    
        public function index(): Response
        {
            $this->getMap()->addMarker(new Marker(
                new Point(48.856613, 2.352222),
                'Paris'
            ));
            return $this->render('map_component.html.twig');
        }
    }
    

Implementation Patterns

Core Workflows

  1. Static Maps:

    • Use Twig components for one-off maps:
      <twig:ux:map
          id="static-map"
          center="{{ [lat, lng] }}"
          zoom="10"
          renderer="leaflet"
      >
          <twig:ux:map:marker
              point="{{ [lat, lng] }}"
              title="Location"
          />
      </twig:ux:map>
      
  2. Dynamic Maps (Live Components):

    • Extend ComponentWithMapTrait for real-time updates:
      class InteractiveMap extends AbstractController
      {
          use ComponentWithMapTrait;
      
          public function __construct()
          {
              $this->getMap()->addMarker(new Marker(
                  new Point(48.856613, 2.352222),
                  'Paris'
              ));
          }
      
          #[Route('/add-marker', name: 'add_marker')]
          public function addMarker(): Response
          {
              $this->getMap()->addMarker(new Marker(
                  new Point(48.853384, 2.348800),
                  'Eiffel Tower'
              ));
              return $this->render('interactive_map.html.twig');
          }
      }
      
  3. Geospatial Data Integration:

    • Fetch coordinates from a database (e.g., PostgreSQL/PostGIS) and render:
      $points = $entityManager->createQueryBuilder()
          ->select('e.latitude, e.longitude, e.name')
          ->from('App\Entity\Location', 'e')
          ->getQuery()
          ->getResult();
      
      foreach ($points as $point) {
          $map->addMarker(new Marker(
              new Point($point['latitude'], $point['longitude']),
              $point['name']
          ));
      }
      
  4. Custom Renderers:

    • Override default options via JavaScript events:
      this.element.addEventListener('ux:map:pre-connect', (event) => {
          event.detail.bridgeOptions = {
              attributionControl: false,
              zoomControl: false
          };
      });
      
  5. Clustering Markers:

    • Enable clustering for large datasets:
      $map->setClusteringAlgorithm(new GridClusteringAlgorithm());
      $map->addMarkers($markers);
      

Integration Tips

  1. Symfony UX 3.x Migration:

    • Replace deprecated render_map() with ux_map() Twig function:
      {{ ux_map({
          id: 'map',
          center: [48.856613, 2.352222],
          zoom: 12,
          renderer: 'leaflet'
      }) }}
      
  2. Live Component Best Practices:

    • Use fitBoundsToMarkers() for auto-zooming:
      $this->getMap()->fitBoundsToMarkers(true);
      
  3. Google Maps Integration:

    • Configure API key and map ID in config/packages/ux_map.yaml:
      ux_map:
          google_maps:
              default_map_id: 'YOUR_MAP_ID'
      
  4. Performance Optimization:

    • Remove unused markers dynamically:
      $this->getMap()->removeAllMarkers();
      $this->getMap()->addMarkers($filteredMarkers);
      
  5. Custom Icons:

    • Use SVG or URL-based icons:
      $marker = new Marker(
          new Point(48.856613, 2.352222),
          'Paris',
          new Icon('https://example.com/icon.svg')
      );
      

Gotchas and Tips

Common Pitfalls

  1. Deprecated Methods:

    • Avoid render_map() (use ux_map() instead).
    • Replace title with infoWindow for polygons/lines/circles.
  2. Live Component Quirks:

    • fitBoundsToMarkers may behave unexpectedly in Live Components. Explicitly disable it if needed:
      $this->getMap()->fitBoundsToMarkers(false);
      
  3. Renderer-Specific Options:

    • Google Maps and Leaflet have different option structures. Use bridgeOptions for renderer-specific configs:
      event.detail.bridgeOptions = {
          // Google Maps specific
          mapId: 'YOUR_MAP_ID'
      };
      
  4. Event Listener Conflicts:

    • Ensure JavaScript event listeners (e.g., ux:map:pre-connect) are registered after the map is initialized.
  5. Coordinate Precision:

    • Use DistanceCalculatorInterface for accurate distance measurements:
      $distance = (new HaversineDistanceCalculator())->calculate(
          new Point(48.856613, 2.352222),
          new Point(51.507351, -0.127758)
      );
      

Debugging Tips

  1. Console Logs:

    • Inspect ux:map:connect events for runtime options:
      this.element.addEventListener('ux:map:connect', (event) => {
          console.log('Map connected:', event.detail);
      });
      
  2. Twig Debugging:

    • Use {{ dump(map) }} to inspect map objects in Twig templates.
  3. Renderer-Specific Issues:

    • For Leaflet: Check browser console for missing tile layers or API errors.
    • For Google Maps: Verify API key and map ID are correctly configured.
  4. Live Component State:

    • Ensure Map objects are not recreated on every request. Use ComponentWithMapTrait for state persistence.

Extension Points

  1. Custom Renderers:

    • Extend AbstractRenderer to support new map providers (e.g., Mapbox):
      class MapboxRenderer extends AbstractRenderer
      {
          public function render(): string
          {
              // Custom Mapbox initialization logic
          }
      }
      
  2. Geospatial Utilities:

    • Use CoordinateUtils for coordinate conversions:
      $dms = CoordinateUtils::toDMS(48.856613);
      
  3. Event-Driven Extensions:

    • Listen to ux:map:marker:click for custom interactions:
      this.element.addEventListener('ux:map:marker:click', (event) => {
          console.log('Marker clicked:', event.detail.marker);
      });
      
  4. Configuration Overrides:

    • Override default map options globally via ux_map.yaml:
      ux_map:
          default_options:
              renderer: 'leaflet'
              zoom: 12
      
  5. Testing:

    • Use MapTestCase for unit testing:
      use Symfony\UX\Map\Tests\MapTestCase;
      
      class MyMapTest extends MapTestCase
      {
          public function testMarkerRendering(): void
          {
              $map = new Map();
              $map->addMarker(new Marker(new Point(0, 0), 'Test'));
              $this->assertHtmlContains($map->render(), 'Test');
          }
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table