├── .gitattributes ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml └── src └── FarhanWazir └── GoogleMaps ├── Containers └── isInsidePolygon.php ├── Facades └── GMapsFacade.php ├── GMaps.php ├── GMapsServiceProvider.php ├── Publishes ├── config │ └── googlemaps.php ├── database │ └── migrations │ │ └── create_gmaps_geocache_table.php └── public │ └── libs │ └── FarhanWazir │ └── GMaps │ └── markerclusterer.js └── example ├── Controllers └── MapController.php ├── Routes └── routes.php └── Views └── map.blade.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | /.idea 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.6 5 | - 5.7 6 | - 5.8 7 | - 5.9 8 | - hhvm 9 | 10 | before_script: 11 | - composer self-update 12 | - composer install --prefer-source --no-interaction --dev 13 | 14 | script: phpunit 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 1.2.5 - 1.5.0: 03 May 2016 4 | ### Added 5 | - Examples create 6 | - Configuration 7 | 8 | ### Changed 9 | - Class modifications 10 | - Installation instructions and usage ReadMe. 11 | 12 | ## 1.8.x - 2.1.1: 31 July 2016 13 | ### Added 14 | - Geofence 15 | - Database 16 | 17 | ### Changed 18 | - Added Geofence for server side check 19 | - Geo cache fixed 20 | - Added usage of geo-fence -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Creative Ideator. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Google Maps 2 | [![Rank](https://phppackages.org/p/farhanwazir/laravelgooglemaps/badge/rank.svg)](http://phppackages.org/p/farhanwazir/laravelgooglemaps) 3 | [![Total Downloads](https://poser.pugx.org/farhanwazir/laravelgooglemaps/d/total.svg)](https://packagist.org/packages/farhanwazir/laravelgooglemaps) 4 | [![Latest Stable Version](https://poser.pugx.org/farhanwazir/laravelgooglemaps/v/stable.svg)](https://packagist.org/packages/farhanwazir/laravelgooglemaps) 5 | [![Latest Unstable Version](https://poser.pugx.org/farhanwazir/laravelgooglemaps/v/unstable.svg)](https://packagist.org/packages/farhanwazir/laravelgooglemaps) 6 | [![License](https://poser.pugx.org/farhanwazir/laravelgooglemaps/license.svg)](https://packagist.org/packages/farhanwazir/laravelgooglemaps) 7 | 8 | This repo aims to use google map features in laravel 5.x. It is easy to use and flexible, you can just install this package and enjoy google map in your website and/or applications. 9 | 10 | 11 | ## Features 12 | 1. Localizing 13 | 2. Map Types 14 | 3. Custom Style 15 | 4. Makers 16 | 5. Info Window 17 | 6. Shapes 18 | 7. Symbols 19 | 8. Overlays 20 | 9. KML and GeoRSS 21 | 10. Traffic and Bicycling Layer 22 | 11. Geocoding Caches 23 | 12. Controls 24 | 13. Street View 25 | 14. Events 26 | 15. Reverse Geocoding 27 | 16. Travel Moding 28 | 17. Proxy 29 | 30 | ### Services & Libraries 31 | 1. Directions 32 | 2. Geocoding 33 | 3. Geometry 34 | 4. Drawing 35 | 5. Places 36 | 6. Autocomplete 37 | 7. Adsense 38 | 8. Geofence (For now only server side geofence available) 39 | 40 | ## Installation 41 | Add in composer.json 42 | ``` 43 | "require": { 44 | "farhanwazir/laravelgooglemaps": "^2.3" 45 | ---- 46 | } 47 | ``` 48 | Then 49 | ``` 50 | composer update 51 | ``` 52 | Or install via composer cli 53 | ``` 54 | composer require farhanwazir/laravelgooglemaps 55 | ``` 56 | 57 | Add service provider `config/app.php` 58 | ```php 59 | FarhanWazir\GoogleMaps\GMapsServiceProvider::class, 60 | ``` 61 | 62 | And finally add in the alias section `config/app.php` 63 | ```php 64 | 'GMaps' => FarhanWazir\GoogleMaps\Facades\GMapsFacade::class, 65 | ``` 66 | 67 | Now publish configuration file 68 | ```php 69 | php artisan vendor:publish --provider="FarhanWazir\GoogleMaps\GMapsServiceProvider" 70 | ``` 71 | 72 | ##Usage 73 | Example files are under FarhanWazir/GoogleMaps/Example: 74 | 75 | Controller Example; reference code for display method 76 | ```php 77 | /******** Custom Map Controls ********/ 78 | 79 | $leftTopControls = ['document.getElementById("leftTopControl")']; // values must be html or javascript element 80 | $this->gmap->injectControlsInLeftTop = $leftTopControls; // inject into map 81 | $leftCenterControls = ['document.getElementById("leftCenterControl")']; 82 | $this->gmap->injectControlsInLeftCenter = $leftCenterControls; 83 | $leftBottomControls = ['document.getElementById("leftBottomControl")']; 84 | $this->gmap->injectControlsInLeftBottom = $leftBottomControls; 85 | 86 | $bottomLeftControls = ['document.getElementById("bottomLeftControl")']; 87 | $this->gmap->injectControlsInBottomLeft = $bottomLeftControls; 88 | $bottomCenterControls = ['document.getElementById("bottomCenterControl")']; 89 | $this->gmap->injectControlsInBottomCenter = $bottomCenterControls; 90 | $bottomRightControls = ['document.getElementById("bottomRightControl")']; 91 | $this->gmap->injectControlsInBottomRight = $bottomRightControls; 92 | 93 | $rightTopControls = ['document.getElementById("rightTopControl")']; 94 | $this->gmap->injectControlsInRightTop = $rightTopControls; 95 | $rightCenterControls = ['document.getElementById("rightCenterControl")']; 96 | $this->gmap->injectControlsInRightCenter = $rightCenterControls; 97 | $rightBottomControls = ['document.getElementById("rightBottomControl")']; 98 | $this->gmap->injectControlsInRightBottom = $rightBottomControls; 99 | 100 | $topLeftControls = ['document.getElementById("topLeftControl")']; 101 | $this->gmap->injectControlsInTopLeft = $topLeftControls; 102 | $topCenterControls = ['document.getElementById("topCenterControl")']; 103 | $this->gmap->injectControlsInTopCenter = $topCenterControls; 104 | $topRightControls = ['document.getElementById("topRightControl")']; 105 | $this->gmap->injectControlsInTopRight = $topRightControls; 106 | 107 | /******** End Controls ********/ 108 | 109 | $config = array(); 110 | $config['map_height'] = "100%"; 111 | $config['center'] = 'Clifton, Karachi'; 112 | 113 | $this->gmap->initialize($config); // Initialize Map with custom configuration 114 | 115 | /*********** Marker Setup ***********/ 116 | $marker = array(); 117 | $marker['draggable'] = true; 118 | //Marker event dragend 119 | $marker['ondragend'] = ' 120 | iw_'. $this->gmap->map_name .'.close(); 121 | reverseGeocode(event.latLng, function(status, result, mark){ 122 | if(status == 200){ 123 | iw_'. $this->gmap->map_name .'.setContent(result); 124 | iw_'. $this->gmap->map_name .'.open('. $this->gmap->map_name .', mark); 125 | } 126 | }, this); 127 | '; 128 | $this->gmap->add_marker($marker); 129 | /*********** End Marker Setup ***********/ 130 | 131 | $map = $this->gmap->create_map(); // This object will render javascript files and map view; you can call JS by $map['js'] and map view by $map['html'] 132 | 133 | return view('map', ['map' => $map]); 134 | ``` 135 | 136 | Route Example 137 | ```php 138 | Route::get('/map', 'MapController@index'); 139 | 140 | Route::get('/', function(){ 141 | $config = array(); 142 | $config['center'] = 'New York, USA'; 143 | GMaps::initialize($config); 144 | $map = GMaps::create_map(); 145 | 146 | echo $map['js']; 147 | echo $map['html']; 148 | }); 149 | ``` 150 | 151 | View Example 152 | ```html 153 | 154 | 155 | {!! $map['js'] !!} 156 | 157 | 158 |
159 |
160 |
161 | This is Left Top Control. 162 |
163 |
164 | This is Left Center Control. 165 |
166 |
167 | This is Left Bottom Control. 168 |
169 |
170 | This is Bottom Right Control. 171 |
172 |
173 | This is Bottom Center Control. 174 |
175 |
176 | This is Bottom Left Control. 177 |
178 |
179 | This is Right Top Control. 180 |
181 |
182 | This is Right Center Control. 183 |
184 |
185 | This is Right Bottom Control. 186 |
187 |
188 | This is Top Left Control. 189 |
190 |
191 | This is Top Center Control. 192 |
193 |
194 | This is Top Right Control. 195 |
196 | {!! $map['html'] !!} 197 |
198 |
199 | 200 | 201 | ``` 202 | 203 | ### Geo-fence Example 204 | ```html 205 | $polygon = array("25.774,-80.190", "18.466,-66.118", "32.321,-64.757", "25.774,-80.190"); //start and end point should be same 206 | $latlngs = array("-12.043333,-77.028333", "-12.043333,-77.028333"); 207 | 208 | GMaps::isMarkerInsideGeofence($polygon, $latlngs); //both parameters should be in array 209 | //return will also in array with boolean values like: array(true, false) 210 | ``` 211 | 212 | # Contribution 213 | - Proxy feature by @grimseer - Nov 22, 2016 214 | - Fixed to load google api via https by @wissamdagher - Apr 04, 2017 215 | - Map full screen support by @wissamdagher - Jul 02, 2017 216 | - Facade namespace fixed by @drehimself - Aug 03, 2017 217 | - Fixed migration file name by @drehimself - Aug 03, 2017 218 | 219 | 220 | # Thank you for using! 221 | If you like it then click Fork! 222 | 223 | Contact me if any query or suggestion you have in support section. 224 | 225 | # Credits 226 | Library initiative: **BioStall** 227 | 228 | BioStall developed library for codeigniter originally, which you can found at http://biostall.com/laravel-google-maps-v3-api-package/ 229 | 230 | Conversion into Laravel from codeigniter by: **GeneaLabs** -- https://github.com/GeneaLabs/Phpgmaps (but it is incomplete) 231 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "farhanwazir/laravelgooglemaps", 3 | "description": "Laravel Google Map package for 5.x. You can use all google map features in laravel.", 4 | "license": "MIT", 5 | "keywords": [ 6 | "laravel", 7 | "gmap", 8 | "map", 9 | "google", 10 | "googlemap", 11 | "gmap" 12 | ], 13 | "authors": [ 14 | { 15 | "name": "Farhan Wazir", 16 | "email": "seejee1@gmail.com", 17 | "role": "Author" 18 | } 19 | ], 20 | "require": { 21 | "php": ">=5.6.0", 22 | "laravel/framework": "5.*" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "FarhanWazir\\GoogleMaps\\": "src/FarhanWazir/GoogleMaps/" 27 | } 28 | }, 29 | "extra": { 30 | "branch-alias": { 31 | "dev-master": "2.5.x-dev" 32 | } 33 | }, 34 | "minimum-stability": "stable" 35 | } 36 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/Containers/isInsidePolygon.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/farhanwazir/laravelgooglemaps/882a1422b91c9f4735ae7188ed897965d253822a/src/FarhanWazir/GoogleMaps/Containers/isInsidePolygon.php -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/Facades/GMapsFacade.php: -------------------------------------------------------------------------------- 1 | section. The library will try to create the file if it does not exist already. Please ensure the destination file is writeable 48 | public $kmlLayerURL = ''; // A URL to publicly available KML or GeoRSS data for displaying geographic information. Multiple KML layers can be passed in by using an array of URL's. Note, if using multiple you'll probably have to set $kmlLayerPreserveViewport to true and manually set map center and zoom 49 | public $kmlLayerPreserveViewport = false; // Specifies whether the map should be adjusted to the bounds of the KmlLayer's contents. By default the map is zoomed and positioned to show the entirety of the layer's contents 50 | public $language = ''; // The map will by default load in the language of the browser. This can be overriden however here. For a full list of codes see https://spreadsheets.google.com/pub?key=p9pdwsai2hDMsLkXsoM05KQ&gid=1 51 | public $loadAsynchronously = false; // Load the map and API asynchronously once the page has loaded 52 | public $map_div_id = "map_canvas"; // The ID of the
that is output which contains the map 53 | public $map_height = "450px"; // The height of the map container. Any units (ie 'px') can be used. If no units are provided 'px' will be presumed 54 | public $map_name = "map"; // The JS reference to the map. Currently not used but to be used in the future when multiple maps are supported 55 | public $map_type = "ROADMAP"; // The default MapType. Values accepted are 'HYBRID', 'ROADMAP', 'SATELLITE' or 'TERRAIN' 56 | public $map_types_available = array(); // The other MapTypes available for selection on the map 57 | public $map_width = "100%"; // The width of the map container. Any units (ie 'px') can be used. If no units are provided 'px' will be presumed 58 | public $maps_loaded = 0; // Counter which keeps track of how many maps have been created to avoid standard functions being output twice 59 | public $mapTypeControlPosition = ''; // The position of the MapType control, eg. 'BOTTOM_RIGHT' 60 | public $mapTypeControlStyle = ''; // The style of the MapType control. blank, 'DROPDOWN_MENU' or 'HORIZONTAL_BAR' values accepted. 61 | public $minzoom = ''; // The minimum zoom level which will be displayed on the map 62 | public $maxzoom = ''; // The maximum zoom level which will be displayed on the map 63 | public $minifyJS = false; // If TRUE will run the JavaScript through Jsmin.php (this file and PHP5+ required) to minify the code 64 | public $noClear = false; // If TRUE do not clear the contents of the map div 65 | public $onboundschanged = ''; // The JavaScript action to perform when the viewport bounds have changed 66 | public $oncenterchanged = ''; // The JavaScript action to perform when themap center property changes 67 | public $onclick = ''; // The JavaScript action to perform when the map is clicked 68 | public $ondblclick = ''; // The JavaScript action to perform when the map is double-clicked 69 | public $ondrag = ''; // The JavaScript action to perform while the map is dragged 70 | public $ondragend = ''; // The JavaScript action to perform when the user stops dragging the map 71 | public $ondragstart = ''; // The JavaScript action to perform when the user starts dragging the map 72 | public $onidle = ''; // The JavaScript action to perform when the map becomes idle after panning or zooming 73 | public $onload = ''; // The JavaScript action to perform when the map first loads. This library hi-jacks the window.load event so add any bespoke code using this option 74 | public $onstaged = ''; 75 | public $onmousemove = ''; // The JavaScript action to perform when the user's mouse moves over the map container 76 | public $onmouseout = ''; // The JavaScript action to perform when the user's mouse exits the map container 77 | public $onmouseover = ''; // The JavaScript action to perform when the user's mouse enters the map container 78 | public $onresize = ''; // The JavaScript action to perform when the maps div changes size 79 | public $onrightclick = ''; // The JavaScript action to perform when the map is right-clicked 80 | public $ontilesloaded = ''; // The JavaScript action to perform when the visible tiles have finished loading 81 | public $onzoomchanged = ''; // The JavaScript action to perform when the maps zoom property changes 82 | public $panoramio = false; // If TRUE will add photos from Panoramio as a layer to your maps as a series of large and small photo icons 83 | public $panoramioTag = ''; // Restrict the set of Panoramio photos shown to those matching a certain textual tag 84 | public $panoramioUser = ''; // Restrict the set of Panoramio photos shown to those matching a particular user 85 | public $region = ''; // Country code top-level domain (eg "uk") within which to search. Useful if supplying addresses rather than lat/longs 86 | public $scaleControlPosition = ''; // The position of the Scale control, eg. 'BOTTOM_RIGHT' 87 | public $scrollwheel = true; // If set to FALSE will disable zooming by scrolling of the mouse wheel 88 | protected $sensor = false; // Set to TRUE if being used on a device that can detect a users location 89 | public $streetViewAddressControl = true; // If set to FALSE will hide the Address control 90 | public $streetViewAddressPosition = ''; // The position of the Address control, eg. 'BOTTOM' 91 | public $streetViewControlPosition = ''; // The position of the Street View control when viewing normal aerial map, eg. 'BOTTOM_RIGHT' 92 | public $streetViewCloseButton = false; // If set to TRUE will show the close button in the top right. The close button allows users to return to the aerial map 93 | public $streetViewLinksControl = true; // If set to FALSE will hide the Links control 94 | public $streetViewPanControl = true; // If set to FALSE will hide the Pan control 95 | public $streetViewPanPosition = ''; // The position of the Scale control, eg. 'TOP_RIGHT' 96 | public $streetViewPovHeading = 0; // The Street View camera heading in degrees relative to true north. True north is 0, east is 90, south is 180, west is 270 97 | public $streetViewPovPitch = 0; // The Street View camera pitch in degrees, relative to the street view vehicle. Directly upwards is 90, Directly downwards is -90. 98 | public $streetViewPovZoom = 0; // The Street View zoom level. Fully zoomed-out is level 0, zooming in increases the zoom level. 99 | public $streetViewZoomControl = true; // If set to FALSE will hide the Zoom control 100 | public $streetViewZoomPosition = ''; // The position of the Scale control, eg. 'TOP_RIGHT' 101 | public $streetViewZoomStyle = ''; // The size of the Street View zoom control. blank, 'SMALL' or 'LARGE' values accepted. 102 | public $styles = array(); // An array of styles used to colour aspects of the map and turn points of interest on and off 103 | public $stylesAsMapTypes = false; // If applying styles, whether to apply them to the default map or add them as additional map types 104 | public $stylesAsMapTypesDefault = ''; // If $stylesAsMapTypes is true the default style. Should contain the 'Name' of the style 105 | public $tilt = 0; // The angle of tilt. Currently only supports the values 0 and 45 in SATELLITE and HYBRID map types and at certain zoom levels 106 | public $trafficOverlay = false; // If set to TRUE will overlay traffic information onto the map by default 107 | public $version = "3"; // Version of the API being used. Not currently used in the library 108 | public $zoom = 13; // The default zoom level of the map. If set to "auto" will autozoom/center to fit in all visible markers. If "auto", also overrides the $center parameter 109 | public $zoomControlPosition = ''; // The position of the Zoom control, eg. 'BOTTOM_RIGHT' 110 | public $zoomControlStyle = ''; // The size of the zoom control. blank, 'SMALL' or 'LARGE' values accepted. 111 | 112 | public $markers = array(); // An array used by the library to store the markers as they are produced 113 | public $markersInfo = array(); // An array containing marker information (id, latitude, longitude etc) for use elsewhere 114 | public $polylines = array(); // An array used by the library to store the polylines as they are produced 115 | public $polygons = array(); // An array used by the library to store the polygons as they are produced 116 | public $circles = array(); // An array used by the library to store the circles as they are produced 117 | public $rectangles = array(); // An array used by the library to store the rectangles as they are produced 118 | public $overlays = array(); // An array used by the library to store the overlays as they are produced 119 | 120 | public $directions = false; // Whether or not the map will be used to show directions 121 | public $directionsStart = ""; // The starting location (lat/long co-ordinate or address) of the directions. Set to 'auto' to default it to the users location 122 | public $directionsEnd = ""; // The destination point (lat/long co-ordinate or address) of the directions. Set to 'auto' to default it to the users location 123 | public $directionsDivID = ""; // An element's ID on the page where textual directions will be output to. Leave blank if not required 124 | public $directionsMode = "DRIVING"; // DRIVING, WALKING or BICYCLING (US Only) - The vehicle/mode of transport to show directions for 125 | public $directionsAvoidTolls = false; // Whether or not directions should avoid tolls 126 | public $directionsAvoidHighways = false; // Whether or not directions should avoid highways 127 | public $directionsDraggable = false; // Whether or not directions on the map are draggable 128 | public $directionsChanged = ""; // JavaScript to perform when directions are dragged 129 | public $directionsUnits = ""; // 'metric' for kilometers and meters or 'imperial for miles and feet. Leave blank and it will default to the region or country of where directions are being obtained 130 | public $directionsWaypointArray = array(); // An array of waypoints. eg array("Boston, MA", "Times Square, NY"); 131 | public $directionsWaypointsOptimize = false; // Should the waypoints be optimised? If TRUE, waypoints will be re-ordered to provide the most efficient route. 132 | 133 | public $drawing = false; // Whether or not the drawing library tools will be loaded 134 | public $drawingControl = true; // If set to FALSE will hide the Drawing Manager control 135 | public $drawingControlPosition = 'TOP_CENTER'; // The position of the Drawing Manager control, eg. 'TOP_RIGHT' 136 | public $drawingDefaultMode = 'marker'; // The default mode for the Drawing Manager. Accepted values are marker, polygon, polyline, rectangle, circle, or null. null means that the user can interact with the map as normal when the map loads, and clicks do not draw anything. 137 | public $drawingModes = array(); // An array of modes available for use. Accepted values are marker, polygon, polyline, rectangle, circle 138 | public $drawingOnComplete = array(); // An array of JS to execute when shapes are completed, one array element per shape. For example: array('circle'=>'JS here', 'polygon'=>'JS here'); 139 | public $drawingOnEdit = array(); // An array of JS to execute when shapes are changed/resized, one array element per shape. For example: array('circle'=>'JS here', 'polygon'=>'JS here'); 140 | 141 | public $places = false; // Whether or not the map will be used to show places 142 | public $placesLocation = ''; // A point (lat/long co-ordinate or address) on the map if the search for places is based around a central point 143 | public $placesRadius = 0; // The radius (in meters) if search is based around a central position 144 | public $placesLocationSW = ''; // If preferring to search within bounds the South-West position (latitude/longitude coordinate OR address) 145 | public $placesLocationNE = ''; // If preferring to search within bounds the North-East position (latitude/longitude coordinate OR address) 146 | public $placesTypes = array(); // The types of places to search for. For a list of supported types see http://code.google.com/apis/maps/documentation/places/supported_types.html 147 | public $placesName = ''; // A term to be matched against when searching for places to display on the map 148 | public $placesAutocompleteInputID = ''; // The ID attribute of the textfield that the autocomplete should effect 149 | public $placesAutocompleteTypes = array(); // The types of places for the autocomplete to return. Options can be seen here https://developers.google.com/maps/documentation/javascript/places#places_autocomplete but include 'establishment' to only return business results, '(cities)', or '(regions)' 150 | public $placesAutocompleteBoundSW = ''; // By specifying an area in which to search for Places, the results are biased towards, but not restricted to, Places contained within these bounds. 151 | public $placesAutocompleteBoundNE = ''; // Both South-West (lat/long co-ordinate or address) and North-East (lat/long co-ordinate or address) values are required if wishing to set bounds 152 | public $placesAutocompleteBoundsMap = false; // An alternative to setting the SW and NE bounds is to use the bounds of the current viewport. If set to TRUE, the bounds will be set to the viewport of the visible map, even if dragged or zoomed 153 | public $placesAutocompleteOnChange = ''; // The JavaScript action to perform when a place is selected 154 | public $palcesAutoCompleteOnChangeFailed = ''; 155 | 156 | public $injectControlsInTopLeft = array(); 157 | public $injectControlsInTopRight = array(); 158 | public $injectControlsInTopCenter = array(); 159 | public $injectControlsInLeftTop = array(); 160 | public $injectControlsInLeftCenter = array(); 161 | public $injectControlsInLeftBottom = array(); 162 | public $injectControlsInRightTop = array(); 163 | public $injectControlsInRightCenter = array(); 164 | public $injectControlsInRightBottom = array(); 165 | public $injectControlsInBottomLeft = array(); 166 | public $injectControlsInBottomRight = array(); 167 | public $injectControlsInBottomCenter = array(); 168 | 169 | //user callbacks 170 | public $init_call_func = ''; 171 | 172 | 173 | public function __construct($config = array()) 174 | { 175 | $this->apiKey = config('googlemaps.key'); 176 | $this->adsensePublisherID = config('googlemaps.adsense_publisher_id'); 177 | $this->class = config('googlemaps.css_class'); 178 | 179 | if (count($config) > 0) { 180 | $this->initialize($config); 181 | } 182 | 183 | #Log::info('debug', "Google Maps Class Initialized"); 184 | } 185 | 186 | public function initialize($config = array()) 187 | { 188 | foreach ($config as $key => $val) { 189 | if (isset($this->$key)) { 190 | $this->$key = $val; 191 | } 192 | } 193 | 194 | if ($this->sensor) { 195 | $this->sensor = "true"; 196 | } else { 197 | $this->sensor = "false"; 198 | } 199 | } 200 | 201 | public function add_marker($params = array()) 202 | { 203 | $marker = array(); 204 | $this->markersInfo['marker_'.count($this->markers)] = array(); 205 | 206 | $marker['position'] = ''; // The position (lat/long co-ordinate or address) at which the marker will appear 207 | $marker['infowindow_content'] = ''; // If not blank, creates an infowindow (aka bubble) with the content provided. Can be plain text or HTML 208 | $marker['id'] = ''; // The unique identifier of the marker suffix (ie. marker_yourID). If blank, this will default to marker_X where X is an incremental number 209 | $marker['clickable'] = true; // Defines if the marker is clickable 210 | $marker['cursor'] = ''; // The name or url of the cursor to display on hover 211 | $marker['draggable'] = false; // Defines if the marker is draggable 212 | $marker['flat'] = false; // If set to TRUE will not display a shadow beneath the icon 213 | $marker['icon'] = ''; // The name or url of the icon to use for the marker 214 | $marker['icon_size'] = ''; // The display size of the sprite or image being used. When using sprites, you must specify the sprite size. Expecting two comma-separated values for width and height respectively (ie '20,30'). See https://developers.google.com/maps/documentation/javascript/3.exp/reference#Icon 215 | $marker['icon_scaledSize'] = ''; // The size of the entire image after scaling, if any. Use this property to stretch/shrink an image or a sprite. Expecting two comma-separated values for width and height respectively (ie '20,30') 216 | $marker['icon_origin'] = ''; // If using a sprite, the position of the image within the sprite. Expecting two comma-separated values for distance from the top and left respectively (ie '20,30') 217 | $marker['icon_anchor'] = ''; // The position at which to anchor an image in correspondance to the location of the marker on the map. By default, the anchor is located along the center point of the bottom of the image. Expecting two comma-separated values (ie '20,30'). Credit to https://github.com/colethorsen 218 | $marker['animation'] = ''; // blank, 'DROP' or 'BOUNCE' 219 | $marker['onclick'] = ''; // JavaScript performed when a marker is clicked 220 | $marker['ondblclick'] = ''; // JavaScript performed when a marker is double-clicked 221 | $marker['ondrag'] = ''; // JavaScript repeatedly performed while the marker is being dragged 222 | $marker['ondragstart'] = ''; // JavaScript performed when a marker is started to be dragged 223 | $marker['ondragend'] = ''; // JavaScript performed when a draggable marker is dropped 224 | $marker['onmousedown'] = ''; // JavaScript performed when a mousedown event occurs on a marker 225 | $marker['onmouseout'] = ''; // JavaScript performed when the mouse leaves the area of the marker icon 226 | $marker['onmouseover'] = ''; // JavaScript performed when the mouse enters the area of the marker icon 227 | $marker['onmouseup'] = ''; // JavaScript performed when a mouseup event occurs on a marker 228 | $marker['onpositionchanged'] = ''; // JavaScript performed when the markers position changes 229 | $marker['onrightclick'] = ''; // JavaScript performed when a right-click occurs on a marker 230 | $marker['raiseondrag'] = true; // If FALSE, disables the raising and lowering of the icon when a marker is being dragged 231 | $marker['shadow'] = ''; // The name or url of the icon's shadow 232 | $marker['title'] = ''; // The tooltip text to show on hover 233 | $marker['visible'] = true; // Defines if the marker is visible by default 234 | $marker['zIndex'] = ''; // The zIndex of the marker. If two markers overlap, the marker with the higher zIndex will appear on top 235 | $marker['label'] = ''; // The label of the marker. 236 | 237 | $marker_output = ''; 238 | 239 | foreach ($params as $key => $value) { 240 | if (isset($marker[$key])) { 241 | $marker[$key] = $value; 242 | } 243 | } 244 | 245 | $marker_id = count($this->markers); 246 | if (trim($marker['id']) != "") { 247 | $marker_id = $marker['id']; 248 | } 249 | 250 | if ($marker['position'] != "") { 251 | if ($this->is_lat_long($marker['position'])) { 252 | //Javascript 253 | $marker_output .= 'var myLatlng = new google.maps.LatLng('.$marker['position'].');'; 254 | 255 | $explodePosition = explode(",", $marker['position']); 256 | $this->markersInfo['marker_'.$marker_id]['latitude'] = trim($explodePosition[0]); 257 | $this->markersInfo['marker_'.$marker_id]['longitude'] = trim($explodePosition[1]); 258 | } else { 259 | $lat_long = $this->get_lat_long_from_address($marker['position']); 260 | $marker_output .= 'var myLatlng = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].');'; 261 | $this->markersInfo['marker_'.$marker_id]['latitude'] = $lat_long[0]; 262 | $this->markersInfo['marker_'.$marker_id]['longitude'] = $lat_long[1]; 263 | } 264 | } 265 | 266 | if ($marker['icon'] != "") { 267 | $marker_output .= ' 268 | var marker_icon = { 269 | url: "'.$marker['icon'].'"'; 270 | if ($marker['icon_size'] != "") { 271 | $marker_output .= ', 272 | size: new google.maps.Size('.$marker['icon_size'].')'; 273 | } 274 | if ($marker['icon_scaledSize'] != "") { 275 | $marker_output .= ', 276 | scaledSize: new google.maps.Size('.$marker['icon_scaledSize'].')'; 277 | } 278 | if ($marker['icon_origin'] != "") { 279 | $marker_output .= ', 280 | origin: new google.maps.Point('.$marker['icon_origin'].')'; 281 | } 282 | if ($marker['icon_anchor'] != "") { 283 | $marker_output .= ', 284 | anchor: new google.maps.Point('.$marker['icon_anchor'].')'; 285 | } 286 | $marker_output .= '}; 287 | '; 288 | } 289 | 290 | $marker_output .= ' 291 | var markerOptions = { 292 | map: '.$this->map_name; 293 | if ($marker['position'] != "") { 294 | $marker_output .= ', 295 | position: myLatlng'; 296 | } 297 | if (!$marker['clickable']) { 298 | $marker_output .= ', 299 | clickable: false'; 300 | } 301 | if ($marker['cursor'] != "") { 302 | $marker_output .= ', 303 | cursor: "'.$marker['cursor'].'"'; 304 | } 305 | if ($marker['draggable']) { 306 | $marker_output .= ', 307 | draggable: true'; 308 | } 309 | if ($marker['flat']) { 310 | $marker_output .= ', 311 | flat: true'; 312 | } 313 | if ($marker['icon'] != "") { 314 | $marker_output .= ', 315 | icon: marker_icon'; 316 | } 317 | if (!$marker['raiseondrag']) { 318 | $marker_output .= ', 319 | raiseOnDrag: false'; 320 | } 321 | if ($marker['shadow'] != "") { 322 | $marker_output .= ', 323 | shadow: "'.$marker['shadow'].'"'; 324 | } 325 | if ($marker['title'] != "") { 326 | $marker_output .= ', 327 | title: "'.$marker['title'].'"'; 328 | $this->markersInfo['marker_'.$marker_id]['title'] = $marker['title']; 329 | } 330 | if (!$marker['visible']) { 331 | $marker_output .= ', 332 | visible: false'; 333 | } 334 | if ($marker['zIndex'] != "" && is_numeric($marker['zIndex'])) { 335 | $marker_output .= ', 336 | zIndex: '.$marker['zIndex']; 337 | } 338 | if ($marker['animation'] != "" && (strtoupper($marker['animation']) == "DROP" || strtoupper($marker['animation'] == "BOUNCE"))) { 339 | $marker_output .= ', 340 | animation: google.maps.Animation.'.strtoupper($marker['animation']); 341 | } 342 | if ($marker['label'] != "") { 343 | $marker_output .= ', 344 | label: "'.$marker['label'].'"'; 345 | } 346 | 347 | 348 | 349 | $marker_output .= ' 350 | }; 351 | marker_'.$marker_id.' = createMarker_'.$this->map_name.'(markerOptions); 352 | marker_'.$marker_id.'.id = marker_'.$marker_id.'; 353 | '; 354 | 355 | if ($marker['infowindow_content'] != "") { 356 | 357 | // Escape any quotes in the event that HTML is being added to the infowindow 358 | $marker['infowindow_content'] = str_replace('\"', '"', $marker['infowindow_content']); 359 | $marker['infowindow_content'] = str_replace('"', '\"', $marker['infowindow_content']); 360 | 361 | $marker_output .= ' 362 | marker_'.$marker_id.'.set("content", "'.$marker['infowindow_content'].'"); 363 | 364 | google.maps.event.addListener(marker_'.$marker_id.', "click", function(event) { 365 | iw_'.$this->map_name.'.setContent(this.get("content")); 366 | iw_'.$this->map_name.'.open('.$this->map_name.', this); 367 | '; 368 | if ($marker['onclick'] != "") { 369 | $marker_output .= $marker['onclick'].' 370 | '; 371 | } 372 | $marker_output .= ' 373 | }); 374 | '; 375 | } else { 376 | if ($marker['onclick'] != "") { 377 | $marker_output .= ' 378 | google.maps.event.addListener(marker_'.$marker_id.', "click", function(event) { 379 | '.$marker['onclick'].' 380 | }); 381 | '; 382 | } 383 | } 384 | 385 | if ($marker['ondblclick'] != "") { 386 | $marker_output .= ' 387 | google.maps.event.addListener(marker_'.$marker_id.', "dblclick", function(event) { 388 | '.$marker['ondblclick'].' 389 | }); 390 | '; 391 | } 392 | if ($marker['onmousedown'] != "") { 393 | $marker_output .= ' 394 | google.maps.event.addListener(marker_'.$marker_id.', "mousedown", function(event) { 395 | '.$marker['onmousedown'].' 396 | }); 397 | '; 398 | } 399 | if ($marker['onmouseout'] != "") { 400 | $marker_output .= ' 401 | google.maps.event.addListener(marker_'.$marker_id.', "mouseout", function(event) { 402 | '.$marker['onmouseout'].' 403 | }); 404 | '; 405 | } 406 | if ($marker['onmouseover'] != "") { 407 | $marker_output .= ' 408 | google.maps.event.addListener(marker_'.$marker_id.', "mouseover", function(event) { 409 | '.$marker['onmouseover'].' 410 | }); 411 | '; 412 | } 413 | if ($marker['onmouseup'] != "") { 414 | $marker_output .= ' 415 | google.maps.event.addListener(marker_'.$marker_id.', "mouseup", function(event) { 416 | '.$marker['onmouseup'].' 417 | }); 418 | '; 419 | } 420 | if ($marker['onpositionchanged'] != "") { 421 | $marker_output .= ' 422 | google.maps.event.addListener(marker_'.$marker_id.', "position_changed", function(event) { 423 | '.$marker['onpositionchanged'].'(event, this); 424 | }); 425 | '; 426 | } 427 | if ($marker['onrightclick'] != "") { 428 | $marker_output .= ' 429 | google.maps.event.addListener(marker_'.$marker_id.', "rightclick", function(event) { 430 | '.$marker['onrightclick'].' 431 | }); 432 | '; 433 | } 434 | 435 | if ($marker['draggable']) { 436 | if ($marker['ondrag'] != "") { 437 | $marker_output .= ' 438 | google.maps.event.addListener(marker_'.$marker_id.', "drag", function(event) { 439 | '.$marker['ondrag'].' 440 | }); 441 | '; 442 | } 443 | if ($marker['ondragend'] != "") { 444 | $marker_output .= ' 445 | google.maps.event.addListener(marker_'.$marker_id.', "dragend", function(event) { 446 | '.$marker['ondragend'].' 447 | }); 448 | '; 449 | } 450 | if ($marker['ondragstart'] != "") { 451 | $marker_output .= ' 452 | google.maps.event.addListener(marker_'.$marker_id.', "dragstart", function(event) { 453 | '.$marker['ondragstart'].' 454 | }); 455 | '; 456 | } 457 | } 458 | 459 | array_push($this->markers, $marker_output); 460 | } 461 | 462 | public function add_polyline($params = array()) 463 | { 464 | $polyline = array(); 465 | 466 | $polyline['points'] = array(); // An array of latitude/longitude coordinates OR addresses, or a mixture of both. If an address is supplied the Google geocoding service will be used to return a lat/long. 467 | $polyline['clickable'] = true; // Defines if the polyline is clickable 468 | $polyline['strokeColor'] = '#FF0000'; // The hex value of the polylines color 469 | $polyline['strokeOpacity'] = '1.0'; // The opacity of the polyline. 0 to 1.0 470 | $polyline['strokeWeight'] = '2'; // The thickness of the polyline 471 | $polyline['onclick'] = ''; // JavaScript performed when a polyline is clicked 472 | $polyline['ondblclick'] = ''; // JavaScript performed when a polyline is double-clicked 473 | $polyline['onmousedown'] = ''; // JavaScript performed when a mousedown event occurs on a polyline 474 | $polyline['onmousemove'] = ''; // JavaScript performed when the mouse moves in the area of the polyline 475 | $polyline['onmouseout'] = ''; // JavaScript performed when the mouse leaves the area of the polyline 476 | $polyline['onmouseover'] = ''; // JavaScript performed when the mouse enters the area of the polyline 477 | $polyline['onmouseup'] = ''; // JavaScript performed when a mouseup event occurs on a polyline 478 | $polyline['onrightclick'] = ''; // JavaScript performed when a right-click occurs on a polyline 479 | $polyline['zIndex'] = ''; // The zIndex of the polyline. If two polylines overlap, the polyline with the higher zIndex will appear on top 480 | 481 | $polyline_output = ''; 482 | 483 | foreach ($params as $key => $value) { 484 | if (isset($polyline[$key])) { 485 | $polyline[$key] = $value; 486 | } 487 | } 488 | 489 | if (count($polyline['points'])) { 490 | $polyline_output .= ' 491 | var polyline_plan_'.count($this->polylines).' = ['; 492 | $i = 0; 493 | $lat_long_output = ''; 494 | foreach ($polyline['points'] as $point) { 495 | if ($i > 0) { 496 | $polyline_output .= ','; 497 | } 498 | $lat_long_to_push = ''; 499 | if ($this->is_lat_long($point)) { 500 | $lat_long_to_push = $point; 501 | $polyline_output .= ' 502 | new google.maps.LatLng('.$point.') 503 | '; 504 | } else { 505 | $lat_long = $this->get_lat_long_from_address($point); 506 | $polyline_output .= ' 507 | new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 508 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 509 | } 510 | $lat_long_output .= ' 511 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 512 | '; 513 | $i++; 514 | } 515 | $polyline_output .= '];'; 516 | 517 | $polyline_output .= $lat_long_output; 518 | 519 | $polyline_output .= ' 520 | var polyline_'.count($this->polylines).' = new google.maps.Polyline({ 521 | path: polyline_plan_'.count($this->polylines).', 522 | strokeColor: "'.$polyline['strokeColor'].'", 523 | strokeOpacity: '.$polyline['strokeOpacity'].', 524 | strokeWeight: '.$polyline['strokeWeight']; 525 | if (!$polyline['clickable']) { 526 | $polyline_output .= ', 527 | clickable: false'; 528 | } 529 | if ($polyline['zIndex'] != "" && is_numeric($polyline['zIndex'])) { 530 | $polyline_output .= ', 531 | zIndex: '.$polyline['zIndex']; 532 | } 533 | $polyline_output .= ' 534 | }); 535 | 536 | polyline_'.count($this->polylines).'.setMap('.$this->map_name.'); 537 | 538 | '; 539 | 540 | if ($polyline['onclick'] != "") { 541 | $polyline_output .= ' 542 | google.maps.event.addListener(polyline_'.count($this->polylines).', "click", function() { 543 | '.$polyline['onclick'].' 544 | }); 545 | '; 546 | } 547 | if ($polyline['ondblclick'] != "") { 548 | $polyline_output .= ' 549 | google.maps.event.addListener(polyline_'.count($this->polylines).', "dblclick", function() { 550 | '.$polyline['ondblclick'].' 551 | }); 552 | '; 553 | } 554 | if ($polyline['onmousedown'] != "") { 555 | $polyline_output .= ' 556 | google.maps.event.addListener(polyline_'.count($this->polylines).', "mousedown", function() { 557 | '.$polyline['onmousedown'].' 558 | }); 559 | '; 560 | } 561 | if ($polyline['onmousemove'] != "") { 562 | $polyline_output .= ' 563 | google.maps.event.addListener(polyline_'.count($this->polylines).', "mousemove", function() { 564 | '.$polyline['onmousemove'].' 565 | }); 566 | '; 567 | } 568 | if ($polyline['onmouseout'] != "") { 569 | $polyline_output .= ' 570 | google.maps.event.addListener(polyline_'.count($this->polylines).', "mouseout", function() { 571 | '.$polyline['onmouseout'].' 572 | }); 573 | '; 574 | } 575 | if ($polyline['onmouseover'] != "") { 576 | $polyline_output .= ' 577 | google.maps.event.addListener(polyline_'.count($this->polylines).', "mouseover", function() { 578 | '.$polyline['onmouseover'].' 579 | }); 580 | '; 581 | } 582 | if ($polyline['onmouseup'] != "") { 583 | $polyline_output .= ' 584 | google.maps.event.addListener(polyline_'.count($this->polylines).', "mouseup", function() { 585 | '.$polyline['onmouseup'].' 586 | }); 587 | '; 588 | } 589 | if ($polyline['onrightclick'] != "") { 590 | $polyline_output .= ' 591 | google.maps.event.addListener(polyline_'.count($this->polylines).', "rightclick", function() { 592 | '.$polyline['onrightclick'].' 593 | }); 594 | '; 595 | } 596 | 597 | array_push($this->polylines, $polyline_output); 598 | } 599 | } 600 | 601 | public function add_polygon($params = array()) 602 | { 603 | $polygon = array(); 604 | 605 | $polygon['points'] = array(); // The positions (latitude/longitude coordinates OR addresses) at which the polygon points will appear. NOTE: The first and last elements of the array must be the same 606 | $polygon['clickable'] = true; // Defines if the polygon is clickable 607 | $polygon['strokeColor'] = '#FF0000'; // The hex value of the polygons border color 608 | $polygon['strokeOpacity'] = '0.8'; // The opacity of the polygon border. 0 to 1.0 609 | $polygon['strokeWeight'] = '2'; // The thickness of the polygon border 610 | $polygon['fillColor'] = '#FF0000'; // The hex value of the polygons fill color 611 | $polygon['fillOpacity'] = '0.3'; // The opacity of the polygons fill 612 | $polygon['onclick'] = ''; // JavaScript performed when a polygon is clicked 613 | $polygon['ondblclick'] = ''; // JavaScript performed when a polygon is double-clicked 614 | $polygon['onmousedown'] = ''; // JavaScript performed when a mousedown event occurs on a polygon 615 | $polygon['onmousemove'] = ''; // JavaScript performed when the mouse moves in the area of the polygon 616 | $polygon['onmouseout'] = ''; // JavaScript performed when the mouse leaves the area of the polygon 617 | $polygon['onmouseover'] = ''; // JavaScript performed when the mouse enters the area of the polygon 618 | $polygon['onmouseup'] = ''; // JavaScript performed when a mouseup event occurs on a polygon 619 | $polygon['onrightclick'] = ''; // JavaScript performed when a right-click occurs on a polygon 620 | $polygon['zIndex'] = ''; // The zIndex of the polygon. If two polygons overlap, the polygon with the higher zIndex will appear on top 621 | 622 | $polygon_output = ''; 623 | 624 | foreach ($params as $key => $value) { 625 | if (isset($polygon[$key])) { 626 | $polygon[$key] = $value; 627 | } 628 | } 629 | 630 | if (count($polygon['points'])) { 631 | $polygon_output .= ' 632 | var polygon_plan_'.count($this->polygons).' = ['; 633 | $i = 0; 634 | $lat_long_output = ''; 635 | foreach ($polygon['points'] as $point) { 636 | if ($i > 0) { 637 | $polygon_output .= ','; 638 | } 639 | $lat_long_to_push = ''; 640 | if ($this->is_lat_long($point)) { 641 | $lat_long_to_push = $point; 642 | $polygon_output .= ' 643 | new google.maps.LatLng('.$point.') 644 | '; 645 | } else { 646 | $lat_long = $this->get_lat_long_from_address($point); 647 | $polygon_output .= ' 648 | new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 649 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 650 | } 651 | $lat_long_output .= ' 652 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 653 | '; 654 | $i++; 655 | } 656 | $polygon_output .= '];'; 657 | 658 | $polygon_output .= $lat_long_output; 659 | } 660 | 661 | $polygon_output .= ' 662 | var polygon_'.count($this->polygons).' = new google.maps.Polygon({ 663 | '; 664 | if (count($polygon['points'])) { 665 | $polygon_output .= 'path: polygon_plan_'.count($this->polygons).', 666 | '; 667 | } 668 | $polygon_output .= ' 669 | strokeColor: "'.$polygon['strokeColor'].'", 670 | strokeOpacity: '.$polygon['strokeOpacity'].', 671 | strokeWeight: '.$polygon['strokeWeight'].', 672 | fillColor: "'.$polygon['fillColor'].'", 673 | fillOpacity: '.$polygon['fillOpacity']; 674 | if (!$polygon['clickable']) { 675 | $polygon_output .= ', 676 | clickable: false'; 677 | } 678 | if ($polygon['zIndex'] != "" && is_numeric($polygon['zIndex'])) { 679 | $polygon_output .= ', 680 | zIndex: '.$polygon['zIndex']; 681 | } 682 | $polygon_output .= ' 683 | }); 684 | 685 | polygon_'.count($this->polygons).'.setMap('.$this->map_name.'); 686 | 687 | '; 688 | 689 | if ($polygon['onclick'] != "") { 690 | $polygon_output .= ' 691 | google.maps.event.addListener(polygon_'.count($this->polygons).', "click", function() { 692 | '.$polygon['onclick'].' 693 | }); 694 | '; 695 | } 696 | if ($polygon['ondblclick'] != "") { 697 | $polygon_output .= ' 698 | google.maps.event.addListener(polygon_'.count($this->polygons).', "dblclick", function() { 699 | '.$polygon['ondblclick'].' 700 | }); 701 | '; 702 | } 703 | if ($polygon['onmousedown'] != "") { 704 | $polygon_output .= ' 705 | google.maps.event.addListener(polygon_'.count($this->polygons).', "mousedown", function() { 706 | '.$polygon['onmousedown'].' 707 | }); 708 | '; 709 | } 710 | if ($polygon['onmousemove'] != "") { 711 | $polygon_output .= ' 712 | google.maps.event.addListener(polygon_'.count($this->polygons).', "mousemove", function() { 713 | '.$polygon['onmousemove'].' 714 | }); 715 | '; 716 | } 717 | if ($polygon['onmouseout'] != "") { 718 | $polygon_output .= ' 719 | google.maps.event.addListener(polygon_'.count($this->polygons).', "mouseout", function() { 720 | '.$polygon['onmouseout'].' 721 | }); 722 | '; 723 | } 724 | if ($polygon['onmouseover'] != "") { 725 | $polygon_output .= ' 726 | google.maps.event.addListener(polygon_'.count($this->polygons).', "mouseover", function() { 727 | '.$polygon['onmouseover'].' 728 | }); 729 | '; 730 | } 731 | if ($polygon['onmouseup'] != "") { 732 | $polygon_output .= ' 733 | google.maps.event.addListener(polygon_'.count($this->polygons).', "mouseup", function() { 734 | '.$polygon['onmouseup'].' 735 | }); 736 | '; 737 | } 738 | if ($polygon['onrightclick'] != "") { 739 | $polygon_output .= ' 740 | google.maps.event.addListener(polygon_'.count($this->polygons).', "rightclick", function() { 741 | '.$polygon['onrightclick'].' 742 | }); 743 | '; 744 | } 745 | 746 | array_push($this->polygons, $polygon_output); 747 | } 748 | 749 | public function add_circle($params = array()) 750 | { 751 | $circle = array(); 752 | 753 | $circle['center'] = ''; // The center position (latitude/longitude coordinate OR addresse) at which the circle will appear 754 | $circle['clickable'] = true; // Defines if the circle is clickable 755 | $circle['radius'] = 0; // The circle radius (in metres) 756 | $circle['strokeColor'] = '0.8'; // The hex value of the circles border color 757 | $circle['strokeOpacity'] = '0.8'; // The opacity of the circle border 758 | $circle['strokeWeight'] = '2'; // The thickness of the circle border 759 | $circle['fillColor'] = '#FF0000'; // The hex value of the circles fill color 760 | $circle['fillOpacity'] = '0.3'; // The opacity of the circles fill 761 | $circle['onclick'] = ''; // JavaScript performed when a circle is clicked 762 | $circle['ondblclick'] = ''; // JavaScript performed when a circle is double-clicked 763 | $circle['onmousedown'] = ''; // JavaScript performed when a mousedown event occurs on a circle 764 | $circle['onmousemove'] = ''; // JavaScript performed when the mouse moves in the area of the circle 765 | $circle['onmouseout'] = ''; // JavaScript performed when the mouse leaves the area of the circle 766 | $circle['onmouseover'] = ''; // JavaScript performed when the mouse enters the area of the circle 767 | $circle['onmouseup'] = ''; // JavaScript performed when a mouseup event occurs on a circle 768 | $circle['onrightclick'] = ''; // JavaScript performed when a right-click occurs on a circle 769 | $circle['zIndex'] = ''; // The zIndex of the circle. If two circles overlap, the circle with the higher zIndex will appear on top 770 | 771 | $circle_output = ''; 772 | 773 | foreach ($params as $key => $value) { 774 | if (isset($circle[$key])) { 775 | $circle[$key] = $value; 776 | } 777 | } 778 | 779 | if ($circle['radius'] > 0 && $circle['center'] != "") { 780 | $lat_long_to_push = ''; 781 | if ($this->is_lat_long($circle['center'])) { 782 | $lat_long_to_push = $circle['center']; 783 | $circle_output = ' 784 | var circleCenter = new google.maps.LatLng('.$circle['center'].') 785 | '; 786 | } else { 787 | $lat_long = $this->get_lat_long_from_address($circle['center']); 788 | $circle_output = ' 789 | var circleCenter = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 790 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 791 | } 792 | $circle_output .= ' 793 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 794 | '; 795 | 796 | $circle_output .= ' 797 | var circleOptions = { 798 | strokeColor: "'.$circle['strokeColor'].'", 799 | strokeOpacity: '.$circle['strokeOpacity'].', 800 | strokeWeight: '.$circle['strokeWeight'].', 801 | fillColor: "'.$circle['fillColor'].'", 802 | fillOpacity: '.$circle['fillOpacity'].', 803 | map: '.$this->map_name.', 804 | center: circleCenter, 805 | radius: '.$circle['radius']; 806 | if (!$circle['clickable']) { 807 | $circle_output .= ', 808 | clickable: false'; 809 | } 810 | if ($circle['zIndex'] != "" && is_numeric($circle['zIndex'])) { 811 | $circle_output .= ', 812 | zIndex: '.$circle['zIndex']; 813 | } 814 | $circle_output .= ' 815 | }; 816 | var circle_'.count($this->circles).' = new google.maps.Circle(circleOptions); 817 | '; 818 | 819 | if ($circle['onclick'] != "") { 820 | $circle_output .= ' 821 | google.maps.event.addListener(circle_'.count($this->circles).', "click", function() { 822 | '.$circle['onclick'].' 823 | }); 824 | '; 825 | } 826 | if ($circle['ondblclick'] != "") { 827 | $circle_output .= ' 828 | google.maps.event.addListener(circle_'.count($this->circles).', "dblclick", function() { 829 | '.$circle['ondblclick'].' 830 | }); 831 | '; 832 | } 833 | if ($circle['onmousedown'] != "") { 834 | $circle_output .= ' 835 | google.maps.event.addListener(circle_'.count($this->circles).', "mousedown", function() { 836 | '.$circle['onmousedown'].' 837 | }); 838 | '; 839 | } 840 | if ($circle['onmousemove'] != "") { 841 | $circle_output .= ' 842 | google.maps.event.addListener(circle_'.count($this->circles).', "mousemove", function() { 843 | '.$circle['onmousemove'].' 844 | }); 845 | '; 846 | } 847 | if ($circle['onmouseout'] != "") { 848 | $circle_output .= ' 849 | google.maps.event.addListener(circle_'.count($this->circles).', "mouseout", function() { 850 | '.$circle['onmouseout'].' 851 | }); 852 | '; 853 | } 854 | if ($circle['onmouseover'] != "") { 855 | $circle_output .= ' 856 | google.maps.event.addListener(circle_'.count($this->circles).', "mouseover", function() { 857 | '.$circle['onmouseover'].' 858 | }); 859 | '; 860 | } 861 | if ($circle['onmouseup'] != "") { 862 | $circle_output .= ' 863 | google.maps.event.addListener(circle_'.count($this->circles).', "mouseup", function() { 864 | '.$circle['onmouseup'].' 865 | }); 866 | '; 867 | } 868 | if ($circle['onrightclick'] != "") { 869 | $circle_output .= ' 870 | google.maps.event.addListener(circle_'.count($this->circles).', "rightclick", function() { 871 | '.$circle['onrightclick'].' 872 | }); 873 | '; 874 | } 875 | 876 | array_push($this->circles, $circle_output); 877 | } 878 | } 879 | 880 | public function add_rectangle($params = array()) 881 | { 882 | $rectangle = array(); 883 | 884 | $rectangle['positionSW'] = ''; // The South-West position (latitude/longitude coordinate OR address) at which the rectangle will appear 885 | $rectangle['positionNE'] = ''; // The North-East position(latitude/longitude coordinate OR address) at which the rectangle will appear 886 | $rectangle['clickable'] = true; // Defines if the rectangle is clickable 887 | $rectangle['strokeColor'] = '0.8'; // The hex value of the rectangles border color 888 | $rectangle['strokeOpacity'] = '0.8'; // The opacity of the rectangle border 889 | $rectangle['strokeWeight'] = '2'; // The thickness of the rectangle border 890 | $rectangle['fillColor'] = '#FF0000'; // The hex value of the rectangles fill color 891 | $rectangle['fillOpacity'] = '0.3'; // The opacity of the rectangles fill 892 | $rectangle['onclick'] = ''; // JavaScript performed when a rectangle is clicked 893 | $rectangle['ondblclick'] = ''; // JavaScript performed when a rectangle is double-clicked 894 | $rectangle['onmousedown'] = ''; // JavaScript performed when a mousedown event occurs on a rectangle 895 | $rectangle['onmousemove'] = ''; // JavaScript performed when the mouse moves in the area of the rectangle 896 | $rectangle['onmouseout'] = ''; // JavaScript performed when the mouse leaves the area of the rectangle 897 | $rectangle['onmouseover'] = ''; // JavaScript performed when the mouse enters the area of the rectangle 898 | $rectangle['onmouseup'] = ''; // JavaScript performed when a mouseup event occurs on a rectangle 899 | $rectangle['onrightclick'] = ''; // JavaScript performed when a right-click occurs on a rectangle 900 | $rectangle['zIndex'] = ''; // The zIndex of the rectangle. If two rectangles overlap, the rectangle with the higher zIndex will appear on top 901 | 902 | $rectangle_output = ''; 903 | 904 | foreach ($params as $key => $value) { 905 | if (isset($rectangle[$key])) { 906 | $rectangle[$key] = $value; 907 | } 908 | } 909 | 910 | if ($rectangle['positionSW'] != "" && $rectangle['positionNE'] != "") { 911 | $lat_long_to_push = ''; 912 | if ($this->is_lat_long($rectangle['positionSW'])) { 913 | $lat_long_to_push = $rectangle['positionSW']; 914 | $rectangle_output .= ' 915 | var positionSW = new google.maps.LatLng('.$rectangle['positionSW'].') 916 | '; 917 | } else { 918 | $lat_long = $this->get_lat_long_from_address($rectangle['positionSW']); 919 | $rectangle_output .= ' 920 | var positionSW = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 921 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 922 | } 923 | $rectangle_output .= ' 924 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 925 | '; 926 | 927 | $lat_long_to_push = ''; 928 | if ($this->is_lat_long($rectangle['positionNE'])) { 929 | $lat_long_to_push = $rectangle['positionNE']; 930 | $rectangle_output .= ' 931 | var positionNE = new google.maps.LatLng('.$rectangle['positionNE'].') 932 | '; 933 | } else { 934 | $lat_long = $this->get_lat_long_from_address($rectangle['positionNE']); 935 | $rectangle_output .= ' 936 | var positionNE = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 937 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 938 | } 939 | $rectangle_output .= ' 940 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 941 | '; 942 | 943 | $rectangle_output .= ' 944 | var rectangleOptions = { 945 | strokeColor: "'.$rectangle['strokeColor'].'", 946 | strokeOpacity: '.$rectangle['strokeOpacity'].', 947 | strokeWeight: '.$rectangle['strokeWeight'].', 948 | fillColor: "'.$rectangle['fillColor'].'", 949 | fillOpacity: '.$rectangle['fillOpacity'].', 950 | map: '.$this->map_name.', 951 | bounds: new google.maps.LatLngBounds(positionSW, positionNE)'; 952 | if (!$rectangle['clickable']) { 953 | $rectangle_output .= ', 954 | clickable: false'; 955 | } 956 | if ($rectangle['zIndex'] != "" && is_numeric($rectangle['zIndex'])) { 957 | $rectangle_output .= ', 958 | zIndex: '.$rectangle['zIndex']; 959 | } 960 | $rectangle_output .= ' 961 | };'; 962 | 963 | $rectangle_output .= ' 964 | var rectangle_'.count($this->rectangles).' = new google.maps.Rectangle(rectangleOptions); 965 | '; 966 | 967 | if ($rectangle['onclick'] != "") { 968 | $rectangle_output .= ' 969 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "click", function() { 970 | '.$rectangle['onclick'].' 971 | }); 972 | '; 973 | } 974 | if ($rectangle['ondblclick'] != "") { 975 | $rectangle_output .= ' 976 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "dblclick", function() { 977 | '.$rectangle['ondblclick'].' 978 | }); 979 | '; 980 | } 981 | if ($rectangle['onmousedown'] != "") { 982 | $rectangle_output .= ' 983 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "mousedown", function() { 984 | '.$rectangle['onmousedown'].' 985 | }); 986 | '; 987 | } 988 | if ($rectangle['onmousemove'] != "") { 989 | $rectangle_output .= ' 990 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "mousemove", function() { 991 | '.$rectangle['onmousemove'].' 992 | }); 993 | '; 994 | } 995 | if ($rectangle['onmouseout'] != "") { 996 | $rectangle_output .= ' 997 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "mouseout", function() { 998 | '.$rectangle['onmouseout'].' 999 | }); 1000 | '; 1001 | } 1002 | if ($rectangle['onmouseover'] != "") { 1003 | $rectangle_output .= ' 1004 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "mouseover", function() { 1005 | '.$rectangle['onmouseover'].' 1006 | }); 1007 | '; 1008 | } 1009 | if ($rectangle['onmouseup'] != "") { 1010 | $rectangle_output .= ' 1011 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "mouseup", function() { 1012 | '.$rectangle['onmouseup'].' 1013 | }); 1014 | '; 1015 | } 1016 | if ($rectangle['onrightclick'] != "") { 1017 | $rectangle_output .= ' 1018 | google.maps.event.addListener(rectangle_'.count($this->rectangles).', "rightclick", function() { 1019 | '.$rectangle['onrightclick'].' 1020 | }); 1021 | '; 1022 | } 1023 | 1024 | array_push($this->rectangles, $rectangle_output); 1025 | } 1026 | } 1027 | 1028 | public function add_ground_overlay($params = array()) 1029 | { 1030 | $overlay = array(); 1031 | 1032 | $overlay['image'] = ''; // JavaScript performed when a ground overlay is clicked 1033 | $overlay['positionSW'] = ''; // The South-West position (latitude/longitude coordinate OR addresse) at which the ground overlay will appear 1034 | $overlay['positionNE'] = ''; // The North-East position (latitude/longitude coordinate OR addresse) at which the ground overlay will appear 1035 | $overlay['clickable'] = true; // Defines if the ground overlay is clickable 1036 | $overlay['onclick'] = ''; // JavaScript performed when a ground overlay is clicked 1037 | 1038 | $overlay_output = ''; 1039 | 1040 | foreach ($params as $key => $value) { 1041 | if (isset($overlay[$key])) { 1042 | $overlay[$key] = $value; 1043 | } 1044 | } 1045 | 1046 | if ($overlay['image'] != "" && $overlay['positionSW'] != "" && $overlay['positionNE'] != "") { 1047 | $lat_long_to_push = ''; 1048 | if ($this->is_lat_long($overlay['positionSW'])) { 1049 | $lat_long_to_push = $overlay['positionSW']; 1050 | $overlay_output .= ' 1051 | var positionSW = new google.maps.LatLng('.$overlay['positionSW'].') 1052 | '; 1053 | } else { 1054 | $lat_long = $this->get_lat_long_from_address($overlay['positionSW']); 1055 | $overlay_output .= ' 1056 | var positionSW = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 1057 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 1058 | } 1059 | $overlay_output .= ' 1060 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 1061 | '; 1062 | 1063 | $lat_long_to_push = ''; 1064 | if ($this->is_lat_long($overlay['positionNE'])) { 1065 | $lat_long_to_push = $overlay['positionNE']; 1066 | $overlay_output .= ' 1067 | var positionNE = new google.maps.LatLng('.$overlay['positionNE'].') 1068 | '; 1069 | } else { 1070 | $lat_long = $this->get_lat_long_from_address($overlay['positionNE']); 1071 | $overlay_output .= ' 1072 | var positionNE = new google.maps.LatLng('.$lat_long[0].', '.$lat_long[1].')'; 1073 | $lat_long_to_push = $lat_long[0].', '.$lat_long[1]; 1074 | } 1075 | $overlay_output .= ' 1076 | lat_longs_'.$this->map_name.'.push(new google.maps.LatLng('.$lat_long_to_push.')); 1077 | '; 1078 | 1079 | $overlay_output .= ' 1080 | var overlay_'.count($this->overlays).' = new google.maps.GroundOverlay("'.$overlay['image'].'", new google.maps.LatLngBounds(positionSW, positionNE), { map: '.$this->map_name; 1081 | if (!$overlay['clickable']) { 1082 | $overlay_output .= ', clickable: false'; 1083 | } 1084 | $overlay_output .= '}); 1085 | '; 1086 | 1087 | if ($overlay['onclick'] != "") { 1088 | $overlay_output .= ' 1089 | google.maps.event.addListener(overlay_'.count($this->overlays).', "click", function() { 1090 | '.$overlay['onclick'].' 1091 | }); 1092 | '; 1093 | } 1094 | 1095 | array_push($this->overlays, $overlay_output); 1096 | } 1097 | } 1098 | 1099 | public function create_map() 1100 | { 1101 | $this->output_js = ''; 1102 | $this->output_js_contents = ''; 1103 | $this->output_html = ''; 1104 | 1105 | $host = 'https'; 1106 | if(empty($_SERVER['HTTPS'])){ 1107 | $host = 'http'; 1108 | } 1109 | 1110 | if ($this->maps_loaded == 0) { 1111 | if ($this->apiKey != "") { 1112 | $apiLocation = $host.'://maps.googleapis.com/maps/api/js?key='.$this->apiKey.'&sensor='.$this->sensor; 1113 | } else { 1114 | $apiLocation = $host.'://maps.google.com/maps/api/js?sensor='.$this->sensor; 1115 | } 1116 | $apiLocation .= 'sensor='.$this->sensor; //Sensor feature depreciated by google API V3 1117 | if ($this->version != "") { 1118 | $apiLocation .= '&v='.$this->version; 1119 | } 1120 | if ($this->region != "" && strlen($this->region) == 2) { 1121 | $apiLocation .= '®ion='.strtoupper($this->region); 1122 | } 1123 | if ($this->language != "") { 1124 | $apiLocation .= '&language='.$this->language; 1125 | } 1126 | $libraries = array(); 1127 | if ($this->adsense != "") { 1128 | array_push($libraries, 'adsense'); 1129 | } 1130 | if ($this->places != "") { 1131 | array_push($libraries, 'places'); 1132 | } 1133 | if ($this->panoramio) { 1134 | array_push($libraries, 'panoramio'); 1135 | } 1136 | if ($this->drawing) { 1137 | array_push($libraries, 'drawing'); 1138 | } 1139 | if (count($libraries)) { 1140 | $apiLocation .= '&libraries='.implode(",", $libraries); 1141 | } 1142 | 1143 | if (!$this->loadAsynchronously) { 1144 | $this->output_js .= ' 1145 | 1146 | '; 1147 | } 1148 | 1149 | if ($this->cluster) { 1150 | $this->output_js .= ' 1151 | 1152 | 1153 | '; 1154 | } 1155 | } 1156 | if ($this->jsfile == "") { 1157 | $this->output_js .= ' 1158 | '; 2315 | } 2316 | } 2317 | } 2318 | 2319 | if ($this->jsfile == "") { 2320 | $this->output_js .= ' 2321 | //]]> 2322 | '; 2323 | } 2324 | 2325 | // set height and width 2326 | if (is_numeric($this->map_width)) { // if no width type set 2327 | $this->map_width = $this->map_width.'px'; 2328 | } 2329 | if (is_numeric($this->map_height)) { // if no height type set 2330 | $this->map_height = $this->map_height.'px'; 2331 | } 2332 | // 2333 | 2334 | $this->output_html .= '
class != "") ? ' class="'.$this->class.'"' : '').'>
'; 2335 | 2336 | ++$this->maps_loaded; 2337 | 2338 | return array('js' => $this->output_js, 'html' => $this->output_html, 'markers' => $this->markersInfo); 2339 | } 2340 | 2341 | public function is_lat_long($input) 2342 | { 2343 | $input = str_replace(", ", ",", trim($input)); 2344 | $input = explode(",", $input); 2345 | if (count($input) == 2) { 2346 | if (is_numeric($input[0]) && is_numeric($input[1])) { // is a lat long 2347 | return true; 2348 | } else { // not a lat long - incorrect values 2349 | return false; 2350 | } 2351 | } else { // not a lat long - too many parts 2352 | return false; 2353 | } 2354 | } 2355 | 2356 | public function get_lat_long_from_address($address, $attempts = 0) 2357 | { 2358 | $lat = 0; 2359 | $lng = 0; 2360 | 2361 | $error = ''; 2362 | 2363 | if ($this->geocodeCaching) { // if caching of geocode requests is activated 2364 | 2365 | $geocache = DB::table($this->geoCacheTableName)->select("latitude","longitude")->where("address", trim(strtolower($address)))->first(); 2366 | 2367 | if ($geocache) { 2368 | 2369 | return array($geocache->latitude, $geocache->longitude); 2370 | } 2371 | } 2372 | 2373 | $data_location = "https://maps.google.com/maps/api/geocode/json?address=".urlencode(utf8_encode($address))."&sensor=".$this->sensor."&key=".$this->apiKey; 2374 | if ($this->region != "" && strlen($this->region) == 2) { 2375 | $data_location .= "®ion=".$this->region; 2376 | } 2377 | 2378 | $context = null; 2379 | $proxy = config('googlemaps.http_proxy'); 2380 | if (!empty($proxy)) { 2381 | $context = stream_context_create([ 2382 | 'http' => [ 2383 | 'proxy' => $proxy, 2384 | 'request_fulluri' => true, 2385 | ] 2386 | ]); 2387 | } 2388 | 2389 | $data = file_get_contents($data_location, false, $context); 2390 | 2391 | $data = json_decode($data); 2392 | 2393 | if ($data->status == "OK") { 2394 | $lat = $data->results[0]->geometry->location->lat; 2395 | $lng = $data->results[0]->geometry->location->lng; 2396 | 2397 | if ($this->geocodeCaching) { // if we to need to cache this result 2398 | if ($address != "" && $lat != 0 && $lng != 0) { 2399 | $data = array( 2400 | "address" => trim(strtolower($address)), 2401 | "latitude" => $lat, 2402 | "longitude" => $lng, 2403 | ); 2404 | DB::table($this->geoCacheTableName)->insert($data); 2405 | } 2406 | } 2407 | } else { 2408 | if ($data->status == "OVER_QUERY_LIMIT") { 2409 | $error = $data->status; 2410 | if ($attempts < 2) { 2411 | sleep(1); 2412 | ++$attempts; 2413 | list($lat, $lng, $error) = $this->get_lat_long_from_address($address, $attempts); 2414 | } 2415 | } 2416 | } 2417 | 2418 | return array($lat, $lng, $error); 2419 | } 2420 | 2421 | 2422 | /** 2423 | * This method will check markers are inside geofence or not 2424 | * @param $polygon array() -- polygon first and last value of array should be same otherwise result will be accurate 2425 | * @param $latlngs array() 2426 | * 2427 | * return @array 2428 | * 2429 | * EXAMPLE::: 2430 | * $latlngs = array("50,70","70,40","-20,30","100,10","-10,-10","40,-20","110,-20"); 2431 | * $polygon = array("-50,30","50,70","100,50","80,10","110,-10","110,-30","-20,-50","-30,-40","10,-10","-10,10","-30,-20","-50,30"); 2432 | */ 2433 | public function isMarkerInsideGeofence($polygon, $latlngs){ 2434 | $cls = new isInsidePolygon(); 2435 | $output = []; 2436 | foreach($latlngs as $key => $point) { 2437 | $output[$key] = $cls->pointInPolygon($point, $polygon); 2438 | } 2439 | return $output; 2440 | } 2441 | 2442 | public function getMapName(){ 2443 | return $this->map_name; 2444 | } 2445 | } 2446 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/GMapsServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 23 | __DIR__.'/Publishes/config/googlemaps.php' => config_path('googlemaps.php') 24 | ], 'config'); 25 | 26 | $timestamp = date('Y_m_d_His', time()); 27 | $this->publishes([ 28 | __DIR__.'/Publishes/database/migrations/create_gmaps_geocache_table.php' => database_path('migrations') . '/' . $timestamp . '_create_gmaps_geocache_table.php' 29 | ], 'migrations'); 30 | 31 | $this->publishes([ 32 | __DIR__.'/Publishes/public/libs/' => public_path('libs') 33 | ], 'public'); 34 | } 35 | 36 | /** 37 | * Register the service provider. 38 | * 39 | * @return void 40 | */ 41 | public function register() 42 | { 43 | $this->app->bind('GMaps', function ($app) { 44 | return new GMaps(); 45 | }); 46 | 47 | } 48 | 49 | /** 50 | * Get the services provided by the provider. 51 | * 52 | * @return array 53 | */ 54 | public function provides() 55 | { 56 | return array('GMaps'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/Publishes/config/googlemaps.php: -------------------------------------------------------------------------------- 1 | env('GOOGLE_MAPS_API_KEY', 'YOUR_GOOGLE_MAPS_API_KEY'), //Get API key: https://code.google.com/apis/console 15 | 'adsense_publisher_id' => env('GOOGLE_ADSENSE_PUBLISHER_ID', ''), //Google AdSense publisher ID 16 | 17 | 'geocode' => [ 18 | 'cache' => false, //Geocode caching into database 19 | 'table_name' => 'gmaps_geocache', //Geocode caching database table name 20 | ], 21 | 22 | 'css_class' => '', //Your custom css class 23 | 24 | 'http_proxy' => env('HTTP_PROXY', null), // Proxy host and port 25 | ]; 26 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/Publishes/database/migrations/create_gmaps_geocache_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->text('address'); 19 | $table->string('latitude'); 20 | $table->string('longitude'); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::drop('gmaps_geocache'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/Publishes/public/libs/FarhanWazir/GMaps/markerclusterer.js: -------------------------------------------------------------------------------- 1 | // ==ClosureCompiler== 2 | // @compilation_level ADVANCED_OPTIMIZATIONS 3 | // @externs_url https://raw.githubusercontent.com/google/closure-compiler/master/contrib/externs/maps/google_maps_api_v3.js 4 | // ==/ClosureCompiler== 5 | 6 | /** 7 | * @name MarkerClusterer for Google Maps v3 8 | * @version version 1.0 9 | * @author Luke Mahe 10 | * @fileoverview 11 | * The library creates and manages per-zoom-level clusters for large amounts of 12 | * markers. 13 | *
14 | * This is a v3 implementation of the 15 | * v2 MarkerClusterer. 17 | */ 18 | 19 | /** 20 | * @license 21 | * Copyright 2010 Google Inc. All Rights Reserved. 22 | * 23 | * Licensed under the Apache License, Version 2.0 (the "License"); 24 | * you may not use this file except in compliance with the License. 25 | * You may obtain a copy of the License at 26 | * 27 | * http://www.apache.org/licenses/LICENSE-2.0 28 | * 29 | * Unless required by applicable law or agreed to in writing, software 30 | * distributed under the License is distributed on an "AS IS" BASIS, 31 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 32 | * See the License for the specific language governing permissions and 33 | * limitations under the License. 34 | */ 35 | 36 | 37 | /** 38 | * A Marker Clusterer that clusters markers. 39 | * 40 | * @param {google.maps.Map} map The Google map to attach to. 41 | * @param {Array.=} opt_markers Optional markers to add to 42 | * the cluster. 43 | * @param {Object=} opt_options support the following options: 44 | * 'gridSize': (number) The grid size of a cluster in pixels. 45 | * 'maxZoom': (number) The maximum zoom level that a marker can be part of a 46 | * cluster. 47 | * 'zoomOnClick': (boolean) Whether the default behaviour of clicking on a 48 | * cluster is to zoom into it. 49 | * 'averageCenter': (boolean) Whether the center of each cluster should be 50 | * the average of all markers in the cluster. 51 | * 'minimumClusterSize': (number) The minimum number of markers to be in a 52 | * cluster before the markers are hidden and a count 53 | * is shown. 54 | * 'styles': (object) An object that has style properties: 55 | * 'url': (string) The image url. 56 | * 'height': (number) The image height. 57 | * 'width': (number) The image width. 58 | * 'anchor': (Array) The anchor position of the label text. 59 | * 'textColor': (string) The text color. 60 | * 'textSize': (number) The text size. 61 | * 'backgroundPosition': (string) The position of the backgound x, y. 62 | * 'iconAnchor': (Array) The anchor position of the icon x, y. 63 | * @constructor 64 | * @extends google.maps.OverlayView 65 | */ 66 | function MarkerClusterer(map, opt_markers, opt_options) { 67 | // MarkerClusterer implements google.maps.OverlayView interface. We use the 68 | // extend function to extend MarkerClusterer with google.maps.OverlayView 69 | // because it might not always be available when the code is defined so we 70 | // look for it at the last possible moment. If it doesn't exist now then 71 | // there is no point going ahead :) 72 | this.extend(MarkerClusterer, google.maps.OverlayView); 73 | this.map_ = map; 74 | 75 | /** 76 | * @type {Array.} 77 | * @private 78 | */ 79 | this.markers_ = []; 80 | 81 | /** 82 | * @type {Array.} 83 | */ 84 | this.clusters_ = []; 85 | 86 | this.sizes = [53, 56, 66, 78, 90]; 87 | 88 | /** 89 | * @private 90 | */ 91 | this.styles_ = []; 92 | 93 | /** 94 | * @type {boolean} 95 | * @private 96 | */ 97 | this.ready_ = false; 98 | 99 | var options = opt_options || {}; 100 | 101 | /** 102 | * @type {number} 103 | * @private 104 | */ 105 | this.gridSize_ = options['gridSize'] || 60; 106 | 107 | /** 108 | * @private 109 | */ 110 | this.minClusterSize_ = options['minimumClusterSize'] || 2; 111 | 112 | 113 | /** 114 | * @type {?number} 115 | * @private 116 | */ 117 | this.maxZoom_ = options['maxZoom'] || null; 118 | 119 | this.styles_ = options['styles'] || []; 120 | 121 | /** 122 | * @type {string} 123 | * @private 124 | */ 125 | this.imagePath_ = options['imagePath'] || 126 | this.MARKER_CLUSTER_IMAGE_PATH_; 127 | 128 | /** 129 | * @type {string} 130 | * @private 131 | */ 132 | this.imageExtension_ = options['imageExtension'] || 133 | this.MARKER_CLUSTER_IMAGE_EXTENSION_; 134 | 135 | /** 136 | * @type {boolean} 137 | * @private 138 | */ 139 | this.zoomOnClick_ = true; 140 | 141 | if (options['zoomOnClick'] != undefined) { 142 | this.zoomOnClick_ = options['zoomOnClick']; 143 | } 144 | 145 | /** 146 | * @type {boolean} 147 | * @private 148 | */ 149 | this.averageCenter_ = false; 150 | 151 | if (options['averageCenter'] != undefined) { 152 | this.averageCenter_ = options['averageCenter']; 153 | } 154 | 155 | this.setupStyles_(); 156 | 157 | this.setMap(map); 158 | 159 | /** 160 | * @type {number} 161 | * @private 162 | */ 163 | this.prevZoom_ = this.map_.getZoom(); 164 | 165 | // Add the map event listeners 166 | var that = this; 167 | google.maps.event.addListener(this.map_, 'zoom_changed', function() { 168 | var zoom = that.map_.getZoom(); 169 | 170 | if (that.prevZoom_ != zoom) { 171 | that.prevZoom_ = zoom; 172 | that.resetViewport(); 173 | } 174 | }); 175 | 176 | google.maps.event.addListener(this.map_, 'idle', function() { 177 | that.redraw(); 178 | }); 179 | 180 | // Finally, add the markers 181 | if (opt_markers && opt_markers.length) { 182 | this.addMarkers(opt_markers, false); 183 | } 184 | } 185 | 186 | 187 | /** 188 | * The marker cluster image path. 189 | * 190 | * @type {string} 191 | * @private 192 | */ 193 | MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_PATH_ = '../images/m'; 194 | 195 | 196 | /** 197 | * The marker cluster image path. 198 | * 199 | * @type {string} 200 | * @private 201 | */ 202 | MarkerClusterer.prototype.MARKER_CLUSTER_IMAGE_EXTENSION_ = 'png'; 203 | 204 | 205 | /** 206 | * Extends a objects prototype by anothers. 207 | * 208 | * @param {Object} obj1 The object to be extended. 209 | * @param {Object} obj2 The object to extend with. 210 | * @return {Object} The new extended object. 211 | * @ignore 212 | */ 213 | MarkerClusterer.prototype.extend = function(obj1, obj2) { 214 | return (function(object) { 215 | for (var property in object.prototype) { 216 | this.prototype[property] = object.prototype[property]; 217 | } 218 | return this; 219 | }).apply(obj1, [obj2]); 220 | }; 221 | 222 | 223 | /** 224 | * Implementaion of the interface method. 225 | * @ignore 226 | */ 227 | MarkerClusterer.prototype.onAdd = function() { 228 | this.setReady_(true); 229 | }; 230 | 231 | /** 232 | * Implementaion of the interface method. 233 | * @ignore 234 | */ 235 | MarkerClusterer.prototype.draw = function() {}; 236 | 237 | /** 238 | * Sets up the styles object. 239 | * 240 | * @private 241 | */ 242 | MarkerClusterer.prototype.setupStyles_ = function() { 243 | if (this.styles_.length) { 244 | return; 245 | } 246 | 247 | for (var i = 0, size; size = this.sizes[i]; i++) { 248 | this.styles_.push({ 249 | url: this.imagePath_ + (i + 1) + '.' + this.imageExtension_, 250 | height: size, 251 | width: size 252 | }); 253 | } 254 | }; 255 | 256 | /** 257 | * Fit the map to the bounds of the markers in the clusterer. 258 | */ 259 | MarkerClusterer.prototype.fitMapToMarkers = function() { 260 | var markers = this.getMarkers(); 261 | var bounds = new google.maps.LatLngBounds(); 262 | for (var i = 0, marker; marker = markers[i]; i++) { 263 | bounds.extend(marker.getPosition()); 264 | } 265 | 266 | this.map_.fitBounds(bounds); 267 | }; 268 | 269 | 270 | /** 271 | * Sets the styles. 272 | * 273 | * @param {Object} styles The style to set. 274 | */ 275 | MarkerClusterer.prototype.setStyles = function(styles) { 276 | this.styles_ = styles; 277 | }; 278 | 279 | 280 | /** 281 | * Gets the styles. 282 | * 283 | * @return {Object} The styles object. 284 | */ 285 | MarkerClusterer.prototype.getStyles = function() { 286 | return this.styles_; 287 | }; 288 | 289 | 290 | /** 291 | * Whether zoom on click is set. 292 | * 293 | * @return {boolean} True if zoomOnClick_ is set. 294 | */ 295 | MarkerClusterer.prototype.isZoomOnClick = function() { 296 | return this.zoomOnClick_; 297 | }; 298 | 299 | /** 300 | * Whether average center is set. 301 | * 302 | * @return {boolean} True if averageCenter_ is set. 303 | */ 304 | MarkerClusterer.prototype.isAverageCenter = function() { 305 | return this.averageCenter_; 306 | }; 307 | 308 | 309 | /** 310 | * Returns the array of markers in the clusterer. 311 | * 312 | * @return {Array.} The markers. 313 | */ 314 | MarkerClusterer.prototype.getMarkers = function() { 315 | return this.markers_; 316 | }; 317 | 318 | 319 | /** 320 | * Returns the number of markers in the clusterer 321 | * 322 | * @return {Number} The number of markers. 323 | */ 324 | MarkerClusterer.prototype.getTotalMarkers = function() { 325 | return this.markers_.length; 326 | }; 327 | 328 | 329 | /** 330 | * Sets the max zoom for the clusterer. 331 | * 332 | * @param {number} maxZoom The max zoom level. 333 | */ 334 | MarkerClusterer.prototype.setMaxZoom = function(maxZoom) { 335 | this.maxZoom_ = maxZoom; 336 | }; 337 | 338 | 339 | /** 340 | * Gets the max zoom for the clusterer. 341 | * 342 | * @return {number} The max zoom level. 343 | */ 344 | MarkerClusterer.prototype.getMaxZoom = function() { 345 | return this.maxZoom_; 346 | }; 347 | 348 | 349 | /** 350 | * The function for calculating the cluster icon image. 351 | * 352 | * @param {Array.} markers The markers in the clusterer. 353 | * @param {number} numStyles The number of styles available. 354 | * @return {Object} A object properties: 'text' (string) and 'index' (number). 355 | * @private 356 | */ 357 | MarkerClusterer.prototype.calculator_ = function(markers, numStyles) { 358 | var index = 0; 359 | var count = markers.length; 360 | var dv = count; 361 | while (dv !== 0) { 362 | dv = parseInt(dv / 10, 10); 363 | index++; 364 | } 365 | 366 | index = Math.min(index, numStyles); 367 | return { 368 | text: count, 369 | index: index 370 | }; 371 | }; 372 | 373 | 374 | /** 375 | * Set the calculator function. 376 | * 377 | * @param {function(Array, number)} calculator The function to set as the 378 | * calculator. The function should return a object properties: 379 | * 'text' (string) and 'index' (number). 380 | * 381 | */ 382 | MarkerClusterer.prototype.setCalculator = function(calculator) { 383 | this.calculator_ = calculator; 384 | }; 385 | 386 | 387 | /** 388 | * Get the calculator function. 389 | * 390 | * @return {function(Array, number)} the calculator function. 391 | */ 392 | MarkerClusterer.prototype.getCalculator = function() { 393 | return this.calculator_; 394 | }; 395 | 396 | 397 | /** 398 | * Add an array of markers to the clusterer. 399 | * 400 | * @param {Array.} markers The markers to add. 401 | * @param {boolean=} opt_nodraw Whether to redraw the clusters. 402 | */ 403 | MarkerClusterer.prototype.addMarkers = function(markers, opt_nodraw) { 404 | for (var i = 0, marker; marker = markers[i]; i++) { 405 | this.pushMarkerTo_(marker); 406 | } 407 | if (!opt_nodraw) { 408 | this.redraw(); 409 | } 410 | }; 411 | 412 | 413 | /** 414 | * Pushes a marker to the clusterer. 415 | * 416 | * @param {google.maps.Marker} marker The marker to add. 417 | * @private 418 | */ 419 | MarkerClusterer.prototype.pushMarkerTo_ = function(marker) { 420 | marker.isAdded = false; 421 | if (marker['draggable']) { 422 | // If the marker is draggable add a listener so we update the clusters on 423 | // the drag end. 424 | var that = this; 425 | google.maps.event.addListener(marker, 'dragend', function() { 426 | marker.isAdded = false; 427 | that.repaint(); 428 | }); 429 | } 430 | this.markers_.push(marker); 431 | }; 432 | 433 | 434 | /** 435 | * Adds a marker to the clusterer and redraws if needed. 436 | * 437 | * @param {google.maps.Marker} marker The marker to add. 438 | * @param {boolean=} opt_nodraw Whether to redraw the clusters. 439 | */ 440 | MarkerClusterer.prototype.addMarker = function(marker, opt_nodraw) { 441 | this.pushMarkerTo_(marker); 442 | if (!opt_nodraw) { 443 | this.redraw(); 444 | } 445 | }; 446 | 447 | 448 | /** 449 | * Removes a marker and returns true if removed, false if not 450 | * 451 | * @param {google.maps.Marker} marker The marker to remove 452 | * @return {boolean} Whether the marker was removed or not 453 | * @private 454 | */ 455 | MarkerClusterer.prototype.removeMarker_ = function(marker) { 456 | var index = -1; 457 | if (this.markers_.indexOf) { 458 | index = this.markers_.indexOf(marker); 459 | } else { 460 | for (var i = 0, m; m = this.markers_[i]; i++) { 461 | if (m == marker) { 462 | index = i; 463 | break; 464 | } 465 | } 466 | } 467 | 468 | if (index == -1) { 469 | // Marker is not in our list of markers. 470 | return false; 471 | } 472 | 473 | marker.setMap(null); 474 | 475 | this.markers_.splice(index, 1); 476 | 477 | return true; 478 | }; 479 | 480 | 481 | /** 482 | * Remove a marker from the cluster. 483 | * 484 | * @param {google.maps.Marker} marker The marker to remove. 485 | * @param {boolean=} opt_nodraw Optional boolean to force no redraw. 486 | * @return {boolean} True if the marker was removed. 487 | */ 488 | MarkerClusterer.prototype.removeMarker = function(marker, opt_nodraw) { 489 | var removed = this.removeMarker_(marker); 490 | 491 | if (!opt_nodraw && removed) { 492 | this.resetViewport(); 493 | this.redraw(); 494 | return true; 495 | } else { 496 | return false; 497 | } 498 | }; 499 | 500 | 501 | /** 502 | * Removes an array of markers from the cluster. 503 | * 504 | * @param {Array.} markers The markers to remove. 505 | * @param {boolean=} opt_nodraw Optional boolean to force no redraw. 506 | */ 507 | MarkerClusterer.prototype.removeMarkers = function(markers, opt_nodraw) { 508 | var removed = false; 509 | 510 | for (var i = 0, marker; marker = markers[i]; i++) { 511 | var r = this.removeMarker_(marker); 512 | removed = removed || r; 513 | } 514 | 515 | if (!opt_nodraw && removed) { 516 | this.resetViewport(); 517 | this.redraw(); 518 | return true; 519 | } 520 | }; 521 | 522 | 523 | /** 524 | * Sets the clusterer's ready state. 525 | * 526 | * @param {boolean} ready The state. 527 | * @private 528 | */ 529 | MarkerClusterer.prototype.setReady_ = function(ready) { 530 | if (!this.ready_) { 531 | this.ready_ = ready; 532 | this.createClusters_(); 533 | } 534 | }; 535 | 536 | 537 | /** 538 | * Returns the number of clusters in the clusterer. 539 | * 540 | * @return {number} The number of clusters. 541 | */ 542 | MarkerClusterer.prototype.getTotalClusters = function() { 543 | return this.clusters_.length; 544 | }; 545 | 546 | 547 | /** 548 | * Returns the google map that the clusterer is associated with. 549 | * 550 | * @return {google.maps.Map} The map. 551 | */ 552 | MarkerClusterer.prototype.getMap = function() { 553 | return this.map_; 554 | }; 555 | 556 | 557 | /** 558 | * Sets the google map that the clusterer is associated with. 559 | * 560 | * @param {google.maps.Map} map The map. 561 | */ 562 | MarkerClusterer.prototype.setMap = function(map) { 563 | this.map_ = map; 564 | }; 565 | 566 | 567 | /** 568 | * Returns the size of the grid. 569 | * 570 | * @return {number} The grid size. 571 | */ 572 | MarkerClusterer.prototype.getGridSize = function() { 573 | return this.gridSize_; 574 | }; 575 | 576 | 577 | /** 578 | * Sets the size of the grid. 579 | * 580 | * @param {number} size The grid size. 581 | */ 582 | MarkerClusterer.prototype.setGridSize = function(size) { 583 | this.gridSize_ = size; 584 | }; 585 | 586 | 587 | /** 588 | * Returns the min cluster size. 589 | * 590 | * @return {number} The grid size. 591 | */ 592 | MarkerClusterer.prototype.getMinClusterSize = function() { 593 | return this.minClusterSize_; 594 | }; 595 | 596 | /** 597 | * Sets the min cluster size. 598 | * 599 | * @param {number} size The grid size. 600 | */ 601 | MarkerClusterer.prototype.setMinClusterSize = function(size) { 602 | this.minClusterSize_ = size; 603 | }; 604 | 605 | 606 | /** 607 | * Extends a bounds object by the grid size. 608 | * 609 | * @param {google.maps.LatLngBounds} bounds The bounds to extend. 610 | * @return {google.maps.LatLngBounds} The extended bounds. 611 | */ 612 | MarkerClusterer.prototype.getExtendedBounds = function(bounds) { 613 | var projection = this.getProjection(); 614 | 615 | // Turn the bounds into latlng. 616 | var tr = new google.maps.LatLng(bounds.getNorthEast().lat(), 617 | bounds.getNorthEast().lng()); 618 | var bl = new google.maps.LatLng(bounds.getSouthWest().lat(), 619 | bounds.getSouthWest().lng()); 620 | 621 | // Convert the points to pixels and the extend out by the grid size. 622 | var trPix = projection.fromLatLngToDivPixel(tr); 623 | trPix.x += this.gridSize_; 624 | trPix.y -= this.gridSize_; 625 | 626 | var blPix = projection.fromLatLngToDivPixel(bl); 627 | blPix.x -= this.gridSize_; 628 | blPix.y += this.gridSize_; 629 | 630 | // Convert the pixel points back to LatLng 631 | var ne = projection.fromDivPixelToLatLng(trPix); 632 | var sw = projection.fromDivPixelToLatLng(blPix); 633 | 634 | // Extend the bounds to contain the new bounds. 635 | bounds.extend(ne); 636 | bounds.extend(sw); 637 | 638 | return bounds; 639 | }; 640 | 641 | 642 | /** 643 | * Determins if a marker is contained in a bounds. 644 | * 645 | * @param {google.maps.Marker} marker The marker to check. 646 | * @param {google.maps.LatLngBounds} bounds The bounds to check against. 647 | * @return {boolean} True if the marker is in the bounds. 648 | * @private 649 | */ 650 | MarkerClusterer.prototype.isMarkerInBounds_ = function(marker, bounds) { 651 | return bounds.contains(marker.getPosition()); 652 | }; 653 | 654 | 655 | /** 656 | * Clears all clusters and markers from the clusterer. 657 | */ 658 | MarkerClusterer.prototype.clearMarkers = function() { 659 | this.resetViewport(true); 660 | 661 | // Set the markers a empty array. 662 | this.markers_ = []; 663 | }; 664 | 665 | 666 | /** 667 | * Clears all existing clusters and recreates them. 668 | * @param {boolean} opt_hide To also hide the marker. 669 | */ 670 | MarkerClusterer.prototype.resetViewport = function(opt_hide) { 671 | // Remove all the clusters 672 | for (var i = 0, cluster; cluster = this.clusters_[i]; i++) { 673 | cluster.remove(); 674 | } 675 | 676 | // Reset the markers to not be added and to be invisible. 677 | for (var i = 0, marker; marker = this.markers_[i]; i++) { 678 | marker.isAdded = false; 679 | if (opt_hide) { 680 | marker.setMap(null); 681 | } 682 | } 683 | 684 | this.clusters_ = []; 685 | }; 686 | 687 | /** 688 | * 689 | */ 690 | MarkerClusterer.prototype.repaint = function() { 691 | var oldClusters = this.clusters_.slice(); 692 | this.clusters_.length = 0; 693 | this.resetViewport(); 694 | this.redraw(); 695 | 696 | // Remove the old clusters. 697 | // Do it in a timeout so the other clusters have been drawn first. 698 | window.setTimeout(function() { 699 | for (var i = 0, cluster; cluster = oldClusters[i]; i++) { 700 | cluster.remove(); 701 | } 702 | }, 0); 703 | }; 704 | 705 | 706 | /** 707 | * Redraws the clusters. 708 | */ 709 | MarkerClusterer.prototype.redraw = function() { 710 | this.createClusters_(); 711 | }; 712 | 713 | 714 | /** 715 | * Calculates the distance between two latlng locations in km. 716 | * @see http://www.movable-type.co.uk/scripts/latlong.html 717 | * 718 | * @param {google.maps.LatLng} p1 The first lat lng point. 719 | * @param {google.maps.LatLng} p2 The second lat lng point. 720 | * @return {number} The distance between the two points in km. 721 | * @private 722 | */ 723 | MarkerClusterer.prototype.distanceBetweenPoints_ = function(p1, p2) { 724 | if (!p1 || !p2) { 725 | return 0; 726 | } 727 | 728 | var R = 6371; // Radius of the Earth in km 729 | var dLat = (p2.lat() - p1.lat()) * Math.PI / 180; 730 | var dLon = (p2.lng() - p1.lng()) * Math.PI / 180; 731 | var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + 732 | Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * 733 | Math.sin(dLon / 2) * Math.sin(dLon / 2); 734 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 735 | var d = R * c; 736 | return d; 737 | }; 738 | 739 | 740 | /** 741 | * Add a marker to a cluster, or creates a new cluster. 742 | * 743 | * @param {google.maps.Marker} marker The marker to add. 744 | * @private 745 | */ 746 | MarkerClusterer.prototype.addToClosestCluster_ = function(marker) { 747 | var distance = 40000; // Some large number 748 | var clusterToAddTo = null; 749 | var pos = marker.getPosition(); 750 | for (var i = 0, cluster; cluster = this.clusters_[i]; i++) { 751 | var center = cluster.getCenter(); 752 | if (center) { 753 | var d = this.distanceBetweenPoints_(center, marker.getPosition()); 754 | if (d < distance) { 755 | distance = d; 756 | clusterToAddTo = cluster; 757 | } 758 | } 759 | } 760 | 761 | if (clusterToAddTo && clusterToAddTo.isMarkerInClusterBounds(marker)) { 762 | clusterToAddTo.addMarker(marker); 763 | } else { 764 | var cluster = new Cluster(this); 765 | cluster.addMarker(marker); 766 | this.clusters_.push(cluster); 767 | } 768 | }; 769 | 770 | 771 | /** 772 | * Creates the clusters. 773 | * 774 | * @private 775 | */ 776 | MarkerClusterer.prototype.createClusters_ = function() { 777 | if (!this.ready_) { 778 | return; 779 | } 780 | 781 | // Get our current map view bounds. 782 | // Create a new bounds object so we don't affect the map. 783 | var mapBounds = new google.maps.LatLngBounds(this.map_.getBounds().getSouthWest(), 784 | this.map_.getBounds().getNorthEast()); 785 | var bounds = this.getExtendedBounds(mapBounds); 786 | 787 | for (var i = 0, marker; marker = this.markers_[i]; i++) { 788 | if (!marker.isAdded && this.isMarkerInBounds_(marker, bounds)) { 789 | this.addToClosestCluster_(marker); 790 | } 791 | } 792 | }; 793 | 794 | 795 | /** 796 | * A cluster that contains markers. 797 | * 798 | * @param {MarkerClusterer} markerClusterer The markerclusterer that this 799 | * cluster is associated with. 800 | * @constructor 801 | * @ignore 802 | */ 803 | function Cluster(markerClusterer) { 804 | this.markerClusterer_ = markerClusterer; 805 | this.map_ = markerClusterer.getMap(); 806 | this.gridSize_ = markerClusterer.getGridSize(); 807 | this.minClusterSize_ = markerClusterer.getMinClusterSize(); 808 | this.averageCenter_ = markerClusterer.isAverageCenter(); 809 | this.center_ = null; 810 | this.markers_ = []; 811 | this.bounds_ = null; 812 | this.clusterIcon_ = new ClusterIcon(this, markerClusterer.getStyles(), 813 | markerClusterer.getGridSize()); 814 | } 815 | 816 | /** 817 | * Determins if a marker is already added to the cluster. 818 | * 819 | * @param {google.maps.Marker} marker The marker to check. 820 | * @return {boolean} True if the marker is already added. 821 | */ 822 | Cluster.prototype.isMarkerAlreadyAdded = function(marker) { 823 | if (this.markers_.indexOf) { 824 | return this.markers_.indexOf(marker) != -1; 825 | } else { 826 | for (var i = 0, m; m = this.markers_[i]; i++) { 827 | if (m == marker) { 828 | return true; 829 | } 830 | } 831 | } 832 | return false; 833 | }; 834 | 835 | 836 | /** 837 | * Add a marker the cluster. 838 | * 839 | * @param {google.maps.Marker} marker The marker to add. 840 | * @return {boolean} True if the marker was added. 841 | */ 842 | Cluster.prototype.addMarker = function(marker) { 843 | if (this.isMarkerAlreadyAdded(marker)) { 844 | return false; 845 | } 846 | 847 | if (!this.center_) { 848 | this.center_ = marker.getPosition(); 849 | this.calculateBounds_(); 850 | } else { 851 | if (this.averageCenter_) { 852 | var l = this.markers_.length + 1; 853 | var lat = (this.center_.lat() * (l-1) + marker.getPosition().lat()) / l; 854 | var lng = (this.center_.lng() * (l-1) + marker.getPosition().lng()) / l; 855 | this.center_ = new google.maps.LatLng(lat, lng); 856 | this.calculateBounds_(); 857 | } 858 | } 859 | 860 | marker.isAdded = true; 861 | this.markers_.push(marker); 862 | 863 | var len = this.markers_.length; 864 | if (len < this.minClusterSize_ && marker.getMap() != this.map_) { 865 | // Min cluster size not reached so show the marker. 866 | marker.setMap(this.map_); 867 | } 868 | 869 | if (len == this.minClusterSize_) { 870 | // Hide the markers that were showing. 871 | for (var i = 0; i < len; i++) { 872 | this.markers_[i].setMap(null); 873 | } 874 | } 875 | 876 | if (len >= this.minClusterSize_) { 877 | marker.setMap(null); 878 | } 879 | 880 | this.updateIcon(); 881 | return true; 882 | }; 883 | 884 | 885 | /** 886 | * Returns the marker clusterer that the cluster is associated with. 887 | * 888 | * @return {MarkerClusterer} The associated marker clusterer. 889 | */ 890 | Cluster.prototype.getMarkerClusterer = function() { 891 | return this.markerClusterer_; 892 | }; 893 | 894 | 895 | /** 896 | * Returns the bounds of the cluster. 897 | * 898 | * @return {google.maps.LatLngBounds} the cluster bounds. 899 | */ 900 | Cluster.prototype.getBounds = function() { 901 | var bounds = new google.maps.LatLngBounds(this.center_, this.center_); 902 | var markers = this.getMarkers(); 903 | for (var i = 0, marker; marker = markers[i]; i++) { 904 | bounds.extend(marker.getPosition()); 905 | } 906 | return bounds; 907 | }; 908 | 909 | 910 | /** 911 | * Removes the cluster 912 | */ 913 | Cluster.prototype.remove = function() { 914 | this.clusterIcon_.remove(); 915 | this.markers_.length = 0; 916 | delete this.markers_; 917 | }; 918 | 919 | 920 | /** 921 | * Returns the center of the cluster. 922 | * 923 | * @return {number} The cluster center. 924 | */ 925 | Cluster.prototype.getSize = function() { 926 | return this.markers_.length; 927 | }; 928 | 929 | 930 | /** 931 | * Returns the center of the cluster. 932 | * 933 | * @return {Array.} The cluster center. 934 | */ 935 | Cluster.prototype.getMarkers = function() { 936 | return this.markers_; 937 | }; 938 | 939 | 940 | /** 941 | * Returns the center of the cluster. 942 | * 943 | * @return {google.maps.LatLng} The cluster center. 944 | */ 945 | Cluster.prototype.getCenter = function() { 946 | return this.center_; 947 | }; 948 | 949 | 950 | /** 951 | * Calculated the extended bounds of the cluster with the grid. 952 | * 953 | * @private 954 | */ 955 | Cluster.prototype.calculateBounds_ = function() { 956 | var bounds = new google.maps.LatLngBounds(this.center_, this.center_); 957 | this.bounds_ = this.markerClusterer_.getExtendedBounds(bounds); 958 | }; 959 | 960 | 961 | /** 962 | * Determines if a marker lies in the clusters bounds. 963 | * 964 | * @param {google.maps.Marker} marker The marker to check. 965 | * @return {boolean} True if the marker lies in the bounds. 966 | */ 967 | Cluster.prototype.isMarkerInClusterBounds = function(marker) { 968 | return this.bounds_.contains(marker.getPosition()); 969 | }; 970 | 971 | 972 | /** 973 | * Returns the map that the cluster is associated with. 974 | * 975 | * @return {google.maps.Map} The map. 976 | */ 977 | Cluster.prototype.getMap = function() { 978 | return this.map_; 979 | }; 980 | 981 | 982 | /** 983 | * Updates the cluster icon 984 | */ 985 | Cluster.prototype.updateIcon = function() { 986 | var zoom = this.map_.getZoom(); 987 | var mz = this.markerClusterer_.getMaxZoom(); 988 | 989 | if (mz && zoom > mz) { 990 | // The zoom is greater than our max zoom so show all the markers in cluster. 991 | for (var i = 0, marker; marker = this.markers_[i]; i++) { 992 | marker.setMap(this.map_); 993 | } 994 | return; 995 | } 996 | 997 | if (this.markers_.length < this.minClusterSize_) { 998 | // Min cluster size not yet reached. 999 | this.clusterIcon_.hide(); 1000 | return; 1001 | } 1002 | 1003 | var numStyles = this.markerClusterer_.getStyles().length; 1004 | var sums = this.markerClusterer_.getCalculator()(this.markers_, numStyles); 1005 | this.clusterIcon_.setCenter(this.center_); 1006 | this.clusterIcon_.setSums(sums); 1007 | this.clusterIcon_.show(); 1008 | }; 1009 | 1010 | 1011 | /** 1012 | * A cluster icon 1013 | * 1014 | * @param {Cluster} cluster The cluster to be associated with. 1015 | * @param {Object} styles An object that has style properties: 1016 | * 'url': (string) The image url. 1017 | * 'height': (number) The image height. 1018 | * 'width': (number) The image width. 1019 | * 'anchor': (Array) The anchor position of the label text. 1020 | * 'textColor': (string) The text color. 1021 | * 'textSize': (number) The text size. 1022 | * 'backgroundPosition: (string) The background postition x, y. 1023 | * @param {number=} opt_padding Optional padding to apply to the cluster icon. 1024 | * @constructor 1025 | * @extends google.maps.OverlayView 1026 | * @ignore 1027 | */ 1028 | function ClusterIcon(cluster, styles, opt_padding) { 1029 | cluster.getMarkerClusterer().extend(ClusterIcon, google.maps.OverlayView); 1030 | 1031 | this.styles_ = styles; 1032 | this.padding_ = opt_padding || 0; 1033 | this.cluster_ = cluster; 1034 | this.center_ = null; 1035 | this.map_ = cluster.getMap(); 1036 | this.div_ = null; 1037 | this.sums_ = null; 1038 | this.visible_ = false; 1039 | 1040 | this.setMap(this.map_); 1041 | } 1042 | 1043 | 1044 | /** 1045 | * Triggers the clusterclick event and zoom's if the option is set. 1046 | * 1047 | * @param {google.maps.MouseEvent} event The event to propagate 1048 | */ 1049 | ClusterIcon.prototype.triggerClusterClick = function(event) { 1050 | var markerClusterer = this.cluster_.getMarkerClusterer(); 1051 | 1052 | // Trigger the clusterclick event. 1053 | google.maps.event.trigger(markerClusterer, 'clusterclick', this.cluster_, event); 1054 | 1055 | if (markerClusterer.isZoomOnClick()) { 1056 | // Zoom into the cluster. 1057 | this.map_.fitBounds(this.cluster_.getBounds()); 1058 | } 1059 | }; 1060 | 1061 | 1062 | /** 1063 | * Adding the cluster icon to the dom. 1064 | * @ignore 1065 | */ 1066 | ClusterIcon.prototype.onAdd = function() { 1067 | this.div_ = document.createElement('DIV'); 1068 | if (this.visible_) { 1069 | var pos = this.getPosFromLatLng_(this.center_); 1070 | this.div_.style.cssText = this.createCss(pos); 1071 | this.div_.innerHTML = this.sums_.text; 1072 | } 1073 | 1074 | var panes = this.getPanes(); 1075 | panes.overlayMouseTarget.appendChild(this.div_); 1076 | 1077 | var that = this; 1078 | var isDragging = false; 1079 | google.maps.event.addDomListener(this.div_, 'click', function(event) { 1080 | // Only perform click when not preceded by a drag 1081 | if (!isDragging) { 1082 | that.triggerClusterClick(event); 1083 | } 1084 | }); 1085 | google.maps.event.addDomListener(this.div_, 'mousedown', function() { 1086 | isDragging = false; 1087 | }); 1088 | google.maps.event.addDomListener(this.div_, 'mousemove', function() { 1089 | isDragging = true; 1090 | }); 1091 | }; 1092 | 1093 | 1094 | /** 1095 | * Returns the position to place the div dending on the latlng. 1096 | * 1097 | * @param {google.maps.LatLng} latlng The position in latlng. 1098 | * @return {google.maps.Point} The position in pixels. 1099 | * @private 1100 | */ 1101 | ClusterIcon.prototype.getPosFromLatLng_ = function(latlng) { 1102 | var pos = this.getProjection().fromLatLngToDivPixel(latlng); 1103 | 1104 | if (typeof this.iconAnchor_ === 'object' && this.iconAnchor_.length === 2) { 1105 | pos.x -= this.iconAnchor_[0]; 1106 | pos.y -= this.iconAnchor_[1]; 1107 | } else { 1108 | pos.x -= parseInt(this.width_ / 2, 10); 1109 | pos.y -= parseInt(this.height_ / 2, 10); 1110 | } 1111 | return pos; 1112 | }; 1113 | 1114 | 1115 | /** 1116 | * Draw the icon. 1117 | * @ignore 1118 | */ 1119 | ClusterIcon.prototype.draw = function() { 1120 | if (this.visible_) { 1121 | var pos = this.getPosFromLatLng_(this.center_); 1122 | this.div_.style.top = pos.y + 'px'; 1123 | this.div_.style.left = pos.x + 'px'; 1124 | } 1125 | }; 1126 | 1127 | 1128 | /** 1129 | * Hide the icon. 1130 | */ 1131 | ClusterIcon.prototype.hide = function() { 1132 | if (this.div_) { 1133 | this.div_.style.display = 'none'; 1134 | } 1135 | this.visible_ = false; 1136 | }; 1137 | 1138 | 1139 | /** 1140 | * Position and show the icon. 1141 | */ 1142 | ClusterIcon.prototype.show = function() { 1143 | if (this.div_) { 1144 | var pos = this.getPosFromLatLng_(this.center_); 1145 | this.div_.style.cssText = this.createCss(pos); 1146 | this.div_.style.display = ''; 1147 | } 1148 | this.visible_ = true; 1149 | }; 1150 | 1151 | 1152 | /** 1153 | * Remove the icon from the map 1154 | */ 1155 | ClusterIcon.prototype.remove = function() { 1156 | this.setMap(null); 1157 | }; 1158 | 1159 | 1160 | /** 1161 | * Implementation of the onRemove interface. 1162 | * @ignore 1163 | */ 1164 | ClusterIcon.prototype.onRemove = function() { 1165 | if (this.div_ && this.div_.parentNode) { 1166 | this.hide(); 1167 | this.div_.parentNode.removeChild(this.div_); 1168 | this.div_ = null; 1169 | } 1170 | }; 1171 | 1172 | 1173 | /** 1174 | * Set the sums of the icon. 1175 | * 1176 | * @param {Object} sums The sums containing: 1177 | * 'text': (string) The text to display in the icon. 1178 | * 'index': (number) The style index of the icon. 1179 | */ 1180 | ClusterIcon.prototype.setSums = function(sums) { 1181 | this.sums_ = sums; 1182 | this.text_ = sums.text; 1183 | this.index_ = sums.index; 1184 | if (this.div_) { 1185 | this.div_.innerHTML = sums.text; 1186 | } 1187 | 1188 | this.useStyle(); 1189 | }; 1190 | 1191 | 1192 | /** 1193 | * Sets the icon to the the styles. 1194 | */ 1195 | ClusterIcon.prototype.useStyle = function() { 1196 | var index = Math.max(0, this.sums_.index - 1); 1197 | index = Math.min(this.styles_.length - 1, index); 1198 | var style = this.styles_[index]; 1199 | this.url_ = style['url']; 1200 | this.height_ = style['height']; 1201 | this.width_ = style['width']; 1202 | this.textColor_ = style['textColor']; 1203 | this.anchor_ = style['anchor']; 1204 | this.textSize_ = style['textSize']; 1205 | this.backgroundPosition_ = style['backgroundPosition']; 1206 | this.iconAnchor_ = style['iconAnchor']; 1207 | }; 1208 | 1209 | 1210 | /** 1211 | * Sets the center of the icon. 1212 | * 1213 | * @param {google.maps.LatLng} center The latlng to set as the center. 1214 | */ 1215 | ClusterIcon.prototype.setCenter = function(center) { 1216 | this.center_ = center; 1217 | }; 1218 | 1219 | 1220 | /** 1221 | * Create the css text based on the position of the icon. 1222 | * 1223 | * @param {google.maps.Point} pos The position. 1224 | * @return {string} The css style text. 1225 | */ 1226 | ClusterIcon.prototype.createCss = function(pos) { 1227 | var style = []; 1228 | style.push('background-image:url(' + this.url_ + ');'); 1229 | var backgroundPosition = this.backgroundPosition_ ? this.backgroundPosition_ : '0 0'; 1230 | style.push('background-position:' + backgroundPosition + ';'); 1231 | 1232 | if (typeof this.anchor_ === 'object') { 1233 | if (typeof this.anchor_[0] === 'number' && this.anchor_[0] > 0 && 1234 | this.anchor_[0] < this.height_) { 1235 | style.push('height:' + (this.height_ - this.anchor_[0]) + 1236 | 'px; padding-top:' + this.anchor_[0] + 'px;'); 1237 | } else if (typeof this.anchor_[0] === 'number' && this.anchor_[0] < 0 && 1238 | -this.anchor_[0] < this.height_) { 1239 | style.push('height:' + this.height_ + 'px; line-height:' + (this.height_ + this.anchor_[0]) + 1240 | 'px;'); 1241 | } else { 1242 | style.push('height:' + this.height_ + 'px; line-height:' + this.height_ + 1243 | 'px;'); 1244 | } 1245 | if (typeof this.anchor_[1] === 'number' && this.anchor_[1] > 0 && 1246 | this.anchor_[1] < this.width_) { 1247 | style.push('width:' + (this.width_ - this.anchor_[1]) + 1248 | 'px; padding-left:' + this.anchor_[1] + 'px;'); 1249 | } else { 1250 | style.push('width:' + this.width_ + 'px; text-align:center;'); 1251 | } 1252 | } else { 1253 | style.push('height:' + this.height_ + 'px; line-height:' + 1254 | this.height_ + 'px; width:' + this.width_ + 'px; text-align:center;'); 1255 | } 1256 | 1257 | var txtColor = this.textColor_ ? this.textColor_ : 'black'; 1258 | var txtSize = this.textSize_ ? this.textSize_ : 11; 1259 | 1260 | style.push('cursor:pointer; top:' + pos.y + 'px; left:' + 1261 | pos.x + 'px; color:' + txtColor + '; position:absolute; font-size:' + 1262 | txtSize + 'px; font-family:Arial,sans-serif; font-weight:bold'); 1263 | return style.join(''); 1264 | }; 1265 | 1266 | 1267 | // Export Symbols for Closure 1268 | // If you are not going to compile with closure then you can remove the 1269 | // code below. 1270 | window['MarkerClusterer'] = MarkerClusterer; 1271 | MarkerClusterer.prototype['addMarker'] = MarkerClusterer.prototype.addMarker; 1272 | MarkerClusterer.prototype['addMarkers'] = MarkerClusterer.prototype.addMarkers; 1273 | MarkerClusterer.prototype['clearMarkers'] = 1274 | MarkerClusterer.prototype.clearMarkers; 1275 | MarkerClusterer.prototype['fitMapToMarkers'] = 1276 | MarkerClusterer.prototype.fitMapToMarkers; 1277 | MarkerClusterer.prototype['getCalculator'] = 1278 | MarkerClusterer.prototype.getCalculator; 1279 | MarkerClusterer.prototype['getGridSize'] = 1280 | MarkerClusterer.prototype.getGridSize; 1281 | MarkerClusterer.prototype['getExtendedBounds'] = 1282 | MarkerClusterer.prototype.getExtendedBounds; 1283 | MarkerClusterer.prototype['getMap'] = MarkerClusterer.prototype.getMap; 1284 | MarkerClusterer.prototype['getMarkers'] = MarkerClusterer.prototype.getMarkers; 1285 | MarkerClusterer.prototype['getMaxZoom'] = MarkerClusterer.prototype.getMaxZoom; 1286 | MarkerClusterer.prototype['getStyles'] = MarkerClusterer.prototype.getStyles; 1287 | MarkerClusterer.prototype['getTotalClusters'] = 1288 | MarkerClusterer.prototype.getTotalClusters; 1289 | MarkerClusterer.prototype['getTotalMarkers'] = 1290 | MarkerClusterer.prototype.getTotalMarkers; 1291 | MarkerClusterer.prototype['redraw'] = MarkerClusterer.prototype.redraw; 1292 | MarkerClusterer.prototype['removeMarker'] = 1293 | MarkerClusterer.prototype.removeMarker; 1294 | MarkerClusterer.prototype['removeMarkers'] = 1295 | MarkerClusterer.prototype.removeMarkers; 1296 | MarkerClusterer.prototype['resetViewport'] = 1297 | MarkerClusterer.prototype.resetViewport; 1298 | MarkerClusterer.prototype['repaint'] = 1299 | MarkerClusterer.prototype.repaint; 1300 | MarkerClusterer.prototype['setCalculator'] = 1301 | MarkerClusterer.prototype.setCalculator; 1302 | MarkerClusterer.prototype['setGridSize'] = 1303 | MarkerClusterer.prototype.setGridSize; 1304 | MarkerClusterer.prototype['setMaxZoom'] = 1305 | MarkerClusterer.prototype.setMaxZoom; 1306 | MarkerClusterer.prototype['onAdd'] = MarkerClusterer.prototype.onAdd; 1307 | MarkerClusterer.prototype['draw'] = MarkerClusterer.prototype.draw; 1308 | 1309 | Cluster.prototype['getCenter'] = Cluster.prototype.getCenter; 1310 | Cluster.prototype['getSize'] = Cluster.prototype.getSize; 1311 | Cluster.prototype['getMarkers'] = Cluster.prototype.getMarkers; 1312 | 1313 | ClusterIcon.prototype['onAdd'] = ClusterIcon.prototype.onAdd; 1314 | ClusterIcon.prototype['draw'] = ClusterIcon.prototype.draw; 1315 | ClusterIcon.prototype['onRemove'] = ClusterIcon.prototype.onRemove; 1316 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/example/Controllers/MapController.php: -------------------------------------------------------------------------------- 1 | gmap = $gmap; 17 | } 18 | 19 | public function index(){ 20 | 21 | /******** Custom Map Controls ********/ 22 | 23 | $leftTopControls = ['document.getElementById("leftTopControl")']; // values must be html or javascript element 24 | $this->gmap->injectControlsInLeftTop = $leftTopControls; // inject into map 25 | $leftCenterControls = ['document.getElementById("leftCenterControl")']; 26 | $this->gmap->injectControlsInLeftCenter = $leftCenterControls; 27 | $leftBottomControls = ['document.getElementById("leftBottomControl")']; 28 | $this->gmap->injectControlsInLeftBottom = $leftBottomControls; 29 | 30 | $bottomLeftControls = ['document.getElementById("bottomLeftControl")']; 31 | $this->gmap->injectControlsInBottomLeft = $bottomLeftControls; 32 | $bottomCenterControls = ['document.getElementById("bottomCenterControl")']; 33 | $this->gmap->injectControlsInBottomCenter = $bottomCenterControls; 34 | $bottomRightControls = ['document.getElementById("bottomRightControl")']; 35 | $this->gmap->injectControlsInBottomRight = $bottomRightControls; 36 | 37 | $rightTopControls = ['document.getElementById("rightTopControl")']; 38 | $this->gmap->injectControlsInRightTop = $rightTopControls; 39 | $rightCenterControls = ['document.getElementById("rightCenterControl")']; 40 | $this->gmap->injectControlsInRightCenter = $rightCenterControls; 41 | $rightBottomControls = ['document.getElementById("rightBottomControl")']; 42 | $this->gmap->injectControlsInRightBottom = $rightBottomControls; 43 | 44 | $topLeftControls = ['document.getElementById("topLeftControl")']; 45 | $this->gmap->injectControlsInTopLeft = $topLeftControls; 46 | $topCenterControls = ['document.getElementById("topCenterControl")']; 47 | $this->gmap->injectControlsInTopCenter = $topCenterControls; 48 | $topRightControls = ['document.getElementById("topRightControl")']; 49 | $this->gmap->injectControlsInTopRight = $topRightControls; 50 | 51 | /******** End Controls ********/ 52 | 53 | $config = array(); 54 | $config['map_height'] = "100%"; 55 | $config['center'] = 'Clifton, Karachi'; 56 | $config['onboundschanged'] = 'if (!centreGot) { 57 | var mapCentre = map.getCenter(); 58 | marker_0.setOptions({ 59 | position: new google.maps.LatLng(mapCentre.lat(), mapCentre.lng()) 60 | }); 61 | } 62 | centreGot = true;'; 63 | 64 | $this->gmap->initialize($config); // Initialize Map with custom configuration 65 | 66 | // set up the marker ready for positioning 67 | $marker = array(); 68 | $marker['draggable'] = true; 69 | $marker['ondragend'] = ' 70 | iw_'. $this->gmap->map_name .'.close(); 71 | reverseGeocode(event.latLng, function(status, result, mark){ 72 | if(status == 200){ 73 | iw_'. $this->gmap->map_name .'.setContent(result); 74 | iw_'. $this->gmap->map_name .'.open('. $this->gmap->map_name .', mark); 75 | } 76 | }, this); 77 | '; 78 | $this->gmap->add_marker($marker); 79 | 80 | $map = $this->gmap->create_map(); // This object will render javascript files and map view; you can call JS by $map['js'] and map view by $map['html'] 81 | 82 | return view('map', ['map' => $map]); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/FarhanWazir/GoogleMaps/example/Routes/routes.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | {!! $map['js'] !!} 7 | 8 | 9 |
10 |
11 |
12 | This is Left Top Control. 13 |
14 |
15 | This is Left Center Control. 16 |
17 |
18 | This is Left Bottom Control. 19 |
20 |
21 | This is Bottom Right Control. 22 |
23 |
24 | This is Bottom Center Control. 25 |
26 |
27 | This is Bottom Left Control. 28 |
29 |
30 | This is Right Top Control. 31 |
32 |
33 | This is Right Center Control. 34 |
35 |
36 | This is Right Bottom Control. 37 |
38 |
39 | This is Top Left Control. 40 |
41 |
42 | This is Top Center Control. 43 |
44 |
45 | This is Top Right Control. 46 |
47 | {!! $map['html'] !!} 48 |
49 |
50 | 51 | --------------------------------------------------------------------------------