├── .gitignore
├── src
├── LatlongServiceProvider.php
├── Map
│ ├── Yandex.php
│ ├── AbstractMap.php
│ ├── Tencent.php
│ ├── Amap.php
│ ├── Baidu.php
│ └── Google.php
├── Extension.php
└── Latlong.php
├── composer.json
├── LICENSE
├── resources
└── views
│ └── latlong.blade.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | phpunit.phar
3 | /vendor
4 | composer.phar
5 | composer.lock
6 | *.project
7 | .idea/
--------------------------------------------------------------------------------
/src/LatlongServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadViewsFrom($extension->views(), 'laravel-admin-latlong');
22 |
23 | Admin::booting(function () {
24 | Form::extend('latlong', Latlong::class);
25 | Show\Field::macro('latlong', Extension::showField());
26 | });
27 | }
28 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel-admin-ext/latlong",
3 | "description": "Latitude & Longitude selector",
4 | "type": "library",
5 | "keywords": ["laravel-admin", "extension"],
6 | "homepage": "https://github.com/laravel-admin-ext/latlong",
7 | "license": "MIT",
8 | "authors": [
9 | {
10 | "name": "z-song",
11 | "email": "zosong@126.com"
12 | }
13 | ],
14 | "require": {
15 | "php": ">=7.0.0",
16 | "encore/laravel-admin": "~1.6"
17 | },
18 | "require-dev": {
19 | "phpunit/phpunit": "~6.0"
20 | },
21 | "autoload": {
22 | "psr-4": {
23 | "Encore\\Admin\\Latlong\\": "src/"
24 | }
25 | },
26 | "extra": {
27 | "laravel": {
28 | "providers": [
29 | "Encore\\Admin\\Latlong\\LatlongServiceProvider"
30 | ]
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Jens Segers
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/resources/views/latlong.blade.php:
--------------------------------------------------------------------------------
1 |
38 |
--------------------------------------------------------------------------------
/src/Map/Yandex.php:
--------------------------------------------------------------------------------
1 | getParams('zoom')}
28 | });
29 |
30 | var myPlacemark = new ymaps.Placemark([lat.val(), lng.val()], {
31 | }, {
32 | preset: 'islands#redDotIcon',
33 | draggable: true
34 | });
35 |
36 | myPlacemark.events.add(['dragend'], function (e) {
37 | lat.val(myPlacemark.geometry.getCoordinates()[0]);
38 | lng.val(myPlacemark.geometry.getCoordinates()[1]);
39 | });
40 |
41 | myMap.geoObjects.add(myPlacemark);
42 | });
43 |
44 | }
45 |
46 | init('{$id['lat']}{$id['lng']}');
47 | })();
48 | EOT;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Map/AbstractMap.php:
--------------------------------------------------------------------------------
1 | api = sprintf($this->api, $key);
32 | }
33 | }
34 |
35 | /**
36 | * @return array
37 | */
38 | public function getAssets()
39 | {
40 | return [$this->api];
41 | }
42 |
43 | public function getParams($field = null) {
44 | if($field) {
45 | return isset($this->params[$field]) ? $this->params[$field] : null;
46 | }
47 | return $this->params;
48 | }
49 |
50 | /**
51 | * Set true to automatically get the current position from the browser on page load
52 | * @param $bool
53 | * @return $this
54 | */
55 | public function setAutoPosition($bool) {
56 | $this->autoPosition = $bool;
57 | return $this;
58 | }
59 |
60 | public function setParams($params) {
61 | $this->params = $params;
62 | return $this;
63 | }
64 |
65 | /**
66 | * @param array $id
67 | * @param bool $autoPosition
68 | * @return string
69 | */
70 | abstract public function applyScript(array $id);
71 | }
--------------------------------------------------------------------------------
/src/Extension.php:
--------------------------------------------------------------------------------
1 | Map\Baidu::class,
19 | 'tencent' => Map\Tencent::class,
20 | 'amap' => Map\Amap::class,
21 | 'google' => Map\Google::class,
22 | 'yandex' => Map\Yandex::class,
23 | ];
24 |
25 | /**
26 | * @var Map\AbstractMap
27 | */
28 | protected static $provider;
29 |
30 | /**
31 | * @param string $name
32 | * @return Map\AbstractMap
33 | */
34 | public static function getProvider($name = '')
35 | {
36 | if (static::$provider) {
37 | return static::$provider;
38 | }
39 |
40 | $name = Extension::config('default', $name);
41 | $args = Extension::config("providers.$name", []);
42 |
43 | return static::$provider = new static::$providers[$name](...array_values($args));
44 | }
45 |
46 | /**
47 | * @return \Closure
48 | */
49 | public static function showField()
50 | {
51 | return function ($lat, $lng, $height = 300, $zoom = 16) {
52 |
53 | return $this->unescape()->as(function () use ($lat, $lng, $height, $zoom) {
54 |
55 | $lat = $this->{$lat};
56 | $lng = $this->{$lng};
57 | $id = ['lat' => 'lat', 'lng' => 'lng'];
58 | Admin::script(Extension::getProvider()
59 | ->setParams([
60 | 'zoom' => $zoom
61 | ])
62 | ->applyScript($id));
63 |
64 | return <<
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | HTML;
78 | });
79 | };
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/Map/Tencent.php:
--------------------------------------------------------------------------------
1 | getParams('zoom')}
29 | });
30 |
31 | var marker = new qq.maps.Marker({
32 | position: center,
33 | draggable: true,
34 | map: map
35 | });
36 |
37 | if( ! lat.val() || ! lng.val()) {
38 | var citylocation = new qq.maps.CityService({
39 | complete : function(result){
40 | map.setCenter(result.detail.latLng);
41 | marker.setPosition(result.detail.latLng);
42 | }
43 | });
44 |
45 | citylocation.searchLocalCity();
46 | }
47 |
48 | qq.maps.event.addListener(map, 'click', function(event) {
49 | marker.setPosition(event.latLng);
50 | });
51 |
52 | qq.maps.event.addListener(marker, 'position_changed', function(event) {
53 | var position = marker.getPosition();
54 | lat.val(position.getLat());
55 | lng.val(position.getLng());
56 | });
57 |
58 | var ap = new qq.maps.place.Autocomplete(document.getElementById("search-{$id['lat']}{$id['lng']}"));
59 |
60 | var searchService = new qq.maps.SearchService({
61 | map : map
62 | });
63 |
64 | qq.maps.event.addListener(ap, "confirm", function(res){
65 | searchService.search(res.value);
66 | });
67 | }
68 |
69 | init('{$id['lat']}{$id['lng']}');
70 | })();
71 | EOT;
72 | }
73 | }
--------------------------------------------------------------------------------
/src/Map/Amap.php:
--------------------------------------------------------------------------------
1 | getParams('zoom')},
21 | center: [lng.val() || 0, lat.val() || 0],//中心点坐标
22 | viewMode:'3D',//使用3D视图
23 | });
24 |
25 | var marker = new AMap.Marker({
26 | map: map,
27 | draggable: true,
28 | position: [lng.val() || 0, lat.val() || 0],
29 | })
30 |
31 | map.on('click', function(e) {
32 | marker.setPosition(e.lnglat);
33 |
34 | lat.val(e.lnglat.getLat());
35 | lng.val(e.lnglat.getLng());
36 | });
37 |
38 | marker.on('dragend', function (e) {
39 | lat.val(e.lnglat.getLat());
40 | lng.val(e.lnglat.getLng());
41 | });
42 |
43 | if( ! lat.val() || ! lng.val()) {
44 | map.plugin('AMap.Geolocation', function () {
45 | geolocation = new AMap.Geolocation();
46 | map.addControl(geolocation);
47 | geolocation.getCurrentPosition();
48 | AMap.event.addListener(geolocation, 'complete', function (data) {
49 | marker.setPosition(data.position);
50 |
51 | lat.val(data.position.getLat());
52 | lng.val(data.position.getLng());
53 | });
54 | });
55 | }
56 |
57 | AMap.plugin('AMap.Autocomplete',function(){
58 | var autoOptions = {
59 | input:"search-{$id['lat']}{$id['lng']}"
60 | };
61 | var autocomplete= new AMap.Autocomplete(autoOptions);
62 |
63 | AMap.event.addListener(autocomplete, "select", function(data){
64 | map.setZoomAndCenter(18, data.poi.location);
65 | marker.setPosition(data.poi.location);
66 | lat.val(data.poi.location.lat);
67 | lng.val(data.poi.location.lng);
68 | });
69 | });
70 | }
71 |
72 | init('map_{$id['lat']}{$id['lng']}');
73 | })();
74 | EOT;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 经纬度选择器/Latitude and longitude selector
2 | ======
3 |
4 | 这个扩展用来帮助你在form表单中选择经纬度,用来替代`Laravel-admin`中内置的`Form\Field\Map`组件, 组件支持的地图包括`Google map`、`百度地图`、`高德地图`、`腾讯地图`、`Yandex map`.
5 |
6 | This extension is used to help you select the latitude and longitude in the form, which is used to replace the `Laravel-admin` built in `Form\Field\Map` component. The supported maps include `Google map`, `Baidu map`, `AMap`, `Tencent Map`, `Yandex map`.
7 |
8 | ## Installation
9 |
10 | ```bash
11 | // For laravel-admin 1.x
12 | composer require laravel-admin-ext/latlong:1.x -vvv
13 |
14 | // For laravel-admin 2.x
15 | composer require laravel-admin-ext/latlong:2.x -vvv
16 | ```
17 |
18 | ## Configuration
19 |
20 | Open `config/admin.php` and add the following configuration to the extensions section:
21 |
22 | ```php
23 |
24 | 'extensions' => [
25 |
26 | 'latlong' => [
27 |
28 | // Whether to enable this extension, defaults to true
29 | 'enable' => true,
30 |
31 | // Specify the default provider
32 | 'default' => 'google',
33 |
34 | // According to the selected provider above, fill in the corresponding api_key
35 | 'providers' => [
36 |
37 | 'google' => [
38 | 'api_key' => '',
39 | ],
40 |
41 | 'yandex' => [
42 | 'api_key' => '',
43 | ],
44 |
45 | 'baidu' => [
46 | 'api_key' => 'xck5u2lga9n1bZkiaXIHtMufWXQnVhdx',
47 | ],
48 |
49 | 'tencent' => [
50 | 'api_key' => 'VVYBZ-HRJCX-NOJ4Z-ZO3PU-ZZA2J-QPBBT',
51 | ],
52 |
53 | 'amap' => [
54 | 'api_key' => '3693fe745aea0df8852739dac08a22fb',
55 | ],
56 | ]
57 | ]
58 | ]
59 |
60 | ```
61 |
62 | ## Usage
63 |
64 | Suppose you have two fields `latitude` and `longitude` in your table that represent latitude and longitude, then use the following in the form:
65 |
66 | ```php
67 | $form->latlong('latitude', 'longitude', 'Position');
68 |
69 | // Set the map height
70 | $form->latlong('latitude', 'longitude', 'Position')->height(500);
71 |
72 | // Set the map zoom
73 | $form->latlong('latitude', 'longitude', 'Position')->zoom(16);
74 |
75 | // Set default position
76 | $form->latlong('latitude', 'longitude', 'Position')->default(['lat' => 90, 'lng' => 90]);
77 | ```
78 |
79 | Use in show page
80 |
81 | ```php
82 | $show->field('Position')->latlong('lat_column', 'long_column', $height = 400, $zoom = 16);
83 | ```
84 |
85 | ## Donate
86 |
87 | 如果觉得这个项目帮你节约了时间,不妨支持一下;)
88 |
89 | 
90 |
91 | License
92 | ------------
93 | Licensed under [The MIT License (MIT)](LICENSE).
94 |
--------------------------------------------------------------------------------
/src/Map/Baidu.php:
--------------------------------------------------------------------------------
1 | getParams('zoom')});
21 | map.enableScrollWheelZoom(true);
22 |
23 | var marker = new BMap.Marker(point);
24 | map.addOverlay(marker);
25 | marker.enableDragging();
26 |
27 | if( ! lat.val() || ! lng.val()) {
28 | var geolocation = new BMap.Geolocation();
29 | geolocation.getCurrentPosition(function(e){
30 | if(this.getStatus() == BMAP_STATUS_SUCCESS){
31 | map.panTo(e.point);
32 | marker.setPosition(e.point);
33 |
34 | lat.val(e.point.lat);
35 | lng.val(e.point.lng);
36 |
37 | }
38 | else {
39 | console.log('failed'+this.getStatus());
40 | }
41 | },{enableHighAccuracy: true})
42 | }
43 |
44 | map.addEventListener("click", function(e){
45 | marker.setPosition(e.point);
46 | lat.val(e.point.lat);
47 | lng.val(e.point.lng);
48 | });
49 |
50 | marker.addEventListener("dragend", function(e){
51 | lat.val(e.point.lat);
52 | lng.val(e.point.lng);
53 | });
54 |
55 | var ac = new BMap.Autocomplete(
56 | {"input" : "search-{$id['lat']}{$id['lng']}"
57 | ,"location" : map
58 | });
59 |
60 | var address;
61 | ac.addEventListener("onconfirm", function(e) { //鼠标点击下拉列表后的事件
62 | var _value = e.item.value;
63 | address = _value.province + _value.city + _value.district + _value.street + _value.business;
64 | setPlace();
65 | });
66 |
67 | function setPlace(){
68 | function myFun(){
69 | var pp = local.getResults().getPoi(0).point;
70 | map.centerAndZoom(pp, {$this->getParams('zoom')});
71 |
72 | marker.setPosition(pp);
73 | lat.val(pp.lat);
74 | lng.val(pp.lng);
75 | }
76 | var local = new BMap.LocalSearch(map, {
77 | onSearchComplete: myFun
78 | });
79 | local.search(address);
80 | }
81 | }
82 |
83 | init('map_{$id['lat']}{$id['lng']}');
84 |
85 | })();
86 | EOT;
87 | }
88 | }
--------------------------------------------------------------------------------
/src/Latlong.php:
--------------------------------------------------------------------------------
1 | Extension::getProvider()->getAssets()];
48 | }
49 |
50 | /**
51 | * Latlong constructor.
52 | *
53 | * @param string $column
54 | * @param array $arguments
55 | */
56 | public function __construct($column, $arguments)
57 | {
58 | $this->column['lat'] = (string)$column;
59 | $this->column['lng'] = (string)$arguments[0];
60 |
61 | array_shift($arguments);
62 |
63 | $this->label = $this->formatLabel($arguments);
64 | $this->id = $this->formatId($this->column);
65 | }
66 |
67 | /**
68 | * Set map height.
69 | *
70 | * @param int $height
71 | * @return $this
72 | */
73 | public function height(int $height)
74 | {
75 | $this->height = $height;
76 |
77 | return $this;
78 | }
79 |
80 |
81 | /**
82 | * Set map zoom.
83 | *
84 | * @param int $zoom
85 | * @return $this
86 | */
87 | public function zoom(int $zoom)
88 | {
89 | $this->zoom = $zoom;
90 |
91 | return $this;
92 | }
93 |
94 | /**
95 | * Set true to automatically get the current position from the browser on page load
96 | * @param $bool
97 | * @return Latlong
98 | */
99 | public function setAutoPosition($bool) {
100 | $this->autoPosition = $bool;
101 | return $this;
102 | }
103 |
104 | /**
105 | * {@inheritdoc}
106 | *
107 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
108 | */
109 | public function render()
110 | {
111 | $this->script = Extension::getProvider()
112 | ->setParams([
113 | 'zoom' => $this->zoom
114 | ])
115 | ->setAutoPosition($this->autoPosition)
116 | ->applyScript($this->id);
117 |
118 | $variables = [
119 | 'height' => $this->height,
120 | 'provider' => Extension::config('default'),
121 | ];
122 |
123 | $this->addVariables($variables);
124 |
125 | return parent::fieldRender();
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/Map/Google.php:
--------------------------------------------------------------------------------
1 | autoPosition)?'1':'0';
18 | return <<getParams('zoom')},
28 | center: LatLng,
29 | panControl: false,
30 | zoomControl: true,
31 | scaleControl: true,
32 | mapTypeId: google.maps.MapTypeId.ROADMAP
33 | }
34 |
35 | var container = document.getElementById("map_"+name);
36 | var map = new google.maps.Map(container, options);
37 |
38 | if (navigator.geolocation && {$autoPosition}) {
39 | navigator.geolocation.getCurrentPosition(function(position) {
40 | var pos = {
41 | lat: position.coords.latitude,
42 | lng: position.coords.longitude
43 | };
44 | map.setCenter(pos);
45 | marker.setPosition(pos);
46 |
47 | lat.val(position.coords.latitude);
48 | lng.val(position.coords.longitude);
49 |
50 | }, function() {
51 |
52 | });
53 | }
54 |
55 | var marker = new google.maps.Marker({
56 | position: LatLng,
57 | map: map,
58 | title: 'Drag Me!',
59 | draggable: true
60 | });
61 |
62 | google.maps.event.addListener(marker, "position_changed", function(event) {
63 | var position = marker.getPosition();
64 |
65 | lat.val(position.lat());
66 | lng.val(position.lng());
67 | });
68 |
69 | google.maps.event.addListener(map, 'click', function(event) {
70 | marker.setPosition(event.latLng);
71 | });
72 |
73 | var autocomplete = new google.maps.places.Autocomplete(
74 | document.getElementById("search-{$id['lat']}{$id['lng']}")
75 | );
76 | autocomplete.bindTo('bounds', map);
77 |
78 | google.maps.event.addListener(autocomplete, 'place_changed', function() {
79 | var place = autocomplete.getPlace();
80 | var location = place.geometry.location;
81 |
82 | if (place.geometry.viewport) {
83 | map.fitBounds(place.geometry.viewport);
84 | } else {
85 | map.setCenter(location);
86 | map.setZoom(18);
87 | }
88 |
89 | marker.setPosition(location);
90 |
91 | lat.val(location.lat());
92 | lng.val(location.lng());
93 | });
94 | }
95 |
96 | init('{$id['lat']}{$id['lng']}');
97 | })();
98 | EOT;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------