[Mapbender-commits] r8384 - trunk/mapbender/http/php

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Mon Jun 18 07:42:34 PDT 2012


Author: armin11
Date: 2012-06-18 07:42:33 -0700 (Mon, 18 Jun 2012)
New Revision: 8384

Added:
   trunk/mapbender/http/php/mod_inspireDownloadFeed.php
Modified:
   trunk/mapbender/http/php/mod_dataISOMetadata.php
Log:
Extension for INSPIRE Download Services - need some review and further things - 1 day.

Modified: trunk/mapbender/http/php/mod_dataISOMetadata.php
===================================================================
--- trunk/mapbender/http/php/mod_dataISOMetadata.php	2012-06-18 12:08:53 UTC (rev 8383)
+++ trunk/mapbender/http/php/mod_dataISOMetadata.php	2012-06-18 14:42:33 UTC (rev 8384)
@@ -61,6 +61,8 @@
 	//Initialize XML document
 	$iso19139Doc = new DOMDocument('1.0');
 	$iso19139Doc->encoding = 'UTF-8';
+	$iso19139Doc->preserveWhiteSpace = false;
+	$iso19139Doc->formatOutput = true;
 } else {
 	echo 'outputFormat: <b>'.$_REQUEST['OUTPUTFORMAT'].'</b> is not set or valid.<br/>'; 
 	die();

Added: trunk/mapbender/http/php/mod_inspireDownloadFeed.php
===================================================================
--- trunk/mapbender/http/php/mod_inspireDownloadFeed.php	                        (rev 0)
+++ trunk/mapbender/http/php/mod_inspireDownloadFeed.php	2012-06-18 14:42:33 UTC (rev 8384)
@@ -0,0 +1,998 @@
+<?php
+//2012-06-15-http://localhost/mapbender/php/mod_inspireDownloadFeed.php?id=70e0c3e5-707c-f8e1-8037-7b38702176d9&type=SERVICE&generatefrom=all
+
+//20648
+// $Id: mod_inspireDownloadFeed.php 235
+// http://www.mapbender.org/index.php/
+// Copyright (C) 2002 CCGIS 
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+//Script to generate a feed for a predefined dataset download as it is demanded in the INSPIRE Download Service guidance 3.0 from 04.05.2012. It will be generated from given wms layers dataurl attributs which are registrated in the mapbender database. The other possibility is, that the wms are used to built the download links. Therefore the wms must support the generation of image/tiff output format with geotiff tags. Many wms do this. These wms must also support a minimum of 1000x1000 pixel for a single getmap request. It works as a webservice. The requested id is the mapbender layers serial id. 
+
+require_once(dirname(__FILE__) . "/../../core/globalSettings.php");
+require_once(dirname(__FILE__) . "/../classes/class_connector.php");
+require_once(dirname(__FILE__) . "/../classes/class_administration.php");
+require_once(dirname(__FILE__) . "/../classes/class_Uuid.php");
+
+$con = db_connect(DBSERVER,OWNER,PW);
+db_select_db(DB,$con);
+
+$admin = new administration();
+
+$imageResolution = 300;
+
+$maxImageSize = 1000;
+
+$maxFeatureCount = 100;
+
+//pull the needed things from tables datalink, md_metadata, layer, wms
+ 
+//parse request parameter
+//make all parameters available as upper case
+foreach($_REQUEST as $key => $val) {
+	$_REQUEST[strtoupper($key)] = $val;
+}
+
+//validate request params
+if (isset($_REQUEST['ID']) & $_REQUEST['ID'] != "") {
+	//validate uuid
+	$testMatch = $_REQUEST["ID"];
+	$uuid = new Uuid($testMatch);
+	$isUuid = $uuid->isValid();
+	if (!$isUuid) {
+		echo 'Id: <b>'.$testMatch.'</b> is not a valid mapbender uuid.<br/>'; 
+		die(); 		
+ 	}
+	$recordId = $testMatch;
+	$testMatch = NULL;
+}
+
+/*
+//validate request params
+if (isset($_REQUEST['ID']) & $_REQUEST['ID'] != "") {
+	//validate integer
+	$testMatch = $_REQUEST["ID"];
+	$pattern = '/^[\d]*$/';		
+ 	if (!preg_match($pattern,$testMatch)){ 
+		echo 'Id: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		die(); 		
+ 	}
+	$recordId = $testMatch;
+	$testMatch = NULL;
+}
+*/
+if (!isset($_REQUEST['TYPE']) || $_REQUEST['TYPE'] == "") {
+	echo '<b>Mandatory parameter type is not set!</b><br>Please set type to <b>DATASET</b> or <b>SERVICE</b>'; 
+	die(); 	
+}
+
+//validate request params
+if (isset($_REQUEST['TYPE']) & $_REQUEST['TYPE'] != "") {
+	//validate type
+	$testMatch = $_REQUEST["TYPE"];	
+ 	if ($testMatch != 'SERVICE' && $testMatch != 'DATASET'){ 
+		echo 'type: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		die(); 		
+ 	}
+	$type = $testMatch;
+	$testMatch = NULL;
+}
+
+if (!isset($_REQUEST['GENERATEFROM']) || $_REQUEST['GENERATEFROM'] == "") {
+	echo '<b>Mandatory parameter GENERATEFROM is not set!</b><br>Please set GENERATEFROM to <b>wmslayer</b>, <b>dataurl</b> or <b>wfs</b> '; 
+	die(); 	
+}
+
+//validate request params
+if (isset($_REQUEST['GENERATEFROM']) & $_REQUEST['GENERATEFROM'] != "") {
+	//validate type
+	$testMatch = $_REQUEST["GENERATEFROM"];	
+ 	if ($testMatch != 'wmslayer' && $testMatch != 'dataurl'  && $testMatch != 'wfs' && $testMatch != 'all'){ 
+		echo 'GENERATEFROM: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		die(); 		
+ 	}
+	$generateFrom = $testMatch;
+	$testMatch = NULL;
+}
+
+if ($generateFrom == "wmslayer") {
+	//check if layerId is set too
+	if (isset($_REQUEST['LAYERID']) & $_REQUEST['LAYERID'] != "") {
+		$testMatch = $_REQUEST["LAYERID"];
+		$pattern = '/^[\d]*$/';		
+ 		if (!preg_match($pattern,$testMatch)){ 
+			echo 'LAYERID must be an integer: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+			die(); 		
+ 		}
+		$layerId = $testMatch;
+		$testMatch = NULL;
+	} else {
+		echo 'Mandatory request parameter <b>layerid</b> must be set if download service should be generated by a wms layer!'; 
+		die(); 	
+	}
+}
+
+if ($generateFrom == "wfs") {
+	//check if layerId is set too
+	if (isset($_REQUEST['WFSID']) & $_REQUEST['WFSID'] != "") {
+		$testMatch = $_REQUEST["WFSID"];
+		$pattern = '/^[\d]*$/';		
+ 		if (!preg_match($pattern,$testMatch)){ 
+			echo 'WFSID must be an integer: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+			die(); 		
+ 		}
+		$wfsId = $testMatch;
+		$testMatch = NULL;
+	} else {
+		echo 'Mandatory request parameter <b>WFSID</b> must be set if download service should be generated by using a Web Feature Service!'; 
+		die(); 	
+	}
+}
+
+//Initialize XML document
+$feedDoc = new DOMDocument('1.0');
+$feedDoc->encoding = 'UTF-8';
+$feedDoc->preserveWhiteSpace = false;
+$feedDoc->formatOutput = true;
+
+//Some needfull functions to pull metadata out of the database.
+//List of data which is needed to build the feed:
+//header part ******
+// - feed title: Generated from dataset name - either mb_metadata.title or layer.layer_title
+// - feed subtitle: Generated from dataset name - either mb_metadata.title or layer.layer_title, organisation name - mapbender group information (metadata contact) - cause it is generated from data of a registrated wms
+// - link to ISO19139 service metadata - this will be created dynamically by given layer_id as this script itself
+// - link to opensearch description for this download service - as before the layer_id will be used as a parameter
+// - id - link to the script itself
+// - rights - the access constraints of the view service are used - they should also give information about the access constraints for the usage of the data
+// - updated : last date the feed was updated - use current timestamp of the wms as the feed will be generated from dataurl entry of the layer object - wms.wms_timestamp
+//datalink.random_id - this is newly created when layers are updated ! - new
+//author - use information from mapbender group - metadata point of contact - registrating organization
+//entry part ******
+// - entry title: Generated from dataset name - either mb_metadata.title or layer.layer_title - in combination e.g. with "Feed for ..."
+// - link to the dataset feed - invoked by layer id as this is done before
+// - summary -  Generated by some infomation: mb_metadata.format, mb_metadata.ref_sytem, ...., datalink.datalink_format
+// - updated - timestamp of wms as done before
+// - 
+
+function generateFeed($feedDoc, $recordId, $generateFrom) {
+	global $admin, $type, $imageResolution, $maxImageSize, $maxFeatureCount, $mapbenderMetadata, $indexMapbenderMetadata, $layerId, $wfsId;
+	
+	switch ($generateFrom) {
+
+		case "dataurl":
+			$sql = <<<SQL
+select *, 'dataurl' as origin from (select * from (select * from (select * from (select mb_metadata.metadata_id, layer_relation.layer_name, layer_relation.fkey_wms_id, layer_relation.layer_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, layer_relation.layer_title, layer_relation.layer_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace  from (select * from layer inner join ows_relation_metadata on layer.layer_id = ows_relation_metadata.fkey_layer_id) as layer_relation inner join mb_metadata on layer_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) as layer_metadata inner join ows_relation_data on ows_relation_data.fkey_layer_id = layer_metadata.layer_id) as layer_relation_data inner join datalink on layer_relation_data.fkey_datalink_id 
 = datalink.datalink_id) as layer_data inner join wms on layer_data.fkey_wms_id = wms.wms_id)  as layer_wms, layer_epsg where layer_wms.layer_id = layer_epsg.fkey_layer_id and layer_epsg.epsg = 'EPSG:4326';  
+SQL;
+		$generateFromDataurl = true;
+		break;
+
+		case "wmslayer":
+			$sql = <<<SQL
+select *, 'wmslayer' as origin from (select * from (select mb_metadata.metadata_id, layer_relation.layer_name, layer_relation.fkey_wms_id, layer_relation.layer_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, layer_relation.layer_title, layer_relation.layer_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace  from (select * from layer inner join ows_relation_metadata on layer.layer_id = ows_relation_metadata.fkey_layer_id) as layer_relation inner join mb_metadata on layer_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) layer_data inner join wms on layer_data.fkey_wms_id = wms.wms_id)  as layer_wms, layer_epsg where layer_wms.layer_id = layer_epsg.fkey_layer_id and layer_epsg.epsg = 'EPSG:4326' and layer_wms.layer_id = $2;  
+SQL;
+		break;
+
+		case "wfs":
+			$sql = <<<SQL
+select *, 'wfs' as origin from (select mb_metadata.metadata_id, featuretype_relation.featuretype_name, featuretype_relation.fkey_wfs_id, featuretype_relation.featuretype_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, featuretype_relation.featuretype_title, featuretype_relation.featuretype_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace,  featuretype_relation.featuretype_latlon_bbox as latlonbbox, featuretype_relation.featuretype_srs from (select * from wfs_featuretype inner join ows_relation_metadata on wfs_featuretype.featuretype_id = ows_relation_metadata.fkey_featuretype_id) as featuretype_relation inner join mb_metadata on featuretype_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) as featuretype_data inner join wfs on feature
 type_data.fkey_wfs_id = wfs.wfs_id where wfs.wfs_id = $2;
+SQL;
+		break;
+
+		case "all":
+			$sql = array();
+			$sql[0] = <<<SQL
+select *, 'dataurl' as origin from (select * from (select * from (select * from (select mb_metadata.metadata_id, layer_relation.layer_name, layer_relation.fkey_wms_id, layer_relation.layer_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, layer_relation.layer_title, layer_relation.layer_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace  from (select * from layer inner join ows_relation_metadata on layer.layer_id = ows_relation_metadata.fkey_layer_id) as layer_relation inner join mb_metadata on layer_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) as layer_metadata inner join ows_relation_data on ows_relation_data.fkey_layer_id = layer_metadata.layer_id) as layer_relation_data inner join datalink on layer_relation_data.fkey_datalink_id 
 = datalink.datalink_id) as layer_data inner join wms on layer_data.fkey_wms_id = wms.wms_id)  as layer_wms, layer_epsg where layer_wms.layer_id = layer_epsg.fkey_layer_id and layer_epsg.epsg = 'EPSG:4326'				
+SQL;
+			$sql[1] =  <<<SQL
+select *, 'wmslayer' as origin from (select * from (select mb_metadata.metadata_id, layer_relation.layer_name, layer_relation.fkey_wms_id, layer_relation.layer_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, layer_relation.layer_title, layer_relation.layer_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace  from (select * from layer inner join ows_relation_metadata on layer.layer_id = ows_relation_metadata.fkey_layer_id) as layer_relation inner join mb_metadata on layer_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) layer_data inner join wms on layer_data.fkey_wms_id = wms.wms_id)  as layer_wms, layer_epsg where layer_wms.layer_id = layer_epsg.fkey_layer_id and layer_epsg.epsg = 'EPSG:4326';		
+		
+SQL;
+			$sql[2] =  <<<SQL
+select *, 'wfs' as origin from (select mb_metadata.metadata_id, featuretype_relation.featuretype_name, featuretype_relation.fkey_wfs_id, featuretype_relation.featuretype_id, mb_metadata.uuid as metadata_uuid, mb_metadata.format,mb_metadata.title as metadata_title, mb_metadata.abstract as metadata_abstract, featuretype_relation.featuretype_title, featuretype_relation.featuretype_abstract, mb_metadata.ref_system as metadata_ref_system, mb_metadata.datasetid, mb_metadata.spatial_res_type, mb_metadata.spatial_res_value, mb_metadata.datasetid_codespace,  featuretype_relation.featuretype_latlon_bbox as latlonbbox, featuretype_relation.featuretype_srs from (select * from wfs_featuretype inner join ows_relation_metadata on wfs_featuretype.featuretype_id = ows_relation_metadata.fkey_featuretype_id) as featuretype_relation inner join mb_metadata on featuretype_relation.fkey_metadata_id = mb_metadata.metadata_id where mb_metadata.uuid = $1) as featuretype_data inner join wfs on feature
 type_data.fkey_wfs_id = wfs.wfs_id;		
+SQL;
+		break;
+	}
+
+	$row = array();
+	$mapbenderMetadata = array();
+	//initialize number of different download options
+	$indexMapbenderMetadata = 0;
+	switch ($generateFrom) {
+		case "dataurl":
+			//only one sql should be done 
+			$v = array($recordId);
+			$t = array('s');
+			$res = db_prep_query($sql,$v,$t);
+			fillMapbenderMetadata($res);
+		break;
+		case "wmslayer":
+			//only one sql should be done 
+			$v = array($recordId, $layerId);
+			$t = array('s','i');
+			$res = db_prep_query($sql,$v,$t);
+			fillMapbenderMetadata($res);
+		break;
+		case "wfs":
+			//only one sql should be done 
+			$v = array($recordId, $wfsId);
+			$t = array('s','i');
+			$res = db_prep_query($sql,$v,$t);
+			fillMapbenderMetadata($res);
+		break;
+		case "all":	//TODO: Maybe a union is a better way, but the sql must be harmonized before
+			for ($i = 0; $i < 3; $i++) {
+				$v = array($recordId);
+				$t = array('s');
+				$sqlQuery = $sql[$i];
+				$res = db_prep_query($sqlQuery,$v,$t);
+				fillMapbenderMetadata($res);
+			}
+		break;
+
+	}
+	$countRessource = count($mapbenderMetadata); //count of coupled featuretypes, layers or dataurls or both!
+	//echo "<error>".count($mapbenderMetadata)."</error>";
+	//die();
+	if ($generateFrom != "wfs") {
+		$countRessource = 1;
+	}
+
+	//for the first entry - top feed level use the first index - right so or do it on another way?
+	$m = 0;
+	
+	if ($generateFromDataurl) {
+		//check if layer_id datalink_id and metadata_id are given and not empty!
+		if (!isset($mapbenderMetadata[$m]->datalink_id) || $mapbenderMetadata[$m]->datalink_id == '') {
+			return "<error>No dataurl element is given for the requested wms layer</error>";
+		}
+	}
+	//TODO - if the wms is a raster based wms and the output format may be geotiff - the feed entries can be generated automatically. We need following information
+	// 1. a raster based wms is given or not - checkbox at metadata editor!
+	// 2. geotiff maybe one of the allowed formats! - layer format
+	// 3. the maximum of pixel which can be served by the wms - maybe 2000x2000px - metadata editor!
+	// 4. The scale hints maybe used to control if a special get map request will produce a picture or not
+	//TODO: In this case we have to generate a feed for every single getmap request. This feed have to be called dynamically too! It will be cool to have the bboxes as get parameter or give a index of the bbox with which the bbox can be calculated again!
+
+	if (!isset($mapbenderMetadata[$m]->metadata_id) || $mapbenderMetadata[$m]->metadata_id == '') {
+		return "<error>The metadataset with id ".$mapbenderMetadata[$m]->metadata_id." has no coupled ".$generateFrom." ressource ".$m."</error>";
+	}
+	$crs = $mapbenderMetadata[$m]->metadata_ref_system;
+	$epsgId = explode(':',$crs);
+		
+	//infos about the registrating department, check first if a special metadata point of contact is defined in the service table - function from mod_showMetadata - TODO: should be defined in admin class
+	if (!isset($mapbenderMetadata[$m]->fkey_mb_group_id) or is_null($mapbenderMetadata[$m]->fkey_mb_group_id) or $mapbenderMetadata[$m]->fkey_mb_group_id == 0){
+		$e = new mb_exception("mod_inspireDownloadFeed.php: fkey_mb_group_id not found!");
+		//Get information about owning user of the relation mb_user_mb_group - alternatively the defined fkey_mb_group_id from the service must be used!
+		$sqlDep = "SELECT mb_group_name, mb_group_title, mb_group_id, mb_group_logo_path, mb_group_address, mb_group_email, mb_group_postcode, mb_group_city, mb_group_voicetelephone, mb_group_facsimiletelephone FROM mb_group AS a, mb_user AS b, mb_user_mb_group AS c WHERE b.mb_user_id = $1  AND b.mb_user_id = c.fkey_mb_user_id AND c.fkey_mb_group_id = a.mb_group_id AND c.mb_user_mb_group_type=2 LIMIT 1";
+		if ($generateFrom != "wfs") {
+			$vDep = array($mapbenderMetadata[$m]->wms_owner);
+		} else {
+			$vDep = array($mapbenderMetadata[$m]->wfs_owner);
+		}
+
+		$tDep = array('i');
+		$resDep = db_prep_query($sqlDep, $vDep, $tDep);
+		$departmentMetadata = db_fetch_array($resDep);
+	} else {
+		$e = new mb_exception("mod_inspireDownloadFeed.php: fkey_mb_group_id found!");
+		$sqlDep = "SELECT mb_group_name , mb_group_title, mb_group_id, mb_group_logo_path , mb_group_address, mb_group_email, mb_group_postcode, mb_group_city, mb_group_voicetelephone, mb_group_facsimiletelephone FROM mb_group WHERE mb_group_id = $1 LIMIT 1";
+		$vDep = array($mapbenderMetadata[$m]->fkey_mb_group_id);
+		$tDep = array('i');
+		$resDep = db_prep_query($sqlDep, $vDep, $tDep);
+		$departmentMetadata = db_fetch_array($resDep);
+	}
+
+	//infos about the owner of the service - he is the man who administrate the metadata - register the service
+	$sql = "SELECT mb_user_email ";
+	$sql .= "FROM mb_user WHERE mb_user_id = $1";
+	if ($generateFrom != "wfs") {
+			$v = array($mapbenderMetadata[$m]->wms_owner);
+		} else {
+			$v = array($mapbenderMetadata[$m]->wfs_owner);
+	}
+	$t = array('i');
+	$res = db_prep_query($sql,$v,$t);
+	$userMetadata = db_fetch_array($res);
+	
+	//check if resource is freely available to anonymous user - which are all users who search thru metadata catalogues:
+	if ($generateFrom != "wfs") {
+		$hasPermission=$admin->getLayerPermission($mapbenderMetadata[$m]->fkey_wms_id,$mapbenderMetadata[$m]->layer_name,PUBLIC_USER);
+	} else {
+		$hasPermission = true;
+	}
+
+	//part which generates the feed 
+	$feed =  $feedDoc->createElementNS('http://www.w3.org/2005/Atom', 'feed');
+	$feed = $feedDoc->appendChild($feed);
+	//$feed->setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+	$feed->setAttribute("xmlns:georss", "http://www.georss.org/georss");
+	if ($type == 'SERVICE') {
+		$feed->setAttribute("xmlns:inspire_dls", "http://inspire.ec.europa.eu/schemas/inspire_dls/1.0");
+	}
+	$feed->setAttribute("xmlns:lang", "de");
+	//echo "<test>".$mapbenderMetadata['fkey_wms_id'].":".$mapbenderMetadata['wms_owner']."</test>";
+	//qualifying id of the referenced ressource: Either dataset id or the id of the metadata record 
+	if (isset($mapbenderMetadata[$m]->datasetid) && $mapbenderMetadata[$m]->datasetid != '' ) {
+		$ressourceId = $mapbenderMetadata[$m]->datasetid_codespace."#".$mapbenderMetadata[$m]->datasetid;
+	}
+
+	//check if the metadata set has a title and abstract if not given (in case of dataurl, use layer information!)
+	//first use metadata title then layer title
+	if (isset($mapbenderMetadata[$m]->metadata_title) && $mapbenderMetadata[$m]->metadata_title != '' ) {
+		$ressourceTitle = $mapbenderMetadata[$m]->metadata_title;
+	} else {
+		if (isset($mapbenderMetadata[$m]->layer_title) && $mapbenderMetadata[$m]->layer_title != '' ) {
+		$ressourceTitle = $mapbenderMetadata[$m]->layer_title;
+		} else {
+			$ressourceTitle = "Title of dataset cannot be found!";
+		}
+	}
+
+	//first use metadata abstract then layer abstract
+	if (isset($mapbenderMetadata[$m]->metadata_abstract) && $mapbenderMetadata[$m]->metadata_abstract != '' ) {
+		$ressourceAbstract = $mapbenderMetadata[$m]->metadata_abstract;
+	} else {
+		if (isset($mapbenderMetadata[$m]->layer_abstract) && $mapbenderMetadata[$m]->layer_abstract != '' ) {
+			$ressourceAbstract = $mapbenderMetadata[$m]->layer_abstract;
+		} else {
+			$ressourceAbstract = "Abstract of dataset cannot be found!";
+		}
+	}
+	//Begin generation of feed content *********************************************************************************************
+	//feed title - 5.1.1 / 5.2
+	//<title>XYZ Example INSPIRE Download Service</title>
+	//<title>XYZ Example INSPIRE Dataset ABC Download</title>
+	$feedTitle = $feedDoc->createElement("title");
+	//$feedTitle->setAttribute("xml:lang", "de");
+	if ($type == 'SERVICE') {
+		$feedTitleText = $feedDoc->createTextNode("INSPIRE Download Service Feed für  ".$ressourceTitle);
+	} else { //DATASET
+		$feedTitleText = $feedDoc->createTextNode("INSPIRE Datensatz Feed für ".$ressourceTitle);
+	}
+	$feedTitle->appendChild($feedTitleText);
+	$feed->appendChild($feedTitle);
+	//feed subtitle - 5.1.2 / 5.2
+	//<subtitle xml:lang="en">INSPIRE Download Service of organisation XYZ providing a data set for the Hydrography theme</subtitle>
+	//<subtitle>INSPIRE Download Service, of organisation XYZ providing dataset ABC for the Hydrography theme</subtitle>
+	$feedSubTitle = $feedDoc->createElement("subtitle");
+	//$feedSubTitle->setAttribute("xml:lang", "de");
+	if ($type == 'SERVICE') {
+		$feedSubTitleText = $feedDoc->createTextNode("INSPIRE Download Service von ".$departmentMetadata['mb_group_title']."");
+	} else { //DATASET
+		$feedSubTitleText = $feedDoc->createTextNode("INSPIRE Download Service von: ".$departmentMetadata['mb_group_title']." zur Bereitstellung des Datensatzes: ".$ressourceTitle);
+	}
+	//TODO maybe add topic
+	$feedSubTitle->appendChild($feedSubTitleText);
+	$feed->appendChild($feedSubTitle);
+
+	//links
+	//metadata
+
+	//service metadata - 5.1.3 / dataset metadata 5.2.1
+	//<link href="http://xyz.org/metadata" rel="describedby" type="application/vnd.iso.19139+xml"/>
+	$feedLink = $feedDoc->createElement("link");
+	if ($type == 'SERVICE') {
+		$feedLink->setAttribute("href", "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_dataLinkDownloadISOMetadata.php?Id=".$recordId."&outputFormat=iso19139");
+	} else { //DATASET
+		$feedLink->setAttribute("href", "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_dataISOMetadata.php?id=".$mapbenderMetadata[$m]->metadata_uuid."&outputFormat=iso19139");
+	}
+	$feedLink->setAttribute("rel", "describedby");
+	$feedLink->setAttribute("rel", "application/vnd.iso.19139+xml");
+	//$feedLink->setAttribute("title", "Metadaten");
+	//$feedLink->setAttribute("hreflang", "de");
+	$feed->appendChild($feedLink);
+
+	//self reference - 5.1.4 / 5.2
+	if ($type == 'SERVICE') {
+		$selfReference = "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_inspireDownloadFeed.php?ID=".$recordId."&type=SERVICE&generatefrom=".$generateFrom;
+	} else { //DATASET
+		$selfReference = "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_inspireDownloadFeed.php?ID=".$recordId."&type=DATASET&generatefrom=".$generateFrom; //TODO: add layerid and wfsid
+	}
+
+	//<link href="http://xyz.org/data" rel="self" type="application/atom+xml" hreflang="en" title="This document"/>
+	$feedLink = $feedDoc->createElement("link");
+	$feedLink->setAttribute("href", $selfReference);
+	$feedLink->setAttribute("rel", "self");
+	$feedLink->setAttribute("type", "application/atom+xml");
+	$feedLink->setAttribute("hreflang", "de");
+	$feedLink->setAttribute("title", "Selbstreferenz");
+	$feed->appendChild($feedLink);
+	
+	//opensearch descriptionlink 5.1.5
+	if ($type == 'SERVICE') {
+		$feedLink = $feedDoc->createElement("link");
+		$feedLink->setAttribute("href", "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mb_datalinkOpensearchDescription.php?ID=".$recordId);
+		$feedLink->setAttribute("rel", "search");
+		$feedLink->setAttribute("type", "application/opensearchdescription+xml");
+		//$feedLink->setAttribute("hreflang", "de");
+		$feedLink->setAttribute("title", "Open Search Beschreibung des INSPIRE Download Dienstes für den Datensatz ".$ressourceTitle);
+		$feed->appendChild($feedLink);
+	} else { //5.2.2
+
+	//description of datatypes - if given??? What todo when there is no description available - some html page have to be referenced?
+		$feedLink = $feedDoc->createElement("link");
+		$feedLink->setAttribute("href", "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_showMetadata.php?languageCode=de&resource=layer&layout=tabs&id=".$recordId); //TODO show metadata in form of html content - switch for each type
+		$feedLink->setAttribute("rel", "describedby");
+		$feedLink->setAttribute("type", "text/html");
+		$feedLink->setAttribute("hreflang", "de");
+		$feedLink->setAttribute("title", "Nähere Beschreibung des Datensatzes");
+		$feed->appendChild($feedLink);
+	}
+	//5.1.6 - 5.1.7
+	//other -- not needed cause only one language is defined
+	//<link href="http://xyz.org/data/de" rel="alternate" type="application/atom+xml" hreflang="de" title="The download service information in German"/>
+	//<link href="http://xyz.org/data/index.html" rel="alternate" type="text/html" hreflang="en" title="An HTML version of this document"/>
+	//<link href="http://xyz.org/data/index.de.html" rel="alternate" type="text/html" hreflang="de"	title="An HTML version of this document in German"/>
+	
+	//<!-- identifier -->
+	//<id>http://xyz.org/data</id> - also self reference - see 5.1.8 on page 39 of INSPIRE GD for Download Services V 3.0
+	// and 5.2.1
+	if ($type == 'SERVICE') {
+		$feedId = $feedDoc->createElement("id");
+		$feedIdText = $feedDoc->createTextNode($selfReference);
+		$feedId->appendChild($feedIdText);
+		$feed->appendChild($feedId);
+	} else { //use inspire resource identifier?
+		$feedId = $feedDoc->createElement("id");
+		$feedIdText = $feedDoc->createTextNode($selfReference);
+		$feedId->appendChild($feedIdText);
+		$feed->appendChild($feedId);
+	}
+	//<!-- rights, access restrictions -->
+	//<rights>Copyright (c) 2011, XYZ; all rights reserved</rights> -- see 5.1.9 on page 39 of INSPIRE GD for Download Services V 3.0 - only accessconstraints should be used
+	$feedRights = $feedDoc->createElement("rights");
+	$feedRightsText = $feedDoc->createTextNode($mapbenderMetadata[$m]->accessconstraints);
+	$feedRights->appendChild($feedRightsText);
+	$feed->appendChild($feedRights);
+
+	//<!-- date/time of last update of feed--> -- see 5.1.10 on page 40 of INSPIRE GD for Download Services V 3.0 - maybe date of metadata should be used - first we use current date!
+	//<updated>2011-09-24T13:45:03Z</updated>
+	$feedUpdated = $feedDoc->createElement("updated");
+	$feedUpdatedText = $feedDoc->createTextNode(date(DATE_ATOM,time()));
+	$feedUpdated->appendChild($feedUpdatedText);
+	$feed->appendChild($feedUpdated);
+
+	//<!-- author info --> 5.1.11 
+	//<author>
+	//	<name>John Doe</name>
+	//	<email>doe at xyz.org</email>
+	//</author>
+	$feedAuthor = $feedDoc->createElement("author");
+	$feedAuthorName = $feedDoc->createElement("name");
+	$feedAuthorName->appendChild($feedDoc->createTextNode($departmentMetadata["mb_group_title"]));
+	$feedAuthorEmail = $feedDoc->createElement("email");
+	$feedAuthorEmail->appendChild($feedDoc->createTextNode($departmentMetadata["mb_group_email"]));
+	$feedAuthor->appendChild($feedAuthorName);
+	$feedAuthor->appendChild($feedAuthorEmail);
+	$feed->appendChild($feedAuthor);
+	
+	//<!-- pre-defined dataset - a entry for each pre-defined dataset - in the case of dataURL only one entry is used! -->
+	//if dataurl not given and a raster wms is defined - calculate the number of entries
+	if ($type == 'DATASET' && $generateFrom == "wmslayer") {
+		$numberOfEntries = 1; //only one entry with many links!!
+		//calculate number of entries and the bboxes
+		if ($mapbenderMetadata[$m]->spatial_res_type != 'groundDistance' & $mapbenderMetadata[$m]->spatial_res_type != 'scaleDenominator') {
+			echo "<error>WMS footprints cannot be calculated, cause kind of resolution is not given.</error>";
+		} else {
+			if (!is_int((integer)$mapbenderMetadata[$m]->spatial_res_value)) {
+				echo "<error>WMS footprints cannot be calculated, cause resolution is no integer.</error>";
+			} else {
+				//calculate the bboxes
+				//transform layer_bbox to mb_metadata epsg
+				/*$georssPolygon = $mapbenderMetadata["minx"]." ".$mapbenderMetadata["miny"]." ".$mapbenderMetadata["maxx"]." ".$mapbenderMetadata["miny"]." ";
+				$georssPolygon .= $mapbenderMetadata["maxx"]." ".$mapbenderMetadata["maxy"]." ".$mapbenderMetadata["minx"]." ".$mapbenderMetadata["maxy"]." ";
+				$georssPolygon .= $mapbenderMetadata["minx"]." ".$mapbenderMetadata["miny"];
+				echo $georssPolygon;*/
+				//TODO: check if epsg, and bbox are filled correctly!
+
+				$sqlMinx = "SELECT X(transform(GeometryFromText('POINT(".$mapbenderMetadata[$m]->minx." ".$mapbenderMetadata[$m]->miny.")',4326),".$epsgId[1].")) as minx";
+				$resMinx = db_query($sqlMinx);
+				$minx = floatval(db_result($resMinx,0,"minx"));
+			
+				$sqlMiny = "SELECT Y(transform(GeometryFromText('POINT(".$mapbenderMetadata[$m]->minx." ".$mapbenderMetadata[$m]->miny.")',4326),".$epsgId[1].")) as miny";
+				$resMiny = db_query($sqlMiny);
+				$miny = floatval(db_result($resMiny,0,"miny"));
+				
+				$sqlMaxx = "SELECT X(transform(GeometryFromText('POINT(".$mapbenderMetadata[$m]->maxx." ".$mapbenderMetadata[$m]->maxy.")',4326),".$epsgId[1].")) as maxx";
+				$resMaxx = db_query($sqlMaxx);
+				$maxx = floatval(db_result($resMaxx,0,"maxx"));
+				
+				$sqlMaxy = "SELECT Y(transform(GeometryFromText('POINT(".$mapbenderMetadata[$m]->maxx." ".$mapbenderMetadata[$m]->maxy.")',4326),".$epsgId[1].")) as maxy";
+				$resMaxy = db_query($sqlMaxy);
+				$maxy = floatval(db_result($resMaxy,0,"maxy"));
+
+	
+				$diffX = $maxx - $minx; //in m
+				$diffY = $maxy - $miny;	//in m
+				//$e = new mb_exception($diffX);
+				//echo $diffX .":". $diffY;
+				//calculate target number of pixels for x and y
+				switch ($mapbenderMetadata[$m]->spatial_res_type) {
+					case "scaleDenominator":
+						//transform to pixel
+						$diffXPx = $diffX / (float)$mapbenderMetadata[$m]->spatial_res_value / (float)0.0254 * floatval($imageResolution);
+						$diffYPx = $diffY / (float)$mapbenderMetadata[$m]->spatial_res_value / (float)0.0254 * floatval($imageResolution);
+					break;
+					case "groundDistance":
+						//transform to pixel
+						$diffXPx = $diffX / floatval($mapbenderMetadata[$m]->spatial_res_value);
+						$diffYPx = $diffY / floatval($mapbenderMetadata[$m]->spatial_res_value);
+						
+					break;
+				}
+				$e = new mb_exception($diffXPx.":".$diffYPx);
+				
+				$nRows = ceil($diffYPx / floatval($maxImageSize));
+				$nCols = ceil($diffXPx / floatval($maxImageSize));
+				$e = new mb_exception($nRows.":".$nCols);
+				$bboxWms = array();
+				/*echo $diffXPx.":".$diffYPx.",";
+				echo $nRows.":".$nCols.",";
+				echo $minx.":".$miny.",";
+				echo $maxx.":".$maxy.",";*/
+				$incX = $diffX / ($diffXPx / floatval($maxImageSize));
+				$incY = $diffY / ($diffYPx / floatval($maxImageSize));
+				for ($j = 0; $j < $nRows; $j++) {
+					for ($k = 0; $k < $nCols; $k++) {
+						//echo "j: ".$k.",k: ".$j;
+						$minxWms = $minx + $k * $incX;
+						//echo "minxWms: ". $minxWms .",";
+						$minyWms = $miny + $j * $incY;
+						//echo "minyWms: ". $minyWms .",";
+						$maxxWms = $minx + ($k+1) * $incX;
+						//echo "maxxWms: ". $maxxWms .",";
+						$maxyWms = $miny + ($j+1) * $incY;
+						//echo "maxyWms: ". $maxyWms .",";
+						$bboxWms[] = $minxWms.",".$minyWms.",".$maxxWms.",".$maxyWms;
+					}
+				}
+			}
+		}
+		//generate wgs84 bbox again - transform it from projected coords
+		$numberOfTiles = count($bboxWms);
+	} else {
+		if ($type == 'DATASET' && $generateFrom == "wfs") {
+			$numberOfEntries = 1;
+			//generate Download Links for the different featuretypes
+			//first calculate the number of tiles for the different featureTypes
+			$featureHits = array();
+			//For each featuretype which was found! Maybe more than one!
+			for ($i = 0; $i < $countRessource; $i++) {
+				$crs = $mapbenderMetadata[$i]->metadata_ref_system;
+				$epsgId = explode(':',$crs);
+				//define request to get number of hits per featuretype
+				$gHLink = $mapbenderMetadata[$i]->wfs_getfeature."SERVICE=WFS&REQUEST=GetFeature&VERSION=";
+				$gHLink .= $mapbenderMetadata[$i]->wfs_version."&typeName=";
+				$gHLink .= $mapbenderMetadata[$i]->featuretype_name."&resultType=hits";
+				//echo $gHLink;
+				$hitConnector = new connector($gHLink);
+				$hitXml = $hitConnector->file;
+				//$e = new mb_exception($hitXml);
+				//parse hits
+				try {
+					$featureTypeHits =  new SimpleXMLElement($hitXml);
+					if ($featureTypeHits == false) {
+						throw new Exception('Cannot parse WFS number of hits request!');
+					}
+				}
+				catch (Exception $e) {
+    					$e = new mb_exception($e->getMessage());
+				}
+				$hits = $featureTypeHits->xpath('/wfs:FeatureCollection/@numberOfFeatures');
+				$featureHits[$i] = (integer)$hits[0];
+				//$e = new mb_exception($featureHits[$i]);
+
+				//calculate further bboxes if the # of hits extents some value
+
+
+				//minimum number of single tiles:
+				$countTiles = ceil($featureHits[$i]/$maxFeatureCount);
+				//echo $countTiles;
+				//echo $maxFeatureCount;
+				//$e = new mb_exception($countTiles);
+				//calculate number of rows and columns from x / y ratio
+				
+				$sqlMinx = "SELECT X(transform(GeometryFromText('POINT(".$mapbenderMetadata[$i]->minx." ".$mapbenderMetadata[$i]->miny.")',4326),".$epsgId[1].")) as minx";
+				$resMinx = db_query($sqlMinx);
+				$minx = floatval(db_result($resMinx,0,"minx"));
+				
+				$sqlMiny = "SELECT Y(transform(GeometryFromText('POINT(".$mapbenderMetadata[$i]->minx." ".$mapbenderMetadata[$i]->miny.")',4326),".$epsgId[1].")) as miny";
+				$resMiny = db_query($sqlMiny);
+				$miny = floatval(db_result($resMiny,0,"miny"));
+				
+				$sqlMaxx = "SELECT X(transform(GeometryFromText('POINT(".$mapbenderMetadata[$i]->maxx." ".$mapbenderMetadata[$i]->maxy.")',4326),".$epsgId[1].")) as maxx";
+				$resMaxx = db_query($sqlMaxx);
+				$maxx = floatval(db_result($resMaxx,0,"maxx"));
+				
+				$sqlMaxy = "SELECT Y(transform(GeometryFromText('POINT(".$mapbenderMetadata[$i]->maxx." ".$mapbenderMetadata[$i]->maxy.")',4326),".$epsgId[1].")) as maxy";
+				$resMaxy = db_query($sqlMaxy);
+				$maxy = floatval(db_result($resMaxy,0,"maxy"));
+
+				$diffX = $maxx - $minx; //in m - depends on given epsg code
+				$diffY = $maxy - $miny;	//in m
+				$e = new mb_exception($diffX);
+				$e = new mb_exception($diffY);
+			
+				$width = ceil(sqrt(($diffX * $diffY) / $countTiles));
+$e = new mb_exception($width);
+				$nRows = ceil($diffY / $width);
+				$nCols = ceil($diffX / $width);
+
+				$bboxWfs = array();
+				$countBbox = 0;
+				/*echo $diffXPx.":".$diffYPx.",";
+				echo $nRows.":".$nCols.",";
+				echo $minx.":".$miny.",";
+				echo $maxx.":".$maxy.",";*/
+				for ($j = 0; $j < $nRows; $j++) {
+					for ($k = 0; $k < $nCols; $k++) {
+						//echo "j: ".$k.",k: ".$j;
+						$minxWfs = $minx + $k * $width;
+						//echo "minxWms: ". $minxWms .",";
+						$minyWfs = $miny + $j * $width;
+						//echo "minyWms: ". $minyWms .",";
+						$maxxWfs = $minx + ($k+1) * $width;
+						//echo "maxxWms: ". $maxxWms .",";
+						$maxyWfs = $miny + ($j+1) * $width;
+						//echo "maxyWms: ". $maxyWms .",";
+						$bboxWfs[$mapbenderMetadata[$i]->featuretype_name][$countBbox] = $minxWfs.",".$minyWfs.",".$maxxWfs.",".$maxyWfs;
+						$countBbox++;	
+					}
+				}
+				$getFeatureLink = array();
+				/*TODO for ($i = 0; $i < $countRessource-1; $i++) {
+					$gFLink = $mapbenderMetadata[$i]->wfs_getfeature."SERVICE=WFS&REQUEST=GetFeature&VERSION=";
+					$gFLink .= $mapbenderMetadata[$i]->wfs_version."&typeName=".$mapbenderMetadata[$i]->featuretype_name;
+					$gFLink .= "&maxFeatures=".$featureHits[$i]."&srsName=".$mapbenderMetadata[$i]->featuretype_srs;
+					$getFeatureLink[] = $gFLink;
+				}*/
+				//echo count($bboxWfs[$mapbenderMetadata[$i]->featuretype_name]);
+				for ($l = 0; $l < count($bboxWfs[$mapbenderMetadata[$i]->featuretype_name]); $l++) {
+					//generate bbox Filter:
+					//<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:3785"><gml:coordinates decimal="." cs="," ts=" ">-8033496.4863128,5677373.0653376 -7988551.5136872,5718801.9346624</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter>
+
+					$bboxFilter = '<Filter xmlns:gml="http://www.opengis.net/gml"><BBOX>';
+					//$bboxFilter .= '<gml:Box srsName="EPSG:'.$epsgId[1].'"';
+					$bboxFilter .= '<ogc:PropertyName>the_geom</ogc:PropertyName>';
+					$bboxFilter .= '<gml:Box>';
+					$bboxFilter .= '<gml:coordinates>';
+					$currentBbox = explode(',',$bboxWfs[$mapbenderMetadata[$i]->featuretype_name][$l]);
+			
+					$bboxFilter .= $currentBbox[0].','.$currentBbox[1].' '.$currentBbox[2].','.$currentBbox[3];
+					$bboxFilter .= '</gml:coordinates></gml:Box></BBOX></Filter>';
+					$bboxFilter = urlencode($bboxFilter);
+
+					$gFLink = $mapbenderMetadata[$i]->wfs_getfeature."SERVICE=WFS&REQUEST=GetFeature&VERSION=";
+					$gFLink .= $mapbenderMetadata[$i]->wfs_version."&typeName=".$mapbenderMetadata[$i]->featuretype_name;
+					$gFLink .= "&maxFeatures=".$featureHits[$i]."&srsName=".$mapbenderMetadata[$i]->featuretype_srs;
+					$gFLink .= "&FILTER=".$bboxFilter;
+					$getFeatureLink[] = $gFLink;
+				}
+				$numberOfTiles = count($bboxWfs[$mapbenderMetadata[$i]->featuretype_name]);
+			}
+			
+		} else { //type SERVICE was set - generate one entry for each coupled resource - they are distinguished by names, titles, ids, bbox, type of download! 
+			$numberOfEntries = count($mapbenderMetadata);
+		}
+	}
+
+	for ($i = 0; $i < $numberOfEntries; $i++) {
+		//<entry> 5.1.12 / 5.2.3
+		$feedEntry = $feedDoc->createElement("entry");
+		//<!-- title for pre-defined dataset -->
+		//<title xml:lang="en">Water network ABC</title>
+		//<title>Water network in CRS EPSG:4258 (GML)</title>
+		$feedEntryTitle = $feedDoc->createElement("title");
+		//$feedEntryTitle->setAttribute("xml:lang", "de");
+		if ($type == 'SERVICE') {
+			//generate one entry for each possible download variant
+			switch ($mapbenderMetadata[$i]->origin) {
+				case "wmslayer":
+					$ressourceServiceFeedEntryTitle = $ressourceTitle." - generiert aus WMS Datenquelle";
+				break;
+				case "dataurl":
+					$ressourceServiceFeedEntryTitle = $ressourceTitle." - generiert aus WMS Capabilities dataURL Element";
+				break;
+				case "wfs":
+					$ressourceServiceFeedEntryTitle = $ressourceTitle." - generiert über WFS GetFeature Aufrufe";
+				break;
+			}
+			$feedEntryTitle->appendChild($feedDoc->createTextNode("Feed Entry für: ".$ressourceServiceFeedEntryTitle)); //TODO: maybe add some category?
+		} else {
+			$feedEntryTitle->appendChild($feedDoc->createTextNode($ressourceTitle. " im CRS ".$mapbenderMetadata[$i]->metadata_ref_system." und Format ".$mapbenderMetadata[$i]->format)); //TODO: maybe add some category?
+		}
+		$feedEntry->appendChild($feedEntryTitle);
+
+		/*For Service: <!—Spatial Dataset Unique Resourse Identifier for this dataset-->
+		<inspire_dls:spatial_dataset_identifier_code>wn_id1</inspire_dls:spatial_dataset_identifier_code>
+		<inspire_dls:spatial_dataset_identifier_namespace>http://xyz.org/</inspire_dls:spatial_dataset_identifier_namespace>
+		<!-- link to dataset metadata record -->
+		<link href="http://xyz.org/metadata/abcISO19139.xml" rel="describedby" type="application/vnd.iso.19139+xml"
+		<!-- link to "Dataset Feed" for pre-defined dataset -->
+		<link rel="alternate" href="http://xyz.org/data/waternetwork_feed.xml" type="application/atom+xml" hreflang="en" title="Feed containing the pre-defined waternetwork dataset (in one or more downloadable formats)"/>
+		<!-- identifier for "Dataset Feed" for pre-defined dataset -->
+		<id>http://xyz.org/data/waternetwork_feed.xml</id>*/
+
+		//or link to dataset 5.2.3
+
+		//<link rel="alternate" href="http://xyz.org/data/abc/waternetwork_WGS84.shp" type="application/x-shp" hreflang="en" title="Water Network encoded as a ShapeFile in WGS84geographic coordinates (http://www.opengis.net/def/crs/OGC/1.3/CRS84)"/>
+			
+		$datasetFeedLink = "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_inspireDownloadFeed.php?id=".$recordId."&type=DATASET&generatefrom=".$mapbenderMetadata[$i]->origin;
+		switch($mapbenderMetadata[$i]->origin) {
+			case "wmslayer":
+				$datasetFeedLink .= "&layerid=".$mapbenderMetadata[$i]->layer_id;
+			break;
+			case "wfs":
+				$datasetFeedLink .= "&wfsid=".$mapbenderMetadata[$i]->wfs_id;
+			break;
+		}
+		$datasetLink = $mapbenderMetadata[$i]->datalink_url;
+		
+		if ($type == 'SERVICE') {
+			//insert resource identifier for service / dataset coupling!!
+			$feedEntryIdCode = $feedDoc->createElement("inspire_dls:spatial_dataset_identifier_code");
+			$feedEntryIdCodeText = $feedDoc->createTextNode($mapbenderMetadata[$i]->datasetid);
+			$feedEntryIdCode->appendChild($feedEntryIdCodeText);
+			$feedEntry->appendChild($feedEntryIdCode);
+
+			$feedEntryIdNamespace = $feedDoc->createElement("inspire_dls:spatial_dataset_identifier_namespace");
+			$feedEntryIdNamespaceText = $feedDoc->createTextNode($mapbenderMetadata[$i]->datasetid_codespace);
+			$feedEntryIdNamespace->appendChild($feedEntryIdNamespaceText);
+			$feedEntry->appendChild($feedEntryIdNamespace);
+
+
+			$metadataLink = "http://".$_SERVER['HTTP_HOST']."/mapbender/php/mod_dataISOMetadata.php?outputFormat=iso19139&id=".$mapbenderMetadata[$m]->metadata_uuid;
+			$feedEntryMetadataLink = $feedDoc->createElement("link");
+			$feedEntryMetadataLink->setAttribute("href",$metadataLink);
+			$feedEntryMetadataLink->setAttribute("rel", "describedby");
+			$feedEntryMetadataLink->setAttribute("type", "application/vnd.iso.19139+xml");
+			$feedEntry->appendChild($feedEntryMetadataLink);
+
+			$furtherLink = $datasetFeedLink;
+			$furtherLinkType = "application/atom+xml";
+			$furtherLinkTitle = "Feed für den pre-defined Datensatz ".$ressourceTitle;
+			$feedEntryLink = $feedDoc->createElement("link");
+			$feedEntryLink->setAttribute("rel", "alternate");
+			$feedEntryLink->setAttribute("href", $furtherLink);
+			$feedEntryLink->setAttribute("type", $furtherLinkType);
+			$feedEntryLink->setAttribute("hreflang", "de");
+			$feedEntryLink->setAttribute("title", $furtherLinkTitle);
+			$feedEntry->appendChild($feedEntryLink);
+		} else { //DATASET
+			switch ($generateFrom) {
+				case "dataurl":
+					$furtherLink = $datasetLink;
+					$furtherLinkType = $mapbenderMetadata[$i]->datalink_format;
+					$furtherLinkTitle = $ressourceTitle." im CRS ".$mapbenderMetadata[$i]->metadata_ref_system."(".$mapbenderMetadata[$m]->format.")";
+				break;
+				case "wmslayer":
+						//example:
+						//http://localhost/cgi-bin/mapserv?map=/data/umn/geoportal/karte_rp/testinspiredownload.map&VERSION=1.1.1&REQUEST=GetMap&SERVICE=WMS&LAYERS=inspirewms&STYLES=&SRS=EPSG:4326&BBOX=6.92134,50.130465,6.93241,50.141535000000005&WIDTH=200&HEIGHT=200&FORMAT=image/png&BGCOLOR=0xffffff&TRANSPARENT=TRUE&EXCEPTIONS=application/vnd.ogc.se_inimage
+					//generate further links, one for each tile which was computed before
+					$furtherLink = array();
+					$furtherLinkType = array();
+					$furtherLinkTitle = array();
+					$furtherLinkBbox = array();
+					for ($m = 0; $m < $numberOfTiles; $m++ ) {
+						$furtherLink[$m] = $mapbenderMetadata[$i]->wms_getmap."REQUEST=GetMap&VERSION=".$mapbenderMetadata[$i]->wms_version."&SERVICE=WMS&LAYERS=".$mapbenderMetadata[$i]->layer_name;
+						$furtherLink[$m] .= "&STYLES=&SRS=".trim($crs)."&BBOX=".$bboxWms[$m]."&WIDTH=".$maxImageSize."&HEIGHT=".$maxImageSize."&FORMAT=image/tiff&";
+						$furtherLink[$m] .= "BGCOLOR=0xffffff&TRANSPARENT=TRUE&EXCEPTIONS=application/vnd.ogc.se_inimage";
+						$furtherLinkType[$m] = "image/tiff"; //formats from layer_format - geotiff
+						$currentTileIndex = $m+1;
+						$furtherLinkTitle[$m] = $ressourceTitle." im CRS ".$mapbenderMetadata[$i]->metadata_ref_system." - ".$mapbenderMetadata[$i]->format." - Teil ".$currentTileIndex." von ".$numberOfTiles."";
+						$furtherLinkBbox[$m] = $bboxWms[$m];
+					}
+				break;
+				case "wfs":
+					//example:
+					//http://localhost/cgi-bin/mapserv?map=/data/umn/geoportal/karte_rp/testinspiredownload.map&VERSION=1.1.1&REQUEST=GetMap&SERVICE=WMS&LAYERS=inspirewms&STYLES=&SRS=EPSG:4326&BBOX=6.92134,50.130465,6.93241,50.141535000000005&WIDTH=200&HEIGHT=200&FORMAT=image/png&BGCOLOR=0xffffff&TRANSPARENT=TRUE&EXCEPTIONS=application/vnd.ogc.se_inimage
+					$furtherLink = array();
+					$furtherLinkType = array();
+					$furtherLinkTitle = array();
+					$furtherLinkBbox = array();
+					for ($m = 0; $m < $numberOfTiles; $m++ ) {
+						$furtherLink[$m] = $getFeatureLink[$m];//was computed before
+						$furtherLinkType[$m] = "text/xml; subtype=gml/3.1.1";//$mapbenderMetadata[$m]->datalink_format; //formats from layer_format - geotiff
+						$furtherLinkTitle[$m] = $ressourceTitle." im CRS ".$mapbenderMetadata[$i]->metadata_ref_system."(".$mapbenderMetadata[$i]->format." - Teil ".$m + 1 ." von ".$numberOfTiles."";
+						$furtherLinkBbox[$m] = $bboxWfs[$mapbenderMetadata[$i]->featuretype_name][$m];
+					}
+				break;
+			}
+			//generate content link
+			for ($m = 0; $m < $numberOfTiles; $m++) {
+				//generate Links
+				$feedEntryLink = $feedDoc->createElement("link");
+				$feedEntryLink->setAttribute("rel", "section");
+				$feedEntryLink->setAttribute("href", $furtherLink[$m]);
+				$feedEntryLink->setAttribute("type", $furtherLinkType[$m]);
+				$feedEntryLink->setAttribute("hreflang", "de");
+				$feedEntryLink->setAttribute("title", $furtherLinkTitle[$m]);
+				$feedEntryLink->setAttribute("bbox", $furtherLinkBbox[$m]);
+				$feedEntry->appendChild($feedEntryLink);		
+			}
+		}
+		//In the case of dynamically build entries for a raster based wms - not the dataurl but another the dyn ulrs will be used in the next feed
+		//5.1.14 / 5.2
+		//<!-- identifier for pre-defined dataset -->
+		//<id>http://xyz.org/data/waternetwork.gml/id>
+		//insert self reference
+		$feedEntryId = $feedDoc->createElement("id");
+		$feedEntryId->appendChild($feedDoc->createTextNode($datasetFeedLink));
+		$feedEntry->appendChild($feedEntryId);
+
+		//<!-- rights, access restrictions -->
+		//<rights>Copyright (c) 2011, XYZ; all rights reserved</rights> -- see 5.1.9 on page 39 of INSPIRE GD for Download Services V 3.0 - only accessconstraints should be used
+		$feedEntryRights = $feedDoc->createElement("rights");
+		$feedEntryRightsText = $feedDoc->createTextNode($mapbenderMetadata[$i]->accessconstraints);
+		$feedEntryRights->appendChild($feedEntryRightsText);
+		$feedEntry->appendChild($feedEntryRights);
+		
+		//5.1.14 / 5.2  - updated
+		//<!-- last date/time pre-defined dataset was updated -->
+		//<updated>2011-06-14T12:22:09Z</updated>
+		$feedEntryUpdated = $feedDoc->createElement("updated");
+		$feedEntryUpdated->appendChild($feedDoc->createTextNode(date(DATE_ATOM,time())));
+		$feedEntry->appendChild($feedEntryUpdated);
+
+		//5.1.15 / 
+		//<!-- summary -->
+		//<summary>This is the entry for water network ABC Dataset</summary>
+		if ($type == 'SERVICE') {
+			$feedEntrySummary = $feedDoc->createElement("summary");
+			$feedEntrySummary->appendChild($feedDoc->createTextNode("Nähere Beschreibung des Feedinhaltes: ".$ressourceAbstract));
+			$feedEntry->appendChild($feedEntrySummary);
+		}
+
+		//5.1.16 / 5.2?
+		//<!-- optional GeoRSS-Simple bounding box of the pre-defined dataset. Must be lat lon -->
+		//<georss:polygon>47.202 5.755 55.183 5.755 55.183 15.253 47.202 15.253 47.202 5.755</georss:polygon>
+		//TODO: Get this out of mb_metadata! If not given get it from layer bbox - but normally they should be identical!
+		$feedEntryBbox = $feedDoc->createElement("georss:polygon");
+		$georssPolygon = $mapbenderMetadata[$i]->minx." ".$mapbenderMetadata[$i]->miny." ".$mapbenderMetadata[$i]->maxx." ".$mapbenderMetadata[$i]->miny." ";
+		$georssPolygon .= $mapbenderMetadata[$i]->maxx." ".$mapbenderMetadata[$i]->maxy." ".$mapbenderMetadata[$i]->minx." ".$mapbenderMetadata[$i]->maxy." ";
+		$georssPolygon .= $mapbenderMetadata[$i]->minx." ".$mapbenderMetadata[$i]->miny;	
+		$feedEntryBbox->appendChild($feedDoc->createTextNode($georssPolygon));
+		$feedEntry->appendChild($feedEntryBbox);
+	
+		//category entry for crs (from mb_metadata) 5.1.17
+		/*<!-- CRSs in which the pre-defined Dataset is available --> <category term="EPSG:25832" scheme="http://www.opengis.net/def/crs/" label="EPSG/0/25832"/> <category term="EPSG:4258" scheme="http://www.opengis.net/def/crs/" label="EPSG/0/4258"/>*/
+		
+		$feedEntryCategory = $feedDoc->createElement("category");
+		$feedEntryCategory->setAttribute("term", "http://www.opengis.net/def/crs/EPSG/".$epsgId[1]);
+		$feedEntryCategory->setAttribute("label", "EPSG/0/".$epsgId[1]);
+		$feedEntry->appendChild($feedEntryCategory);
+
+		//<!-- INSPIRE Spatial Object Types contained in the pre-defined dataset -->
+		//<category term="Watercourse" scheme="http://inspire-registry.jrc.ec.europa.eu/registers/FCD/" label="Watercourse" xml:lang="en"/>
+		//only applicable for inspire conformant datasets!
+		//Generate List of inspire themes of the given layer!
+		/*$sql = "SELECT inspire_category.inspire_category_id, inspire_category.inspire_category_code_en FROM inspire_category, layer_inspire_category WHERE layer_inspire_category.fkey_layer_id=$1 AND layer_inspire_category.fkey_inspire_category_id=inspire_category.inspire_category_id";
+		$v = array((integer)$mapbenderMetadata['layer_id']);
+		$t = array('i');
+		$res = db_prep_query($sql,$v,$t);
+		while ($row = db_fetch_array($res)) {
+			//part for the name of the inspire category
+			$feedEntryCategory = $feedDoc->createElement("category");
+			$feedEntryCategory->setAttribute("term", $row['inspire_category_code_en']);
+			$feedEntryCategory->setAttribute("scheme", "http://www.eionet.europa.eu/gemet/theme_concepts?langcode=en&ns=5&th=".$row['inspire_category_id']);
+			$feedEntryCategory->setAttribute("label", $row['inspire_category_code_en']);
+			$feedEntryCategory->setAttribute("xml:lang", "en");
+			$feedEntry->appendChild($feedEntryCategory);
+		}
+		*/
+		/*$feedEntryCategory = $feedDoc->createElement("category");
+		$feedEntryCategory->setAttribute("term", "Watercourse");
+		$feedEntryCategory->setAttribute("scheme", "http://inspire-registry.jrc.ec.europa.eu/registers/FCD/");
+		$feedEntryCategory->setAttribute("label", "Watercourse");
+		$feedEntryCategory->setAttribute("xml:lang", "en");
+		$feedEntry->appendChild($feedEntryCategory);
+		//<category term="StandingWater" scheme="http://inspire-registry.jrc.ec.europa.eu/registers/FCD/" label="Standing Water" xml:lang="en"/>
+		$feedEntryCategory = $feedDoc->createElement("category");
+		$feedEntryCategory->setAttribute("term", "StandingWater");
+		$feedEntryCategory->setAttribute("scheme", "http://inspire-registry.jrc.ec.europa.eu/registers/FCD/");
+		$feedEntryCategory->setAttribute("label", "Standing Water");
+		$feedEntryCategory->setAttribute("xml:lang", "en");
+		$feedEntry->appendChild($feedEntryCategory);*/
+	//</entry>
+
+		$feed->appendChild($feedEntry);
+	}
+	//}
+	return $feedDoc->saveXML();
+}
+
+//function to give away the xml data
+function pushFeed($feedDoc, $recordId, $generateFrom) {
+	header("Content-type: application/xhtml+xml; charset=UTF-8");
+	$xml = generateFeed($feedDoc, $recordId, $generateFrom);
+	echo $xml;
+	die();
+}
+
+function fillMapbenderMetadata($dbResult) {
+	//function increments $indexMapbenderMetadata !!!
+	global $mapbenderMetadata, $indexMapbenderMetadata;
+	//echo "<error>fill begins</error>";
+	while ($row = db_fetch_assoc($dbResult)) {
+		//get relevant information 
+		//echo "<error>".$indexMapbenderMetadata."</error>";
+		$mapbenderMetadata[$indexMapbenderMetadata]->origin = $row['origin']; 
+		$mapbenderMetadata[$indexMapbenderMetadata]->latlonbbox = $row['latlonbbox']; 
+		$mapbenderMetadata[$indexMapbenderMetadata]->datalink_id = $row['datalink_id']; 
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_id = $row['metadata_id']; 
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_ref_system = $row['metadata_ref_system']; 	
+		$mapbenderMetadata[$indexMapbenderMetadata]->fkey_mb_group_id = $row['fkey_mb_group_id'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wms_owner = $row['wms_owner'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_owner = $row['wfs_owner'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->fkey_wms_id = $row['fkey_wms_id'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->layer_id = $row['layer_id'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->layer_name = $row['layer_name'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->datasetid = $row['datasetid'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->datasetid_codespace = $row['datasetid_codespace'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_uuid = $row['metadata_uuid'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->minx = $row['minx'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->miny = $row['miny'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->maxx = $row['maxx'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->maxy = $row['maxy'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_title = $row['metadata_title'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->layer_title = $row['layer_title'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_abstract = $row['metadata_abstract'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->layer_abstract = $row['layer_abstract'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->accessconstraints = $row['accessconstraints'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_uuid = $row['metadata_uuid'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->spatial_res_type = $row['spatial_res_type'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->spatial_res_value = $row['spatial_res_value'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_ref_system = $row['metadata_ref_system'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->format = $row['format'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->datalink_url = $row['datalink_url'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wms_getmap = $row['wms_getmap'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wms_version = $row['wms_version'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->layer_name = $row['layer_name'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->datalink_format = $row['datalink_format'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->metadata_ref_system = $row['metadata_ref_system'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->format = $row['format'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->featuretype_name = $row['featuretype_name'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->featuretype_srs = $row['featuretype_srs'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->featuretype_title = $row['featuretype_title'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_title = $row['wfs_title'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_id = $row['wfs_id'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_abstract = $row['wfs_abstract'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_getfeature = $row['wfs_getfeature'];
+		$mapbenderMetadata[$indexMapbenderMetadata]->wfs_version = $row['wfs_version'];
+		//$mapbenderMetadata[$indexMapbenderMetadata]->format = $row['format'];
+		//check if codespace was given in metadata or it must be generated from uuid and default codespace
+		if (($mapbenderMetadata[$indexMapbenderMetadata]->datasetid_codespace == '' or !isset($mapbenderMetadata[$indexMapbenderMetadata]->datasetid_codespace)) or ($mapbenderMetadata[$indexMapbenderMetadata]->datasetid == '' or !isset($mapbenderMetadata[$indexMapbenderMetadata]->datasetid))) {
+			//generate one:
+			$mapbenderMetadata[$indexMapbenderMetadata]->datasetid_codespace = METADATA_DEFAULT_CODESPACE;
+			$mapbenderMetadata[$indexMapbenderMetadata]->datasetid = $mapbenderMetadata[$indexMapbenderMetadata]->metadata_uuid;
+		}
+		if ($generateFrom == "wfs") {
+			$latlonbbox = explode(",",$mapbenderMetadata[$indexMapbenderMetadata]->latlonbbox);
+			$mapbenderMetadata[$indexMapbenderMetadata]->minx = $latlonbbox[0];
+			$mapbenderMetadata[$indexMapbenderMetadata]->miny = $latlonbbox[1];
+			$mapbenderMetadata[$indexMapbenderMetadata]->maxx = $latlonbbox[2];
+			$mapbenderMetadata[$indexMapbenderMetadata]->maxy = $latlonbbox[3];
+		}
+		$indexMapbenderMetadata++;
+	}
+}
+
+
+//do all the other things which had to be done ;-)
+pushFeed($feedDoc, $recordId, $generateFrom); //throw it out to world!
+
+?>
+



More information about the Mapbender_commits mailing list