mostafaznv/nova-map-field
Composer 安装命令:
composer require mostafaznv/nova-map-field
包简介
Map Field for Laravel Nova
README 文档
README
Using this package, you can use spatial fields in Laravel Nova.
nova-map-field.mp4
I am on an open-source journey 🚀, and I wish I could solely focus on my development path without worrying about my financial situation. However, as life is not perfect, I have to consider other factors.
Therefore, if you decide to use my packages, please kindly consider making a donation. Any amount, no matter how small, goes a long way and is greatly appreciated. 🍺
Requirements:
- PHP 8.1 or higher
- Laravel 10.* or higher
Laravel Compatibility
| Laravel | PHP | Nova Map Field |
|---|---|---|
| ^8.0 - ^9.0 | ^8.0.2 | ^3.0 |
| ^10.0 - ^13.0 | ^8.1 | ^4.0 (latest) |
Installation
-
Install the package via composer:
composer require mostafaznv/nova-map-field
-
Publish config and assets:
php artisan vendor:publish --provider="Mostafaznv\NovaMapField\NovaMapFieldServiceProvider" -
Done
Usage
-
Create table with spatial fields
<?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(); }); } };
-
Add
HasSpatialtrait to model<?php namespace App\Models; use MatanYadaev\EloquentSpatial\Traits\HasSpatial; class Location extends Model { use HasSpatial; }
-
Define spatial columns of model
<?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 ]; }
-
Add map fields to resource
<?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'), ]; } }
-
Done
Map Field Methods
| method | Arguments | description |
|---|---|---|
| templateUrl | url string |
Specifies template of map |
| projection | projection string |
Specifies projection of map |
| srid | srid integer default: 0 |
Specifies SRID of map |
| defaultLatitude | latitude float |
Specifies latitude of map on page load |
| defaultLongitude | longitude float |
Specifies longitude of map on page load |
| zoom | zoom integer |
Specifies default map zoom |
| withoutZoomControl | status bool default: true |
Specifies whether zoom in/out button should display on map or not |
| withoutZoomSlider | status bool default: true |
Specifies whether zoom slider should display on map or not |
| withFullScreenControl | status bool default: true |
Specifies whether full screen button should display on map or not |
| mapHeight | height integer default: 400 |
Map's height |
| hideDetailButton | status bool default: true |
Specifies whether Show Details button should appear on detail pages or not |
| markerIcon | icon integer available: 1, 2, 3 |
Marker icon |
| withSearchBox | boolean |
Specifies whether map has search box or not |
| searchProvider | provider MapSearchProvider |
|
| searchProviderApiKey | apiKey string |
Specifies api key for search provider, if needed |
| withAutocompleteSearch | status bool default: true |
Specifies whether search results should load immediately or not |
| searchAutocompleteMinLength | minLength int |
Specifies the minimum number of characters to trigger search action |
| searchAutocompleteTimeout | timeout int |
Specifies the minimum number of ms to wait before triggering search action |
| searchLanguage | language string |
Specifies preferable language |
| searchPlaceholder | placeholder string |
|
| searchBoxType | type MapSearchBoxType |
Using this item, you can specify type of search box (button, or text-field |
| searchResultLimit | limit int |
Specifies limit of results |
| searchResultKeepOpen | status boolean |
Specifies whether the results keep opened |
| withTransformation | status boolean |
Specifies whether transport feature should be enable on polygons |
| transformScale | status boolean |
Using this method, you can enable/disable scaling features |
| transformRotate | status boolean |
Using this method, you can enable/disable rotating features |
| transformStretch | status boolean |
Using this method, you can enable/disable stretch option |
| requiredOnCreate | status bool default: true |
Makes field required on creation |
| requiredOnUpdate | status bool default: true |
Makes field required on update |
| default | $callback PointValue |
Set default value for map field. Note: Only works in MapPointField |
| capture | capture Capture experimental |
By employing this method, you can capture a screenshot reflecting the current state of the map field and save it to the filesystem |
Config Properties
| Method | Type | Default | Description |
|---|---|---|---|
| template-url | string | https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png |
Default Template URL. Must include {x}, {y} or {-y}, and {z} placeholders. |
| projection | string | EPSG:3857 |
Default projection of map |
| srid | int | 0 | Default SRID of map |
| default-latitude | bool | 0 | Default latitude of map |
| default-longitude | bool | 0 | Default longitude of map |
| zoom | int | 12 | Default zoom of map |
| controls.zoom-control | bool | true | Specifies if map should display zoom controls (zoom in/out buttons) or not |
| controls.zoom-slider | bool | true | Specifies if map should display zoom slider or not |
| controls.full-screen-control | bool | false | Specifies if map should display full screen button or not |
| controls.undo-control | bool | true | Specifies if map should display undo control or not (Only for Polygon and MultiPolygon) |
| controls.clear-map-control | bool | true | Specifies if map should display clear map control or not (Only for Polygon and MultiPolygon) |
| map-height | int | 400 | Specifies map height |
| icon | int | 1 | Specifies marker icon. available values: 1, 2, 3 |
| style.stroke-color | string | red | Using this property, you can specify stroke color of polygons or other shapes. Either in hexadecimal or as RGBA array |
| style.stroke-width | int | 2 | Width of the stroke (px) |
| style.fill-color | string | rgba(255, 0, 0, 0.4) | Using this property, you can specify filling color of polygons or other shapes. Either in hexadecimal or as RGBA array. |
| show-detail-button | bool | true | Specifies whether Show Details button should appear on detail pages or not |
| search.enable | bool | true | Using this item, you can toggle displaying search box on maps |
| search.provider | MapSearchProvider | OSM | Specifies search provider available providers: OSM, MAPQUEST, PHOTON, PELIAS, BING, OPENCAGE |
| search.api-key | string | '' | Specifies API key if required |
| search.autocomplete | bool | false | Using this item, you can toggle autocomplete feature for search box |
| search.autocomplete-min-length | int | 2 | The minimum number of characters to trigger search |
| search.autocomplete-timeout | int | 200 | The minimum number of ms to wait before triggering search action |
| search.language | string | en-US | Specifies preferable language |
| search.placeholder | string | Search for an address | Specifies placeholder for text input |
| search.box-type | MapSearchBoxType | TEXT_FIELD | Specifies type of search box. available types: BUTTON, TEXT_FIELD |
| search.limit | int | 5 | Specifies limit of results |
| search.keep-open | bool | false | Specifies whether the results keep opened |
| transform.enable | bool | true | Using this item, you can toggle transforming polygons maps |
| transform.scale | bool | true | Using this property, you can toggle scaling features |
| transform.scale | bool | true | Using this property, you can toggle rotating features |
| transform.stretch | bool | true | Using this property, you can enable/disable stretch option |
Capture Screenshot
Utilizing this method enables the capture of a screenshot that mirrors the current state of the map field, subsequently saving it to the filesystem. It is important to note that this feature is experimental and its performance may vary. The underlying mechanism operates by generating an image on the client's machine each time the client/admin modifies the map field state. Subsequently, this image is transmitted to the server, where it is then stored in the filesystem.
To enable this feature, you must first add the capture method to your map field. This method accepts a single argument, which is an instance of the Capture class.
<?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(), ]; } }
Note
Activating this feature is as straightforward as calling the static make function of Capture. Nevertheless, for those seeking to tailor the behavior of this functionality, alternative methods are available for customization.
Using Spatial Columns over Application
This package uses Laravel Eloquent Spatial under the hood. to use columns and querying them over the application, please read Laravel Eloquent Spatial documentation
Tricks
Transform Polygons
To transform polygons, You should press Alt (Option ⌥) button and drag that polygon everywhere you want.
Select Polygons
To select polygons (and modify them), You can press Alt (Option ⌥) button and then click on the polygon.
By pressing the Alt (Option ⌥) key, drawing mode will be disabled, and you can select every polygon you want.
Complete Example
<?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) ), ]; } }
Deployment
The map field uses a web worker that loads data from blob values, and if you have a strict Content-Security-Policy header (e.g. with default 'none'), you will need to give permission to load data via this method by adding a worker-src directive to your CSP:
worker-src 'self' blob:;
Migration
From 3.* to 4.*
- Support for
matanyadaev/laravel-eloquent-spatialversions 2 and 3 has been dropped. The package now exclusively supports version 4 and higher. - The
HasSpatialColumnstrait has been removed from the package. Instead, use theHasSpatialtrait from the laravel-eloquent-spatial package. - Both
MapSearchBoxTypeandMapSearchProvidercustom enums have been refactored and are now located in theMostafaznv\NovaMapField\Enumsnamespace, utilizing PHP 8.1 enums. This update affects:- The
searchBoxTypeandsearchProvidermethods across all map field types (MapPointField, MapPolygonField, MapMultiPolygonField) - The configuration file properties
search.box-typeandsearch.provider.
- The
I am on an open-source journey 🚀, and I wish I could solely focus on my development path without worrying about my financial situation. However, as life is not perfect, I have to consider other factors.
Therefore, if you decide to use my packages, please kindly consider making a donation. Any amount, no matter how small, goes a long way and is greatly appreciated. 🍺
License
This software is released under The MIT License (MIT).
Sponsors
mostafaznv/nova-map-field 适用场景与选型建议
mostafaznv/nova-map-field 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 106.17k 次下载、GitHub Stars 达 46, 最近一次更新时间为 2022 年 06 月 24 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「geocoder」 「map」 「nova」 「laravel」 「spatial」 「OpenLayers」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 mostafaznv/nova-map-field 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 mostafaznv/nova-map-field 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 mostafaznv/nova-map-field 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Laravel Nova card that shows you your system information.
A Laravel Nova card.
Maps in minutes. Powered by the Google Maps API.
Yii2 map input widget. Allows you to select geographcal coordinates via a human-friendly inteface.
A Laravel Nova package for publishable fields
A Laravel Nova package for translatable fields
统计信息
- 总下载量: 106.17k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 46
- 点击次数: 27
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-06-24