[OpenLayers-Users] Offline Storage Help

ANC anajera at bicimapas.com.mx
Sat Jan 4 16:15:58 PST 2014


Hello List,

I am working on a mobile mapping application for mountain bike trails in our
country. All the data used for this project is hosted on our own server
(Apache running on Linux) and that includes:

1. The trail data in GPX format.
2. A WMS server using Mapserver for the topographical map data.
3. The website.

The application concept is to have a mobile webpage that would allow users
to have access to the maps while they are online, select the trail they are
interested in and be able to save both the map and the trail to the device's
localStorage for offline use.

I have been using the OpenLayers Offline-Storage sample as the parting point
for this purpose with some modifications. The UI has been modified for
Mobile devices covering the full screen as well as adding the
touchNavigation control. Two buttons shall be available on the map window,
one to start the map images seeding process and another to clear the cache,
both of them using the seeding functions in the Offline-Storage sample (the
code that I thought was not needed for the 2 buttons was removed but maybe I
took off something that was important). I have made a good progress on this
but I after clicking the seeding button, I am not getting the map tiles to
be stored for offline use, though the GPX file does. You can see the
development application in this link

http://www.bicimapas.com.mx/bmovil.html

The buttons are located on the bottom left (please excuse the poor graphics,
the final CSS will be taken care of as soon as the functionality is there).
The red one triggers the seeding function while the blue one clears the
cache. When the red button is clicked, I can see that the seeding process
seems to run but when going offline, the tiles are not there. I am testing
in an iPhone 4 as well as FireFox with Firebug in my PC. Firebug shows no
errors.

The code I am using is posted below and I have some questions regarding the
Offline-storage sample functions and statements:

1. Considering all the data used for the application (webpage, GPS files and
WMS server by means of Mapserver) is hosted in the same server, there is no
need for a proxy, in my opinion, so the statement calling the proxy was
removed from the code. I wonder whether a proxy is still required for the
seeding (cacheWrite) process? In other applications we have, we do WMS Web
Feature Info as well as WFS requests without needing the proxy. 

2. On the Offline-storage sample, a WMS layer is instantiated and the 

eventListeners{tileloaded:updateStatus}

statement is added to the layer parameters. What is the purpose of this
eventListener?  I added it to our WMS map instantiation but I have no clue
what is it for. Where is the "tileloaded" event defined?

3. Shall I be concerned about CORS?  This is a new concept to me and have no
idea how this could affect this application, but is mentioned several times
in the sample code. As far as I understand, as all the data sources are in
the same server, this should not be an issue. If so, how shall the code be
modified?

4. Is the GPX file being seeded instead of the topo map layers?  If so, what
shall be done to cache both layers?  

Thanks in advance for your help and any guidance that can be provided to
solve this issue is much appreciated. The code used for the example in the
link above is as follows:

bmovil.html

<!DOCTYPE html>
<html lang='en'>
<head> 
    <meta http-equiv="Content-Type" content="text/html";
charset="ISO-8859-1" /> 
		<title>BiciMapas Móvil</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=0">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <link rel="stylesheet"
href="http://openlayers.org/dev/theme/default/style.css" type="text/css">
    <link rel="stylesheet"
href="http://openlayers.org/dev/examples/style.css" type="text/css">
    
    
    
    
</head>
<body	onload='init();'>
    <div id='map_element'>
    	
	</div>
</body>
</html>


THIS IS THE JS FILE

   
  
   
  var map, cacheWrite, cacheRead1, cacheRead2;
    
	function init() {
        // Setup our map object
        map = new OpenLayers.Map('map_element', {
        	controls: [
        	new OpenLayers.Control.Zoom(),
        	//new OpenLayers.Control.PanZoomBar(),
        	//new OpenLayers.Control.NavToolbar (),
        	//new OpenLayers.Control.LayerSwitcher(),
        	//new OpenLayers.Control.ScaleLine(),
        	new OpenLayers.Control.TouchNavigation({dragPanOptions:
{enableKinetic: true}})//,
        	//new OpenLayers.Control.Graticule({layerName: "Coordenadas",
labelFormat: "dms", labelSymbolizer: {fontFamily: "arial", fontSize: "12px",
fontWeight: "bold", fontColor: "blue"}})
        	
        	],
        	maxExtent: new OpenLayers.Bounds (-121.616821, 13.607919,
-77.567276, 34.575615),
        	maxScale: 15000000,
        	minScale: 2500
        	});
        
       // Setup our layer objects
       
   var layer1 = new OpenLayers.Layer.WMS(
		"BiciMapas Topo",
		"http://HOST/cgi-bin/mapserv?", 
		{map: '/PATH/TO/MAPFILE/BCMP_BASE_TOPO.map',
			format: "image/png", 
	layers:'BCMP_BASE_TOPO'},
	{singleTile: true,
	 eventListeners: {
	 	tileloaded: updateStatus
	}
	});	
	map.addLayer (layer1)	  
	
	
	 var gpxStyles = new OpenLayers.StyleMap({
                "default": new OpenLayers.Style({
                    pointRadius: "5", // sized according to type attribute
                    label: "${name}",        
                    labelAlign: 'cb',
                    fontSize: 9,
                    fontFamily: "Arial",
                    fontColor: "brown",
                    fontWeight: "bold",
                    labelYOffset: 6,
                    fillColor: "yellow",
                    strokeColor: "red",
                    strokeWidth: 3, 
                    strokeOpacity: 1
                }),
                "select": new OpenLayers.Style({
                    fillColor: "#66ccff",
                    strokeColor: "#3399ff",
                    graphicZIndex: 2
                })
            }); 
    

