kmz_compressor 1.0.6 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebde16462c1697fb99bcde921668d7bb36ea5c79
|
4
|
+
data.tar.gz: e6e2b43e2e112c910fdd05088274fb5c14d2c169
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cced39b8c3f876a615ec6c2b22c6d67c4a51b828e636b08d593e6b53035edf2937943f478aeb57df124594e7e45aa2858702c699417cec3edf9b842790ac1059
|
7
|
+
data.tar.gz: c609706c23a23010294500544b3346829918609d88a7ce337284b681a91104244757394a201a054013f4163e63d33f29524f370797a14a380f09f9d03e4a12b8
|
@@ -1,178 +1,191 @@
|
|
1
|
-
MapLayerManager = {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
// Prime the KMZ cache on the server before unleashing google's many tilemills
|
10
|
-
cacheAndLoadKMLLayer: function(map, kmlPath, layerName, options) {
|
11
|
-
var requestTimestamp = new Date;
|
12
|
-
kmlPath = this.sanitizeURI(kmlPath);
|
13
|
-
|
14
|
-
$.ajax(this.host + kmlPath, {type:'head', complete:function(){
|
15
|
-
if (!MapLayerManager.requestTimestamps[layerName] || MapLayerManager.requestTimestamps[layerName] < requestTimestamp){
|
16
|
-
MapLayerManager.requestTimestamps[layerName] = requestTimestamp;
|
17
|
-
MapLayerManager.loadKMLLayer(map, MapLayerManager.cachedKMZPath(kmlPath), layerName, options)
|
18
|
-
}
|
19
|
-
}});
|
20
|
-
},
|
21
|
-
loadKMLLayer: function(map, kmlPath, layerName, options) {
|
22
|
-
// Replace spaces with pluses so we don't have problems with some things turning them into %20s and some not
|
23
|
-
kmlPath = this.sanitizeURI(kmlPath);
|
24
|
-
options = options || {}
|
25
|
-
options.map = map;
|
26
|
-
|
27
|
-
var kmlLayer = new google.maps.KmlLayer(this.host + kmlPath, options);
|
28
|
-
var layer = MapLayerManager.addLayer(layerName, kmlLayer)
|
29
|
-
this.loadingCount++
|
30
|
-
$(window.document).trigger({type: this.layerLoadingEventName, layer:layer})
|
31
|
-
|
32
|
-
// Try and catch the defaultviewport_changed event so we can remove the old layer (sometimes this works, sometimes not)
|
33
|
-
google.maps.event.addListener(kmlLayer, 'defaultviewport_changed', function(){
|
34
|
-
MapLayerManager.sweep();
|
35
|
-
});
|
36
|
-
|
37
|
-
// Add a listener to catch clicks and close all info windows on other layers
|
38
|
-
google.maps.event.addListener(kmlLayer, 'click', function(){
|
39
|
-
MapLayerManager.everyLayer(function(layer){
|
40
|
-
if (layer.kml != kmlLayer){ // Don't close this layer's info window
|
41
|
-
layer.kml.setOptions({suppressInfoWindows:true})
|
42
|
-
layer.kml.setOptions({suppressInfoWindows:false})
|
43
|
-
}
|
44
|
-
})
|
45
|
-
});
|
46
|
-
},
|
47
|
-
// Generates the url of the cached KMZ for the given kmlPath
|
48
|
-
cachedKMZPath: function(kmlPath){
|
49
|
-
return '/kmz/' + hex_sha256(kmlPath) + '.kmz'
|
50
|
-
},
|
51
|
-
centerWhenLoaded: function(map, layerNames){
|
52
|
-
var handler = function(){
|
53
|
-
// If we have no layer names
|
54
|
-
if (!layerNames || layerNames.length == 0){
|
55
|
-
layerNames = MapLayerManager.layerNames()
|
56
|
-
}
|
1
|
+
window.MapLayerManager = function(map){
|
2
|
+
var map = map;
|
3
|
+
var host = location.protocol + "//" + location.host
|
4
|
+
var layers = []
|
5
|
+
var loadingCount = 0 // How many layers are being loade
|
6
|
+
var requestTimestamps = { }
|
7
|
+
var layerLoadingEventName = 'map:layerLoading'
|
8
|
+
var layerLoadedEventName = 'map:layerLoaded'
|
57
9
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
}
|
10
|
+
// Prime the KMZ cache on the server before unleashing google's many tilemills
|
11
|
+
function cacheAndLoadKMLLayer(kmlPath, layerName, options) {
|
12
|
+
var requestTimestamp = new Date;
|
13
|
+
kmlPath = sanitizeURI(kmlPath);
|
63
14
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
return $(this.layers.slice(0)).map(function(){return this.name})
|
69
|
-
},
|
70
|
-
addLayer: function(layerName, kml){
|
71
|
-
this.layers.unshift({name:layerName, kml:kml})
|
72
|
-
return this.layers[0]
|
73
|
-
},
|
74
|
-
getLayer: function(layerName){
|
75
|
-
var desiredLayer
|
76
|
-
this.everyLayer(function(layer, index){
|
77
|
-
if (layer.name == layerName){
|
78
|
-
desiredLayer = layer
|
79
|
-
return false;
|
80
|
-
}
|
81
|
-
})
|
82
|
-
return desiredLayer
|
83
|
-
},
|
84
|
-
// Shows the layer and returns true, returns false if the layer couldn't be hidden
|
85
|
-
hideLayer: function(layerName){
|
86
|
-
var layer = this.getLayer(layerName);
|
87
|
-
if (layer && layer.kml){
|
88
|
-
layer.oldMap = layer.kml.getMap();
|
89
|
-
layer.kml.setMap(null)
|
90
|
-
layer.hidden = true
|
91
|
-
return true
|
92
|
-
} else if (layer) {
|
93
|
-
layer.hidden = true
|
94
|
-
} else {
|
95
|
-
return false
|
96
|
-
}
|
97
|
-
},
|
98
|
-
// Shows the layer and returns true, returns false if the layer couldn't be shown
|
99
|
-
showLayer: function(layerName){
|
100
|
-
var layer = this.getLayer(layerName);
|
101
|
-
if (layer && layer.kml && layer.oldMap){
|
102
|
-
layer.kml.setMap(layer.oldMap);
|
103
|
-
layer.oldMap = null
|
104
|
-
layer.hidden = false
|
105
|
-
return true
|
106
|
-
} else {
|
107
|
-
return false
|
15
|
+
$.ajax(host + kmlPath, {type:'head', complete:function(){
|
16
|
+
if (!requestTimestamps[layerName] || requestTimestamps[layerName] < requestTimestamp){
|
17
|
+
requestTimestamps[layerName] = requestTimestamp;
|
18
|
+
loadKMLLayer(cachedKMZPath(kmlPath), layerName, options)
|
108
19
|
}
|
109
|
-
}
|
110
|
-
|
111
|
-
for (var i = 0; i < layerNames.length; i++){
|
112
|
-
var layer = this.getLayer(layerNames[i]);
|
113
|
-
if (!layer || !layer.loaded){
|
114
|
-
return false;
|
115
|
-
}
|
116
|
-
}
|
117
|
-
return true
|
118
|
-
},
|
119
|
-
centerOnLayers: function(map, layerNames){
|
120
|
-
var bounds;
|
121
|
-
|
122
|
-
for (var i = 0; i < layerNames.length; i++){
|
123
|
-
var layer = this.getLayer(layerNames[i])
|
124
|
-
if (layer.error){
|
125
|
-
continue
|
126
|
-
}
|
20
|
+
}});
|
21
|
+
}
|
127
22
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
23
|
+
function loadKMLLayer(kmlPath, layerName, options) {
|
24
|
+
// Replace spaces with pluses so we don't have problems with some things turning them into %20s and some not
|
25
|
+
kmlPath = sanitizeURI(kmlPath);
|
26
|
+
options = options || {}
|
27
|
+
options.map = map;
|
28
|
+
|
29
|
+
var kmlLayer = new google.maps.KmlLayer(host + kmlPath, options);
|
30
|
+
var layer = addLayer(layerName, kmlLayer)
|
31
|
+
loadingCount++
|
32
|
+
$(window.document).trigger({type: layerLoadingEventName, layer:layer})
|
33
|
+
|
34
|
+
// Try and catch the defaultviewport_changed event so we can remove the old layer (sometimes this works, sometimes not)
|
35
|
+
google.maps.event.addListener(kmlLayer, 'defaultviewport_changed', function(){
|
36
|
+
sweep();
|
37
|
+
});
|
38
|
+
|
39
|
+
// Add a listener to catch clicks and close all info windows on other layers
|
40
|
+
google.maps.event.addListener(kmlLayer, 'click', function(){
|
41
|
+
everyLayer(function(layer){
|
42
|
+
if (layer.kml != kmlLayer){ // Don't close this layer's info window
|
43
|
+
layer.kml.setOptions({suppressInfoWindows:true})
|
44
|
+
layer.kml.setOptions({suppressInfoWindows:false})
|
45
|
+
}
|
46
|
+
})
|
47
|
+
});
|
48
|
+
}
|
49
|
+
|
50
|
+
// Generates the url of the cached KMZ for the given kmlPath
|
51
|
+
function cachedKMZPath(kmlPath){
|
52
|
+
return '/kmz/' + hex_sha256(kmlPath) + '.kmz'
|
53
|
+
}
|
54
|
+
|
55
|
+
function centerWhenLoaded(layerNamez){
|
56
|
+
var handler = function(){
|
57
|
+
// If we have no layer names
|
58
|
+
if (!layerNamez || layerNamez.length == 0){
|
59
|
+
layerNamez = layerNames()
|
60
|
+
}
|
61
|
+
|
62
|
+
if (layersLoaded(layerNamez)){
|
63
|
+
$(window.document).unbind(layerLoadedEventName, handler)
|
64
|
+
centerOnLayers(layerNamez);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
$(window.document).bind(layerLoadedEventName, handler)
|
69
|
+
}
|
70
|
+
|
71
|
+
// Returns the layer names
|
72
|
+
function layerNames(){
|
73
|
+
return $(layers.slice(0)).map(function(){return name})
|
74
|
+
}
|
75
|
+
|
76
|
+
function addLayer(layerName, kml){
|
77
|
+
layers.unshift({name:layerName, kml:kml})
|
78
|
+
return layers[0]
|
79
|
+
}
|
80
|
+
|
81
|
+
function getLayer(layerName){
|
82
|
+
var desiredLayer
|
83
|
+
everyLayer(function(layer, index){
|
84
|
+
if (layer.name == layerName){
|
85
|
+
desiredLayer = layer
|
86
|
+
return false;
|
135
87
|
}
|
136
|
-
}
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
88
|
+
})
|
89
|
+
return desiredLayer
|
90
|
+
}
|
91
|
+
|
92
|
+
// Hides the layer and returns true, returns false if the layer couldn't be hidden, returns nothing if the layer existed but the kml hadn't yet been loaded
|
93
|
+
function hideLayer(layerName){
|
94
|
+
var layer = getLayer(layerName);
|
95
|
+
if (layer && layer.kml){
|
96
|
+
layer.oldMap = layer.kml.getMap();
|
97
|
+
layer.kml.setMap(null)
|
98
|
+
layer.hidden = true
|
99
|
+
return true
|
100
|
+
} else if (layer) {
|
101
|
+
layer.hidden = true
|
102
|
+
} else {
|
103
|
+
return false
|
104
|
+
}
|
105
|
+
}
|
106
|
+
|
107
|
+
// Shows the layer and returns true, returns false if the layer couldn't be shown
|
108
|
+
function showLayer(layerName){
|
109
|
+
var layer = getLayer(layerName);
|
110
|
+
if (layer && layer.kml && layer.oldMap){
|
111
|
+
layer.kml.setMap(layer.oldMap);
|
112
|
+
layer.oldMap = null
|
113
|
+
layer.hidden = false
|
114
|
+
return true
|
115
|
+
} else {
|
116
|
+
return false
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
function layersLoaded(layerNames){
|
121
|
+
for (var i = 0; i < layerNames.length; i++){
|
122
|
+
var layer = getLayer(layerNames[i]);
|
123
|
+
if (!layer || !layer.loaded){
|
124
|
+
return false;
|
143
125
|
}
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
126
|
+
}
|
127
|
+
return true
|
128
|
+
}
|
129
|
+
|
130
|
+
function centerOnLayers(layerNames){
|
131
|
+
var bounds;
|
132
|
+
|
133
|
+
for (var i = 0; i < layerNames.length; i++){
|
134
|
+
var layer = getLayer(layerNames[i])
|
135
|
+
if (layer.error){
|
136
|
+
continue
|
137
|
+
}
|
138
|
+
|
139
|
+
if (layer.kml.getDefaultViewport().toSpan().toString() != "(180, 360)"){
|
140
|
+
bounds = bounds || layer.kml.getDefaultViewport();
|
141
|
+
bounds.union(layer.kml.getDefaultViewport());
|
142
|
+
}
|
143
|
+
}
|
144
|
+
if (bounds){
|
145
|
+
map.fitBounds(bounds);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
function removeLayer(layerName){
|
150
|
+
everyLayer(function(layer, index){
|
151
|
+
if (layer.name == layerName){
|
152
|
+
layer.kml.setMap(null)
|
153
|
+
layers.splice(index, 1);
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
});
|
157
|
+
}
|
158
|
+
|
159
|
+
function removeLayers(){
|
160
|
+
everyLayer(function(layer){
|
161
|
+
removeLayer(layer.name);
|
149
162
|
})
|
150
|
-
}
|
151
|
-
everyLayer
|
152
|
-
// NOTE: We use an iterator instead of a for loop because modifications to
|
163
|
+
}
|
164
|
+
function everyLayer(fn){
|
165
|
+
// NOTE: We use an iterator instead of a for loop because modifications to layers that occur during iteration can mess us up
|
153
166
|
// e.g. if we're responding to an event during the loop and the event adds a layer, we may end up re-iterating on a layer we've already processed
|
154
|
-
$.each(
|
167
|
+
$.each(layers.slice(0), function(index, layer){
|
155
168
|
fn(layer, index);
|
156
169
|
})
|
157
|
-
}
|
170
|
+
}
|
158
171
|
|
159
172
|
// Keep layers synced with their state
|
160
|
-
sweep
|
173
|
+
function sweep(){
|
161
174
|
var foundLayers = [];
|
162
|
-
|
175
|
+
everyLayer(function(layer, index){
|
163
176
|
var kmlStatus = layer.kml ? layer.kml.getStatus() : null;
|
164
177
|
|
165
178
|
// If the layer just finished loading
|
166
179
|
if (!layer.loaded && kmlStatus) {
|
167
|
-
|
180
|
+
loadingCount--
|
168
181
|
layer.loaded = true
|
169
182
|
layer.error = kmlStatus == 'OK' ? null : kmlStatus // if there were any errors, record them
|
170
|
-
$(window.document).trigger({type:
|
183
|
+
$(window.document).trigger({type: layerLoadedEventName, layer:layer})
|
171
184
|
}
|
172
185
|
|
173
186
|
// A layer should be hidden, but the kml is showing, hide it (i.e. correct layers that were hidden before the kml was loaded)
|
174
187
|
if (layer.hidden && layer.loaded && layer.kml.getMap()){
|
175
|
-
|
188
|
+
hideLayer(layer.name)
|
176
189
|
}
|
177
190
|
|
178
191
|
// Remove old layers
|
@@ -180,18 +193,47 @@ MapLayerManager = {
|
|
180
193
|
// Don't delete an instance if we haven't yet seen a version of it with status 'OK'
|
181
194
|
if ($.inArray(layer.name, foundLayers) > -1){
|
182
195
|
layer.kml.setMap(null);
|
183
|
-
|
196
|
+
layers.splice(index, 1);
|
184
197
|
} else if (layer.loaded) {
|
185
198
|
foundLayers.push(layer.name)
|
186
199
|
}
|
187
200
|
})
|
188
|
-
},
|
189
|
-
sanitizeURI: function(uri){
|
190
|
-
// Replace spaces with pluses so we don't have problems with some things turning them into %20s and some not
|
191
|
-
// Matches the middleware process
|
192
|
-
return encodeURI(decodeURI(uri))
|
193
201
|
}
|
194
|
-
};
|
195
202
|
|
196
|
-
//
|
197
|
-
|
203
|
+
// Replace spaces with pluses so we don't have problems with some things turning them into %20s and some not
|
204
|
+
// Matches the middleware process
|
205
|
+
function sanitizeURI(uri){
|
206
|
+
var url = $('<a href="' + uri + '"/>')[0]
|
207
|
+
var pathname = decodeURI(url.pathname).trim().replace(/^\/\//, '/') // IE will return a path name with a leading double slash, so ensure it's only a single slash
|
208
|
+
var search = decodeURIComponent(url.search.replace(/\+/g, '%20')).trim().replace(/^\?/, '') // Ensure all "plus spaces" are hex encoded spaces
|
209
|
+
|
210
|
+
output = pathname
|
211
|
+
|
212
|
+
if (search !== ''){
|
213
|
+
output += '?'
|
214
|
+
}
|
215
|
+
|
216
|
+
// Encode the individual uri components
|
217
|
+
output += $.map(search.split('&'), function(component){
|
218
|
+
return $.map(component.split('='), function(kv){
|
219
|
+
// HACK: Firefox 'helps' us out by encoding apostrophes as %27 in AJAX requests, However its encodeURIcomponent method
|
220
|
+
// does not. This difference causes a mismatch between the url we use to calculate the cache path in the browser
|
221
|
+
// and on the server. This hack undoes the damage. See https://bugzilla.mozilla.org/show_bug.cgi?id=407172
|
222
|
+
return encodeURIComponent(kv).replace(/'/g, '%27')
|
223
|
+
}).join('=')
|
224
|
+
}).join('&')
|
225
|
+
|
226
|
+
return output
|
227
|
+
}
|
228
|
+
|
229
|
+
|
230
|
+
// INIT
|
231
|
+
|
232
|
+
// Because google events sometimes get missed, we ensure we're up to date every now and again
|
233
|
+
setInterval(sweep, 1000)
|
234
|
+
|
235
|
+
|
236
|
+
// PUBLIC INTERFACE
|
237
|
+
|
238
|
+
return {cacheAndLoadKMLLayer:cacheAndLoadKMLLayer, loadKMLLayer:loadKMLLayer, centerWhenLoaded:centerWhenLoaded, addLayer:addLayer, removeLayer:removeLayer, map:map}
|
239
|
+
}
|
@@ -9,16 +9,10 @@ module KMZCompressor
|
|
9
9
|
|
10
10
|
# If the User is asking for a KMZ file
|
11
11
|
if request.path_info.end_with? '.kmz'
|
12
|
-
|
13
|
-
# does not. This difference causes a mismatch between the browser's cached KMZ path, and the server.
|
14
|
-
# This hack undoes the damage. See https://bugzilla.mozilla.org/show_bug.cgi?id=407172
|
15
|
-
recoded_uri = URI.encode(URI.decode(request.fullpath))
|
16
|
-
|
17
|
-
# HACK: Also encode brackets of nested params because the javascript version does, but the ruby version does not
|
18
|
-
recoded_uri = recoded_uri.gsub('[', '%5B').gsub(']','%5D')
|
12
|
+
uri = request.fullpath
|
19
13
|
|
20
14
|
# Use a hash of the request path (before we gsub it) as the filename we will save on the HD
|
21
|
-
cache_path = "public/kmz/#{Digest::SHA2.hexdigest(
|
15
|
+
cache_path = "public/kmz/#{Digest::SHA2.hexdigest(uri)}.kmz"
|
22
16
|
file_exists = File.exists?(cache_path)
|
23
17
|
|
24
18
|
if file_exists
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kmz_compressor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Wallace
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|