Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wms styling #595

Merged
merged 8 commits into from
Jul 14, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ require('codemirror/lib/codemirror.css');
require('codemirror/addon/lint/lint.css');
require('codemirror/addon/fold/foldgutter.css');

// Colorbrewer
require('colorbrewer');

require('./common/js/jsonlint');
require('codemirror');
require('codemirror/mode/javascript/javascript');
Expand Down
9 changes: 9 additions & 0 deletions examples/sld/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"path": "sld",
"title": "Adding styles to WMS raster layers",
"exampleCss": ["main.css"],
"exampleJs": ["main.js"],
"about": {
"text": "Rendering tiles from a WMS server by customizing the style."
}
}
26 changes: 26 additions & 0 deletions examples/sld/index.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
extends ../common/templates/index.jade

block append mainContent
div#controls

.form-group(title="Select a color palette.")
label(for="palette") Color Palette
select#palette.mapparam(param-name="palette", placeholder="YlGn")

.form-group(title="Select number of colors.")
label(for="color-count") Number of colors
select#color-count.mapparam(param-name="color-count")

.form-group(title="Discrete or continuous colors.")
label(for="palette-type") Palette Type
select#palette-type.mapparam(param-name="palette-type", placeholder="continuous")
option(value="continuous") Continuous
option(value="discrete") Discrete

.form-group(title="Minimum value for your data")
label(for="min") Minimum
input#min.mapparam(param-name="x", placeholder="0")

.form-group(title="Maximum value for your data.")
label(for="max") Maximum
input#max.mapparam(param-name="x", placeholder="300")
29 changes: 29 additions & 0 deletions examples/sld/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#controls {
overflow-x: hidden;
overflow-y: auto;
position: absolute;
left: 10px;
top: 80px;
z-index: 10;
border-radius: 5px;
border: 1px solid grey;
box-shadow: 1px 1px 3px black;
opacity: 0.5;
transition: opacity 250ms ease;
background: #CCC;
color: black;
padding: 4px;
font-size: 14px;
}
#controls:hover {
opacity: 1;
}
#controls.no-controls {
display: none;
}
#controls .form-group {
margin-bottom: 0;
}
#controls label {
min-width: 90px;
}
261 changes: 261 additions & 0 deletions examples/sld/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
var colorbrewer = colorbrewer;

var layer = {
// Default values
palette: 'YlGn',
selectedNum: '3',
type: 'continuous',
min: '0',
max: '300',
name: 'usgs:ned',
sld: '',
projection: 'EPSG:3785'
};

var layerViewer = {
renderPalettes: function () {
var paletteArray = Object.keys(colorbrewer);
utility.populateDropdown('#palette', paletteArray);
},
renderWidget: function (layer) {

// Populates the number of colors dropdown
$('#color-count')
.empty();
var numberArray = Object.keys(colorbrewer[layer.palette]);
utility.populateDropdown('#color-count', numberArray);

// Sets the count
$('#color-count')
.val(layer.selectedNum);

// Sets the type
$('#palette-type')
.val(layer.type);

// Sets the min and max values
$('#min')
.val(layer.min);
$('#max')
.val(layer.max);
}
};

var layerController = {
syncLayer: function (layer) {
// Sync the model with UI
layer.palette = $('#palette')
.val();

var items = Object.keys(colorbrewer[layer.palette]);
var maxNumber = parseInt(items[items.length - 1]);

if (parseInt($('#color-count').val()) <= maxNumber) {
layer.selectedNum = $('#color-count').val();
} else {
layer.selectedNum = String(maxNumber);
}

layer.type = $('#palette-type')
.val();
layer.min = $('#min')
.val();
layer.max = $('#max')
.val();
layer.sld = this.generateSld(layer);
},
generateSld: function (layer) {
// Orchestrates the sld generation
var sequence = utility.generateSequence(layer.min, layer.max, layer.selectedNum);
var palette_array = utility.getPalette(layer.palette, layer.selectedNum);
var xml = utility.generateXml(layer.name, layer.selectedNum, sequence,
palette_array, layer.type);
return xml;
}
};

// Run after the DOM loads
$(function () {
'use strict';

// Create a map object
var map = geo.map({
node: '#map',
zoom: 8,
center: {
x: -76.0,
y: 39
}
});
// Add an OSM layer
map.createLayer('osm');

// Populate the palette dropdown
layerViewer.renderPalettes();

// Render the widget
layerViewer.renderWidget(layer);

// Generate sld
layer.sld = layerController.generateSld(layer);

// Add the wms layer
var wms = utility.createWMSLayer(map, layer.sld, layer.projection, layer.name);

// If any of the input boxes changes regenerate sld again
$('#palette, #color-count, #min, #max, #palette-type')
.change(function () {
layerController.syncLayer(layer);
layerViewer.renderWidget(layer);

map.deleteLayer(wms);

wms = utility.createWMSLayer(map, layer.sld, layer.projection,
layer.name);
});

});

