Browse Source

stuff from former http://drop.mro.name/megalithicireland2osm/

Marcus Rohrmoser 3 years ago
parent
commit
43fdf23a92

+ 60 - 0
MarkerCluster.Default.css

@@ -0,0 +1,60 @@
+.marker-cluster-small {
+	background-color: rgba(181, 226, 140, 0.6);
+	}
+.marker-cluster-small div {
+	background-color: rgba(110, 204, 57, 0.6);
+	}
+
+.marker-cluster-medium {
+	background-color: rgba(241, 211, 87, 0.6);
+	}
+.marker-cluster-medium div {
+	background-color: rgba(240, 194, 12, 0.6);
+	}
+
+.marker-cluster-large {
+	background-color: rgba(253, 156, 115, 0.6);
+	}
+.marker-cluster-large div {
+	background-color: rgba(241, 128, 23, 0.6);
+	}
+
+	/* IE 6-8 fallback colors */
+.leaflet-oldie .marker-cluster-small {
+	background-color: rgb(181, 226, 140);
+	}
+.leaflet-oldie .marker-cluster-small div {
+	background-color: rgb(110, 204, 57);
+	}
+
+.leaflet-oldie .marker-cluster-medium {
+	background-color: rgb(241, 211, 87);
+	}
+.leaflet-oldie .marker-cluster-medium div {
+	background-color: rgb(240, 194, 12);
+	}
+
+.leaflet-oldie .marker-cluster-large {
+	background-color: rgb(253, 156, 115);
+	}
+.leaflet-oldie .marker-cluster-large div {
+	background-color: rgb(241, 128, 23);
+}
+
+.marker-cluster {
+	background-clip: padding-box;
+	border-radius: 20px;
+	}
+.marker-cluster div {
+	width: 30px;
+	height: 30px;
+	margin-left: 5px;
+	margin-top: 5px;
+
+	text-align: center;
+	border-radius: 15px;
+	font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
+	}
+.marker-cluster span {
+	line-height: 30px;
+	}

+ 6 - 0
MarkerCluster.css

@@ -0,0 +1,6 @@
+.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
+	-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
+	-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
+	-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
+	transition: transform 0.3s ease-out, opacity 0.3s ease-in;
+	}

+ 440 - 0
gpx.js

