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 bc9da3b..85c64fb 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -38,5 +38,9 @@
array('name' => 'favorite#get_favorites', 'url' => '/api/1.0/favorite/getFavorites', 'verb' => 'POST'),
array('name' => 'favorite#remove_favorite', 'url' => '/api/1.0/favorite/removeFromFavorites', 'verb' => 'POST'),
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/favoritecontroller.php b/controller/favoritecontroller.php
index 0d736e7..ba34c6d 100644
--- a/controller/favoritecontroller.php
+++ b/controller/favoritecontroller.php
@@ -86,6 +86,18 @@ public function getFavorites(){
return new JSONResponse($favorites);
}
+ /**
+ * @NoAdminRequired
+ *
+ * @param $name string
+ *
+ * @return JSONResponse
+ */
+ public function getFavoritesByName($name){
+ $favorites = $this->favoriteMapper->findByName($name);
+ return new JSONResponse($favorites);
+ }
+
/**
* @NoAdminRequired
*
diff --git a/controller/pagecontroller.php b/controller/pagecontroller.php
index 13ec0ea..5b201aa 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,10 +57,25 @@ public function index() {
// marker icons
$csp->addAllowedImageDomain('https://api.tiles.mapbox.com');
// inline images
- $csp->addAllowedScriptDomain('data:');
$csp->addAllowedImageDomain('data:');
//overpasslayer api
$csp->addAllowedConnectDomain('http://overpass-api.de/api/interpreter?');
+ $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;
@@ -106,7 +126,7 @@ public function search() {
$kw = $this -> params('search');
$bbox = $this -> params('bbox');
$response = array('contacts'=>array(),'nodes'=>array(),'addresses'=>array());
-
+
$contacts = $cm -> search($kw, array('FN', 'ADR'));
foreach ($contacts as $r) {
$data = array();
@@ -126,7 +146,7 @@ public function search() {
}
}
//$response['addresses'] = (array)($this->doAdresslookup($kw));
-
+
return $response;
}
@@ -139,9 +159,9 @@ public function geodecode(){
$lat = $this->params('lat');
$lng = $this->params('lng');
$zoom = $this->params('zoom');
-
+
$hash = md5($lat.','.$lng.'@'.$zoom);
-
+
$checkCache = $this -> checkGeoCache($hash);
if(!$checkCache){
$url = 'http://nominatim.openstreetmap.org/reverse/?format=json&email=brantje@gmail.com&lat='.$lat.'&lng='. $lng.'&zoom=67108864';
@@ -154,7 +174,7 @@ public function geodecode(){
}
echo $response;
die();
- }
+ }
/**
* Simply method that posts back the payload of the request
* @NoAdminRequired
@@ -217,7 +237,7 @@ private function getURL($url, $userAgent = true) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
- curl_setopt($ch, CURLOPT_TIMEOUT, 900);
+ curl_setopt($ch, CURLOPT_TIMEOUT, 900);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
if ($userAgent) {
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB5');
diff --git a/css/leaflet/Control.Geocoder.css b/css/leaflet/Control.Geocoder.css
new file mode 100644
index 0000000..ddc78ae
--- /dev/null
+++ b/css/leaflet/Control.Geocoder.css
@@ -0,0 +1,104 @@
+.leaflet-control-geocoder {
+ background: white;
+}
+
+.leaflet-control-geocoder a, .leaflet-control-geocoder .leaflet-control-geocoder-icon {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom: none;
+ display: inline-block;
+}
+
+.leaflet-control-geocoder .leaflet-control-geocoder-alternatives a {
+ width: inherit;
+ height: inherit;
+ line-height: inherit;
+}
+
+.leaflet-control-geocoder a:hover, .leaflet-control-geocoder .leaflet-control-geocoder-icon:hover {
+ border-bottom: none;
+ display: inline-block;
+}
+
+.leaflet-control-geocoder-form {
+ display: none;
+ vertical-align: middle;
+}
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form {
+ display: inline-block;
+}
+.leaflet-control-geocoder-form input {
+ font-size: 120%;
+ border: 0;
+ background-color: transparent;
+ width: 246px;
+}
+.leaflet-control-geocoder-icon {
+ background-image: url(images/geocoder.png);
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon {
+ background-image: url(images/throbber.gif);
+}
+
+.leaflet-control-geocoder-form-no-error {
+ display: none;
+}
+
+.leaflet-control-geocoder-form input:focus {
+ outline: none;
+}
+
+.leaflet-control-geocoder-form button {
+ display: none;
+}
+.leaflet-control-geocoder-error {
+ margin-top: 8px;
+ margin-left: 8px;
+ display: block;
+ color: #444;
+}
+.leaflet-control-geocoder-alternatives {
+ display: block;
+ width: 272px;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.leaflet-control-geocoder-alternatives-minimized {
+ display: none;
+ height: 0;
+}
+.leaflet-control-geocoder-alternatives li {
+ white-space: nowrap;
+ display: block;
+ overflow: hidden;
+ padding: 5px 8px;
+ text-overflow: ellipsis;
+ border-bottom: 1px solid #ccc;
+ cursor: pointer;
+}
+
+.leaflet-control-geocoder-alternatives li a, .leaflet-control-geocoder-alternatives li a:hover {
+ width: inherit;
+ height: inherit;
+ line-height: inherit;
+ background: inherit;
+ border-radius: inherit;
+ text-align: left;
+}
+
+.leaflet-control-geocoder-alternatives li:last-child {
+ border-bottom: none;
+}
+.leaflet-control-geocoder-alternatives li:hover, .leaflet-control-geocoder-selected {
+ background-color: #f5f5f5;
+}
+.leaflet-control-geocoder-address-detail {
+
+}
+.leaflet-control-geocoder-address-context {
+ color: #666;
+}
diff --git a/css/leaflet/images/geocoder.png b/css/leaflet/images/geocoder.png
new file mode 100644
index 0000000..d82a017
Binary files /dev/null and b/css/leaflet/images/geocoder.png differ
diff --git a/css/leaflet/images/throbber.gif b/css/leaflet/images/throbber.gif
new file mode 100644
index 0000000..c0c52a0
Binary files /dev/null and b/css/leaflet/images/throbber.gif differ
diff --git a/css/leaflet/leaflet-routing-machine.css b/css/leaflet/leaflet-routing-machine.css
index 3f55305..f513955 100644
--- a/css/leaflet/leaflet-routing-machine.css
+++ b/css/leaflet/leaflet-routing-machine.css
@@ -1,114 +1,258 @@
-.leaflet-routing-container {
- width:240px;
- padding-top: 4px;
- transition: margin-right 0.2s ease;
-}
-
-.leaflet-control-container .leaflet-routing-container-hide {
- margin-right: -340px;
-}
-
-.leaflet-routing-container h2 {
- font-size: 14px;
-}
-
-.leaflet-routing-container h3 {
- font-size: 12px;
- font-weight: normal;
-}
-.leaflet-marker-icon-wrapper{
- position: absolute;
-}
-.leaflet-routing-alt, .leaflet-routing-geocoders {
- padding: 6px;
- margin-top: 2px;
- margin-bottom: 6px;
- border-bottom: 1px solid #ccc;
- max-height: 320px;
- overflow-y: auto;
- transition: all 0.2s ease;
-}
-
-.leaflet-bar .leaflet-routing-alt:last-child {
- border-bottom: none;
-}
-
-.leaflet-routing-alt-minimized {
- color: #888;
- max-height: 64px;
- overflow: hidden;
- cursor: pointer;
-}
-
-.leaflet-routing-alt table {
- border-collapse: collapse;
-}
-
-.leaflet-routing-alt tr:hover {
- background-color: #eee;
- cursor: pointer;
-}
-
-.leaflet-routing-alt::-webkit-scrollbar {
- width: 8px;
-}
-
-.leaflet-routing-alt::-webkit-scrollbar-track {
- border-radius: 2px;
- background-color: #eee;
-}
-
-.leaflet-routing-alt::-webkit-scrollbar-thumb {
- border-radius: 2px;
- background-color: #888;
-}
-
-.leaflet-routing-geocoders input {
- width: 192px;
- padding: 4px;
- border: 1px solid #ccc;
-}
-
-.leaflet-routing-geocoders button {
- font: bold 18px 'Lucida Console', Monaco, monospace;
- border: 1px solid #ccc;
- border-radius: 4px;
- background-color: white;
- margin: 0 6px;
- float: right;
- cursor: pointer;
- transition: background-color 0.2s ease;
-}
-
-.leaflet-routing-geocoders button:hover {
- background-color: #eee;
-}
-
-.leaflet-routing-geocoder-result {
- position: absolute;
- max-height: 0;
- overflow: hidden;
- transition: all 0.5s ease;
- z-index: 60;
-}
-
-.leaflet-routing-geocoder-result table {
- width: 100%;
- border: 1px solid #ccc;
- border-radius: 0 0 4px 4px;
- background-color: white;
- cursor: pointer;
-}
-
-.leaflet-routing-geocoder-result-open {
- max-height: 800px;
-}
-
-.leaflet-routing-geocoder-selected, .leaflet-routing-geocoder-result tr:hover {
- background-color: #eee;
-}
-
-.leaflet-routing-geocoder-no-results {
- font-style: italic;
- color: #888;
-}
\ No newline at end of file
+.leaflet-routing-container, .leaflet-routing-error {
+ width: 320px;
+ background-color: white;
+ padding-top: 4px;
+ transition: all 0.2s ease;
+ box-sizing: border-box;
+}
+
+.leaflet-control-container .leaflet-routing-container-hide {
+ width: 32px;
+ height: 32px;
+}
+
+.leaflet-routing-container h2 {
+ font-size: 14px;
+}
+
+.leaflet-routing-container h3 {
+ font-size: 12px;
+ font-weight: normal;
+}
+
+.leaflet-routing-collapsible .leaflet-routing-geocoders {
+ margin-top: 20px;
+}
+
+.leaflet-routing-alt, .leaflet-routing-geocoders, .leaflet-routing-error {
+ padding: 6px;
+ margin-top: 2px;
+ margin-bottom: 6px;
+ border-bottom: 1px solid #ccc;
+ max-height: 320px;
+ overflow-y: auto;
+ transition: all 0.2s ease;
+}
+
+.leaflet-control-container .leaflet-routing-container-hide .leaflet-routing-alt,
+.leaflet-control-container .leaflet-routing-container-hide .leaflet-routing-geocoders {
+ display: none;
+}
+
+.leaflet-bar .leaflet-routing-alt:last-child {
+ border-bottom: none;
+}
+
+.leaflet-routing-alt-minimized {
+ color: #888;
+ max-height: 64px;
+ overflow: hidden;
+ cursor: pointer;
+}
+
+.leaflet-routing-alt table {
+ border-collapse: collapse;
+}
+
+.leaflet-routing-alt tr:hover {
+ background-color: #eee;
+ cursor: pointer;
+}
+
+.leaflet-routing-alt::-webkit-scrollbar {
+ width: 8px;
+}
+
+.leaflet-routing-alt::-webkit-scrollbar-track {
+ border-radius: 2px;
+ background-color: #eee;
+}
+
+.leaflet-routing-alt::-webkit-scrollbar-thumb {
+ border-radius: 2px;
+ background-color: #888;
+}
+
+.leaflet-routing-icon {
+ background-image: url('leaflet.routing.icons.png');
+ -webkit-background-size: 240px 20px;
+ background-size: 240px 20px;
+ background-repeat: no-repeat;
+ margin: 0;
+ content: '';
+ display: inline-block;
+ vertical-align: top;
+ width: 20px;
+ height: 20px;
+}
+
+.leaflet-routing-icon-continue { background-position: 0 0; }
+.leaflet-routing-icon-sharp-right { background-position: -20px 0; }
+.leaflet-routing-icon-turn-right { background-position: -40px 0; }
+.leaflet-routing-icon-bear-right { background-position: -60px 0; }
+.leaflet-routing-icon-u-turn { background-position: -80px 0; }
+.leaflet-routing-icon-sharp-left { background-position: -100px 0; }
+.leaflet-routing-icon-turn-left { background-position: -120px 0; }
+.leaflet-routing-icon-bear-left { background-position: -140px 0; }
+.leaflet-routing-icon-depart { background-position: -160px 0; }
+.leaflet-routing-icon-enter-roundabout { background-position: -180px 0; }
+.leaflet-routing-icon-arrive { background-position: -200px 0; }
+.leaflet-routing-icon-via { background-position: -220px 0; }
+
+.leaflet-routing-geocoders div {
+ padding: 4px 0px 4px 0px;
+}
+
+.leaflet-routing-geocoders input {
+ width: 303px;
+ width: calc(100% - 4px);
+ line-height: 1.67;
+ border: 1px solid #ccc;
+}
+
+.leaflet-routing-geocoders button {
+ font: bold 18px 'Lucida Console', Monaco, monospace;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ background-color: white;
+ margin: 0;
+ margin-right: 3px;
+ float: right;
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+}
+
+.leaflet-routing-add-waypoint:after {
+ content: '+';
+}
+
+.leaflet-routing-reverse-waypoints:after {
+ font-weight: normal;
+ content: '\21c5';
+}
+
+.leaflet-routing-geocoders button:hover {
+ background-color: #eee;
+}
+
+.leaflet-routing-geocoders input,.leaflet-routing-remove-waypoint,.leaflet-routing-geocoder {
+ position: relative;
+}
+
+.leaflet-routing-geocoder-result {
+ font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+ position: absolute;
+ max-height: 0;
+ overflow: hidden;
+ transition: all 0.5s ease;
+ z-index: 1000; /* Arbitrary, but try to be above "most" things. */
+}
+
+.leaflet-routing-geocoder-result table {
+ width: 100%;
+ border: 1px solid #ccc;
+ border-radius: 0 0 4px 4px;
+ background-color: white;
+ cursor: pointer;
+}
+
+.leaflet-routing-geocoder-result-open {
+ max-height: 800px;
+}
+
+.leaflet-routing-geocoder-selected, .leaflet-routing-geocoder-result tr:hover {
+ background-color: #eee;
+}
+
+.leaflet-routing-geocoder-no-results {
+ font-style: italic;
+ color: #888;
+}
+
+.leaflet-routing-remove-waypoint {
+ background-color: transparent;
+ display: inline-block;
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+.leaflet-routing-remove-waypoint:after {
+ position: absolute;
+ display: block;
+ width: 15px;
+ height: 1px;
+ z-index: 1;
+ right: 1px;
+ top: 4px;
+ bottom: 0;
+ margin: auto;
+ padding: 2px;
+ font-size: 18px;
+ font-weight: bold;
+ content: "\00d7";
+ text-align: center;
+ cursor: pointer;
+ color: #ccc;
+ background: white;
+ padding-bottom: 16px;
+ margin-top: -16px;
+ padding-right: 4px;
+ line-height: 1;
+}
+
+.leaflet-routing-remove-waypoint:hover {
+ color: black;
+}
+
+.leaflet-routing-instruction-distance {
+ width: 48px;
+}
+
+.leaflet-routing-collapse-btn {
+ position: absolute;
+ top: 0;
+ right: 6px;
+ font-size: 24px;
+ color: #ccc;
+ font-weight: bold;
+}
+
+.leaflet-routing-collapse-btn:after {
+ content: '\00d7';
+}
+
+.leaflet-routing-container-hide .leaflet-routing-collapse-btn {
+ position: relative;
+ left: 4px;
+ top: 4px;
+ display: block;
+ width: 26px;
+ height: 23px;
+ background-image: url('routing-icon.png');
+}
+
+.leaflet-routing-container-hide .leaflet-routing-collapse-btn:after {
+ content: none;
+}
+
+.leaflet-top .leaflet-routing-container.leaflet-routing-container-hide {
+ margin-top: 10px !important;
+}
+.leaflet-right .leaflet-routing-container.leaflet-routing-container-hide {
+ margin-right: 10px !important;
+}
+.leaflet-bottom .leaflet-routing-container.leaflet-routing-container-hide {
+ margin-bottom: 10px !important;
+}
+.leaflet-left .leaflet-routing-container.leaflet-routing-container-hide {
+ margin-left: 10px !important;
+}
+
+@media only screen and (max-width: 640px) {
+ .leaflet-routing-container {
+ margin: 0 !important;
+ padding: 0 !important;
+ width: 100%;
+ height: 100%;
+ }
+}
diff --git a/css/leaflet/leaflet.routing.icons.png b/css/leaflet/leaflet.routing.icons.png
new file mode 100644
index 0000000..2566467
Binary files /dev/null and b/css/leaflet/leaflet.routing.icons.png differ
diff --git a/css/leaflet/leaflet.routing.icons.svg b/css/leaflet/leaflet.routing.icons.svg
new file mode 100644
index 0000000..a544746
--- /dev/null
+++ b/css/leaflet/leaflet.routing.icons.svg
@@ -0,0 +1,239 @@
+
+
+
+
diff --git a/css/leaflet/routing-icon.png b/css/leaflet/routing-icon.png
new file mode 100644
index 0000000..3f4b80b
Binary files /dev/null and b/css/leaflet/routing-icon.png differ
diff --git a/css/style.css b/css/style.css
index c20a78d..b9eff6e 100644
--- a/css/style.css
+++ b/css/style.css
@@ -42,6 +42,40 @@ div.olControlZoom a {
filter: alpha(opacity=80);
}
+div#search {
+ position: absolute;
+ top: 3px;
+ left: 50px;
+ z-index: 1;
+}
+
+div.geocoder-container {
+ display: block;
+}
+
+input.geocoder {
+ width: 210px;
+}
+
+ul.geocoder-list {
+ background: white;
+ width: 400px;
+ font-size: 10px;
+ position: absolute;
+}
+
+li.geocoder-list-item {
+ padding: 5px;
+}
+
+li.geocoder-list-item:hover {
+ background: #ddd;
+}
+
+button#geocoder-button {
+ background: white;
+}
+
input#search {
width: 180px;
margin: 10px 10px;
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/db/favoritemapper.php b/db/favoritemapper.php
index 90fc007..947a786 100644
--- a/db/favoritemapper.php
+++ b/db/favoritemapper.php
@@ -22,6 +22,16 @@ public function find($id) {
return $this->findEntity($sql, [$id]);
}
+ /**
+ * @param string $name
+ * @return Favorite[]
+ */
+ public function findByName($name) {
+ $sql = 'SELECT * FROM `*PREFIX*maps_favorites` '.
+ 'WHERE `name` ILIKE ?';
+ return $this->findEntities($sql, ['%' . addcslashes($name, '\\_%') . '%']);
+ }
+
/**
* @param string $userId
* @param string $from
diff --git a/js/3rdparty/leaflet/lib/Control.Geocoder.js b/js/3rdparty/leaflet/lib/Control.Geocoder.js
index fdd8792..e3f0ca1 100644
--- a/js/3rdparty/leaflet/lib/Control.Geocoder.js
+++ b/js/3rdparty/leaflet/lib/Control.Geocoder.js
@@ -1,22 +1,10 @@
-(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({
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o' +
- (this.options.showResultIcons && result.icon ?
- '
' :
- '') +
- result.name + '';
- L.DomEvent.addListener(li, 'click', function clickHandler() {
- this._geocodeResultSelected(result);
- }, this);
+ var li = L.DomUtil.create('li', ''),
+ a = L.DomUtil.create('a', '', 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;
},
_keydown: function(e) {
var _this = this,
- select = function select(dir) {
+ select = function select(dir) {
if (_this._selection) {
- L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
+ L.DomUtil.removeClass(_this._selection, 'leaflet-control-geocoder-selected');
_this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
}
if (!_this._selection) {
@@ -185,11 +191,17 @@
}
if (_this._selection) {
- L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
+ L.DomUtil.addClass(_this._selection, 'leaflet-control-geocoder-selected');
}
};
switch (e.keyCode) {
+ // Escape
+ case 27:
+ if (this.options.collapsed) {
+ this._collapse();
+ }
+ break;
// Up
case 38:
select(-1);
@@ -203,7 +215,7 @@
// Enter
case 13:
if (this._selection) {
- var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10);
+ var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
this._geocodeResultSelected(this._results[index]);
this._clearResults();
L.DomEvent.preventDefault(e);
@@ -211,27 +223,452 @@
}
return true;
}
- });
+ }),
+ factory: function(options) {
+ return new L.Control.Geocoder(options);
+ }
+};
- L.Control.geocoder = function(id, options) {
- return new L.Control.Geocoder(id, options);
- };
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./geocoders/nominatim":7}],2:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
- 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);
- };
+module.exports = {
+ "class": L.Class.extend({
+ initialize: function(key) {
+ this.key = key;
+ },
+
+ geocode : function (query, cb, context) {
+ Util.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
+ query: query,
+ key : this.key
+ }, function(data) {
+ var results = [];
+ if( data.resourceSets.length > 0 ){
+ 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) {
+ Util.jsonp('//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');
+ }
+ }),
+
+ factory: function(key) {
+ return new L.Control.Geocoder.Bing(key);
+ }
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],3:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(key, options) {
+ this._key = key;
+ L.setOptions(this, options);
+ // Backwards compatibility
+ this.options.serviceUrl = this.options.service_url || this.options.serviceUrl;
+ },
+
+ geocode: function(query, cb, context) {
+ var params = {
+ address: query
+ };
+
+ if (this._key && this._key.length) {
+ params.key = this._key;
+ }
+
+ params = L.Util.extend(params, this.options.geocodingQueryParams);
+
+ Util.getJSON(this.options.serviceUrl, params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.results && data.results.length) {
+ for (var i = 0; i <= data.results.length - 1; i++) {
+ loc = data.results[i];
+ latLng = L.latLng(loc.geometry.location);
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
+ results[i] = {
+ name: loc.formatted_address,
+ bbox: latLngBounds,
+ center: latLng,
+ properties: loc.address_components
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var params = {
+ latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
+ };
+ params = L.Util.extend(params, this.options.reverseQueryParams);
+ if (this._key && this._key.length) {
+ params.key = this._key;
+ }
+
+ Util.getJSON(this.options.serviceUrl, params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.results && data.results.length) {
+ for (var i = 0; i <= data.results.length - 1; i++) {
+ loc = data.results[i];
+ latLng = L.latLng(loc.geometry.location);
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
+ results[i] = {
+ name: loc.formatted_address,
+ bbox: latLngBounds,
+ center: latLng,
+ properties: loc.address_components
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ }
+ }),
+
+ factory: function(key, options) {
+ return new L.Control.Geocoder.Google(key, options);
+ }
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],4:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
+ },
+
+ initialize: function(accessToken, options) {
+ L.setOptions(this, options);
+ this._accessToken = accessToken;
+ },
+
+ geocode: function(query, cb, context) {
+ Util.getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', {
+ access_token: this._accessToken
+ }, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.features && data.features.length) {
+ for (var i = 0; i <= data.features.length - 1; i++) {
+ loc = data.features[i];
+ latLng = L.latLng(loc.center.reverse());
+ if(loc.hasOwnProperty('bbox'))
+ {
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
+ }
+ else
+ {
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ }
+ results[i] = {
+ name: loc.place_name,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(location, scale, cb, context) {
+ Util.getJSON(this.options.serviceUrl + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
+ access_token: this._accessToken
+ }, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.features && data.features.length) {
+ for (var i = 0; i <= data.features.length - 1; i++) {
+ loc = data.features[i];
+ latLng = L.latLng(loc.center.reverse());
+ if(loc.hasOwnProperty('bbox'))
+ {
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
+ }
+ else
+ {
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ }
+ results[i] = {
+ name: loc.place_name,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ }
+ }),
+
+ factory: function(accessToken, options) {
+ return new L.Control.Geocoder.Mapbox(accessToken, options);
+ }
+};
+
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],5:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: '//www.mapquestapi.com/geocoding/v1'
+ },
+
+ initialize: function(key, options) {
+ // MapQuest seems to provide URI encoded API keys,
+ // so to avoid encoding them twice, we decode them here
+ this._key = decodeURIComponent(key);
+
+ L.Util.setOptions(this, options);
+ },
+
+ _formatName: function() {
+ var r = [],
+ i;
+ for (i = 0; i < arguments.length; i++) {
+ if (arguments[i]) {
+ r.push(arguments[i]);
+ }
+ }
+
+ return r.join(', ');
+ },
+
+ geocode: function(query, cb, context) {
+ Util.jsonp(this.options.serviceUrl + '/address', {
+ key: this._key,
+ location: query,
+ limit: 5,
+ outFormat: 'json'
+ }, function(data) {
+ var results = [],
+ loc,
+ latLng;
+ if (data.results && data.results[0].locations) {
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
+ loc = data.results[0].locations[i];
+ latLng = L.latLng(loc.latLng);
+ results[i] = {
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
+ bbox: L.latLngBounds(latLng, latLng),
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ }, this);
+ },
- L.Control.Geocoder.Nominatim = L.Class.extend({
+ reverse: function(location, scale, cb, context) {
+ Util.jsonp(this.options.serviceUrl + '/reverse', {
+ key: this._key,
+ location: location.lat + ',' + location.lng,
+ outputFormat: 'json'
+ }, function(data) {
+ var results = [],
+ loc,
+ latLng;
+ if (data.results && data.results[0].locations) {
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
+ loc = data.results[0].locations[i];
+ latLng = L.latLng(loc.latLng);
+ results[i] = {
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
+ bbox: L.latLngBounds(latLng, latLng),
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ }, this);
+ }
+ }),
+
+ factory: function(key, options) {
+ return new L.Control.Geocoder.MapQuest(key, options);
+ }
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],6:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
options: {
- serviceUrl: OC.generateUrl('apps/maps/router?url=http://nominatim.openstreetmap.org/')
+ serviceUrl: '//search.mapzen.com/v1',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(apiKey, options) {
+ L.Util.setOptions(this, options);
+ this._apiKey = apiKey;
+ this._lastSuggest = 0;
+ },
+
+ geocode: function(query, cb, context) {
+ var _this = this;
+ Util.getJSON(this.options.serviceUrl + "/search", L.extend({
+ 'api_key': this._apiKey,
+ 'text': query
+ }, this.options.geocodingQueryParams), function(data) {
+ cb.call(context, _this._parseResults(data, "bbox"));
+ });
+ },
+
+ suggest: function(query, cb, context) {
+ var _this = this;
+ Util.getJSON(this.options.serviceUrl + "/autocomplete", L.extend({
+ 'api_key': this._apiKey,
+ 'text': query
+ }, this.options.geocodingQueryParams), function(data) {
+ if (data.geocoding.timestamp > this._lastSuggest) {
+ this._lastSuggest = data.geocoding.timestamp;
+ cb.call(context, _this._parseResults(data, "bbox"));
+ }
+ });
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var _this = this;
+ Util.getJSON(this.options.serviceUrl + "/reverse", L.extend({
+ 'api_key': this._apiKey,
+ 'point.lat': location.lat,
+ 'point.lon': location.lng
+ }, this.options.reverseQueryParams), function(data) {
+ cb.call(context, _this._parseResults(data, "bounds"));
+ });
+ },
+
+ _parseResults: function(data, bboxname) {
+ var results = [];
+ L.geoJson(data, {
+ pointToLayer: function (feature, latlng) {
+ return L.circleMarker(latlng);
+ },
+ onEachFeature: function(feature, layer) {
+ var result = {};
+ result['name'] = layer.feature.properties.label;
+ result[bboxname] = layer.getBounds();
+ result['center'] = result[bboxname].getCenter();
+ result['properties'] = layer.feature.properties;
+ results.push(result);
+ }
+ });
+ return results;
+ }
+ }),
+
+ factory: function(apiKey, options) {
+ return new L.Control.Geocoder.Mapzen(apiKey, options);
+ }
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],7:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: '//nominatim.openstreetmap.org/',
+ geocodingQueryParams: {},
+ reverseQueryParams: {},
+ htmlTemplate: function(r) {
+ var a = r.address,
+ parts = [];
+ if (a.road || a.building) {
+ parts.push('{building} {road} {house_number}');
+ }
+
+ if (a.city || a.town || a.village) {
+ parts.push('{postcode} {city} {town} {village}');
+ }
+
+ if (a.state || a.country) {
+ parts.push('{state} {country}');
+ }
+
+ return Util.template(parts.join('
'), a, true);
+ }
},
initialize: function(options) {
@@ -239,11 +676,13 @@
},
geocode: function(query, cb, context) {
- L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', {
+ Util.jsonp(this.options.serviceUrl + 'search', L.extend({
q: query,
limit: 5,
- format: 'json'
- }, function(data) {
+ format: 'json',
+ addressdetails: 1
+ }, this.options.geocodingQueryParams),
+ function(data) {
var results = [];
for (var i = data.length - 1; i >= 0; i--) {
var bbox = data[i].boundingbox;
@@ -251,9 +690,12 @@
results[i] = {
icon: data[i].icon,
name: data[i].display_name,
+ html: this.options.htmlTemplate ?
+ this.options.htmlTemplate(data[i])
+ : undefined,
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
+ center: L.latLng(data[i].lat, data[i].lon),
+ properties: data[i]
};
}
cb.call(context, results);
@@ -261,133 +703,334 @@
},
reverse: function(location, scale, cb, context) {
- L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', {
+ Util.jsonp(this.options.serviceUrl + 'reverse', L.extend({
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.options.reverseQueryParams), function(data) {
+ var result = [],
+ loc;
+
+ if (data && data.lat && data.lon) {
+ loc = L.latLng(data.lat, data.lon);
+ result.push({
+ name: data.display_name,
+ html: this.options.htmlTemplate ?
+ this.options.htmlTemplate(data)
+ : undefined,
+ center: loc,
+ bounds: L.latLngBounds(loc, loc),
+ properties: data
+ });
+ }
+
+ cb.call(context, result);
}, this, 'json_callback');
}
- });
+ }),
- L.Control.Geocoder.nominatim = function(options) {
+ factory: function(options) {
return new L.Control.Geocoder.Nominatim(options);
- };
+ }
+};
- L.Control.Geocoder.Bing = L.Class.extend({
- initialize: function(key) {
- this.key = key;
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],8:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: '//photon.komoot.de/api/',
+ reverseUrl: '//photon.komoot.de/reverse/',
+ nameProperties: [
+ 'name',
+ 'street',
+ 'suburb',
+ 'hamlet',
+ 'town',
+ 'city',
+ 'state',
+ 'country'
+ ]
},
- 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
+ initialize: function(options) {
+ L.setOptions(this, options);
+ },
+
+ geocode: function(query, cb, context) {
+ var params = L.extend({
+ q: query
+ }, this.options.geocodingQueryParams);
+
+ Util.getJSON(this.options.serviceUrl, params, L.bind(function(data) {
+ cb.call(context, this._decodeFeatures(data));
+ }, this));
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(latLng, scale, cb, context) {
+ var params = L.extend({
+ lat: latLng.lat,
+ lon: latLng.lng
+ }, this.options.geocodingQueryParams);
+
+ Util.getJSON(this.options.reverseUrl, params, L.bind(function(data) {
+ cb.call(context, this._decodeFeatures(data));
+ }, this));
+ },
+
+ _decodeFeatures: function(data) {
+ var results = [],
+ i,
+ f,
+ c,
+ latLng,
+ extent,
+ bbox;
+
+ if (data && data.features) {
+ for (i = 0; i < data.features.length; i++) {
+ f = data.features[i];
+ c = f.geometry.coordinates;
+ latLng = L.latLng(c[1], c[0]);
+ extent = f.properties.extent;
+
+ if (extent) {
+ bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
+ } else {
+ bbox = L.latLngBounds(latLng, latLng);
+ }
+
+ results.push({
+ name: this._deocodeFeatureName(f),
+ center: latLng,
+ bbox: bbox,
+ properties: f.properties
+ });
+ }
+ }
+
+ return results;
+ },
+
+ _deocodeFeatureName: function(f) {
+ var j,
+ name;
+ for (j = 0; !name && j < this.options.nameProperties.length; j++) {
+ name = f.properties[this.options.nameProperties[j]];
+ }
+
+ return name;
+ }
+ }),
+
+ factory: function(options) {
+ return new L.Control.Geocoder.Photon(options);
+ }
+};
+
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],9:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Util = require('../util');
+
+module.exports = {
+ "class": L.Class.extend({
+ options: {
+ serviceUrl: 'http://api.what3words.com/'
+ },
+
+ initialize: function(accessToken) {
+ this._accessToken = accessToken;
+ },
+
+ geocode: function(query, cb, context) {
+ //get three words and make a dot based string
+ Util.getJSON(this.options.serviceUrl +'w3w', {
+ key: this._accessToken,
+ string: query.split(/\s+/).join('.')
}, 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)
+ var results = [], loc, latLng, latLngBounds;
+ if (data.position && data.position.length) {
+ loc = data.words;
+ latLng = L.latLng(data.position[0],data.position[1]);
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ results[0] = {
+ name: loc.join('.'),
+ bbox: latLngBounds,
+ center: latLng
};
}
+
cb.call(context, results);
- }, this, 'jsonp');
+ });
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
},
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
+ Util.getJSON(this.options.serviceUrl +'position', {
+ key: this._accessToken,
+ position: [location.lat,location.lng].join(',')
}, 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)
+ var results = [],loc,latLng,latLngBounds;
+ if (data.position && data.position.length) {
+ loc = data.words;
+ latLng = L.latLng(data.position[0],data.position[1]);
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ results[0] = {
+ name: loc.join('.'),
+ bbox: latLngBounds,
+ center: latLng
};
}
cb.call(context, results);
- }, this, 'jsonp');
+ });
}
- });
+ }),
- L.Control.Geocoder.bing = function(key) {
- return new L.Control.Geocoder.Bing(key);
- };
+ factory: function(accessToken) {
+ return new L.Control.Geocoder.What3Words(accessToken);
+ }
+};
- 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]));
- }
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"../util":11}],10:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ Control = require('./control'),
+ Nominatim = require('./geocoders/nominatim'),
+ Bing = require('./geocoders/bing'),
+ MapQuest = require('./geocoders/mapquest'),
+ Mapbox = require('./geocoders/mapbox'),
+ What3Words = require('./geocoders/what3words'),
+ Google = require('./geocoders/google'),
+ Photon = require('./geocoders/photon'),
+ Mapzen = require('./geocoders/mapzen');
- 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);
- },
+module.exports = L.Util.extend(Control["class"], {
+ Nominatim: Nominatim["class"],
+ nominatim: Nominatim.factory,
+ Bing: Bing["class"],
+ bing: Bing.factory,
+ MapQuest: MapQuest["class"],
+ mapQuest: MapQuest.factory,
+ Mapbox: Mapbox["class"],
+ mapbox: Mapbox.factory,
+ What3Words: What3Words["class"],
+ what3words: What3Words.factory,
+ Google: Google["class"],
+ google: Google.factory,
+ Photon: Photon["class"],
+ photon: Photon.factory,
+ Mapzen: Mapzen["class"],
+ mapzen: Mapzen.factory
+});
- initialize: function(serviceUrl, scheme, options) {
- L.Util.setOptions(this, options);
+L.Util.extend(L.Control, {
+ Geocoder: module.exports,
+ geocoder: Control.factory
+});
- this._serviceUrl = serviceUrl;
- this._scheme = scheme;
- },
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./control":1,"./geocoders/bing":2,"./geocoders/google":3,"./geocoders/mapbox":4,"./geocoders/mapquest":5,"./geocoders/mapzen":6,"./geocoders/nominatim":7,"./geocoders/photon":8,"./geocoders/what3words":9}],11:[function(require,module,exports){
+(function (global){
+var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
+ lastCallbackId = 0,
+ htmlEscape = (function() {
+ // Adapted from handlebars.js
+ // https://github.com/wycats/handlebars.js/
+ var badChars = /[&<>"'`]/g;
+ var possible = /[&<>"'`]/;
+ var escape = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ '\'': ''',
+ '`': '`'
+ };
- 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);
+ function escapeChar(chr) {
+ return escape[chr];
}
- });
- L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) {
- return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options);
- };
+ return function(string) {
+ if (string == null) {
+ return '';
+ } else if (!string) {
+ return string + '';
+ }
+
+ // Force a string conversion as this will be done by the append regardless and
+ // the regex test will do this transparently behind the scenes, causing issues if
+ // an object's to string has escaped characters in it.
+ string = '' + string;
+
+ if (!possible.test(string)) {
+ return string;
+ }
+ return string.replace(badChars, escapeChar);
+ };
+ })();
+
+module.exports = {
+ jsonp: function(url, params, callback, context, jsonpParam) {
+ var callbackId = '_l_geocoder_' + (lastCallbackId++);
+ 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);
+ },
+
+ getJSON: function(url, params, callback) {
+ var xmlHttp = new XMLHttpRequest();
+ xmlHttp.onreadystatechange = function () {
+ if (xmlHttp.readyState !== 4){
+ return;
+ }
+ if (xmlHttp.status !== 200 && xmlHttp.status !== 304){
+ callback('');
+ return;
+ }
+ callback(JSON.parse(xmlHttp.response));
+ };
+ xmlHttp.open('GET', url + L.Util.getParamString(params), true);
+ xmlHttp.setRequestHeader('Accept', 'application/json');
+ xmlHttp.send(null);
+ },
+
+ template: function (str, data) {
+ return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
+ var value = data[key];
+ if (value === undefined) {
+ value = '';
+ } else if (typeof value === 'function') {
+ value = value(data);
+ }
+ return htmlEscape(value);
+ });
+ },
+
+ htmlEscape: htmlEscape
+};
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}]},{},[10]);
- return L.Control.Geocoder;
-}));
\ No newline at end of file
diff --git a/js/3rdparty/leaflet/plugins/leaflet-routing-machine.min.js b/js/3rdparty/leaflet/plugins/leaflet-routing-machine.min.js
index c3c22a6..e3817dd 100644
--- a/js/3rdparty/leaflet/plugins/leaflet-routing-machine.min.js
+++ b/js/3rdparty/leaflet/plugins/leaflet-routing-machine.min.js
@@ -1,1394 +1,4 @@
-// Packaging/modules magic dance. This code is inserted before all other
-// code when the dist is built.
-(function (factory) {
- 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) {
-(function() {
- 'use strict';
-
- L.Routing = L.Routing || {};
-
- L.Routing.Autocomplete = L.Class.extend({
- options: {
- timeout: 500,
- blurTimeout: 100,
- noResultsMessage: 'No results found.'
- },
-
- initialize: function(elem, callback, context, options) {
- L.setOptions(this, options);
-
- this._elem = elem;
- this._resultFn = options.resultFn ? L.Util.bind(options.resultFn, options.resultContext) : null;
- this._autocomplete = options.autocompleteFn ? L.Util.bind(options.autocompleteFn, options.autocompleteContext) : null;
- this._selectFn = L.Util.bind(callback, context);
- this._container = L.DomUtil.create('div', 'leaflet-routing-geocoder-result');
- this._resultTable = L.DomUtil.create('table', '', this._container);
-
- // TODO: looks a bit like a kludge to register same for input and keypress -
- // browsers supporting both will get duplicate events; just registering
- // input will not catch enter, though.
- L.DomEvent.addListener(this._elem, 'input', this._keyPressed, this);
- L.DomEvent.addListener(this._elem, 'keypress', this._keyPressed, this);
- L.DomEvent.addListener(this._elem, 'keydown', this._keyDown, this);
- L.DomEvent.addListener(this._elem, 'blur', function(e) {
- if (this._isOpen) {
- //this.close();
- }
- else
- {
- if($(e.srcElement).val()==''){
- $(e.srcElement).attr('completiontype','local');
- }
- }
- }, this);
- },
-
- close: function() {
- L.DomUtil.removeClass(this._container, 'leaflet-routing-geocoder-result-open');
- this._isOpen = false;
- },
-
- _open: function() {
- var sibling = this._elem.nextSibling;
- if (!this._container.parentElement) {
- if (sibling) {
- this._elem.parentElement.insertBefore(this._container, sibling);
- } else {
- this._elem.parentElement.appendChild(this._container);
- }
- this._container.style.left = this._elem.offsetLeft + 'px';
- this._container.style.top = (this._elem.offsetTop + this._elem.offsetHeight) + 'px';
- this._container.style.width = 'auto';
- }
-
- L.DomUtil.addClass(this._container, 'leaflet-routing-geocoder-result-open');
- this._isOpen = true;
- },
-
- _setResults: function(results) {
- var i,
- tr,
- td,
- text;
-
- delete this._selection;
- this._results = results;
-
- while (this._resultTable.firstChild) {
- this._resultTable.removeChild(this._resultTable.firstChild);
- }
-
- for (i = 0; i < results.length; i++) {
- tr = L.DomUtil.create('tr', '', this._resultTable);
- tr.setAttribute('data-result-index', i);
- td = L.DomUtil.create('td', '', tr);
- text = document.createTextNode(results[i].name);
- td.appendChild(text);
- // mousedown + click because:
- // http://stackoverflow.com/questions/10652852/jquery-fire-click-before-blur-event
- L.DomEvent.addListener(td, 'mousedown', L.DomEvent.preventDefault);
- L.DomEvent.addListener(td, 'click', this._resultSelected(results[i]), this);
- }
-
- if (!i) {
- tr = L.DomUtil.create('tr', '', this._resultTable);
- td = L.DomUtil.create('td', 'leaflet-routing-geocoder-no-results', tr);
- td.innerHTML = this.options.noResultsMessage;
- }
-
- this._open();
-
- if (results.length > 0) {
- // Select the first entry
- this._select(1);
- }
- },
-
- _resultSelected: function(r) {
- $(this._elem).attr('completed','true');
- return L.bind(function() {
- this.close();
- this._elem.value = r.name;
- this._lastCompletedText = r.name;
- this._selectFn(r);
- }, this);
- },
- keyPressTimeout: 0,
- _keyPressed: function(e) {
- var index;
-
- if($(e.srcElement).attr('completionType')!="OSM") return;
-
- if(e.target.value==''){
- this._unselect;
- this.close();
- $(e.target).attr('completiontype','local');
- return;
- }
- if (this._isOpen && e.keyCode === 13 && this._selection) {
- index = parseInt(this._selection.getAttribute('data-result-index'), 10);
- this._resultSelected(this._results[index])();
- L.DomEvent.preventDefault(e);
- return;
- }
- clearTimeout(this.keyPressTimeout);
- var _this = this;
- this.keyPressTimeout = setTimeout(function(){ _this._complete(_this._resultFn, true)} ,500)
- if (e.keyCode === 13) {
- this._complete(this._resultFn, true);
- return;
- }
- else
- {
- $(e.srcElement).removeAttr('completed');
- }
-
- if (this._autocomplete && document.activeElement === this._elem) {
- if (this._timer) {
- clearTimeout(this._timer);
- }
- this._timer = setTimeout(L.Util.bind(function() { this._complete(this._autocomplete); }, this),
- this.options.timeout);
- return;
- }
-
-
- },
-
- _select: function(dir) {
- var sel = this._selection;
- if (sel) {
- L.DomUtil.removeClass(sel.firstChild, 'leaflet-routing-geocoder-selected');
- sel = sel[dir > 0 ? 'nextSibling' : 'previousSibling'];
- }
- if (!sel) {
- sel = this._resultTable[dir > 0 ? 'firstChild' : 'lastChild'];
- }
-
- if (sel) {
- L.DomUtil.addClass(sel.firstChild, 'leaflet-routing-geocoder-selected');
- this._selection = sel;
- }
- },
-
- _unselect: function() {
- if (this._selection) {
- L.DomUtil.removeClass(this._selection.firstChild, 'leaflet-routing-geocoder-selected');
- }
- delete this._selection;
- },
-
- _keyDown: function(e) {
- if (this._isOpen) {
- switch (e.keyCode) {
- // Up
- case 38:
- this._select(-1);
- L.DomEvent.preventDefault(e);
- return;
- // Down
- case 40:
- this._select(1);
- L.DomEvent.preventDefault(e);
- return;
- }
- }
- },
-
- _complete: function(completeFn, trySelect) {
- var v = this._elem.value;
- function completeResults(results) {
- this._lastCompletedText = v;
- //if (trySelect && results.length === 1) {
- //this._resultSelected(results[0])();
- //} else {
- this._setResults(results);
- //}
- }
-
- if (!v) {
- return;
- }
-
- if (v !== this._lastCompletedText) {
- completeFn(v, completeResults, this);
- } else if (trySelect) {
- completeResults.call(this, this._results);
- }
- }
- });
-})();
-(function() {
- 'use strict';
-
- // Ignore camelcase naming for this file, since OSRM's API uses
- // underscores.
- /* jshint camelcase: false */
-
- L.Routing = L.Routing || {};
-
- L.Routing._jsonpCallbackId = 0;
- L.Routing._jsonp = function(url, callback, context, jsonpParam) {
- var callbackId = '_l_routing_machine_' + (L.Routing._jsonpCallbackId++),
- script;
- url += '&' + jsonpParam + '=' + callbackId;
- window[callbackId] = L.Util.bind(callback, context);
- script = document.createElement('script');
- script.type = 'text/javascript';
- script.src = url;
- script.id = callbackId;
- console.log(url);
- document.getElementsByTagName('head')[0].appendChild(script);
- };
-
- L.Routing.OSRM = L.Class.extend({
- //
- options: {
- serviceUrl:OC.generateUrl('apps/maps/router?url=http://router.project-osrm.org/viaroute'),
- geometryPrecision: 6
- },
-
- initialize: function(options) {
- L.Util.setOptions(this, options);
- this._hints = {
- locations: {}
- };
- },
-
- route: function(waypoints, callback, context) {
- var url = this._buildRouteUrl(waypoints);
-
- L.Routing._jsonp(url, function(data) {
- this._routeDone(data, waypoints, callback, context);
- }, this, 'jsonp');
-
- return this;
- },
-
- _routeDone: function(response, waypoints, callback, context) {
- context = context || callback;
- if (response.status !== 0) {
- callback.call(context, {
- status: response.status,
- message: response.message
- });
- return;
- }
-
- var alts = [{
- name: response.route_name.join(', '),
- coordinates: this._decode(response.route_geometry, this.options.geometryPrecision),
- instructions: this._convertInstructions(response.route_instructions),
- summary: this._convertSummary(response.route_summary),
- waypoints: response.via_points
- }],
- i;
-
- if (response.alternative_geometries) {
- for (i = 0; i < response.alternative_geometries.length; i++) {
- alts.push({
- name: response.alternative_names[i].join(', '),
- coordinates: this._decode(response.alternative_geometries[i], this.options.geometryPrecision),
- instructions: this._convertInstructions(response.alternative_instructions[i]),
- summary: this._convertSummary(response.alternative_summaries[i]),
- waypoints: response.via_points
- });
- }
- }
-
- this._saveHintData(response, waypoints);
- callback.call(context, null, alts);
- },
-
- _buildRouteUrl: function(waypoints) {
- var locs = [],
- locationKey,
- hint;
-
- for (var i = 0; i < waypoints.length; i++) {
- locationKey = this._locationKey(waypoints[i].latLng);
- locs.push('loc=' + locationKey);
-
- hint = this._hints.locations[locationKey];
- if (hint) {
- locs.push('hint=' + hint);
- }
- }
-
- return this.options.serviceUrl + '?' +
- 'instructions=true&' +
- locs.join('&') +
- (this._hints.checksum !== undefined ? '&checksum=' + this._hints.checksum : '');
- },
-
- _locationKey: function(location) {
- return location.lat + ',' + location.lng;
- },
-
- _saveHintData: function(route, waypoints) {
- var hintData = route.hint_data,
- loc;
- this._hints = {
- checksum: hintData.checksum,
- locations: {}
- };
- for (var i = hintData.locations.length - 1; i >= 0; i--) {
- loc = waypoints[i].latLng;
- this._hints.locations[this._locationKey(loc)] = hintData.locations[i];
- }
- },
-
- // Adapted from
- // https://github.com/DennisSchiefer/Project-OSRM-Web/blob/develop/WebContent/routing/OSRM.RoutingGeometry.js
- _decode: function(encoded, precision) {
- var len = encoded.length,
- index=0,
- lat=0,
- lng = 0,
- array = [];
-
- precision = Math.pow(10, -precision);
-
- while (index < len) {
- var b,
- shift = 0,
- result = 0;
- do {
- b = encoded.charCodeAt(index++) - 63;
- result |= (b & 0x1f) << shift;
- shift += 5;
- } while (b >= 0x20);
- var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
- lat += dlat;
- shift = 0;
- result = 0;
- do {
- b = encoded.charCodeAt(index++) - 63;
- result |= (b & 0x1f) << shift;
- shift += 5;
- } while (b >= 0x20);
- var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
- lng += dlng;
- //array.push( {lat: lat * precision, lng: lng * precision} );
- array.push( [lat * precision, lng * precision] );
- }
- return array;
- },
-
- _convertSummary: function(osrmSummary) {
- return {
- totalDistance: osrmSummary.total_distance,
- totalTime: osrmSummary.total_time
- };
- },
-
- _convertInstructions: function(osrmInstructions) {
- var result = [],
- i,
- instr,
- type,
- driveDir;
-
- for (i = 0; i < osrmInstructions.length; i++) {
- instr = osrmInstructions[i];
- type = this._drivingDirectionType(instr[0]);
- driveDir = instr[0].split('-');
- if (type) {
- result.push({
- type: type,
- distance: instr[2],
- time: instr[4],
- road: instr[1],
- direction: instr[6],
- exit: driveDir.length > 1 ? driveDir[1] : undefined,
- index: instr[3]
- });
- }
- }
-
- return result;
- },
-
- _drivingDirectionType: function(d) {
- switch (parseInt(d, 10)) {
- case 1:
- return 'Straight';
- case 2:
- return 'SlightRight';
- case 3:
- return 'Right';
- case 4:
- return 'SharpRight';
- case 5:
- return 'TurnAround';
- case 6:
- return 'SharpLeft';
- case 7:
- return 'Left';
- case 8:
- return 'SlightRight';
- case 9:
- return 'WaypointReached';
- case 10:
- // TODO: "Head on"
- // https://github.com/DennisOSRM/Project-OSRM/blob/master/DataStructures/TurnInstructions.h#L48
- return 'Straight';
- case 11:
- case 12:
- return 'Roundabout';
- case 15:
- return 'DestinationReached';
- default:
- return null;
- }
- }
- });
-
- L.Routing.osrm = function(options) {
- return new L.Routing.OSRM(options);
- };
-})();
-(function() {
- 'use strict';
-
- L.Routing = L.Routing || {};
-
- L.Routing.Line = L.Class.extend({
- includes: L.Mixin.Events,
-
- options: {
- styles: [
- {color: 'black', opacity: 0.15, weight: 7},
- {color: 'white', opacity: 0.8, weight: 2},
- {color: 'blue', opacity: 1, weight: 2}
- ],
- addWaypoints: true
- },
-
- initialize: function(route, options) {
- L.Util.setOptions(this, options);
- this._route = route;
-
- this._wpIndices = this._findWaypointIndices();
- },
-
- addTo: function(map) {
- map.addLayer(this);
- return this;
- },
-
- onAdd: function(map) {
- var geom = this._route.coordinates,
- i,
- pl;
-
- this._map = map;
- this._layers = [];
- for (i = 0; i < this.options.styles.length; i++) {
- pl = L.polyline(geom, this.options.styles[i])
- .addTo(map);
- if (this.options.addWaypoints) {
- pl.on('mousedown', this._onLineTouched, this);
- }
- this._layers.push(pl);
- }
- },
-
- onRemove: function(map) {
- var i;
- for (i = 0; i < this._layers.length; i++) {
- map.removeLayer(this._layers[i]);
- }
-
- delete this._map;
- },
-
- getBounds: function() {
- return L.latLngBounds(this._route.coordinates);
- },
-
- _findWaypointIndices: function() {
- var wps = this._route.waypoints,
- indices = [],
- i;
- for (i = 0; i < wps.length; i++) {
- indices.push(this._findClosestRoutePoint(L.latLng(wps[i])));
- }
-
- return indices;
- },
-
- _findClosestRoutePoint: function(latlng) {
- var minDist = Number.MAX_VALUE,
- minIndex,
- i,
- d;
-
- for (i = this._route.coordinates.length - 1; i >= 0 ; i--) {
- // TODO: maybe do this in pixel space instead?
- d = latlng.distanceTo(this._route.coordinates[i]);
- if (d < minDist) {
- minIndex = i;
- minDist = d;
- }
- }
-
- return minIndex;
- },
-
- _findNearestWpBefore: function(i) {
- var j = this._wpIndices.length - 1;
- while (j >= 0 && this._wpIndices[j] > i) {
- j--;
- }
-
- return j;
- },
-
- _onLineTouched: function(e) {
- var afterIndex = this._findNearestWpBefore(this._findClosestRoutePoint(e.latlng));
- this.fire('linetouched', {
- afterIndex: afterIndex,
- latlng: e.latlng
- });
- },
- });
-
- L.Routing.line = function(route, options) {
- return new L.Routing.Line(route, options);
- };
-})();
-(function() {
- 'use strict';
-
- L.Routing = L.Routing || {};
-
- L.Routing.Itinerary = L.Control.extend({
- includes: L.Mixin.Events,
-
- options: {
- units: 'metric',
- pointMarkerStyle: {
- radius: 5,
- color: '#03f',
- fillColor: 'white',
- opacity: 1,
- fillOpacity: 0.7
- },
- summaryTemplate: '{name}
{distance}, {time}
',
- distanceTemplate: '{value} {unit}',
- timeTemplate: '{time}',
- unitNames: {
- meters: 'm',
- kilometers: 'km',
- yards: 'yd',
- miles: 'mi',
- hours: 'h',
- minutes: 'm�n',
- seconds: 's'
- },
- containerClassName: '',
- alternativeClassName: '',
- minimizedClassName: '',
- itineraryClassName: '',
- roundingSensitivity: 1,
- show: true
- },
-
- initialize: function(options) {
- L.setOptions(this, options);
- },
-
- onAdd: function() {
- this._container = L.DomUtil.create('div', 'leaflet-routing-container' +
- (!this.options.show ? 'leaflet-routing-container-hide' : '') +
- this.options.containerClassName);
- L.DomEvent.disableClickPropagation(this._container);
- L.DomEvent.addListener(this._container, 'mousewheel', function(e) {
- L.DomEvent.stopPropagation(e);
- });
- return this._container;
- },
-
- onRemove: function() {
- },
-
- setAlternatives: function(routes) {
- var i,
- alt,
- altDiv;
-
- this._clearAlts();
-
- this._routes = routes;
-
- for (i = 0; i < this._routes.length; i++) {
- alt = this._routes[i];
- altDiv = this._createAlternative(alt, i);
- this._container.appendChild(altDiv);
- this._altElements.push(altDiv);
- }
-
- this.fire('routeselected', {route: this._routes[0]});
-
-
- return this;
- },
-
- show: function() {
- L.DomUtil.removeClass(this._container, 'leaflet-routing-container-hide');
- },
-
- hide: function() {
- L.DomUtil.addClass(this._container, 'leaflet-routing-container-hide');
- },
-
- _createAlternative: function(alt, i) {
- var altDiv = L.DomUtil.create('div', 'leaflet-routing-alt ' +
- this.options.alternativeClassName +
- (i > 0 ? ' leaflet-routing-alt-minimized ' + this.options.minimizedClassName : ''));
- altDiv.innerHTML = L.Util.template(this.options.summaryTemplate, {
- name: alt.name,
- distance: this._formatDistance(alt.summary.totalDistance),
- time: this._formatTime(alt.summary.totalTime)
- });
- L.DomEvent.addListener(altDiv, 'click', this._onAltClicked, this);
-
- altDiv.appendChild(this._createItineraryTable(alt));
- return altDiv;
- },
-
- _clearAlts: function() {
- var i,
- alt;
- // TODO: this is really inelegant
- for (i = 0; this._container && i < this._container.children.length; i++) {
- alt = this._container.children[i];
- if (L.DomUtil.hasClass(alt, 'leaflet-routing-alt')) {
- this._container.removeChild(alt);
- i--;
- }
- }
-
- this._altElements = [];
- },
-
- _createItineraryTable: function(r) {
- var table = L.DomUtil.create('table', this.options.itineraryClassName),
- body = L.DomUtil.create('tbody', '', table),
- i,
- instr,
- row,
- row2,
- td;
-
- for (i = 0; i < r.instructions.length; i++) {
- instr = r.instructions[i];
- row = L.DomUtil.create('tr', '', body);
- td = L.DomUtil.create('td', '', row);
- td.appendChild(document.createTextNode(this._instruction(instr, i)));
-
- row2 = L.DomUtil.create('tr', '', body);
- td = L.DomUtil.create('td', '', row2);
- td.appendChild(document.createTextNode(this._formatDistance(instr.distance)));
-
-
- this._addRowListeners(row, r.coordinates[instr.index]);
- this._addRowListeners(row2, r.coordinates[instr.index]);
- }
-
- return table;
- },
-
- _addRowListeners: function(row, coordinate) {
- var _this = this,
- marker;
- L.DomEvent.addListener(row, 'mouseover', function() {
- marker = L.circleMarker(coordinate,
- _this.options.pointMarkerStyle).addTo(_this._map);
- });
- L.DomEvent.addListener(row, 'mouseout', function() {
- if (marker) {
- _this._map.removeLayer(marker);
- marker = null;
- }
- });
- L.DomEvent.addListener(row, 'click', function(e) {
- _this._map.panTo(coordinate);
- L.DomEvent.stopPropagation(e);
- });
- },
-
- _onAltClicked: function(e) {
- var altElem,
- j,
- n,
- isCurrentSelection,
- classFn;
-
- altElem = e.target || window.event.srcElement;
- while (!L.DomUtil.hasClass(altElem, 'leaflet-routing-alt')) {
- altElem = altElem.parentElement;
- }
-
- if (L.DomUtil.hasClass(altElem, 'leaflet-routing-alt-minimized')) {
- for (j = 0; j < this._altElements.length; j++) {
- n = this._altElements[j];
- isCurrentSelection = altElem === n;
- classFn = isCurrentSelection ? 'removeClass' : 'addClass';
- L.DomUtil[classFn](n, 'leaflet-routing-alt-minimized');
- if (this.options.minimizedClassName) {
- L.DomUtil[classFn](n, this.options.minimizedClassName);
- }
-
- if (isCurrentSelection) {
- // TODO: don't fire if the currently active is clicked
- this.fire('routeselected', {route: this._routes[j]});
- }
- }
- }
-
- L.DomEvent.stop(e);
- },
-
- _formatDistance: function(d /* Number (meters) */) {
- var un = this.options.unitNames,
- v,
- data;
-
- if (this.options.units === 'imperial') {
- d = d / 1.609344;
- if (d >= 1000) {
- data = {
- value: (this._round(d) / 1000),
- unit: un.miles
- };
- } else {
- data = {
- value: this._round(d / 1.760),
- unit: un.yards
- };
- }
- } else {
- v = this._round(d);
- data = {
- value: v >= 1000 ? (v / 1000) : v,
- unit: v >= 1000 ? un.kilometers : un.meters
- };
- }
-
- return L.Util.template(this.options.distanceTemplate, data);
- },
-
- _round: function(d) {
- var pow10 = Math.pow(10, (Math.floor(d / this.options.roundingSensitivity) + '').length - 1),
- r = Math.floor(d / pow10),
- p = (r > 5) ? pow10 : pow10 / 2;
-
- return Math.round(d / p) * p;
- },
-
- _formatTime: function(t /* Number (seconds) */) {
- if (t > 86400) {
- return Math.round(t / 3600) + ' h';
- } else if (t > 3600) {
- return Math.floor(t / 3600) + ' h ' +
- Math.round((t % 3600) / 60) + ' min';
- } else if (t > 300) {
- return Math.round(t / 60) + ' min';
- } else if (t > 60) {
- return Math.floor(t / 60) + ' min ' +
- (t % 60) + ' s';
- } else {
- return t + ' s';
- }
- },
-
- _instruction: function(instr, i) {
- if (instr.type !== undefined) {
- return L.Util.template(this._getInstructionTemplate(instr, i),
- L.extend({exit: this._formatOrder(instr.exit), dir: this._dir[instr.direction]},
- instr));
- } else {
- return instr.text;
- }
- },
-
- _getInstructionTemplate: function(instr, i) {
- switch (instr.type) {
- case 'Straight':
- return (i === 0 ? 'Head' : 'Continue') + ' {dir}' + (instr.road ? ' on {road}' : '');
- case 'SlightRight':
- return 'Slight right' + (instr.road ? ' onto {road}' : '');
- case 'Right':
- return 'Right' + (instr.road ? ' onto {road}' : '');
- case 'SharpRight':
- return 'Sharp right' + (instr.road ? ' onto {road}' : '');
- case 'TurnAround':
- return 'Turn around';
- case 'SharpLeft':
- return 'Sharp left' + (instr.road ? ' onto {road}' : '');
- case 'Left':
- return 'Left' + (instr.road ? ' onto {road}' : '');
- case 'SlightLeft':
- return 'Slight left' + (instr.road ? ' onto {road}' : '');
- case 'WaypointReached':
- return 'Waypoint reached';
- case 'Roundabout':
- return 'Take the {exit} exit in the roundabout';
- case 'DestinationReached':
- return 'Destination reached';
- }
- },
-
- _formatOrder: function(n) {
- var i = n % 10 - 1,
- suffix = ['st', 'nd', 'rd'];
-
- return suffix[i] ? n + suffix[i] : n + 'th';
- },
-
- _dir: {
- N: 'north',
- NE: 'northeast',
- E: 'east',
- SE: 'southeast',
- S: 'south',
- SW: 'southwest',
- W: 'west',
- NW: 'northwest'
- }
- });
-
- L.Routing.Itinerary._instructions = {
- };
-
- L.Routing.itinerary = function(router) {
- return new L.Routing.Itinerary(router);
- };
-})();
-(function() {
- 'use strict';
-
- var Waypoint = L.Class.extend({
- initialize: function(latLng, name) {
- this.latLng = latLng;
- this.name = name;
- }
- });
-
- L.Routing = L.Routing || {};
-
- L.Routing.Plan = L.Class.extend({
- includes: L.Mixin.Events,
-
- options: {
- dragStyles: [
- {color: 'black', opacity: 0.15, weight: 7},
- {color: 'white', opacity: 0.8, weight: 4},
- {color: 'orange', opacity: 1, weight: 2, dashArray: '7,12'}
- ],
- draggableWaypoints: true,
- addWaypoints: true,
- maxGeocoderTolerance: 200,
- autocompleteOptions: {},
- geocodersClassName: '',
- geocoderPlaceholder: function(i, numberWaypoints) {
- return i === 0 ?
- 'Search' :
- (i < numberWaypoints - 1 ?
- 'Via ' + i :
- 'End');
- },
- geocoderClass: function(i) {
- return 'geocoder-'+i;
- }
- },
-
- initialize: function(waypoints, options) {
- L.Util.setOptions(this, options);
- this._waypoints = [];
- this.setWaypoints(waypoints);
- },
-
- isReady: function() {
- var i;
- for (i = 0; i < this._waypoints.length; i++) {
- if (!this._waypoints[i].latLng) {
- return false;
- }
- }
-
- return true;
- },
-
- getWaypoints: function() {
- var i,
- wps = [];
-
- for (i = 0; i < this._waypoints.length; i++) {
- wps.push(this._waypoints[i]);
- }
-
- return wps;
- },
-
- setWaypoints: function(waypoints) {
- var args = [0, this._waypoints.length].concat(waypoints);
- this.spliceWaypoints.apply(this, args);
- return this;
- },
-
- spliceWaypoints: function() {
- var args = [arguments[0], arguments[1]],
- i,
- wp;
-
- for (i = 2; i < arguments.length; i++) {
- args.push(arguments[i] && arguments[i].hasOwnProperty('latLng') ? arguments[i] : new Waypoint(arguments[i]));
- }
-
- [].splice.apply(this._waypoints, args);
-
- while (this._waypoints.length < 2) {
- wp = new Waypoint();
- this._waypoints.push(wp);
- args.push(wp);
- }
-
- this._updateMarkers();
- this._fireChanged.apply(this, args);
- },
-
- onAdd: function(map) {
- this._map = map;
- this._updateMarkers();
- },
-
- onRemove: function() {
- var i;
- this._removeMarkers();
-
- if (this._newWp) {
- for (i = 0; i < this._newWp.lines.length; i++) {
- this._map.removeLayer(this._newWp.lines[i]);
- }
- }
-
- delete this._map;
- },
-
- createGeocoders: function() {
- var container = L.DomUtil.create('div', 'leaflet-routing-geocoders ' + this.options.geocodersClassName),
- waypoints = this._waypoints,
- i,
- geocoderElem,
- clRoute,
- addWpBtn;
-
- this._geocoderContainer = container;
- this._geocoderElems = [];
-
- for (i = 0; i < waypoints.length; i++) {
- geocoderElem = this._createGeocoder(i);
- container.appendChild(geocoderElem);
- this._geocoderElems.push(geocoderElem);
- }
-
- addWpBtn = L.DomUtil.create('button', '', container);
- addWpBtn.setAttribute('type', 'button');
- addWpBtn.className = 'addwaypoint';
- addWpBtn.innerHTML = '+';
- clRoute = L.DomUtil.create('button', '', container);
- clRoute.setAttribute('type', 'button');
- clRoute.className = 'clearroute icon-close';
- clRoute.style.display = 'none';
- clRoute.innerHTML = 'Clear route';
- if (this.options.addWaypoints) {
- L.DomEvent.addListener(addWpBtn, 'click', function() {
- if(!$('.geocoder-1').is(':visible')){
- $('.geocoder-1').show();
- $('.geocoder-0').attr('OSM');
- }
- else
- {
- this.spliceWaypoints(waypoints.length, 0, null);
- }
- }, this);
- } else {
- addWpBtn.style.display = 'none';
- }
-
- this.on('waypointsspliced', this._updateGeocoders);
-
- return container;
- },
-
- _createGeocoder: function(i) {
- var geocoderElem = L.DomUtil.create('input', ''),
- wp = this._waypoints[i];
- geocoderElem.setAttribute('placeholder', this.options.geocoderPlaceholder(i, this._waypoints.length));
- geocoderElem.setAttribute('completionType', 'OSM');
- geocoderElem.className = this.options.geocoderClass(i, this._waypoints.length);
-
- this._updateWaypointName(i, geocoderElem);
- // This has to be here, or geocoder's value will not be properly
- // initialized.
- // TODO: look into why and make _updateWaypointName fix this.
- geocoderElem.value = wp.name;
-
- L.DomEvent.addListener(geocoderElem, 'click', function() {
- this.select();
- }, geocoderElem);
-
- new L.Routing.Autocomplete(geocoderElem, function(r) {
- geocoderElem.value = r.name;
- wp.name = r.name;
- wp.latLng = r.center;
- this._updateMarkers();
- this._fireChanged();
- }, this, L.extend({
- resultFn: this.options.geocoder.geocode,
- resultContext: this.options.geocoder,
- autocompleteFn: this.options.geocoder.suggest,
- autocompleteContext: this.options.geocoder
- }, this.options.autocompleteOptions));
-
- return geocoderElem;
- },
-
- _updateGeocoders: function(e) {
- var newElems = [],
- i,
- geocoderElem,
- beforeElem;
-
- // Determine where to insert geocoders for new waypoints
- if (e.index >= this._geocoderElems.length) {
- // lastChild is the "add new wp" button
- beforeElem = this._geocoderContainer.lastChild;
- } else {
- beforeElem = this._geocoderElems[e.index];
- }
-
- // Insert new geocoders for new waypoints
- for (i = 0; i < e.added.length; i++) {
- geocoderElem = this._createGeocoder(e.index + i);
- this._geocoderContainer.insertBefore(geocoderElem, beforeElem);
- newElems.push(geocoderElem);
- }
- //newElems.reverse();
-
- for (i = e.index; i < e.index + e.nRemoved; i++) {
- this._geocoderContainer.removeChild(this._geocoderElems[i]);
- }
-
- newElems.splice(0, 0, e.index, e.nRemoved);
- [].splice.apply(this._geocoderElems, newElems);
-
- for (i = 0; i < this._geocoderElems.length; i++) {
- this._geocoderElems[i].placeholder = this.options.geocoderPlaceholder(i, this._waypoints.length);
- this._geocoderElems[i].className = this.options.geocoderClass(i, this._waypoints.length);
- }
- },
-
- _updateGeocoder: function(i, geocoderElem) {
- var wp = this._waypoints[i],
- value = wp && wp.name ? wp.name : '';
- geocoderElem.value = value;
- },
-
- _updateWaypointName: function(i, geocoderElem, force) {
- var wp = this._waypoints[i];
-
- wp.name = wp.name || '';
-
- if (wp.latLng && (force || !wp.name)) {
- if (this.options.geocoder && this.options.geocoder.reverse) {
- this.options.geocoder.reverse(wp.latLng, 67108864 /* zoom 18 */, function(rs) {
- if (rs.length > 0 && rs[0].center.distanceTo(wp.latLng) < this.options.maxGeocoderTolerance) {
- wp.name = rs[0].name;
- } else {
- wp.name = '';
- }
- this._updateGeocoder(i, geocoderElem);
- }, this);
- } else {
- wp.name = '';
- }
-
- this._updateGeocoder(i, geocoderElem);
- }
-
- },
-
- _removeMarkers: function() {
- var i;
- if (this._markers) {
- for (i = 0; i < this._markers.length; i++) {
- if (this._markers[i]) {
- this._map.removeLayer(this._markers[i]);
- }
- }
- }
- this._markers = [];
- },
-
- _updateMarkers: function() {
- var i,
- icon,
- m;
-
- if (!this._map) {
- return;
- }
-
- this._removeMarkers();
-
- for (i = 0; i < this._waypoints.length; i++) {
- if (this._waypoints[i].latLng) {
- icon = (typeof(this.options.waypointIcon) === 'function') ?
- this.options.waypointIcon(i, this._waypoints[i].name, this._waypoints.length) :
- this.options.waypointIcon;
- m = this._createMarker(icon, i);
- if (this.options.draggableWaypoints) {
- this._hookWaypointEvents(m, i);
- }
- } else {
- m = null;
- }
- this._markers.push(m);
- }
- },
-
- _createMarker: function(icon, i) {
- var options = {
- draggable: true
- };
- if (icon) {
- options.icon = icon;
- }
- var marker = L.marker(this._waypoints[i].latLng, options);
- toolKit.addMarker(marker,'',Maps.showPopup)
- return marker
- },
-
- _fireChanged: function() {
- this.fire('waypointschanged', {waypoints: this.getWaypoints()});
-
- if (arguments.length >= 2) {
- this.fire('waypointsspliced', {
- index: Array.prototype.shift.call(arguments),
- nRemoved: Array.prototype.shift.call(arguments),
- added: arguments
- });
- }
- },
-
- _hookWaypointEvents: function(m, i) {
- m.on('dragstart', function(e) {
- this.fire('waypointdragstart', this._createWaypointEvent(i, e));
- }, this);
- m.on('drag', function(e) {
- this.fire('waypointdrag', this._createWaypointEvent(i, e));
- }, this);
- m.on('dragend', function(e) {
- this.fire('waypointdragend', this._createWaypointEvent(i, e));
- this._waypoints[i].latLng = e.target.getLatLng();
- this._waypoints[i].name = '';
- this._updateWaypointName(i, this._geocoderElems[i], true);
- this._fireChanged();
- }, this);
- },
-
- _createWaypointEvent: function(i, e) {
- return {index: i, latlng: e.target.getLatLng()};
- },
-
- dragNewWaypoint: function(e) {
- var i;
- this._newWp = {
- afterIndex: e.afterIndex,
- marker: L.marker(e.latlng).addTo(this._map),
- lines: []
- };
-
- for (i = 0; i < this.options.dragStyles.length; i++) {
- this._newWp.lines.push(L.polyline([
- this._waypoints[e.afterIndex].latLng,
- e.latlng,
- this._waypoints[e.afterIndex + 1].latLng
- ], this.options.dragStyles[i]).addTo(this._map));
- }
-
- this._markers.splice(e.afterIndex + 1, 0, this._newWp.marker);
- this._map.on('mousemove', this._onDragNewWp, this);
- this._map.on('mouseup', this._onWpRelease, this);
- },
-
- _onDragNewWp: function(e) {
- var i;
- this._newWp.marker.setLatLng(e.latlng);
- for (i = 0; i < this._newWp.lines.length; i++) {
- this._newWp.lines[i].spliceLatLngs(1, 1, e.latlng);
- }
- },
-
- _onWpRelease: function(e) {
- var i;
- this._map.off('mouseup', this._onWpRelease, this);
- this._map.off('mousemove', this._onDragNewWp, this);
- for (i = 0; i < this._newWp.lines.length; i++) {
- this._map.removeLayer(this._newWp.lines[i]);
- }
- this.spliceWaypoints(this._newWp.afterIndex + 1, 0, e.latlng);
- delete this._newWp;
- }
- });
-
- L.Routing.plan = function(waypoints, options) {
- return new L.Routing.Plan(waypoints, options);
- };
-})();
-(function() {
- 'use strict';
-
- L.Routing.Control = L.Routing.Itinerary.extend({
- options: {
- fitSelectedRoutes: true
- },
-
- initialize: function(options) {
- L.Util.setOptions(this, options);
-
- this._router = this.options.router || new L.Routing.OSRM();
- this._plan = this.options.plan || L.Routing.plan(undefined, { geocoder: this.options.geocoder });
- if (this.options.geocoder) {
- this._plan.options.geocoder = this.options.geocoder;
- }
- if (this.options.waypoints) {
- this._plan.setWaypoints(this.options.waypoints);
- }
-
- L.Routing.Itinerary.prototype.initialize.call(this, options);
-
- this.on('routeselected', this._routeSelected, this);
- this._plan.on('waypointschanged', function(e) {
- this._route();
- this.fire('waypointschanged', {waypoints: e.waypoints});
- }, this);
-
- this._route();
- },
-
- onAdd: function(map) {
- var container = L.Routing.Itinerary.prototype.onAdd.call(this, map);
-
- this._map = map;
- this._map.addLayer(this._plan);
-
- if (this.options.geocoder) {
- container.insertBefore(this._plan.createGeocoders(), container.firstChild);
- }
-
- return container;
- },
-
- onRemove: function(map) {
- if (this._line) {
- map.removeLayer(this._line);
- }
- map.removeLayer(this._plan);
- return L.Routing.Itinerary.prototype.onRemove.call(this, map);
- },
-
- getWaypoints: function() {
- return this._plan.getWaypoints();
- },
-
- setWaypoints: function(waypoints) {
- if(waypoints.length==0) $('.clearroute').hide();
- this._plan.setWaypoints(waypoints);
- return this;
- },
-
- spliceWaypoints: function() {
- var removed = this._plan.spliceWaypoints.apply(this._plan, arguments);
- return removed;
- },
-
- getPlan: function() {
- return this._plan;
- },
-
- _routeSelected: function(e) {
- var route = e.route;
- this._clearLine();
-
- this._line = L.Routing.line(route, this.options.lineOptions);
- this._line.addTo(this._map);
- this._hookEvents(this._line);
-
- if (this.options.fitSelectedRoutes) {
- this._map.fitBounds(this._line.getBounds());
- }
- },
-
- _hookEvents: function(l) {
- l.on('linetouched', function(e) {
- this._plan.dragNewWaypoint(e);
- }, this);
- },
-
- _route: function() {
- var wps;
-
- this._clearLine();
- this._clearAlts();
-
- if (this._plan.isReady()) {
- wps = this._plan.getWaypoints();
- this.fire('routingstart', {waypoints: wps});
- this._router.route(wps, function(err, routes) {
- if (err) {
- this.fire('routingerror', {error: err});
- return;
- }
- this.fire('routesfound', {waypoints: wps, routes: routes});
- $('.clearroute').show();
- this.setAlternatives(routes);
-
- }, this);
- }
- },
-
- _clearLine: function() {
- if (this._line) {
- this._map.removeLayer(this._line);
- delete this._line;
- }
- }
- });
-
- L.Routing.control = function(options) {
- return new L.Routing.Control(options);
- };
-})();
- return L.Routing;
-}));
-// Packaging/modules magic dance end. This code is inserted after all other
-// code when the dist is built.
\ No newline at end of file
+/*! leaflet-routing-machine - v2.6.1 - 2016-01-07 */
+
+!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,(b.L||(b.L={})).Routing=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=200&&300>a||304===a}function e(){void 0===h.status||d(h.status)?b.call(h,null,h):b.call(h,h,null)}var f=!1;if("undefined"==typeof window.XMLHttpRequest)return b(Error("Browser not supported"));if("undefined"==typeof c){var g=a.match(/^\s*https?:\/\/[^\/]*/);c=g&&g[0]!==location.protocol+"//"+location.domain+(location.port?":"+location.port:"")}var h=new window.XMLHttpRequest;if(c&&!("withCredentials"in h)){h=new window.XDomainRequest;var i=b;b=function(){if(f)i.apply(this,arguments);else{var a=this,b=arguments;setTimeout(function(){i.apply(a,b)},0)}}}return"onload"in h?h.onload=e:h.onreadystatechange=function(){4===h.readyState&&e()},h.onerror=function(a){b.call(this,a||!0,null),b=function(){}},h.onprogress=function(){},h.ontimeout=function(a){b.call(this,a,null),b=function(){}},h.onabort=function(a){b.call(this,a,null),b=function(){}},h.open("GET",a,!0),h.send(null),f=!0,h}"undefined"!=typeof b&&(b.exports=d)},{}],2:[function(a,b,c){function d(a,b){a=Math.round(a*b),a<<=1,0>a&&(a=~a);for(var c="";a>=32;)c+=String.fromCharCode((32|31&a)+63),a>>=5;return c+=String.fromCharCode(a+63)}var e={};e.decode=function(a,b){for(var c,d,e=0,f=0,g=0,h=[],i=0,j=0,k=null,l=Math.pow(10,b||5);e=32);c=1&j?~(j>>1):j>>1,i=j=0;do k=a.charCodeAt(e++)-63,j|=(31&k)<=32);d=1&j?~(j>>1):j>>1,f+=c,g+=d,h.push([f/l,g/l])}return h},e.encode=function(a,b){if(!a.length)return"";for(var c=Math.pow(10,b||5),e=d(a[0][0],c)+d(a[0][1],c),f=1;f0&&this._select(1)},_createClickListener:function(a){var b=this._resultSelected(a);return L.bind(function(){this._elem.blur(),b()},this)},_resultSelected:function(a){return L.bind(function(){this.close(),this._elem.value=a.name,this._lastCompletedText=a.name,this._selectFn(a)},this)},_keyPressed:function(a){var b;return this._isOpen&&13===a.keyCode&&this._selection?(b=parseInt(this._selection.getAttribute("data-result-index"),10),this._resultSelected(this._results[b])(),void L.DomEvent.preventDefault(a)):13===a.keyCode?void this._complete(this._resultFn,!0):this._autocomplete&&document.activeElement===this._elem?(this._timer&&clearTimeout(this._timer),void(this._timer=setTimeout(L.Util.bind(function(){this._complete(this._autocomplete)},this),this.options.timeout))):void this._unselect()},_select:function(a){var b=this._selection;b&&(L.DomUtil.removeClass(b.firstChild,"leaflet-routing-geocoder-selected"),b=b[a>0?"nextSibling":"previousSibling"]),b||(b=this._resultTable[a>0?"firstChild":"lastChild"]),b&&(L.DomUtil.addClass(b.firstChild,"leaflet-routing-geocoder-selected"),this._selection=b)},_unselect:function(){this._selection&&L.DomUtil.removeClass(this._selection.firstChild,"leaflet-routing-geocoder-selected"),delete this._selection},_keyDown:function(a){if(this._isOpen)switch(a.keyCode){case 27:return this.close(),void L.DomEvent.preventDefault(a);case 38:return this._select(-1),void L.DomEvent.preventDefault(a);case 40:return this._select(1),void L.DomEvent.preventDefault(a)}},_complete:function(a,b){function c(a){this._lastCompletedText=d,b&&1===a.length?this._resultSelected(a[0])():this._setResults(a)}var d=this._elem.value;d&&(d!==this._lastCompletedText?a(d,c,this):b&&c.call(this,this._results))}})}()},{}],4:[function(a,b,c){(function(c){!function(){"use strict";var d="undefined"!=typeof window?window.L:"undefined"!=typeof c?c.L:null;d.Routing=d.Routing||{},d.extend(d.Routing,a("./L.Routing.Itinerary")),d.extend(d.Routing,a("./L.Routing.Line")),d.extend(d.Routing,a("./L.Routing.Plan")),d.extend(d.Routing,a("./L.Routing.OSRM")),d.extend(d.Routing,a("./L.Routing.ErrorControl")),d.Routing.Control=d.Routing.Itinerary.extend({options:{fitSelectedRoutes:"smart",routeLine:function(a,b){return d.Routing.line(a,b)},autoRoute:!0,routeWhileDragging:!1,routeDragInterval:500,waypointMode:"connect",useZoomParameter:!1,showAlternatives:!1},initialize:function(a){d.Util.setOptions(this,a),this._router=this.options.router||new d.Routing.OSRM(a),this._plan=this.options.plan||d.Routing.plan(this.options.waypoints,a),this._requestCount=0,d.Routing.Itinerary.prototype.initialize.call(this,a),this.on("routeselected",this._routeSelected,this),this._plan.on("waypointschanged",this._onWaypointsChanged,this),a.routeWhileDragging&&this._setupRouteDragging(),this.options.autoRoute&&this.route()},onAdd:function(a){var b=d.Routing.Itinerary.prototype.onAdd.call(this,a);return this._map=a,this._map.addLayer(this._plan),this.options.useZoomParameter&&this._map.on("zoomend",function(){this.route({callback:d.bind(this._updateLineCallback,this)})},this),this._plan.options.geocoder&&b.insertBefore(this._plan.createGeocoders(),b.firstChild),b},onRemove:function(a){return this._line&&a.removeLayer(this._line),a.removeLayer(this._plan),d.Routing.Itinerary.prototype.onRemove.call(this,a)},getWaypoints:function(){return this._plan.getWaypoints()},setWaypoints:function(a){return this._plan.setWaypoints(a),this},spliceWaypoints:function(){var a=this._plan.spliceWaypoints.apply(this._plan,arguments);return a},getPlan:function(){return this._plan},getRouter:function(){return this._router},_routeSelected:function(a){var b=a.route,c=this.options.showAlternatives&&a.alternatives,d=this.options.fitSelectedRoutes,e="smart"===d&&!this._waypointsVisible()||"smart"!==d&&d;this._updateLines({route:b,alternatives:c}),e&&this._map.fitBounds(this._line.getBounds()),"snap"===this.options.waypointMode&&(this._plan.off("waypointschanged",this._onWaypointsChanged,this),this.setWaypoints(b.waypoints),this._plan.on("waypointschanged",this._onWaypointsChanged,this))},_waypointsVisible:function(){var a,b,c,e,f,g=this.getWaypoints();try{for(a=this._map.getSize(),e=0;ea.x/5||c.y>a.y/5)&&this._waypointsInViewport()}catch(h){return!1}},_waypointsInViewport:function(){var a,b,c=this.getWaypoints();try{a=this._map.getBounds()}catch(d){return!1}for(b=0;b"+a.message+"
=b,j=i?function(a){return a}:d.bind(this._round,this);return"imperial"===this.options.units?(e=a/.9144,f=e>=1e3?{value:j(a/1609.344,b),unit:h.miles}:{value:j(e,b),unit:h.yards}):(c=j(a,b),f={value:c>=1e3?c/1e3:c,unit:c>=1e3?h.kilometers:h.meters}),i&&(g=Math.pow(10,-b),f.value=Math.round(f.value*g)/g),d.Util.template(this.options.distanceTemplate,f)},_round:function(a,b){var c=b||this.options.roundingSensitivity,d=Math.pow(10,(Math.floor(a/c)+"").length-1),e=Math.floor(a/d),f=e>5?d:d/2;return Math.round(a/f)*f},formatTime:function(a){return a>86400?Math.round(a/3600)+" h":a>3600?Math.floor(a/3600)+" h "+Math.round(a%3600/60)+" min":a>300?Math.round(a/60)+" min":a>60?Math.floor(a/60)+" min"+(a%60!==0?" "+a%60+" s":""):a+" s"},formatInstruction:function(a,b){return void 0===a.text?d.Util.template(this._getInstructionTemplate(a,b),d.extend({exitStr:a.exit?d.Routing.Localization[this.options.language].formatOrder(a.exit):"",dir:d.Routing.Localization[this.options.language].directions[a.direction]},a)):a.text},getIconName:function(a,b){switch(a.type){case"Straight":return 0===b?"depart":"continue";case"SlightRight":return"bear-right";case"Right":return"turn-right";case"SharpRight":return"sharp-right";case"TurnAround":return"u-turn";case"SharpLeft":return"sharp-left";case"Left":return"turn-left";case"SlightLeft":return"bear-left";case"WaypointReached":return"via";case"Roundabout":return"enter-roundabout";case"DestinationReached":return"arrive"}},_getInstructionTemplate:function(a,b){var c="Straight"===a.type?0===b?"Head":"Continue":a.type,e=d.Routing.Localization[this.options.language].instructions[c];return e[0]+(e.length>1&&a.road?e[1]:"")}}),b.exports=d.Routing}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./L.Routing.Localization":11}],7:[function(a,b,c){(function(c){!function(){"use strict";function d(a){a.setSelectionRange?a.setSelectionRange(0,9999):a.select()}var e="undefined"!=typeof window?window.L:"undefined"!=typeof c?c.L:null;e.Routing=e.Routing||{},e.extend(e.Routing,a("./L.Routing.Autocomplete")),e.Routing.GeocoderElement=e.Class.extend({includes:e.Mixin.Events,options:{createGeocoder:function(a,b,c){var d=e.DomUtil.create("div","leaflet-routing-geocoder"),f=e.DomUtil.create("input","",d),g=c.addWaypoints?e.DomUtil.create("span","leaflet-routing-remove-waypoint",d):void 0;return f.disabled=!c.addWaypoints,{container:d,input:f,closeButton:g}},geocoderPlaceholder:function(a,b,c){var d=e.Routing.Localization[c.options.language].ui;return 0===a?d.startPlaceholder:b-1>a?e.Util.template(d.viaPlaceholder,{viaNumber:a}):d.endPlaceholder},geocoderClass:function(){return""},waypointNameFallback:function(a){var b=a.lat<0?"S":"N",c=a.lng<0?"W":"E",d=(Math.round(1e4*Math.abs(a.lat))/1e4).toString(),e=(Math.round(1e4*Math.abs(a.lng))/1e4).toString();return b+d+", "+c+e},maxGeocoderTolerance:200,autocompleteOptions:{},language:"en"},initialize:function(a,b,c,f){e.setOptions(this,f);var g=this.options.createGeocoder(b,c,this.options),h=g.closeButton,i=g.input;i.setAttribute("placeholder",this.options.geocoderPlaceholder(b,c,this)),i.className=this.options.geocoderClass(b,c),this._element=g,this._waypoint=a,this.update(),i.value=a.name,e.DomEvent.addListener(i,"click",function(){d(this)},i),h&&e.DomEvent.addListener(h,"click",function(){this.fire("delete",{waypoint:this._waypoint})},this),new e.Routing.Autocomplete(i,function(b){i.value=b.name,a.name=b.name,a.latLng=b.center,this.fire("geocoded",{waypoint:a,value:b})},this,e.extend({resultFn:this.options.geocoder.geocode,resultContext:this.options.geocoder,autocompleteFn:this.options.geocoder.suggest,autocompleteContext:this.options.geocoder},this.options.autocompleteOptions))},getContainer:function(){return this._element.container},setValue:function(a){this._element.input.value=a},update:function(a){var b,c=this._waypoint;c.name=c.name||"",!c.latLng||!a&&c.name||(b=this.options.waypointNameFallback(c.latLng),this.options.geocoder&&this.options.geocoder.reverse?this.options.geocoder.reverse(c.latLng,67108864,function(a){a.length>0&&a[0].center.distanceTo(c.latLng){name}{distance}, {time}
",timeTemplate:"{time}",containerClassName:"",alternativeClassName:"",minimizedClassName:"",itineraryClassName:"",totalDistanceRoundingSensitivity:-1,show:!0,collapsible:void 0,collapseBtn:function(a){var b=d.DomUtil.create("span",a.options.collapseBtnClass);d.DomEvent.on(b,"click",a._toggle,a),a._container.insertBefore(b,a._container.firstChild)},collapseBtnClass:"leaflet-routing-collapse-btn"},initialize:function(a){d.setOptions(this,a),this._formatter=this.options.formatter||new d.Routing.Formatter(this.options),this._itineraryBuilder=this.options.itineraryBuilder||new d.Routing.ItineraryBuilder({containerClassName:this.options.itineraryClassName})},onAdd:function(a){var b=this.options.collapsible;return b=b||void 0===b&&a.getSize().x<=640,this._container=d.DomUtil.create("div","leaflet-routing-container leaflet-bar "+(this.options.show?"":"leaflet-routing-container-hide ")+(b?"leaflet-routing-collapsible ":"")+this.options.containerClassName),this._altContainer=this.createAlternativesContainer(),this._container.appendChild(this._altContainer),d.DomEvent.disableClickPropagation(this._container),d.DomEvent.addListener(this._container,"mousewheel",function(a){d.DomEvent.stopPropagation(a)}),b&&this.options.collapseBtn(this),this._container},onRemove:function(){},createAlternativesContainer:function(){return d.DomUtil.create("div","leaflet-routing-alternatives-container")},setAlternatives:function(a){var b,c,d;for(this._clearAlts(),this._routes=a,b=0;b0?" leaflet-routing-alt-minimized "+this.options.minimizedClassName:"")),e=this.options.summaryTemplate,f=d.extend({name:a.name,distance:this._formatter.formatDistance(a.summary.totalDistance,this.options.totalDistanceRoundingSensitivity),time:this._formatter.formatTime(a.summary.totalTime)},a);return c.innerHTML="function"==typeof e?e(f):d.Util.template(e,f),d.DomEvent.addListener(c,"click",this._onAltClicked,this),this.on("routeselected",this._selectAlt,this),c.appendChild(this._createItineraryContainer(a)),c},_clearAlts:function(){for(var a=this._altContainer;a&&a.firstChild;)a.removeChild(a.firstChild);this._altElements=[]},_createItineraryContainer:function(a){var b,c,d,e,f,g,h=this._itineraryBuilder.createContainer(),i=this._itineraryBuilder.createStepsContainer();for(h.appendChild(i),b=0;b=0;c--)d=a.distanceTo(this._route.coordinates[c]),e>d&&(b=c,e=d);return b},_extendToWaypoints:function(){var a,b,d,e=this._route.inputWaypoints,f=this._getWaypointIndices();for(a=0;athis.options.missingRouteTolerance&&this._addSegment([b,d],this.options.missingRouteStyles)},_addSegment:function(a,b,d){var e,f;for(e=0;e=0&&b[c]>a;)c--;return c},_onLineTouched:function(a){var b=this._findNearestWpBefore(this._findClosestRoutePoint(a.latlng));this.fire("linetouched",{afterIndex:b,latlng:a.latlng})},_getWaypointIndices:function(){return this._wpIndices||(this._wpIndices=this._route.waypointIndices||this._findWaypointIndices()),this._wpIndices}}),c.Routing.line=function(a,b){return new c.Routing.Line(a,b)},b.exports=c.Routing}()}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],11:[function(a,b,c){!function(){"use strict";L.Routing=L.Routing||{},L.Routing.Localization={en:{directions:{N:"north",NE:"northeast",E:"east",SE:"southeast",S:"south",SW:"southwest",W:"west",NW:"northwest"},instructions:{Head:["Head {dir}"," on {road}"],Continue:["Continue {dir}"," on {road}"],SlightRight:["Slight right"," onto {road}"],Right:["Right"," onto {road}"],SharpRight:["Sharp right"," onto {road}"],TurnAround:["Turn around"],SharpLeft:["Sharp left"," onto {road}"],Left:["Left"," onto {road}"],SlightLeft:["Slight left"," onto {road}"],WaypointReached:["Waypoint reached"],Roundabout:["Take the {exitStr} exit in the roundabout"," onto {road}"],DestinationReached:["Destination reached"]},formatOrder:function(a){var b=a%10-1,c=["st","nd","rd"];return c[b]?a+c[b]:a+"th"},ui:{startPlaceholder:"Start",viaPlaceholder:"Via {viaNumber}",endPlaceholder:"End"}},de:{directions:{N:"Norden",NE:"Nordosten",E:"Osten",SE:"Südosten",S:"Süden",SW:"Südwesten",W:"Westen",NW:"Nordwesten"},instructions:{Head:["Richtung {dir}"," auf {road}"],Continue:["Geradeaus Richtung {dir}"," auf {road}"],SlightRight:["Leicht rechts abbiegen"," auf {road}"],Right:["Rechts abbiegen"," auf {road}"],SharpRight:["Scharf rechts abbiegen"," auf {road}"],TurnAround:["Wenden"],SharpLeft:["Scharf links abbiegen"," auf {road}"],Left:["Links abbiegen"," auf {road}"],SlightLeft:["Leicht links abbiegen"," auf {road}"],WaypointReached:["Zwischenhalt erreicht"],Roundabout:["Nehmen Sie die {exitStr} Ausfahrt im Kreisverkehr"," auf {road}"],DestinationReached:["Sie haben ihr Ziel erreicht"]},formatOrder:function(a){return a+"."},ui:{startPlaceholder:"Start",viaPlaceholder:"Via {viaNumber}",endPlaceholder:"Ziel"}},sv:{directions:{N:"norr",NE:"nordost",E:"öst",SE:"sydost",S:"syd",SW:"sydväst",W:"väst",NW:"nordväst"},instructions:{Head:["Åk åt {dir}"," på {road}"],Continue:["Fortsätt {dir}"," på {road}"],SlightRight:["Svagt höger"," på {road}"],Right:["Sväng höger"," på {road}"],SharpRight:["Skarpt höger"," på {road}"],TurnAround:["Vänd"],SharpLeft:["Skarpt vänster"," på {road}"],Left:["Sväng vänster"," på {road}"],SlightLeft:["Svagt vänster"," på {road}"],WaypointReached:["Viapunkt nådd"],Roundabout:["Tag {exitStr} avfarten i rondellen"," till {road}"],DestinationReached:["Framme vid resans mål"]},formatOrder:function(a){return["första","andra","tredje","fjärde","femte","sjätte","sjunde","åttonde","nionde","tionde"][a-1]},ui:{startPlaceholder:"Från",viaPlaceholder:"Via {viaNumber}",endPlaceholder:"Till"}},sp:{directions:{N:"norte",NE:"noreste",E:"este",SE:"sureste",S:"sur",SW:"suroeste",W:"oeste",NW:"noroeste"},instructions:{Head:["Derecho {dir}"," sobre {road}"],Continue:["Continuar {dir}"," en {road}"],SlightRight:["Leve giro a la derecha"," sobre {road}"],Right:["Derecha"," sobre {road}"],SharpRight:["Giro pronunciado a la derecha"," sobre {road}"],TurnAround:["Dar vuelta"],SharpLeft:["Giro pronunciado a la izquierda"," sobre {road}"],Left:["Izquierda"," en {road}"],SlightLeft:["Leve giro a la izquierda"," en {road}"],WaypointReached:["Llegó a un punto del camino"],Roundabout:["Tomar {exitStr} salida en la rotonda"," en {road}"],DestinationReached:["Llegada a destino"]},formatOrder:function(a){return a+"º"},ui:{startPlaceholder:"Inicio",viaPlaceholder:"Via {viaNumber}",endPlaceholder:"Destino"}},nl:{directions:{N:"noordelijke",NE:"noordoostelijke",E:"oostelijke",SE:"zuidoostelijke",S:"zuidelijke",SW:"zuidewestelijke",W:"westelijke",NW:"noordwestelijke"},instructions:{Head:["Vertrek in {dir} richting"," de {road} op"],Continue:["Ga in {dir} richting"," de {road} op"],SlightRight:["Volg de weg naar rechts"," de {road} op"],Right:["Ga rechtsaf"," de {road} op"],SharpRight:["Ga scherpe bocht naar rechts"," de {road} op"],TurnAround:["Keer om"],SharpLeft:["Ga scherpe bocht naar links"," de {road} op"],Left:["Ga linksaf"," de {road} op"],SlightLeft:["Volg de weg naar links"," de {road} op"],WaypointReached:["Aangekomen bij tussenpunt"],Roundabout:["Neem de {exitStr} afslag op de rotonde"," de {road} op"],DestinationReached:["Aangekomen op eindpunt"]},formatOrder:function(a){return 1===a||a>=20?a+"ste":a+"de"},ui:{startPlaceholder:"Vertrekpunt",viaPlaceholder:"Via {viaNumber}",endPlaceholder:"Bestemming"}},fr:{directions:{N:"nord",NE:"nord-est",E:"est",SE:"sud-est",S:"sud",SW:"sud-ouest",W:"ouest",NW:"nord-ouest"},instructions:{Head:["Tout droit au {dir}"," sur {road}"],Continue:["Continuer au {dir}"," sur {road}"],SlightRight:["Légèrement à droite"," sur {road}"],Right:["A droite"," sur {road}"],SharpRight:["Complètement à droite"," sur {road}"],TurnAround:["Faire demi-tour"],SharpLeft:["Complètement à gauche"," sur {road}"],Left:["A gauche"," sur {road}"],SlightLeft:["Légèrement à gauche"," sur {road}"],WaypointReached:["Point d'étape atteint"],Roundabout:["Au rond-point, prenez la {exitStr} sortie"," sur {road}"],DestinationReached:["Destination atteinte"]},formatOrder:function(a){return a+"º"},ui:{startPlaceholder:"Départ",viaPlaceholder:"Intermédiaire {viaNumber}",endPlaceholder:"Arrivée"}},it:{directions:{N:"nord",NE:"nord-est",E:"est",SE:"sud-est",S:"sud",SW:"sud-ovest",W:"ovest",NW:"nord-ovest"},instructions:{Head:["Dritto verso {dir}"," su {road}"],Continue:["Continuare verso {dir}"," su {road}"],SlightRight:["Mantenere la destra"," su {road}"],
+Right:["A destra"," su {road}"],SharpRight:["Strettamente a destra"," su {road}"],TurnAround:["Fare inversione di marcia"],SharpLeft:["Strettamente a sinistra"," su {road}"],Left:["A sinistra"," sur {road}"],SlightLeft:["Mantenere la sinistra"," su {road}"],WaypointReached:["Punto di passaggio raggiunto"],Roundabout:["Alla rotonda, prendere la {exitStr} uscita"],DestinationReached:["Destinazione raggiunta"]},formatOrder:function(a){return a+"º"},ui:{startPlaceholder:"Partenza",viaPlaceholder:"Intermedia {viaNumber}",endPlaceholder:"Destinazione"}},pt:{directions:{N:"norte",NE:"nordeste",E:"leste",SE:"sudeste",S:"sul",SW:"sudoeste",W:"oeste",NW:"noroeste"},instructions:{Head:["Siga {dir}"," na {road}"],Continue:["Continue {dir}"," na {road}"],SlightRight:["Curva ligeira a direita"," na {road}"],Right:["Curva a direita"," na {road}"],SharpRight:["Curva fechada a direita"," na {road}"],TurnAround:["Retorne"],SharpLeft:["Curva fechada a esquerda"," na {road}"],Left:["Curva a esquerda"," na {road}"],SlightLeft:["Curva ligueira a esquerda"," na {road}"],WaypointReached:["Ponto de interesse atingido"],Roundabout:["Pegue a {exitStr} saída na rotatória"," na {road}"],DestinationReached:["Destino atingido"]},formatOrder:function(a){return a+"º"},ui:{startPlaceholder:"Origem",viaPlaceholder:"Intermédio {viaNumber}",endPlaceholder:"Destino"}}},b.exports=L.Routing}()},{}],12:[function(a,b,c){(function(c){!function(){"use strict";var d="undefined"!=typeof window?window.L:"undefined"!=typeof c?c.L:null,e=a("corslite"),f=a("polyline");d.Routing=d.Routing||{},d.extend(d.Routing,a("./L.Routing.Waypoint")),d.Routing.OSRM=d.Class.extend({options:{serviceUrl:"//router.project-osrm.org/viaroute",timeout:3e4,routingOptions:{}},initialize:function(a){d.Util.setOptions(this,a),this._hints={locations:{}}},route:function(a,b,c,f){var g,h,i,j,k=!1,l=[];for(g=this.buildRouteUrl(a,d.extend({},this.options.routingOptions,f)),h=setTimeout(function(){k=!0,b.call(c||b,{status:-1,message:"OSRM request timed out."})},this.options.timeout),j=0;j=0;b--)e[b]=d.latLng(c[b]);return e},_toWaypoints:function(a,b){var c,e=[];for(c=0;c=0;d--)c=b[d].latLng,this._hints.locations[this._locationKey(c)]=a.locations[d]},_convertSummary:function(a){return{totalDistance:a.total_distance,totalTime:a.total_time}},_convertInstructions:function(a){var b,c,d,e,f=[];for(b=0;b1?e[1]:void 0,index:c[3]});return f},_drivingDirectionType:function(a){switch(parseInt(a,10)){case 1:return"Straight";case 2:return"SlightRight";case 3:return"Right";case 4:return"SharpRight";case 5:return"TurnAround";case 6:return"SharpLeft";case 7:return"Left";case 8:return"SlightLeft";case 9:return"WaypointReached";case 10:return"Straight";case 11:case 12:return"Roundabout";case 15:return"DestinationReached";default:return null}},_clampIndices:function(a,b){var c,d=b.length-1;for(c=0;c0||this._waypoints.length>2?this.spliceWaypoints(a,1):this.spliceWaypoints(a,1,new d.Routing.Waypoint)},this).on("geocoded",function(b){this._updateMarkers(),this._fireChanged(),this._focusGeocoder(a+1),this.fire("waypointgeocoded",{waypointIndex:a,waypoint:b.waypoint})},this).on("reversegeocoded",function(b){this.fire("waypointgeocoded",{waypointIndex:a,waypoint:b.waypoint})},this),b},_updateGeocoders:function(){var a,b,c=[];for(a=0;a=0;a--)b=this._createGeocoder(a),this._geocoderContainer.insertBefore(b.getContainer(),this._geocoderContainer.firstChild),c.push(b);this._geocoderElems=c.reverse()},_removeMarkers:function(){var a;if(this._markers)for(a=0;a=2&&this.fire("waypointsspliced",{index:Array.prototype.shift.call(arguments),nRemoved:Array.prototype.shift.call(arguments),added:arguments})},_hookWaypointEvents:function(a,b,c){var e,f,g=function(a){return c?a.latlng:a.target.getLatLng()},h=d.bind(function(a){this.fire("waypointdragstart",{index:b,latlng:g(a)})},this),i=d.bind(function(a){this._waypoints[b].latLng=g(a),this.fire("waypointdrag",{index:b,latlng:g(a)})},this),j=d.bind(function(a){this._waypoints[b].latLng=g(a),this._waypoints[b].name="",this._geocoderElems&&this._geocoderElems[b].update(!0),this.fire("waypointdragend",{index:b,latlng:g(a)}),this._fireChanged()},this);c?(e=d.bind(function(a){this._markers[b].setLatLng(a.latlng),i(a)},this),f=d.bind(function(a){this._map.dragging.enable(),this._map.off("mouseup",f),this._map.off("mousemove",e),j(a)},this),this._map.dragging.disable(),this._map.on("mousemove",e),this._map.on("mouseup",f),h({latlng:this._waypoints[b].latLng})):(a.on("dragstart",h),a.on("drag",i),a.on("dragend",j))},dragNewWaypoint:function(a){var b=a.afterIndex+1;this.options.routeWhileDragging?(this.spliceWaypoints(b,0,a.latlng),this._hookWaypointEvents(this._markers[b],b,!0)):this._dragNewWaypoint(b,a.latlng)},_dragNewWaypoint:function(a,b){var c,e=new d.Routing.Waypoint(b),f=this._waypoints[a-1],g=this._waypoints[a],h=this.options.createMarker(a,e,this._waypoints.length+1),i=[],j=d.bind(function(a){var b;for(h&&h.setLatLng(a.latlng),b=0;b';
}
})
- 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);
@@ -139,7 +158,8 @@ Array.prototype.unique = function() {
zoom : oldZoom,
zoomControl : false,
layers : [mapQuest]
- });
+ }),
+
map.options.minZoom = 3;
var hash = new L.Hash(map);
/*var baseMaps = {
@@ -170,18 +190,19 @@ Array.prototype.unique = function() {
});
routing = L.Routing.control({
waypoints : [],
- geocoder : L.Control.Geocoder.nominatim(),
- plan : L.Routing.plan(null, {
- waypointIcon : function(i) {
- return new L.Icon.Label.Default({
- labelText : String.fromCharCode(65 + i)
- });
- }
- })
+ //geocoder : geocoder,
+ routeWhileDragging: true,
+ fitSelectedRoutes: true,
+ show: false
}).addTo(map);
- $(".leaflet-routing-geocoders").appendTo("#searchContainer");
- $(".leaflet-routing-container").appendTo("#searchContainer");
- $('.geocoder-0').attr('completiontype', 'local');
+
+ routing.getPlan().on('waypointschanged', function(e) {
+ geocodeSearch.waypointsChanged(e);
+ })
+
+ apiKey = '';
+
+ geocodeSearch.addGeocoder();
// properly style as input field
//$('#searchContainer').find('input').attr('type', 'text');
@@ -192,6 +213,16 @@ Array.prototype.unique = function() {
Maps.displayPoiIcons(zoom);
})
+ $.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();
});
@@ -204,14 +235,10 @@ Array.prototype.unique = function() {
if (Maps.droppedPin) {
map.removeLayer(Maps.droppedPin);
Maps.droppedPin = false;
- if ($('.geocoder-0').attr('completiontype') === 'local' && ($('.geocoder-0').val() == '')) {
- $('.geocoder-0').val('');
- }
}
if (/*(curTime - Maps.mouseDowntime) > 200 && */Maps.dragging === false) {//200 = 2 seconds
addGeocodeMarker(e.latlng);
}
-
});
map.on("dragstart", function() {
@@ -220,18 +247,6 @@ Array.prototype.unique = function() {
map.on("dragend zoomend", function(e) {
Maps.saveCurrentLocation(e);
Maps.dragging = false;
- var searchInput = $('.geocoder-0')
- if (searchInput.attr('completiontype') == 'local' && searchInput.val() != '') {
- var data = {
- search : searchInput.val(),
- bbox : map.getBounds().toBBoxString()
- }
- clearTimeout(searchTimeout);
- searchTimeout = setTimeout(function() {
- console.log('Get new results');
- mapSearch.getSearchResults(data, mapSearch.showResultsOnMap);
- }, 500);
- }
})
$(document).on('click', '.toggle-children', function(e) {
@@ -432,6 +447,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');
@@ -473,30 +498,6 @@ Array.prototype.unique = function() {
/* searchItems = []*/
searchTimeout = 0;
- $(document).on('keyup blur', '.geocoder-0', function(e) {
- if ($(this).attr('completiontype') != 'local')
- return;
-
- var data = {
- search : $(this).val(),
- bbox : map.getBounds().toBBoxString()
- }
- clearTimeout(searchTimeout);
- if ($(this).val() == '') {
- mapSearch.clearSearchResults();
- mapSearch._ids = [];
- }
- if (e.keyCode != 13) {
- searchTimeout = setTimeout(function() {
-
- }, 1000)
- } else {
- mapSearch.clearSearchResults();
- mapSearch._ids = [];
- mapSearch.getSearchResults(data, mapSearch.showResultsOnMap);
- }
-
- });
/**
* setDestination on click
*/
@@ -511,18 +512,18 @@ 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]), "")
+ ]);
- $('.geocoder-1').show();
map.closePopup();
});
-
/**
* Clear route
*/
@@ -555,6 +556,249 @@ Array.prototype.unique = function() {
}
}
+ geocodeSearch = {
+ results : [],
+ waypoints : [],
+ markers : [],
+ apiKeySet : function() {
+ return apiKey != null && apiKey.length > 0;
+ },
+ addGeocoder : function() {
+ var geocoderInputs = document.getElementsByClassName('geocoder');
+ var elems = 0;
+ if(geocoderInputs != null) elems = geocoderInputs.length;
+ if(elems == 7) return;//only allow 5 via points
+ var timeoutId;
+ var searchCont = document.getElementById('search');
+ var geocoderDiv = document.createElement('div');
+ geocoderDiv.className = 'geocoder-container';
+ var input = document.createElement('input');
+ input.type = 'text';
+ input.className = 'geocoder not-geocoded';
+ 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';
+ input.id = 'geocoder-start';
+ list.id = 'geocoder-results-start';
+ input.placeholder = 'Start address';
+
+ btn.className = 'icon-add geocoder-button';
+ btn.id = 'geocoder-add';
+ btn.addEventListener('click', function() {
+ geocodeSearch.addGeocoder();
+ });
+
+ geocoderDiv.appendChild(input);
+ geocoderDiv.appendChild(list);
+ geocoderDiv.appendChild(btn);
+ searchCont.appendChild(geocoderDiv);
+ } else if(elems == 1) {
+ geocoderDiv.id = 'geocoder-container-end';
+ input.id = 'geocoder-end';
+ list.id = 'geocoder-results-end';
+ input.placeholder = 'End address';
+
+ btn.className = 'icon-close geocoder-button';
+ btn.id = 'geocoder-remove-end';
+ btn.addEventListener('click', function() {
+ geocodeSearch.removeGeocoder(geocoderDiv);
+ });
+
+ geocoderDiv.appendChild(input);
+ geocoderDiv.appendChild(list);
+ geocoderDiv.appendChild(btn);
+ searchCont.appendChild(geocoderDiv);
+ } else {
+ var id = elems - 2;
+ geocoderDiv.id = 'geocoder-container-' + id;
+ input.id = 'geocoder-' + id;
+ list.id = 'geocoder-results-' + id;
+ input.placeholder = 'Via address '/* + (id+1)*/;
+
+ btn.className = 'icon-close geocoder-button';
+ btn.id = 'geocoder-remove-' + id;
+ btn.addEventListener('click', function() {
+ geocodeSearch.removeGeocoder(geocoderDiv);
+ });
+
+ var children = searchCont.childNodes;
+ var childLength = children.length;
+ geocoderDiv.appendChild(input);
+ geocoderDiv.appendChild(list);
+ geocoderDiv.appendChild(btn);
+ searchCont.insertBefore(geocoderDiv, children[childLength-1]);
+ }
+ },
+ removeGeocoder : function(div) {
+ var geocoderInputs = document.getElementsByClassName('geocoder');
+ var elems = 0;
+ if(geocoderInputs != null) elems = geocoderInputs.length;
+ var isGeocoded = div.getElementsByClassName('is-geocoded');
+ if(isGeocoded.length > 0) {
+ geocodeSearch.removeMarker(isGeocoded[0].id)
+ }
+ //alert(div.getElementById('geocoder-end').toSource())
+ if(div.id == 'geocoder-container-end') {
+ var children = div.parentElement.childNodes;
+ var childLength = children.length;
+ var newEndDiv = children[childLength-2];
+ var newInput = newEndDiv.getElementsByClassName('geocoder')[0];
+ var newList = newEndDiv.getElementsByClassName('geocoder-list')[0];
+ var newButton = newEndDiv.getElementsByClassName('geocoder-button')[0];
+ newEndDiv.id = 'geocoder-container-end';
+ newInput.id = 'geocoder-end';
+ newList.id = 'geocoder-results-end';
+ if(document.getElementsByClassName('geocoder').length - 1 > 1) {
+ newInput.placeholder = 'End address';
+ }
+ newButton.id = 'geocoder-remove-end';
+ }
+ div.parentElement.removeChild(div);
+ },
+ removeMarker : function(id) {
+ var remIndex = -1;
+ for(var i=0; i= 0) {
+ geocodeSearch.markers.splice(remIndex, 1);
+ geocodeSearch.computeRoute();
+ }
+ },
+ clearResults : function(input) {
+ geocodeSearch.results = [];
+ var idParts = input.id.split('-');
+ var id = idParts[0] + '-results-' + idParts[1];
+ var list = document.getElementById(id);
+ if(list == null) return;
+ list.innerHTML = '';
+ list.style.display = 'none';
+ },
+ performGeocode : function(input) {
+ var query = input.value;
+ geocodeSearch.clearResults(input);
+ input.className = input.className.replace('is-geocoded', 'not-geocoded');
+ geocodeSearch.removeMarker(input.id);
+ if(query.length < 3) return;
+ geocoder.geocode(query, function(data) {
+ geocodeSearch.addResults(data);
+ var formData = {
+ name : query
+ };
+ $.post(OC.generateUrl('/apps/maps/api/1.0/favorite/getFavoritesByName'), formData, function(data){
+ $.each(data, function(index, content) {
+ content.center = L.latLng(content.lat, content.lng);
+ content.bbox = null;
+ content.type = 'favorite';
+ geocodeSearch.addResults(data);
+ });
+ geocodeSearch.displayResults(input);
+ });
+ }, null);
+ //TODO search for contacts
+ },
+ addResults : function(searchResults) {
+ $.each(searchResults, function(index, cont) {
+ geocodeSearch.results.push(cont);
+ })
+ },
+ displayResults : function(input) {
+ var idParts = input.id.split('-');
+ var id = idParts[0] + '-results-' + idParts[1];
+ var list = document.getElementById(id);
+ $.each(geocodeSearch.results, function(index, content) {
+ var li = document.createElement('li');
+ li.appendChild(document.createTextNode(content.name));
+ li.setAttribute('id', 'entry-' + index);
+ var className = 'geocoder-list-item';
+ if(content.type == 'favorite') className += ' icon-starred';
+ li.setAttribute('class', className);
+ li.addEventListener('click', function() {
+ input.className = input.className.replace('not-geocoded', 'is-geocoded');
+ var marker = L.marker(content.center);
+ geocodeSearch.markers.push([[input.id], [marker]]);
+ toolKit.addMarker(marker, content.name);
+ var points = document.getElementsByClassName('is-geocoded');
+ if(points.length < 2 && content.bbox != null) {
+ map.fitBounds(content.bbox);
+ };
+ input.value = content.name;
+ geocodeSearch.clearResults(input);
+ geocodeSearch.computeRoute();
+ });
+ list.appendChild(li);
+ }, null);
+ list.style.display = 'block';
+ },
+ computeRoute : function() {
+ geocodeSearch.waypoints = [];
+ var points = document.getElementsByClassName('is-geocoded');
+ if(points.length < 2) return;
+ $.each(points, function(i) {
+ var id = $(this).attr('id');
+ var val = $(this).val();
+ for(var i=0; i= 1000) distance = parseFloat(distance/1000).toFixed(1) + 'km';
+ else distance += 'm';
+ time = Math.ceil(time / 60); // time as minutes
+ var hours = Math.floor(time / 60);
+ var minutes = time % 60;
+ alert('Route ' + name + ' is ' + distance + ' long and takes about ' + hours + ':' + minutes);
+ });
+ },
+ 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(wps, function(idx, wp) {
+ var name = wp.name;
+ if(name == null || name == '') {
+ geocoder.reverse(wp.latLng, 67108864, function(data) {
+ var input = inputContainers[idx].getElementsByClassName('geocoder')[0];
+ data = data[0];
+ input.value = data.name;
+ wp.name = data.name;
+ wp.latLng = data.center;
+ });
+ }
+ });
+ }
+ },
+
mapSearch = {
searchItems : [],
_ids : [],
@@ -658,6 +902,7 @@ Array.prototype.unique = function() {
Maps = {
addressbooks : [],
+ addresses : [],
tempArr : [],
tempCounter : 0,
tempTotal : 0,
@@ -770,6 +1015,38 @@ Array.prototype.unique = function() {
}
Maps.addressbooks.push(book);
})
+ //Load addresses in array
+ $.each(Maps.addressbooks, function(ai) {
+ $.get(OC.generateUrl('/apps/contacts/addressbook/' + this.backend + '/' + this.id + '/contacts'), function(r) {
+ $.each(r.contacts, function(ci) {
+ var name = this.data.FN[0].value;
+ var adr = {};
+ var orgAdr = {};
+ if(this.data.ADR){
+ for(var i=0; i< this.data.ADR.length; i++){
+ var currAddr = this.data.ADR[i].value;
+ //remove empty cells (didn't work with delete or any other function...thus: ugly code
+ for (var j=currAddr.length-1; j>=0; j--) {
+ if (currAddr[j] === null || currAddr[j] === undefined || currAddr[j] === "") {
+ currAddr.splice(j,1);
+ }
+ }
+ adr[i] = currAddr.toString().replace(/,/g, ", ");
+ orgAdr[i] = this.data.ADR[i].value;
+ }
+
+ }
+ if(!adr[0]) return true;
+ var addr = {
+ 'name': name,
+ 'add': adr,
+ 'orgAdd': orgAdr
+ };
+ Maps.addresses.push(addr);
+ });
+ });
+ });
+ //end
Maps.loadContacts();
})
},
@@ -1017,7 +1294,7 @@ Array.prototype.unique = function() {
return false;
},
_popupMouseOut: function(e) {
- if(marker == null) return false;
+ 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 63cee4e..81ae9a4 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -7,7 +7,6 @@
\OCP\Util::addScript('maps', '3rdparty/overpass/OverPassLayer');
\OCP\Util::addScript('maps', '3rdparty/leaflet/plugins/leaflet-routing-machine.min');
-\OCP\Util::addScript('maps', '3rdparty/leaflet/lib/Control.Geocoder');
\OCP\Util::addScript('maps', '3rdparty/leaflet/lib/leaflet.iconlabel');
\OCP\Util::addScript('maps', '3rdparty/leaflet/plugins/leaflet-hash');
@@ -27,10 +26,13 @@
\OCP\Util::addScript('maps', '3rdparty/binaryajax-lib');
\OCP\Util::addScript('maps', '3rdparty/exif');
+\OCP\Util::addScript('maps', '3rdparty/leaflet/lib/Control.Geocoder');
+
\OCP\Util::addStyle('maps', 'leaflet/leaflet');
\OCP\Util::addStyle('maps', 'leaflet/leaflet-compass.min');
\OCP\Util::addStyle('maps', 'leaflet/leaflet-routing-machine');
+\OCP\Util::addStyle('maps', 'leaflet/Control.Geocoder');
\OCP\Util::addStyle('maps', 'style');
\OCP\Util::addStyle('maps', 'font-awesome.min');
@@ -76,12 +78,17 @@