Browse Source

Draw orientations on the public map

It's not very pretty for now, but it works
Baptiste Jonglez 10 years ago
parent
commit
edc2e26d8f
4 changed files with 160 additions and 1 deletions
  1. 20 0
      assets/leaflet-semicircle/LICENSE
  2. 113 0
      assets/leaflet-semicircle/semicircle.js
  3. 25 1
      assets/map.js
  4. 2 0
      views/base.tpl

+ 20 - 0
assets/leaflet-semicircle/LICENSE

@@ -0,0 +1,20 @@
+Copyright 2013, Jieter
+
+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.

+ 113 - 0
assets/leaflet-semicircle/semicircle.js

@@ -0,0 +1,113 @@
+/**
+ * Semicircle extension for L.Circle.
+ * Jan Pieter Waagmeester <jieter@jieter.nl>
+ */
+
+/*jshint browser:true, strict:false, globalstrict:false, indent:4, white:true, smarttabs:true*/
+/*global L:true*/
+
+(function (L) {
+
+	// save original getPathString function to draw a full circle.
+	var original_getPathString = L.Circle.prototype.getPathString;
+
+	L.Circle = L.Circle.extend({
+		options: {
+			startAngle: 0,
+			stopAngle: 359.9999
+		},
+
+		// make sure 0 degrees is up (North) and convert to radians.
+		_fixAngle: function (angle) {
+			return (angle - 90) * L.LatLng.DEG_TO_RAD;
+		},
+		startAngle: function () {
+			return this._fixAngle(this.options.startAngle);
+		},
+		stopAngle: function () {
+			return this._fixAngle(this.options.stopAngle);
+		},
+
+		//rotate point x,y+r around x,y with angle.
+		rotated: function (angle, r) {
+			return this._point.add(
+				L.point(Math.cos(angle), Math.sin(angle)).multiplyBy(r)
+			).round();
+		},
+
+		getPathString: function () {
+			var center = this._point,
+			    r = this._radius;
+
+			// If we want a circle, we use the original function
+			if (this.options.startAngle === 0 && this.options.stopAngle > 359) {
+				return original_getPathString.call(this);
+			}
+
+			var start = this.rotated(this.startAngle(), r),
+				end = this.rotated(this.stopAngle(), r);
+
+			if (this._checkIfEmpty()) {
+				return '';
+			}
+
+			if (L.Browser.svg) {
+				var largeArc = (this.options.stopAngle - this.options.startAngle >= 180) ? '1' : '0';
+				//move to center
+				var ret = "M" + center.x + "," + center.y;
+				//lineTo point on circle startangle from center
+				ret += "L " + start.x + "," + start.y;
+				//make circle from point start - end:
+				ret += "A " + r + "," + r + ",0," + largeArc + ",1," + end.x + "," + end.y + " z";
+
+				return ret;
+			} else {
+				//TODO: fix this for semicircle...
+				center._round();
+				r = Math.round(r);
+				return "A " + center.x + "," + center.y + " " + r + "," + r + " 0," + (65535 * 360);
+			}
+		},
+		setStartAngle: function (angle) {
+			this.options.startAngle = angle;
+			return this.redraw();
+		},
+		setStopAngle: function (angle) {
+			this.options.stopAngle = angle;
+			return this.redraw();
+		},
+		setDirection: function (direction, degrees) {
+			if (degrees === undefined) {
+				degrees = 10;
+			}
+			this.options.startAngle = direction - (degrees / 2);
+			this.options.stopAngle = direction + (degrees / 2);
+
+			return this.redraw();
+		}
+	});
+	L.Circle.include(!L.Path.CANVAS ? {} : {
+		_drawPath: function () {
+			var center = this._point,
+			    r = this._radius;
+
+			var start = this.rotated(this.startAngle(), r);
+
+			this._ctx.beginPath();
+			this._ctx.moveTo(center.x, center.y);
+			this._ctx.lineTo(start.x, start.y);
+
+			this._ctx.arc(center.x, center.y, this._radius,
+				this.startAngle(), this.stopAngle(), false);
+			this._ctx.lineTo(center.x, center.y);
+		}
+
+		// _containsPoint: function (p) {
+		// TODO: fix for semicircle.
+		// var center = this._point,
+		//     w2 = this.options.stroke ? this.options.weight / 2 : 0;
+
+		//  return (p.distanceTo(center) <= this._radius + w2);
+		// }
+	});
+})(L);

+ 25 - 1
assets/map.js

@@ -43,9 +43,33 @@ $( document ).ready(function() {
             layer.bindPopup(feature.properties.popupContent);
         }
 
+        function drawSemiCircles(feature, layer) {
+            orientations_to_angle = {
+                'N': 0,
+                'NO': -45,
+                'O': -90,
+                'SO': -135,
+                'S': 180,
+                'SE': 135,
+                'E': 90,
+                'NE': 45
+            };
+            if (feature.properties.place) {
+                feature.properties.place.orientations.map(function(orien) {
+                    // Strangely enough, we need to invert the coordinates.
+                    L.circle([feature.geometry.coordinates[1],
+                              feature.geometry.coordinates[0]], 150)
+                        .setDirection(orientations_to_angle[orien], 45)
+                        .addTo(map);
+                });
+            }
+        }
+
         // Add to map
         var featureLayer = L.geoJson(data, {
-            onEachFeature: buildPopupContent
+            onEachFeature: function(feature, layer) {
+                buildPopupContent(feature, layer);
+                drawSemiCircles(feature, layer); }
         }).addTo(map);
 
         // Auto Zoom

+ 2 - 0
views/base.tpl

@@ -14,6 +14,8 @@
     <!-- Leaflet -->
     <link rel="stylesheet" type="text/css" media="all" href="assets/leaflet/leaflet.css" />
     <script src="assets/leaflet/leaflet.js" type="text/javascript"></script>
+    <!-- Leaflet-semicircle -->
+    <script src="assets/leaflet-semicircle/semicircle.js" type="text/javascript"></script>
 
     <!-- Custom -->
     <link rel="stylesheet" type="text/css" media="all" href="assets/main.css" />