@@ -0,0 +1,440 @@
+/**
+ * Copyright (C) 2011-2012 Pavel Shramov
+ * Copyright (C) 2013 Maxime Petazzoni <maxime.petazzoni@bulix.org>
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Thanks to Pavel Shramov who provided the initial implementation and Leaflet
+ * integration. Original code was at https://github.com/shramov/leaflet-plugins.
+ *
+ * It was then cleaned-up and modified to record and make available more
+ * information about the GPX track while it is being parsed so that the result
+ * can be used to display additional information about the track that is
+ * rendered on the Leaflet map.
+ */
+
+/** JvdB: downloaded on 16.aug.2015 from https://rawgit.com/mpetazzoni/leaflet-gpx/master/gpx.js */
+
+var _MAX_POINT_INTERVAL_MS = 15000;
+var _SECOND_IN_MILLIS = 1000;
+var _MINUTE_IN_MILLIS = 60 * _SECOND_IN_MILLIS;
+var _HOUR_IN_MILLIS = 60 * _MINUTE_IN_MILLIS;
+
+var _DEFAULT_MARKER_OPTS = {
+  startIconUrl: 'pin-icon-start.png',
+  endIconUrl: 'pin-icon-end.png',
+  shadowUrl: 'pin-shadow.png',
+  wptIconUrls : {
+  },
+  iconSize: [33, 50],
+  shadowSize: [50, 50],
+  iconAnchor: [16, 45],
+  shadowAnchor: [16, 47]
+};
+var _DEFAULT_POLYLINE_OPTS = {
+	color:'blue'
+};
+var _DEFAULT_GPX_OPTS = {
+  parseElements: ['track', 'route', 'waypoint']
+};
+L.GPX = L.FeatureGroup.extend({
+  initialize: function(gpx, options) {
+    options.max_point_interval = options.max_point_interval || _MAX_POINT_INTERVAL_MS;
+    options.marker_options = this._merge_objs(
+      _DEFAULT_MARKER_OPTS,
+      options.marker_options || {});
+    options.polyline_options = this._merge_objs(
+      _DEFAULT_POLYLINE_OPTS,
+      options.polyline_options || {});
+    options.gpx_options = this._merge_objs(
+      _DEFAULT_GPX_OPTS,
+      options.gpx_options || {});
+
+    L.Util.setOptions(this, options);
+
+    // Base icon class for track pins.
+    L.GPXTrackIcon = L.Icon.extend({ options: options.marker_options });
+
+    this._gpx = gpx;
+    this._layers = {};
+    this._info = {
+      name: null,
+      length: 0.0,
+      elevation: {gain: 0.0, loss: 0.0, max: 0.0, min: Infinity, _points: []},
+      hr: {avg: 0, _total: 0, _points: []},
+      duration: {start: null, end: null, moving: 0, total: 0}
+    };
+
+    if (gpx) {
+      this._parse(gpx, options, this.options.async);
+    }
+  },
+
+  get_duration_string: function(duration, hidems) {
+    var s = '';
+
+    if (duration >= _HOUR_IN_MILLIS) {
+      s += Math.floor(duration / _HOUR_IN_MILLIS) + ':';
+      duration = duration % _HOUR_IN_MILLIS;
+    }
+
+    var mins = Math.floor(duration / _MINUTE_IN_MILLIS);
+    duration = duration % _MINUTE_IN_MILLIS;
+    if (mins < 10) s += '0';
+    s += mins + '\'';
+
+    var secs = Math.floor(duration / _SECOND_IN_MILLIS);
+    duration = duration % _SECOND_IN_MILLIS;
+    if (secs < 10) s += '0';
+    s += secs;
+
+    if (!hidems && duration > 0) s += '.' + Math.round(Math.floor(duration)*1000)/1000;
+    else s += '"';
+
+    return s;
+  },
+
+  // Public methods
+  to_miles:            function(v) { return v / 1.60934; },
+  to_ft:               function(v) { return v * 3.28084; },
+  m_to_km:             function(v) { return v / 1000; },
+  m_to_mi:             function(v) { return v / 1609.34; },
+
+  get_name:            function() { return this._info.name; },
+  get_desc:            function() { return this._info.desc; },
+  get_author:          function() { return this._info.author; },
+  get_copyright:       function() { return this._info.copyright; },
+  get_distance:        function() { return this._info.length; },
+  get_distance_imp:    function() { return this.to_miles(this.m_to_km(this.get_distance())); },
+
+  get_start_time:      function() { return this._info.duration.start; },
+  get_end_time:        function() { return this._info.duration.end; },
+  get_moving_time:     function() { return this._info.duration.moving; },
+  get_total_time:      function() { return this._info.duration.total; },
+
+  get_moving_pace:     function() { return this.get_moving_time() / this.m_to_km(this.get_distance()); },
+  get_moving_pace_imp: function() { return this.get_moving_time() / this.get_distance_imp(); },
+
+  get_moving_speed:    function() { return this.m_to_km(this.get_distance()) / (this.get_moving_time() / (3600 * 1000)) ; },
+  get_moving_speed_imp:function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_moving_time() / (3600 * 1000)) ; },
+
+  get_total_speed:     function() { return this.m_to_km(this.get_distance()) / (this.get_total_time() / (3600 * 1000)); },
+  get_total_speed_imp: function() { return this.to_miles(this.m_to_km(this.get_distance())) / (this.get_total_time() / (3600 * 1000)); },
+
+  get_elevation_gain:     function() { return this._info.elevation.gain; },
+  get_elevation_loss:     function() { return this._info.elevation.loss; },
+  get_elevation_data:     function() {
+    var _this = this;
+    return this._info.elevation._points.map(
+      function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
+        function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' m'; });
+      });
+  },
+  get_elevation_data_imp: function() {
+    var _this = this;
+    return this._info.elevation._points.map(
+      function(p) { return _this._prepare_data_point(p, _this.m_to_mi, _this.to_ft,
+        function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' ft'; });
+      });
+  },
+  get_elevation_max:      function() { return this._info.elevation.max; },
+  get_elevation_min:      function() { return this._info.elevation.min; },
+  get_elevation_max_imp:  function() { return this.to_miles(this.m_to_km(this.get_elevation_max())); },
+  get_elevation_min_imp:  function() { return this.to_miles(this.m_to_km(this.get_elevation_min())); },
+
+  get_average_hr:         function() { return this._info.hr.avg; },
+  get_heartrate_data:     function() {
+    var _this = this;
+    return this._info.hr._points.map(
+      function(p) { return _this._prepare_data_point(p, _this.m_to_km, null,
+        function(a, b) { return a.toFixed(2) + ' km, ' + b.toFixed(0) + ' bpm'; });
+      });
+  },
+  get_heartrate_data_imp: function() {
+    var _this = this;
+    return this._info.hr._points.map(
+      function(p) { return _this._prepare_data_point(p, _this.m_to_mi, null,
+        function(a, b) { return a.toFixed(2) + ' mi, ' + b.toFixed(0) + ' bpm'; });
+      });
+  },
+
+  reload: function() {
+    this.clearLayers();
+    this._parse(this._gpx, this.options, this.options.async);
+  },
+
+  // Private methods
+  _merge_objs: function(a, b) {
+    var _ = {};
+    for (var attr in a) { _[attr] = a[attr]; }
+    for (var attr in b) { _[attr] = b[attr]; }
+    return _;
+  },
+
+  _prepare_data_point: function(p, trans1, trans2, trans_tooltip) {
+    var r = [trans1 && trans1(p[0]) || p[0], trans2 && trans2(p[1]) || p[1]];
+    r.push(trans_tooltip && trans_tooltip(r[0], r[1]) || (r[0] + ': ' + r[1]));
+    return r;
+  },
+
+  _load_xml: function(url, cb, options, async) {
+    if (async == undefined) async = this.options.async;
+    if (options == undefined) options = this.options;
+
+    var req = new window.XMLHttpRequest();
+    req.open('GET', url, async);
+    try {
+      req.overrideMimeType('text/xml'); // unsupported by IE
+    } catch(e) {}
+    req.onreadystatechange = function() {
+      if (req.readyState != 4) return;
+      if(req.status == 200) cb(req.responseXML, options);
+    };
+    req.send(null);
+  },
+
+  _parse: function(input, options, async) {
+    var _this = this;
+    var cb = function(gpx, options) {
+      var layers = _this._parse_gpx_data(gpx, options);
+      if (!layers) return;
+      _this.addLayer(layers);
+      _this.fire('loaded');
+    }
+    if (input.substr(0,1)==='<') { // direct XML has to start with a <
+      var parser = new DOMParser();
+      setTimeout(function() {
+        cb(parser.parseFromString(input, "text/xml"), options);
+      });
+    } else {
+      this._load_xml(input, cb, options, async);
+    }
+  },
+
+  _parse_gpx_data: function(xml, options) {
+    var j, i, el, layers = [];
+    var tags = [];
+    var parseElements = options.gpx_options.parseElements;
+    if(parseElements.indexOf('route') > -1) {
+      tags.push(['rte','rtept']);
+    }
+    if(parseElements.indexOf('track') > -1) {
+      tags.push(['trkseg','trkpt']);
+    }
+
+    var name = xml.getElementsByTagName('name');
+    if (name.length > 0) {
+      this._info.name = name[0].textContent;
+    }
+    var desc = xml.getElementsByTagName('desc');
+    if (desc.length > 0) {
+      this._info.desc = desc[0].textContent;
+    }
+    var author = xml.getElementsByTagName('author');
+    if (author.length > 0) {
+      this._info.author = author[0].textContent;
+    }
+    var copyright = xml.getElementsByTagName('copyright');
+    if (copyright.length > 0) {
+      this._info.copyright = copyright[0].textContent;
+    }
+
+    for (j = 0; j < tags.length; j++) {
+      el = xml.getElementsByTagName(tags[j][0]);
+      for (i = 0; i < el.length; i++) {
+        var coords = this._parse_trkseg(el[i], xml, options, tags[j][1]);
+        if (coords.length === 0) continue;
+
+        // add track
+        var l = new L.Polyline(coords, options.polyline_options);
+        this.fire('addline', { line: l })
+        layers.push(l);
+
+        if (options.marker_options.startIconUrl) {
+          // add start pin
+          var p = new L.Marker(coords[0], {
+            clickable: false,
+              icon: new L.GPXTrackIcon({iconUrl: options.marker_options.startIconUrl})
+          });
+          this.fire('addpoint', { point: p });
+          layers.push(p);
+        }
+
+        if (options.marker_options.endIconUrl) {
+          // add end pin
+          p = new L.Marker(coords[coords.length-1], {
+            clickable: false,
+            icon: new L.GPXTrackIcon({iconUrl: options.marker_options.endIconUrl})
+          });
+          this.fire('addpoint', { point: p });
+          layers.push(p);
+        }
+      }
+    }
+
+    this._info.hr.avg = Math.round(this._info.hr._total / this._info.hr._points.length);
+
+    /* JvdB parse WayPoints e.g.
+    *   <wpt lat="52.390606999397278" lon="4.933056039735675">
+         <ele>8.832767</ele>
+         <time>2015-08-16T11:34:54Z</time>
+         <name>START3</name>
+         <desc>Some point</desc>
+         <sym>Pin, Blue</sym>
+         <type>user</type>
+        </wpt>
+    */
+    if (parseElements.indexOf('waypoint') > -1) {
+        el = xml.getElementsByTagName('wpt');
+        for (i = 0; i < el.length; i++) {
+          var ll = new L.LatLng(
+              el[i].getAttribute('lat'),
+              el[i].getAttribute('lon'));
+
+            var nameEl = el[i].getElementsByTagName('name');
+            name = '';
+            if (nameEl.length > 0) {
+              name = nameEl[0].textContent;
+            }
+
+            var descEl = el[i].getElementsByTagName('desc');
+            desc = '';
+            if (descEl.length > 0) {
+              desc = descEl[0].textContent;
+            }
+
+            var symEl = el[i].getElementsByTagName('sym');
+            var symKey = '';
+            if (symEl.length > 0) {
+                symKey = symEl[0].textContent;
+            }
+
+          // add WayPointMarker, based on "sym" element if avail and icon is configured
+          var symIcon = options.marker_options.wptIconUrls[symKey];
+          var marker = new L.Marker(ll, {
+              clickable: true,
+              title: name,
+              icon: symIcon ? new L.GPXTrackIcon({iconUrl: symIcon}) : new L.Icon.Default()
+          });
+          marker.bindPopup("<b>" + name + "</b>" + (desc.length > 0 ? '<br>' + desc : '')).openPopup();
+          this.fire('addpoint', {point: marker});
+          // http://gis.stackexchange.com/a/123068
+          markerClusters.addLayer(marker);
+          // layers.push(marker);
+        }
+    }
+
+    if (!layers.length) return;
+    var layer = layers[0];
+    if (layers.length > 1)
+      layer = new L.FeatureGroup(layers);
+    return layer;
+  },
+
+  _parse_trkseg: function(line, xml, options, tag) {
+    var el = line.getElementsByTagName(tag);
+    if (!el.length) return [];
+    var coords = [];
+    var last = null;
+
+    for (var i = 0; i < el.length; i++) {
+      var _, ll = new L.LatLng(
+        el[i].getAttribute('lat'),
+        el[i].getAttribute('lon'));
+      ll.meta = { time: null, ele: null, hr: null };
+
+      _ = el[i].getElementsByTagName('time');
+      if (_.length > 0) {
+        ll.meta.time = new Date(Date.parse(_[0].textContent));
+      }
+
+      _ = el[i].getElementsByTagName('ele');
+      if (_.length > 0) {
+        ll.meta.ele = parseFloat(_[0].textContent);
+      }
+
+      _ = el[i].getElementsByTagNameNS('*', 'hr');
+      if (_.length > 0) {
+        ll.meta.hr = parseInt(_[0].textContent);
+        this._info.hr._points.push([this._info.length, ll.meta.hr]);
+        this._info.hr._total += ll.meta.hr;
+      }
+
+      if(ll.meta.ele > this._info.elevation.max)
+        this._info.elevation.max = ll.meta.ele;
+
+      if(ll.meta.ele < this._info.elevation.min)
+        this._info.elevation.min = ll.meta.ele;
+
+      this._info.elevation._points.push([this._info.length, ll.meta.ele]);
+      this._info.duration.end = ll.meta.time;
+
+      if (last != null) {
+        this._info.length += this._dist3d(last, ll);
+
+        var t = ll.meta.ele - last.meta.ele;
+        if (t > 0) this._info.elevation.gain += t;
+        else this._info.elevation.loss += Math.abs(t);
+
+        t = Math.abs(ll.meta.time - last.meta.time);
+        this._info.duration.total += t;
+        if (t < options.max_point_interval) this._info.duration.moving += t;
+      } else {
+        this._info.duration.start = ll.meta.time;
+      }
+
+      last = ll;
+      coords.push(ll);
+    }
+
+    return coords;
+  },
+
+  _dist2d: function(a, b) {
+    var R = 6371000;
+    var dLat = this._deg2rad(b.lat - a.lat);
+    var dLon = this._deg2rad(b.lng - a.lng);
+    var r = Math.sin(dLat/2) *
+      Math.sin(dLat/2) +
+      Math.cos(this._deg2rad(a.lat)) *
+      Math.cos(this._deg2rad(b.lat)) *
+      Math.sin(dLon/2) *
+      Math.sin(dLon/2);
+    var c = 2 * Math.atan2(Math.sqrt(r), Math.sqrt(1-r));
+    var d = R * c;
+    return d;
+  },
+
+  _dist3d: function(a, b) {
+    var planar = this._dist2d(a, b);
+    var height = Math.abs(b.meta.ele - a.meta.ele);
+    return Math.sqrt(Math.pow(planar, 2) + Math.pow(height, 2));
+  },
+
+  _deg2rad: function(deg) {
+    return deg * Math.PI / 180;
+  }
+});

