kmz_compressor 1.0.6 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
|