Browse Source

started implementing barts design, improved local ip filter on main, changed js animation flows

pull/3/head
rscmbbng 11 years ago
parent
commit
105fd7b6ce
  1. 129
      main.py
  2. BIN
      web/images/bclogo.png
  3. BIN
      web/images/marker-icon.png
  4. 18
      web/index.py
  5. 99
      web/js/bc.js
  6. 17
      web/js/leaflet/leaflet.css
  7. 599
      web/js/rlayer-src.js
  8. 66
      web/style.css

129
main.py

@ -322,6 +322,9 @@ class bc(object):
if self.options.debug == True:
print 'Target open, with results \n'
return
if '[prohibited]' in output[-1]:
if self.options.debug == True:
print 'prohibited'
def traces(self):
'''
@ -345,7 +348,7 @@ class bc(object):
self.lft()
if self.options.debug == True:
logfile = open('tracelogfile', 'a')
thingstolog = ['='*45 + "\n", "Browser: ", self.browser_path.split('/')[-1], "\n", "Version: ", self.browser_version, "\n", "Path to browser: ", self.browser_path, "\n", "History db: ", self.browser_history_path, "\n","URL: ", self.url[0], "\n", "Host: ",url, "\n", "Host ip: ", url_ip, "\n", '='*45, "\n"]
thingstolog = ['='*45 + "\n", "Browser: ", self.browser_path.split('/')[-1], "\n", "Version: ", self.browser_version, "\n", "Path to browser: ", self.browser_path, "\n", "History db: ", self.browser_history_path, "\n","URL: ", self.url, "\n", "Host: ",url, "\n", "Host ip: ", url_ip, "\n", '='*45, "\n"]
for item in thingstolog:
logfile.write(item)
print '='*45 + "\n" + "Packages Route:\n" + '='*45
@ -357,57 +360,61 @@ class bc(object):
for ip in line:
if re.match(r'\d{1,4}\.\dms$', ip):
self.timestamp = ip.replace('ms', '')
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip):
self.hop_ip = ip
record = self.geoip.record_by_addr(ip)
try:
self.asn = self.geoasn.org_by_addr(ip)
except:
self.asn = 'No ASN provided'
#print record
try:
self.hop_host_name = socket.gethostbyaddr(ip)[0]
except:
self.hop_host_name = 'No hostname'
try:
longitude = str(record['longitude'])
self.longitude = longitude
latitude = str(record['latitude'])
self.latitude = latitude
except:
self.longitude = '-'
self.latitude = '-'
try:
if record.has_key('country_name') and record['city'] is not '':
country = record['country_name']
city = record['city']
print "Trace:", self.hop_count, "->", ip, "->", longitude + ":" + latitude, "->", city, "->", country, "->", self.hop_host_name, "->", self.asn, '->', self.timestamp+'ms'
#self.hop_count +=1
self.city = city
self.country = country
self.server_name = self.hop_host_name
cc = record['country_code'].lower()
elif record.has_key('country_name'):
country = record['country_name']
print "Trace:", self.hop_count, "->", ip, "->", longitude + ":" + latitude, "->", country, "->", self.hop_host_name, "->", self.asn, '->', self.timestamp+'ms'
self.country = country
self.city = '-'
self.server_name = self.hop_host_name
cc = record['country_code'].lower()
#self.hop_count+=1
self.vardict = {'url': self.url, 'destination_ip': self.destination_ip, 'hop_count': self.hop_count,'hop_ip': self.hop_ip, 'server_name': self.server_name, 'country': self.country, 'city': self.city, 'longitude': self.longitude, 'latitude': self.latitude, 'asn' : self.asn, 'timestamp' : self.timestamp, 'country_code': cc }
except:
print "Trace:", self.hop_count, "->", "Not allowed"
self.vardict = {'url': self.url, 'destination_ip': self.destination_ip, 'hop_count': self.hop_count,'hop_ip': self.hop_ip, 'server_name': self.server_name, 'country': '-', 'city': '-', 'longitude': '-', 'latitude': '-', 'asn' : self.asn, 'timestamp' : self.timestamp, 'country_code': '-' }
if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip) or re.match(r'^192.168\.\d{1,3}\.\d{1,3}$', ip) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', ip):
pass
else:
if re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip):
self.hop_ip = ip
record = self.geoip.record_by_addr(ip)
try:
self.asn = self.geoasn.org_by_addr(ip)
except:
self.asn = 'No ASN provided'
#print record
try:
self.hop_host_name = socket.gethostbyaddr(ip)[0]
except:
self.hop_host_name = 'No hostname'
try:
longitude = str(record['longitude'])
self.longitude = longitude
latitude = str(record['latitude'])
self.latitude = latitude
except:
self.longitude = '-'
self.latitude = '-'
try:
if record.has_key('country_name') and record['city'] is not '':
country = record['country_name']
city = record['city']
print "Trace:", self.hop_count, "->", ip, "->", longitude + ":" + latitude, "->", city, "->", country, "->", self.hop_host_name, "->", self.asn, '->', self.timestamp+'ms'
#self.hop_count +=1
self.city = city
self.country = country
self.server_name = self.hop_host_name
cc = record['country_code'].lower()
elif record.has_key('country_name'):
country = record['country_name']
print "Trace:", self.hop_count, "->", ip, "->", longitude + ":" + latitude, "->", country, "->", self.hop_host_name, "->", self.asn, '->', self.timestamp+'ms'
self.country = country
self.city = '-'
self.server_name = self.hop_host_name
cc = record['country_code'].lower()
#self.hop_count+=1
self.vardict = {'url': self.url, 'destination_ip': self.destination_ip, 'hop_count': self.hop_count,'hop_ip': self.hop_ip, 'server_name': self.server_name, 'country': self.country, 'city': self.city, 'longitude': self.longitude, 'latitude': self.latitude, 'asn' : self.asn, 'timestamp' : self.timestamp, 'country_code': cc }
except:
#pass
print "Trace:", self.hop_count, "->", "Not allowed", ip
self.vardict = {'url': self.url, 'destination_ip': self.destination_ip, 'hop_count': self.hop_count,'hop_ip': self.hop_ip, 'server_name': self.server_name, 'country': '-', 'city': '-', 'longitude': '-', 'latitude': '-', 'asn' : self.asn, 'timestamp' : self.timestamp, 'country_code': '-' }
self.hop_count+=1
# write xml data to file
self.result_list.append(self.vardict)
xml_results = xml_reporting(self)
xml_results.print_xml_results('data.xml')
if self.options.export_xml:
open(self.options.export_xml, 'w') # starting a new xml data container in write mode
xml_results.print_xml_results(self.options.export_xml)
self.hop_count+=1
# write xml data to file
self.result_list.append(self.vardict)
xml_results = xml_reporting(self)
xml_results.print_xml_results('data.xml')
if self.options.export_xml:
open(self.options.export_xml, 'w') # starting a new xml data container in write mode
xml_results.print_xml_results(self.options.export_xml)
if self.options.debug == True:
logfile.close()
@ -493,7 +500,7 @@ class bc(object):
# run traceroutes
match_ip = self.url[0].strip('http://').strip(':8080')
#regex for filtering local network IPs
if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^192.168\.\d{1,3}$', match_ip) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', match_ip) or match_ip.startswith('file://'):
if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^192.168\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', match_ip) or match_ip.startswith('file://'):
print '='*45 + "\n", "Target:\n" + '='*45 + "\n"
print "URL:", self.url[0], "\n"
print "Warning: This target is not valid!.\n"
@ -507,14 +514,14 @@ class bc(object):
else:
traces = self.try_running(self.traces, "\nInternal error tracerouting.")
# start web mode (on a different thread)
try:
t = threading.Thread(target=BorderCheckWebserver, args=(self, ))
t.daemon = True
t.start()
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
t.join()
sys.exit()
try:
t = threading.Thread(target=BorderCheckWebserver, args=(self, ))
t.daemon = True
t.start()
time.sleep(2)
except (KeyboardInterrupt, SystemExit):
t.join()
sys.exit()
# open same browser of history access on a new tab
try:
webbrowser.open('http://127.0.0.1:8080', new=1)
@ -537,7 +544,7 @@ class bc(object):
print "URL:", self.url[0], "\n"
pass
if url != self.old_url:
if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^192.168\.\d{1,3}$', match_ip) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', match_ip):
if re.match(r'^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^192.168\.\d{1,3}\.\d{1,3}$', match_ip) or re.match(r'^172.(1[6-9]|2[0-9]|3[0-1]).[0-9]{1,3}.[0-9]{1,3}$', match_ip):
pass
else:
if self.url[0].startswith('file://'):

BIN
web/images/bclogo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
web/images/marker-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

18
web/index.py

@ -26,7 +26,7 @@ timestamp_list = []
last_hop = int(xml.findall('hop')[-1].text)
country_code_list = []
for counter in range(1, last_hop+1):
for counter in range(0, last_hop+1):
url = xml.getroot().text
hop_element = parseString(dom.getElementsByTagName('hop')[counter].toxml().encode('utf-8'))
hop = xml.findall('hop')[counter].text
@ -60,7 +60,7 @@ output = """
<link rel="stylesheet" href="js/cluster/MarkerCluster.Default.css"/>
<link rel="stylesheet" href="js/cluster/MarkerCluster.css"/>
<script src="js/leaflet/leaflet.js"></script>
<script src="js/rlayer-modified.min.js"></script>
<script src="js/rlayer-src.js"></script>
<script src="js/raphael.js"></script>
<script src="js/jquery-1.10.2.min.js"></script>
<script src="js/bc.js"></script>
@ -79,9 +79,19 @@ output = """
</head>
<body>
<div id="wrapper">
<div id="header">"""+url+"""</div>
<div class="header">Travelling to:</div>
<div class ="header" id="url">"""+url+"""</div>
<div id="map" style="width: 100%; height: 100%"></div>
<div id="bar"><button id='button'><</button></div>
<div class ="bar">
<div id="button"> > </div>
<div class = info>
<div> <img src='images/bclogo.png'></img></div>
<div id='info-text'> for some reason if the text is tooo<br /> wide/long nothing appears here..fucking black magicfor some reason if the text is tooofor some reason if the text is tooo
<div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
hop_list = """+str(hop_list)+"""

99
web/js/bc.js

@ -3,30 +3,57 @@ window.onload = function () {
var map = L.map('map',{
minZoom: 2,
maxZoom:6,
zoomControl:false
}).setView(latlong[index], 5);
}).setView(latlong[index], 4);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
//setting the controls:
new L.Control.Zoom({
position: 'topright'}
).addTo(map)
//custom markers:
var customIcon = L.icon({
iconUrl: 'images/marker-icon.png',
iconSize: [20, 20], // size of the icon
iconAnchor: [10, 10], // point of the icon which will correspond to marker's location
popupAnchor: [-200, 200] // point from which the popup should open relative to the iconAnchor
});
//the slider bar
$('.info').hide()
slide = 0
$('#button').bind('click', function(){
$('#bar').animate({"width": '200'})
var info = $("<div id = info><p>this is where info goes</p><p>I will make a 'slide back' option later</p></div>")
.appendTo("#bar")
console.log('click')
if (slide == 0){
$('.bar').animate({"width": '300'})
$('.info').show()
$('#button').html('<')
}
slide += 1
if (slide == 2){
$('.bar').animate({"width": '20'})
$('.info').hide()
$('#button').html('>')
slide = 0}
})
})
$('#but').bind('click', function(){
console.log('click')
$('.leaflet-popup-content-wrapper').css({'height':'700px'})
$('#metadata-content').show()
})
//function chain for drawing the markers and lines on the map.
delay = (500+timestamp_list[index]) //sets the animationspeed
delay = (100+timestamp_list[index]) //sets the animationspeed
clusterGroups = {} //contains all country specific clusters
@ -58,26 +85,42 @@ window.onload = function () {
function AddMarker(src, index){
makeClusterGroups(country_code_list, index)
var marker = L.marker([src[0], src[1]])
var marker = L.marker([src[0], src[1]],{icon: customIcon})
var popup = L.Popup({
maxHeight: 50})
var popupcontent = "<p>Hop no:"+hop_list[index]+"<br /><div id='metadata' $(this).hide()><button id='but'>show metadata</button><div id='metadata-content'>Server name:<br />"+server_name_list[index]+"<br />Network owner:<br />"+asn_list[index]+"</div></div>"
var popupcontent = "<p>Hop no:"+hop_list[index]+"<br />Server name:<br />"+server_name_list[index]+"<br />Network owner:<br />"+asn_list[index]+"</p>"
marker.bindPopup(popupcontent)
AddMarkerCluster(marker, index)
}
function AddStep(src, dest, index){
var b = new R.BezierAnim([src, dest], {})
map.addLayer(b)
AddMarker(src, index)
//console.log('AddStepp'+index)
processStep(index)
//console.log(delay)
}
var b = new R.BezierAnim([src, dest])
map.addLayer(b)
AddMarker(src, index)
//console.log('AddStepp'+index)
if (index < counter_max){
map.panTo(latlong[index+1],{
animate: true,
duration: 2
})}
else
if (index = counter_max){
map.panTo(latlong[index],{
animate: true,
duration: 2
})
}
window.setTimeout(function(){
processStep(index)
}, 2000)
//console.log(delay)
}
function processStep (index) {
map.panTo(latlong[index]);
if (index < counter_max-2) {
if (index < counter_max-1) {
//console.log('hop#', hop_list[index])
changeFavicon('images/world/'+country_code_list[index]+'.png')
window.setTimeout(function () {
@ -86,7 +129,8 @@ window.onload = function () {
}, delay);}
else
if (index < counter_max-1){
if (index < counter_max){
// map.panTo(latlong[index+1]);
//console.log('hop#', hop_list[index])
changeFavicon('images/world/'+country_code_list[index]+'.png')
window.setTimeout(function () {
@ -94,14 +138,15 @@ window.onload = function () {
}, delay);}
else
if (index = counter_max-1){
if (index = counter_max){
// map.panTo(latlong[index]);
changeFavicon('images/world/'+country_code_list[index]+'.png')
//console.log('fin')
console.log('fin')
//map.fitBounds([bounds])
}
index = index + 1
delay = (500 + timestamp_list[index])
delay = (100 + timestamp_list[index])
}
$('.leaflet-marker-icon').bind('click', function(){
console.log('clickkkk')

17
web/js/leaflet/leaflet.css

@ -396,8 +396,6 @@
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
-webkit-border-radius: 12px;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
@ -413,19 +411,6 @@
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;
@ -440,7 +425,7 @@
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
color: #white;
text-decoration: none;
font-weight: bold;
background: transparent;

599
web/js/rlayer-src.js

@ -0,0 +1,599 @@
/*
RaphaelLayer, a JavaScript library for overlaying Raphael objects onto Leaflet interactive maps. http://dynmeth.github.com/RaphaelLayer
(c) 2012-2013, David Howell, Dynamic Methods Pty Ltd
Version 0.1.3
*/
(function() {
var R, originalR;
if (typeof exports != 'undefined') {
R = exports;
} else {
R = {};
originalR = window.R;
R.noConflict = function() {
window.R = originalR;
return R;
};
window.R = R;
}
R.version = '0.1.3';
R.Layer = L.Class.extend({
includes: L.Mixin.Events,
initialize: function(options) {
},
onAdd: function (map) {
this._map = map;
this._map._initRaphaelRoot();
this._paper = this._map._paper;
this._set = this._paper.set();
map.on('viewreset', this.projectLatLngs, this);
this.projectLatLngs();
},
onRemove: function(map) {
map.off('viewreset', this.projectLatLngs, this);
this._map = null;
this._set.forEach(function(item) {
item.remove();
}, this);
this._set.clear();
},
projectLatLngs: function() {
},
animate: function(attr, ms, easing, callback) {
this._set.animate(attr, ms, easing, callback);
return this;
},
hover: function(f_in, f_out, icontext, ocontext) {
this._set.hover(f_in, f_out, icontext, ocontext);
return this;
},
attr: function(name, value) {
this._set.attr(name, value);
return this;
}
});
L.Map.include({
_initRaphaelRoot: function () {
if (!this._raphaelRoot) {
this._raphaelRoot = this._panes.overlayPane;
this._paper = Raphael(this._raphaelRoot);
this.on('moveend', this._updateRaphaelViewport);
this._updateRaphaelViewport();
}
},
_updateRaphaelViewport: function () {
var p = 0.02,
size = this.getSize(),
panePos = L.DomUtil.getPosition(this._mapPane),
min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)),
max = min.add(size.multiplyBy(1 + p*2)),
width = max.x - min.x,
height = max.y - min.y,
root = this._raphaelRoot,
pane = this._panes.overlayPane;
this._paper.setSize(width, height);
L.DomUtil.setPosition(root, min);
root.setAttribute('width', width);
root.setAttribute('height', height);
this._paper.setViewBox(min.x, min.y, width, height, false);
}
});
R.Marker = R.Layer.extend({
initialize: function(latlng, pathString, attr, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlng = latlng;
this._pathString = (typeof pathString == 'string' ? pathString : 'M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z');
this._attr = (typeof pathString == 'object' ? pathString : (attr ? attr : {'fill': '#000'}));
},
projectLatLngs: function() {
if (this._path) this._path.remove();
var p = this._map.latLngToLayerPoint(this._latlng);
var r = Raphael.pathBBox(this._pathString);
this._path = this._paper.path(this._pathString)
.attr(this._attr)
.translate(p.x - 1.05*r.width, p.y - 1.15*r.height)
.toFront();
this._set.push(this._path);
}
});
R.Pulse = R.Layer.extend({
initialize: function(latlng, radius, attr, pulseAttr, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlng = latlng;
this._radius = (typeof radius == 'number' ? radius : 6);
this._attr = (typeof radius == 'object' ? radius : (typeof attr == 'object' ? attr : {'fill': '#30a3ec', 'stroke': '#30a3ec'}));
this._pulseAttr = (typeof radius == 'object' ? attr : typeof pulseAttr == 'object' ? pulseAttr : {
'stroke-width': 3,
'stroke': this._attr.stroke
});
this._repeat = 3;
},
onRemove: function (map) {
R.Layer.prototype.onRemove.call(this, map);
if(this._marker) this._marker.remove();
if(this._pulse) this._pulse.remove();
},
projectLatLngs: function() {
if(this._marker) this._marker.remove();
if(this._pulse) this._pulse.remove();
var p = this._map.latLngToLayerPoint(this._latlng);
this._marker = this._paper.circle(p.x, p.y, this._radius).attr(this._attr);
this._pulse = this._paper.circle(p.x, p.y, this._radius).attr(this._pulseAttr);
var anim = Raphael.animation({
'0%': {transform: 's0.3', opacity: 1.0},
'100%': {transform: 's3.0', opacity: 0.0, easing: '<'}
}, 1000);
this._pulse.animate(anim.repeat(this._repeat));
}
});
R.Polyline = R.Layer.extend({
initialize: function(latlngs, attr, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlngs = latlngs;
this._attr = attr || {'fill': '#000', 'stroke': '#000'};
},
projectLatLngs: function() {
this._set.clear();
if (this._path) this._path.remove();
this._path = this._paper.path(this.getPathString())
.attr(this._attr)
.toBack();
this._set.push(this._path);
},
getPathString: function() {
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
}
return str;
}
});
R.Polygon = R.Layer.extend({
initialize: function(latlngs, attr, options) {
R.Layer.prototype.initialize.call(this, options);
if(latlngs.length == 1) {
if(latlngs[0] instanceof Array) {
latlngs = latlngs[0];
}
}
this._latlngs = latlngs;
this._attr = attr || {'fill': 'rgba(255, 0, 0, 0.5)', 'stroke': '#f00', 'stroke-width': 2};
},
projectLatLngs: function() {
if (this._path) this._path.remove();
this._path = this._paper.path(this.getPathString())
.attr(this._attr)
.toBack();
this._set.push(this._path);
},
getPathString: function() {
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
}
str += 'Z';
return str;
}
});
R.PolygonGlow = R.Layer.extend({
initialize: function(latlngs, attr, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlngs = latlngs;
this._attr = attr || {'fill': 'rgba(255, 0, 0, 1)', 'stroke': '#f00', 'stroke-width': 3};
},
onRemove: function(map) {
R.Layer.prototype.onRemove.call(this, map);
if(this._path) this._path.remove();
},
projectLatLngs: function() {
if (this._path) this._path.remove();
this._path = this._paper.path(this.getPathString())
.attr(this._attr)
.toBack();
var p = this._path;
var fadeIn = function() {
p.animate({
'fill-opacity': 0.25
}, 1000, '<', fadeOut);
};
var fadeOut = function() {
p.animate({
'fill-opacity': 1
}, 1000, '<', fadeIn);
};
fadeOut();
},
getPathString: function() {
for(var i=0, len=this._latlngs.length, str=''; i<len; i++) {
var p = this._map.latLngToLayerPoint(this._latlngs[i]);
str += (i ? 'L' : 'M') + p.x + ' ' + p.y;
}
str += 'Z';
return str;
}
});
R.Bezier = R.Layer.extend({
initialize: function(latlngs, attr, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlngs = latlngs;
this._attr = attr;
},
projectLatLngs: function() {
if(this._path) this._path.remove();
var start = this._map.latLngToLayerPoint(this._latlngs[0]),
end = this._map.latLngToLayerPoint(this._latlngs[1]),
cp = this.getControlPoint(start, end);
this._path = this._paper.path('M' + start.x + ' ' + start.y + 'Q' + cp.x + ' ' + cp.y + ' ' + end.x + ' ' + end.y)
.attr(this._attr)
.toBack();
this._set.push(this._path);
},
getControlPoint: function(start, end) {
var cp = { x: 0, y: 0 };
cp.x = start.x + (end.x - [start.x]) / 2;
cp.y = start.y + (end.y - [start.y]) / 2;
var amp = 0;
if (this.closeTo(start.x, end.x) && !this.closeTo(start.y, end.y)) {
amp = (start.x - end.x) * 1 + 15 * (start.x >= end.x ? 1 : -1);
cp.x = Math.max(start.x, end.x) + amp;
} else {
amp = (end.y - start.y) * 1.5 + 15 * (start.y < end.y ? 1 : -1);
cp.y = Math.min(start.y, end.y) + amp;
}
return cp;
},
closeTo: function(a, b) {
var t = 15;
return (a - b > -t && a - b < t);
}
});
R.BezierAnim = R.Layer.extend({
initialize: function(latlngs, attr, cb, options) {
R.Layer.prototype.initialize.call(this, options);
this._latlngs = latlngs;
this._attr = attr;
this._cb = cb;
},
onRemove: function (map) {
R.Layer.prototype.onRemove.call(this, map);
if(this._path) this._path.remove();
if(this._sub) this._sub.remove();
},
projectLatLngs: function() {
if(this._path) this._path.remove();
if(this._sub) this._sub.remove();
var self = this,
start = this._map.latLngToLayerPoint(this._latlngs[0]),
end = this._map.latLngToLayerPoint(this._latlngs[1]),
cp = this.getControlPoint(start, end),
pathString="M"+start.x+" "+start.y+" L"+end.x+" "+end.y,
line = this._paper.path(pathString).hide();
this._paper.customAttributes.alongBezier = function(a) {
var r = this.data('reverse');
var len = this.data('pathLength');
return {
path: this.data('bezierPath').getSubpath(r ? (1-a)*len : 0, r ? len : a*len)
};
};
var sub = this._sub = this._paper.path()
.data('bezierPath', line)
.data('pathLength', line.getTotalLength())
.data('reverse', false)
.attr({
'stroke': '#BE1E2D',
'alongBezier': 0,
'stroke-width': 1
});
sub.stop().animate({
alongBezier: 1
}, 2000, function() {
//self._cb();
sub.data('reverse', true);
// sub.stop().animate({
// 'alongBezier': 0
// }, 500, function() { sub.remove(); });
});
},
getControlPoint: function(start, end) {
var cp = { x: 0, y: 0 };
cp.x = start.x + (end.x - [start.x]) / 2;
cp.y = start.y + (end.y - [start.y]) / 2;
var amp = 0;
if (this.closeTo(start.x, end.x) && !this.closeTo(start.y, end.y)) {
amp = (start.x - end.x) * 1 + 15 * (start.x >= end.x ? 1 : -1);
cp.x = Math.max(start.x, end.x) + amp;
} else {
amp = (end.y - start.y) * 1.5 + 15 * (start.y < end.y ? 1 : -1);
cp.y = Math.min(start.y, end.y) + amp;
}
return cp;
},
closeTo: function(a, b) {
var t = 15;
return (a - b > -t && a - b < t);
}
});
R.FeatureGroup = L.FeatureGroup.extend({
initialize: function(layers, options) {
L.FeatureGroup.prototype.initialize.call(this, layers, options);
},
animate: function(attr, ms, easing, callback) {
this.eachLayer(function(layer) {
layer.animate(attr, ms, easing, callback);
});
},
onAdd: function(map) {
L.FeatureGroup.prototype.onAdd.call(this,map);
this._set = this._map._paper.set();
for(i in this._layers) {
this._set.push(this._layers[i]._set);
}
},
hover: function(h_in, h_out, c_in, c_out) {
this.eachLayer(function(layer) {
layer.hover(h_in, h_out, c_in, c_out);
});
return this;
},
attr: function(name, value) {
this.eachLayer(function(layer) {
layer.attr(name, value);
});
return this;
}
});
/*
* Contains L.MultiPolyline and L.MultiPolygon layers.
*/
(function () {
function createMulti(Klass) {
return R.FeatureGroup.extend({
initialize: function (latlngs, options) {
this._layers = {};
this._options = options;
this.setLatLngs(latlngs);
},
setLatLngs: function (latlngs) {
var i = 0, len = latlngs.length;
this.eachLayer(function (layer) {
if (i < len) {
layer.setLatLngs(latlngs[i++]);
} else {
this.removeLayer(layer);
}
}, this);
while (i < len) {
this.addLayer(new Klass(latlngs[i++], this._options));
}
return this;
}
});
}
R.MultiPolyline = createMulti(R.Polyline);
R.MultiPolygon = createMulti(R.Polygon);
}());
R.GeoJSON = R.FeatureGroup.extend({
initialize: function (geojson, options) {
L.Util.setOptions(this, options);
this._geojson = geojson;
this._layers = {};
if (geojson) {
this.addGeoJSON(geojson);
}
},
addGeoJSON: function (geojson) {
var features = geojson.features,
i, len;
if (features) {
for (i = 0, len = features.length; i < len; i++) {
this.addGeoJSON(features[i]);
}
return;
}
var isFeature = (geojson.type === 'Feature'),
geometry = isFeature ? geojson.geometry : geojson,
layer = R.GeoJSON.geometryToLayer(geometry, this.options.pointToLayer);
this.fire('featureparse', {
layer: layer,
properties: geojson.properties,
geometryType: geometry.type,
bbox: geojson.bbox,
id: geojson.id,
geometry: geojson.geometry
});
this.addLayer(layer);
}
});
L.Util.extend(R.GeoJSON, {
geometryToLayer: function (geometry, pointToLayer) {
var coords = geometry.coordinates,
layers = [],
latlng, latlngs, i, len, layer;
switch (geometry.type) {
case 'Point':
latlng = this.coordsToLatLng(coords);
return pointToLayer ? pointToLayer(latlng) : new R.Marker(latlng);
case 'MultiPoint':
for (i = 0, len = coords.length; i < len; i++) {
latlng = this.coordsToLatLng(coords[i]);
layer = pointToLayer ? pointToLayer(latlng) : new R.Marker(latlng);
layers.push(layer);
}
return new R.FeatureGroup(layers);
case 'LineString':
latlngs = this.coordsToLatLngs(coords);
return new R.Polyline(latlngs);
case 'Polygon':
latlngs = this.coordsToLatLngs(coords, 1);
return new R.Polygon(latlngs);
case 'MultiLineString':
latlngs = this.coordsToLatLngs(coords, 1);
return new R.MultiPolyline(latlngs);
case "MultiPolygon":
latlngs = this.coordsToLatLngs(coords, 2);
return new R.MultiPolygon(latlngs);
case "GeometryCollection":
for (i = 0, len = geometry.geometries.length; i < len; i++) {
layer = this.geometryToLayer(geometry.geometries[i], pointToLayer);
layers.push(layer);
}
return new R.FeatureGroup(layers);
default:
throw new Error('Invalid GeoJSON object.');
}
},
coordsToLatLng: function (coords, reverse) { // (Array, Boolean) -> LatLng
var lat = parseFloat(coords[reverse ? 0 : 1]),
lng = parseFloat(coords[reverse ? 1 : 0]);
return new L.LatLng(lat, lng, true);
},
coordsToLatLngs: function (coords, levelsDeep, reverse) { // (Array, Number, Boolean) -> Array
var latlng,
latlngs = [],
i, len;
for (i = 0, len = coords.length; i < len; i++) {
latlng = levelsDeep ?
this.coordsToLatLngs(coords[i], levelsDeep - 1, reverse) :
this.coordsToLatLng(coords[i], reverse);
latlngs.push(latlng);
}
return latlngs;
}
});
}());

66
web/style.css

@ -1,13 +1,36 @@
#header{
top:40px;
width: 100%;
@font-face {
font-family: "SourceSansPro-Regular";
src: url('fonts/SourceSansPro-Regular.otf') format("truetype");
}
@font-face {
font-family: "SourceSansPro-Bold";
src: url('fonts/SourceSansPro-Bold.otf') format("truetype");
}
body{
font-family: 'SourceSansPro-Regular', Arial, serif;
font-size: 10px;
}
.header{
top:35px;
width: inherit;
height: 10px;
position: absolute;
z-index: 3;
color:red;
text-align: center;
color:white;
font-size: 12;
text-shadow: 0px 2px 3px rgba(150, 150, 150, 1)
}
#url{
top:50px;
font-size: 30px;
color:white;
font-family: 'SourceSansPro-Bold';
text-shadow: 0px 2px 3px rgba(150, 150, 150, 1)
}
#map {
z-index:1;
top: 0px;
@ -16,20 +39,41 @@
}
#bar{
.bar{
z-index:2;
top:0px;
right:0px;
width:50px;
left:0px;
width:20px;
height:100%;
position:fixed;
position:absolute;
background-color: white;
border-left: 1px black solid;
-webkit-box-shadow: 12px 0px 8px -5px rgba(0, 0, 0, 0.5);
box-shadow: 12px 0px 8px -5px rgba(0, 0, 0, 0.5);
}
#button{
z-index:3;
float:right;
width: 10px;
height: 90%;
padding: 5px;
font-size: 20px;
}
.info{
z-index: 4;
color:black;
padding: 15px;
float: left;
overflow: auto;
#info{
color:red;
}
.info img{
top :0px;
}
.info #info-text{
text-align: center;
height:inherit;
}

Loading…
Cancel
Save