Open Layers web map development with Geoserver

The last few months, I have been learning the basics of OpenLayers 3.6. This has involved learning to setup a map, import layers from various sources and add feature overlays.

The screenshots below show where I am at: I have a few layers (one geojson, WMS on my own geoserver and a WMS on a public geoserver) which can be switched on and off and a feature overlay for the Countries layer, providing the user with some relevant information. Screenshots can be seen below.

tool_crop

All layers on, with feature overlay on France and text occuring in bottom right hand of screen.

tool_crop

Counties layer (my geoserver) switched off, with additional feature overlay styling upon specified zoom layer.

tool_crop

Streams layer (public geoserver) and OSM base map switched on, other layers off.

Source code can be seen below:


<!doctype html>
<html lang="en">
<head>
	<title>Playing with various sources and layers</title>
	<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.css" type="text/css">
	<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script>
</head>
	
<body>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script> 
	<div class="row-fluid">
		<div class="col-sm-8">
			<div id="map" class="map"></div>
		</div>
		<div class="col-sm-4">
			<div class="row">
				<div class="span2">
					<div id="info_check" style="height:400px"><label>Layers</label></div>
					<div id="info_text" style="height:40px; width:200px" class="alert alert-success"></div>
				</div>
			</div>
		</div>
	</div>
		
<script>
		
	//start of the layer definitions
		
	var geoLayer = new ol.layer.Vector({
		source: new ol.source.Vector({
		url:'countries.geojson',
		format: new ol.format.GeoJSON({projection: 'EPSG:3857'})}),
		style: function(feature, resolution) {
			style.getText().setText(resolution < 10000 ? feature.get('name') : '');
		return styles;}});
		geoLayer.set('name', 'Countries of the world');

	//correct way to load geojson above: changed with OL 3.5 and greater. Layer stored locally
	
	//WMS layer extracted from third party geoserver.
	
	var vectorLayer = new ol.layer.Tile({
		source: new ol.source.TileWMS({
		preload: Infinity,
		url: 'http://felek.cns.umass.edu:8080/geoserver/wms',
		serverType:'geoserver',
		params:{
			'LAYERS':"Streams:Developed", 'TILED':true
		}})});
		vectorLayer.set('name','Streams');
		
	//OSM base layer	
		
	var osmLayer = new ol.layer.Tile({source: new ol.source.OSM()});
		osmLayer.set('name','OSM Base map');
	
	//Layer extracted from personal geoserver. Note geoserver must be running on computer to ensure layer is pushed to map.
		
	var vectorLayer2 = new ol.layer.Tile({
		source: new ol.source.TileWMS({
		preload: Infinity,
		url: 'http://localhost:8080/geoserver/wms',
		serverType:'geoserver',
		params:{
			'LAYERS':"tiger:Map2", 'TILED':true
		}})});
		vectorLayer2.set('name','Counties');
	
	//Map setup
		
	var center = ol.proj.transform([0,0], 'EPSG:4326', 'EPSG:3857');
	var view = new ol.View({center: center, zoom: 3});
	var layers = [osmLayer, geoLayer, vectorLayer, vectorLayer2];
	var map = new ol.Map({target: 'map', layers: layers, view: view});
	
	//Styling for Countries layer. This could be put in a css file and linked to in the Head.
		
	var style = new ol.style.Style({
	    fill: new ol.style.Fill({
			color: 'rgba(255, 255, 255, 0.6)'}),
		stroke: new ol.style.Stroke({
			color: '#319FD3',
			width: 1}),
		text: new ol.style.Text({
			font: '12px Calibri,sans-serif',
			fill: new ol.style.Fill({
			  color: '#000'}),
		stroke: new ol.style.Stroke({
			  color: '#fff',
			  width: 3})
		  })
	});
		
	var styles = [style];
	
	//Generate function that allows layer switching
		
	function generate_checkbox(id_checkbox, label_name, html_element, layers2) {
		var checkbox = document.createElement('input'); /* using javascript instead of html to create checkbox and here
			we create an input element equiv to  <input...>*/
		checkbox.type = "checkbox"; /*here we have defined the variable checkbox as a checkbox. equiv to
			type="checkbox"*/
		checkbox.id = id_checkbox; /*let the id of the checkbox = checkbox_id. Equiv to id="xyz"*/
		
		var label = document.createElement('label'); /*use javascript to create html label*/
		label.htmlFor = id_checkbox; // this label is for checkbox with checkbox_id
		label.appendChild(document.createTextNode(label_name)); //giving a label called 'label name' to var label
			
		var br = document.createElement("br");
		html_element.appendChild(br);
		html_element.appendChild(checkbox);
		html_element.appendChild(label);
		// give the variables label and checkbox to a html_element
		
		//Listen for when each layer checkbox has been changed (unticked)
		
		document.getElementById(id_checkbox).addEventListener('change', function() {
			var checked = this.checked;
			if (checked !== layers2.getVisible()) {
			layers2.setVisible(checked);}});
	}
		
	//Create a loop to generate checkboxes and populate them with layer information.
		
	for (var i = layers.length - 1; i >= 0; i--) //backwards loop
	{ 
		var id = layers[i].get('id');
		var name = layers[i].get('name');

		generate_checkbox('layer_id_' + i, '\u00A0' + name, document.getElementById('info_check'), layers[i]); //Run above function to create checkbox in the 'info_
		//check' html element defined in the Head.
	}
		
	//Create styling for feature overlay for Countries layer - this highlights the area of interest 
	//and changes Name text to bold and red upon a specified zoom level.	
	
	var highlightStyleCache = {};

	var featureOverlay = new ol.FeatureOverlay({
		map: map,
		style: function(feature, resolution) {
			var text = resolution < 5000 ? feature.get('name') : '';
			if (!highlightStyleCache[text]) {
			  highlightStyleCache[text] = [new ol.style.Style({
				stroke: new ol.style.Stroke({
				  color: '#f00',
				  width: 1}),
				fill: new ol.style.Fill({
				  color: 'rgba(255,0,0,0.1)'}),
				text: new ol.style.Text({
				  font: '14px Calibri,sans-serif',
				  text: text,
				  fill: new ol.style.Fill({
					color: '#000'}),
				  stroke: new ol.style.Stroke({
					color: '#f00',
					width: 3})
				})
			  })];
			}
			
			return highlightStyleCache[text];
		}
	});

	//Add feature overlay based on pixel location of the cursor.
	
	var highlight;
	
	var displayFeatureInfo = function(pixel) {
		var feature = map.forEachFeatureAtPixel(pixel, function(feature, layer) {
			return feature;
		});

		var info = document.getElementById('info_text'); //select text bar in html element 'info_text'.
		
		//If cursor is on the layer, get the information from the 'iso_a2' column in the geojson, else leave blank.
		
		if (feature) {
			info.innerHTML = feature.get('iso_a2') + ': ' + feature.get('name');
			} else {
			info.innerHTML = '&nbsp;';
		}
		
		if (feature !== highlight) {
			if (highlight) {
				featureOverlay.removeFeature(highlight);
			}
			if (feature) {
				featureOverlay.addFeature(feature);
			}
			highlight = feature;
		}
	};

	//If the user moves cursor or clicks, then the pixle location is captured and used to power the displayFeatureInfo function.
	
	map.on('pointermove', function(evt) {
		if (evt.dragging) {
			return;
		}
		var pixel = map.getEventPixel(evt.originalEvent);
			displayFeatureInfo(pixel);
	});

	map.on('click', function(evt) {
		displayFeatureInfo(evt.pixel);
	});
		
		
		</script>
	</body>
</html>

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s