Infraestructura de Datos Espaciales de Zaragoza (IDEZar)

Ejemplo II: Uso de OpenLayer

Visualización de los monumentos de la ciudad sobre la cartografía base de Zaragoza mediante el acceso al WMST (servicio de mapas tileado) de IDEE (en WGS84) y al API del Ayuntamiento de Zaragoza (en WGS84)

Código Fuente

<html>
	<head>
		<meta charset="utf-8">
		<title>Visor OpenLayers WMTS</title>
		<script src="http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.2.1/proj4.js" type="text/javascript"></script>
		<script src="http://epsg.io/25830.js" type="text/javascript"></script>
		<script src="http://openlayers.org/en/v3.7.0/build/ol.js" type="text/javascript"></script>
		<link rel="stylesheet" href="http://openlayers.org/en/v3.7.0/css/ol.css" type="text/css">
		<style type="text/css">
			#mapa-ol-wms, #mapa-ol-wmts{		
				width:600px;
				height:30em;
			}
			#map{		
				width:100%;
				height:500px;
				box-shadow: 5px 5px 5px #888;
			}
			.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: 300px;
				font: 12px Tahoma !important;
			}
			.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: "";
			}
		</style>
	</head>
	<body>
		<div id="mapa-ol-wmts"></div>
			<div id="popup-wmts" class="ol-popup">
				<a href="#" id="popup-closer-wmts" class="ol-popup-closer"></a>
			<div id="popup-content-wmts"></div>
		</div>
		
		<script>
			var mapInitialZoom = 14;
			var mapMinZoom = 12;
			var mapMaxZoom = 19;
			
			var projectionOLWMTS = ol.proj.get('EPSG:4326');
			var projectionOLWMTSExtent = projectionOLWMTS.getExtent();
			var sizeWMTS = ol.extent.getWidth(projectionOLWMTSExtent) / 512;
			var resolutionsWMTS = new Array(19);
			var matrixIdsWMTS = new Array(19);
			for (var z = 0; z < 19; ++z) {
				// generate resolutions and matrixIds arrays for this WMTS
				resolutionsWMTS[z] = sizeWMTS / Math.pow(2, z);
				matrixIdsWMTS[z] = z;
			}

			var attributionWMTS = new ol.Attribution({
				html: 'Teselas de PNOA cedido por © Instituto Geográfico Nacional de España'
			});

			var vectorSourceWMTS = new ol.source.Vector({
				url: "http://www.zaragoza.es/api/recurso/turismo/monumento.geojson?srsname=wgs84&rows=2000&fl=id,title,description,geometry",
				format: new ol.format.GeoJSON(),
				useSpatialIndex: true
			});
	 
			var clusterSource = new ol.source.Cluster({
				distance: 60,
				source: vectorSourceWMTS,
				useSpatialIndex: true
			});
			var styleCacheWMTS = {};
			var gjsonFileWMTSCluster = new ol.layer.Vector({
				source: clusterSource,
				style: function(cluster, resolution) {
					var size = cluster.get('features').length;
					var style = styleCacheWMTS[size];
					if (!style) {
						if (size == 1) {
							var src = cluster.getProperties().features[0].getProperties().icon;
							if (!src) {
								src = "http://www.zaragoza.es/contenidos/iconos/location.png";
							}
							style = [new ol.style.Style({
								image: new ol.style.Icon(({
									src: src
								}))
							})];
						} else {
							style = [new ol.style.Style({
								image: new ol.style.Circle({
									radius: (parseInt(size/10)+3)*5,
									stroke: new ol.style.Stroke({
										color: '#FFFFFF',
										width: 2
									}),
									fill: new ol.style.Fill({
										color: '#CC0000'
									})
								}),
								text: new ol.style.Text({
									text: size.toString(),
									font: "14px Tahoma",
									fill: new ol.style.Fill({
										color: '#FFFFFF'
									})
								})
							})];
						}
						styleCacheWMTS[size] = style;
					}
					return style;
				}
			});
			
			var containerPopupWMTS = document.getElementById('popup-wmts');
			var contentPopupWMTS = document.getElementById('popup-content-wmts');
			var closerPopupWMTS = document.getElementById('popup-closer-wmts');
			
			closerPopupWMTS.onclick = function() {
				popupPopupWMTS.setPosition(undefined);
				closerPopupWMTS.blur();
				return false;
			};

			var popupPopupWMTS = new ol.Overlay({
				element: containerPopupWMTS,
				autoPan: true,
				autoPanAnimation: {
					duration: 250
				}
			});
	 
			var mapOLWMTS = new ol.Map({
				layers: [
					new ol.layer.Tile({
						opacity: 1.0,
						source: new ol.source.WMTS({
							attributions: [attributionWMTS],
							url: 'http://www.ign.es/wmts/ign-base',
							layer: 'IGNBaseTodo',
							matrixSet: 'InspireCRS84Quad',
							format: 'image/png',
							projection: projectionOLWMTS,
							tileGrid: new ol.tilegrid.WMTS({
								origin: ol.extent.getTopLeft(projectionOLWMTSExtent),
								resolutions: resolutionsWMTS,
								matrixIds: matrixIdsWMTS
							}),
							style: 'default',
							minZoom: mapMinZoom,
							maxZoom: mapMaxZoom
						})
					}),
					gjsonFileWMTSCluster
				],
				overlays: [popupPopupWMTS],
				target: 'mapa-ol-wmts',
				controls: ol.control.defaults({
					attributionOptions: ({
						collapsible: false
					})
				}),
				view: new ol.View({
					projection: projectionOLWMTS,
					center: ol.proj.transform([-0.8807887554972524, 41.65701793638502], "EPSG:4326", projectionOLWMTS),
					zoom: mapInitialZoom,
					minZoom: mapMinZoom,
					maxZoom: mapMaxZoom
				})
			});
			
			mapOLWMTS.on('singleclick', function(evt) {
				var cluster = mapOLWMTS.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
					return feature;
				});
				
				if (cluster) {
					if (cluster.getProperties().features.length == 1) {
						// Popup de la feature
						var feature = cluster.getProperties().features[0];
						var coord = feature.getGeometry().getCoordinates();
						var props = feature.getProperties();
						var title = props.title;
						var description = props.description;
						if (title || description) {
							var info = (title ? "<b>" + title + "</b>" : "");
							info += (description ? "<p>" + description + "</p>" : "");
							popupPopupWMTS.setOffset([0, -10]);
							contentPopupWMTS.innerHTML = info;
							popupPopupWMTS.setPosition(coord);
						}
					} else {
						// Eliminar popup si lo hay
						document.getElementById(mapOLWMTS.getTarget()).style.cursor = 'default';
						popupPopupWMTS.setPosition(undefined);
						closerPopupWMTS.blur();
						// Desclusterizar
						var clusterFeatures = cluster.getProperties().features;
						var clusterExtent = ol.extent.createEmpty();
						for (var j = 0, jj = clusterFeatures.length; j < jj; ++j) {
							ol.extent.extend(clusterExtent, clusterFeatures[j].getGeometry().getExtent());
						}
						mapOLWMTS.getView().fit(clusterExtent, mapOLWMTS.getSize())
					}
				} else {
					popupPopupWMTS.setPosition(undefined);
					closerPopupWMTS.blur();
				}
			});
			
			mapOLWMTS.on('pointermove', function(e) {
				var pixel = mapOLWMTS.getEventPixel(e.originalEvent);
				var hit = mapOLWMTS.hasFeatureAtPixel(pixel);
				document.getElementById(mapOLWMTS.getTarget()).style.cursor = (hit ? 'pointer' : 'default');
			});
		</script>
	</body>
</html>

Visualización