mostafaznv/nova-map-field

Laravel Nova 地图字段

4.0.3 2024-09-04 17:46 UTC

README

License Packagist Downloads Latest Version on Packagist

使用此包,您可以在 Laravel Nova 中使用空间字段。

nova-map-field.mp4

我在开源之旅中🚀,希望我能专注于我的开发路径,而不必担心我的经济状况。然而,生活并不完美,我必须考虑其他因素。

因此,如果您决定使用我的包,请考虑慷慨捐赠。任何金额,无论大小,都意义重大,非常感谢。🍺

Donate

要求

  • PHP 8.1 或更高版本
  • Laravel 10.* 或更高版本

Laravel 兼容性

安装

  1. 通过 composer 安装包
    composer require mostafaznv/nova-map-field
  2. 发布配置和资产
    php artisan vendor:publish --provider="Mostafaznv\NovaMapField\NovaMapFieldServiceProvider"
  3. 完成

使用方法

  1. 创建具有空间字段的表
    <?php
    
    return new class extends Migration
    {
        public function up()
        {
            Schema::create('locations', function (Blueprint $table) {
                $table->id();
                $table->string('title', 150);
                
                # laravel 10
                $table->point('location')->nullable();
                $table->polygon('area')->nullable();
                $table->multiPolygon('areas')->nullable();
                
                # laravel 11 and higher
                $table->geometry('location', subtype: 'point')->nullable();
                $table->geometry('area', subtype: 'polygon')->nullable();
                $table->geometry('areas', subtype: 'multipolygon')->nullable();
    
                $table->timestamps();
            });
        }
    };
  2. HasSpatial 特性添加到模型中
    <?php
    
    namespace App\Models;
    
    use MatanYadaev\EloquentSpatial\Traits\HasSpatial;
    
    
    class Location extends Model
    {
        use HasSpatial;
    }
  3. 定义模型的空间列
    <?php
    
    namespace App\Models;
    
    use MatanYadaev\EloquentSpatial\Objects\MultiPolygon;
    use MatanYadaev\EloquentSpatial\Objects\Point;
    use MatanYadaev\EloquentSpatial\Objects\Polygon;
    use MatanYadaev\EloquentSpatial\Traits\HasSpatial;
    
    
    class Location extends Model
    {
        use HasSpatial;
    
        protected $casts = [
            'location' => Point::class,
            'area'     => Polygon::class,
            'areas'    => MultiPolygon::class
        ];
    }
  4. 将地图字段添加到资源中
    <?php
    
    namespace App\Nova\Resources;
    
    use Mostafaznv\NovaMapField\Fields\MapMultiPolygonField;
    use Mostafaznv\NovaMapField\Fields\MapPointField;
    use Mostafaznv\NovaMapField\Fields\MapPolygonField;
    
    
    class Location extends Resource
    {
        public function fields(Request $request): array
        {
            return [
                MapPointField::make('location'),
                MapPolygonField::make('area'),
                MapMultiPolygonField::make('areas'),
            ];
        }
    }
  5. 完成

地图字段方法

配置属性

捕获屏幕截图

利用此方法可以捕获反映当前地图字段状态的屏幕截图,并将其保存到文件系统。请注意,此功能是 实验性 的,其性能可能有所不同。底层机制是通过在客户端/管理员修改地图字段状态时在客户端机器上生成图像来操作的。随后,此图像被发送到服务器,然后存储在文件系统中。

要启用此功能,您必须首先将 capture 方法添加到地图字段。此方法接受一个参数,即 Capture 类的实例。

<?php

namespace App\Nova\Resources;

use App\Nova\Resource;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Image;
use App\Models\Location as Model;
use Mostafaznv\NovaMapField\DTOs\Capture;
use Mostafaznv\NovaMapField\Fields\MapPointField;

class Location extends Resource
{
    public static string $model = Model::class;

    public function fields(Request $request): array
    {
        return [
            ID::make()->sortable(),

            MapPointField::make(trans('Location'), 'location')
                ->capture(
                     Capture::make('location_screenshot', 600, 600)
                        ->disk('location')
                        ->maxZoom(9)
                        ->padding([10, 10, 10, 10])
                        ->nearest(true)
                        ->prunable(true)
                ),

            Image::make(trans('Location Screenshot'), 'location_screenshot')
                ->disk('location')
                ->prunable()
                ->exceptOnForms(),
        ];
    }
}