var utility = {
// Some utility functions

populateDropdown: function (dropdown, array) {
// Populates the dropdown based on the array given
$.each(array, function () {
var option = document.createElement('option');
$(dropdown)
.append($(option)
.attr('value', this)
.html(this));
});
},
generateSequence: function (start, stop, count) {
// Generates a sequence of numbers with the given start,
// stop and count variables
var sequence = [];
var step = (stop - start) / (count - 1.0);
for (var i = 0; i < count; i++) {
sequence.push(parseFloat(start + i * step));
}
return sequence;
},
getPalette: function (name, count) {
// Gets the palette array with the given name and count parameters
return colorbrewer[name][count];
},
createMapEntry: function (xml, color, value, opacity) {
// Adds a color-quantity-opacity entry to the sld
$(xml)
.find('ColorMap')
.append($('<ColorMapEntry>', xml)
.attr({
color: color,
quantity: value,
opacity: opacity
}));
},
generateXml: function (name, count, values, palette, type) {
// Generates the xml (sld) file with the given parameters
var xml = $($.parseXML(
'<?xml version="1.0" encoding="utf-8" ?><StyledLayerDescriptor />'
));
$('StyledLayerDescriptor', xml)
.attr({
'version': '1.0.0',
'xsi:schemaLocation': 'http://www.opengis.net/sld StyledLayerDescriptor.xsd',
'xmlns': 'http://www.opengis.net/sld',
'xmlns:ogc': 'http://www.opengis.net/ogc',
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance'
});
$('StyledLayerDescriptor', xml)
.append($('<NamedLayer>', xml));
$(xml)
.find('NamedLayer')
.append($('<Name>', xml))
.append($(
'<UserStyle>', xml));
$(xml)
.find('Name')
.text(name);
$(xml)
.find('UserStyle')
.append($('<Title>', xml))
.append($(
'<IsDefault>', xml))
.append($('<FeatureTypeStyle>', xml));
$(xml)
.find('Title')
.text('Custom Visualization');
$(xml)
.find('IsDefault')
.text(1);
$(xml)
.find('FeatureTypeStyle')
.append($('<Rule>', xml));
$(xml)
.find('Rule')
.append($('<RasterSymbolizer>', xml));
$(xml)
.find('RasterSymbolizer')
.append($('<ColorMap>', xml));

if (type === 'discrete') {
$(xml)
.find('ColorMap')
.attr({
'type': 'intervals'
});
}

for (var i = 0; i < count; i++) {
this.createMapEntry(xml, palette[i], values[i], 1);
}
var xmlString = (new XMLSerializer())
.serializeToString(xml.context);

return xmlString;
},
createWMSLayer: function (map, sld, projection, layer_name) {

// Add an OSM layer with a WMS server as the source of its titles
var wms = map.createLayer('osm', {
keepLower: false,
attribution: null
});

wms.url(function (x, y, zoom) {
// Compute the bounding box
var bb = wms.gcsTileBounds({
x: x,
y: y,
level: zoom
}, projection);
var bbox_mercator = bb.left + ',' + bb.bottom + ',' +
bb.right + ',' + bb.top;
// Set the WMS server parameters
var params = {
'SERVICE': 'WMS',
'VERSION': '1.3.0',
'REQUEST': 'GetMap',
'LAYERS': layer_name, // US Elevation
'STYLES': '',
'BBOX': bbox_mercator,
'WIDTH': 256, //Use 256x256 tiles
'HEIGHT': 256,
'FORMAT': 'image/png',
'TRANSPARENT': true,
'SRS': projection,
'TILED': true,
'SLD_BODY': sld
};
// OpenGeo Demo Web Map Service
var baseUrl =
'http://demo.boundlessgeo.com/geoserver/ows';
return baseUrl + '?' + $.param(params);
});

return wms;

}
};
Binary file added examples/sld/thumb.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"bootswatch": "^3.3.6",
"codecov.io": "^0.1.6",
"codemirror": "^5.15.2",
"colorbrewer": "^1.0.0",
"css-loader": "^0.23.1",
"docco": "^0.7.0",
"earcut": "^2.1.1",
Expand Down
3 changes: 3 additions & 0 deletions webpack-examples.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ var loaders = base.module.loaders.concat([{
}, {
test: /jsonlint\.js$/,
loader: 'expose?jsonlint'
}, {
test: require.resolve('colorbrewer'),
loader: 'expose?colorbrewer'
}]);

loaders = loaders.concat(external.module.loaders);
Expand Down