OpenLayers Tutorial Part 3

Display Features on Click Tutorial Part 1

In our previous tutorial we created a basic OpenLayers map and then added one our GeoServer layers to it.

In this tutorial, we will make the GeoServer layer clickable in order to display feature information.

In the 2 previous tutorials we add all of our CSS and Javascript "inline". Here, we will use external CSS and Javascript file to keep our code organized.

/home/username/
  • map.html
  • custom.css
  • custom.js

As in our first tutorial, lets begin with a basic HTML document.

<html>
  <head>
    <title>
	OpenLayers with GeoServer Features</title>
	</head>
  <body>
  </body>
</html>

Include these OpenLayers CSS and Javascript files in head tag:

	 <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css">

This time, in order to handle our feature click request, we will also add jQuery to our header section:

<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>

As earlier, we now add the map div on the page where you want to display the map and set the height/width for this div

<div id="map"></div>

This time, in order to provide a space for our feature information, we will also add a div for the feature display:

<div id="map" class="map"></div>
<div id="popup" class="ol-popup">
	<a href="#" id="popup-closer" class="ol-popup-closer"></a>
	<div id="popup-content"></div>
</div>

Our HTML document, map.html, should now look as below:

	  
			  <html>
	<head>
		<title>OpenLayers with GeoServer Features</title>
		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol.css" type="text/css">
		<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol.js"></script>
		
		<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
		
	</head>
	<body>
		<div id="map" class="map"></div>
		<div id="popup" class="ol-popup">
			<a href="#" id="popup-closer" class="ol-popup-closer"></a>
			<div id="popup-content"></div>
		</div>
	</body>
</html>

Next, create our CSS file as custom.css:

.ol-popup {
	position: absolute;
	background-color: white;
	-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
	filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
	padding: 15px;
	border-radius: 10px;
	border: 1px solid #cccccc;
	bottom: 12px;
	left: -50px;
	min-width: 280px;
  }
  .ol-popup:after, .ol-popup:before {
	top: 100%;
	border: solid transparent;
	content: " ";
	height: 0;
	width: 0;
	position: absolute;
	pointer-events: none;
  }
  .ol-popup:after {
	border-top-color: white;
	border-width: 10px;
	left: 48px;
	margin-left: -10px;
  }
  .ol-popup:before {
	border-top-color: #cccccc;
	border-width: 11px;
	left: 48px;
	margin-left: -11px;
  }
  .ol-popup-closer {
	text-decoration: none;
	position: absolute;
	top: 2px;
	right: 8px;
  }
  .ol-popup-closer:after {
	content: "✖";
  }

Now, create our Javascript file as custom.js:

$(document).ready(function() {
	var wmsSource = new ol.source.ImageWMS({
		url: 'https://localhost/geoserver/wms',
		params: {'LAYERS': 'topp:states'},
		ratio: 1,
		serverType: 'geoserver'
	});

	var layers = [
		new ol.layer.Tile({
		  source: new ol.source.OSM()
		}),
		new ol.layer.Image({
			extent: [-13884991, 2870341, -7455066, 6338219],
			source: wmsSource
		})
	]

	var view = new ol.View({
		center: [-10997148, 4569099],
	  zoom: 4
	});

	var map = new ol.Map({
		layers: layers,
		target: 'map',
		view: view
	});



	/**
	* Elements that make up the popup.
	*/
	var container = document.getElementById('popup');
	var content = document.getElementById('popup-content');
	var closer = document.getElementById('popup-closer');

	/**
	* Create an overlay to anchor the popup to the map.
	*/
	var overlay = new ol.Overlay({
		element: container,
		autoPan: true,
		autoPanAnimation: {
		  duration: 250
		}
	});

	/**
	* Add a click handler to hide the popup.
	* @return {boolean} Don't follow the href.
	*/
	closer.onclick = function() {
		overlay.setPosition(undefined);
		closer.blur();
		return false;
	};

	map.addOverlay(overlay);



	map.on('singleclick', function(evt) {
		var allowed_properties = ["STATE_NAME", "DRVALONE"]; // [];
		
		var url = wmsSource.getGetFeatureInfoUrl(evt.coordinate, view.getResolution(), 'EPSG:3857', {'INFO_FORMAT': 'application/json'});
		if (url) {
			
			$.getJSON(url, '', function(data) {
				var html = '';
				
				$.each(data.features, function(index, obj) {
					if(obj.type == "Feature") {
						var properties = obj.properties;
						
						html += '<h3>'+obj.id+'</h3>';
						html += '<p>';
						
						for (var property in properties) {
							if (properties.hasOwnProperty(property)) {
								if(!allowed_properties || allowed_properties.indexOf(property) != -1) {
									html += '<b>'+property+' : </b>'+properties[property]+'<br>';
								}
							}
						}
						
						html += '</p>';
					}
				});
				
				var coordinate = evt.coordinate;
				content.innerHTML = html;
				overlay.setPosition(coordinate);
			});
			
		}
	});
});

Note: above we have limited the properties displayed to and . To show feature properties, set var allowed_properties = [];

// Iterate through properties with key and values
for (var property in properties) {
	if (properties.hasOwnProperty(property)) {
	
		var allowed_properties = []; // Set the targeted property names only
		if(allowed_properties.indexOf(property) != -1) {
			html += '<b>'+property+' : </b>'+properties[property]+'<br>';
		}
	}
}

Putting it all together.

Now, let's add our custom.css and custom.js files to the header of our map.html file:


			  <link rel="stylesheet" href="custom.css" type="text/css">
<script src="custom.js"></script>/

Finally, we have our completed HTML page with css and js includes:

Create our CSS sheet, custom.css as below:

Now, we add the javascript for the overlay and the pop-up:

<html>
	<head>
		<title>OpenLayers with GeoServer Features</title>
		<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol.css" type="text/css">
		<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.6.5/ol.js"></script>
		
		<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
		<link rel="stylesheet" href="custom.css" type="text/css">
		<script src="custom.js"></script>
	</head>
	<body>
		<div id="map" class="map"></div>
		<div id="popup" class="ol-popup">
			<a href="#" id="popup-closer" class="ol-popup-closer"></a>
			<div id="popup-content"></div>
		</div>
	</body>
</html>

 

Up Next: User Directories

Leaflet Demo Tutorial