注意

激活此功能就像调用 Capture 的静态 make 函数一样简单。然而,对于那些想要定制此功能行为的人来说,还有其他方法可供选择。

在应用程序中使用空间列

此包在底层使用 Laravel Eloquent Spatial。要使用列并在应用程序中进行查询,请阅读 Laravel Eloquent Spatial 文档

技巧

变换多边形

要变换多边形,您应该按 Alt (Option ) 键并拖动该多边形到您想要的位置。

选择多边形

要选择多边形(并修改它们),您可以按 Alt (Option ) 键,然后单击多边形。通过按 Alt (Option ) 键,绘制模式将被禁用,您可以选择您想要的所有多边形。

完整示例

<?php

namespace App\Nova\Resources;

use App\Nova\Resource;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use App\Models\Location as Model;
use Mostafaznv\NovaMapField\DTOs\Capture;
use Mostafaznv\NovaMapField\DTOs\PointValue;
use Mostafaznv\NovaMapField\Enums\MapSearchBoxType;
use Mostafaznv\NovaMapField\Enums\MapSearchProvider;
use Mostafaznv\NovaMapField\Fields\MapPointField;

class Location extends Resource
{
    public static string $model = Model::class;

    public function fields(Request $request): array
    {
        return [
            ID::make()->sortable(),

            Text::make('Title')
                ->sortable()
                ->rules('required', 'max:255'),
                
            MapPointField::make(trans('Location'), 'location')
                ->templateUrl('https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png')
                ->projection('EPSG:3857')
                ->srid(3857)
                ->defaultLatitude(35.6978527)
                ->defaultLongitude(51.4037269)
                ->zoom(14)
                ->withoutZoomControl()
                ->withoutZoomSlider()
                ->withoutUndoControl()
                ->withFullScreenControl()
                ->mapHeight(360)
                ->hideDetailButton(false)
                ->markerIcon(3)
                ->searchProvider(MapSearchProvider::OSM)
                ->searchProviderApiKey('api-key')
                ->withAutocompleteSearch()
                ->searchAutocompleteMinLength(4)
                ->searchAutocompleteTimeout(500)
                ->searchLanguage('fa-IR')
                ->searchPlaceholder('Placeholder ...')
                ->searchBoxType(MapSearchBoxType::BUTTON)
                ->searchResultLimit(3)
                ->searchResultKeepOpen(true)
                ->withTransformation()
                ->transformScale()
                ->transformRotate()
                ->transformStretch()
                ->required()
                ->requiredOnCreate()
                ->requiredOnUpdate()
                ->stacked()
                ->capture(
                    Capture::make('location_screenshot', 600, 600)
                        ->disk('location')
                        ->maxZoom(9)
                        ->padding([10, 10, 10, 10])
                        ->nearest(true)
                        ->prunable(true)
                    
                )
                ->default(
                    PointValue::make(51.5887845, 4.7760237)
                ),
        ];
    }
}

部署

地图字段使用一个加载来自 blob 值的数据的 Web Worker,如果您有一个严格的内容安全策略头(例如,使用 default 'none'),您需要通过在您的 CSP 中添加一个 worker-src 指令来允许通过此方法加载数据

worker-src 'self' blob:;

迁移

从 3.* 到 4.*

  • 已删除对 matanyadaev/laravel-eloquent-spatial 版本 2 和 3 的支持。该包现在仅支持版本 4 及更高版本。
  • 已从包中删除 HasSpatialColumns 特性。相反,使用来自 laravel-eloquent-spatial 包的 HasSpatial 特性。
  • 自定义枚举 MapSearchBoxTypeMapSearchProvider 都已重构,现在位于 Mostafaznv\NovaMapField\Enums 命名空间中,使用 PHP 8.1 枚举。这次更新影响以下内容:
    • 所有地图字段类型(MapPointField、MapPolygonField、MapMultiPolygonField)中的 searchBoxTypesearchProvider 方法。
    • 配置文件属性 search.box-typesearch.provider

我在开源之旅中🚀,希望我能专注于我的开发路径,而不必担心我的经济状况。然而,生活并不完美,我必须考虑其他因素。

因此,如果您决定使用我的包,请考虑慷慨捐赠。任何金额,无论大小,都意义重大,非常感谢。🍺

Donate

许可证

本软件发布在 MIT 许可证 (MIT) 下。

赞助商

JetBrains Logo (Main) logo