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: 79e17ac2936c8d47cc6da99e1629f206f1fb0d4e
4
- data.tar.gz: dd115027b9ace264fa4d1f8a6794099a25cfa992
3
+ metadata.gz: ebde16462c1697fb99bcde921668d7bb36ea5c79
4
+ data.tar.gz: e6e2b43e2e112c910fdd05088274fb5c14d2c169
5
5
  SHA512:
6
- metadata.gz: 334c98a719886b620636e1db952050ca98b12cfd5811c24c463fe5489c80cd757a839bbad4d6e447c62bc16c59a789d09c289e576cbddc94769a82f78125248a
7
- data.tar.gz: cf6c715e44da2f7252763819d3e760b7e698d4c690dde4ff5633da3e743cbd773d04385167670fbee1d4dd84fa7f908ad83698374d222e4c83a9142b0000bca0
6
+ metadata.gz: cced39b8c3f876a615ec6c2b22c6d67c4a51b828e636b08d593e6b53035edf2937943f478aeb57df124594e7e45aa2858702c699417cec3edf9b842790ac1059
7
+ data.tar.gz: c609706c23a23010294500544b3346829918609d88a7ce337284b681a91104244757394a201a054013f4163e63d33f29524f370797a14a380f09f9d03e4a12b8
@@ -1,178 +1,191 @@
1
- MapLayerManager = {
2
- host: location.protocol + "//" + location.host,
3
- layers: [],
4
- loadingCount: 0, // How many layers are being loaded
5
- requestTimestamps: { },
6
- layerLoadingEventName: 'map:layerLoading',
7
- layerLoadedEventName: 'map:layerLoaded',
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
- if (MapLayerManager.layersLoaded(layerNames)){
59
- $(window.document).unbind(MapLayerManager.layerLoadedEventName, handler)
60
- MapLayerManager.centerOnLayers(map, layerNames);
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
- $(window.document).bind(this.layerLoadedEventName, handler)
65
- },
66
- // Returns the layer names
67
- layerNames: function(){
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
- layersLoaded: function(layerNames){
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
- if (layer.kml.getDefaultViewport().toSpan().toString() != "(180, 360)"){
129
- bounds = bounds || layer.kml.getDefaultViewport();
130
- bounds.union(layer.kml.getDefaultViewport());
131
- }
132
- }
133
- if (bounds){
134
- map.fitBounds(bounds);
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
- removeLayer: function(layerName){
138
- this.everyLayer(function(layer, index){
139
- if (layer.name == layerName){
140
- layer.kml.setMap(null)
141
- MapLayerManager.layers.splice(index, 1);
142
- return;
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
- removeLayers: function(){
147
- this.everyLayer(function(layer){
148
- MapLayerManager.removeLayer(layer.name);
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: function(fn){
152
- // NOTE: We use an iterator instead of a for loop because modifications to this.layers that occur during iteration can mess us up
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(this.layers.slice(0), function(index, layer){
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: function(){
173
+ function sweep(){
161
174
  var foundLayers = [];
162
- this.everyLayer(function(layer, index){
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
- MapLayerManager.loadingCount--
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: MapLayerManager.layerLoadedEventName, layer:layer})
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
- MapLayerManager.hideLayer(layer.name)
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
- MapLayerManager.layers.splice(index, 1);
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
- // Because google events sometimes get missed, we ensure we're up to date every now and again
197
- setInterval(function(){MapLayerManager.sweep()}, 1000)
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
- # HACK: Firefox 'helps' us out by encoding apostrophes as %27 in AJAX requests, However its encodeURI method
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(recoded_uri)}.kmz"
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
@@ -1,3 +1,3 @@
1
1
  module KMZCompressor
2
- VERSION = "1.0.6"
2
+ VERSION = "2.0.1"
3
3
  end
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: 1.0.6
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-02-28 00:00:00.000000000 Z
12
+ date: 2014-04-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails