diff --git a/LICENSE b/LICENSE index 2d503ea..86a66e9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014, Petr Olišar +Copyright (c) 2015, Petr Olišar All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.md b/README.md index 48482ea..e3fbc48 100644 --- a/README.md +++ b/README.md @@ -1,210 +1,23 @@ -GoogleAPI +Google Map API ========= -This component is for Nette framework and make Google map display easier - -[Google map API](http://dev.olisar.eu/google-map-api/api/2.0) +This component is stated for Nette framework and it simlifies working with a Google map. Requirements ============ * Nette Framework 2.1+ -* Jquery 1.8+ Installation ============ composer require olicek/google-map-api:dev-master -then you can enable the extension using your neon config - - extensions: - map: Oli\GoogleAPI\MapApiExtension - -Configuration in neon file -========================== - -You can define your map and all markers in in config neon file. All configuration in neon is optional. -```yml -map: - key: your_key # your personal key to google map - zoom: 2 - width: 300px # map will 300px width - height: 150px # map will 150px height - coordinates: # you can name keies as you whis or use [49, 15] - lat: 49.8037633 - lng: 15.4749126 - type: SATELLITE # type of map - markers: # this section will be configured amrkers - bound: on # zoom as mutch as possible, but every marker will be displaied - markerClusterer: on # neer markers group to one cluster - addMarkers: # definitions of markers - - # first marker has no name - coordinates: # the same as map coordinates - sirka: 47 - vyska: 15 - icon: images/point.png # it will display png image from www/images/point.png - message: - text: Opened message # text of message - autoOpen: on # if it is on, this message will be displaied after map loaded - 1: # second marker has name 1 - coordinates: [46, 13] - animation: DROP # this marker will has drop animation - title: Hello world - icon: images/point2.png - Prague: # last marker has name Prague - coordinates: - lat: 48 - lng: 15 - animation: DROP - message: - Closed message - autoOpen: off # message has autoOpen default off -``` - -Default values can be seen in [MapApiExtension](https://github.com/Olicek/GoogleMapAPI/blob/master/src/DI/MapApiExtension.php#L19-L31) - -Simplest usage -============== - -To your presenter include (if you have PHP 5.4+) - -``` php -class MapPresenter extends Nette\Application\UI\Presenter -{ - use \Oli\GoogleAPI\TMap; - - // ... -} -``` -and to template - - {control map} - - -Define map in component -======================= -``` php -private $map; -private $markers; +and now the component can be registered in extensions in a neon config -public function __construct(\Oli\GoogleAPI\IMapAPI $mapApi, \Oli\GoogleAPI\IMarkers $markers) -{ - $this->map = $mapApi; - $this->markers = $markers; -} - -public function createComponentMap() -{ - $map = $this->map->create(); - $markers = $this->markers->create(); - - // ... - - $map->addMarkers($markers); - return $map; -} -``` -And in template - - {* JS and HTML *} - {control map} - {* just HTML *} - {control map:HTML} - {* just JS *} - {control map:JS} - -Map options ------------ -``` php -protected function createComponentGoogleMap() -{ - $map->setCoordinates(array(41.15, 15.65)) - $map->setProportions('800px', '480px'); // Default is 100% x 100%. If proportion is default, map must be - // wrapped to some concrete proportions otherwise it will not be displayed. - $map->setKey('your_key'); - $map->setZoom(8); // <0, 19> - $map->setType(MapAPI::SATELITE); - $map->isStaticMap(); // Map will be displayed as img. (To the image can be inserted colored) markers. - $map->addMarkers($markers); // give markers to the map - return $map; -} -``` -Markers options ---------------- -``` php -$markers = $this->markers->create(); - -/** - * Put marker to the coordinate - * Optional animation, can be DROP, BOUNCE, false - * Optional title can be string|null - */ -$markers->addMarker(array(50.250718,14.583435), false, null); - -/** - * Message can contains HTML tags - * Optional auto open: auto open the message - * Static map can not display messages - */ -$markers->setMessage('

Hello world

', false); -$markers->deleteMarkers(); -$markers->isMarkerClusterer(); // neer markers group to one cluster -$markers->fitBounds(); // zoom as mutch as possible, but every marker will be displaied -$markers->setColor('red'); // Can set color of markers to 10 diferent colors -$markers->setDefaultIconPath('img/'); // Path which will be prepend icon path - -/** - * Icon from www folder. - * If default path was not set, setIcon would be '/www/someIcon.png' - */ -$markers->setIcon('someIcon.png'); ``` -Complex example ---------------- - -config.neon - - map: - key: my_key - width: 750px - height: 450px - markers: - defaultIconPath: images/mapPoints - -Presenter -``` php -protected function createComponentGoogleMap() -{ - $map = $this->map->create(); - - $map->setCoordinates(array(50.250718,14.583435)) - ->setZoom(4) - ->setType(MapAPI::TERRAIN); - - $markers = $this->markers->create(); - $markers->fitBounds(); - - if(count($markersFromDb) > 30) - { - $markers->isMarkerClusterer(); - } - - foreach ($markersFromDb as $marker) - { - $markers->addMarker(array($marker->lat, $marker->lng), Marker::DROP) - ->setMessage( - '

'.$marker->title.'


'.$marker->description - )->setIcon($marker->icon); - } - $map->addMarkers($markers); - return $map; -} +extensions: + map: Oli\GoogleAPI\MapApiExtension ``` -Template - - {block content} - {control map:HTML} - {/block} + +The last step is to link `client-side/googleMapAPI.js` to your page. - {block scripts} - {control map:JS} - {/block} +[Documentation](https://github.com/Olicek/GoogleMapAPI/tree/master/docs) \ No newline at end of file diff --git a/client-side/googleMapAPI.js b/client-side/googleMapAPI.js index 3c9a270..d0af230 100644 --- a/client-side/googleMapAPI.js +++ b/client-side/googleMapAPI.js @@ -1,16 +1,18 @@ -/** - * Copyright (c) 2015 Petr Olišar (http://olisar.eu) - * - * For the full copyright and license information, please view - * the file LICENSE.md that was distributed with this source code. +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. */ + var GoogleMap = GoogleMap || {}; GoogleMap = function(element) { this.element = element; this.map; + this.directionsDisplay; + this.directionsService; this.markers = []; this.options = {}; this.boundsProperty; @@ -43,6 +45,7 @@ GoogleMap.prototype = { this.options.key = properties.key; this.options.bound = properties.bound; this.options.cluster = properties.cluster; + this.options.waypoints = properties.waypoint; this.URL = this.element.dataset.markersfallback; @@ -66,6 +69,11 @@ GoogleMap.prototype = { base.map = new google.maps.Map(base.element, mapOptions); base.map.setTilt(45); base.loadMarkers(); + + if (base.options.waypoints !== null) + { + base.drawDirections(); + } }, loadMarkers: function() @@ -96,6 +104,64 @@ GoogleMap.prototype = { request.send(); }, + drawDirections: function () + { + var base = this; + if (base.options.waypoints.start === undefined || + base.options.waypoints.end === undefined) { + console.log('You must define start and end point of the way!'); + } + var start = base.options.waypoints.start; + var end = base.options.waypoints.end; + var waypoints = []; + + if (base.options.waypoints.waypoints !== undefined) { + for (var i = 0; i < base.options.waypoints.waypoints.length; i++) { + waypoints.push({ + location: new google.maps.LatLng( + base.options.waypoints.waypoints[i].position[0], + base.options.waypoints.waypoints[i].position[1]), + stopover:true}); + } + } + + base.directionsDisplay = new google.maps.DirectionsRenderer(); + base.directionsService = new google.maps.DirectionsService(); + base.directionsDisplay.setMap(base.map); + var request = { + origin: new google.maps.LatLng(start.position[0], start.position[1]), + destination: new google.maps.LatLng(end.position[0], end.position[1]), + waypoints: waypoints, + optimizeWaypoints: true, + travelMode: google.maps.TravelMode[base.options.waypoints.travelmode] + }; + + function merge_options(obj1,obj2){ + var obj3 = {}; + for (var attrname in obj1) { + if (attrname !== 'start' && attrname !== 'end' && + attrname !== 'travelmode') { + obj3[attrname] = obj1[attrname]; + } + } + for (var attrname in obj2) { + if (attrname !== 'start' && attrname !== 'end' && + attrname !== 'travelmode' && attrname !== 'waypoints') { + obj3[attrname] = obj2[attrname]; + } + } + return obj3; + } + + request = merge_options(request, base.options.waypoints); + base.directionsService.route(request, function(response, status) { + if (status == google.maps.DirectionsStatus.OK) { + base.directionsDisplay.setDirections(response); + var route = response.routes[0]; + } + }); + }, + insertMarkers: function(markers) { var base = this; @@ -189,17 +255,7 @@ GoogleMap.prototype = { var animation; if ("animation" in marker) { - switch(marker['animation']) - { - case 'DROP': - animation = google.maps.Animation.DROP; - break; - case 'BOUNCE': - animation = google.maps.Animation.BOUNCE; - break; - default: - null; - } + animation = google.maps.Animation[marker.animation]; } return animation; diff --git a/docs/en/index.md b/docs/en/index.md new file mode 100644 index 0000000..3138673 --- /dev/null +++ b/docs/en/index.md @@ -0,0 +1,187 @@ +Google Map API +========= +This component is stated for Nette framework and it simlifies working with a Google map. + +Requirements +============ +* Nette Framework 2.1+ + +Installation +============ + + composer require olicek/google-map-api:dev-master + +and now the component can be registered in extensions in a neon config + +``` +extensions: + map: Oli\GoogleAPI\MapApiExtension +``` + +The last step is to link `client-side/googleMapAPI.js` to your page. + +Configuration in a neon file +========================== + +You can define your map and all markers in the config neon file. All configurations in neon are optional. +```yml +map: + key: your_key # your personal key to google map + zoom: 2 + width: 300px # map will 300px width + height: 150px # map will 150px height + coordinates: # you can name keies as you whis or use [49, 15] + lat: 49.8037633 + lng: 15.4749126 + type: SATELLITE # type of map + markers: # this section will be configured amrkers + bound: on # zoom as mutch as possible, but every marker will be displaied + markerClusterer: on # neer markers group to one cluster + addMarkers: # definitions of markers + - # first marker has no name + coordinates: # the same as map coordinates + sirka: 47 + vyska: 15 + icon: images/point.png # it will display png image from www/images/point.png + message: + text: Opened message # text of message + autoOpen: on # if it is on, this message will be displaied after map loaded + 1: # second marker has name 1 + coordinates: [46, 13] + animation: DROP # this marker will has drop animation + title: Hello world + icon: images/point2.png + Prague: # last marker has name Prague + coordinates: + lat: 48 + lng: 15 + animation: DROP + message: + Closed message + autoOpen: off # message has autoOpen default off +``` + +Default values can be seen in [MapApiExtension](https://github.com/Olicek/GoogleMapAPI/blob/master/src/DI/MapApiExtension.php#L19-L31) + +The simplest example of application +============== + +Insert to your presenter (if you have PHP 5.4+) + +``` php +class MapPresenter extends Nette\Application\UI\Presenter +{ + use \Oli\GoogleAPI\TMap; + + // ... +} +``` +and to the template + + {control map} + + +Define map in a component +======================= +``` php +private $map; +private $markers; + +public function __construct(\Oli\GoogleAPI\IMapAPI $mapApi, \Oli\GoogleAPI\IMarkers $markers) +{ + $this->map = $mapApi; + $this->markers = $markers; +} + +public function createComponentMap() +{ + $map = $this->map->create(); + $markers = $this->markers->create(); + + // ... + + $map->addMarkers($markers); + return $map; +} +``` +And in the template + +`{control map}` + +Markers options +--------------- +``` php +$markers = $this->markers->create(); + +$markers->addMarker(array(50.250718,14.583435), false, null); + +$markers->setMessage('

Hello world

', false); +$markers->deleteMarkers(); +$markers->isMarkerClusterer(); // neer markers group to one cluster +$markers->fitBounds(); // zoom as mutch as possible, but every marker will be displaied +$markers->setColor('red'); // Can set color of markers to 10 diferent colors +$markers->setDefaultIconPath('img/'); // Path which will be prepend icon path + +/** + * Icon from www folder. + * If default path was not set, setIcon would be '/www/someIcon.png' + */ +$markers->setIcon('someIcon.png'); +``` +Complex example +--------------- + +config.neon + + map: + key: my_key + width: 750px + height: 450px + markers: + defaultIconPath: images/mapPoints + +Presenter +``` php +protected function createComponentGoogleMap() +{ + $map = $this->map->create(); + + $map->setCoordinates(array(50.250718,14.583435)) + ->setZoom(4) + ->setType(MapAPI::TERRAIN); + + $markers = $this->markers->create(); + $markers->fitBounds(); + + if(count($markersFromDb) > 30) + { + $markers->isMarkerClusterer(); + } + + foreach ($markersFromDb as $marker) + { + $addedMarker = $markers->addMarker(array($marker->lat, $marker->lng), Marker::DROP) + ->setMessage( + '

'.$marker->title.'


'.$marker->description + )->setIcon($marker->icon); + + // $marker->waypoint can be start, end, waypoints + $map->setWaypoint($marker->waypoint, $addedMarker); + } + + $map->setDirection([ + 'avoidHighways' => true, + 'avoidTolls' => true, + ]); + + $map->addMarkers($markers); + return $map; +} +``` +### Template + +``` +{block content} + {control map} +{/block} +``` diff --git a/docs/en/map.md b/docs/en/map.md new file mode 100644 index 0000000..bc7cd97 --- /dev/null +++ b/docs/en/map.md @@ -0,0 +1,74 @@ +Map +======= + +The easiest way how to create `Oli\GoogleAPI\MapAPI` object is to use a factory + +``` +public function injectGoogleMapAPI(IMapAPI $mapApi) +{ + $this->googleMapAPI = $mapApi; +} + +public function createComponentMap() +{ + $map = $this->googleMapAPI->create(); + return $map; +} +``` + +Object `MapAPI` with the settings from a config is available in variable `$map` in this moment. + +Methods +------- + + +### setCoordinates(array $coordinates) + +In coordinates, you can set a latitude and a longitude. If the coordinates are empty, it will set NULL. It's the same as [0, 0]. + +### setProportions($width, $height) + +This method sets a width and a height of the map. It's optional, but if proportions are not set, the map will not be displaied unless you set it in css. + +### setKey($key) + + +### setZoom($zoom) + +Zoom is integer and it must be <0, 19>. Default value is 7. + +### setType($type) + +It can be only one of [4 basic](https://developers.google.com/maps/documentation/javascript/maptypes#BasicMapTypes) map types. + +### isStaticMap($staticMap = TRUE) + +This method creates map as a picture. When the map is static, only `height`, `width`, `zoom`, `coordinates` and markers has an effect. + +### isScrollable($scrollable = TRUE) + +If scrollable is `TRUE`, when mouse is over the map and a user is scrolling, it has no effect. + +### addMarkers(Markers $markers) + +This method must be called, if you want to put the markers to the map. It just transmit markers from `$markers` to the map. + +### setWaypoint($key, $waypoint) + +Key defines, if the marker will be first, last or betwen. Values are `start`, `end` and `waypoints`. `$waypoint` is array. The marker can be set as waypoint, for example like that: + +``` +$start = $markers->addMarker([46, 13], Markers::BOUNCE, 'Start')->getMarker(); +$end = $markers->addMarker([46, 12], FALSE, 'Finish')->getMarker(); +$map->setWaypoint('start', $start)->setWaypoint('end', $end); +``` + +### setDirection(array $direction) + +Direction sets a few additional parameters for drawing a way. Everything what is [here](https://developers.google.com/maps/documentation/javascript/3.exp/reference#DirectionsRequest) can be set. If nothing is set, it will use just `travelmode = DRIVING`. + +### invalidateMarkers() + +It is alias to `handleMarkers()` + +Markers are loaded lazy via ajax, after eveything else is done. If you need to redraw the markers, you can call this method and markers will be replaced. diff --git a/docs/en/markers.md b/docs/en/markers.md new file mode 100644 index 0000000..cb1de66 --- /dev/null +++ b/docs/en/markers.md @@ -0,0 +1,126 @@ +Markers +======= + +The easiest way, how to create `Oli\GoogleAPI\Markers` object, is to use a factory + +``` +public function injectGoogleMapMarkers(\Oli\GoogleAPI\Markers $markers) +{ + $this->googleMapMarkers = $markers; +} + +public function createComponentMap() +{ + $markers = $this->googleMapMarkers->create(); + // ... + return $markers; +} +``` + +Object `Markers` with all the markers from the config is in variable `$markers` in this moment. + +Methods +------- + + +### addMarkers() + +``` +$markers->addMarkers($array); +``` + +You can add multiple markers through this method. This method is internally used to add markers from the config. + +### addMarker() + +``` +/** + * @param array $animation + * @param boolean|string $animation + * @param NULL|string $animation + */ +$markers->addMarker(array $position, $animation = FALSE, $title = NULL); +``` + +This method is the only one which is required to create a marker. + +Position is an array, where the array is [latitude, longitude]. The animation can be `Markers::DROP`, `Markers::BOUNCE` or default `FALSE`. +Title is like HTML title, which is showed on mouseover. + +### getMarker() + +``` +$markers->getMarker(); +``` + +Return last inserted marker. + +### deleteMarkers() + +``` +$markers->deleteMarkers(); +``` + +Delete all markers. + +### setMessage() + +``` +$markers->setMessage($message, $autoOpen = FALSE); +``` + +Set [message](https://developers.google.com/maps/documentation/javascript/examples/infowindow-simple), with is showed by click on marker. If second parameter is `TRUE`, message is shown by default. + +> Message can contains HTML tags + +### isMarkerClusterer() + +``` +$markers->isMarkerClusterer($cluster = TRUE); +``` + +Create [cluster](https://googlemaps.github.io/js-marker-clusterer/docs/examples.html) from close markers. + +### getMarkerClusterer() + +### fitBounds() + +``` +$markers->fitBounds($bound = TRUE); +``` + +Set zoom as close as possible and all markers are shown in the same time. + +### getBound() + +### setDefaultIconPath() + +``` +$markers->setDefaultIconPath($defaultPath); +``` + +Set default path to icons. This path will be used to the every next added icon. It's relative to `www` folder. + + +### setIcon() + +``` +$markers->setIcon($icon); +``` + +If default path is set, it will be used before `$icon` string. It's relative to `www` folder (or default path folder). + +### setColor() + +``` +$markers->setColor($color) +``` + +A few colors can be set through this simple way. It just colorizes the default marker. + +* green +* purple +* yellow +* blue +* orange +* red \ No newline at end of file diff --git a/src/DI/MapApiExtension.php b/src/DI/MapApiExtension.php index 7cd3e99..5f5d043 100644 --- a/src/DI/MapApiExtension.php +++ b/src/DI/MapApiExtension.php @@ -1,6 +1,6 @@ 'DRIVING']; /** @@ -69,7 +80,7 @@ public function setCoordinates(array $coordinates) if(!count($coordinates)) { - $this->coordinates = array(null, null); + $this->coordinates = array(NULL, NULL); } else { $this->coordinates = array_values($coordinates); @@ -144,6 +155,31 @@ public function setType($type) } + public function setWaypoint($key, $waypoint) + { + if($key === 'waypoints') + { + $this->waypoints['waypoints'][] = $waypoint; + + } else + { + $this->waypoints[$key] = $waypoint; + } + return $this; + } + + + public function setDirection(array $direction) + { + $this->direction = $direction; + if(!array_key_exists('travelmode', $this->direction)) + { + $this->direction['travelmode'] = 'DRIVING'; + } + return $this; + } + + /** * @return array Width and Height of the map. */ @@ -186,7 +222,7 @@ public function getType() * @return \Oli\GoogleAPI\MapAPI * @throws \InvalidArgumentException */ - public function isStaticMap($staticMap = true) + public function isStaticMap($staticMap = TRUE) { if (!is_bool($staticMap)) { @@ -198,7 +234,7 @@ public function isStaticMap($staticMap = true) } - public function isScrollable($scrollable = true) + public function isScrollable($scrollable = TRUE) { if (!is_bool($scrollable)) { @@ -257,7 +293,8 @@ public function render() 'scrollable' => $this->scrollable, 'key' => $this->key, 'bound' => $this->bound, - 'cluster' => $this->markerClusterer + 'cluster' => $this->markerClusterer, + 'waypoint' => !is_null($this->waypoints) ? array_merge($this->waypoints, $this->direction) : NULL ); $this->template->map = \Nette\Utils\Json::encode($map); $this->template->setFile(dirname(__FILE__) . '/template.latte'); diff --git a/src/Map/Markers.php b/src/Map/Markers.php index ba99966..cbb1969 100644 --- a/src/Map/Markers.php +++ b/src/Map/Markers.php @@ -1,6 +1,6 @@ markers); + } + /** * @return Array */ @@ -211,7 +216,7 @@ public function setDefaultIconPath($defaultPath) /** * - * @param String $color Color can be 24-bit color or: black, brown, green, purple, yellow, blue, gray, orange, red, white + * @param String $color Color can be 24-bit color or: green, purple, yellow, blue, gray, orange, red * @return \Oli\GoogleAPI\Markers */ public function setColor($color) diff --git a/src/Map/TMap.php b/src/Map/TMap.php index b24698e..020f302 100644 --- a/src/Map/TMap.php +++ b/src/Map/TMap.php @@ -1,6 +1,6 @@ addMarkers($this->googleMapMarkers->create()); return $map; } + }