From 3aae399d94b318a04dc8418137ac69e5aef67270 Mon Sep 17 00:00:00 2001 From: Vinzenz Rosenkranz Date: Fri, 15 Jan 2016 14:14:33 +0100 Subject: [PATCH] small fixes and updates --- appinfo/application.php | 10 +- appinfo/database.xml | 23 + appinfo/routes.php | 3 + controller/apikeycontroller.php | 103 +++++ controller/pagecontroller.php | 29 +- css/style.css | 1 + db/apikey.php | 15 + db/apikeymapper.php | 44 ++ js/3rdparty/leaflet/lib/Control.Geocoder.js | 87 +--- .../leaflet/lib/Control.Geocoder.js.old | 393 ------------------ js/script.js | 92 +++- templates/main.php | 5 + 12 files changed, 299 insertions(+), 506 deletions(-) create mode 100644 controller/apikeycontroller.php create mode 100644 db/apikey.php create mode 100644 db/apikeymapper.php delete mode 100644 js/3rdparty/leaflet/lib/Control.Geocoder.js.old diff --git a/appinfo/application.php b/appinfo/application.php index bd596b2..f6ce0b7 100644 --- a/appinfo/application.php +++ b/appinfo/application.php @@ -18,6 +18,7 @@ use \OCA\Maps\Db\DeviceMapper; use \OCA\Maps\Db\LocationMapper; use \OCA\Maps\Db\FavoriteMapper; +use \OCA\Maps\Db\ApiKeyMapper; use \OCA\Maps\Controller\PageController; use \OCA\Maps\Controller\LocationController; use \OCA\Maps\Controller\FavoriteController; @@ -41,7 +42,8 @@ public function __construct (array $urlParams=array()) { $c->query('Request'), $c->query('UserId'), $c->query('CacheManager'), - $c->query('DeviceMapper') + $c->query('DeviceMapper'), + $c->query('ApiKeyMapper') ); }); $container->registerService('LocationController', function($c) { @@ -89,6 +91,12 @@ public function __construct (array $urlParams=array()) { $server->getDb() ); }); + $container->registerService('ApiKeyMapper', function($c) use ($server) { + /** @var SimpleContainer $c */ + return new ApiKeyMapper( + $server->getDb() + ); + }); } diff --git a/appinfo/database.xml b/appinfo/database.xml index 11b1fbf..43e91df 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -173,4 +173,27 @@ + + *dbprefix*maps_apikeys + + + id + integer + 0 + true + 1 + 41 + + + user_id + text + 64 + + + api_key + text + 64 + + +
diff --git a/appinfo/routes.php b/appinfo/routes.php index 2f94e2c..85c64fb 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -40,4 +40,7 @@ array('name' => 'favorite#update_favorite', 'url' => '/api/1.0/favorite/updateFavorite', 'verb' => 'POST'), array('name' => 'favorite#get_favorites_by_name', 'url' => '/api/1.0/favorite/getFavoritesByName', 'verb' => 'POST'), + array('name' => 'apikey#get_key', 'url' => '/api/1.0/apikey/getKey', 'verb' => 'POST'), + array('name' => 'apikey#add_key', 'url' => '/api/1.0/apikey/addKey', 'verb' => 'POST'), + ))); diff --git a/controller/apikeycontroller.php b/controller/apikeycontroller.php new file mode 100644 index 0000000..df5e3f6 --- /dev/null +++ b/controller/apikeycontroller.php @@ -0,0 +1,103 @@ + + * @copyright Vinzenz Rosenkranz 2015 + */ + +namespace OCA\Maps\Controller; + +use OCA\Maps\Db\ApiKey; +use OCA\Maps\Db\ApiKeyMapper; +use \OCP\IRequest; +use \OCP\AppFramework\Http\JSONResponse; +use \OCP\AppFramework\ApiController; + + +class ApiKeyController extends ApiController { + + private $userId; + private $apiKeyMapper; + + public function __construct($appName, IRequest $request, ApiKeyMapper $apiKeyMapper, $userId) { + parent::__construct($appName, $request); + $this->apiKeyMapper = $apiKeyMapper; + $this->userId = $userId; + } + + /** + * @NoAdminRequired + * + * @param $key string + * @param $id int + * @return JSONResponse + */ + public function updateKey($key, $id) { + + $apikey = new ApiKey(); + $apikey->setId($id); + $apikey->setApiKey($key); + + /* Only save apiKey if it exists in db */ + try { + $this->apiKeyMapper->find($id); + return new JSONResponse($this->apiKeyMapper->update($apikey)); + } catch(\OCP\AppFramework\Db\DoesNotExistException $e) { + return new JSONResponse([ + 'error' => $e->getMessage() + ]); + } + } + + /** + * @NoAdminRequired + * + * @param $key string + * @return JSONResponse + */ + public function addKey($key){ + $apikey = new ApiKey(); + $apikey->setApiKey($key); + $apikey->setUserId($this->userId); + + /* @var $apikey ApiKey */ + $apikey = $this->apiKeyMapper->insert($apikey); + + $response = array('id'=> $apikey->getId()); + return new JSONResponse($response); + } + + /** + * @NoAdminRequired + * + * @return JSONResponse + */ + public function getKey(){ + $apikey = new ApiKey(); + try { + $apikey = $this->apiKeyMapper->findByUser($this->userId); + } catch(\OCP\AppFramework\Db\DoesNotExistException $e) { + $apikey->setUserId($this->userId); + } + return new JSONResponse($apikey); + } + + /** + * @NoAdminRequired + * + * @param $id int + * @return JSONResponse + */ + public function removeApiKey($id){ + $apikey = $this->apiKeyMapper->find($id); + if($apikey->userId == $this->userId) { + $this->apiKeyMapper->delete($apikey); + } + return new JSONResponse(); + } + +} diff --git a/controller/pagecontroller.php b/controller/pagecontroller.php index 6994c07..4171d6f 100644 --- a/controller/pagecontroller.php +++ b/controller/pagecontroller.php @@ -11,7 +11,9 @@ namespace OCA\Maps\Controller; +use \OCA\Maps\Db\ApiKey; use \OCA\Maps\Db\DeviceMapper; +use \OCA\Maps\Db\ApiKeyMapper; use \OCP\IRequest; use \OCP\AppFramework\Http\TemplateResponse; use \OCP\AppFramework\Controller; @@ -22,13 +24,16 @@ class PageController extends Controller { private $userId; private $cacheManager; private $deviceMapper; + private $apiKeyMapper; public function __construct($appName, IRequest $request, $userId, CacheManager $cacheManager, - DeviceMapper $deviceMapper) { + DeviceMapper $deviceMapper, + ApiKeyMapper $apiKeyMapper) { parent::__construct($appName, $request); $this -> userId = $userId; $this -> cacheManager = $cacheManager; $this -> deviceMapper = $deviceMapper; + $this -> apiKeyMapper = $apiKeyMapper; } /** @@ -52,11 +57,23 @@ public function index() { // marker icons $csp->addAllowedImageDomain('https://api.tiles.mapbox.com'); // inline images - $csp->addAllowedScriptDomain('data:'); - // nominatim geocoder - $csp->addAllowedScriptDomain('http://nominatim.openstreetmap.org/search?q=*'); - $csp->addAllowedScriptDomain('http://nominatim.openstreetmap.org/reverse'); - $csp->addAllowedConnectDomain('http://router.project-osrm.org'); + $csp->addAllowedImageDomain('data:'); + $tmpkey = new ApiKey(); + try { + $tmpkey = $this->apiKeyMapper->findByUser($this->userId); + } catch(\OCP\AppFramework\Db\DoesNotExistException $e) { + $tmpkey->setUserId($this->userId); + } + if($tmpkey->apiKey != null && strlen($tmpkey->apiKey) > 0) { + // mapzen geocoder + $csp->addAllowedConnectDomain('http://search.mapzen.com/v1/search?'); + $csp->addAllowedConnectDomain('http://search.mapzen.com/v1/reverse?'); + } else { + // nominatim geocoder + $csp->addAllowedScriptDomain('http://nominatim.openstreetmap.org/search?q=*'); + $csp->addAllowedScriptDomain('http://nominatim.openstreetmap.org/reverse'); + $csp->addAllowedConnectDomain('http://router.project-osrm.org'); + } $response->setContentSecurityPolicy($csp); } return $response; diff --git a/css/style.css b/css/style.css index 12d2640..eb4b9b7 100644 --- a/css/style.css +++ b/css/style.css @@ -61,6 +61,7 @@ ul.geocoder-list { background: white; width: 400px; font-size: 10px; + position: absolute; } li.geocoder-list-item { diff --git a/db/apikey.php b/db/apikey.php new file mode 100644 index 0000000..838e02c --- /dev/null +++ b/db/apikey.php @@ -0,0 +1,15 @@ +findEntity($sql, [$id]); + } + + /** + * @param string $uid + * @throws \OCP\AppFramework\Db\DoesNotExistException if not found + * @return ApiKey + */ + public function findByUser($uid) { + $sql = 'SELECT * FROM `*PREFIX*maps_apikeys` '. + 'WHERE `user_id` = ?'; + return $this->findEntity($sql, [$uid]); + } + + /** + * @param int $limit + * @param int $offset + * @return ApiKey[] + */ + public function findAll($limit=null, $offset=null) { + $sql = 'SELECT * FROM `*PREFIX*maps_apikeys`'; + return $this->findEntities($sql, $limit, $offset); + } +} diff --git a/js/3rdparty/leaflet/lib/Control.Geocoder.js b/js/3rdparty/leaflet/lib/Control.Geocoder.js index 4a6a51e..e3f0ca1 100644 --- a/js/3rdparty/leaflet/lib/Control.Geocoder.js +++ b/js/3rdparty/leaflet/lib/Control.Geocoder.js @@ -52,10 +52,7 @@ module.exports = { this._container.appendChild(this._errorElement); container.appendChild(this._alts); -// L.DomEvent.addListener(form, 'submit', this._geocode, this); - L.DomEvent.addListener(form, 'input', this._geocode, this); -// L.DomEvent.addListener(form, 'input', this._checkForContacts, this); -// L.DomEvent.addListener(form, 'submit', this._onSearchSubmit, this); + L.DomEvent.addListener(form, 'submit', this._geocode, this); if (this.options.collapsed) { if (this.options.expand === 'click') { @@ -113,93 +110,11 @@ module.exports = { return this; }, - /*_createAltCont: function(result, index) { - var li = L.DomUtil.create('li', ''), - a = L.DomUtil.create('a', 'listContact', li), - icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null, - text = result.html ? undefined : document.createTextNode(result.name), - clickHandler = function clickHandler(e) { - L.DomEvent.preventDefault(e); - this._geocodeResultSelected(result); - }; - - if (icon) { - icon.src = result.icon; - } - - li.setAttribute('data-result-index', index); - - if (result.html) { - a.innerHTML = result.html; - } else { - a.appendChild(text); - } - - L.DomEvent.addListener(li, 'click', clickHandler, this); - - return li; - },*/ - - /*_checkForContacts: function(e) { - L.DomEvent.preventDefault(e); - //TODO add contact loading - //TODO add geocode of current search if no item is selected - var inp = this._input.value; - if(inp.length < 3) return; - var splitInp = inp.split(" "); - var contactAddrs = []; - var idx = 5; - for(var i=0; i -1){ - var address = { - 'city': Maps.addresses[i].orgAdd[adIndex][3], - 'street': Maps.addresses[i].orgAdd[adIndex][2] - }; - } - var displayName = Maps.addresses[i].name; - var tmpRes = { - 'address': address, - 'displayName': displayName, - 'name': displayName - }; - //TODO only works with alert - alert(tmpRes.toSource()); - this._alts.appendChild(this._createAltCont(tmpRes, idx)); - idx++; - } - } - return false; - },*/ - - /*_onSearchSubmit: function(e) { - this.options.geocoder.geocode(this._input.value, this._loadBestResult, this); - return false; - },*/ - _geocode: function(event) { L.DomEvent.preventDefault(event); this._clearResults(); - if(this._input.value.length < 3) return false; - setTimeout(500); L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber'); this.options.geocoder.geocode(this._input.value, this._geocodeResult, this); -// this._checkForContacts(event); return false; }, diff --git a/js/3rdparty/leaflet/lib/Control.Geocoder.js.old b/js/3rdparty/leaflet/lib/Control.Geocoder.js.old deleted file mode 100644 index fdd8792..0000000 --- a/js/3rdparty/leaflet/lib/Control.Geocoder.js.old +++ /dev/null @@ -1,393 +0,0 @@ -(function (factory) { - // Packaging/modules magic dance - var L; - if (typeof define === 'function' && define.amd) { - // AMD - define(['leaflet'], factory); - } else if (typeof module !== 'undefined') { - // Node/CommonJS - L = require('leaflet'); - module.exports = factory(L); - } else { - // Browser globals - if (typeof window.L === 'undefined') - throw 'Leaflet must be loaded first'; - factory(window.L); - } -}(function (L) { - 'use strict'; - L.Control.Geocoder = L.Control.extend({ - options: { - showResultIcons: false, - collapsed: true, - expand: 'click', - position: 'topright', - placeholder: 'Search...', - errorMessage: 'Nothing found.' - }, - - _callbackId: 0, - - initialize: function (options) { - L.Util.setOptions(this, options); - if (!this.options.geocoder) { - this.options.geocoder = new L.Control.Geocoder.Nominatim(); - } - }, - - onAdd: function (map) { - var className = 'leaflet-control-geocoder', - container = L.DomUtil.create('div', className), - form = this._form = L.DomUtil.create('form', className + '-form', container), - input, - icon; - - this._map = map; - input = this._input = L.DomUtil.create('input'); - input.type = 'text'; - - L.DomEvent.addListener(input, 'keydown', this._keydown, this); - //L.DomEvent.addListener(input, 'onpaste', this._clearResults, this); - //L.DomEvent.addListener(input, 'oninput', this._clearResults, this); - - icon = L.DomUtil.create('div', 'leaflet-control-geocoder-icon'); - container.appendChild(icon); - - this._errorElement = document.createElement('div'); - this._errorElement.className = className + '-form-no-error'; - this._errorElement.innerHTML = this.options.errorMessage; - - this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized'); - - form.appendChild(input); - form.appendChild(this._errorElement); - container.appendChild(this._alts); - - L.DomEvent.addListener(form, 'submit', this._geocode, this); - - if (this.options.collapsed) { - if (this.options.expand === 'click') { - L.DomEvent.addListener(icon, 'click', function(e) { - // TODO: touch - if (e.button === 0 && e.detail === 1) { - this._toggle(); - } - }, this); - } else { - L.DomEvent.addListener(icon, 'mouseover', this._expand, this); - L.DomEvent.addListener(icon, 'mouseout', this._collapse, this); - this._map.on('movestart', this._collapse, this); - } - } else { - this._expand(); - } - - L.DomEvent.disableClickPropagation(container); - - return container; - }, - - _geocodeResult: function (results) { - L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber'); - if (results.length === 1) { - this._geocodeResultSelected(results[0]); - } else if (results.length > 0) { - this._alts.innerHTML = ''; - this._results = results; - L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized'); - for (var i = 0; i < results.length; i++) { - this._alts.appendChild(this._createAlt(results[i], i)); - } - } else { - L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error'); - } - }, - - markGeocode: function(result) { - this._map.fitBounds(result.bbox); - - if (this._geocodeMarker) { - this._map.removeLayer(this._geocodeMarker); - } - - this._geocodeMarker = new L.Marker(result.center) - .bindPopup(result.name) - .addTo(this._map) - .openPopup(); - - return this; - }, - - _geocode: function(event) { - L.DomEvent.preventDefault(event); - - L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber'); - this._clearResults(); - this.options.geocoder.geocode(this._input.value, this._geocodeResult, this); - - return false; - }, - - _geocodeResultSelected: function(result) { - if (this.options.collapsed) { - this._collapse(); - } - this.markGeocode(result); - }, - - _toggle: function() { - if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) { - this._collapse(); - } else { - this._expand(); - } - }, - - _expand: function () { - L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded'); - this._input.select(); - }, - - _collapse: function () { - this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', ''); - L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized'); - }, - - _clearResults: function () { - L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized'); - this._selection = null; - L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error'); - }, - - _createAlt: function(result, index) { - var li = document.createElement('li'); - li.innerHTML = '' + - (this.options.showResultIcons && result.icon ? - '' : - '') + - result.name + ''; - L.DomEvent.addListener(li, 'click', function clickHandler() { - this._geocodeResultSelected(result); - }, this); - - return li; - }, - - _keydown: function(e) { - var _this = this, - select = function select(dir) { - if (_this._selection) { - L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected'); - _this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling']; - } - if (!_this._selection) { - _this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild']; - } - - if (_this._selection) { - L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected'); - } - }; - - switch (e.keyCode) { - // Up - case 38: - select(-1); - L.DomEvent.preventDefault(e); - break; - // Up - case 40: - select(1); - L.DomEvent.preventDefault(e); - break; - // Enter - case 13: - if (this._selection) { - var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10); - this._geocodeResultSelected(this._results[index]); - this._clearResults(); - L.DomEvent.preventDefault(e); - } - } - return true; - } - }); - - L.Control.geocoder = function(id, options) { - return new L.Control.Geocoder(id, options); - }; - - L.Control.Geocoder.callbackId = 0; - L.Control.Geocoder.jsonp = function(url, params, callback, context, jsonpParam) { - var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++); - params[jsonpParam || 'callback'] = callbackId; - window[callbackId] = L.Util.bind(callback, context); - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = url + L.Util.getParamString(params); - script.id = callbackId; - document.getElementsByTagName('head')[0].appendChild(script); - }; - - L.Control.Geocoder.Nominatim = L.Class.extend({ - options: { - serviceUrl: OC.generateUrl('apps/maps/router?url=http://nominatim.openstreetmap.org/') - }, - - initialize: function(options) { - L.Util.setOptions(this, options); - }, - - geocode: function(query, cb, context) { - L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', { - q: query, - limit: 5, - format: 'json' - }, function(data) { - var results = []; - for (var i = data.length - 1; i >= 0; i--) { - var bbox = data[i].boundingbox; - for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]); - results[i] = { - icon: data[i].icon, - name: data[i].display_name, - bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]), - center: L.latLng((bbox[0] + bbox[1]) / 2, (bbox[2] + bbox[3]) / 2), - originalObject: data - }; - } - cb.call(context, results); - }, this, 'json_callback'); - }, - - reverse: function(location, scale, cb, context) { - L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', { - lat: location.lat, - lon: location.lng, - zoom: Math.round(Math.log(scale / 256) / Math.log(2)), - addressdetails: 1, - format: 'json' - }, function(data) { - var loc = L.latLng(data.lat, data.lon); - cb.call(context, [{ - name: data.display_name, - center: loc, - bounds: L.latLngBounds(loc, loc), - originalObject: data - }]); - }, this, 'json_callback'); - } - }); - - L.Control.Geocoder.nominatim = function(options) { - return new L.Control.Geocoder.Nominatim(options); - }; - - L.Control.Geocoder.Bing = L.Class.extend({ - initialize: function(key) { - this.key = key; - }, - - geocode : function (query, cb, context) { - L.Control.Geocoder.jsonp(OC.generateUrl('apps/maps/router?url=http://dev.virtualearth.net/REST/v1/Locations'), { - query: query, - key : this.key - }, function(data) { - var results = []; - for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) { - var resource = data.resourceSets[0].resources[i], - bbox = resource.bbox; - results[i] = { - name: resource.name, - bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]), - center: L.latLng(resource.point.coordinates) - }; - } - cb.call(context, results); - }, this, 'jsonp'); - }, - - reverse: function(location, scale, cb, context) { - L.Control.Geocoder.jsonp(OC.generateUrl('apps/maps/router?url=http://dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng), { - key : this.key - }, function(data) { - var results = []; - for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) { - var resource = data.resourceSets[0].resources[i], - bbox = resource.bbox; - results[i] = { - name: resource.name, - bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]), - center: L.latLng(resource.point.coordinates) - }; - } - cb.call(context, results); - }, this, 'jsonp'); - } - }); - - L.Control.Geocoder.bing = function(key) { - return new L.Control.Geocoder.Bing(key); - }; - - L.Control.Geocoder.RaveGeo = L.Class.extend({ - options: { - querySuffix: '', - deepSearch: true, - wordBased: false - }, - - jsonp: function(params, callback, context) { - var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++), - paramParts = []; - params.prepend = callbackId + '('; - params.append = ')'; - for (var p in params) { - paramParts.push(p + '=' + escape(params[p])); - } - - window[callbackId] = L.Util.bind(callback, context); - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.src = this._serviceUrl + '?' + paramParts.join('&'); - script.id = callbackId; - document.getElementsByTagName('head')[0].appendChild(script); - }, - - initialize: function(serviceUrl, scheme, options) { - L.Util.setOptions(this, options); - - this._serviceUrl = serviceUrl; - this._scheme = scheme; - }, - - geocode: function(query, cb, context) { - L.Control.Geocoder.jsonp(this._serviceUrl, { - address: query + this.options.querySuffix, - scheme: this._scheme, - outputFormat: 'jsonp', - deepSearch: this.options.deepSearch, - wordBased: this.options.wordBased - }, function(data) { - var results = []; - for (var i = data.length - 1; i >= 0; i--) { - var r = data[i], - c = L.latLng(r.y, r.x); - results[i] = { - name: r.address, - bbox: L.latLngBounds([c]), - center: c - }; - } - cb.call(context, results); - }, this); - } - }); - - L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) { - return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options); - }; - - - return L.Control.Geocoder; -})); \ No newline at end of file diff --git a/js/script.js b/js/script.js index 59d141e..2f38461 100644 --- a/js/script.js +++ b/js/script.js @@ -28,6 +28,23 @@ Array.prototype.unique = function() { } return unique; }; + +function debounce(func, wait, immediate) { + var timeout; + return function() { + var context = this; + var args = arguments; + var later = function() { + timeout = null; + if(!immediate) func.apply(context, args); + } + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if(callNow) func.apply(context, args); + } +} + (function($, OC) { var normalMarkerImg = OC.filePath('maps', 'css', 'leaflet/images/marker-icon.png'); @@ -48,21 +65,23 @@ Array.prototype.unique = function() { function addGeocodeMarker(latlng) { Maps.droppedPin = new L.marker(latlng); - var decoder = L.Control.Geocoder.nominatim(); - decoder.reverse(latlng, 67108864, function(results) { + geocoder.reverse(latlng, 67108864, function(results) { var result = results[0]; setTimeout(function() { var knownFields = ['country', 'country_code', 'postcode', 'residential', 'road', 'state', 'suburb', 'town', 'house_number']; var popupHtml = ''; - $.each(result.originalObject.address, function(k, v) { + var properties = result.properties; + var address = properties; + if(!geocodeSearch.apiKeySet()) address = properties.address; + $.each(address, function(k, v) { if ($.inArray(k, knownFields) == -1) { var prefix = k; popupHtml += v + '
'; } }) - var houseNo = (result.originalObject.address.house_number) ? result.originalObject.address.house_number : ''; - popupHtml += result.originalObject.address.road + ' ' + houseNo + '
'; - popupHtml += result.originalObject.address.town + ', ' + result.originalObject.address.state + ', ' + result.originalObject.address.country; + var houseNo = (address.house_number) ? address.house_number : ''; + popupHtml += address.road + ' ' + houseNo + '
'; + popupHtml += address.town + ', ' + address.state + ', ' + address.country; toolKit.addMarker(Maps.droppedPin, popupHtml, true); }, 50); @@ -140,11 +159,6 @@ Array.prototype.unique = function() { zoomControl : false, layers : [mapQuest] }), - geocoder = L.Control.Geocoder.nominatim(); - /*control = L.Control.geocoder({ - collapsed: false, - geocoder: geocoder - }).addTo(map);*/ map.options.minZoom = 3; var hash = new L.Hash(map); @@ -186,11 +200,23 @@ Array.prototype.unique = function() { geocodeSearch.waypointsChanged(e); }) + apiKey = ''; + geocodeSearch.addGeocoder(); // properly style as input field //$('#searchContainer').find('input').attr('type', 'text'); + $.post(OC.generateUrl('/apps/maps/api/1.0/apikey/getKey'), null, function(data){ + if(data.id != null && data.apiKey != null) { + apiKey = data.apiKey; + document.getElementById('apiKey').value = apiKey; + geocoder = L.Control.Geocoder.mapzen(apiKey); + } else { + geocoder = L.Control.Geocoder.nominatim(); + } + }); + map.on('mousedown', function(e) { Maps.mouseDowntime = new Date().getTime(); }); @@ -404,6 +430,16 @@ Array.prototype.unique = function() { minDate : -900 }); + $(document).on('click', '#setApiKey', function(e) { + var value = document.getElementById('apiKey').value; + if(value.length == 0) return; + var formData = { + key : value + }; + $.post(OC.generateUrl('/apps/maps/api/1.0/apikey/addKey'), formData, function(data){ + }); + }); + $(document).on('click', '.deviceHistory', function(e) { var isVisible = $(this).parent().find('i').length; var dId = $(this).parent().attr('data-deviceId'); @@ -459,13 +495,15 @@ Array.prototype.unique = function() { $(document).on('click', '.setDestination', function() { var latlng = $(this).attr('data-latlng'); - routing.setWaypoints([]) var end = latlng.split(','); end[0] = end[0] * 1; end[1] = end[1] * 1; //map.removeLayer(routing); - routing.setWaypoints([L.latLng(currentlocation[0], currentlocation[1]), L.latLng(end[0], end[1])]); + routing.setWaypoints([ + L.Routing.waypoint(L.latLng(currentlocation[0], currentlocation[1]), ""), + L.Routing.waypoint(L.latLng(end[0], end[1]), "") + ]); map.closePopup(); }); @@ -505,6 +543,9 @@ Array.prototype.unique = function() { results : [], waypoints : [], markers : [], + apiKeySet : function() { + return apiKey != null && apiKey.length > 0; + }, addGeocoder : function() { var geocoderInputs = document.getElementsByClassName('geocoder'); var elems = 0; @@ -517,17 +558,17 @@ Array.prototype.unique = function() { var input = document.createElement('input'); input.type = 'text'; input.className = 'geocoder not-geocoded'; - input.addEventListener('keyup', function() { - clearTimeout(timeoutId); - timeoutId = setTimeout(geocodeSearch.performGeocode(input), 500); - }); + var debounceTimeout = 500; + if(!geocodeSearch.apiKeySet()) debounceTimeout = 1000; + input.addEventListener('input', debounce(function() { + geocodeSearch.performGeocode(input) + }, debounceTimeout)); input.addEventListener('blur', geocodeSearch.clearResults(input)); var list = document.createElement('ul'); list.className = 'geocoder-list'; list.style.display = 'none'; var btn = document.createElement('button'); - if(elems == 0) { geocoderDiv.id = 'geocoder-container-start'; @@ -601,7 +642,9 @@ Array.prototype.unique = function() { newEndDiv.id = 'geocoder-container-end'; newInput.id = 'geocoder-end'; newList.id = 'geocoder-results-end'; - newInput.placeholder = 'End address'; + if(document.getElementsByClassName('geocoder').length - 1 > 1) { + newInput.placeholder = 'End address'; + } newButton.id = 'geocoder-remove-end'; } div.parentElement.removeChild(div); @@ -716,8 +759,15 @@ Array.prototype.unique = function() { }); }, waypointsChanged : function(e) { + var wps = e.waypoints; + var wpscount = wps.length; + var inputcount = document.getElementById('search').childNodes.length; + while(wpscount > inputcount) { + geocodeSearch.addGeocoder(); + inputcount++; + } var inputContainers = document.getElementById('search').childNodes; - $.each(e.waypoints, function(idx, wp) { + $.each(wps, function(idx, wp) { var name = wp.name; if(name == null || name == '') { geocoder.reverse(wp.latLng, 67108864, function(data) { @@ -1171,6 +1221,7 @@ Array.prototype.unique = function() { } toolKit = { addMarker : function(marker, markerHTML, openPopup, fav) { + if(marker == null || marker._latlng == null) return; fav = fav || false; var openPopup = (openPopup) ? true : false; var latlng = marker._latlng.lat + ',' + marker._latlng.lng; @@ -1217,6 +1268,7 @@ Array.prototype.unique = function() { return false; }, _popupMouseOut: function(e) { + if(marker == null || marker._popup == null) return false; L.DomEvent.off(marker._popup, 'mouseout', this._popupMouseOut, this); var tgt = e.toElement || e.relatedTarget; if (this._getParent(tgt, 'leaflet-popup')) return true; diff --git a/templates/main.php b/templates/main.php index 2a4e026..f1d4d40 100644 --- a/templates/main.php +++ b/templates/main.php @@ -79,6 +79,11 @@
Location tracking settings +

Mapzen API key

+

+ +