I'm using OpenLayers 3 and GeoServer to create a spatial web application in which I want to enable users to choose a colour ramp (using Colorbrewer) and a number of breaks for styling an attribute in their analysis layer (i.e. to style a choropleth). I have been able to get this working by dynamically generating an SLD XML string and passing it in as the value to the SLD_BODY parameter in the TileWMS source, but only with 3 breaks/classes. When I select 4 or more classes nothing is returned and I believe the issue is that the SLD becomes too long for the OpenLayers TileWMS GET request. I have read a variety of posts that explain you can do a POST request in OpenLayers 2 to get around this issue, but I haven't found anything on how to do this using OpenLayers 3. Only a response in this post hints at a solution, but it's not enough for me to work out an answer. The following is how I'm currently defining the layer and adding the SLD. Does anyone know how to get around character limit with the OpenLayers 3 GET request by using POST instead?
window.layer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://' + window.location.hostname + ':8080/geoserver/wms',
params: {LAYERS: geoserverLayer, STYLES: undefined, SLD_BODY: sld, CQL_FILER: geoserverFilter, TILED: true},
serverType: 'geoserver'
})
});
Answer
I am not sure whether my answer is going to give you the final solution. But give it a try and let us know if something good comes up. So do the following:
add
tileLoadFunction
to your source. Like so:window.layer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://' + window.location.hostname + ':8080/geoserver/wms',
params: {LAYERS: geoserverLayer, STYLES: undefined, SLD_BODY: sld, CQL_FILER: geoserverFilter, TILED: true},
serverType: 'geoserver',
tileLoadFunction: function(image, src) {
imagePostFunction(image, src);
}
})
});create your custom imagePostFunction like so:
function imagePostFunction(image, src) {
var img = image.getImage();
if (typeof window.btoa === 'function') {
var xhr = new XMLHttpRequest();
xhr.open('POST', src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status === 200) {
console.log("this.response",this.response);
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var type = xhr.getResponseHeader('content-type');
if (type.indexOf('image') === 0) {
img.src = 'data:' + type + ';base64,' + window.btoa(data);
}
}
};
xhr.send();
} else {
img.src = src;
}
}It should force ol3 to execute a POST request but I am not sure if parameters are going to be passed to the POST body of the request and thus solve the long url problem.
Also consider the following post , might helps. In any way please let us know if it works.
UPDATE HERE FOR imagePostFunction
function imagePostFunction(image, src) {
var img = image.getImage();
if (typeof window.btoa === 'function') {
var xhr = new XMLHttpRequest();
console.log("src",src);
**//GET ALL THE PARAMETERS OUT OF THE SOURCE URL**
var dataEntries = src.split("&");
var url;
var params = "";
for (var i = 0 ; i< dataEntries.length ; i++){
console.log("dataEntries[i]",dataEntries[i]);
if (i===0){
url = dataEntries[i];
}
else{
params = params + "&"+dataEntries[i];
}
}
console.log("params",params);
xhr.open('POST', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status === 200) {
console.log("this.response",this.response);
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var type = xhr.getResponseHeader('content-type');
if (type.indexOf('image') === 0) {
img.src = 'data:' + type + ';base64,' + window.btoa(data);
}
}
};
//SET THE PROPER HEADERS AND FINALLY SEND THE PARAMETERS
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-length", params.length);
xhr.setRequestHeader("Connection", "close");
xhr.send(params);
} else {
img.src = src;
}
}
No comments:
Post a Comment