BIN
images/marker-icon.png


BIN
images/marker-shadow.png


+ 121 - 0
index.html

@@ -0,0 +1,121 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <meta name="generator" content=
+  "HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 15.17), see www.w3.org" />
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
+  <!-- http://leafletjs.com/examples/quick-start.html -->
+  <!-- http://cdn.leafletjs.com/leaflet/v0.7.7/ -->
+  <link rel="stylesheet" href="leaflet.css" type="text/css" />
+  <script src="leaflet.js" type="text/javascript">
+//<![CDATA[
+  // http://cdn.leafletjs.com/leaflet/v0.7.7/
+  //]]>
+  </script>
+  <script src="gpx.js" type="text/javascript">
+//<![CDATA[
+  // https://rawgit.com/mpetazzoni/leaflet-gpx/master/
+  //]]>
+  </script>
+
+  <!-- https://github.com/Leaflet/Leaflet.markercluster
+   http://gis.stackexchange.com/a/123068 -->
+  <link rel="stylesheet" href="./MarkerCluster.css" />
+  <link rel="stylesheet" href="./MarkerCluster.Default.css" />
+  <script src="./leaflet.markercluster-src.js"></script>
+
+  <title>Megalithic Ireland Maps</title>
+  <style type="text/css">
+/*<![CDATA[*/
+  #mapdiv {
+    height: 95vh;
+  }
+  /*]]>*/
+  </style>
+</head>
+
+<body>
+  <div id="mapdiv"></div>
+  <script type="text/javascript">
+//<![CDATA[
+  var map = null;
+  {
+    var centerGps = new L.LatLng(53.45862, -7.53662);
+    var zoom = 7;
+    var posMatch = window.location.href.match(/#map=(\d+)\/(-?\d+(?:\.\d+)?)\/(-?\d+(?:\.\d+)?)/);
+    if( posMatch ) {
+      centerGps = new L.LatLng(posMatch[2], posMatch[3]);
+      zoom = posMatch[1];
+    };
+    map = L.map('mapdiv', {center: centerGps, zoom: zoom, maxZoom:18});
+    map.on("moveend", function(e) {
+      // http://stackoverflow.com/a/21432964
+      var c = map.getCenter();
+      history.pushState(null, null, "#map=" + map.getZoom() + '/' + c.lat.toFixed(5) + '/' + c.lng.toFixed(5) + '&layers=C');
+    });
+  }
+  var osmAttr = '&copy; <a href="http://openstreetmap.org">OpenStreetMap<\/a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA<\/a>';
+  // map.addLayer(new L.TileLayer('https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', { attribution: '&copy; OpenCycleMap, ' + 'Map data ' + osmAttr }));
+  map.addLayer(new L.TileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', { attribution: '&copy; OpenCycleMap, ' + 'Map data ' + osmAttr }));
+
+  // http://gis.stackexchange.com/a/123068
+  var markerClusters = new L.MarkerClusterGroup({maxClusterRadius: 50, chunkedLoading: true, polygonOptions: {stroke: false}});
+
+  // https://github.com/mpetazzoni/leaflet-gpx
+  new L.GPX('./monuments.gpx', {
+    async: true,
+    gpx_options: { parseElements: ['waypoint'] },
+    marker_options: {
+      startIconUrl: null,
+      endIconUrl: null,
+      shadowUrl: null,
+      wptIconUrls: {
+        'subject#abbeys': 'poi-img/convent.png',
+        'subject#castles': 'poi-img/castle.png',
+        'subject#holywells': 'poi-img/fountain.png',
+        'subject#stonecircles': 'poi-img/cromlech.png',
+        '': 'poi-img/sight-2.png',
+        //
+        'subject#bullauns': 'poi-img/sight-2.png',
+        'subject#courttombs': 'poi-img/sight-2.png',
+        'subject#crossslabs': 'poi-img/sight-2.png',
+        'subject#cultstones': 'poi-img/sight-2.png',
+        'subject#mottes': 'poi-img/sight-2.png',
+        'subject#oratories': 'poi-img/sight-2.png',
+        'subject#passagetombs': 'poi-img/sight-2.png',
+        'subject#pilgrimagesites': 'poi-img/sight-2.png',
+        'subject#portaltombs': 'poi-img/sight-2.png',
+        'subject#promontoryforts': 'poi-img/sight-2.png',
+        'subject#ringforts': 'poi-img/sight-2.png',
+        'subject#rockart': 'poi-img/sight-2.png',
+        'subject#roundtowers': 'poi-img/sight-2.png',
+        'subject#sheelas': 'poi-img/sight-2.png',
+        'subject#standingstones': 'poi-img/sight-2.png',
+        'subject#stonepairs': 'poi-img/sight-2.png',
+        'subject#stonerows': 'poi-img/sight-2.png',
+        'subject#walledtowns': 'poi-img/sight-2.png',
+        'subject#wedgetombs': 'poi-img/sight-2.png',
+      },
+      iconSize: [32, 37],
+      // shadowSize: [50, 50],
+      iconAnchor: [16, 37],
+      // shadowAnchor: [16, 47]
+    }
+  });
+
+  // http://gis.stackexchange.com/a/123068
+  map.addLayer(markerClusters);
+  L.control.scale().addTo(map);
+
+  //]]>
+  </script>
+
+  <p id="explanation">POIs loaded directly from <a href="monuments.gpx"><tt>monuments.gpx</tt></a>,
+  Map  <a href="http://mapicons.nicolasmollet.com/markers/">Icons by Nicolas
+  Mollet</a>. <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons 3.0
+  BY-SA</a>.</p>
+</body>
+</html>

+ 478 - 0
leaflet.css

@@ -0,0 +1,478 @@
+/* required styles */
+
+.leaflet-map-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-pane,
+.leaflet-tile-container,
+.leaflet-overlay-pane,
+.leaflet-shadow-pane,
+.leaflet-marker-pane,
+.leaflet-popup-pane,
+.leaflet-overlay-pane svg,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+	position: absolute;
+	left: 0;
+	top: 0;
+	}
+.leaflet-container {
+	overflow: hidden;
+	-ms-touch-action: none;
+	}
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	-webkit-user-select: none;
+	   -moz-user-select: none;
+	        user-select: none;
+	-webkit-user-drag: none;
+	}
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	display: block;
+	}
+/* map is broken in FF if you have max-width: 100% on tiles */
+.leaflet-container img {
+	max-width: none !important;
+	}
+/* stupid Android 2 doesn't understand "max-width: none" properly */
+.leaflet-container img.leaflet-image-layer {
+	max-width: 15000px !important;
+	}
+.leaflet-tile {
+	filter: inherit;
+	visibility: hidden;
+	}
+.leaflet-tile-loaded {
+	visibility: inherit;
+	}
+.leaflet-zoom-box {
+	width: 0;
+	height: 0;
+	}
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+.leaflet-overlay-pane svg {
+	-moz-user-select: none;
+	}
+
+.leaflet-tile-pane    { z-index: 2; }
+.leaflet-objects-pane { z-index: 3; }
+.leaflet-overlay-pane { z-index: 4; }
+.leaflet-shadow-pane  { z-index: 5; }
+.leaflet-marker-pane  { z-index: 6; }
+.leaflet-popup-pane   { z-index: 7; }
+
+.leaflet-vml-shape {
+	width: 1px;
+	height: 1px;
+	}
+.lvml {
+	behavior: url(#default#VML);
+	display: inline-block;
+	position: absolute;
+	}
+
+
+/* control positioning */
+
+.leaflet-control {
+	position: relative;
+	z-index: 7;
+	pointer-events: auto;
+	}
+.leaflet-top,
+.leaflet-bottom {
+	position: absolute;
+	z-index: 1000;
+	pointer-events: none;
+	}
+.leaflet-top {
+	top: 0;
+	}
+.leaflet-right {
+	right: 0;
+	}
+.leaflet-bottom {
+	bottom: 0;
+	}
+.leaflet-left {
+	left: 0;
+	}
+.leaflet-control {
+	float: left;
+	clear: both;
+	}
+.leaflet-right .leaflet-control {
+	float: right;
+	}
+.leaflet-top .leaflet-control {
+	margin-top: 10px;
+	}
+.leaflet-bottom .leaflet-control {
+	margin-bottom: 10px;
+	}
+.leaflet-left .leaflet-control {
+	margin-left: 10px;
+	}
+.leaflet-right .leaflet-control {
+	margin-right: 10px;
+	}
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile,
+.leaflet-fade-anim .leaflet-popup {
+	opacity: 0;
+	-webkit-transition: opacity 0.2s linear;
+	   -moz-transition: opacity 0.2s linear;
+	     -o-transition: opacity 0.2s linear;
+	        transition: opacity 0.2s linear;
+	}
+.leaflet-fade-anim .leaflet-tile-loaded,
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+	opacity: 1;
+	}
+
+.leaflet-zoom-anim .leaflet-zoom-animated {
+	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
+	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
+	     -o-transition:      -o-transform 0.25s cubic-bezier(0,0,0.25,1);
+	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
+	}
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile,
+.leaflet-touching .leaflet-zoom-animated {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	     -o-transition: none;
+	        transition: none;
+	}
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+	visibility: hidden;
+	}
+
+
+/* cursors */
+
+.leaflet-clickable {
+	cursor: pointer;
+	}
+.leaflet-container {
+	cursor: -webkit-grab;
+	cursor:    -moz-grab;
+	}
+.leaflet-popup-pane,
+.leaflet-control {
+	cursor: auto;
+	}
+.leaflet-dragging .leaflet-container,
+.leaflet-dragging .leaflet-clickable {
+	cursor: move;
+	cursor: -webkit-grabbing;
+	cursor:    -moz-grabbing;
+	}
+
+
+/* visual tweaks */
+
+.leaflet-container {
+	background: #ddd;
+	outline: 0;
+	}
+.leaflet-container a {
+	color: #0078A8;
+	}
+.leaflet-container a.leaflet-active {
+	outline: 2px solid orange;
+	}
+.leaflet-zoom-box {
+	border: 2px dotted #38f;
+	background: rgba(255,255,255,0.5);
+	}
+
+
+/* general typography */
+.leaflet-container {
+	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	}
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+	border-radius: 4px;
+	}
+.leaflet-bar a,
+.leaflet-bar a:hover {
+	background-color: #fff;
+	border-bottom: 1px solid #ccc;
+	width: 26px;
+	height: 26px;
+	line-height: 26px;
+	display: block;
+	text-align: center;
+	text-decoration: none;
+	color: black;
+	}
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+	background-position: 50% 50%;
+	background-repeat: no-repeat;
+	display: block;
+	}
+.leaflet-bar a:hover {
+	background-color: #f4f4f4;
+	}
+.leaflet-bar a:first-child {
+	border-top-left-radius: 4px;
+	border-top-right-radius: 4px;
+	}
+.leaflet-bar a:last-child {
+	border-bottom-left-radius: 4px;
+	border-bottom-right-radius: 4px;
+	border-bottom: none;
+	}
+.leaflet-bar a.leaflet-disabled {
+	cursor: default;
+	background-color: #f4f4f4;
+	color: #bbb;
+	}
+
+.leaflet-touch .leaflet-bar a {
+	width: 30px;
+	height: 30px;
+	line-height: 30px;
+	}
+
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+	font: bold 18px 'Lucida Console', Monaco, monospace;
+	text-indent: 1px;
+	}
+.leaflet-control-zoom-out {
+	font-size: 20px;
+	}
+
+.leaflet-touch .leaflet-control-zoom-in {
+	font-size: 22px;
+	}
+.leaflet-touch .leaflet-control-zoom-out {
+	font-size: 24px;
+	}
+
+
+/* layers control */
+
+.leaflet-control-layers {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
+	background: #fff;
+	border-radius: 5px;
+	}
+.leaflet-control-layers-toggle {
+	background-image: url(images/layers.png);
+	width: 36px;
+	height: 36px;
+	}
+.leaflet-retina .leaflet-control-layers-toggle {
+	background-image: url(images/layers-2x.png);
+	background-size: 26px 26px;
+	}
+.leaflet-touch .leaflet-control-layers-toggle {
+	width: 44px;
+	height: 44px;
+	}
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+	display: none;
+	}
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+	display: block;
+	position: relative;
+	}
+.leaflet-control-layers-expanded {
+	padding: 6px 10px 6px 6px;
+	color: #333;
+	background: #fff;
+	}
+.leaflet-control-layers-selector {
+	margin-top: 2px;
+	position: relative;
+	top: 1px;
+	}
+.leaflet-control-layers label {
+	display: block;
+	}
+.leaflet-control-layers-separator {
+	height: 0;
+	border-top: 1px solid #ddd;
+	margin: 5px -10px 5px -6px;
+	}
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+	background: #fff;
+	background: rgba(255, 255, 255, 0.7);
+	margin: 0;
+	}
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+	padding: 0 5px;
+	color: #333;
+	}
+.leaflet-control-attribution a {
+	text-decoration: none;
+	}
+.leaflet-control-attribution a:hover {
+	text-decoration: underline;
+	}
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+	font-size: 11px;
+	}
+.leaflet-left .leaflet-control-scale {
+	margin-left: 5px;
+	}
+.leaflet-bottom .leaflet-control-scale {
+	margin-bottom: 5px;
+	}
+.leaflet-control-scale-line {
+	border: 2px solid #777;
+	border-top: none;
+	line-height: 1.1;
+	padding: 2px 5px 1px;
+	font-size: 11px;
+	white-space: nowrap;
+	overflow: hidden;
+	-moz-box-sizing: content-box;
+	     box-sizing: content-box;
+
+	background: #fff;
+	background: rgba(255, 255, 255, 0.5);
+	}
+.leaflet-control-scale-line:not(:first-child) {
+	border-top: 2px solid #777;
+	border-bottom: none;
+	margin-top: -2px;
+	}
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+	border-bottom: 2px solid #777;
+	}
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	box-shadow: none;
+	}
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	border: 2px solid rgba(0,0,0,0.2);
+	background-clip: padding-box;
+	}
+
+
+/* popup */
+
+.leaflet-popup {
+	position: absolute;
+	text-align: center;
+	}
+.leaflet-popup-content-wrapper {
+	padding: 1px;
+	text-align: left;
+	border-radius: 12px;
+	}
+.leaflet-popup-content {
+	margin: 13px 19px;
+	line-height: 1.4;
+	}
+.leaflet-popup-content p {
+	margin: 18px 0;
+	}
+.leaflet-popup-tip-container {
+	margin: 0 auto;
+	width: 40px;
+	height: 20px;
+	position: relative;
+	overflow: hidden;
+	}
+.leaflet-popup-tip {
+	width: 17px;
+	height: 17px;
+	padding: 1px;
+
+	margin: -10px auto 0;
+
+	-webkit-transform: rotate(45deg);
+	   -moz-transform: rotate(45deg);
+	    -ms-transform: rotate(45deg);
+	     -o-transform: rotate(45deg);
+	        transform: rotate(45deg);
+	}
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+	background: white;
+
+	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+	}
+.leaflet-container a.leaflet-popup-close-button {
+	position: absolute;
+	top: 0;
+	right: 0;
+	padding: 4px 4px 0 0;
+	text-align: center;
+	width: 18px;
+	height: 14px;
+	font: 16px/14px Tahoma, Verdana, sans-serif;
+	color: #c3c3c3;
+	text-decoration: none;
+	font-weight: bold;
+	background: transparent;
+	}
+.leaflet-container a.leaflet-popup-close-button:hover {
+	color: #999;
+	}
+.leaflet-popup-scrolled {
+	overflow: auto;
+	border-bottom: 1px solid #ddd;
+	border-top: 1px solid #ddd;
+	}
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+	zoom: 1;
+	}
+.leaflet-oldie .leaflet-popup-tip {
+	width: 24px;
+	margin: 0 auto;
+
+	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+	}
+.leaflet-oldie .leaflet-popup-tip-container {
+	margin-top: -1px;
+	}
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+	border: 1px solid #999;
+	}
+
+
+/* div icon */
+
+.leaflet-div-icon {
+	background: #fff;
+	border: 1px solid #666;
+	}

File diff suppressed because it is too large
+ 9 - 0
leaflet.js


File diff suppressed because it is too large
+ 2163 - 0
leaflet.markercluster-src.js


+ 0 - 13
maps/index.html

@@ -1,13 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
-  <title>megalithicireland.com</title>
-</head>
-
-<body>
-  <p>Hello, world!</p>
-</body>
-</html>

File diff suppressed because it is too large
+ 4856 - 0
monuments.gpx


BIN
poi-img/castle.png


BIN
poi-img/convent.png


BIN
poi-img/cromlech.png


BIN
poi-img/fountain.png


BIN
poi-img/megalith.png


BIN
poi-img/sight-2.png