diff --git a/map_matching/conf/env.conf b/map_matching/conf/env.conf
deleted file mode 100644
index 972c6ff..0000000
--- a/map_matching/conf/env.conf
+++ /dev/null
@@ -1,10 +0,0 @@
-var server = {
- local: "http://localhost:8002/trace_attributes",
- dev: "https://valhalla.dev.mapzen.com/trace_attributes",
- prod:"https://valhalla.mapzen.com/trace_attributes"
-}
-var accessToken = {
- local: "",
- dev: "valhalla-t_16n1c",
- prod:"valhalla-UdVXVeg"
-}
diff --git a/map_matching/css/classic.css b/map_matching/css/classic.css
deleted file mode 100644
index f1f0d29..0000000
--- a/map_matching/css/classic.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.columns .ui-table{border-collapse:collapse;border-width:1px 1px 0 1px;border-style:solid;border-color:#ccc;width:100%}.columns .ui-table thead tr{background-image:-webkit-linear-gradient(top, #dbdbdb 10%, #b8b8b8 100%);background-image:linear-gradient(to bottom, #dbdbdb 10%, #b8b8b8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#DBDBDB', endColorstr='#B8B8B8',GradientType=0 );color:#333;font-size:14px;font-weight:bold;text-align:left}.columns .ui-table thead tr th{padding:5px 5px 5px 8px;border-right:1px solid #878787;border-bottom:1px solid #878787}.columns .ui-table thead tr th:first-child{border-left:1px solid #ccc}.columns .ui-table thead tr th:last-child{border-right:1px solid #ccc}.columns .ui-table thead tr th .ui-arrow{display:block;float:right;font-size:10px;width:10px}.columns .ui-table thead tr th.ui-table-sort-up,.columns .ui-table thead tr th.ui-table-sort-down{background:-webkit-linear-gradient(top, #d0d9e4 10%, #94a3c0 100%);background:linear-gradient(to bottom, #d0d9e4 10%, #94a3c0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#D0D9E4', endColorstr='#94A3C0',GradientType=0 )}.columns .ui-table tbody{font-size:14px}.columns .ui-table tbody tr td{border-right:1px solid #ccc;padding:12px}.columns .ui-table tbody tr.ui-table-rows-even{background:#F1F4F8}.columns .ui-table tbody tr.ui-table-rows-odd{background:#ffffff}.columns .ui-table-footer{background-image:-webkit-linear-gradient(top, #cbcbcb 10%, #aaa 100%);background-image:linear-gradient(to bottom, #cbcbcb 10%, #aaa 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#CBCBCB', endColorstr='#AAAAAA',GradientType=0 );border-top:1px solid #878787;width:100%;padding:8px 0;font-size:11px;text-align:left;color:#333}.columns .ui-table-footer span{vertical-align:middle}.columns .ui-table-footer .ui-table-size,.columns .ui-table-footer .ui-table-results,.columns .ui-table-footer .ui-table-controls{display:inline-block;width:32%}.columns .ui-table-footer .ui-table-size{padding-left:20px}.columns .ui-table-footer .ui-table-results{text-align:center}.columns .ui-table-footer .ui-table-controls{text-align:right}.columns .ui-table-footer .ui-table-control-next,.columns .ui-table-footer .ui-table-control-prev,.columns .ui-table-footer .ui-table-control-disabled{display:inline-block;background-image:-webkit-linear-gradient(top, #fdfdfd 10%, #c0bfbe 100%);background-image:linear-gradient(to bottom, #fdfdfd 10%, #c0bfbe 100%);background-color:transparent;border:1px solid #333;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;list-style:none;margin:0;padding:5px;vertical-align:middle;font-weight:bold;color:#333;cursor:pointer;text-align:center}.columns .ui-table-footer .ui-table-control-disabled img{opacity:0.5}.columns .ui-columns-search{font-size:14px;background:-webkit-linear-gradient(top, #d1d1d1 10%, #a7a7a8 100%);background:linear-gradient(to bottom, #d1d1d1 10%, #a7a7a8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#D1D1D1', endColorstr='#A7A7A8',GradientType=0 );padding:10px;border-bottom:1px solid #878787;text-align:right}.columns .ui-columns-search input{width:200px;border-radius:10px;padding:4px 10px 4px 25px;border:2px solid transparent;background-image:url(../images/search.png);background-position:5px center;background-repeat:no-repeat}.columns .ui-columns-search input:focus{border:2px solid #6196CD;outline:none}
-.columns {
- margin: 20px auto !important;
-}
diff --git a/map_matching/css/leaflet.label.css b/map_matching/css/leaflet.label.css
deleted file mode 100644
index b926d33..0000000
--- a/map_matching/css/leaflet.label.css
+++ /dev/null
@@ -1,56 +0,0 @@
-.leaflet-label {
- //background: rgb(235, 235, 235);
- //background: rgba(235, 235, 235, 0.81);
- //background: #585858;
- //background-clip: padding-box;
- //border-color: #777;
- //border-color: rgba(0,0,0,0.25);
- //border-radius: 4px;
- //border-style: solid;
- //border-width: 4px;
- color: #FFFFFF;
- //color: #111;
- display: block;
- font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
- font-weight: bold;
- padding: 1px 6px;
- position: absolute;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- pointer-events: none;
- white-space: nowrap;
- z-index: 6;
-}
-
-.leaflet-label.leaflet-clickable {
- cursor: pointer;
- pointer-events: auto;
-}
-
-.leaflet-label:before,
-.leaflet-label:after {
- border-top: 6px solid transparent;
- border-bottom: 6px solid transparent;
- content: none;
- position: absolute;
- top: 5px;
-}
-
-.leaflet-label:before {
- border-right: 6px solid black;
- border-right-color: inherit;
- left: -10px;
-}
-
-.leaflet-label:after {
- border-left: 6px solid black;
- border-left-color: inherit;
- right: -10px;
-}
-
-.leaflet-label-right:before,
-.leaflet-label-left:after {
- content: "";
-}
diff --git a/map_matching/css/mapzen-common.css b/map_matching/css/mapzen-common.css
deleted file mode 100644
index c64916c..0000000
--- a/map_matching/css/mapzen-common.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/* button styles */
-
-.btn {
- border-radius: 0;
- border-width: 1px;
- text-transform: uppercase;
- font-weight: 600;
- padding: 10px 16px;
-}
-
-
-.btn-mapzen {
- border-color: #d4645c;;
- background-color: #d4645c;;
- color: #fff;
- text-shadow: none;
-}
-
-.btn-mapzen:hover, .btn-mapzen:focus {
- border-color: #993434;
- background-color: #993434;
- color: #fff;
-}
-
-.btn-transparent {
- background: transparent;
- border-color: #444;;
- color: #444;;
-}
-
-.btn-transparent:hover, .btn-transparent:focus {
- background-color: #e5e5e5;
- border-color: #444;;
- color: #444;;
-}
\ No newline at end of file
diff --git a/map_matching/css/optimized_route.css b/map_matching/css/optimized_route.css
deleted file mode 100644
index cf5a6e6..0000000
--- a/map_matching/css/optimized_route.css
+++ /dev/null
@@ -1,287 +0,0 @@
-html {
- width: 100%;
- height: 100%;
-}
-
-body {
- font: 13px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
- width: 100%;
- height: 100%;
- color: #383a3a;
- min-height: 600px;
-}
-
-.container-fluid {
- height: 100%;
- margin: 0;
- padding: 0;
-}
-
-.control-container {
- width: 500px;
- height: 100%;
- float: left;
- background-color: #eee;
- padding: 20px;
- overflow-y: auto;
-}
-
-#map {
- width: calc( 100% - 500px);
- height: 100%;
- float: left;
-}
-
-.tableView {
- padding-top: 20px;
-}
-
-.instruction {
- text-align: center;
- font-weight: 600;
- margin: 20px 0;
-}
-
-/* these are for blocking ui */
-div[class*="Wrapper"] {
- background-color: #fff;
- position: relative;
- padding: 10px;
- margin: 10px 0;
- text-align: center;
-}
-
-div[class*="Blocker"] {
- position: absolute;
- left: 0;
- top: 0;
- z-index: 1050;
-}
-
-.block {
- width: 100%;
- height: 100%;
- background-color:rgba(238,238,238,0.5);
-}
-
-
-/* optimize type button */
-.stitched {
- padding: 8px;
- margin-right: 7px;
- margin-bottom: 20px;
- background: #FFFFFF;
- color: #A4A4A4;
- font-size: 16px;
- border: 2px dashed #DADADA;
- box-shadow: 0;
-}
-
-.stitched.selected {
- color: #68c175;
- border: 2px solid #99cfc1;
- cursor: default;
-}
-
-button:focus {
- outline: 2px solid #9ed7a7;
-}
-
-.done {
- background-color: #fff;
- padding: 3px 8px;
- margin: 15px auto;
- width: auto;
- text-align: center;
- border: 1px solid #666;
- cursor: pointer;
-}
-
-ol {
- padding: 0 30px;
-}
-
-li {
- list-style-type: none;
- width: 100%;
- height: 45px;
- border-bottom: 1px solid #31783c;
- position: relative;
- margin: 5px 0;
-}
-li .marker {
- width: 28px;
- height: 36px;
- margin-left: 5px;
- margin-top: 5px;
- background-repeat: no-repeat;
- float: left;
- color: #fff;
- padding-top: 5px;
- font-weight: 600;
- text-align: center;
-}
-
-li .start { background-image:url(../../matrix/resource/matrix_pin_start.png); }
-li .end { background-image:url(../../matrix/resource/matrix_pin_end.png);}
-
-li .geocode {
- font-size: 14px;
- position: absolute;
- left: 40px;
- bottom: 10px;
-}
-
-li .placeholder.geocode {
- color: #ccc;
-}
-
-
-.routingBtns {
- //float: right;
-}
-
-.btnWrapper::after {
- content: "";
- display: table;
- clear: both;
-}
-
-.plain {
- float: left;
- background: transparent;
- border: none;
- color: #68c175;
- padding: 10px 16px;
- margin-top: 2px;
-}
-
-.btnOptimize {
- background-color: #68c175;
- float: left;
- padding: 10px 26px;
- border: 1px solid #68c175;
- color: #fff;
- text-transform: uppercase;
-}
-
-.btnOptimize:hover {
- background-color: #31783c;
- border-color: #31783c;
-}
-
-.leaflet-routing-alt tr {
- min-height: 40px;
- height: 80px;
- border-bottom: 1px solid #eee;
-}
-
-.leaflet-routing-icon {
- -webkit-background-size: 240px 20px;
- background-size: 240px 20px;
- background-repeat: no-repeat;
- margin: 0;
- content: '';
- display: inline-block;
- vertical-align: top;
- width: 20px;
-}
-
-.leaflet-routing-icon h2 {
- width: 20px;
- margin-left: 11px;
- margin-bottom: 20px;
- color: white;
-}
-
-.leaflet-routing-icon img{
- z-index: -1;
- margin-top: -60px;
- position: relative;
- bottom: -15px;
- }
-
-.leaflet-routing-container .start {
- font-size: 18px;
- min-height: 60px;
- line-height: 60px;
- padding-left: 50px;
- background-image: url('../../matrix/resource/matrix_pin_start.png');
- background-repeat: no-repeat;
- background-position: 5px 8px;
- background-size: 45px 55px;
- letter-spacing: 0.5px;
-}
-
-.leaflet-routing-container .dest{
- font-size: 18px;
- line-height:60px;
- min-height:40px;
- padding-left:50px;
- background-image: url('../../matrix/resource/matrix_pin_end.png');
- background-repeat: no-repeat;
- background-position: 5px 8px;
- background-size: 45px 55px;
- letter-spacing: 0.5px;
-}
-
-/* vehicle mode*/
-
-.vehicleBox {
- //width: 170px;
- // float: left;
-}
-
-.vehicleBox .vehicle {
- width: 50px;
- height: 41px;
- float: left;
- background-color: transparent;
- // border: 2px dashed #DADADA;
- margin-right: 5px;
- background-image: url('../../matrix/images/modes.svg');
- background-size: 150px 41px;
- background-repeat: no-repeat;
-}
-.vehicleBox .vehicle.active {
- color: #68c175;
- border: 2px solid #68c175;;
-}
-
-.bike { background-position: -50px 0;}
-.pedestrian { background-position: -100px 0;}
-
-.leaflet-label-right:before,
-.leaflet-label-left:after {
- content: none;
-}
-
-html.is-iframed-demo .container-fluid {
- padding-left: 0;
- padding-right: 0;
-}
-
-@media (max-width: 767px) {
- html.is-iframed-demo #map {
- height: calc( 100% - 550px );
- }
- .container-fluid {
- width: 100%;
- height: auto;
- }
- .control-container {
- width: 100%;
- height: auto;
- }
- #map {
- width: 500px;
- }
-}
-
-html.is-iframed-demo .not-map-part {
- margin: 0 auto;
-}
-
-html.is-iframed-demo .hide-if-iframed {
- display: none;
-}
\ No newline at end of file
diff --git a/map_matching/index-internal.html b/map_matching/index-internal.html
deleted file mode 100644
index 6fca34e..0000000
--- a/map_matching/index-internal.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Select an environment
-
- localhost
- development
- production
-
-
-
-
-
-
-
-
-
-
-
Clear All
-
-
-
-
-
-
-
GeoJSON
-
-
-
-
-
-
-
Locations
-
-
- {{point.index}}
- {{point.latlon}}
-
-
-
- {{endgeocode}}
-
-
-
{{end_mapInstruction}}
-
-
-
-
-
-
-
-
< Back
-
-
- start over
-
-
-
JSON Optimized Route Response Link
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/map_matching/index.html b/map_matching/index.html
index 3b975c9..bd5ef83 100644
--- a/map_matching/index.html
+++ b/map_matching/index.html
@@ -1,107 +1,305 @@
-
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Clear All
-
+
+
+
+
+
+
+
+
-
Options
-
Radius:
+
Options
+
Radius:
-
GeoJSON
-
-
-
-
-
-
-
Locations
-
-
- {{point.index}}
- {{point.latlon}}
-
-
-
- {{endgeocode}}
-
-
-
{{end_mapInstruction}}
-
-
+
GeoJSON
+
+
-
-
-
< Back
-
-
- start over
-
-
-
JSON Optimized Route Response Link
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
\ No newline at end of file
diff --git a/map_matching/js/LICENSE.txt b/map_matching/js/LICENSE.txt
deleted file mode 100755
index e445cd3..0000000
--- a/map_matching/js/LICENSE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2014, Michael Eisenbraun (http://eisenbraun.github.io/columns/)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/map_matching/js/MIT-LICENCE.txt b/map_matching/js/MIT-LICENCE.txt
deleted file mode 100644
index 1ace2f3..0000000
--- a/map_matching/js/MIT-LICENCE.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright 2012 Jacob Toye
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/map_matching/js/jquery.columns.min.js b/map_matching/js/jquery.columns.min.js
deleted file mode 100644
index 9764f56..0000000
--- a/map_matching/js/jquery.columns.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/***
- * Copyright (c) 2014
- * Licensed under the MIT License.
- *
- * Author: Michael Eisenbraun
- * Version: 2.2.2
- * Requires: jQuery 1.7.2+
- * Documentation: http://eisenbraun.github.io/columns/
- */if(!window.console)var console={log:function(){}};(function(e){e.fn.columns=function(n){var r=[],i=Array.prototype.slice.call(arguments,1);typeof n=="string"?this.each(function(){var t=e.data(this,"columns");if(typeof t=="undefined"||!e.isFunction(t[n]))return e.error('No such method "'+n+'" for Columns');var s=t[n].apply(t,i);s!==undefined&&s!==t&&r.push(s)}):this.each(function(){e.data(this,"columns")||e.data(this,"columns",new t(this,n))});return r.length===0?this.data("columns"):r.length===1?r[0]:r};var t=function(t,n){this.$el=e(t);n&&e.extend(this,n);this.VERSION="2.2.2";this.sort=function(){function n(e,n,r){n=n?-1:1;return function(i,s){i=i[e];s=s[e];if(t.test(i)&&t.test(s)){i=new Date(i);i=Date.parse(i);s=new Date(s);s=Date.parse(s)}else if(typeof r!="undefined"){i=r(i);s=r(s)}return i
s?n*1:0}}var e=this,t=/^(Jan|January|Feb|February|Mar|March|Apr|April|May|Jun|June|Jul|July|Aug|August|Sep|September|Oct|October|Nov|November|Dec|December|(0?\d{1})|(10|11|12))(-|\s|\/|\.)(0?[1-9]|(1|2)[0-9]|3(0|1))(-|\s|\/|\.|,\s)(19|20)?\d\d$/i;e.total&&e.sortBy&&typeof e.data[0][e.sortBy]!="undefined"&&e.data.sort(n(e.sortBy,e.reverse))};this.filter=function(){var t=this,n=t.searchableFields.length;if(t.query){var r=new RegExp(t.query,"gi");t.data=e.grep(t.data,function(e){for(var i=0;i'):i.push('');e.each(t.schema,function(e,n){n.hide||(n.template?i.push(""+t.chevron(n.template,r)+" "):i.push(""+r[n.key]+" "))});i.push(" ");return i}function i(){var n=[];n.push("");e.each(t.showRows,function(e,r){var i='"+r+" ";n.push(i)});n.push(" ");t.showRowsMenu=n.join("")}function s(){t.rows=[];t.total?e.each(t.data,function(e,i){e===0&&n();t.rows.push(r(e,i).join(""))}):t.rows.push('No Results ')}var t=this;t.resetData();t.searching&&t.filter();t.sorting&&t.sort();t.paginating&&t.paginate();s();i();var o={prevPage:t.page-1,nextPage:t.page+1,prevPageExists:t.pageExists(t.page-1),nextPageExists:t.pageExists(t.page+1),resultRange:t.range,tableTotal:t.total,showRowsMenu:t.showRowsMenu,rows:t.rows,headers:t.thead,query:t.query,search:t.search,table:t.table};e.extend(t.view,o);t.plugins&&e.each(t.plugins,function(e,n){typeof ColumnsPlugins!="undefined"&&typeof ColumnsPlugins[n]!="undefined"&&ColumnsPlugins[n].create.call(t)});if(t.search){t.$el.html(t.chevron(t.template,t.view));t.search=!1}else{e("[data-columns-table]",t.$el).remove();t.$el.append(t.chevron(t.template,t.view))}return!0};this.init=function(){function n(){t.schema=[];e.each(t.data[0],function(e){t.schema.push({header:e,key:e})})}function r(){t.searchableFields=[];e.each(t.data[0],function(e){t.searchableFields.push(e)})}function i(){t.sortableFields=[];e.each(t.data[0],function(e){t.sortableFields.push(e)})}function s(){e.ajax({url:t.templateFile,async:!1,success:function(e){t.template=e},error:function(){e.error("Template could not be found.")}})}var t=this;if(e.isArray(t.data)){t.master=[];t.view={};t.$el.addClass("columns");t.$el.on("click",".ui-table-sortable",function(n){var r=e(this).data("columns-sortby");t.sortBy===r&&(t.reverse=t.reverse?!1:!0);t.sortBy=r;t.sortHandler(n)});t.$el.on("click",".ui-table-control-next, .ui-table-control-prev",function(n){t.page=e(this).data("columns-page");t.pageHandler(n)});t.$el.on("keyup",".ui-table-search",function(n){t.query=e(this).val();t.searchHandler(n)});t.$el.on("change",".ui-table-size select",function(n){t.size=parseInt(e(this).val());t.sizeHandler(n)});t.plugins&&e.each(t.plugins,function(e,n){typeof ColumnsPlugins!="undefined"&&typeof ColumnsPlugins[n]!="undefined"&&ColumnsPlugins[n].init.call(t)});t.conditioning&&t.condition();t.schema||n();t.searchableFields||r();t.sortableFields||i();t.templateFile&&s();e.extend(t.master,t.data);t.create()}else e.error('The "data" parameter must be an array.')};this.init()};t.prototype={evenRowClass:"ui-table-rows-even",oddRowClass:"ui-table-rows-odd",liveSearch:!0,page:1,pages:1,plugins:null,query:null,reverse:!1,pagination:!0,schema:null,search:!0,searchableFields:null,showRows:[10,20,30,50],size:20,sortableFields:null,sortBy:null,table:!0,templateFile:null,template:' {{#search}}
{{/search}} {{#table}} {{#headers}} {{#sortable}} {{header}} {{/sortable}} {{#notSortable}} {{header}} {{/notSortable}} {{#sortedUp}} {{header}} ▲ {{/sortedUp}} {{#sortedDown}} {{header}} ▼ {{/sortedDown}} {{/headers}} {{#rows}} {{{.}}} {{/rows}}
{{/table}} ',conditioning:!0,paginating:!0,searching:!0,sorting:!0,pageHandler:function(){this.create()},searchHandler:function(e){this.liveSearch?this.create():e.keyCode=="13"&&this.create()},sizeHandler:function(){this.create()},sortHandler:function(){this.page=1;this.create()},destroy:function(){this.$el.data("columns",null);this.$el.empty();return!0},getObject:function(){return this},getPage:function(){return this.page},getQuery:function(){return this.query},getRange:function(){return this.range},getRows:function(){return this.rows},getShowRowsMenu:function(){return this.showRowsMenu},getTemplate:function(){return this.template},getThead:function(){return this.thead},getTotal:function(){return this.total},getVersion:function(){return this.VERSION},getView:function(){return this.view},gotoPage:function(e){if(this.pageExists(e)){this.page=e;this.create();return!0}return!1},pageExists:function(e){return e>0&&e<=this.pages?!0:!1},resetData:function(e){this.data=this.master.slice(0);return this.data},setMaster:function(t){if(e.isArray(t)){this.master=t;return!0}return!1},setPage:function(e){this.page=this.pageExists(e)?e:this.page;return this.page},setRange:function(){var e=(this.page-1)*this.size,t=e+this.size"'\/]/g,function(e){return f[e]})}function m(t,r){function m(){if(f&&!l)while(u.length)delete o[u.pop()];else u=[];f=!1;l=!1}function x(e){typeof e=="string"&&(e=e.split(h,2));if(!n(e)||e.length!==2)throw new Error("Invalid tags: "+e);w=new RegExp(i(e[0])+"\\s*");E=new RegExp("\\s*"+i(e[1]));S=new RegExp("\\s*"+i("}"+e[1]))}if(!t)return[];var s=[],o=[],u=[],f=!1,l=!1,w,E,S;x(r||e.tags);var T=new b(t),N,C,k,L,A,O;while(!T.eos()){N=T.pos;k=T.scanUntil(w);if(k)for(var M=0,_=k.length;M<_;++M){L=k.charAt(M);a(L)?u.push(o.length):l=!0;o.push(["text",L,N,N+1]);N+=1;L==="\n"&&m()}if(!T.scan(w))break;f=!0;C=T.scan(v)||"name";T.scan(c);if(C==="="){k=T.scanUntil(p);T.scan(p);T.scanUntil(E)}else if(C==="{"){k=T.scanUntil(S);T.scan(d);T.scanUntil(E);C="&"}else k=T.scanUntil(E);if(!T.scan(E))throw new Error("Unclosed tag at "+T.pos);A=[C,k,N,T.pos];o.push(A);if(C==="#"||C==="^")s.push(A);else if(C==="/"){O=s.pop();if(!O)throw new Error('Unopened section "'+k+'" at '+N);if(O[1]!==k)throw new Error('Unclosed section "'+O[1]+'" at '+N)}else C==="name"||C==="{"||C==="&"?l=!0:C==="="&&x(k)}O=s.pop();if(O)throw new Error('Unclosed section "'+O[1]+'" at '+T.pos);return y(g(o))}function g(e){var t=[],n,r;for(var i=0,s=e.length;i0?r[r.length-1][4]:t;break;default:n.push(i)}}return t}function b(e){this.string=e;this.tail=e;this.pos=0}function w(e,t){this.view=e==null?{}:e;this.cache={".":this.view};this.parent=t}function E(){this.cache={}}var t=Object.prototype.toString,n=Array.isArray||function(e){return t.call(e)==="[object Array]"},s=RegExp.prototype.test,u=/\S/,f={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},c=/\s*/,h=/\s+/,p=/\s*=/,d=/\s*\}/,v=/#|\^|\/|>|\{|&|=|!/;b.prototype.eos=function(){return this.tail===""};b.prototype.scan=function(e){var t=this.tail.match(e);if(!t||t.index!==0)return"";var n=t[0];this.tail=this.tail.substring(n.length);this.pos+=n.length;return n};b.prototype.scanUntil=function(e){var t=this.tail.search(e),n;switch(t){case-1:n=this.tail;this.tail="";break;case 0:n="";break;default:n=this.tail.substring(0,t);this.tail=this.tail.substring(t)}this.pos+=n.length;return n};w.prototype.push=function(e){return new w(e,this)};w.prototype.lookup=function(e){var t=this.cache,n;if(e in t)n=t[e];else{var i=this,s,o;while(i){if(e.indexOf(".")>0){n=i.view;s=e.split(".");o=0;while(n!=null&&o":if(!s)continue;c=r(s)?s(l[1]):s[l[1]];c!=null&&(u+=this.renderTokens(this.parse(c),i,s,c));break;case"&":c=i.lookup(l[1]);c!=null&&(u+=c);break;case"name":c=i.lookup(l[1]);c!=null&&(u+=e.escape(c));break;case"text":u+=l[1]}}return u};e.name="mustache.js";e.version="0.8.1";e.tags=["{{","}}"];var S=new E;e.clearCache=function(){return S.clearCache()};e.parse=function(e,t){return S.parse(e,t)};e.render=function(e,t,n){return S.render(e,t,n)};e.to_html=function(t,n,i,s){var o=e.render(t,n,i);if(!r(s))return o;s(o)};e.escape=l;e.Scanner=b;e.Context=w;e.Writer=E;return e});
\ No newline at end of file
diff --git a/map_matching/js/main.js b/map_matching/js/main.js
deleted file mode 100644
index 165778e..0000000
--- a/map_matching/js/main.js
+++ /dev/null
@@ -1,354 +0,0 @@
-var app = angular.module('optimized_route', []);
-var hash_params = L.Hash.parseHash(location.hash);
-
-var envServer = "production";
-var envToken = accessToken.prod;
-var serviceUrl = server.prod;
-var sentManyToManyEnd = false;
-var optimized_route = true;
-
-function selectEnv() {
- $("#env_dropdown").find("option:selected").each(function() {
- envServer = $(this).text();
- getEnvToken();
- });
-}
-
-selectEnv();
-
-function handleChange(evt) {
- var sel = document.getElementById('selector');
- for (var i = 0; i < sel.options.length; i++) {
- var results = sel.options[i].text + " " + sel.options[i].value;
- sel.options[i].innerHTML = results;
- }
-}
-
-function getEnvToken() {
- switch (envServer) {
- case "localhost":
- envToken = accessToken.local;
- serviceUrl = server.local;
- break;
- case "development":
- envToken = accessToken.dev;
- serviceUrl = server.dev;
- break;
- case "production":
- envToken = accessToken.prod;
- serviceUrl = server.prod;
- break;
- }
-}
-
-app.run(function($rootScope) {
- var hash_loc = hash_params ? hash_params : {
- center : {
- lat : 40.7486,
- lng : -73.9690
- },
- zoom : 13
- };
- $rootScope.geobase = {
- zoom : hash_loc.zoom,
- lat : hash_loc.center.lat,
- lon : hash_loc.center.lng
- };
- $(document).on('new-location', function(e) {
- $rootScope.geobase = {
- zoom : e.zoom,
- lat : e.lat,
- lon : e.lon
- };
- });
-});
-
-
-//hooks up to the div whose data-ng-controller attribute matches this name
-app.controller('OptimizedRouteController', function($scope, $rootScope, $sce, $http) {
- var road = L.tileLayer('http://b.tile.openstreetmap.org/{z}/{x}/{y}.png', {
- attribution : '© OpenStreetMap contributers'
- }),
- cycle = L.tileLayer('http://b.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=f8f13e0070864ac3ad996f7bf7beb9af', {
- attribution : 'Maps © Thunderforest, ;Data © OpenStreetMap contributors '
- }), elevation = L.tileLayer('http://b.tile.thunderforest.com/outdoors/{z}/{x}/{y}.png?apikey=f8f13e0070864ac3ad996f7bf7beb9af', {
- attribution : 'Maps © Thunderforest, ;Data © OpenStreetMap contributors '
- });
-
- var mapMatchingControl;
-
- var mapMatch = function () {
- var traceCoords = $scope.endPoints.map(function(gLoc) {
- return [parseFloat(gLoc.lon), parseFloat(gLoc.lat)];
- });
-
- var trace = {
- type: 'MultiPoint',
- coordinates: traceCoords
- };
-
- if (mapMatchingControl) {
- mapMatchingControl.removeFrom(map);
- }
- mapMatchingControl = L.mapMatching(trace, {
- externalTraceLayer: L.layerGroup(markers),
- serviceUrlParams: {api_key: envToken, mode: $scope.mode,
- search_radius: document.getElementById('radius').value },
- serviceUrl: serviceUrl
- }).addTo(map);
-
- update(true, traceCoords, $scope.mode);
- };
-
- var mapMatchingGeoJSONControl;
-
- var mapMatchGeoJSON = function (traceGeoJSON) {
- var markers = {
- 'type': 'MultiPoint',
- 'coordinates': traceGeoJSON.coordinates || (traceGeoJSON.geometry && traceGeoJSON.geometry.coordinates)
- };
-
- if (mapMatchingGeoJSONControl) {
- mapMatchingGeoJSONControl.removeFrom(map);
- }
- mapMatchingGeoJSONControl = L.mapMatching(traceGeoJSON, {
- serviceUrlParams: {api_key: envToken, mode: $scope.mode,
- search_radius: document.getElementById('radius').value },
- serviceUrl: serviceUrl
- }).addTo(map);
-
- update(true, traceGeoJSON, $scope.mode);
- };
-
- var baseMaps = {
- "Road" : road,
- "Cycle" : cycle,
- "Elevation" : elevation
- };
-
- //leaflet slippy map
- var map = L.map('map', {
- zoom : $rootScope.geobase.zoom,
- zoomControl : true,
- layers : [ road ],
- center : [ $rootScope.geobase.lat, $rootScope.geobase.lon ]
- });
-
- // var sequence = new Sequence(map);
-
- // If iframed, we're going to have to disable some of the touch interaction
- // to not hijack page scroll. See Stamen's Checklist for Maps: http://content.stamen.com/stamens-checklist-for-maps
- if (window.self !== window.top) {
- map.scrollWheelZoom.disable();
- }
-
- L.control.layers(baseMaps, null).addTo(map);
-
- // If iframed, we're going to have to disable some of the touch interaction
- // to not hijack page scroll. See Stamen's Checklist for Maps: http://content.stamen.com/stamens-checklist-for-maps
- if (window.self !== window.top) {
- map.scrollWheelZoom.disable();
- }
-
- var getOriginIcon = function() {
- return new L.Icon({
- iconUrl : '../matrix/resource/matrix_pin_start.png',
- iconSize : [ 30, 36 ],
- shadowUrl: null
- });
- };
-
- var getDestinationIcon = function() {
- return new L.Icon({
- iconUrl : '../matrix/resource/matrix_pin_end.png',
- iconSize : [ 30, 36 ],
- shadowUrl: null
- });
- };
-
- //Number of locations
- var hash = new L.Hash(map);
- var markers = [];
- var remove_markers = function() {
- for (var i = 0; i < markers.length; i++) {
- map.removeLayer(markers[i]);
- }
- markers = [];
- };
-
-
- var parseHash = function() {
- var hash = window.location.hash;
- if (hash.indexOf('#') === 0)
- hash = hash.substr(1);
- return hash.split('&');
- };
-
- var parseParams = function(pieces) {
- var parameters = {};
- pieces.forEach(function(e, i, a) {
- var parts = e.split('=');
- if (parts.length < 2)
- parts.push('');
- parameters[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
- });
- return parameters;
- };
-
- var update = function(show, coords, costing) {
- // update the permalink hash
- var pieces = parseHash();
- var extra = '';
- pieces.forEach(function(e, i, a) {
- if (e.length && e.slice(0, 'locations='.length) != 'locations=' && e.slice(0, 'costing='.length) != 'costing=' && e.slice(0, 'directions_options='.length) != 'directions_options=')
- extra = extra + (extra.length ? '&' : '') + e;
- });
- var parameter = '&costing=' + JSON.stringify(costing);
- window.location.hash = '#' + extra + parameter;
- document.getElementById('permalink').innerHTML = "Map Matching Permalink ";
- };
-
- var hashRoute = function() {
- document.getElementById('permalink').innerHTML = "Map Matching Permalink ";
- };
-
- $rootScope.$on('map.setView', function(ev, geo, zoom) {
- map.setView(geo, zoom || 8);
- });
-
- $rootScope.$on('map.dropDestMarker', function(ev, geo, locCount) {
- var marker = new L.marker(geo, {
- icon : getDestinationIcon(),
- draggable:true
- }).bindLabel((locCount).toString(), (locCount < 10) ? {
- position: [geo.lat,geo.lon],
- noHide: true,
- offset: [-9,-12]
- } : {
- position: [geo.lat,geo.lon],
- noHide: true,
- offset: [-13,-12]
- });
- map.addLayer(marker);
- markers.push(marker);
- marker.on('dragend', function(event){
- var marker = event.target;
- var position = marker.getLatLng();
- marker.setLatLng(position,{draggable:'true'}).bindPopup(position);
- var latlon = position.lat.toFixed(6) + ' , '+ position.lng.toFixed(6);
- var latLngIndex = parseInt(marker.label._content);
- $scope.endPoints.splice(latLngIndex-1,1,{index: (latLngIndex), lat:position.lat, lon: position.lng,latlon: latlon});
- $scope.$apply();
- mapMatch();
- return;
- });
- });
-
- $scope.renderHtml = function(html_code) {
- return $sce.trustAsHtml(html_code);
- };
-
- $scope.setMode = function(mode) {
- $scope.mode = mode;
- mapMatch();
- };
-
- // show something to start with but only if it was requested
- $(window).load(function(e) {
- hashRoute();
- });
-
- var reset_form = function() {
- $scope.endPoints = [];
- };
-
- //set up map events
- var counterText = 1;
- map.on('click', function(e) {
- if (!markers.length) {
- $scope.manyToManyClick(e);
- }
-
- var geo = {
- 'lat' : e.latlng.lat.toFixed(6),
- 'lon' : e.latlng.lng.toFixed(6)
- };
-
- $rootScope.$emit('map.dropDestMarker', [ geo.lat, geo.lon ], counterText);
- var latlon = geo.lat + ' , '+ geo.lon;
- $scope.endPoints.push({
- index: (counterText),
- lat: geo.lat,
- lon: geo.lon,
- latlon: latlon
- });
- $scope.$apply();
- counterText++;
-
- mapMatch();
- });
-
- var traceLayer;
- $('#geojson_match').click(function () {
- $scope.clearAll();
- var geojson = JSON.parse($('#geojson').val());
- if (traceLayer) {
- map.removeLayer(traceLayer);
- }
- traceLayer = L.geoJson(geojson, {
- style: {
- color: '#ff7800'
- }
- }).addTo(map);
- map.fitBounds(traceLayer.getBounds());
- mapMatchGeoJSON(geojson);
- });
-
- var clearBtn = document.getElementById("clear_btn");
-
- $scope.mode = 'auto';
- $scope.endPoints = [];
- $scope.editingFocus = 'start_points';
- $scope.appView = 'control';
-
- $scope.backToControlView = function(e) {
- $scope.appView = 'control';
- };
-
- $scope.clearRouteShape = function(e) {
- };
-
- $scope.clearAll = function(e) {
- $scope.endPoints = [];
- $scope.appView = 'control';
- $scope.editingFocus = 'start_points';
- sentManyToManyEnd = false;
- counterText = 1;
-
- if (mapMatchingControl) {
- mapMatchingControl.removeFrom(map);
- }
- mapMatchingControl = null;
-
- markers.forEach(function (marker) {
- map.removeLayer(marker);
- });
-
- markers = [];
- window.location.hash = "";
- };
-
- $scope.goToEndPoints = function(e) {
- $scope.editingFocus = 'end_points';
- };
-
- $scope.manyToManyClick = function(e) {
- reset_form();
- $scope.start_mapInstruction = " Click on the map to add a point";
- $scope.end_mapInstruction = " Click on the map to add points";
- $scope.startgeocode = "lat, long";
- $scope.endgeocode = "lat, long";
- getEnvToken();
- };
-
-});
diff --git a/map_matching/js/map_matching.js b/map_matching/js/map_matching.js
deleted file mode 100644
index c0380d6..0000000
--- a/map_matching/js/map_matching.js
+++ /dev/null
@@ -1,267 +0,0 @@
-(function () {
- 'use strict';
-
- var coordToLatLng = function (coord) {
- var lng = coord[0], lat = coord[1];
- return L.latLng(lat, lng);
- };
-
- var readTraceCoords = function (geo) {
- if (geo && geo.coordinates) {
- return geo.coordinates;
- } else if (geo && geo.geometry && geo.geometry.coordinates) {
- return geo.geometry.coordiantes;
- } else {
- return null;
- }
- };
-
- var defaultTraceBuilder = function (geoTrace, options) {
- var coords = readTraceCoords(geoTrace);
- if (!coords) {
- return null;
- }
- options = options || {draggable: true};
- var circles = L.GeoJSON.coordsToLatLngs(coords).map(function (latlng) {
- return L.marker(latlng, options);
- });
- return L.layerGroup(circles);
- };
-
- var readMatchCoords = function (geo) {
- try {
- return geo.properties.matched_coordinates;
- } catch (err) {
- return null;
- }
- };
-
- var defaultMatchPointBuilder = function (geo, options) {
- var matchCoords = readMatchCoords(geo);
- var circles = matchCoords.filter(function (coord) {
- return coord != null;
- }).map(function (coord) {
- return L.circleMarker(coordToLatLng(coord), options);
- });
- return L.layerGroup(circles);
- };
-
- var defaultMatchLineBuilder = function (geoTrace, geoResults, options) {
- var traceCoords = readTraceCoords(geoTrace);
- if (!traceCoords) {
- return null;
- }
-
- var matchCoords = readMatchCoords(geoResults);
- if (!matchCoords) {
- return null;
- }
-
- var lines = traceCoords.map(function (coord, idx) {
- return matchCoords[idx]? [coordToLatLng(coord), coordToLatLng(matchCoords[idx])] : null;
- }).filter(function (coord) { return coord !== null; });
-
- return L.multiPolyline(lines, options);
- };
-
- var defaultMatchRouteBuilder = function (geo, options) {
- return L.geoJson(geo, options);
- };
-
- var encode = function (coordinates) {
- var output = [];
- //handy lambda to turn an integer into an encoded string
- var serialize = function(number) {
- //move the bits left 1 position and flip all the bits if it was a negative number
- number = number < 0 ? ~(number << 1) : (number << 1);
- //write 5 bit chunks of the number
- while (number >= 0x20) {
- var nextValue = (0x20 | (number & 0x1f)) + 63;
- output.push(String.fromCharCode(nextValue));
- number >>= 5;
- }
- //write the last chunk
- number += 63;
- output.push(String.fromCharCode(number));
- };
-
- //this is an offset encoding so we remember the last point we saw
- var last_lon = 0, last_lat = 0;
- //for each point
- coordinates.forEach(function(p) {
- //shift the decimal point 6 places to the right, floor and cast to int
- var lon = Math.floor(p[0] * 1e6) | 0;
- var lat = Math.floor(p[1] * 1e6) | 0;
- //encode each coordinate, lat first for some reason
- serialize(lat - last_lat);
- serialize(lon - last_lon);
- //remember the last one we encountered
- last_lon = lon;
- last_lat = lat;
- });
- return output.join('');
- };
-
- function decode(encoded) {
- //six degrees of precision in valhalla
- var inv = 1.0 / 1e6;
- var decoded = [];
- var previous = [0,0];
- var i = 0;
- //for each byte
- while(i < encoded.length) {
- //for each coord (lat, lon)
- var ll = [0,0]
- for(var j = 0; j < 2; j++) {
- var shift = 0;
- var byte = 0x20;
- //keep decoding bytes until you have this coord
- while(byte >= 0x20) {
- byte = encoded.charCodeAt(i++) - 63;
- ll[j] |= (byte & 0x1f) << shift;
- shift += 5;
- }
- //add previous offset to get final value and remember for next one
- ll[j] = previous[j] + (ll[j] & 1 ? ~(ll[j] >> 1) : (ll[j] >> 1));
- previous[j] = ll[j];
- }
- //scale by precision and chop off long coords also flip the positions so
- //its the far more standard lon,lat instead of lat,lon
- decoded.push([ll[1] * inv,ll[0] * inv]);
- }
- //hand back the list of coordinates
- return decoded;
- };
-
- var geoJsonToTrace = function (geojson, options) {
- //convert to trace format
- var trace = {
- 'costing': options.serviceUrlParams.mode,
- 'search_radius': parseFloat(options.serviceUrlParams.search_radius),
- 'shape_match': 'map_snap',
- 'filters':{
- 'attributes':['edge.way_id','edge.begin_shape_index','edge.end_shape_index','matched.point','matched.edge_index','matched.begin_route_discontinuity','matched.end_route_discontinuity','shape'],
- 'action':'include'
- }
- };
- //dont bother with non numbers
- if(!isFinite(trace.search_radius))
- delete trace['search_radius'];
- //clean up url
- delete options.serviceUrlParams['mode'];
- delete options.serviceUrlParams['search_radius'];
- //encode the coordinates to send
- trace['encoded_polyline'] = encode(geojson['coordinates']);
- return trace;
- };
-
- var attributesToGeoJson = function (attributes) {
- //decode the shape
- var shape = decode(attributes.shape);
- //turn the continuous runs of shape indicies into multilinestrings
- var multilines = [];
- var matched = [];
- var start = 0;
- for(var p of attributes.matched_points) {
- //keep every matched point
- matched.push([p.lon, p.lat]);
- //starts a discontinuity so make a linestring up to and including this point
- if(p.begin_route_discontinuity)
- multilines.push(shape.slice(start, attributes.edges[p.edge_index].end_shape_index + 1));
- //ends a discontinuity so make a linestring start here
- else if(p.end_route_discontinuity)
- start = attributes.edges[p.edge_index].begin_shape_index;
- }
- //get the last bit
- if(start < shape.length)
- multilines.push(shape.slice(start, shape.length));
- //hand it back as geojson
- return {
- "type": "Feature",
- "geometry": {
- "type": "MultiLineString",
- "coordinates": multilines
- },
- "properties": {
- "matched_coordinates": matched
- }
- };
- };
-
- L.MapMatching = L.Control.extend({
- options: {
- serviceUrl: 'http://valhalla.mapzen.com/trace_attributes',
- serviceUrlParams: {},
- traceBuilder: defaultTraceBuilder,
- matchLineBuilder: defaultMatchLineBuilder,
- matchPointBuilder: defaultMatchPointBuilder,
- matchRouteBuilder: defaultMatchRouteBuilder
- },
-
- initialize: function (trace, options) {
- this.trace = geoJsonToTrace(trace, options);
- L.Util.setOptions(this, options);
- },
-
- onAdd: function (map) {
- if (this.options.externalTraceLayer) {
- this.traceLayer = this.options.externalTraceLayer;
- } else {
- this.traceLayer = this.options.traceBuilder.call(this, this.trace);
- if (this.traceLayer) {
- this.traceLayer.addTo(map);
- }
- }
- this.match(map);
- return L.DomUtil.create('div', 'my-custom-control');
- },
-
- match: function (map) {
- this.onRemove(map);
-
- var control = this, geoTrace = this.trace;
-
- var urlParams = $.param(this.options.serviceUrlParams),
- url = this.options.serviceUrl + (urlParams? ('?' + urlParams) : ''),
- requestBody = JSON.stringify(geoTrace);
-
- return $.post(url, requestBody, function (resp) {
- if (control._map !== map) {
- return;
- }
-
- var geoResults = attributesToGeoJson(resp);
-
- control.matchPointLayer = control.options.matchPointBuilder.call(control, geoResults);
- if (control.matchPointLayer) {
- control.matchPointLayer.addTo(map);
- }
-
- control.matchLineLayer = control.options.matchLineBuilder.call(control, geoTrace, geoResults);
- if (control.matchLineLayer) {
- control.matchLineLayer.addTo(map);
- }
-
- control.matchRouteLayer = control.options.matchRouteBuilder.call(control, geoResults);
- if (control.matchRouteLayer) {
- control.matchRouteLayer.addTo(map);
- }
- }, 'json');
- },
-
- onRemove: function (map) {
- if (this.traceLayer)
- map.removeLayer(this.traceLayer);
- if (this.matchPointLayer)
- map.removeLayer(this.matchPointLayer);
- if (this.matchLineLayer)
- map.removeLayer(this.matchLineLayer);
- if (this.matchRouteLayer)
- map.removeLayer(this.matchRouteLayer);
- }
- });
-
- L.mapMatching = function(trace, options) {
- return new L.MapMatching(trace, options);
- };
-})();
diff --git a/map_matching/main.js b/map_matching/main.js
new file mode 100644
index 0000000..5eeacd7
--- /dev/null
+++ b/map_matching/main.js
@@ -0,0 +1,169 @@
+const serviceUrl = 'https://valhalla1.openstreetmap.de/trace_attributes'
+const currentLocation = { lng: -122.424058, lat: 37.805689 }
+let mode = 'auto'
+let map
+let draw
+let geojsonFeatureCollection = { type: 'FeatureCollection', features: [] }
+
+function setMode (m) {
+ mode = arguments[0]
+ document.querySelectorAll('.vehicleBox button').forEach(button => {
+ button.classList.toggle('active', button.getAttribute('name') === m)
+ })
+ geojsonMatch()
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ map = new maplibregl.Map({
+ style: 'https://tiles.openfreemap.org/styles/positron',
+ center: currentLocation,
+ zoom: 15.7,
+ container: 'map'
+ })
+
+ draw = new MapboxDraw({
+ displayControlsDefault: false,
+ defaultMode: 'draw_line_string'
+ })
+ map.addControl(draw, 'top-left')
+ map.on('draw.create', function (e) {
+ document.getElementById('geojson').value = JSON.stringify(e.features[0].geometry)
+ geojsonMatch()
+ })
+
+ map.once('styledata', () => {
+ map.addSource('geojsonSource', {
+ type: 'geojson',
+ data: geojsonFeatureCollection
+ })
+
+ map.addLayer({
+ id: 'geojsonLayer',
+ type: 'line',
+ source: 'geojsonSource',
+ layout: {},
+ paint: {
+ 'line-color': ['get', 'color'],
+ 'line-width': 4
+ }
+ })
+ })
+})
+
+function geojsonMatch () {
+ if (document.getElementById('geojson').value === '') { return }
+
+ mapMatcher.geojson = JSON.parse(document.getElementById('geojson').value)
+ mapMatcher.mode = mode
+ mapMatcher.search_radius = document.getElementById('radius').value
+ mapMatcher.serviceUrl = serviceUrl
+ mapMatcher.matchedCoordinates = []
+ mapMatcher.match()
+ draw.deleteAll()
+ draw.changeMode('draw_line_string')
+}
+
+const mapMatcher = {
+ match: function () {
+ this.removeLayers()
+
+ geojsonFeatureCollection.features.push({
+ type: 'Feature',
+ geometry: this.geojson,
+ properties: { color: '#ff3400' }
+ })
+ map.getSource('geojsonSource').setData(geojsonFeatureCollection)
+
+ const bounds = turf.bbox(this.geojson)
+ map.fitBounds(bounds, { padding: 20 })
+
+ const _this = this
+
+ fetch(serviceUrl, {
+ method: 'POST',
+ body: JSON.stringify(this.createJsonPostParams())
+ }).then(response => response.json()).then(resp => {
+ _this.matchingResponse = resp
+ _this.setMatchResult()
+ _this.updateGeojsonSource()
+ })
+ },
+
+ removeLayers: function () {
+ geojsonFeatureCollection = { type: 'FeatureCollection', features: [] }
+ map.getSource('geojsonSource').setData(geojsonFeatureCollection)
+ },
+
+ updateGeojsonSource: function () {
+ const _this = this
+ const lines = this.geojson.coordinates.map(function (coord, idx) {
+ if (_this.matchedCoordinates[idx]) {
+ return [coord, _this.matchedCoordinates[idx]]
+ }
+ return null
+ }).filter(function (coord) { return coord !== null })
+
+ const matchingPointsLineFeature = turf.lineStrings(lines, { color: '#0000ff' })
+
+ geojsonFeatureCollection.features = geojsonFeatureCollection.features.concat(matchingPointsLineFeature.features)
+ geojsonFeatureCollection.features = geojsonFeatureCollection.features.concat(this.matchResult.features)
+
+ map.getSource('geojsonSource').setData(geojsonFeatureCollection)
+ },
+
+ createJsonPostParams: function () {
+ return {
+ encoded_polyline: polyline.fromGeoJSON(this.geojson, 6),
+ costing: this.mode,
+ shape_match: 'map_snap',
+ trace_options: {
+ search_radius: parseFloat(this.search_radius),
+ turn_penalty_factor: 300
+ },
+ filters: {
+ attributes: [
+ 'edge.names',
+ 'edge.way_id',
+ 'edge.begin_shape_index',
+ 'edge.end_shape_index',
+ 'matched.point',
+ 'matched.edge_index',
+ 'matched.begin_route_discontinuity',
+ 'matched.end_route_discontinuity',
+ 'shape'
+ ],
+ action: 'include'
+ }
+ }
+ },
+
+ setMatchResult: function () {
+ // decode the shape
+ const shape = polyline.decode(this.matchingResponse.shape, 6)
+ // turn the continuous runs of shape indicies into multilinestrings
+ let multilines = []
+ this.matchedCoordinates = []
+ let start = 0
+ for (const p of this.matchingResponse.matched_points) {
+ // keep every matched point
+ this.matchedCoordinates.push([p.lon, p.lat])
+ if (p.begin_route_discontinuity) {
+ // starts a discontinuity so make a linestring up to and including this point
+ multilines.push(shape.slice(start, this.matchingResponse.edges[p.edge_index].end_shape_index + 1))
+ } else if (p.end_route_discontinuity) {
+ // ends a discontinuity so make a linestring start here
+ start = this.matchingResponse.edges[p.edge_index].begin_shape_index
+ }
+ }
+ // get the last bit
+ if (start < shape.length) {
+ multilines.push(shape.slice(start, shape.length))
+ }
+ // reverse the coordinates because polyline decodes to [lat, lon], but geojson is [lon, lat]
+ multilines = multilines.map(function (line) {
+ return line.map((coord) => coord.reverse())
+ })
+ // hand it back as geojson
+ this.matchResult = turf.lineStrings(multilines, { color: '#00ff00' })
+ }
+}
\ No newline at end of file
diff --git a/map_matching/style.css b/map_matching/style.css
new file mode 100644
index 0000000..21093c7
--- /dev/null
+++ b/map_matching/style.css
@@ -0,0 +1,70 @@
+html {
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ font: 13px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
+ width: 100%;
+ height: 100%;
+ color: #383a3a;
+ min-height: 600px;
+ padding: 0;
+ margin: 0;
+}
+
+.container {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ width: 100%;
+}
+
+#controls {
+ width: 500px;
+ background-color: #eee;
+ padding: 20px;
+ overflow-y: auto;
+ text-align: center;
+}
+
+#map-container {
+ height: 100%;
+ flex-grow: 1;
+}
+
+#map {
+ width: 100%;
+ height: 100%;
+}
+
+#geojson {
+ width: 100%;
+ height: 150px;
+}
+
+.vehicleBox .vehicle {
+ width: 50px;
+ height: 41px;
+ background-color: transparent;
+ margin-right: 5px;
+ background-image: url('../matrix/images/modes.svg');
+ background-size: 150px 41px;
+ background-repeat: no-repeat;
+}
+
+.vehicleBox .vehicle.active {
+ color: #68c175;
+ border: 2px solid #68c175;
+}
+
+.bike {
+ background-position: -50px 0;
+}
+
+.pedestrian {
+ background-position: -100px 0;
+}
\ No newline at end of file