summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Smedegaard <dr@jones.dk>2018-05-14 00:08:20 +0200
committerJonas Smedegaard <dr@jones.dk>2018-05-14 00:08:20 +0200
commit16a831488d5a4071f3433ca97cde13ec62136631 (patch)
tree71bcd1c61f6d431a6ce91571be080f453849c58d
Initial draft.
-rw-r--r--.gitignore1
-rw-r--r--build/js/tours.js18
-rw-r--r--etc/build.js45
l---------src/css/font-awesome.css1
l---------src/css/leaflet/MarkerCluster.Default.css1
l---------src/css/leaflet/MarkerCluster.css1
-rw-r--r--src/css/leaflet/extra-markers.css236
l---------src/css/leaflet/leaflet.css1
-rw-r--r--src/css/map.css23
-rw-r--r--src/img/leaflet.extra-markers/markers_default.pngbin0 -> 119805 bytes
-rw-r--r--src/img/leaflet.extra-markers/markers_default@2x.pngbin0 -> 254280 bytes
-rw-r--r--src/img/leaflet.extra-markers/markers_shadow.pngbin0 -> 535 bytes
-rw-r--r--src/img/leaflet.extra-markers/markers_shadow@2x.pngbin0 -> 1469 bytes
-rw-r--r--src/js/app/boundary.js23
-rw-r--r--src/js/app/mapfactory.js28
-rw-r--r--src/js/app/places.js36
l---------src/js/lib/images1
-rw-r--r--src/js/lib/leaflet.extra-markers.js106
l---------src/js/lib/leaflet.js1
l---------src/js/lib/leaflet.markercluster.js1
l---------src/js/lib/require.js1
-rw-r--r--src/js/lib/require/json.js84
l---------src/js/lib/require/text.js1
-rw-r--r--src/js/slippymap.js14
-rw-r--r--src/js/tours.js28
25 files changed, 651 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a007fea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+build/*
diff --git a/build/js/tours.js b/build/js/tours.js
new file mode 100644
index 0000000..820ea99
--- /dev/null
+++ b/build/js/tours.js
@@ -0,0 +1,18 @@
+/**
+ * @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/requirejs/text for details
+ */
+
+/** @license
+ * RequireJS plugin for loading JSON files
+ * - depends on Text plugin and it was HEAVILY "inspired" by it as well.
+ * Author: Miller Medeiros
+ * Version: 0.4.0 (2014/04/10)
+ * Released under the MIT license
+ *
+ * Patched (2013/10/10):
+ * - supports JS-like comments which are beginning from /* or //
+ */
+
+requirejs(["./slippymap"],function(e){var n="../../";requirejs.config({baseUrl:n+"js/lib"}),requirejs(["app/mapfactory"],function(e){L.Icon.Default.imagePath=n+"img/leaflet/";var r=e("content",[[52.1381,8.39802],[52.04,8.18859]]);requirejs(["app/boundary","json!data/copenhagen.json"],function(e,n){r.addLayer(e(n)),r.layers.addOverlay(e(n),"Regionsgrænse")}),requirejs(["app/places","json!data/tours.json"],function(e,n,t){r.addLayer(e(n)),t(r)})})}),define("../tours",function(){}),define("text",["module"],function(e){"use strict";var n,r,t,o,i,a=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],s=/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,u=/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,c="undefined"!=typeof location&&location.href,l=c&&location.protocol&&location.protocol.replace(/\:/,""),f=c&&location.hostname,p=c&&(location.port||void 0),d={},v=e.config&&e.config()||{};return n={version:"2.0.12",strip:function(e){if(e){e=e.replace(s,"");var n=e.match(u);n&&(e=n[1])}else e="";return e},jsEscape:function(e){return e.replace(/(['\\])/g,"\\$1").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r").replace(/[\u2028]/g,"\\u2028").replace(/[\u2029]/g,"\\u2029")},createXhr:v.createXhr||function(){var e,n,r;if("undefined"!=typeof XMLHttpRequest)return new XMLHttpRequest;if("undefined"!=typeof ActiveXObject)for(n=0;n<3;n+=1){r=a[n];try{e=new ActiveXObject(r)}catch(e){}if(e){a=[r];break}}return e},parseName:function(e){var n,r,t,o=!1,i=e.indexOf("."),a=0===e.indexOf("./")||0===e.indexOf("../");return i!==-1&&(!a||i>1)?(n=e.substring(0,i),r=e.substring(i+1,e.length)):n=e,t=r||n,i=t.indexOf("!"),i!==-1&&(o="strip"===t.substring(i+1),t=t.substring(0,i),r?r=t:n=t),{moduleName:n,ext:r,strip:o}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,useXhr:function(e,r,t,o){var i,a,s,u=n.xdRegExp.exec(e);return!u||(i=u[2],a=u[3],a=a.split(":"),s=a[1],a=a[0],!(i&&i!==r||a&&a.toLowerCase()!==t.toLowerCase()||(s||a)&&s!==o))},finishLoad:function(e,r,t,o){t=r?n.strip(t):t,v.isBuild&&(d[e]=t),o(t)},load:function(e,r,t,o){if(o&&o.isBuild&&!o.inlineText)return void t();v.isBuild=o&&o.isBuild;var i=n.parseName(e),a=i.moduleName+(i.ext?"."+i.ext:""),s=r.toUrl(a),u=v.useXhr||n.useXhr;return 0===s.indexOf("empty:")?void t():void(!c||u(s,l,f,p)?n.get(s,function(r){n.finishLoad(e,i.strip,r,t)},function(e){t.error&&t.error(e)}):r([a],function(e){n.finishLoad(i.moduleName+"."+i.ext,i.strip,e,t)}))},write:function(e,r,t,o){if(d.hasOwnProperty(r)){var i=n.jsEscape(d[r]);t.asModule(e+"!"+r,"define(function () { return '"+i+"';});\n")}},writeFile:function(e,r,t,o,i){var a=n.parseName(r),s=a.ext?"."+a.ext:"",u=a.moduleName+s,c=t.toUrl(a.moduleName+s)+".js";n.load(u,t,function(r){var t=function(e){return o(c,e)};t.asModule=function(e,n){return o.asModule(e,c,n)},n.write(e,u,t,i)},i)}},"node"===v.env||!v.env&&"undefined"!=typeof process&&process.versions&&process.versions.node&&!process.versions["node-webkit"]?(r=require.nodeRequire("fs"),n.get=function(e,n,t){try{var o=r.readFileSync(e,"utf8");0===o.indexOf("\ufeff")&&(o=o.substring(1)),n(o)}catch(e){t&&t(e)}}):"xhr"===v.env||!v.env&&n.createXhr()?n.get=function(e,r,t,o){var i,a=n.createXhr();if(a.open("GET",e,!0),o)for(i in o)o.hasOwnProperty(i)&&a.setRequestHeader(i.toLowerCase(),o[i]);v.onXhr&&v.onXhr(a,e),a.onreadystatechange=function(n){var o,i;4===a.readyState&&(o=a.status||0,o>399&&o<600?(i=new Error(e+" HTTP status: "+o),i.xhr=a,t&&t(i)):r(a.responseText),v.onXhrComplete&&v.onXhrComplete(a,e))},a.send(null)}:"rhino"===v.env||!v.env&&"undefined"!=typeof Packages&&"undefined"!=typeof java?n.get=function(e,n){var r,t,o="utf-8",i=new java.io.File(e),a=java.lang.System.getProperty("line.separator"),s=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(i),o)),u="";try{for(r=new java.lang.StringBuffer,t=s.readLine(),t&&t.length()&&65279===t.charAt(0)&&(t=t.substring(1)),null!==t&&r.append(t);null!==(t=s.readLine());)r.append(a),r.append(t);u=String(r.toString())}finally{s.close()}n(u)}:("xpconnect"===v.env||!v.env&&"undefined"!=typeof Components&&Components.classes&&Components.interfaces)&&(t=Components.classes,o=Components.interfaces,Components.utils.import("resource://gre/modules/FileUtils.jsm"),i="@mozilla.org/windows-registry-key;1"in t,n.get=function(e,n){var r,a,s,u={};i&&(e=e.replace(/\//g,"\\")),s=new FileUtils.File(e);try{r=t["@mozilla.org/network/file-input-stream;1"].createInstance(o.nsIFileInputStream),r.init(s,1,0,!1),a=t["@mozilla.org/intl/converter-input-stream;1"].createInstance(o.nsIConverterInputStream),a.init(r,"utf-8",r.available(),o.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER),a.readString(r.available(),u),a.close(),r.close(),n(u.value)}catch(e){throw new Error((s&&s.path||"")+": "+e)}}),n}),define("json",["text"],function(text){function cacheBust(e){return e=e.replace(CACHE_BUST_FLAG,""),e+=e.indexOf("?")<0?"?":"&",e+CACHE_BUST_QUERY_PARAM+"="+Math.round(2147483647*Math.random())}var CACHE_BUST_QUERY_PARAM="bust",CACHE_BUST_FLAG="!bust",jsonParse="undefined"!=typeof JSON&&"function"==typeof JSON.parse?JSON.parse:function(val){return eval("("+val+")")},PROTECTION_PREFIX=/^\)\]\}',?\n/,buildMap={};return{load:function(e,n,r,t){e=e.replace(new RegExp("^[^?]*"),function(e){return".json"===e.substr(-5)?e:e+".json"});var o=n.toUrl(e);!t.isBuild||t.inlineJSON!==!1&&e.indexOf(CACHE_BUST_QUERY_PARAM+"=")===-1?0===o.indexOf("empty:")?r(null):text.get(o,function(n){var o=(""+n).replace(PROTECTION_PREFIX,"");o=o.replace(/\/\*.+?\*\/|\/\/[^\n\r]*/g,"");var i=null;try{i=jsonParse(o),t.isBuild&&(buildMap[e]=i),r(i)}catch(e){r.error(e)}},r.error,{accept:"application/json"}):r(null)},normalize:function(e,n){return e.indexOf(CACHE_BUST_FLAG)!==-1&&(e=cacheBust(e)),n(e)},write:function(e,n,r){if(n in buildMap){var t=buildMap[n];r('define("'+e+"!"+n+'", function () { return '+(t?JSON.stringify(t):t)+"; });\n")}}}}),define("json!data/copenhagen.json",function(){return{}}),define("json!data/tours.json",function(){return{}}); \ No newline at end of file
diff --git a/etc/build.js b/etc/build.js
new file mode 100644
index 0000000..3ecf8d0
--- /dev/null
+++ b/etc/build.js
@@ -0,0 +1,45 @@
+{
+ appDir: '../src',
+ mainConfigFile: '../src/js/slippymap.js',
+ dir: '../build',
+ modules: [
+ //First set up the common build layer.
+ {
+ //module names are relative to baseUrl
+ name: '../slippymap',
+ //List common dependencies here. Only need to list
+ //top level dependencies, "include" will find
+ //nested dependencies.
+ include: [
+ 'leaflet',
+ 'leaflet.extra-markers',
+ 'leaflet.markercluster',
+ 'app/mapfactory',
+ 'app/boundary',
+ 'app/places'
+ ]
+ },
+
+ //Now set up a build layer for each page, but exclude
+ //the common one. "exclude" will exclude
+ //the nested, built dependencies from "slippymap". Any
+ //"exclude" that includes built modules should be
+ //listed before the build layer that wants to exclude it.
+ //"include" the appropriate "app/main*" module since by default
+ //it will not get added to the build since it is loaded by a nested
+ //requirejs in the page*.js files.
+ {
+ name: '../tours',
+ include: [
+ 'json!data/copenhagen.json',
+ 'app/places',
+ 'json!data/tours.json'
+ ],
+ exclude: ['../slippymap']
+ }
+
+ ],
+ optimize: "uglify2",
+ optimizeCss: "standard.keepLines",
+ removeCombined: true,
+}
diff --git a/src/css/font-awesome.css b/src/css/font-awesome.css
new file mode 120000
index 0000000..faba91f
--- /dev/null
+++ b/src/css/font-awesome.css
@@ -0,0 +1 @@
+/usr/share/fonts-font-awesome/css/font-awesome.css \ No newline at end of file
diff --git a/src/css/leaflet/MarkerCluster.Default.css b/src/css/leaflet/MarkerCluster.Default.css
new file mode 120000
index 0000000..2cf500e
--- /dev/null
+++ b/src/css/leaflet/MarkerCluster.Default.css
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/MarkerCluster.Default.css \ No newline at end of file
diff --git a/src/css/leaflet/MarkerCluster.css b/src/css/leaflet/MarkerCluster.css
new file mode 120000
index 0000000..a791781
--- /dev/null
+++ b/src/css/leaflet/MarkerCluster.css
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/MarkerCluster.css \ No newline at end of file
diff --git a/src/css/leaflet/extra-markers.css b/src/css/leaflet/extra-markers.css
new file mode 100644
index 0000000..735dd87
--- /dev/null
+++ b/src/css/leaflet/extra-markers.css
@@ -0,0 +1,236 @@
+/* Marker setup */
+.extra-marker {
+ background: url("../../img/leaflet.extra-markers/markers_default.png") no-repeat 0 0;
+ width: 35px;
+ height: 46px;
+ position: absolute;
+ left: 0;
+ top: 0;
+ display: block;
+ text-align: center;
+}
+
+.extra-marker-svg {
+ background: none;
+}
+
+.extra-marker svg {
+ position: absolute;
+ top: 2px;
+ left: 3px;
+ width: 30px;
+ stroke-width:1;
+}
+
+.extra-marker-shadow {
+ background: url("../../img/leaflet.extra-markers/markers_shadow.png") no-repeat 0 0;
+ width: 36px;
+ height: 16px;
+}
+/* Retina displays */
+@media (min--moz-device-pixel-ratio: 1.5), (-o-min-device-pixel-ratio: 3/2), (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 1.5dppx) {
+ .extra-marker {
+ background-image: url("../../img/leaflet.extra-markers/markers_default@2x.png");
+ background-size: 540px 184px;
+ }
+ .extra-marker-shadow {
+ background-image: url("../../img/leaflet.extra-markers/markers_shadow@2x.png");
+ background-size: 35px 16px;
+ }
+}
+/* Icons */
+.extra-marker i {
+ color: #fff;
+ margin-top: 10px;
+ display: inline-block;
+ font-size: 14px;
+}
+/* Semantic UI Fix */
+.extra-marker i.icon {
+ margin-right: 0;
+ opacity: 1;
+}
+/* Sprites setup */
+.extra-marker-circle-red {
+ background-position: 0 0;
+}
+.extra-marker-circle-orange-dark {
+ background-position: -36px 0;
+}
+.extra-marker-circle-orange {
+ background-position: -72px 0;
+}
+.extra-marker-circle-yellow {
+ background-position: -108px 0;
+}
+.extra-marker-circle-blue-dark {
+ background-position: -144px 0;
+}
+.extra-marker-circle-blue {
+ background-position: -180px 0;
+}
+.extra-marker-circle-cyan {
+ background-position: -216px 0;
+}
+.extra-marker-circle-purple {
+ background-position: -252px 0;
+}
+.extra-marker-circle-violet {
+ background-position: -288px 0;
+}
+.extra-marker-circle-pink {
+ background-position: -324px 0;
+}
+.extra-marker-circle-green-dark {
+ background-position: -360px 0;
+}
+.extra-marker-circle-green {
+ background-position: -396px 0;
+}
+.extra-marker-circle-green-light {
+ background-position: -432px 0;
+}
+.extra-marker-circle-black {
+ background-position: -468px 0;
+}
+.extra-marker-circle-white {
+ background-position: -504px 0;
+}
+.extra-marker-square-red {
+ background-position: 0 -46px;
+}
+.extra-marker-square-orange-dark {
+ background-position: -36px -46px;
+}
+.extra-marker-square-orange {
+ background-position: -72px -46px;
+}
+.extra-marker-square-yellow {
+ background-position: -108px -46px;
+}
+.extra-marker-square-blue-dark {
+ background-position: -144px -46px;
+}
+.extra-marker-square-blue {
+ background-position: -180px -46px;
+}
+.extra-marker-square-cyan {
+ background-position: -216px -46px;
+}
+.extra-marker-square-purple {
+ background-position: -252px -46px;
+}
+.extra-marker-square-violet {
+ background-position: -288px -46px;
+}
+.extra-marker-square-pink {
+ background-position: -324px -46px;
+}
+.extra-marker-square-green-dark {
+ background-position: -360px -46px;
+}
+.extra-marker-square-green {
+ background-position: -396px -46px;
+}
+.extra-marker-square-green-light {
+ background-position: -432px -46px;
+}
+.extra-marker-square-black {
+ background-position: -468px -46px;
+}
+.extra-marker-square-white {
+ background-position: -504px -46px;
+}
+.extra-marker-star-red {
+ background-position: 0 -92px;
+}
+.extra-marker-star-orange-dark {
+ background-position: -36px -92px;
+}
+.extra-marker-star-orange {
+ background-position: -72px -92px;
+}
+.extra-marker-star-yellow {
+ background-position: -108px -92px;
+}
+.extra-marker-star-blue-dark {
+ background-position: -144px -92px;
+}
+.extra-marker-star-blue {
+ background-position: -180px -92px;
+}
+.extra-marker-star-cyan {
+ background-position: -216px -92px;
+}
+.extra-marker-star-purple {
+ background-position: -252px -92px;
+}
+.extra-marker-star-violet {
+ background-position: -288px -92px;
+}
+.extra-marker-star-pink {
+ background-position: -324px -92px;
+}
+.extra-marker-star-green-dark {
+ background-position: -360px -92px;
+}
+.extra-marker-star-green {
+ background-position: -396px -92px;
+}
+.extra-marker-star-green-light {
+ background-position: -432px -92px;
+}
+.extra-marker-star-black {
+ background-position: -468px -92px;
+}
+.extra-marker-star-white {
+ background-position: -504px -92px;
+}
+.extra-marker-penta-red {
+ background-position: 0 -138px;
+}
+.extra-marker-penta-orange-dark {
+ background-position: -36px -138px;
+}
+.extra-marker-penta-orange {
+ background-position: -72px -138px;
+}
+.extra-marker-penta-yellow {
+ background-position: -108px -138px;
+}
+.extra-marker-penta-blue-dark {
+ background-position: -144px -138px;
+}
+.extra-marker-penta-blue {
+ background-position: -180px -138px;
+}
+.extra-marker-penta-cyan {
+ background-position: -216px -138px;
+}
+.extra-marker-penta-purple {
+ background-position: -252px -138px;
+}
+.extra-marker-penta-violet {
+ background-position: -288px -138px;
+}
+.extra-marker-penta-pink {
+ background-position: -324px -138px;
+}
+.extra-marker-penta-green-dark {
+ background-position: -360px -138px;
+}
+.extra-marker-penta-green {
+ background-position: -396px -138px;
+}
+.extra-marker-penta-green-light {
+ background-position: -432px -138px;
+}
+.extra-marker-penta-black {
+ background-position: -468px -138px;
+}
+.extra-marker-penta-white {
+ background-position: -504px -138px;
+}
+.extra-marker .fa-number:before {
+ content: attr(number);
+}
diff --git a/src/css/leaflet/leaflet.css b/src/css/leaflet/leaflet.css
new file mode 120000
index 0000000..40a1f03
--- /dev/null
+++ b/src/css/leaflet/leaflet.css
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/leaflet.css \ No newline at end of file
diff --git a/src/css/map.css b/src/css/map.css
new file mode 100644
index 0000000..626ff84
--- /dev/null
+++ b/src/css/map.css
@@ -0,0 +1,23 @@
+.leaflet-control-layers-toggle {
+ background-image: url(../img/leaflet/layers.png);
+}
+
+.leaflet-retina .leaflet-control-layers-toggle {
+ background-image: url(../img/leaflet/layers-2x.png);
+}
+
+#content {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+}
+
+.leaflet-control-scale {
+ text-align: center;
+}
+
+.info {
+ background-color: white;
+}
diff --git a/src/img/leaflet.extra-markers/markers_default.png b/src/img/leaflet.extra-markers/markers_default.png
new file mode 100644
index 0000000..2c81d15
--- /dev/null
+++ b/src/img/leaflet.extra-markers/markers_default.png
Binary files differ
diff --git a/src/img/leaflet.extra-markers/markers_default@2x.png b/src/img/leaflet.extra-markers/markers_default@2x.png
new file mode 100644
index 0000000..35ff61b
--- /dev/null
+++ b/src/img/leaflet.extra-markers/markers_default@2x.png
Binary files differ
diff --git a/src/img/leaflet.extra-markers/markers_shadow.png b/src/img/leaflet.extra-markers/markers_shadow.png
new file mode 100644
index 0000000..33cf955
--- /dev/null
+++ b/src/img/leaflet.extra-markers/markers_shadow.png
Binary files differ
diff --git a/src/img/leaflet.extra-markers/markers_shadow@2x.png b/src/img/leaflet.extra-markers/markers_shadow@2x.png
new file mode 100644
index 0000000..1116503
--- /dev/null
+++ b/src/img/leaflet.extra-markers/markers_shadow@2x.png
Binary files differ
diff --git a/src/js/app/boundary.js b/src/js/app/boundary.js
new file mode 100644
index 0000000..f7ebd06
--- /dev/null
+++ b/src/js/app/boundary.js
@@ -0,0 +1,23 @@
+define(['leaflet'], function(L) {
+
+ var boundaries = L.layerGroup();
+
+ // GeoJSON feature styling and grouping
+ function returnMarker(feature, latlng) {
+ return L.marker(latlng);
+ };
+
+ var boundary = L.geoJson([], {
+ pointToLayer: returnMarker,
+ style: {
+ "color": "#ff0080",
+ "fillOpacity": 0
+ }
+ });
+
+ return function(data) {
+ boundary.addData(data);
+ boundaries.addLayer(boundary);
+ return boundaries;
+ };
+});
diff --git a/src/js/app/mapfactory.js b/src/js/app/mapfactory.js
new file mode 100644
index 0000000..4802f50
--- /dev/null
+++ b/src/js/app/mapfactory.js
@@ -0,0 +1,28 @@
+define(['leaflet'], function(L) {
+ // base config
+ var attribOSM = '&copy; <a href="https://www.openstreetmap.org/">OpenStreetMap-bidragydere</a>';
+ var licenseCcBySa2 = 'under en <a href="https://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Kreditering-DelPåSammeVilkår</a> licens.';
+ var licenseODbL ='under licensen <a href="https://opendatacommons.org/licenses/odbl/1.0/">ODbL 1.0</a>';
+ var TileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ attribution: attribOSM + ', kartografi ' + licenseCcBySa2 + ', kortdata ' + licenseODbL
+ }),
+ scale = L.control.scale({
+ imperial: false
+ });
+
+ return function(id, bounds) {
+ var map = L.map(id, {
+ layers: [TileLayer]
+ })
+ if (bounds) {
+ map.fitBounds(L.latLngBounds(bounds));
+ } else {
+ map.fitWorld().zoomIn();
+ }
+ map.attributionControl.setPrefix(false);
+
+ scale.addTo(map);
+
+ return map;
+ };
+});
diff --git a/src/js/app/places.js b/src/js/app/places.js
new file mode 100644
index 0000000..7ae5008
--- /dev/null
+++ b/src/js/app/places.js
@@ -0,0 +1,36 @@
+define([
+ 'leaflet',
+ 'leaflet.markercluster'
+], function(L) {
+
+ // GeoJSON feature grouping
+ function returnMarker(feature, latlng) {
+ var marker = new L.CircleMarker(latlng,{
+ color: 'none',
+ fillColor: 'rgba(110, 204, 57, 0.6)',
+ fillOpacity: '1',
+ });
+ // bindTooltip was introduced in LeafletJS 1.0.
+ try {
+ marker.bindTooltip(
+ feature.properties.name
+ );
+ } catch (e) {
+ if (console) {
+ console.warn('tooltip skipped (using an old Leaflet?)');
+ }
+ };
+ return marker;
+ };
+
+ var place = L.geoJson([], {
+ pointToLayer: returnMarker
+ });
+
+ return function(data) {
+ place.addData(data);
+ return L.markerClusterGroup({
+ maxClusterRadius: 10
+ }).addLayer(place);
+ };
+});
diff --git a/src/js/lib/images b/src/js/lib/images
new file mode 120000
index 0000000..a962773
--- /dev/null
+++ b/src/js/lib/images
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/images \ No newline at end of file
diff --git a/src/js/lib/leaflet.extra-markers.js b/src/js/lib/leaflet.extra-markers.js
new file mode 100644
index 0000000..30f2b97
--- /dev/null
+++ b/src/js/lib/leaflet.extra-markers.js
@@ -0,0 +1,106 @@
+(function(window, document, undefined) {
+ "use strict";
+ L.ExtraMarkers = {};
+ L.ExtraMarkers.version = "1.0.6";
+ L.ExtraMarkers.Icon = L.Icon.extend({
+ options: {
+ iconSize: [ 35, 45 ],
+ iconAnchor: [ 17, 42 ],
+ popupAnchor: [ 1, -32 ],
+ shadowAnchor: [ 10, 12 ],
+ shadowSize: [ 36, 16 ],
+ className: "",
+ prefix: "",
+ extraClasses: "",
+ shape: "circle",
+ icon: "",
+ innerHTML: "",
+ markerColor: "red",
+ svgBorderColor: "#fff",
+ svgOpacity: 1,
+ iconColor: "#fff",
+ number: "",
+ svg: false
+ },
+ initialize: function(options) {
+ options = L.Util.setOptions(this, options);
+ },
+ createIcon: function() {
+ var div = document.createElement("div"), options = this.options;
+ if (options.icon) {
+ div.innerHTML = this._createInner();
+ }
+ if (options.innerHTML) {
+ div.innerHTML = options.innerHTML;
+ }
+ if (options.bgPos) {
+ div.style.backgroundPosition = -options.bgPos.x + "px " + -options.bgPos.y + "px";
+ }
+ if(!options.svg) {
+ this._setIconStyles(div, options.shape + "-" + options.markerColor);
+ } else {
+ this._setIconStyles(div, "svg");
+ }
+ return div;
+ },
+ _createInner: function() {
+ var iconColorStyle = "", iconNumber = "", options = this.options;
+ if (options.iconColor) {
+ iconColorStyle = "style='color: " + options.iconColor + "' ";
+ }
+ if (options.number) {
+ iconNumber = "number='" + options.number + "' ";
+ }
+
+ if(options.svg) {
+ var svg = '<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.529271 95.44922" style="fill:'+options.markerColor+';stroke:'+options.svgBorderColor+';fill-opacity:'+options.svgOpacity+';" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><g transform="translate(-139.52 -173.21)"><path d="m174.28 173.21c-19.199 0.00035-34.764 15.355-34.764 34.297 0.007 6.7035 1.5591 12.813 5.7461 18.854l0.0234 0.0371 28.979 42.262 28.754-42.107c3.1982-5.8558 5.9163-11.544 6.0275-19.045-0.0001-18.942-15.565-34.298-34.766-34.297z"/></g></svg>';
+
+ if(options.shape == "square") {
+ svg = '<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69.457038 96.523441" style="fill:'+options.markerColor+';stroke:'+options.svgBorderColor+';fill-opacity:'+options.svgOpacity+';" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><g transform="translate(-545.27 -658.39)"><path d="m545.27 658.39v65.301h22.248l12.48 31.223 12.676-31.223h22.053v-65.301h-69.457z"/></g></svg>';
+ }
+
+ if(options.shape == "star") {
+ svg = '<svg style="top:0; fill:'+options.markerColor+';stroke:'+options.svgBorderColor+';fill-opacity:'+options.svgOpacity+';" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 77.690999 101.4702"><g transform="translate(-101.15 -162.97)"><g transform="matrix(1 0 0 1.0165 -65.712 -150.28)"><path d="m205.97 308.16-11.561 11.561h-16.346v16.346l-11.197 11.197 11.197 11.197v15.83h15.744l11.615 33.693 11.467-33.568 0.125-0.125h16.346v-16.346l11.197-11.197-11.197-11.197v-15.83h-15.83l-11.561-11.561z"/></g></g></svg>';
+ }
+
+ if(options.shape == "penta") {
+ svg = '<svg style="fill:'+options.markerColor+';stroke:'+options.svgBorderColor+';fill-opacity:'+options.svgOpacity+';" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 71.550368 96.362438" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/"><g transform="translate(-367.08 -289.9)"><path d="m367.08 322.5 17.236-32.604h36.151l18.164 32.25-35.665 64.112z"/></g></svg>';
+ }
+
+ return svg+"<i " + iconNumber + iconColorStyle + "class='" + options.extraClasses + " " + options.prefix + " " + options.icon + "'></i>";
+ }
+
+ return "<i " + iconNumber + iconColorStyle + "class='" + options.extraClasses + " " + options.prefix + " " + options.icon + "'></i>";
+ },
+ _setIconStyles: function(img, name) {
+ var options = this.options, size = L.point(options[name === "shadow" ? "shadowSize" : "iconSize"]), anchor, leafletName;
+ if (name === "shadow") {
+ anchor = L.point(options.shadowAnchor || options.iconAnchor);
+ leafletName = "shadow";
+ } else {
+ anchor = L.point(options.iconAnchor);
+ leafletName = "icon";
+ }
+ if (!anchor && size) {
+ anchor = size.divideBy(2, true);
+ }
+ img.className = "leaflet-marker-" + leafletName + " extra-marker extra-marker-" + name + " " + options.className;
+ if (anchor) {
+ img.style.marginLeft = -anchor.x + "px";
+ img.style.marginTop = -anchor.y + "px";
+ }
+ if (size) {
+ img.style.width = size.x + "px";
+ img.style.height = size.y + "px";
+ }
+ },
+ createShadow: function() {
+ var div = document.createElement("div");
+ this._setIconStyles(div, "shadow");
+ return div;
+ }
+ });
+ L.ExtraMarkers.icon = function(options) {
+ return new L.ExtraMarkers.Icon(options);
+ };
+})(window, document);
diff --git a/src/js/lib/leaflet.js b/src/js/lib/leaflet.js
new file mode 120000
index 0000000..f0df49d
--- /dev/null
+++ b/src/js/lib/leaflet.js
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/leaflet.js \ No newline at end of file
diff --git a/src/js/lib/leaflet.markercluster.js b/src/js/lib/leaflet.markercluster.js
new file mode 120000
index 0000000..881bcea
--- /dev/null
+++ b/src/js/lib/leaflet.markercluster.js
@@ -0,0 +1 @@
+/usr/share/javascript/leaflet/leaflet.markercluster.js \ No newline at end of file
diff --git a/src/js/lib/require.js b/src/js/lib/require.js
new file mode 120000
index 0000000..a2b8052
--- /dev/null
+++ b/src/js/lib/require.js
@@ -0,0 +1 @@
+/usr/share/javascript/requirejs/require.js \ No newline at end of file
diff --git a/src/js/lib/require/json.js b/src/js/lib/require/json.js
new file mode 100644
index 0000000..40e4da1
--- /dev/null
+++ b/src/js/lib/require/json.js
@@ -0,0 +1,84 @@
+/** @license
+ * RequireJS plugin for loading JSON files
+ * - depends on Text plugin and it was HEAVILY "inspired" by it as well.
+ * Author: Miller Medeiros
+ * Version: 0.4.0 (2014/04/10)
+ * Released under the MIT license
+ *
+ * Patched (2013/10/10):
+ * - supports JS-like comments which are beginning from /* or //
+ */
+define(['text'], function (text) {
+
+ var CACHE_BUST_QUERY_PARAM = 'bust',
+ CACHE_BUST_FLAG = '!bust',
+ jsonParse = (typeof JSON !== 'undefined' && typeof JSON.parse === 'function') ? JSON.parse : function (val) {
+ return eval('(' + val + ')'); //quick and dirty
+ },
+ PROTECTION_PREFIX = /^\)\]\}',?\n/,
+ buildMap = {};
+
+ function cacheBust(url) {
+ url = url.replace(CACHE_BUST_FLAG, '');
+ url += (url.indexOf('?') < 0) ? '?' : '&';
+ return url + CACHE_BUST_QUERY_PARAM + '=' + Math.round(2147483647 * Math.random());
+ }
+
+ //API
+ return {
+ load: function(name, req, onLoad, config) {
+ // Make sure file part of url ends with .json, add it if not
+ name = name.replace(new RegExp("^[^?]*"), function(base) {
+ return base.substr(-5) === ".json" ? base : base + ".json";
+ });
+ var url = req.toUrl(name);
+ if (config.isBuild && (config.inlineJSON === false || name.indexOf(CACHE_BUST_QUERY_PARAM + '=') !== -1)) {
+ //avoid inlining cache busted JSON or if inlineJSON:false
+ onLoad(null);
+ } else if (url.indexOf('empty:') === 0) {
+ //and don't inline files marked as empty: urls
+ onLoad(null);
+ } else {
+ text.get(url,
+ function (data) {
+ // Need to check if the JSON data has been formatted for the JSON array security vulnerability
+ var cleaned_data = ('' + data).replace(PROTECTION_PREFIX, '');
+ cleaned_data = cleaned_data.replace(/\/\*.+?\*\/|\/\/[^\n\r]*/g, '');
+ var parsed = null;
+ try {
+ parsed = jsonParse(cleaned_data);
+ if (config.isBuild) {
+ buildMap[name] = parsed;
+ }
+ onLoad(parsed);
+ } catch (e) {
+ onLoad.error(e);
+ //onLoad(null); -- should we really call onLoad???
+ }
+ },
+ onLoad.error, {
+ accept: 'application/json'
+ }
+ );
+ }
+ },
+
+ normalize: function (name, normalize) {
+ // used normalize to avoid caching references to a "cache busted" request
+ if (name.indexOf(CACHE_BUST_FLAG) !== -1) {
+ name = cacheBust(name);
+ }
+ // resolve any relative paths
+ return normalize(name);
+ },
+
+ // write method based on RequireJS official text plugin by James Burke
+ // https://github.com/jrburke/requirejs/blob/master/text.js
+ write: function (pluginName, moduleName, write) {
+ if (moduleName in buildMap) {
+ var content = buildMap[moduleName];
+ write('define("' + pluginName + '!' + moduleName + '", function () { return ' + (content ? JSON.stringify(content) : content) + '; });\n');
+ }
+ }
+ };
+});
diff --git a/src/js/lib/require/text.js b/src/js/lib/require/text.js
new file mode 120000
index 0000000..2b490b4
--- /dev/null
+++ b/src/js/lib/require/text.js
@@ -0,0 +1 @@
+/usr/share/javascript/requirejs/text.js \ No newline at end of file
diff --git a/src/js/slippymap.js b/src/js/slippymap.js
new file mode 100644
index 0000000..910ee9a
--- /dev/null
+++ b/src/js/slippymap.js
@@ -0,0 +1,14 @@
+// shared code common across pages
+requirejs.config({
+ baseUrl: 'js/lib',
+ paths: {
+ text: 'require/text',
+ json: 'require/json',
+ app: '../app',
+ data: '../../data'
+ },
+ shim: {
+ 'leaflet.extra-markers': ['leaflet'],
+ 'leaflet.markercluster': ['leaflet']
+ }
+});
diff --git a/src/js/tours.js b/src/js/tours.js
new file mode 100644
index 0000000..83e1cae
--- /dev/null
+++ b/src/js/tours.js
@@ -0,0 +1,28 @@
+//Load common code that includes config, then load the app logic for this page.
+requirejs(['./slippymap'], function(_foo) {
+ var depth = '../../';
+ requirejs.config({
+ baseUrl: depth + 'js/lib',
+ });
+ requirejs(['app/mapfactory'], function(mkmap) {
+ L.Icon.Default.imagePath = depth + 'img/leaflet/';
+ var map = mkmap('content', [
+ [52.1381, 8.39802],
+ [52.0400, 8.18859]
+ ]);
+ requirejs([
+ 'app/boundary',
+ 'json!data/copenhagen.json'
+ ], function(boundary, data) {
+ map.addLayer(boundary(data));
+ map.layers.addOverlay(boundary(data), 'Regionsgrænse');
+ });
+ requirejs([
+ 'app/places',
+ 'json!data/tours.json',
+ ], function(places, data, hook) {
+ map.addLayer(places(data));
+ hook(map);
+ });
+ });
+});