Filament Google Maps

repository·v3·Indexed 43 days ago

https://github.com/cheesegrits/filament-google-maps

A Filament plugin for integrating Google Maps into the Filament admin panel. It provides a MapColumn for displaying static map images in tables, tools for geocoding and reverse geocoding database tables via CLI, and commands to scaffold map widgets and generate necessary Eloquent model code.

Tokens
8.5K
Snippets
42
Records
44
Agent score
55%

What's inside Filament Google Maps

  1. MapColumn expected state format

    v3

    The MapColumn requires the underlying data (the state) to represent a geographic coordinate. It accepts either:

    1. An associative array: ['lat' => 1.23, 'lng' => 4.56]
    2. A JSON string: '{"lat": 1.23, "lng": 4.56}'

    If the state is invalid or cannot be decoded, it defaults to ['lat' => 0, 'lng' => 0] to prevent errors.

  2. Use Drawing Controls and GeoJSON layers

    v3

    Enable users to draw shapes (markers, circles, polygons, polylines, rectangles) on the map.

    • drawingControl(): Enables the drawing toolbar.
    • drawingModes(): Specifies which shapes are allowed.
    • drawingField(): Specifies a field to store the resulting drawing coordinates (GeoJSON-ish).
    • geoJson(): Loads a GeoJSON layer onto the map from a file, URL, or raw string.
    • geoJsonContainsField(): Automatically updates a field with the properties of the GeoJSON polygon that contains the map marker.
    Map::make('map')
        ->drawingControl()
        ->drawingModes(['marker' => true, 'polygon' => true])
        ->drawingField('shapes_data')
        ->geoJson('layers/my_layer.json', 's3')
        ->geoJsonContainsField('selected_zone', 'id')
  3. Create a Filament Google Maps widget with make:filament-google-maps-widget

    v3

    Use the make:filament-google-maps-widget command to generate a new map widget class. This command automates the creation of the widget class and its corresponding Blade view, and it attempts to automatically wire up the model's latitude, longitude, and location attributes.

    Prerequisite: Your model must have the latitude and longitude attributes defined. If you haven't done this yet, run the fgm:model-code command and paste the resulting code into your model before running this command.

    Usage:

    php artisan make:filament-google-maps-widget {name?} {model?} {--R|resource=} {--M|map} {--T|table} {--F|force}

    Arguments:

    • name: The name of the widget class (e.g., DealershipMap).
    • model: The model the widget will use (e.g., Location or Maps/Dealership).

    Options:

    • --resource=: (Optional) The resource where the widget should be placed (e.g., LocationResource). If provided, the widget is created within the resource's directory structure.
    • --map: Specifies a simple map widget type.
    • --table: Specifies a map widget with an integrated table.
    • --force: Overwrites existing files if they already exist.

    Post-Creation Steps:

    If used within a Resource:

    1. Register the widget in your resource class using getWidgets().
    2. Register the widget in your resource page (e.g., ListRecords, ViewRecord, or ManageRecords) by adding it to either getHeaderWidgets() or getFooterWidgets().

    If used as a standalone widget (not in a resource):

    1. Move the generated file to your Livewire widgets directory (e.g., app/Http/Livewire/Widgets/).
    2. Invoke it in a Blade template using: @livewire('widgets.your_widget_name_in_snake_case').
    php artisan make:filament-google-maps-widget DealershipMap Location --resource=LocationResource
  4. Configure Google Maps Autocomplete

    v3

    Enable Google Places autocomplete by linking the map to another form field. When a user selects a place from the autocomplete menu, the map marker will automatically update to that location. You can customize the search types, the specific field to extract data from, and the allowed countries.

    Use autocomplete() to link a field, and optionally autocompleteReverse() to enable reverse geocoding (updating the linked field with the address when the marker is moved).

    Map::make('location')
        ->autocomplete('address_field', ['address', 'establishment'], 'formatted_address', ['US', 'CA'])
        ->autocompleteReverse()
  5. Generate model code for Filament Google Maps

    v3

    The filament-google-maps:model-code command generates the necessary PHP code for your Eloquent model to work seamlessly with the Filament Google Maps package. It produces computed attribute accessors and mutators, as well as the required static methods for the package to identify latitude, longitude, and the computed location field.

    To use this command, you can either provide all arguments via flags for a non-interactive experience or run it without arguments to be prompted for details.

    Key requirements for the generated code:

    • The lat and lng fields must exist in your database table as decimal columns.
    • The location field (the computed attribute) should not exist in your database schema; it is a virtual attribute used by Filament.
    • The location attribute must be included in your model's $fillable array.
    php artisan filament-google-maps:model-code MyModel --lat=latitude --lng=longitude --location=location
  6. Enable Geolocate features

    v3

    Add a button to the map that allows users to request their current location.

    • geolocate(): Adds the button to the map.
    • geolocateLabel(): Customizes the button text (defaults to 'Set Current Location').
    • geolocateOnLoad(): Automatically requests the user's location when the form loads. Use the always parameter to force this even if the field already has a state.
    Map::make('location')
        ->geolocate()
        ->geolocateLabel('Find Me')
        ->geolocateOnLoad(true, true)
  7. Use Reverse Geocoding to populate form fields

    v3

    You can automatically populate multiple form fields based on the map marker's location using reverse geocoding. The reverseGeocode() method accepts an associative array where the key is the form field name and the value is a format string using specific placeholders.

    Format Placeholders:

    • %n: Street Number
    • %S: Street Name
    • %L: City (Locality)
    • %D: City District (Sub-Locality)
    • %z: Zipcode (Postal Code)
    • %A1, %A2, %A3, %A4, %A5: Admin Level Names
    • %a1, %a2, %a3, %a4, %a5: Admin Level Codes
    • %C: Country
    • %c: Country Code
    Map::make('map')
        ->reverseGeocode([
            'street' => '%n %S',
            'city' => '%L',
            'state' => '%A1',
            'zip' => '%z',
        ])
  8. Add GeoJSON layers to MapEntry

    v3

    You can overlay GeoJSON data on a MapEntry using the geoJson() method. The component is flexible in how it consumes the data:

    1. Raw GeoJSON: Pass a string that starts with { or [.
    2. URL: Pass a full URL to a GeoJSON file.
    3. Local File: Pass a file path and specify the storage disk using the second argument (defaults to 'public').

    Example of using a local file on a specific disk:

    MapEntry::make()
        ->geoJson('layers/map-data.json', 's3')
    MapEntry::make()
        ->geoJson('layers/map-data.json', 's3')
  9. Use the Geocomplete field for address autocomplete

    v3

    The Geocomplete field provides a Google Maps address autocomplete input within Filament forms. It can be configured to handle simple strings or complex location states (arrays containing coordinates and addresses).

    use Cheesegrits\FilamentGoogleMaps\Fields\Geocomplete;
    
    Geocomplete::make('address')
  10. Add a 'Geolocate' button to the field

    v3

    The geolocate() method adds a suffix button to the field. When clicked, it requests the user's current browser location and uses reverse geocoding to fill the field with a formatted address.

    You can customize the icon used for this button with geolocateIcon().

    Geocomplete::make('address')
        ->geolocate()
        ->geolocateIcon('heroicon-s-location-marker')
  11. Display maps in Infolists using MapEntry

    v3

    Use MapEntry to display a Google Map in read-only Filament Infolist views. It allows you to visualize coordinates, zoom levels, and GeoJSON layers.

    Key Configuration Options

    • defaultLocation(Closure|array $location): Sets the initial center of the map. Accepts an array of [$lat, $lng] or ['lat' => $lat, 'lng' => $lng], or a closure returning one of these formats.
    • defaultZoom(Closure|int $defaultZoom): Sets the initial zoom level (typically between 1 and 20).
    • height(Closure|string $height): Sets the CSS height of the map container (e.g., '350px').
    • geoJson(Closure|string $file, Closure|string $disk = 'public'): Adds a GeoJSON layer. The $file can be a raw GeoJSON string (starting with { or [), a URL, or a path to a file on a specific storage disk.
    • geoJsonVisible(Closure|bool $visible): Determines if the GeoJSON layer is rendered visually. Useful for tracking polygons without displaying them.
    • mapControls(Closure|array $controls): Overrides or extends the default map controls (like zoomControl, fullscreenControl, etc.).
    MapEntry::make()
        ->defaultLocation(['lat' => 44.2171392, 'lng' => 15.3419776])
        ->defaultZoom(12)
        ->height('400px')
        ->geoJson('path/to/layers.json', 's3')
  12. Configure MapColumn appearance and behavior

    v3

    You can customize the MapColumn using several methods to control the map's visual properties and API behavior:

    • icon(string|Closure|null $icon): Sets a fully qualified URL to a PNG icon to be used as the marker pin.
    • type(string|Closure|null $type): Sets the map type. Allowed values are 'satellite', 'hybrid', 'roadmap', or 'terrain'. Defaults to 'roadmap'.
    • height(int|Closure $height): Sets the height in pixels.
    • width(int|string|Closure $width): Sets the width in pixels.
    • size(int|string|Closure $size): A convenience method that sets both width and height to the same pixel value.
    • zoom(int|Closure $zoom): Sets the zoom level (typically between 1 and 20).
    • extraImgAttributes(array|Closure $attributes): Provides an array of additional HTML attributes to apply to the <img> tag.
    • ttl(int|Closure $ttl): Sets the Time To Live (in seconds) for caching the image. The default is 30 days. Warning: Setting this too low can significantly increase Google Maps API costs.
    MapColumn::make('location')
        ->type('satellite')
        ->zoom(15)
        ->size(300)
        ->icon('https://example.com/marker.png')
        ->extraImgAttributes(['class' => 'rounded-lg shadow-md'])