Detection whether position is within community borders.

This commit is contained in:
Andreas Baldeau 2014-08-10 11:37:05 +02:00
parent cabc070b77
commit 43b4ad9178
31 changed files with 11960 additions and 16 deletions

View file

@ -0,0 +1,24 @@
{
"author": {
"name": "https://github.com/angular-ui/bootstrap/graphs/contributors"
},
"name": "angular-bootstrap",
"version": "0.11.0",
"main": [
"./ui-bootstrap-tpls.js"
],
"dependencies": {
"angular": ">=1"
},
"homepage": "https://github.com/angular-ui/bootstrap-bower",
"_release": "0.11.0",
"_resolution": {
"type": "version",
"tag": "0.11.0",
"commit": "75b302f82c1a3b0647695a3dfeacab0a153ea8a0"
},
"_source": "git://github.com/angular-ui/bootstrap-bower.git",
"_target": "~0.11.0",
"_originalSource": "angular-bootstrap",
"_direct": true
}

View file

@ -0,0 +1,11 @@
{
"author": {
"name": "https://github.com/angular-ui/bootstrap/graphs/contributors"
},
"name": "angular-bootstrap",
"version": "0.11.0",
"main": ["./ui-bootstrap-tpls.js"],
"dependencies": {
"angular": ">=1"
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

32
app/bower_components/geolib/.bower.json vendored Normal file
View file

@ -0,0 +1,32 @@
{
"name": "Geolib",
"main": "dist/geolib.js",
"version": "2.0.9",
"homepage": "https://github.com/manuelbieh/Geolib",
"authors": [
"Manuel Bieh <github@manuelbieh.de>"
],
"description": "Library to perform geo specific tasks",
"keywords": [
"geolocation",
"geo",
"distance"
],
"license": "LGPL",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"_release": "2.0.9",
"_resolution": {
"type": "version",
"tag": "2.0.9",
"commit": "c4222cde0d201e5d03f0d70ae560a5707907761c"
},
"_source": "git://github.com/manuelbieh/Geolib.git",
"_target": "~2.0.9",
"_originalSource": "geolib"
}

171
app/bower_components/geolib/Gruntfile.js vendored Normal file
View file

@ -0,0 +1,171 @@
/*global module:false*/
module.exports = function(grunt) {
require('time-grunt')(grunt);
require('load-grunt-tasks')(grunt);
grunt.registerTask('version', function(target, op) {
var fs = require('fs');
var data = JSON.parse(fs.readFileSync('package.json', {encoding: 'utf-8'}));
var version = data.version.split('.');
var major = parseInt(version[0], 10);
var minor = parseInt(version[1], 10);
var patch = parseInt(version[2].split('+')[0], 10);
var info = version[2].split('+')[1];
var log = '';
if(typeof op == 'undefined' || op === '+') {
op = '+';
log += 'Incrementing ';
} else if(op === '-') {
op = op;
log += 'Decrementing ';
} else if(!isNaN(parseInt(op, 10))) {
op = parseInt(op, 10);
log += 'Using ' + op + ' as new ';
} else {
grunt.log.fail('Illegal operation.');
return false;
}
if(['major', 'minor', 'patch'].indexOf(target) > -1) {
log += target + ' version. ';
}
switch(target) {
case 'major':
major = op == '-' ? major-1 : (op == '+' ? major+1 : op);
if(major < 0) major = 0;
break;
case 'minor':
minor = op == '-' ? minor-1 : (op == '+' ? minor+1 : op);
if(minor < 0) minor = 0;
break;
case 'patch':
patch = op == '-' ? patch-1 : (op == '+' ? patch+1 : op);
if(patch < 0) patch = 0;
break;
}
data.version = [major, minor, patch].join('.') + (info ? '+' + info : '');
grunt.log.writeln(log + 'New version is ' + data.version);
fs.writeFileSync('package.json', JSON.stringify(data, null, 2), {encoding: 'utf-8'})
grunt.config.data.pkg.version = data.version;
grunt.task.run('default');
});
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
banner: '/*! <%= pkg.name %> <%= pkg.version %> by <%= pkg.author.name %>\n'+
'* Library to provide geo functions like distance calculation,\n' +
'* conversion of decimal coordinates to sexagesimal and vice versa, etc.\n' +
'* WGS 84 (World Geodetic System 1984)\n' +
'* \n' +
'* @author <%= pkg.author.name %>\n' +
'* @url <%= pkg.author.url %>\n' +
'* @version <%= pkg.version %>\n' +
'* @license <%= _.pluck(pkg.licenses, "type").join(", ") %> \n**/',
lint: {
files: ['src/geolib.js']
},
qunit: {
files: ['tests/*.html']
},
concat: {
main: {
options: {
banner: '<%= banner %>',
report: false
},
src: ['src/geolib.js'],
dest: 'dist/geolib.js'
}
},
copy: {
component: {
files: [{
src: "package.json",
dest: "component.json"
}]
},
elev: {
files: [{
src: ['src/geolib.elevation.js'],
dest: 'dist/geolib.elevation.js'
}]
}
},
replace: {
version: {
src: ['dist/*.js', 'bower.json'],
overwrite: true,
replacements: [{
from: '$version$',
to: '<%= pkg.version %>'
}, {
from: /"version": "([0-9a-zA-Z\-\.\+]*)",/,
to: '"version": "<%= pkg.version %>",'
}]
}
},
uglify: {
options: {
preserveComments: 'some'
},
main: {
files: {
'dist/geolib.min.js': ['dist/geolib.js']
}
},
elev: {
files: {
'dist/geolib.elevation.min.js': ['dist/geolib.elevation.js']
}
}
},
watch: {
all: {
files: '<%= jshint.all %>',
tasks: ['default']
}
},
jshint: {
all: [
'src/geolib.js',
'src/geolib.elevation.js'
],
options: {
curly: true,
eqeqeq: false,
immed: true,
latedef: true,
newcap: false,
noarg: true,
sub: true,
undef: true,
boss: true,
eqnull: true,
globals: {
module: true,
define: true,
require: true,
elevationResult: true
}
}
}
});
// Default task.
grunt.registerTask('default', ['concat:main', 'copy', 'replace', 'uglify']);
grunt.registerTask('travis', ['jshint','qunit']);
grunt.registerTask('test', ['qunit']);
};

21
app/bower_components/geolib/LICENSE vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2011-2014 Manuel Bieh
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.

262
app/bower_components/geolib/README.md vendored Normal file
View file

@ -0,0 +1,262 @@
# Geolib v2.0.9
[![Build Status](https://secure.travis-ci.org/manuelbieh/Geolib.png?branch=master)](http://travis-ci.org/manuelbieh/Geolib)
Library to provide basic geospatial operations like distance calculation, conversion of decimal coordinates to sexagesimal and vice versa, etc.
[View demo](http://www.manuel-bieh.de/publikationen/scripts/geolib/demo.html)
<h2>Methods</h2>
<h3>geolib.getDistance(object start, object end[, int accuracy])</h3>
Calculates the distance between two geo coordinates
Takes 2 or 3 arguments. First 2 arguments must be an object with latitude and a longitude properties (e.g. `{latitude: 52.518611, longitude: 13.408056}`). Coordinates can be in sexagesimal or decimal format. 3rd argument is accuracy (in meters). So a calculated distance of 1248 meters with an accuracy of 100 is returned as `1200` (accuracy 10 = `1250` etc.).
Return value is always an integer and represents the distance in meters.
<h4>Examples</h4>
<pre>geolib.getDistance(
{latitude: 51.5103, longitude: 7.49347},
{latitude: "51° 31' N", longitude: "7° 28' E"}
);
geolib.getDistance(
{latitude: 51.5103, longitude: 7.49347},
{latitude: "51° 31' N", longitude: "7° 28' E"}
);
// Working with W3C Geolocation API
navigator.geolocation.getCurrentPosition(
function(position) {
alert('You are ' + geolib.getDistance(position.coords, {
latitude: 51.525,
longitude: 7.4575
}) + ' meters away from 51.525, 7.4575');
},
function() {
alert('Position could not be determined.')
},
{
enableHighAccuracy: true
}
);
</pre>
<h3>geolib.getCenter(array coords)</h3>
Calculates the geographical center of all points in a collection of geo coordinates
Takes an object or array of coordinates and calculates the center of it.
Returns an object: `{"latitude": centerLat, "longitude": centerLng, "distance": diagonalDistance}`
<h4>Examples</h4>
<pre>var spots = {
"Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
"Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
"London Eye": {latitude: 51.503333, longitude: -0.119722},
"Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
"Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
"Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
"Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
}
geolib.getCenter(spots);
geolib.getCenter([
{latitude: 52.516272, longitude: 13.377722},
{latitude: 51.515, longitude: 7.453619},
{latitude: 51.503333, longitude: -0.119722}
]);
</pre>
<h3>geolib.isPointInside(object latlng, array coords)</h3>
Checks whether a point is inside of a polygon or not.
Note: the polygon coords must be in correct order!
Returns true or false
<h4>Example</h4>
<pre>
geolib.isPointInside(
{latitude: 51.5125, longitude: 7.485},
[
{latitude: 51.50, longitude: 7.40},
{latitude: 51.555, longitude: 7.40},
{latitude: 51.555, longitude: 7.625},
{latitude: 51.5125, longitude: 7.625}
]
); // -> true</pre>
<h3>geolib.isPointInCircle(object latlng, object center, integer radius)</h3>
Similar to is point inside: checks whether a point is inside of a circle or not.
Returns true or false
<h4>Example</h4>
<pre>// checks if 51.525, 7.4575 is within a radius of 5km from 51.5175, 7.4678
geolib.isPointInCircle(
{latitude: 51.525, longitude: 7.4575},
{latitude: 51.5175, longitude: 7.4678},
5000
);</pre>
<h3>geolib.orderByDistance(object latlng, mixed coords)</h3>
Sorts an object or array of coords by distance from a reference coordinate
Returns a sorted array [{latitude: x, longitude: y, distance: z, key: property}]
<h4>Examples</h4>
<pre>
// coords array
geolib.orderByDistance({latitude: 51.515, longitude: 7.453619}, [
{latitude: 52.516272, longitude: 13.377722},
{latitude: 51.518, longitude: 7.45425},
{latitude: 51.503333, longitude: -0.119722}
]);
// coords object
geolib.orderByDistance({latitude: 51.515, longitude: 7.453619}, {
a: {latitude: 52.516272, longitude: 13.377722},
b: {latitude: 51.518, longitude: 7.45425},
c: {latitude: 51.503333, longitude: -0.119722}
});
</pre>
<h3>geolib.findNearest(object latlng, mixed coords[[, int offset], int limit])</h3>
Finds the nearest coordinate to a reference coordinate.
<h4>Examples</h4>
<pre>var spots = {
"Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
"Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
"London Eye": {latitude: 51.503333, longitude: -0.119722},
"Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
"Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
"Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
"Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
}
// in this case set offset to 1 otherwise the nearest point will always be your reference point
geolib.findNearest(spots['Dortmund U-Tower'], spots, 1)
</pre>
<h3>geolib.getPathLength(mixed coords)</h3>
Calculates the length of a collection of coordinates
Returns the length of the path in meters
<h4>Example</h4>
<pre>
// Calculate distance from Berlin via Dortmund to London
geolib.getPathLength([
{latitude: 52.516272, longitude: 13.377722}, // Berlin
{latitude: 51.515, longitude: 7.453619}, // Dortmund
{latitude: 51.503333, longitude: -0.119722} // London
]); // -> 945235</pre>
<h3>geolib.getSpeed(coords, coords[, options])</h3>
Calculates the speed between two points within a given time span.
Returns the speed in <em>options.unit</em> (default is km/h).
<h4>Example</h4>
<pre>
geolib.getSpeed(
{lat: 51.567294, lng: 7.38896, time: 1360231200880},
{lat: 52.54944, lng: 13.468509, time: 1360245600880},
{unit: 'mph'}
); // -> 66.9408 (mph)</pre>
<h3>geolib.convertUnit(string unit, float distance[, int round])</h3>
Converts a given distance (in meters) to another unit.
<h4>Parameters</h4>
`unit` can be one of:
- m (meter)
- km (kilometers)
- cm (centimeters)
- mm (millimeters)
- mi (miles)
- sm (seamiles)
- ft (foot)
- in (inch)
- yd (yards)
`distance` distance to be converted (source must be in meter)
`round` fractional digits
<h4>Example</h4>
`geolib.convertUnit('km', 14213, 2) // -> 14,21`
<h3>geolib.sexagesimal2decimal(string coord)</h3>
Converts a sexagesimal coordinate to decimal format
<h4>Example</h4>
`geolib.sexagesimal2decimal("51° 29' 46\" N")`
<h3>geolib.decimal2sexagesimal(float coord)</h3>
Converts a decimal coordinate to sexagesimal format
<h4>Example</h4>
`geolib.decimal2sexagesimal(51.49611111); // -> 51° 29' 46.00`
<h3>geolib.latitude(object latlng)</h3>
<h3>geolib.longitude(object latlng)</h3>
<h3>geolib.elevation(object latlng)</h3>
Returns the latitude/longitude/elevation for a given point and converts it to decimal.
Works with:
- latitude: `latitude`, `lat`, 0 (GeoJSON array)
- longitude: `longitude`, `lng`, `lon`, 1 (GeoJSON array)
- elevation: `elevation`, `elev`, `alt`, `altitude`, 2 (GeoJSON array)
<h4>Examples</h4>
`geolib.latitude({lat: 51.49611, lng: 7.38896}); // -> 51.49611`
`geolib.longitude({lat: 51.49611, lng: 7.38896}); // -> 7.38896`
<h3>geolib.useDecimal(mixed latlng)</h3>
Checks if a coordinate is already in decimal format and, if not, converts it to
<h4>Example</h4>
<pre>geolib.useDecimal("51° 29' 46\" N"); // -> 51.59611111
geolib.useDecimal(51.59611111) // -> 51.59611111</pre>
<h2>Changelog</h2>
<h3>v2.0.0+beta1</h3>
- Dropped support for IE6, IE7, IE8
- Added new methods `geolib.latitude()`, `geolib.longitude()`, `geolib.elevation()` to get latitude, longitude or elevation of points. Will be converted to decimal format automatically
- Added new method `geolib.extend()` to extend geolib object
- Added support for GeoJSON format (`[lon, lat, elev]`)
- Added property `geolib.version` to query the currently used version
- Moved `geolib.elevation` to an optional module (`geolib.elevation.js`)
- Using `Object.create(Geolib.prototype)` instead of object literal `{}`
- New folder structure: compiled `geolib.js` can now be found in `dist/` instead of root dir
- Improved Grunt build task

23
app/bower_components/geolib/bower.json vendored Normal file
View file

@ -0,0 +1,23 @@
{
"name": "Geolib",
"main": "dist/geolib.js",
"version": "2.0.9",
"homepage": "https://github.com/manuelbieh/Geolib",
"authors": [
"Manuel Bieh <github@manuelbieh.de>"
],
"description": "Library to perform geo specific tasks",
"keywords": [
"geolocation",
"geo",
"distance"
],
"license": "LGPL",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View file

@ -0,0 +1,51 @@
{
"name": "geolib",
"homepage": "http://github.com/manuelbieh/Geolib",
"author": {
"name": "Manuel Bieh",
"url": "http://www.manuelbieh.com/"
},
"repository": {
"type": "git",
"url": "http://github.com/manuelbieh/geolib.git"
},
"devDependencies": {
"grunt": "~0.4",
"grunt-cli": "*",
"grunt-contrib-uglify": "~0.2",
"grunt-contrib-concat": "~0.3",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-copy": "~0.4",
"grunt-contrib-qunit": "~0.2.0",
"grunt-text-replace": "~0.3.6",
"grunt-contrib-jshint": "~0.6.2",
"phantomjs": "~1.8.0",
"grunt-jslint": "~1.0.0",
"time-grunt": "~0.3.1",
"load-grunt-tasks": "~0.4.0"
},
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"files": [
"geolib.js"
],
"description": "Library to perform geo specific tasks",
"keywords": [
"geolocation",
"geo",
"distance",
"geojson",
"geospatial",
"lbs",
"location"
],
"scripts": {
"test": "grunt travis --verbose"
},
"version": "2.0.9",
"main": "./geolib"
}

View file

@ -0,0 +1,190 @@
/*! geolib.elevation 2.0.9 by Manuel Bieh
*
* Elevation Addon for Geolib.js
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version 2.0.9
* @license MIT
*/
;(function(global, geolib, undefined) {
var elevation = {
/*global google:true geolib:true require:true module:true elevationResult:true */
/**
* @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
* @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*/
getElevation: function() {
if (typeof global.navigator !== 'undefined') {
this.getElevationClient.apply(this, arguments);
} else {
this.getElevationServer.apply(this, arguments);
}
},
/* Optional elevation addon requires Googlemaps API JS */
getElevationClient: function(coords, cb) {
if (!global.google) {
throw new Error("Google maps api not loaded");
}
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var path = [];
for(var i = 0; i < coords.length; i++) {
path.push(new google.maps.LatLng(
this.latitude(coords[i]),
this.longitude(coords[i])
));
}
var positionalRequest = {
'path': path,
'samples': path.length
};
var elevationService = new google.maps.ElevationService();
var geolib = this;
elevationService.getElevationAlongPath(positionalRequest, function (results, status) {
geolib.elevationHandler(results, status, coords, cb);
});
},
getElevationServer: function(coords, cb) {
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var gm = require('googlemaps');
var path = [];
for(var i = 0; i < coords.length; i++) {
path.push(
this.latitude(coords[i]) + ',' + this.longitude(coords[i])
);
}
var geolib = this;
gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
geolib.elevationHandler(results.results, results.status, coords, cb);
});
},
elevationHandler: function(results, status, coords, cb) {
var latsLngsElevs = [];
if (status == "OK" ) {
for (var i = 0; i < results.length; i++) {
latsLngsElevs.push({
"lat": this.latitude(coords[i]),
"lng": this.longitude(coords[i]),
"elev":results[i].elevation
});
}
cb(null, latsLngsElevs);
} else {
cb(new Error("Could not get elevation using Google's API"), elevationResult.status);
}
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* @return Number % grade
*/
getGrade: function(coords) {
var rise = Math.abs(
this.elevation(coords[coords.length-1]) - this.elevation(coords[0])
);
var run = this.getPathLength(coords);
return Math.floor((rise/run)*100);
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* @return Object {gain:#gain, loss:#loss}
*/
getTotalElevationGainAndLoss: function(coords) {
var gain = 0;
var loss = 0;
for(var i = 0; i < coords.length - 1; i++) {
var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);
if (deltaElev > 0) {
loss += deltaElev;
} else {
gain += Math.abs(deltaElev);
}
}
return {
"gain": gain,
"loss": loss
};
}
};
// Node module
if (typeof module !== 'undefined' &&
typeof module.exports !== 'undefined') {
geolib = require('geolib');
geolib.extend(elevation);
// AMD module
} else if (typeof define === "function" && define.amd) {
define(["geolib"], function (geolib) {
geolib.extend(elevation);
return geolib;
});
// we're in a browser
} else {
geolib.extend(elevation);
}
}(this, this.geolib));

View file

@ -0,0 +1,10 @@
/*! geolib.elevation 2.0.9 by Manuel Bieh
*
* Elevation Addon for Geolib.js
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version 2.0.9
* @license MIT
*/
!function(a,b){var c={getElevation:function(){"undefined"!=typeof a.navigator?this.getElevationClient.apply(this,arguments):this.getElevationServer.apply(this,arguments)},getElevationClient:function(b,c){if(!a.google)throw new Error("Google maps api not loaded");if(0===b.length)return c(null,null);if(1===b.length)return c(new Error("getElevation requires at least 2 points."));for(var d=[],e=0;e<b.length;e++)d.push(new google.maps.LatLng(this.latitude(b[e]),this.longitude(b[e])));var f={path:d,samples:d.length},g=new google.maps.ElevationService,h=this;g.getElevationAlongPath(f,function(a,d){h.elevationHandler(a,d,b,c)})},getElevationServer:function(a,b){if(0===a.length)return b(null,null);if(1===a.length)return b(new Error("getElevation requires at least 2 points."));for(var c=require("googlemaps"),d=[],e=0;e<a.length;e++)d.push(this.latitude(a[e])+","+this.longitude(a[e]));var f=this;c.elevationFromPath(d.join("|"),d.length,function(c,d){f.elevationHandler(d.results,d.status,a,b)})},elevationHandler:function(a,b,c,d){var e=[];if("OK"==b){for(var f=0;f<a.length;f++)e.push({lat:this.latitude(c[f]),lng:this.longitude(c[f]),elev:a[f].elevation});d(null,e)}else d(new Error("Could not get elevation using Google's API"),elevationResult.status)},getGrade:function(a){var b=Math.abs(this.elevation(a[a.length-1])-this.elevation(a[0])),c=this.getPathLength(a);return Math.floor(b/c*100)},getTotalElevationGainAndLoss:function(a){for(var b=0,c=0,d=0;d<a.length-1;d++){var e=this.elevation(a[d])-this.elevation(a[d+1]);e>0?c+=e:b+=Math.abs(e)}return{gain:b,loss:c}}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?(b=require("geolib"),b.extend(c)):"function"==typeof define&&define.amd?define(["geolib"],function(a){return a.extend(c),a}):b.extend(c)}(this,this.geolib);

1150
app/bower_components/geolib/dist/geolib.js vendored Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

BIN
app/bower_components/geolib/earth.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

498
app/bower_components/geolib/index.html vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,51 @@
{
"name": "geolib",
"homepage": "http://github.com/manuelbieh/Geolib",
"author": {
"name": "Manuel Bieh",
"url": "http://www.manuelbieh.com/"
},
"repository": {
"type": "git",
"url": "http://github.com/manuelbieh/geolib.git"
},
"devDependencies": {
"grunt": "~0.4",
"grunt-cli": "*",
"grunt-contrib-uglify": "~0.2",
"grunt-contrib-concat": "~0.3",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-copy": "~0.4",
"grunt-contrib-qunit": "~0.2.0",
"grunt-text-replace": "~0.3.6",
"grunt-contrib-jshint": "~0.6.2",
"phantomjs": "~1.8.0",
"grunt-jslint": "~1.0.0",
"time-grunt": "~0.3.1",
"load-grunt-tasks": "~0.4.0"
},
"licenses": [
{
"type": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
],
"files": [
"geolib.js"
],
"description": "Library to perform geo specific tasks",
"keywords": [
"geolocation",
"geo",
"distance",
"geojson",
"geospatial",
"lbs",
"location"
],
"scripts": {
"test": "grunt travis --verbose"
},
"version": "2.0.9",
"main": "./geolib"
}

View file

@ -0,0 +1,190 @@
/*! geolib.elevation $version$ by Manuel Bieh
*
* Elevation Addon for Geolib.js
*
* @author Manuel Bieh
* @url http://www.manuelbieh.com/
* @version $version$
* @license MIT
*/
;(function(global, geolib, undefined) {
var elevation = {
/*global google:true geolib:true require:true module:true elevationResult:true */
/**
* @param Array Collection of coords [{latitude: 51.510, longitude: 7.1321}, {latitude: 49.1238, longitude: "8° 30' W"}, ...]
* @return Array [{lat:#lat, lng:#lng, elev:#elev},....]}
*/
getElevation: function() {
if (typeof global.navigator !== 'undefined') {
this.getElevationClient.apply(this, arguments);
} else {
this.getElevationServer.apply(this, arguments);
}
},
/* Optional elevation addon requires Googlemaps API JS */
getElevationClient: function(coords, cb) {
if (!global.google) {
throw new Error("Google maps api not loaded");
}
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var path = [];
for(var i = 0; i < coords.length; i++) {
path.push(new google.maps.LatLng(
this.latitude(coords[i]),
this.longitude(coords[i])
));
}
var positionalRequest = {
'path': path,
'samples': path.length
};
var elevationService = new google.maps.ElevationService();
var geolib = this;
elevationService.getElevationAlongPath(positionalRequest, function (results, status) {
geolib.elevationHandler(results, status, coords, cb);
});
},
getElevationServer: function(coords, cb) {
if (coords.length === 0) {
return cb(null, null);
}
if (coords.length === 1) {
return cb(new Error("getElevation requires at least 2 points."));
}
var gm = require('googlemaps');
var path = [];
for(var i = 0; i < coords.length; i++) {
path.push(
this.latitude(coords[i]) + ',' + this.longitude(coords[i])
);
}
var geolib = this;
gm.elevationFromPath(path.join('|'), path.length, function(err, results) {
geolib.elevationHandler(results.results, results.status, coords, cb);
});
},
elevationHandler: function(results, status, coords, cb) {
var latsLngsElevs = [];
if (status == "OK" ) {
for (var i = 0; i < results.length; i++) {
latsLngsElevs.push({
"lat": this.latitude(coords[i]),
"lng": this.longitude(coords[i]),
"elev":results[i].elevation
});
}
cb(null, latsLngsElevs);
} else {
cb(new Error("Could not get elevation using Google's API"), elevationResult.status);
}
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* @return Number % grade
*/
getGrade: function(coords) {
var rise = Math.abs(
this.elevation(coords[coords.length-1]) - this.elevation(coords[0])
);
var run = this.getPathLength(coords);
return Math.floor((rise/run)*100);
},
/**
* @param Array [{lat:#lat, lng:#lng, elev:#elev},....]}
* @return Object {gain:#gain, loss:#loss}
*/
getTotalElevationGainAndLoss: function(coords) {
var gain = 0;
var loss = 0;
for(var i = 0; i < coords.length - 1; i++) {
var deltaElev = this.elevation(coords[i]) - this.elevation(coords[i + 1]);
if (deltaElev > 0) {
loss += deltaElev;
} else {
gain += Math.abs(deltaElev);
}
}
return {
"gain": gain,
"loss": loss
};
}
};
// Node module
if (typeof module !== 'undefined' &&
typeof module.exports !== 'undefined') {
geolib = require('geolib');
geolib.extend(elevation);
// AMD module
} else if (typeof define === "function" && define.amd) {
define(["geolib"], function (geolib) {
geolib.extend(elevation);
return geolib;
});
// we're in a browser
} else {
geolib.extend(elevation);
}
}(this, this.geolib));

1141
app/bower_components/geolib/src/geolib.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -34,6 +34,8 @@
<script src="bower_components/angular-route/angular-route.min.js"></script> <script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script> <script src="bower_components/angular-leaflet-directive/dist/angular-leaflet-directive.min.js"></script>
<script src="bower_components/underscore/underscore.js"></script> <script src="bower_components/underscore/underscore.js"></script>
<script src="bower_components/geolib/dist/geolib.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<!-- endbuild --> <!-- endbuild -->
<!-- build:js(.tmp) scripts/templates.js --> <!-- build:js(.tmp) scripts/templates.js -->
@ -56,6 +58,8 @@
<script src="scripts/directives/nodeSaved.js"></script> <script src="scripts/directives/nodeSaved.js"></script>
<script src="scripts/directives/tokenForm.js"></script> <script src="scripts/directives/tokenForm.js"></script>
<script src="scripts/dialogs/outsideOfCommunityDialog.js"></script>
<script src="scripts/validation/constraints.js"></script> <script src="scripts/validation/constraints.js"></script>
<!-- endbuild --> <!-- endbuild -->

View file

@ -5,7 +5,8 @@ angular.module('ffffng', [
'ngRoute', 'ngRoute',
'ng', 'ng',
'leaflet-directive', 'leaflet-directive',
'templates-main' 'templates-main',
'ui.bootstrap'
]) ])
.config(function ($routeProvider) { .config(function ($routeProvider) {
$routeProvider $routeProvider

View file

@ -0,0 +1,29 @@
'use strict';
angular.module('ffffng')
.factory('OutsideOfCommunityDialog', function ($modal, config) {
var ctrl = function ($scope, $modalInstance, action) {
$scope.action = action;
$scope.config = config;
$scope.proceed = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
return {
open: function (action) {
return $modal.open({
controller: ctrl,
templateUrl: 'views/dialogs/outsideOfCommunityDialog.html',
resolve: {
action: function () { return action; }
}
});
}
};
});

View file

@ -2,7 +2,17 @@
angular.module('ffffng') angular.module('ffffng')
.directive('fNodeForm', function () { .directive('fNodeForm', function () {
var ctrl = function ($scope, $timeout, Constraints, $element, _, config, $window) { var ctrl = function (
$scope,
$timeout,
Constraints,
$element,
_,
config,
$window,
geolib,
OutsideOfCommunityDialog
) {
$scope.config = config; $scope.config = config;
angular.extend($scope, { angular.extend($scope, {
center: { center: {
@ -29,6 +39,29 @@ angular.module('ffffng')
} }
}); });
if (config.otherCommunityInfo.showBorderForDebugging) {
$scope.paths = {
border: {
color: '#ff0000',
weight: 3,
latlngs: config.otherCommunityInfo.localCommunityPolygon.concat(
[config.otherCommunityInfo.localCommunityPolygon[0]]
)
}
};
}
var geolibPolygon = _.map(config.otherCommunityInfo.localCommunityPolygon, function (point) {
return {
latitude: point.lat,
longitude: point.lng
};
});
var inCommunityArea = function (lat, lng) {
return geolib.isPointInside({latitude: lat, longitude: lng}, geolibPolygon);
};
var updateNodePosition = function (lat, lng) { var updateNodePosition = function (lat, lng) {
$scope.markers.node = { $scope.markers.node = {
lat: lat, lat: lat,
@ -45,15 +78,17 @@ angular.module('ffffng')
$scope.node.coords = lat + ' ' + lng; $scope.node.coords = lat + ' ' + lng;
}); });
function withValidCoords(coords, callback) { function withValidCoords(coords, callback, invalidCallback) {
invalidCallback = invalidCallback || function () {};
coords = coords || ''; coords = coords || '';
coords = coords.trim(); coords = coords.trim();
if (_.isEmpty(coords)) { if (_.isEmpty(coords)) {
return; return invalidCallback();
} }
if ($scope.hasError('coords')) { if ($scope.hasError('coords')) {
return; return invalidCallback();
} }
var parts = coords.split(/\s+/); var parts = coords.split(/\s+/);
@ -61,7 +96,7 @@ angular.module('ffffng')
var lat = Number(parts[0]); var lat = Number(parts[0]);
var lng = Number(parts[1]); var lng = Number(parts[1]);
callback(lat, lng); return callback(lat, lng);
} }
$scope.updateMap = function (optCoords) { $scope.updateMap = function (optCoords) {
@ -90,9 +125,7 @@ angular.module('ffffng')
mac: 'Für die MAC-Adresse gibt es bereits einen Eintrag.' mac: 'Für die MAC-Adresse gibt es bereits einen Eintrag.'
}; };
$scope.onSubmit = function (node) { var doSubmit = function (node) {
submitted = true;
if ($scope.nodeForm.$invalid) { if ($scope.nodeForm.$invalid) {
var firstInvalid = _.filter($element.find('form').find('input'), function (input) { var firstInvalid = _.filter($element.find('form').find('input'), function (input) {
return $scope.nodeForm[input.name].$invalid; return $scope.nodeForm[input.name].$invalid;
@ -114,7 +147,27 @@ angular.module('ffffng')
} }
$window.scrollTo(0, 0); $window.scrollTo(0, 0);
}); });
}.bind(this); };
$scope.onSubmit = function (node) {
submitted = true;
withValidCoords(
node.coords,
function (lat, lng) {
if (!config.otherCommunityInfo.showInfo || inCommunityArea(lat, lng)) {
doSubmit(node);
} else {
OutsideOfCommunityDialog.open($scope.action).result.then(function () {
doSubmit(node);
});
}
},
function () {
doSubmit(node);
}
);
};
$scope.updateMap($scope.node.coords); $scope.updateMap($scope.node.coords);
withValidCoords($scope.node.coords, function (lat, lng) { withValidCoords($scope.node.coords, function (lat, lng) {

View file

@ -1,6 +1,18 @@
'use strict'; 'use strict';
angular.module('ffffng') (function () {
.factory('_', function () { var module = angular.module('ffffng');
return window._;
function lib(name, windowField) {
if (!windowField) {
windowField = name;
}
module.factory(name, function () {
return window[windowField];
}); });
}
lib('_');
lib('geolib');
})();

View file

@ -12,6 +12,7 @@
@import "views/directives/_nodeForm"; @import "views/directives/_nodeForm";
@import "views/directives/_nodeSaved"; @import "views/directives/_nodeSaved";
@import "views/directives/_tokenForm"; @import "views/directives/_tokenForm";
@import "views/dialogs/_outsideOfCommunityDialog";
body { body {
padding-bottom: 40px; padding-bottom: 40px;

View file

@ -0,0 +1,37 @@
.outside-of-community-dialog {
.modal-header {
h3 {
@extend .modal-title;
}
.cancel-icon {
@extend .fa, .fa-times;
position: relative;
float: right;
top: 10px;
right: 0;
margin-left: 15px;
cursor: pointer;
color: $gray;
}
}
.modal-footer {
.proceed {
@extend .btn;
margin-left: 5px;
&.create {
@extend .btn-info;
}
&.update {
@extend .btn-primary;
}
}
}
}

View file

@ -0,0 +1,35 @@
<div class="outside-of-community-dialog">
<div class="modal-header">
<i class="cancel-icon" ng-click="cancel()"></i>
<h3>Dein Router steht außerhalb des {{config.community.name}} Gebiets</h3>
</div>
<div class="modal-body">
<p>
<strong>Erst mal großartig, dass du Freifunk machen möchtest!</strong>
</p>
<p>
Freifunk steht u.a. für Denzentralität. Deshalb wäre es klasse wenn Du Dich einer Community in Deiner Nähe anschließt oder vielleicht sogar
<a href="http://freifunk.net/wie-mache-ich-mit/lokale-gruppe-gruenden/" target="_blank">Deine eigene gründest</a>.
Da aller Anfang schwer ist, macht es für eben diesen vielleicht Sinn sich erst mal einer
<a href="http://freifunk.net/wie-mache-ich-mit/community-finden/" target="_blank">nahegelegen Gruppe</a>
anzuschließen. Auch wir von {{config.community.name}} stehen Dir natürlich gerne mit Rat und Tat zur Seite und mit den
existierenden Hilfsmitteln ist die technische Hürde auch nicht mehr ganz so gigantisch.
</p>
<p>
Es gibt auch technische Gründe, die gegen eine Erweiterung über die Grenzen von {{config.community.name}} hinaus sprechen.
Das Problem mit Mesh-Netzen heute ist, dass sie nicht besonders gut skalieren und mit jedem weiteren Router die Leistung nach
unten geht.
</p>
<p>
Im Moment kommen ständig neue Freifunk-Communities dazu. Welche Communities es schon gibt, siehts Du
<a href="http://freifunk.net/wie-mache-ich-mit/community-finden/" target="_blank">in dieser Übersicht</a>.
</p>
</div>
<div class="modal-footer">
<button class="cancel" ng-click="cancel()">Abbrechen</button>
<button class="proceed {{action}}" ng-click="proceed()" ng-switch="action">
<span ng-switch-when="create"><i class="fa fa-dot-circle-o"></i> Knoten dennoch anmelden</span>
<span ng-switch-when="update"><i class="fa fa-pencil"></i> Daten dennoch ändern</span>
</button>
</div>
</div>

View file

@ -49,7 +49,7 @@
</span> </span>
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<leaflet class="map" center="center" layers="layers" markers="markers"></leaflet> <leaflet class="map" center="center" layers="layers" markers="markers" paths="paths"></leaflet>
</div> </div>
</div> </div>
</div> </div>

View file

@ -10,11 +10,13 @@
"bootstrap-sass-official": "~3.1.1", "bootstrap-sass-official": "~3.1.1",
"es5-shim": "~3.4.0", "es5-shim": "~3.4.0",
"font-awesome": "~4.1.0", "font-awesome": "~4.1.0",
"geolib": "~2.0.9",
"jquery": "~2.1.1", "jquery": "~2.1.1",
"json3": "~3.3.1", "json3": "~3.3.1",
"leaflet-dist": "~0.7.2", "leaflet-dist": "~0.7.2",
"sass-bootstrap": "~3.0.2", "sass-bootstrap": "~3.0.2",
"underscore": "~1.6.0" "underscore": "~1.6.0",
"angular-bootstrap": "~0.11.0"
}, },
"devDependencies": { "devDependencies": {
"angular-mocks": "1.2.16", "angular-mocks": "1.2.16",