Completed
Push — master ( f83f1c...d7e941 )
by Matt
11:01
created

map.js ➔ addAllWanders   C

Complexity

Conditions 9

Size

Total Lines 51
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 31
dl 0
loc 51
rs 6.6666
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
// TODO: Refactor the heck out of this mess
2
3
/* LeafletJS and Omnivore */
4
/** global: L */
5
/** global: omnivore */
6
/*global L, omnivore */ /* For ESLint */
7
8
var streetMap;
9
var satelliteMap;
10
11
12
var base = L.latLng($("#mapid").data("homebaseLat"), $("#mapid").data("homebaseLng"));
13
14
function setUpMap(options)
15
{
16
    var mapboxAccessToken = $("#mapid").data("mapboxAccessToken");
17
    var locusRadius = 1609.34; // 1 mile
18
19
    streetMap = L.tileLayer(
20
        "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}@2x?access_token=" + mapboxAccessToken,
21
        {
22
            // These are mapbox-specific
23
            id: "gothick/ckhb31na304g619t67r3gcngx",
24
            tileSize: 512,
25
            zoomOffset: -1,
26
            // More general
27
            maxZoom: 19,
28
            attribution: "Map data &copy; <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery © <a href='https://www.mapbox.com/'>Mapbox</a>"
29
        });
30
31
    satelliteMap = L.tileLayer(
32
        "https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}@2x?access_token=" + mapboxAccessToken,
33
        {
34
            // These are mapbox-specific
35
            id: "gothick/ckhwgr59r0uai19o077hp87w4",
36
            tileSize: 512,
37
            zoomOffset: -1,
38
            // More general
39
            maxZoom: 19,
40
            attribution: "Map data &copy; <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors, <a href='https://creativecommons.org/licenses/by-sa/2.0/'>CC-BY-SA</a>, Imagery © <a href='https://www.mapbox.com/'>Mapbox</a>"
41
        });
42
43
    var circle = L.circle(base, {
44
        color: "green",
45
        fillColor: "#faa",
46
        fillOpacity: 0.15,
47
        radius: locusRadius,
48
        interactive: false
49
    });
50
51
    // Because Object.assign isn't supported in older browsers
52
    // https://stackoverflow.com/a/41455739/300836
53
    $.extend(options, {
54
        maxBounds: base.toBounds(locusRadius * 5), // Give a bit of wiggle room around the circle, but don"t let the user drift too far away
55
        layers: [streetMap, circle]
56
    });
57
58
    var map = L.map("mapid", options)
59
        .setView(base, 14);
60
61
    var baseMaps = {
62
        "Satellite": satelliteMap,
63
        "Streets": streetMap
64
    };
65
66
    L.control.layers(baseMaps).addTo(map);
67
    L.control.scale().addTo(map);
68
69
    L.control.locate().addTo(map);
70
71
    return map;
72
}
73
74
function selectedWanderStyle() {
75
    return {
76
        color: "#FFA500"
77
    };
78
}
79
80
function unselectedWanderStyle() {
81
    return {
82
        color: "#3388FF"
83
    };
84
}
85
86
var currentlySelected = null;
87
88
var CustomGeoJSON = L.GeoJSON.extend({
89
    options: {
90
        // TODO: Do we need to go to all this trouble to keep the wander id
91
        // handy? Maybe we could just capture it in the bindPopup closure?
92
        wanderId: null
93
    }
94
 });
95
96
 var photoLayer = null;
97
98
 function addPhotos(map, photos)
99
 {
100
     if (photoLayer) {
101
         map.removeLayer(photoLayer);
102
     }
103
104
     photoLayer = L.photo.cluster().on("click", function(evt) {
105
         var photo = evt.layer.photo;
106
         var template = "<a href='{imageShowUri}'><img src='{url}' width='300' /></a><p>{caption}</p>";
107
         // TODO: Video
108
         evt.layer.bindPopup(L.Util.template(template, photo), {
109
             className: "leaflet-popup-photo",
110
             minWidth: 300
111
         }).openPopup();
112
     });
113
114
     photoLayer.add(photos).addTo(map);
115
 }
116
117
 function addWanderImages(map, wanderId) {
118
    var photos = [];
119
120
    // Our API allows us to grab only those photos with co-ordinates set
121
    $.getJSON("/api/wanders/" + wanderId + "/images?exists[latlng]=true", function(images) {
122
        $.each(images["hydra:member"], function(key, image) {
123
            photos.push({
124
                lat: image.latlng[0],
125
                lng: image.latlng[1],
126
                url: image.mediumImageUri,
127
                caption: image.title || "",
128
                thumbnail: image.markerImageUri,
129
                imageShowUri: image.imageShowUri,
130
                // TODO?
131
                video: null
132
            });
133
        });
134
        addPhotos(map, photos);
135
    });
136
}
137
138
function addAllWanders(map)
139
{
140
    // TODO: We should probably use some kind of Hydra client. This"ll do for now.
141
    $.getJSON("/api/wanders", function(data) {
142
        var last = data["hydra:totalItems"];
143
        var layers = [];
144
        $.each(data["hydra:member"], function(key, wander) {
145
            var isLastWander = (last - 1 === key);
146
            var track = omnivore.gpx(wander.gpxFilename,
147
                    null,
148
                    new CustomGeoJSON(null, {
149
                        wanderId: wander.id,
150
                        style: isLastWander ? selectedWanderStyle() : unselectedWanderStyle()
151
                    }))
152
                .bindPopup(function(layer) {
153
                    // Toggle styles
154
                    currentlySelected.setStyle(unselectedWanderStyle());
155
                    layer.setStyle(selectedWanderStyle());
156
                    layer.bringToFront();
157
                    currentlySelected = layer;
158
159
                    addWanderImages(map, layer.options.wanderId);
160
                    // Popup
161
                    var template = "<a href='{contentUrl}'>{title}</a>";
162
                    return L.Util.template(template, wander);
163
                });
164
            track.wanderId = wander.id;
165
            track.addTo(map);
166
            layers.push(track);
167
            if (isLastWander) {
168
                currentlySelected = track;
169
                track.on("ready", function() {
170
                    track.bringToFront();
171
                });
172
            } else {
173
                track.on("ready", function() {
174
                    // Our layers load asynchonously, and I can't find an event
175
                    // that fires once all our geoJSON layers are loaded, so the
176
                    // above bringToFront() for the most recent wander might
177
                    // fire before other layers load. This is a bit of a hack to
178
                    // send any layers that load later to the back, keeping the
179
                    // most recent wander at the front.
180
                    track.bringToBack();
181
                });
182
            }
183
        });
184
        $.when.apply($, layers).then(function() {
185
            console.log('All loaded');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
186
        });
187
    });
188
}
189
190
function addWander(map, wanderId, addImages)
191
{
192
    $.getJSON("/api/wanders/" + wanderId, function(wander) {
193
        omnivore.gpx(wander.gpxFilename)
194
            .bindPopup(function(/* layer */) {
195
                return wander.title;
196
            })
197
            .addTo(map);
198
        // Based on the example at https://github.com/turban/Leaflet.Photo/blob/gh-pages/examples/picasa.html
199
        if (addImages) {
200
            addWanderImages(map, wanderId);
201
        }
202
    });
203
}
204