<html>
<head>
<title>Catalogue of web mapping services (alpha)</title>
<link rel="stylesheet" type="text/css" href="../../externals/ext/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="../../externals/ext/resources/css/xtheme-gray.css" />
<link rel="stylesheet" type="text/css" href="../../externals/openlayers/theme/default/style.css" />
<link rel="stylesheet" type="text/css" href="../../core/theme/css/styler.css" />
<link rel="stylesheet" type="text/css" href="../../core/theme/css/popup-gray.css" />
<link rel="stylesheet" type="text/css" href="./theme/column-tree.css" />
<script type="text/javascript" src="../../externals/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../externals/ext/ext-all-debug.js"></script>
<script type="text/javascript" src="../../externals/openlayers/OpenLayers.js"></script>
<!-- <script type="text/javascript" src="../../externals/openlayers/lib/OpenLayers.js"></script> -->
<script>
window.scriptLocation = "../../core/";
</script>
<script type="text/javascript" src="../../core/lib/GeoExt.js"></script>
<script type="text/javascript" src="./AddLayerWindow.js"></script>
<script type="text/javascript" src="./CustomFilterBuilder.js"></script>
<script type="text/javascript" src="./LayerTree.js"></script>
<script type="text/javascript" src="./LayerNodeUI.js"></script>
<script type="text/javascript" src="./MaxFeaturesWarning.js"></script>
<script>
Ext.BLANK_IMAGE_URL = "../../externals/ext/resources/images/default/s.gif";
// These should go in a better spot.
function recordize(attrs){
var records = new Array();
var mapping = {
"double": "float",
"string": "string",
"long" : "int",
"MultiSurfacePropertyType": "auto"
}
for (var i = 0; i < attrs.length; i++){
var a = attrs[i];
var k = a.type.replace(/.*:/, '');
if (mapping[k]){
records.push({
name: a.name,
mapping: a.name,
type: mapping[k]
});
}
}
return Ext.data.Record.create(records);
}
function columnize(attrs){
var cols = new Array();
for (var i = 0; i < attrs.length; i++){
var a = attrs[i];
if (a.type){
cols.push({
id: a.name,
header: a.name,
dataIndex: a.name,
hidden: (i>11 | a.type.startsWith('gml:')),
sortable: true
});
} else {
console.log(a.name + " has no type");
}
}
return cols;
}
GeoExt.Drake = {
filterBuilder: null,
grid: null,
filter: null,
store: null,
fields: null,
map: null,
wfsStoreLayer: null,
load: function(config) {
OpenLayers.Util.extend(this, config);
// Show the error window on network failures.
GeoExt.RequestMgr.on("requestexception", function(request, url) {
var errorWindow = new GeoExt.ErrorWindow({
request: request,
url: url,
modal: true
});
errorWindow.show();
}, this);
var attributeStore = new GeoExt.data.AttributesStore({
url: this.wfsUrl + "?typename=" + this.getFullType() + "&request=describefeaturetype"
});
attributeStore.load({
// TODO: Rename x to something meaningful.
callback: function(x){
this.fields = [];
for (var i = 0; i < x.length; i++){
this.fields.push(x[i].data);
}
this.initFilter();
this.initFeatureStore();
this.initWMSStore();
this.initMap();
this.initFilterBuilder();
this.initPagingBar();
this.initFeatureGrid();
this.initLayerTree();
this.initLegendPanel();
new Ext.Viewport({
layout: 'border',
items: [
new Ext.Panel({
region: "west",
layout: "border",
items: [
this.filterBuilder,
this.layerTree
],
width: 370,
collapsible: true,
collapseMode: "mini",
split: true
}),
this.mapPanel,
//this.grid,
this.legendPanel
]
});
},
scope: this
});
},
initFilter: function() {
this.filter = new OpenLayers.Filter.Logical({
type: OpenLayers.Filter.Logical.OR,
filters: []
});
},
createProxy: function(params) {
params = params || {};
var type = params.type || this.featureType;
var ns = params.namespace || 'http://emsmaps.intranet.who.int:8080/geoserver/WHO';
var prefix = params.prefix || this.featurePrefix;
var proto = new OpenLayers.Protocol.WFS({
url: this.wfsUrl,
featureType: type,
featureNS: ns,
featurePrefix: prefix,
srsName: "EPSG:4326",
version: "1.1.0",
maxFeatures: this.maxFeatures
});
return new GeoExt.data.ProtocolProxy({protocol: proto});
},
initFeatureStore: function() {
// create the data store
this.featureStore = new Ext.data.Store({
proxy: this.createProxy(),
remoteSort: true,
reader: new Ext.data.JsonReader({}, [])
});
var showMaxFeaturesWarning = true;
this.featureStore.on("load", function() {
if (showMaxFeaturesWarning && this.featureStore.getTotalCount() >= this.maxFeatures) {
var maxFeaturesWarning = new GeoExt.drake.MaxFeaturesWarning({
maxFeatures: this.maxFeatures
});
maxFeaturesWarning.on("donotshowchange", function(newValue) {
showMaxFeaturesWarning = !newValue;
}, this);
maxFeaturesWarning.show();
}
}, this);
},
initWMSStore: function() {
this.wmsStore = new Ext.data.GroupingStore({
url: this.wmsUrl + "?request=getcapabilities",
reader: new GeoExt.data.WMSCapabilitiesReader(),
sortInfo: {field: 'prefix'},
groupField: 'prefix'
});
},
initFilterBuilder: function() {
this.filterBuilder = new GeoExt.drake.CustomFilterBuilder({
title: "Filter Builder",
region: "south",
height: 175,
autoScroll: true,
filter: this.filter.clone(),
attributes: new GeoExt.data.AttributesStore({
url: this.getWFSLayerURL(this.getFullType()),
ignore: {name: "the_geom"}
}),
addToToolbar: ["->", new Ext.form.Checkbox({
boxLabel: "Use Filter",
enableToggle: true,
handler: function(checkbox, checked) {
if (checked){
this.featureStore.proxy.setOGCFilter(this.filterBuilder.getFilter());
this.filterBuilder.on("change", this.updateQueryFilter, this);
} else {
this.featureStore.proxy.setOGCFilter(null);
this.filterBuilder.un("change", this.updateQueryFilter, this);
}
this.reloadFeatureStore();
},
scope: this
})]
});
},
initPagingBar: function() {
this.pagingBar = new Ext.PagingToolbar({
pageSize: 7,
store: this.featureStore,
displayInfo: true,
displayMsg: 'Displaying features {0} - {1} of {2}',
emptyMsg: 'No features to display'
});
},
initMap: function() {
this.map = new OpenLayers.Map({
theme: null,
controls: [],
units: "m",
projection: new OpenLayers.Projection("EPSG:4326"),
// maxExtent: new OpenLayers.Bounds(-139.53227612499998,20.816194750000008,-59.55180737499998,55.44510100000001)
maxExtent: new OpenLayers.Bounds(-180,-90,180,90)
});
this.wfsStoreLayer = new GeoExt.layer.Vector("Vector Layer", {
store: this.featureStore,
displayInLayerSwitcher: false
}
);
/*
var baseLayer = new OpenLayers.Layer.WMS(
"OpenStreetMap",
"http://demo.opengeo.org/geoserver_openstreetmap/gwc/service/wms",
{layers: 'openstreetmap', format:'image/png'}, {isBaseLayer: true}
);
var vmap0 = new OpenLayers.Layer.WMS(
"Metacarta Vmap0",
"http://labs.metacarta.com/wms/vmap0",
{layers: 'basic'}, {isBaseLayer: true}
);
*/
var countries = new OpenLayers.Layer.WMS(
"WHO Official Political Boundaries",
"/geoserver/wms?",
{layers: 'WHO:ith_list_polygon'}, {isBaseLayer: true}
);
                        
                        var gaul = new OpenLayers.Layer.WMS(
"FAO Admin 1 Level (GAUL)",
"http://geonetwork3.fao.org/ows/12691_1?",
{layers: 'gaul_first_level', format:'image/png'}, {isBaseLayer: false, visibility:false}
);
                        
                        var gpd = new OpenLayers.Layer.WMS(
"FAO Global Poultry Density",
"http://geonetwork3.fao.org/ows/12720?",
{layers: 'poultry_density', format:'image/png'}, {isBaseLayer: false, visibility:false}
);
                        
                        var pig = new OpenLayers.Layer.WMS(
"FAO Global Pig Density",
"http://geonetwork3.fao.org/ows/12719?",
{layers: 'pig_density', format:'image/png'}, {isBaseLayer: false, visibility:false}
);
                        var pop = new OpenLayers.Layer.WMS(
"Landscan Global Population",
"http://geonetwork3.fao.org/ows/1261?",
{layers: 'landscan_global_population_2000', format:'image/png'}, {isBaseLayer: false}
);
                        
                        var apcp = new OpenLayers.Layer.WMS("IRI 6-day Forecast Precipitation","http://iridl.ldeo.columbia.edu/expert/home/.mbell/.IRI/.MD/.IFRC/.ESRL/.PSD/.refcst/.tot6day/.apcp/S/last/VALUE/X/Y/fig-/colors/black/thin/countries_gaz/-fig//color_smoothing/null/psdef/wmsfigmap",
{layers: 'apcp', transparent: 'false', wrapDateLine: 'true', srs: 'EPSG:4326' }, {isBaseLayer: false, visibility:false});
                        
                        var prcpa = new OpenLayers.Layer.WMS("IRI Precipitation Anomaly","http://iridl.ldeo.columbia.edu/SOURCES/.IRI/.MD/.CID/wmsmap",
{layers: 'prcp_anomaly', transparent: 'false', wrapDateLine: 'true', srs: 'EPSG:4326' }, {isBaseLayer: false, visibility:false});
                        
                        var csmt = new OpenLayers.Layer.WMS("IRI Months Suitable for Malaria Transmission","http://iridl.ldeo.columbia.edu/SOURCES/.IRI/.MD/.SERVIR/wmsmap?",
{layers: 'CSMT.Annual_Sum', transparent: 'false', wrapDateLine: 'true', srs: 'EPSG:4326' }, {isBaseLayer: false, visibility:false});
                        
                        var prcp = new OpenLayers.Layer.WMS("FEWS estimated precipitation","http://iridl.ldeo.columbia.edu/expert/SOURCES/.NOAA/.NCEP/.CPC/.FEWS/.Africa/.TEN-DAY/.RFEv2/.est_prcp/MEWSprcp_colors/X/Y/fig-+colors+grey+verythin+mews_dist+black+verythin+mews_prov+black+thin+countries_gaz+black+thinnish+coasts_gaz+-fig+//antialias+true+psdef/wmsfigmap",
{layers: 'est_prcp', transparent: 'false', wrapDateLine: 'true', srs: 'EPSG:4326' }, {isBaseLayer: false, visibility:false});
                        
                                
// Add some layers with a dummy base layer.
this.map.addLayers([
countries,
                                gaul,
                                gpd,
                                pig,
                                pop,
                                apcp,
                                prcpa,
                                csmt,
                                prcp,
this.wfsStoreLayer
]);
this.map.addControl(new OpenLayers.Control.Navigation());
this.map.addControl(new OpenLayers.Control.PanZoomBar());
this.mapPanel = new GeoExt.MapPanel({
region: "center",
map: this.map,
zoom: 4,
center: new OpenLayers.LonLat(-99.54204174999998,38.13064787500001)
});
},
initFeatureGrid: function() {
this.grid = new Ext.grid.GridPanel({
title: "Feature Query Results",
stripeRows: true,
height:230,
region: "south",
collapsible: true,
collapseMode: "mini",
loadMask: {
msg: "Loading features...",
store: this.featureStore
},
columns: [],
store: this.featureStore,
selModel: new GeoExt.grid.FeatureSelectionModel({
layer: this.wfsStoreLayer
}),
bbar: this.pagingBar
});
this.grid.on("rowdblclick", function(grid, index, evt) {
var record = grid.getSelectionModel().getSelected();
if (record) {
var bounds = record.data.feature.geometry.getBounds();
this.map.zoomToExtent(bounds);
}
}, this);
///////////// POPUP STUFF
this.grid.getSelectionModel().on("rowselect", function (model, row, record){
var feature = record.data.feature;
var content = "<p> You selected " + feature.fid + "! I am truly impressed! </p>";
feature.popup = new GeoExt.popup.Popup({
title: feature.fid,
feature: feature,
width: 235,
height: 70,
html: content,
collapsible: true,
collapsed: true,
expandOnShow: false
});
var popup = feature.popup;
this.grid.store.on("load", function(store, records, options){
var record;
for(var i = 0; i < records.length; i++){
if(records[i].data.feature == feature){
return;
}
}
if(popup.anc){
popup.close();
}
});
feature.popup.addToMapPanel(this.mapPanel);
}, this);
this.grid.getSelectionModel().on("rowdeselect", function(model, row, record){
var feature = record.data.feature;
if(feature.popup.anc){
feature.popup.close();
}
});
},
initLayerTree: function() {
var addLayerButton = new Ext.Button({
text: "Add Layer...",
disabled: true,
handler: function() {
var win = new GeoExt.drake.AddLayerWindow({
capsStore: this.wmsStore
});
win.on("layerschosen", function(layers) {
var layer;
for (var index = 0; index < layers.length; index++) {
var layerRecord = layers[index];
var name = layerRecord.data.name;
var tilesOrigin = layerRecord.data.llbbox[0] + "," + layerRecord.data.llbbox[1];
layer = new OpenLayers.Layer.WMS(name, this.wmsUrl, {
layers: name,
format: "image/png",
transparent: "true",
tiled: true,
tilesOrigin: tilesOrigin
}, {
isBaselayer: false,
maxExtent: OpenLayers.Bounds.fromArray(layerRecord.data.llbbox)
});
layer.drakestyles = layerRecord.data.styles;
var found = false;
for (var layersIndex = 0; layersIndex < this.map.layers.length; layersIndex++) {
if (this.map.layers[layersIndex] instanceof OpenLayers.Layer.WMS) {
if (layer.params.LAYERS == this.map.layers[layersIndex].params.LAYERS) {
found = true;
break;
}
}
}
if (!found) {
this.map.addLayer(layer);
}
}
}, this);
win.show();
},
scope: this
});
var root = new Ext.tree.TreeNode({});
var baseLayerContainer = new GeoExt.tree.BaseLayerContainer({
map: this.map
});
var wfsStore = new Ext.data.Store({
reader: new GeoExt.data.WFSCapabilitiesReader(),
url: this.wfsUrl + "?request=GetCapabilities"
});
// TODO: We should probably have some UI that shows the layer tree is loading,
// as the overlayContainer will not be added to the layerTree until the
// wfsStore's request returns. This is not Hugely Important Right Now, but
// experience tells me that for some user, at some point, this request
// is gonna hang.
wfsStore.load({
callback: function(response) {
var overlayContainer = new GeoExt.tree.OverlayLayerContainer({
map: this.map
});
overlayContainer.on("customizeconfig", function(config, layer) {
config.uiProvider = GeoExt.drake.LayerNodeUI;
config.queryable = wfsStore.find("name", layer.params.LAYERS) >= 0;
});
root.appendChild(overlayContainer);
// Don't allow them to click the Add Layer button until we
// have all the data we need. (i.e., we have it all now,
// so enable the button).
addLayerButton.setDisabled(false);
}
})
root.appendChild(baseLayerContainer);
this.layerTree = new GeoExt.tree.LayerTree({
border: false,
split: true,
rootVisible: false,
title: "Layers",
region: "center",
autoScroll: true,
root: root,
bbar: [
addLayerButton,
new Ext.Button({
text: "Remove selected",
handler: function() {
var nodes = layerTree.getSelectionModel().getSelectedNodes();
for (var i = 0; i < nodes.length; i++){
var layerName = nodes[i].text;
for (var j = 0; j < map.layers.length; j++) {
if (map.layers[j] instanceof OpenLayers.Layer.WMS) {
if (layerName == map.layers[j].params.LAYERS) {
map.layers[j].destroy();
break;
} }
}
}
}
})
]
});
this.layerTree.on("contextmenu", function(node, e){
if (node.layer){
var menuConfig = [{
id: "zoomtobounds",
text: "Zoom to layer bounds",
handler: function(evt){
this.map.zoomToExtent(node.layer.maxExtent);
},
scope: this
}];
if (node.layer.drakestyles && node.layer.drakestyles.length > 1){
for (var i = 0; i < node.layer.drakestyles.length; i++){
var style = node.layer.drakestyles[i];
menuConfig.push({id: style.name,
text: "Render by \"" + style.title + '"',
handler: function(style){
return function(evt){
node.layer.params.STYLES = style.name;
node.layer.redraw();
};
}(style),
scope: this
});
}
}
var menu = new Ext.menu.Menu(menuConfig);
menu.showAt(e.getPoint());
}
}, this);
this.layerTree.on("layeractivated", this.activateLayer, this);
},
addLayerHandler: function() {
},
initLegendPanel: function() {
this.legendPanel = new GeoExt.LegendPanel({
map: this.map,
region: "east",
title: "Legend",
width: 200,
bodyStyle: "padding: 5px",
collapsible: true,
autoScroll: true
});
},
getFullType: function() {
return this.featurePrefix + ":" + this.featureType;
},
getWFSLayerURL: function(type) {
return this.wfsUrl + "?request=DescribeFeatureType&typename=" + type;
},
activateLayer: function(layer) {
this.filterBuilder.attributes = new GeoExt.data.AttributesStore({
url: this.getWFSLayerURL(layer.name),
ignore: {name: "the_geom"}
});
this.filterBuilder.setFilter(null);
var typename = layer.params.LAYERS;
// update fields
var attributeStore = new GeoExt.data.AttributesStore({
url: this.wfsUrl + "?typename=" + typename + "&request=describefeaturetype"
});
attributeStore.load({
// TODO: Rename x to something meaningful.
callback: function(x){
this.fields = [];
for (var i = 0; i < x.length; i++){
this.fields.push(x[i].data);
}
this.finishActivating(attributeStore.reader.namespace, typename);
},
scope: this
});
},
finishActivating: function(namespace, typename) {
var parts = typename.split(':');
this.featurePrefix = parts[0];
this.featureType = parts[1];
this.featureStore.proxy = this.createProxy({prefix: parts[0], type: parts[1], namespace: namespace});
this.featureStore.reader = new GeoExt.data.FeatureReader({}, recordize(this.fields));
this.grid.setTitle(typename + " - " + namespace);
this.grid.colModel.setConfig(columnize(this.fields));
this.reloadFeatureStore();
},
updateQueryFilter: function(builder){
this.featureStore.proxy.setOGCFilter(builder.getFilter());
this.reloadFeatureStore();
},
reloadFeatureStore: function() {
this.featureStore.load({
params: {
start: 0,
limit: this.featuresPerPage
}
});
}
};
Ext.onReady(function() {
GeoExt.Drake.load({
featurePrefix: "topp",
featureType: "states",
geoserverUrl: "/geoserver",
wmsUrl: "/geoserver/wms",
wfsUrl: "/geoserver/wfs",
maxFeatures: 300,
featuresPerPage: 7
});
});
</script>
</head>
<body>
</body>
</html>