var lgpx = new OpenLayers.Layer.Vector("Ruta", {
				strategies: [new OpenLayers.Strategy.Fixed()],
				protocol: new OpenLayers.Protocol.HTTP({
					url: "CHILUCO.gpx",
					format: new OpenLayers.Format.GPX({extractWaypoints: true,
extractRoutes: false, extractAttributes: true})
				}),
				//style: {strokeColor: "green", strokeWidth: 3, strokeOpacity: 0.5,
pointRadius: 4, label: "PUNTO"},
				styleMap: gpxStyles,
				projection: map.displayProjection
			});
 

             map.addLayer(lgpx); 

             lgpx.events.register('loadend',lgpx,function() { 
                 var bounds = this.getDataExtent(); 
                 map.zoomToExtent(bounds); 
             }); 

    
        
                
// GEOLOCATION 
  	
//	 var markers = new OpenLayers.Layer.Markers("Markers");
// 	 map.addLayer(markers);
 	
 	// Recenter on user position
//	navigator.geolocation.getCurrentPosition(function(position) {       
        
//        var lonLat = new OpenLayers.LonLat(position.coords.longitude,
//                                position.coords.latitude);
//        var icon = new
OpenLayers.Icon('images/Empresa/marker-icon-red.png');
                                        
//        markers.addMarker(new OpenLayers.Marker(lonLat, icon));
       
//        map.setCenter(lonLat, 14 // Zoom level
//        );

//    });	


// BUTTONS FOR CACHING

 var b1 = new OpenLayers.Control.Button({trigger: startSeeding
,displayClass: "btnWrite"});
 var b2 = new OpenLayers.Control.Button({trigger: clearCache, displayClass:
"btnClear"});

 var hpanel = new OpenLayers.Control.Panel({displayClass: "panel"});
 hpanel.addControls([b1, b2]);
 map.addControl(hpanel);



 // try cache before loading from remote resource
    cacheRead1 = new OpenLayers.Control.CacheRead({
        eventListeners: {
            activate: function() {
                cacheRead2.deactivate();
            }
        }
    });
    // try loading from remote resource and fall back to cache
    cacheRead2 = new OpenLayers.Control.CacheRead({
        autoActivate: false,
        fetchEvent: "tileerror",
        eventListeners: {
            activate: function() {
                cacheRead1.deactivate();
            }
        }
    });
    cacheWrite = new OpenLayers.Control.CacheWrite({
        imageFormat: "image/png",
        eventListeners: {
            cachefull: function() {
                if (seeding) {
                    stopSeeding();
                }
                status.innerHTML = "Cache full.";
            }
        }
    });
 
 map.addControls([cacheRead1, cacheRead2, cacheWrite]);
 
 var status = document.getElementById("status"),
        hits = document.getElementById("hits"),
        cacheHits = 0,
        seeding = false;
 
 function updateStatus(evt) {
        if (window.localStorage) {
            status.innerHTML = localStorage.length + " entries in cache.";
        } else {
            status.innerHTML = "Local storage not supported. Try a different
browser.";
        }
        if (evt && evt.tile.url.substr(0, 5) === "data:") {
            cacheHits++;
        }
        hits.innerHTML = cacheHits + " cache hits.";
    }
    
 
 
  // clear all tiles from the cache
    function clearCache() {
        OpenLayers.Control.CacheWrite.clearCache();
        updateStatus();
    }
    
 // start seeding the cache
    function startSeeding() {
        var layer = map.baseLayer,
            zoom = map.getZoom();
        seeding = {
            zoom: zoom,
            extent: map.getExtent(),
            center: map.getCenter(),
            cacheWriteActive: cacheWrite.active,
            buffer: layer.buffer,
            layer: layer
        };
        // make sure the next setCenter triggers a load
        map.zoomTo(zoom === layer.numZoomLevels-1 ? zoom - 1 : zoom + 1);
        // turn on cache writing
        cacheWrite.activate();
        // turn off cache reading
        cacheRead1.deactivate();
        cacheRead2.deactivate();
        
        layer.events.register("loadend", null, seed);
        
        // start seeding
        map.setCenter(seeding.center, zoom);
    }
    
    // seed a zoom level based on the extent at the time startSeeding was
called
    function seed() {
        var layer = seeding.layer;
        var tileWidth = layer.tileSize.w;
        var nextZoom = map.getZoom() + 1;
        var extentWidth = seeding.extent.getWidth() /
map.getResolutionForZoom(nextZoom);
        // adjust the layer's buffer size so we don't have to pan
        layer.buffer = Math.ceil((extentWidth / tileWidth - map.getSize().w
/ tileWidth) / 2);
        map.zoomIn();
        if (nextZoom === layer.numZoomLevels-1) {
            stopSeeding();
        }
    }
    
    // stop seeding (when done or when cache is full)
    function stopSeeding() {
        // we're done - restore previous settings
        seeding.layer.events.unregister("loadend", null, seed);
        seeding.layer.buffer = seeding.buffer;
        map.setCenter(seeding.center, seeding.zoom);
        if (!seeding.cacheWriteActive) {
            cacheWrite.deactivate();
        }
 //       if (read.checked) {
 //           setType();
 //       }
        seeding = false;
    }   
 
}




--
View this message in context: http://osgeo-org.1560.x6.nabble.com/Offline-Storage-Help-tp5096401.html
Sent from the OpenLayers Users mailing list archive at Nabble.com.


More information about the Users mailing list