work on result rendering
* add tracks + heat map * copy result lists instead of using just a reference * introduce proper loggingsimu_flags
parent
b81719aba3
commit
36ff8fd0be
|
|
@ -1,15 +1,15 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from .analyzer import Analyzer, Result
|
from .analyzer import Analyzer, Result
|
||||||
from .analyzer.biogames import BoardDurationAnalyzer, SimulationRoundsAnalyzer
|
from .analyzer.biogames import BoardDurationAnalyzer, SimulationRoundsAnalyzer, ActivationSequenceAnalyzer
|
||||||
from .analyzer.default import LogEntryCountAnalyzer, LocationAnalyzer, LogEntrySequenceAnalyzer, ActionSequenceAnalyzer
|
from .analyzer.default import LogEntryCountAnalyzer, LocationAnalyzer, LogEntrySequenceAnalyzer, ActionSequenceAnalyzer
|
||||||
from .analyzer.locomotion import LocomotionActionAnalyzer, CacheSequenceAnalyzer
|
from .analyzer.locomotion import LocomotionActionAnalyzer, CacheSequenceAnalyzer
|
||||||
from .analyzer.mask import MaskSpatials
|
from .analyzer.mask import MaskSpatials
|
||||||
from .render import Render
|
from .render import Render
|
||||||
from .render.default import PrintRender, JSONRender
|
from .render.default import PrintRender, JSONRender, TrackRender, HeatMapRender
|
||||||
from .render.locomotion import LocomotionActionRelativeRender, LocomotionActionAbsoluteRender, \
|
from .render.locomotion import LocomotionActionRelativeRender, LocomotionActionAbsoluteRender, \
|
||||||
LocomotionActionRatioRender
|
LocomotionActionRatioRender
|
||||||
from .render.biogames import SimulationRoundsRender
|
from .render.biogames import SimulationRoundsRender, BoardDurationHistRender, BoardDurationBoxRender
|
||||||
|
|
||||||
__FALLBACK__ = PrintRender
|
__FALLBACK__ = PrintRender
|
||||||
__MAPPING__ = {
|
__MAPPING__ = {
|
||||||
|
|
@ -23,7 +23,18 @@ __MAPPING__ = {
|
||||||
SimulationRoundsAnalyzer: [
|
SimulationRoundsAnalyzer: [
|
||||||
JSONRender,
|
JSONRender,
|
||||||
SimulationRoundsRender,
|
SimulationRoundsRender,
|
||||||
]
|
],
|
||||||
|
BoardDurationAnalyzer: [
|
||||||
|
BoardDurationHistRender,
|
||||||
|
BoardDurationBoxRender,
|
||||||
|
],
|
||||||
|
ActivationSequenceAnalyzer: [
|
||||||
|
JSONRender,
|
||||||
|
],
|
||||||
|
LocationAnalyzer: [
|
||||||
|
TrackRender,
|
||||||
|
#HeatMapRender,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -37,4 +48,6 @@ def render(cls: type, results: List[Result]):
|
||||||
for r in get_renderer(cls):
|
for r in get_renderer(cls):
|
||||||
p = r()
|
p = r()
|
||||||
p.result_types.append(cls)
|
p.result_types.append(cls)
|
||||||
p.render(results)
|
rendered = p.render(results)
|
||||||
|
if rendered:
|
||||||
|
print(str(r))
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,24 @@
|
||||||
from analyzers.settings import LogSettings
|
from analyzers.settings import LogSettings
|
||||||
|
import logging
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Result:
|
class Result:
|
||||||
def __init__(self, analysis, result):
|
def __init__(self, analysis, result):
|
||||||
self.result = result
|
self.result = result
|
||||||
self.__analysis__ = analysis
|
self.__analysis__ = analysis
|
||||||
|
log.debug("set" + str(len(self.result)))
|
||||||
|
|
||||||
def analysis(self):
|
def analysis(self):
|
||||||
return self.__analysis__
|
return self.__analysis__
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
|
log.debug("get" + str(len(self.result)))
|
||||||
return self.result
|
return self.result
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Result " + str(self.__analysis__) + ": " + str(type(self.result)) + ">"
|
return "<Result " + str(self.__analysis__) + ": " + str(type(self.result)) + " "+str(len(self.result))+">"
|
||||||
|
|
||||||
|
|
||||||
class Analyzer:
|
class Analyzer:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from . import Result, LogSettings, Analyzer
|
from . import Result, LogSettings, Analyzer
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class BoardDurationAnalyzer(Analyzer):
|
class BoardDurationAnalyzer(Analyzer):
|
||||||
"""
|
"""
|
||||||
|
|
@ -61,3 +64,21 @@ class SimulationRoundsAnalyzer(Analyzer):
|
||||||
simu_id = entry['answers']["@id"]
|
simu_id = entry['answers']["@id"]
|
||||||
self.store[simu_id] += 1
|
self.store[simu_id] += 1
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class ActivationSequenceAnalyzer(Analyzer):
|
||||||
|
__name__ = "ActivationSequence"
|
||||||
|
|
||||||
|
def __init__(self, settings: LogSettings):
|
||||||
|
super().__init__(settings)
|
||||||
|
self.store = []
|
||||||
|
|
||||||
|
def result(self) -> Result:
|
||||||
|
return Result(type(self), self.store)
|
||||||
|
|
||||||
|
def process(self, entry: dict) -> bool:
|
||||||
|
if entry[self.settings.type_field] in self.settings.sequences['start']:
|
||||||
|
if entry['cache']:
|
||||||
|
self.store.append(entry['cache']['@id'])
|
||||||
|
else:
|
||||||
|
logger.error("null cache")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import json
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from . import Result, LogSettings, Analyzer
|
from . import Result, LogSettings, Analyzer
|
||||||
|
|
@ -10,25 +10,19 @@ class LocationAnalyzer(Analyzer):
|
||||||
"""
|
"""
|
||||||
entries = []
|
entries = []
|
||||||
__name__ = "Location"
|
__name__ = "Location"
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
class Formats:
|
|
||||||
geojson = 0
|
|
||||||
|
|
||||||
def __init__(self, settings: LogSettings):
|
def __init__(self, settings: LogSettings):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
|
|
||||||
def result(self) -> Result:
|
def result(self) -> Result:
|
||||||
# return self.entries
|
self.log.debug(len(self.entries))
|
||||||
return Result(type(self), self.entries)
|
return Result(type(self), list(self.entries))
|
||||||
|
|
||||||
def render(self, format: int = Formats.geojson):
|
|
||||||
if format is self.Formats.geojson:
|
|
||||||
return json.dumps([entry['location']['coordinates'] for entry in self.entries])
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def process(self, entry: dict) -> bool:
|
def process(self, entry: dict) -> bool:
|
||||||
if entry[self.settings.type_field] in self.settings.spatials:
|
if entry[self.settings.type_field] in self.settings.spatials:
|
||||||
self.entries.append(entry)
|
self.entries.append(entry)
|
||||||
|
#self.log.debug(len(self.entries))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -57,7 +51,7 @@ class LogEntrySequenceAnalyzer(Analyzer):
|
||||||
__name__ = "LogEntrySequence"
|
__name__ = "LogEntrySequence"
|
||||||
|
|
||||||
def result(self) -> Result:
|
def result(self) -> Result:
|
||||||
return Result(type(self), self.store)
|
return Result(type(self), list(self.store))
|
||||||
|
|
||||||
def process(self, entry: dict) -> bool:
|
def process(self, entry: dict) -> bool:
|
||||||
entry_type = entry[self.settings.type_field]
|
entry_type = entry[self.settings.type_field]
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ class CacheSequenceAnalyzer(Analyzer):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def result(self) -> Result:
|
def result(self) -> Result:
|
||||||
return Result(type(self), self.store)
|
return Result(type(self), list(self.store))
|
||||||
|
|
||||||
def __init__(self, settings: LogSettings):
|
def __init__(self, settings: LogSettings):
|
||||||
super().__init__(settings)
|
super().__init__(settings)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from typing import List, Tuple
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
from . import Render
|
from . import Render
|
||||||
from .. import Result, SimulationRoundsAnalyzer
|
from .. import Result, SimulationRoundsAnalyzer, BoardDurationAnalyzer
|
||||||
|
|
||||||
|
|
||||||
def plot(src_data: List[Tuple[str, List[int]]]):
|
def plot(src_data: List[Tuple[str, List[int]]]):
|
||||||
|
|
@ -29,3 +29,36 @@ class SimulationRoundsRender(Render):
|
||||||
plot(data_tuples)
|
plot(data_tuples)
|
||||||
|
|
||||||
result_types = [SimulationRoundsAnalyzer]
|
result_types = [SimulationRoundsAnalyzer]
|
||||||
|
|
||||||
|
class BoardDurationHistRender(Render):
|
||||||
|
|
||||||
|
result_types = [BoardDurationAnalyzer]
|
||||||
|
|
||||||
|
def render(self, results: List[Result]):
|
||||||
|
data = []
|
||||||
|
for result in self.filter(results):
|
||||||
|
session = result.get()
|
||||||
|
_data = []
|
||||||
|
for board in session:
|
||||||
|
if "active" in board:
|
||||||
|
_data.append(board["active"])
|
||||||
|
else:
|
||||||
|
_data.append(0)
|
||||||
|
data.append(_data)
|
||||||
|
n, bins, patches = plt.hist(data, log=True)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
class BoardDurationBoxRender(Render):
|
||||||
|
result_types = [BoardDurationAnalyzer]
|
||||||
|
|
||||||
|
def render(self, results: List[Result]):
|
||||||
|
data = defaultdict(list)
|
||||||
|
for result in self.filter(results):
|
||||||
|
get = result.get()
|
||||||
|
for board in get:
|
||||||
|
duration = board['active'] if 'active' in board else 0
|
||||||
|
data[board['id']].append(duration)
|
||||||
|
data_tuples = [(key, data[key]) for key in sorted(data)]
|
||||||
|
data_tuples = sorted(data_tuples, key=lambda x: sum(x[1]))
|
||||||
|
plot(data_tuples)
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from . import Render, Result
|
from . import Render, Result
|
||||||
|
from .. import LocationAnalyzer
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PrintRender(Render):
|
class PrintRender(Render):
|
||||||
|
|
@ -12,3 +16,34 @@ class PrintRender(Render):
|
||||||
class JSONRender(Render):
|
class JSONRender(Render):
|
||||||
def render(self, results: List[Result]):
|
def render(self, results: List[Result]):
|
||||||
print(json.dumps([r.get() for r in self.filter(results)], indent=1))
|
print(json.dumps([r.get() for r in self.filter(results)], indent=1))
|
||||||
|
|
||||||
|
|
||||||
|
class TrackRender(Render):
|
||||||
|
result_types = [LocationAnalyzer]
|
||||||
|
|
||||||
|
def render(self, results: List[Result]):
|
||||||
|
data = []
|
||||||
|
log.debug(results)
|
||||||
|
for result in self.filter(results):
|
||||||
|
if len(result.get()) > 0:
|
||||||
|
data.append(
|
||||||
|
[[entry['location']['coordinates'][1], entry['location']['coordinates'][0]] for entry in
|
||||||
|
result.get()])
|
||||||
|
dumps = json.dumps(data)
|
||||||
|
with open("track_data.js", "w") as out:
|
||||||
|
out.write("tracks=" + dumps + ";")
|
||||||
|
return dumps
|
||||||
|
|
||||||
|
|
||||||
|
class HeatMapRender(TrackRender):
|
||||||
|
weight = 0.01
|
||||||
|
|
||||||
|
def render(self, results: List[Result]):
|
||||||
|
raw = super(HeatMapRender, self).render(results)
|
||||||
|
data = []
|
||||||
|
for session in json.loads(raw):
|
||||||
|
data += [(entry[0], entry[1], self.weight) for entry in session]
|
||||||
|
dumps = json.dumps(data)
|
||||||
|
with open('heat_data.js', 'w') as out:
|
||||||
|
out.write("coords = " + dumps + ";")
|
||||||
|
return dumps
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,18 @@
|
||||||
],
|
],
|
||||||
"analyzers": {
|
"analyzers": {
|
||||||
"analyzers": [
|
"analyzers": [
|
||||||
"LocationAnalyzer",
|
"LocationAnalyzer"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"disabled_analyzers":[
|
||||||
"LogEntryCountAnalyzer",
|
"LogEntryCountAnalyzer",
|
||||||
"LogEntrySequenceAnalyzer",
|
"LogEntrySequenceAnalyzer",
|
||||||
"ActionSequenceAnalyzer",
|
"ActionSequenceAnalyzer",
|
||||||
"BoardDurationAnalyzer",
|
"BoardDurationAnalyzer",
|
||||||
"LocomotionActionAnalyzer",
|
"LocomotionActionAnalyzer",
|
||||||
"CacheSequenceAnalyzer",
|
"CacheSequenceAnalyzer",
|
||||||
"SimulationRoundsAnalyzer"
|
"SimulationRoundsAnalyzer",
|
||||||
]
|
"ActivationSequenceAnalyzer"],
|
||||||
},
|
|
||||||
"sequences": {
|
"sequences": {
|
||||||
"start": "de.findevielfalt.games.game2.instance.log.entry.LogEntryCache",
|
"start": "de.findevielfalt.games.game2.instance.log.entry.LogEntryCache",
|
||||||
"end": {
|
"end": {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
from load import LOADERS
|
from load import LOADERS
|
||||||
from typing import List
|
from typing import List
|
||||||
from analyzers import get_renderer, Analyzer, render
|
from analyzers import get_renderer, Analyzer, render
|
||||||
|
|
@ -5,6 +6,10 @@ from analyzers.settings import LogSettings, load_settings
|
||||||
import analyzers
|
import analyzers
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(format='%(levelname)s %(name)s:%(message)s', level=logging.DEBUG)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def process_log(log_id: str, settings: LogSettings) -> List[Analyzer]:
|
def process_log(log_id: str, settings: LogSettings) -> List[Analyzer]:
|
||||||
logfile = "data/inst_{id}.{format}".format(id=log_id, format=settings.log_format)
|
logfile = "data/inst_{id}.{format}".format(id=log_id, format=settings.log_format)
|
||||||
loader = LOADERS[settings.log_format]()
|
loader = LOADERS[settings.log_format]()
|
||||||
|
|
@ -28,7 +33,8 @@ if __name__ == '__main__':
|
||||||
"20d4244719404ffab0ca386c76e4b112",
|
"20d4244719404ffab0ca386c76e4b112",
|
||||||
"56d9b64144ab44e7b90bf766f3be32e3",
|
"56d9b64144ab44e7b90bf766f3be32e3",
|
||||||
"dc2cdc28ca074715b905e4aa5badff10",
|
"dc2cdc28ca074715b905e4aa5badff10",
|
||||||
"e32b16998440475b994ab46d481d3e0c", ]
|
"e32b16998440475b994ab46d481d3e0c",
|
||||||
|
]
|
||||||
log_ids = [
|
log_ids = [
|
||||||
"34fecf49dbaca3401d745fb467",
|
"34fecf49dbaca3401d745fb467",
|
||||||
"44ea194de594cd8d63ac0314be",
|
"44ea194de594cd8d63ac0314be",
|
||||||
|
|
@ -41,16 +47,17 @@ if __name__ == '__main__':
|
||||||
"fe1331481f85560681f86827ec",
|
"fe1331481f85560681f86827ec",
|
||||||
"fec57041458e6cef98652df625", ]
|
"fec57041458e6cef98652df625", ]
|
||||||
results = []
|
results = []
|
||||||
|
#TODO: capture session ID, dict
|
||||||
for log_id in log_ids:
|
for log_id in log_ids:
|
||||||
for analysis in process_log(log_id, settings):
|
for analysis in process_log(log_id, settings):
|
||||||
print("* Result for " + analysis.name())
|
logger.info("* Result for " + analysis.name())
|
||||||
# print(analysis.result())
|
# print(analysis.result())
|
||||||
# print(analysis.render())
|
# print(analysis.render())
|
||||||
results.append(analysis.result())
|
results.append(analysis.result())
|
||||||
if False:
|
if False:
|
||||||
for r in get_renderer(analyzers.LocomotionActionAnalyzer):
|
for r in get_renderer(analyzers.LocomotionActionAnalyzer):
|
||||||
r().render(results)
|
r().render(results)
|
||||||
render(analyzers.SimulationRoundsAnalyzer, results)
|
render(analyzers.LocationAnalyzer, results)
|
||||||
|
|
||||||
# for analyzers in analyzers:
|
# for analyzers in analyzers:
|
||||||
# if analyzers.name() in ["LogEntryCount", "ActionSequenceAnalyzer"]:
|
# if analyzers.name() in ["LogEntryCount", "ActionSequenceAnalyzer"]:
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
[]
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Leaflet.heat demo</title>
|
||||||
|
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
|
||||||
|
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
|
||||||
|
<style>
|
||||||
|
#map { width: 1024px; height: 768px; }
|
||||||
|
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
|
||||||
|
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
|
||||||
|
a { color: #0077ff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="map"></div>
|
||||||
|
|
||||||
|
<!-- <script src="../node_modules/simpleheat/simpleheat.js"></script>
|
||||||
|
<script src="../src/HeatLayer.js"></script> -->
|
||||||
|
|
||||||
|
<script src="https://rawgit.com/Leaflet/Leaflet.heat/gh-pages/dist/leaflet-heat.js"></script>
|
||||||
|
|
||||||
|
<!--script src="./test.js"></script-->
|
||||||
|
<script>
|
||||||
|
var options = {maxZoom:22};
|
||||||
|
var map = L.map('map', options).setView([49.90299388, 10.87004638], 17);
|
||||||
|
|
||||||
|
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||||
|
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
function addHeat(coords){
|
||||||
|
var transformed = coords.map(function (p) { return [p[1], p[0], 0.25]; });
|
||||||
|
var heat = L.heatLayer(transformed).addTo(map);
|
||||||
|
}
|
||||||
|
//coords = coords.map(function (p) { return [p[1], p[0], 0.05]; });
|
||||||
|
|
||||||
|
//var heat = L.heatLayer(coords).addTo(map);
|
||||||
|
addHeat(coords);
|
||||||
|
</script>
|
||||||
|
<!--script src="./coord.js"></script>
|
||||||
|
<script>
|
||||||
|
//addHeat(coords);
|
||||||
|
</script-->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Leaflet.heat demo</title>
|
||||||
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
|
||||||
|
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
|
||||||
|
crossorigin=""/>
|
||||||
|
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
|
||||||
|
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
|
||||||
|
crossorigin=""></script>
|
||||||
|
<style>
|
||||||
|
#map { width: 1024px; height: 768px; }
|
||||||
|
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
|
||||||
|
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
|
||||||
|
a { color: #0077ff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="map"></div>
|
||||||
|
|
||||||
|
<!-- <script src="../node_modules/simpleheat/simpleheat.js"></script>
|
||||||
|
<script src="../src/HeatLayer.js"></script> -->
|
||||||
|
|
||||||
|
<script src="http://rawgit.com/Leaflet/Leaflet.heat/gh-pages/dist/leaflet-heat.js"></script>
|
||||||
|
|
||||||
|
<script src="./track_data.js"></script>
|
||||||
|
<script>
|
||||||
|
var options = {maxZoom:22};
|
||||||
|
//var map = L.map('map', options).setView([49.90299388, 10.87004638], 17);
|
||||||
|
var map = L.map('map', options);
|
||||||
|
|
||||||
|
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
|
||||||
|
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
||||||
|
}).addTo(map);
|
||||||
|
|
||||||
|
function addHeat(coords){
|
||||||
|
//var transformed = coords.map(function (p) { return [p[1], p[0], 0.25]; });
|
||||||
|
var heat = L.heatLayer(coords).addTo(map);
|
||||||
|
}
|
||||||
|
var layers=[];
|
||||||
|
function addTrack(tracks, i){
|
||||||
|
layers[i] = L.polyline(tracks[i], {color:"green"});
|
||||||
|
map.fitBounds(layers[i].getBounds());
|
||||||
|
layers[i].on('mouseover', function (e) {
|
||||||
|
e.target.setStyle({'color':'red'});
|
||||||
|
});
|
||||||
|
layers[i].on('mouseout', function (e) {
|
||||||
|
e.target.setStyle({'color':'green'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//coords = coords.map(function (p) { return [p[1], p[0], 0.05]; });
|
||||||
|
|
||||||
|
//var heat = L.heatLayer(coords).addTo(map);
|
||||||
|
//addHeat(coords);
|
||||||
|
for (var i in tracks) {
|
||||||
|
addTrack(tracks, i);
|
||||||
|
}
|
||||||
|
L.control.layers(null, layers).addTo(map);
|
||||||
|
</script>
|
||||||
|
<!--script src="./heat_data.js"></script>
|
||||||
|
<script>
|
||||||
|
addHeat(coords);
|
||||||
|
</script-->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue