Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am a begginner to OpenLayers, and my question is about making things more efficient.

My work is about displaying time-dependent weather elements on several point locations on the map. All these are initially stored in a MySQL database, and I use a PHP file to convert a (parameterized) query result into GeoJSON format. All the features are points with a pair of coordinates, but many properties (like name, temperature, dewpoint, wind direction, wind strength etc.) With a refreshing strategy, I manage to keep the elements up-to-date.

Each property is supposed to be displayed in a different layer on the map, so that the user can show or hide whatever finds or not necessary. There are a names' layer, a temperatures' layer, a dewpoints' layer and so on.

The way to create two of these layers can be presented at the last lines of the following code:

var wgs84 = new OpenLayers.Projection("EPSG:4326");
var mercator = new OpenLayers.Projection("EPSG:900913");

var myURL="http://localhost:8080/wxproj/wx-json.php";

var clustering = new OpenLayers.Strategy.Cluster({distance:40});
var refreshing = new OpenLayers.Strategy.Refresh({interval:1000});

var clusters = new OpenLayers.Layer.Vector("LIGHTNINGS", { 
    strategies: [clustering, refreshing, new OpenLayers.Strategy.Fixed()],
    styleMap: myLightningStyles,
    protocol: new OpenLayers.Protocol.HTTP({
        url: myURL,
        format: new OpenLayers.Format.GeoJSON({
            'internalProjection': mercator,
            'externalProjection' : wgs84 }),
        async: false
        })
    });

var stations = new OpenLayers.Layer.Vector("STATIONS", { 
    strategies: [new OpenLayers.Strategy.Fixed()],
    styleMap: myStationStyles,
    protocol: new OpenLayers.Protocol.HTTP({
        url: myURL,
        format: new OpenLayers.Format.GeoJSON({
            'internalProjection': mercator,
            'externalProjection' : wgs84 }),
        async: false
        })
    });

 map.addLayers([clusters, stations]);

The obvious drawback is that I have to call the same file "wx-json.php" several times, one for each layer, getting in almost all cases the same GeoJSON-formatted result exactly. While it is sufficient to call it once, every time needed, and then distribute the properties (and its values) to the layers (and their features, accordingly).

One thought about bypassing this result, is appending parameters to the URL, so that I get the GeoJSON-formatted features with one property at each call:

var myURL="http://localhost:8080/wxproj/wx-json.php?property=station";
var stations = new OpenLayers.Layer.Vector("STATIONS", { ... });

var myURL="http://localhost:8080/wxproj/wx-json.php?property=lightnings";
var clusters = new OpenLayers.Layer.Vector("LIGHTNINGS", { ... });

But I find it also consuming.

Is there any more efficient way to get the GeoJSON data only once and then create the layers with features according to each property?

Edit: I found a similar question that restates my own demand, that is a single GeoJSON file backing multiple Vector Layers. But, there is no code to understand how this is being done.


Well, it has been a month without some answer, so I suppose my question needs some refrase:

What I really need with OL is filling a number of overlay layers with features by reading once (in a period) a GeoJSON file.

I get each half-an-hour a different GeoJSON file, which corresponds to a lot of point features, each with a pair of coordinates and some properties. For each one of the properties, I create one overlay layer in OpenLayers. Essentially, there are the same points in all layers, but a different property is hightlighted for every layer.

The way I went so far, was reading the same GeoJSON file as many times as many are the layers. This way has been expressed in the first block of code above, at my first question one month ago: Each layer manages to get its own features reading for itself from the PHP file, which produces a GeoJSON format output.

However, this way is not desirable, because of the too many independent calls to the webserver, while the layers display essentially the same thing; what's more, if the PHP file changes its output in the meantime of layers' reading, the displayed result is prone to confusion.

My question is therefore about another way of loading my features. I want to read once, in a period say half-an-hour, the GeoJSON (output from the PHP) and get all my layers filled from this.

share|improve this question
    
There are several examples how to create from a programmed datasource(=hardcoded vector layers). It would be easy to call the json using jquery and from there on use jquery to build layers according to the attributes given. –  Glenn Plas Nov 7 '12 at 9:04

2 Answers 2

Well for this case forget about the OpenLayers.Strateg[ies] for data update. You going need to write your own police for Layer Feature retrieval.

Did you know about temporal data in database?

  • Create a Feature/Geometry loading service with temporal support
  • Create a FeatureCollection or layer change service with temporal support
  • Create a poller to call those services
  • Write callbacks to populate returned data from those services

First client coming, foreach layer to a request to read feature/Geometry with or without attributes. Populate the fid attribute of each feature/geometry with a unique identifier.

After initial load, begin pool server with new timestamp. Update the features by comparison of fid attribute.

Works faster do not?

share|improve this answer

I finally managed to do my JSON call once and then fill all my necessary layers. Here are the basic aspects in code:

var wgs84 = new OpenLayers.Projection("EPSG:4326");
var mercator = new OpenLayers.Projection("EPSG:900913"); 
function init() {
  function Incorporate_Data(r) { /* Function inside init() */
     var x=r.priv.responseText;
     var arr=[ stations, temperatures, visibility, clouds ]; /* ARRAY OF MAP LAYERS TO BE FILLED */
     var j=new OpenLayers.Format.GeoJSON({'internalProjection':mercator,'externalProjection':wgs84});
     for(i in arr) {
        arr[i].destroyFeatures();
        arr[i].addFeatures(j.read(x));
        }
     }
/* define mapoptions here */
var map=new OpenLayers.Map(mapoptions);
/* define some base layer here */
var mainstyle=new OpenLayers.Style();
/* define mainstyle and more styles here */
var myStyles=new OpenLayers.Stylemap({"default":mainstyle});
/* define more stylemaps here */
var temperatures=new OpenLayers.Layer.Vector("TEMPERATURES", styleMap: tempStyles, renderers: ["Canvas"]});
/* define more of the layers here (such as visibility and clouds) */

var stations=new OpenLayers.Layer.Vector("STATIONS", {
   strategies: [
      new OpenLayers.Strategy.Refresh({interval:30000}),
      new OpenLayers.Strategy.BBOX(),
      new OpenLayers.Strategy.Fixed()], stylemap:myStyles,
      protocol: new OpenLayers.Protocol.HTTP({
         url: "http://localhost:8080/wxproj/wx-json.php",
         format: new OpenLayers.Format.GeoJSON({'internalProjection':mercator,'externalProjection':wgs84}),
         async:true,
         handleResponse: Incorporate_Data}),
      renderers: ["Canvas"]});

map.addLayers([baselayer, stations, temperature, visibility, clouds]);
map.setCenter(center,zoom);
}//init()

Although I think that there can be more efficient code, I hope that this works fine. I want to answer if it possible to keep the Incorporate_Data() function out of the init() function, and if the strategies for stations can be reduced. Any comments welcome.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.