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

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Fri Aug 2 05:11:42 PDT 2019


Author: armin11
Date: 2019-08-02 05:11:42 -0700 (Fri, 02 Aug 2019)
New Revision: 10194

Added:
   trunk/mapbender/http/php/mod_linkedDataProxy_2.php
Log:
Draft for better wfs 3.0 proxy - many things have to be done - will replace mod_linkedDataProxy.php in few weeks ;-)

Added: trunk/mapbender/http/php/mod_linkedDataProxy_2.php
===================================================================
--- trunk/mapbender/http/php/mod_linkedDataProxy_2.php	                        (rev 0)
+++ trunk/mapbender/http/php/mod_linkedDataProxy_2.php	2019-08-02 12:11:42 UTC (rev 10194)
@@ -0,0 +1,1147 @@
+<?php
+require_once(dirname(__FILE__)."/../../core/globalSettings.php");
+require_once(dirname(__FILE__)."/../classes/class_cache.php");
+require_once(dirname(__FILE__)."/../classes/class_universal_wfs_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_3_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_owsConstraints.php");
+//http://localhost/mapbender/devel_tests/wfsClientTest.php?wfsid=16&ft=vermkv:fluren_rlp&bbox=7.9,50.8,8.0,52
+//initialize some parameter
+//objects per page
+$maxObjectsPerPage = 10;
+//default page
+$page = 0;
+//default format f
+$f = "json";
+//default outputFormat for wfs objects:
+$outputFormat = "text/xml";
+//outputFormat whitelist
+$allowedOutputFormats = array("text/xml; subtype=gml/3.1.1","text/xml; subtype=gml/3.2","text/xml; subtype=gml/2.1.2","text/xml; subtype=gml/3.2.1","SHAPEZIP","application/json; subtype=geojson","text/csv","application/zip");
+//outputFormat for pages - parameter f=...
+$allowedFormats = array("html","xml","json");
+//initial extent for leaflet client
+$minxFC = 48;
+$minyFC = 6;
+$maxxFC = 51;
+$maxyFC = 9;
+function microtime_float() {
+    	list($usec, $sec) = explode(" ", microtime());
+    	return ((float)$usec + (float)$sec);
+}
+//outputFormatter for attribute values - urls, ...
+function string2html($string) {
+	if (filter_var($string, FILTER_VALIDATE_URL)) {
+		return "<a href='".$string."' target='_blank'>".$string."</a>";
+	}
+	return $string;
+}
+//handle http request parameters
+//parse request parameters
+if (isset($_REQUEST["wfsid"]) & $_REQUEST["wfsid"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["wfsid"];
+	$pattern = '/^[\d,]*$/';		
+ 	if (!preg_match($pattern,$testMatch)){ 
+		//echo 'id: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		echo 'Parameter <b>wfsid</b> is not valid (integer or cs integer list).<br/>'; 
+		die(); 		
+ 	}
+	$wfsid = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["fid"]) & $_REQUEST["fid"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["fid"];
+	$pattern = '/^[0-9a-zA-Z\.\-_:]*$/';	
+ 	if (!preg_match($pattern,$testMatch)){ 
+		//echo 'id: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		echo 'Parameter <b>id</b> is not valid (integer or cs integer list).<br/>'; 
+		die(); 		
+ 	}
+	$fid = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["p"]) & $_REQUEST["p"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["p"];
+	$pattern = '/^[\d]*$/';		
+ 	if (!preg_match($pattern,$testMatch)){ 
+		//echo 'id: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		echo 'Parameter <b>p</b> is not valid (integer).<br/>'; 
+		die(); 		
+ 	}
+	$page = $testMatch;
+	$testMatch = NULL;
+}
+
+if (isset($_REQUEST["collection"]) & $_REQUEST["collection"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["collection"];
+	$pattern = '/^[0-9a-zA-Z\.\-
+_:]*$/';		
+ 	if (!preg_match($pattern,$testMatch)){ 
+		//echo 'id: <b>'.$testMatch.'</b> is not valid.<br/>'; 
+		echo 'Parameter <b>collection</b> is not valid (ogc resource name or id).<br/>'; 
+		die(); 		
+ 	}
+	$collection = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["collections"]) & $_REQUEST["collections"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["collections"];
+	if (!in_array($testMatch, array("all"))){ 
+		echo 'Parameter <b>collections</b> is not valid (maybe all).<br/>'; 
+		die(); 		
+ 	}
+	$collections = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["items"]) & $_REQUEST["items"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["items"];
+	if (!in_array($testMatch, array("all"))){ 
+		echo 'Parameter <b>items</b> is not valid (maybe all).<br/>'; 
+		die(); 		
+ 	}
+	$items = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["outputFormat"]) & $_REQUEST["outputFormat"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["outputFormat"];
+		
+ 	if (!in_array($testMatch, $allowedOutputFormats)){ 
+		echo 'Parameter <b>outputFormat</b> is not valid - must be one of: '.implode(',', $allowedOutputFormats).'<br/>'; 
+		die(); 		
+ 	}
+	$outputFormat = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["f"]) & $_REQUEST["f"] != "") {
+	//validate to csv integer list
+	$testMatch = $_REQUEST["f"];	
+ 	if (!in_array($testMatch, $allowedFormats)){ 
+		echo 'Parameter <b>f</b> is not valid - must be one of: '.implode(',', $allowedFormats).'<br/>'; 
+		die(); 		
+ 	}
+	$f = $testMatch;
+	$testMatch = NULL;
+}
+if (isset($_REQUEST["bbox"]) & $_REQUEST["bbox"] != "") {
+	//validate to float/integer
+	$testMatch = $_REQUEST["bbox"];
+	//$pattern = '/^[-\d,]*$/';
+	$pattern = '/^[-+]?([0-9]*\.[0-9]+|[0-9]+)*$/';
+	$testMatchArray = explode(',',$testMatch);
+ 	if (count($testMatchArray) != 4) {
+		echo 'Parameter <b>bbox</b> has a wrong amount of entries.<br/>';
+		die();
+	}
+	for($i=0; $i<count($testMatchArray);$i++){
+		if (!preg_match($pattern,$testMatchArray[$i])){
+			echo 'Parameter <b>bbox</b> is not a valid coordinate value.<br/>';
+			die();
+ 		}
+	}
+	$bbox = $testMatch;
+	$testMatch = NULL;
+}
+$proxyStartTime = microtime_float();
+//instantiate needed classes 
+$cache = new Cache();
+//generate json return object - after this build up html if wished!!!!****************************************************************
+// returnObject differs for service / collection / item
+$returnObject = new stdClass();
+//************************************************************************************************************************************
+//service list part 
+//************************************************************************************************************************************
+if (!isset($wfsid) || $wfsid == "") {
+    //list all public available wfs which are classified as opendata!
+    $returnObject->service = array();
+    //$sql = "SELECT * FROM (SELECT wfs_id, wfs_version, wfs_abstract, wfs_title, wfs_owsproxy, fkey_termsofuse_id FROM wfs INNER JOIN wfs_termsofuse ON wfs_id = fkey_wfs_id) AS wfs_tou INNER JOIN termsofuse ON fkey_termsofuse_id = termsofuse_id WHERE isopen = 1";
+    //all wfs - without open filter!
+    $sql = "SELECT wfs_id, wfs_abstract, wfs_version, wfs_title, wfs_owsproxy FROM wfs";
+    $v = array();
+    $t = array();
+    $res = db_prep_query($sql, $v, $t);	
+    $i = 0;	
+    while($row = db_fetch_array($res)){
+        $returnObject->service[$i]->id = $row['wfs_id'];
+        $returnObject->service[$i]->title = $row['wfs_title'];
+        $returnObject->service[$i]->version = $row['wfs_version'];
+        $returnObject->service[$i]->description = $row['wfs_abstract'];
+        //get contraints
+        $constraints = new OwsConstraints();
+        $constraints->languageCode = "de";
+        $constraints->asTable = true;
+        $constraints->id = $returnObject->service[$i]->id;
+        $constraints->type = "wfs";
+        $constraints->returnDirect = false;
+        //$returnObject->service[$i]->tou = json_encode($constraints->getDisclaimer());//TODO encoding problems occur!
+        $i++;
+    } 
+    if ($i == 0) {
+        $returnObject->success = false;
+        $returnObject->message = "No services found in registry";
+    } else {
+        $returnObject->success = true;
+    	$returnObject->message = "Services found in registry!";
+    }
+} else {
+    //************************************************************************************************************************************
+    //service part 
+    //************************************************************************************************************************************
+    //try to instantiate wfs object
+    $myWfsFactory = new UniversalWfsFactory();
+    $wfs = $myWfsFactory->createFromDb($wfsid);
+    if ($wfs == null) {
+	$returnObject->success = false;
+    	$returnObject->message = "Wfs object could not be created from db!";
+    } else {
+	//create service part if no collection is requested		
+	if (!isset($collection) || $collection == "" || $collections == "all") {
+            //************************************************************************************************************************************
+            //service only part 
+            //************************************************************************************************************************************
+	    //add from rlp!
+	    $returnObject->id = $wfsid;
+            $returnObject->title = $wfs->title;
+	    $returnObject->description = $wfs->summary;
+	    //
+	    $returnObject->links = array();
+	    $returnObject->crs = array();
+	    $returnObject->collections = array();
+	    $returnObject->links[0]->rel = "self";
+	    $returnObject->links[0]->type = "application/json";
+	    $returnObject->links[0]->title = "this document";
+	    $returnObject->links[0]->href = $_SERVER['REQUEST_URI']."&f=json";
+	    $returnObject->links[1]->rel = "alternate";
+	    $returnObject->links[1]->type = "text/html";
+	    $returnObject->links[1]->title = "this document as HTML";
+	    $returnObject->links[1]->href = $_SERVER['REQUEST_URI']."&f=html";
+	    //TODO service api
+	    //TODO conformance
+	    //TODO data
+	    $returnObject->links[2]->rel = "data";
+	    $returnObject->links[2]->type = "application/json";
+	    $returnObject->links[2]->title = "Metadata about the feature collections";
+	    $returnObject->links[2]->href = $_SERVER['REQUEST_URI']."?wfsid=".$wfsid."&collections=all&f=json";
+	    //available crs? - howto get from capabilities
+	    
+            //************************************************************************************************************************************
+	    //collection / featuretype list
+            //************************************************************************************************************************************
+	    $collectionArray = array();
+	    $collectionCount = 0;				
+	    foreach ($wfs->featureTypeArray as $featureType) {
+                $returnObject->collections[$collectionCount]->name = $featureType->name;
+		$returnObject->collections[$collectionCount]->title = $featureType->title;
+		$returnObject->collections[$collectionCount]->description = $featureType->description;
+		$returnObject->collections[$collectionCount]->extent->spatial = array();
+		$returnObject->collections[$collectionCount]->links[0]->rel = "item";
+		$returnObject->collections[$collectionCount]->links[0]->type = "application/json";
+                $returnObject->collections[$collectionCount]->links[0]->title = $featureType->title." as GeoJSON";
+		$returnObject->collections[$collectionCount]->links[0]->href = $_SERVER['REQUEST_URI']."?wfsid=".$wfsid."&collection=".$featureType->name."&items=all&f=json";
+		//one item entry for each format!
+		//self
+		$returnObject->collections[$collectionCount]->links[1]->rel = "self";
+		$returnObject->collections[$collectionCount]->links[1]->type = "application/json";
+                $returnObject->collections[$collectionCount]->links[1]->title = "Information about the ".$featureType->title." data";
+		$returnObject->collections[$collectionCount]->links[1]->href = $_SERVER['REQUEST_URI']."?wfsid=".$wfsid."&collection=".$featureType->name."&f=json";
+		//alternate
+		//TODO
+		$returnObject->collections[$collectionCount]->extent->crs = array();
+		$collectionCount++;
+            }
+	} else {
+	    //special collection selected
+	    //is collection one of the featuretypes of this wfs?
+	    //************************************************************************************************************************************
+	    //collection part 
+	    //************************************************************************************************************************************
+	    //test if collection is available in service
+            $ftNameInWfs = false;
+	    foreach ($wfs->featureTypeArray as $featureType) {
+		if ($featureType->name == $collection) {
+		    $ftNameInWfs = true;
+		    $ftTitle = $featureType->title;
+		    $ftName = $featureType->name;
+		    $ftDbId = $featureType->id;
+		    //output formats
+		    $ftOutputFormats = implode(',', array_unique($featureType->featuretypeOutputFormatArray));
+		    //get other relevant ft information
+		    break;
+		} 
+	    }
+	    if ($ftNameInWfs) {
+	        if (!isset($item) || $item == "") {
+		    $myFeatureType = $wfs->findFeatureTypeByName($ftName);			
+		    $geomColumnName = $wfs->findGeomColumnNameByFeaturetypeId($myFeatureType->id);
+		    //generate description of collection in json
+		    $returnObject->name = $myFeatureType->name;
+		    $returnObject->title = $myFeatureType->title;
+		    $returnObject->description = $myFeatureType->abstract;
+		    $returnObject->extent->spatial = array();
+		    $returnObject->extent->temporal = array();
+		    $returnObject->links =array();
+		    $returnObject->links[0]->rel = "item";
+		    $returnObject->links[0]->type = "application/geo+json";
+ 		    $returnObject->links[0]->title = $myFeatureType->title." as GeoJSON";
+                    $returnObject->links[0]->href = $_SERVER['REQUEST_URI']."?wfsid=".$wfsid."&collection=".$featureType->name."&items=all&f=json";
+		    //TODO: items in other formats, self, alternate
+		    if ($items == "all") { //show items in list!
+			//reinitialize object!
+			$returnObject = new stdClass();
+			$returnObject->type = "FeatureCollection";
+			$returnObject->links = array();
+			$returnObject->links[0]->rel = "self";
+			$returnObject->links[0]->type = "application/geo+json";			
+			$returnObject->links[0]->title = "this document";
+			$returnObject->links[0]->href = $_SERVER['REQUEST_URI'];
+			//TODO  alternate
+		        //check for given spatialFilter (bbox)
+		        if (isset($bbox) && $bbox != '') {
+		            $filter = $wfs->bbox2spatialFilter($bbox, $geomColumnName, $srs="EPSG:4326", $version='2.0.0');
+		        } else { 
+		            $filter = null;
+		        }
+		        //write number of features to ram cache:
+		        if ($cache->isActive) {
+		            if ($cache->cachedVariableExists(md5("count_".$wfsid."_".$collection."_".(string)$filter)) == false) {
+		                $numberOfObjects = $wfs->countFeatures($collection, $filter);
+		                $cache->cachedVariableAdd(md5("count_".$wfsid."_".$collection."_".(string)$filter), $numberOfObjects);
+		            } else {
+//$e = new mb_exception("read count from cache!");
+		                $numberOfObjects = $cache->cachedVariableFetch(md5("count_".$wfsid."_".$collection."_".(string)$filter));
+		            }
+		            //$e = new mb_notice("http/classes/class_crs.php - store crs info to cache!");
+		            //return true;
+		        } else {
+		            $numberOfObjects = $wfs->countFeatures($collection, $filter);
+		        }
+			//$e = new mb_exception("number of objects: ".$numberOfObjects);
+		        //request first object and metadata
+		        //count objects
+		        //TODO - create json
+		        //$html .= "wfs max features: ".$wfs->wfs_max_features."<br>";
+		        //$html .=  $ftTitle." (".$numberOfObjects.") - id: " .$ftDbId. " - output formats: ".$ftOutputFormats."<br>";
+		        //get first page
+		        //calculate pages
+		        $numberOfPages = ceil($numberOfObjects / $maxObjectsPerPage);
+		        //decide which page should be requested
+		        //$page = 0;
+		        //calculate offset for requested page
+		        if ($page >= $numberOfPages) {
+			    $returnObject->success = false;
+    			    $returnObject->message = "Requested page exeeds number of max pages!";
+			    if ($f == "json") {
+			        header("application/json");
+			        echo json_encode($returnObject);
+			    }	
+		            die();
+		        } else {
+		            $startIndex = $page * $maxObjectsPerPage;
+		        }
+			//next page
+			$returnObject->links[1]->rel = "next";
+			$returnObject->links[1]->type = "application/geo+json";			
+			$returnObject->links[1]->title = "next page";
+			$returnObject->links[1]->href = $_SERVER['REQUEST_URI']."&p=".($page + 1);
+		        //$html .= '</div>';
+		        //get more info for featuretype
+//$e = new mb_exception("bbox: ".$bbox);
+//$e = new mb_exception("filter: ".$filter);
+		        //force version to be 2.0.0!!!!! - hope the server will support it
+		        $features = $wfs->getFeaturePaging($ftName, $filter, "EPSG:4326", null, null, $maxObjectsPerPage, $startIndex, "2.0.0");
+		        //transform to geojson to allow rendering !
+		        $gml3Class = new Gml_3_Factory();
+		        //create featuretype object
+		        //TODO
+//$e = new mb_exception("geom column type: ".$geomColumnName);	
+		        $gml3Object = $gml3Class->createFromXml($features, null, $wfs, $myFeatureType, $geomColumnName);
+//$e = new mb_exception("geojson from mb class: ".json_encode($gml3Object));
+		        $geojsonList = new stdClass();
+		        $geojsonList->type = "FeatureCollection";
+		        $geojsonList->features = array();
+		        $geojsonBbox = array();
+		        $geojsonIndex = 0;
+		        $minxFC = 90;
+		        $minyFC = 180;
+		        $maxxFC = -90;
+		        $maxyFC = -180;
+		        //TODO write javascript object if to var if html is requested
+		        //$html .= "<script>";
+		        foreach($gml3Object->featureCollection->featureArray as $mbFeature) {
+//$e = new mb_exception("geojson from mb feature exporthandler: ".$mbFeature->toGeoJSON());
+		            //bbox
+		            $geojsonBbox[$geojsonIndex]->mbBbox = $mbFeature->getBbox();
+		            //transform to simple bbox object for leaflet
+		            $bbox_new = explode(' ',str_replace(']','',str_replace('[','',$geojsonBbox[$geojsonIndex]->mbBbox)));
+		            $bbox_new = explode('|',str_replace(')','',str_replace('(','',str_replace(')(','|',$bbox_new[0]))));
+		            $bbox_min = explode(',',$bbox_new[0]);
+		            $bbox_max = explode(',',$bbox_new[1]);
+		            $geojsonBbox[$geojsonIndex]->minx = $bbox_min[0];
+		            $geojsonBbox[$geojsonIndex]->miny = $bbox_min[1];
+		            $geojsonBbox[$geojsonIndex]->maxx = $bbox_max[0];
+		            $geojsonBbox[$geojsonIndex]->maxy = $bbox_max[1];
+		            if ($minxFC > $geojsonBbox[$geojsonIndex]->minx) {
+		                $minxFC = $geojsonBbox[$geojsonIndex]->minx;
+		            }
+		            if ($minyFC > $geojsonBbox[$geojsonIndex]->miny) {
+		                $minyFC = $geojsonBbox[$geojsonIndex]->miny;
+		            }
+		            if ($maxxFC < $geojsonBbox[$geojsonIndex]->maxx) {
+		                $maxxFC = $geojsonBbox[$geojsonIndex]->maxx;
+		            }
+		            if ($maxyFC < $geojsonBbox[$geojsonIndex]->maxy){
+		                $maxyFC = $geojsonBbox[$geojsonIndex]->maxy;
+		            }
+		            //get geomtype
+		            $geomType = json_decode($mbFeature->toGeoJSON())->geometry->type;
+		            $geojsonList->features[] = json_decode($mbFeature->toGeoJSON());
+		            //$html .= "var feature_".$geomType."=".json_encode($geojsonList->features).";";
+		            $geojsonIndex++;
+		        }
+			$usedProxyTime = microtime_float() - $proxyStartTime;
+			$returnObject->numberMatched = $numberOfObjects;
+			$returnObject->numberReturned = $geojsonIndex;
+			$date = new DateTime();
+			$returnObject->timeStamp = date('Y-m-d\TH:i:s.Z\Z', $date->getTimestamp());
+			$returnObject->genTime = $usedProxyTime;
+			$returnObject->features = $geojsonList->features;
+			
+			
+		        //TODO write javascript object if to var if html is requested
+		        //$html .= "var feature_".$geomType."=".json_encode($geojsonList).";";
+		        //$html .= "</script>";
+		        //get number of features returned:
+		        //parse hits
+		        //$e = new mb_exception($features);
+		        try {
+		            $featureCollectionObject =  new SimpleXMLElement($features);
+		            if ($featureCollectionObject == false) {
+		                throw new Exception('Cannot parse WFS features request!');
+		            }
+		        }
+		        catch (Exception $e) {
+		            $e = new mb_exception($e->getMessage());
+		        }
+		        //TODO: hardcode wfs 2.0.0!
+		        switch ("2.0.0") {
+		            case "2.0.0":
+		                $hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberReturned');
+			        break;
+		            case "2.0.2":
+			        $hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberReturned');
+			        break;
+		            /*case "1.1.0":
+			        $hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberOfFeatures');
+			        break;*/
+		        }
+		    }
+		    //TODO - print to json
+		    //$html .= (integer)$hits[0]." results found for page ".$page."<br>";
+		    //$html .= "<br>";
+		} else {	            
+		    //************************************************************************************************************************************
+	            //item part 
+	            //************************************************************************************************************************************
+		}	
+	    } else {
+		$returnObject->success = false;
+    	        $returnObject->message = "Collection/Featuretype not available in service!";
+            }
+	}
+    }
+}
+
+//************************************************************************************************************************************
+//item part 
+//************************************************************************************************************************************
+
+
+switch ($f) {
+    case "json":
+	header("application/json");
+	echo json_encode($returnObject);
+	break;
+    case "html":
+	$newline = "\n";
+	//define header and navigation bar
+	$html = '';
+	$html .= '<!DOCTYPE html>'.$newline;
+	$html .= '<html>'.$newline;
+	$html .= '<head>'.$newline;
+	$html .= '<title>Mapbender WFS OpenLinkedData Proxy</title>'.$newline;
+	$html .= '<meta http-equiv="X-UA-Compatible" content="IE=edge">'.$newline;
+	$html .= '<meta charset="utf-8" />'.$newline;
+	$html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">'.$newline;	
+	//$html .= '<link rel="shortcut icon" type="image/x-icon" href="" />';
+	//leaflet css
+	$html .= '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>'.$newline;
+	//leaflet js
+	$html .= '<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>'.$newline;
+	//bootstrap
+	$html .= '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">'.$newline;
+    	$html .= '<link rel="stylesheet" href="../css/ldproxy_ia.css"/>'.$newline;
+	//own styles - mapviewer ...
+	$html .= '<style>
+	#map {
+		width: 600px;
+		height: 400px;
+	}
+</style>'.$newline;
+	//************************************************************************************************************************************
+	$html .= '<body>'.$newline;
+	//************************************************************************************************************************************
+	//navbar
+	$html .= '<nav class="navbar navbar-light bg-light navbar-expand-sm">'.$newline;
+	$html .= '<div class="container">'.$newline;
+	$html .= '<div id="navbar" class="navbar-collapse collapse d-flex justify-content-between align-items-center">'.$newline;
+	$html .= '<ol class="breadcrumb bg-light my-0 pl-0">'.$newline;
+	//
+	if (!isset($wfsid)){ // && (!isset($collection) || ($collections != 'all'))) {
+	    $html .= '<li class="breadcrumb-item active">Datasets</li>'.$newline;
+	} else {
+	    if (!isset($collection) || $collections == 'all') {
+	        $html .= '<li class="breadcrumb-item"><a href="'.$_SERVER['REQUEST_URI'].'">Datasets</a></li>'.$newline; //TODO - use base uri
+                $html .= '<li class="breadcrumb-item active">'.$returnObject->title.'</li>'.$newline;
+	    }
+	}
+	//
+	$html .= '</ol>'.$newline;
+	$html .= '<ul class="list-separated m-0 p-0 text-muted">'.$newline;
+	$html .= '</ul>'.$newline;        
+	$html .= '</div>'.$newline;
+	$html .= '<!--button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">'.$newline;
+	$html .= '<span class="navbar-toggler-icon"></span>'.$newline;
+	$html .= '</button-->'.$newline;
+	$html .= '</div>'.$newline;
+	$html .= '</nav>'.$newline;
+	//
+	//logic
+	if (!isset($wfsid)) {
+	//header for proxy
+	    $html .= "";
+	    $html .= '<div class="container py-4">'.$newline;
+	    $html .= '    <div itemscope itemtype="http://schema.org/DataCatalog">'.$newline;
+	    $html .= '        <h1 itemprop="name">Geodaten des Landes Rheinland-Pfalz</h1>'.$newline;
+	    $html .= '        <p itemprop="description">Unter einer offenen Lizenz publizierte Geodaten des Landes Rheinland-Pfalz als LinkedOpenData.</p>'.$newline;
+	    $html .= '        <p itemprop="url" class="d-none">https://www.opendata.geoportal.rlp.de/</p>'.$newline;
+	    $html .= '        <br/>'.$newline;
+	    $html .= '        <br/>'.$newline;
+	    $html .= '        <br/>'.$newline;
+    	    $html .= '        <ul class="list-unstyled space-after">'.$newline;
+	    foreach ($returnObject->service as $service) {
+	        $html .= '            <li itemprop="dataset" itemscope itemtype="http://schema.org/Dataset">'.$newline;
+                $html .= '                <h2>'.$newline;
+                $html .= '                    <a itemprop="url" href="?wfsid='.$service->id.'">'.$newline;
+                $html .= '                        <span itemprop="name">'.$service->title.'</span>'.$newline;
+                $html .= '                    </a>'.$newline;
+                $html .= '                </h2>'.$newline;
+                $html .= '                <span itemprop="description">'.$service->description.'</span>'.$newline;
+                $html .= '                <span itemprop="sameAs" class="d-none">/ad-links</span>'.$newline;
+                $html .= '            </li>'.$newline;						
+	    }
+	    $html .= '        </ul>'.$newline;
+	} else {
+	    if (!isset($collection) || $collections == 'all') {
+		//show service and collection info	    
+		$html .= "";
+		$html .= '<div class="container py-4">'.$newline;
+                $html .= '    <div itemscope itemtype="http://schema.org/Dataset">'.$newline;
+        	$html .= '        <h1 itemprop="name">'.$returnObject->title.'</h1>'.$newline;
+       	 	$html .= '        <span itemprop="description">'.$returnObject->description.'</span>'.$newline;
+        	$html .= '        <p itemprop="url" class="d-none">'.$_SERVER['REQUEST_URI'].'</p>'.$newline;//TODO canonical url
+            	$html .= '        <div itemprop="includedInDataCatalog" itemscope itemtype="http://schema.org/Datacatalog" class="d-none">'.$newline;
+                $html .= '            <div itemprop="url">https://www.ldproxy.nrw.de/'.$_SERVER['REQUEST_URI'].'</div>'.$newline;//TODO canonical url
+            	$html .= '        </div>'.$newline;
+		$html .= '    </div>'.$newline;
+		$html .= '</div>'.$newline;
+	    }
+	}
+	//************************************************************************************************************************************	
+	$html .= '    </div>'.$newline;
+	$html .= '</div>'.$newline;
+	//footer
+
+	$html .= '<footer class="footer bg-light py-4 d-flex flex-column justify-content-around align-items-center">'.$newline;
+	$html .= '    <div class="container d-flex flex-row justify-content-between align-items-center w-100">'.$newline;
+	$html .= '        <span>'.$newline;
+	$html .= '            <span class="text-muted small mr-2">powered by</span>'.$newline;
+	$html .= '            <a class="navbar-brand" href="https://git.osgeo.org/gitea/armin11/GeoPortal.rlp" target="_blank">GeoPortal.rlp</a>'.$newline;
+	$html .= '        </span>'.$newline;
+	$html .= '        <span>'.$newline;
+	$html .= '        </span>'.$newline;
+	$html .= '    </div>'.$newline;
+	$html .= '</footer>'.$newline;
+	$html .= '</body>'.$newline;
+	$html .= '</html>'.$newline;
+	//
+	header("text/html");
+	echo $html;
+	die();
+}
+die();
+
+//************************************************************************************************************************************
+
+
+
+
+//do the html things
+$html = '';
+$html .= '<!DOCTYPE html>';
+$html .= '<html>';
+$html .= '<head>';
+$html .= '<title>Mapbender WFS OpenLinkedData Proxy</title>';
+$html .= '<meta http-equiv="X-UA-Compatible" content="IE=edge">';
+$html .= '<meta charset="utf-8" />';
+$html .= '<meta name="viewport" content="width=device-width, initial-scale=1.0">';	
+//$html .= '<link rel="shortcut icon" type="image/x-icon" href="" />';
+$html .= '<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>';
+$html .= '<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js" integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og==" crossorigin=""></script>';
+//bootstrap
+$html .= '<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">';
+//own styles - mapviewer ...
+$html .= '<style>
+		html, body {
+			height: 100%;
+			margin: 0;
+		}
+		#map {
+			width: 600px;
+			height: 400px;
+		}
+	</style>';	
+$html .= '</head>';	
+$html .= '<body>';
+//navigation bar
+$html .= '<nav class="navbar navbar-light bg-light navbar-expand-sm">   ';
+$html .= '    <div class="container">';
+$html .= '        <div id="navbar" class="navbar-collapse collapse d-flex justify-content-between align-items-center">';
+$html .= '            <ol class="breadcrumb bg-light my-0 pl-0">';
+//if (!isset($wfsid)) {
+	$html .= '                            <li class="breadcrumb-item active">Datasets</li>';
+//} else {
+	//$html .= '                            <li class="breadcrumb-item active">'..'</li>';			
+//}
+//$html .= '                            <li class="breadcrumb-item active">Datasets</li>';
+$html .= '            </ol>';
+$html .= '            <ul class="list-separated m-0 p-0 text-muted">';
+$html .= '            </ul>    ';        
+$html .= '        </div>';
+
+$html .= '                    <!--button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">';
+$html .= '                <span class="navbar-toggler-icon"></span>';
+$html .= '            </button-->';
+
+$html .= '    </div>';
+$html .= '</nav>';
+$html .= '<script>';
+//https://stackoverflow.com/questions/5997450/append-to-url-and-refresh-page
+
+$html .= "	function URL_add_parameter(url, param, value){";
+$html .= "	    var hash       = {};";
+$html .= "	    var parser     = document.createElement('a');";
+
+$html .= "	    parser.href    = url;";
+
+$html .= "	    var parameters = parser.search.split(/\?|&/);";
+
+$html .= "	    for(var i=0; i < parameters.length; i++) {";
+$html .= "	        if(!parameters[i])";
+$html .= "	            continue;";
+
+$html .= "	        var ary      = parameters[i].split('=');";
+$html .= "	        hash[ary[0]] = ary[1];";
+$html .= "	    }";
+
+$html .= "	    hash[param] = value;";
+
+$html .= "	    var list = [];  ";
+$html .= "	    Object.keys(hash).forEach(function (key) {";
+$html .= "	        list.push(key + '=' + hash[key]);";
+$html .= "	    });";
+
+$html .= "	    parser.search = '?' + list.join('&');";
+$html .= "	    return parser.href;";
+$html .= "	}";
+
+$html .= "	function URL_remove_parameter(url, param){";
+$html .= "	    var hash       = {};";
+$html .= "	    var parser     = document.createElement('a');";
+
+$html .= "	    parser.href    = url;";
+
+$html .= "	    var parameters = parser.search.split(/\?|&/);";
+
+$html .= "	    for(var i=0; i < parameters.length; i++) {";
+$html .= "	        if(!parameters[i])";
+$html .= "	            continue;";
+
+$html .= "	        var ary      = parameters[i].split('=');";
+$html .= "	        hash[ary[0]] = ary[1];";
+$html .= "	    }";
+
+$html .= "	    hash[param] = 0;";
+
+$html .= "	    var list = [];  ";
+$html .= "	    Object.keys(hash).forEach(function (key) {";
+$html .= "		if (key != param) {";
+$html .= "	        	list.push(key + '=' + hash[key]);";
+$html .= "		}";
+$html .= "	    });";
+
+$html .= "	    parser.search = '?' + list.join('&');";
+$html .= "	    return parser.href;";
+$html .= "	}";
+
+
+$html .= '</script>';
+//only show map if wfsid is selected
+$html .= "<div id='map'></div>";
+$html .= "<div id='bboxButtons'><input type='button' onclick='location.href = URL_add_parameter(URL_remove_parameter(location.href, \"p\"), \"bbox\", map.getBounds().getWest()+\",\"+map.getBounds().getSouth()+\",\"+map.getBounds().getEast()+\",\"+map.getBounds().getNorth());return false;' value='Set Bbox Filter'><input type='button' onclick='location.href = URL_remove_parameter(URL_remove_parameter(location.href, \"bbox\"), \"p\");return false;' value='Delete Bbox Filter'><input type='button' onclick='location.href = location.href.split(\"?\")[0]';return false;' value='WFS List'></div>";
+
+//div elements
+/*$html .= '<div id="wfs_info"></div>';
+$html .= '<div id="wfs_table"></div>';
+$html .= '<div id="map"></div>';
+$html .= '<div id="featuretype_table"></div>';	
+$html .= '<div id="feature_table"></div>';
+$html .= '<div id="counter"></div>';*/
+//javascripts
+//$html .= '<script src="sample-geojson.js" type="text/javascript"></script>';	
+$html .= '<script>';	
+$html .= "	var map = L.map('map').setView([50, 7.44], 7);";
+
+$html .= "	L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?";
+$html .= "access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {";
+$html .= "		maxZoom: 18,";
+$html .= "		attribution: 'Map data © <a href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> contributors, ' +";
+$html .= "			'<a href=\"https://creativecommons.org/licenses/by-sa/2.0/\">CC-BY-SA</a>, ' +";
+$html .= "			'Imagery © <a href=\"https://www.mapbox.com/\">Mapbox</a>',";
+$html .= "		id: 'mapbox.light'";
+$html .= "	}).addTo(map);";
+if (!isset($wfsid) || !isset($ft)) {
+	$html .= 'document.getElementById("map").style.display = "none"; ';
+	$html .= 'document.getElementById("bboxButtons").style.display = "none"; ';
+}
+$html .= '</script>';
+
+$htmlFooter = '</body></html>';
+$htmlFooter = '<footer class="footer bg-light py-4 d-flex flex-column justify-content-around align-items-center">';
+$htmlFooter .= '<div class="container d-flex flex-row justify-content-between align-items-center w-100">';
+$htmlFooter .= '<span><span class="text-muted small mr-2">powered by</span><a class="navbar-brand" href="https://git.osgeo.org/gitea/armin11/GeoPortal.rlp" target="_blank">GeoPortal.rlp</a></span>';
+$htmlFooter .= '<span>';
+$htmlFooter .= '</span>';
+$htmlFooter .= '</div>';
+$htmlFooter .= '</footer>';
+
+//php logic	
+//generate list of allowed wfs_ids!
+//TODO
+/*
+*/
+	if (!isset($wfsid) || $wfsid == "") {
+		//list all public available wfs which are classified as opendata!
+		$openWfs = new stdClass();
+		$openWfs->list = array();
+		$sql = "SELECT * FROM (SELECT wfs_id, wfs_version, wfs_abstract, wfs_title, wfs_owsproxy, fkey_termsofuse_id FROM wfs INNER JOIN wfs_termsofuse ON wfs_id = fkey_wfs_id) AS wfs_tou INNER JOIN termsofuse ON fkey_termsofuse_id = termsofuse_id WHERE isopen = 1";
+		//all wfs - without open filter!
+		//$sql = "SELECT wfs_id, wfs_abstract, wfs_version, wfs_title, wfs_owsproxy FROM wfs";
+		$v = array();
+		$t = array();
+		$res = db_prep_query($sql, $v, $t);	
+		$i = 0;	
+		while($row = db_fetch_array($res)){
+			$openWfs->list[$i]->id = $row['wfs_id'];
+			$openWfs->list[$i]->title = $row['wfs_title'];
+			$openWfs->list[$i]->version = $row['wfs_version'];
+			$openWfs->list[$i]->description = $row['wfs_abstract'];
+			$i++;
+		}
+		$html .= '<div id="wfs_info">';	
+		$html .= '<ul class="list-unstyled space-after">';
+		//$html .= "Available WFS:";			
+		//$html .= "<br>";
+		foreach ($openWfs->list as $openWfs) {
+			$html .= '<li itemscope itemtype="http://schema.org/Dataset">';
+			$html .= '<h1>';
+			$html .= '<a itemprop="url" href="'.$_SERVER['REQUEST_URI']."?wfsid=".$openWfs->id.'">';
+			$html .= '<span itemprop="name">'.$openWfs->title.' (WFS '.$openWfs->version.')</span>';
+			$html .= '</a>';
+			$html .= '</h1>';
+			$html .= '<span itemprop="description">'.$openWfs->description.'</span>';
+			$html .= '</li>';	
+			
+		}
+		$html .= '</ul>';
+		$html .= $htmlFooter.'</body></html>';
+		echo $html;
+		die();
+	} else {
+		//try to instantiate wfs object
+		$myWfsFactory = new UniversalWfsFactory();
+		$wfs = $myWfsFactory->createFromDb($wfsid);
+
+		if ($wfs == null) {
+			$html .=  "wfs could not be instantiated!";
+			$html .= '</div>';
+		} else {
+			$html .= '</div>';
+			if (isset($ft) && $ft != "") {
+				if (isset($fid) && $fid != "") {		
+					//$html .= '<div id="feature_table">';
+					//header("Content-Type: application/gml+xml;version=3.1");
+					header("Content-Type: ".$outputFormat);
+					
+					echo $wfs->getFeatureById($ft, $outputFormat, $fid, "2.0.0", "EPSG:4326");
+					//$html .= '</div>';
+					//$html .= '</body>';
+					//$html .= '</html>';
+					die();
+				} else {		
+
+					$html .= '<div id="featuretype_info">';
+					$html .= "wfs successfully instantiated! ft is set!";
+					$html .= "<br>";
+					$html .= "wfs title: ".$wfs->title." - version: ".$wfs->getVersion();
+					$html .= "<br>";
+					//$ftNameArray = array();
+					$ftNameInWfs = false;
+					foreach ($wfs->featureTypeArray as $featureType) {
+						//$ftNameArray[] = $featureType->name;
+						if ($featureType->name == $ft) {
+							$ftNameInWfs = true;
+							$ftTitle = $featureType->title;
+							$ftName = $featureType->name;
+							$ftDbId = $featureType->id;
+		//output formats
+							$ftOutputFormats = implode(',', array_unique($featureType->featuretypeOutputFormatArray));
+							//get other relevant ft information
+							break;
+						} 
+					}
+					if ($ftNameInWfs) {
+						//TODO: cache counted features to allow faster access !!!!!
+					
+						$myFeatureType = $wfs->findFeatureTypeByName($ftName);
+						//get geom column name
+//TODO						
+						$geomColumnName = $wfs->findGeomColumnNameByFeaturetypeId($myFeatureType->id);
+
+//get bbox filter if defined!
+						//check for given spatialFilter (bbox)
+						if (isset($bbox) && $bbox != '') {
+							$filter = $wfs->bbox2spatialFilter($bbox, $geomColumnName, $srs="EPSG:4326", $version='2.0.0');
+							//$page = 0;
+						} else { 
+							$filter = null;
+						}
+						//$numberOfObjects = $wfs->countFeatures($ft);
+						//write to cache:
+						if ($cache->isActive) {
+							if ($cache->cachedVariableExists(md5("count_".$wfsid."_".$ft."_".(string)$filter)) == false) {
+								$numberOfObjects = $wfs->countFeatures($ft, $filter);
+								$cache->cachedVariableAdd(md5("count_".$wfsid."_".$ft."_".(string)$filter), $numberOfObjects);
+				
+							} else {
+//$e = new mb_exception("read count from cache!");
+								$numberOfObjects = $cache->cachedVariableFetch(md5("count_".$wfsid."_".$ft."_".(string)$filter));
+							}
+							//$e = new mb_notice("http/classes/class_crs.php - store crs info to cache!");
+							//return true;
+						} else {
+							$numberOfObjects = $wfs->countFeatures($ft, $filter);
+			
+						}
+$e = new mb_exception("number of objects: ".$numberOfObjects);
+						//request first object and metadata
+						//count objects
+						$html .= "wfs max features: ".$wfs->wfs_max_features."<br>";
+						$html .=  $ftTitle." (".$numberOfObjects.") - id: " .$ftDbId. " - output formats: ".$ftOutputFormats."<br>";
+						//get first page
+						//calculate pages
+						$numberOfPages = ceil($numberOfObjects / $maxObjectsPerPage);
+						//decide which page should be requested
+						//$page = 0;
+						//calculate offset for requested page
+						if ($page >= $numberOfPages) {
+							echo "requested page exeeds number of max pages!";
+							die();
+						} else {
+							$startIndex = $page * $maxObjectsPerPage;
+						}
+						$html .= '</div>';
+						//get more info for featuretype
+
+//$e = new mb_exception("bbox: ".$bbox);
+
+//$e = new mb_exception("filter: ".$filter);
+						//force version to be 2.0.0!!!!! - hope the server will support it
+						$features = $wfs->getFeaturePaging($ftName, $filter, "EPSG:4326", null, null, $maxObjectsPerPage, $startIndex, "2.0.0");
+						//transform to geojson to allow rendering !
+						$gml3Class = new Gml_3_Factory();
+						//create featuretype object
+//TODO
+
+//$e = new mb_exception("geom column type: ".$geomColumnName);
+						
+						$gml3Object = $gml3Class->createFromXml($features, null, $wfs, $myFeatureType, $geomColumnName);
+//$e = new mb_exception("geojson from mb class: ".json_encode($gml3Object));
+						$geojsonList = new stdClass();
+						$geojsonList->type = "FeatureCollection";
+						$geojsonList->features = array();
+						$geojsonBbox = array();
+						$geojsonIndex = 0;
+						$minxFC = 90;
+						$minyFC = 180;
+						$maxxFC = -90;
+						$maxyFC = -180;
+						$html .= "<script>";
+						foreach($gml3Object->featureCollection->featureArray as $mbFeature) {
+							//$e = new mb_exception("geojson from mb feature exporthandler: ".$mbFeature->toGeoJSON());
+							//bbox
+							$geojsonBbox[$geojsonIndex]->mbBbox = $mbFeature->getBbox();
+							//transform to simple bbox object for leaflet
+							$bbox_new = explode(' ',str_replace(']','',str_replace('[','',$geojsonBbox[$geojsonIndex]->mbBbox)));
+							$bbox_new = explode('|',str_replace(')','',str_replace('(','',str_replace(')(','|',$bbox_new[0]))));
+							$bbox_min = explode(',',$bbox_new[0]);
+							$bbox_max = explode(',',$bbox_new[1]);
+
+							$geojsonBbox[$geojsonIndex]->minx = $bbox_min[0];
+							$geojsonBbox[$geojsonIndex]->miny = $bbox_min[1];
+							$geojsonBbox[$geojsonIndex]->maxx = $bbox_max[0];
+							$geojsonBbox[$geojsonIndex]->maxy = $bbox_max[1];
+							if ($minxFC > $geojsonBbox[$geojsonIndex]->minx) {
+								$minxFC = $geojsonBbox[$geojsonIndex]->minx;
+							}
+							if ($minyFC > $geojsonBbox[$geojsonIndex]->miny) {
+								$minyFC = $geojsonBbox[$geojsonIndex]->miny;
+							}
+							if ($maxxFC < $geojsonBbox[$geojsonIndex]->maxx) {
+								$maxxFC = $geojsonBbox[$geojsonIndex]->maxx;
+							}
+							if ($maxyFC < $geojsonBbox[$geojsonIndex]->maxy){
+								$maxyFC = $geojsonBbox[$geojsonIndex]->maxy;
+							}
+
+							//get geomtype
+							$geomType = json_decode($mbFeature->toGeoJSON())->geometry->type;
+							$geojsonList->features[] = json_decode($mbFeature->toGeoJSON());
+							//$html .= "var feature_".$geomType."=".json_encode($geojsonList->features).";";
+							$geojsonIndex++;
+						}
+						$html .= "var feature_".$geomType."=".json_encode($geojsonList).";";
+						$html .= "</script>";
+						//get number of features returned:
+						//parse hits
+		//$e = new mb_exception($features);
+						try {
+							$featureCollectionObject =  new SimpleXMLElement($features);
+							if ($featureCollectionObject == false) {
+								throw new Exception('Cannot parse WFS features request!');
+							}
+						}
+						catch (Exception $e) {
+				    			$e = new mb_exception($e->getMessage());
+						}
+						//hardcode wfs 2.0.0!
+						switch ("2.0.0") {
+							case "2.0.0":
+								$hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberReturned');
+								break;
+							case "2.0.2":
+								$hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberReturned');
+								break;
+							/*case "1.1.0":
+								$hits = $featureCollectionObject->xpath('/wfs:FeatureCollection/@numberOfFeatures');
+								break;*/
+						}
+						$html .= (integer)$hits[0]." results found for page ".$page."<br>";
+						$html .= "<br>";
+//$e = new mb_exception("ft name: ".$ftName);
+//pagination ****************************************************************************************************************
+						$html .= '<nav id="pagination">';
+    						$html .= '<ul class="pagination mb-4">';
+						//page backward
+						if (($page - 1) >= 0) {
+							 $html .= "<li class=\"page-item\"><a class=\"page-link\" href='".delTotalFromQuery("p", $_SERVER['REQUEST_URI'])."&p=". ($page - 1) ."' target='_self'>". ($page - 1) . "</a><li>";
+						}
+						//page current
+						$html .=  "<li class=\"page-item active\"><a class=\"page-link\" href=\"\">".$page." (".($numberOfPages - 1).")</a><li>";
+						//page forward
+
+						if (($page + 1) < $numberOfPages) {
+							$html .= "<li class=\"page-item\"><a class=\"page-link\" href='".delTotalFromQuery("p", $_SERVER['REQUEST_URI'])."&p=". ($page + 1) ."' target='_self'>". ($page + 1) ."</a></li>";
+						}
+						//depends on the gml version!
+    						$html .= '</ul>';
+						$html .= '</nav>';
+//pagination ****************************************************************************************************************
+						//problem with id: maybe wfs is not configured in the right way!
+						$gmlIds = $featureCollectionObject->xpath('/wfs:FeatureCollection/wfs:member/'.$ftName.'/@gml:id');
+						//$html .= '<div id="feature_table">';
+						$html .= '<ul class="list-unstyled">';
+						$html .= '<li>';
+						$objIndex = 0;
+						foreach ($gmlIds as $gmlId) {
+$html .= '<div  itemscope itemtype="http://schema.org/Place">';
+							//link getfeaturebyid 
+							//echo "gml_id: ".$gmlId."<br>";
+							//echo $gmlId."<br>";
+							//<h4 class="mt-3 mb-1"><a href="https://www.ldproxy.nrw.de/kataster/collections/flurstueck/items/DENW19AL0000geMFFL?f=html&relations=bahnstrecken,gewaesser&resolve=true"><span itemprop="name">Bad Wünnenberg, Wünnenberg, 016 </span></a></h4>
+							//$html .= "<a  href='#' onclick='zoomToExtent(".$geojsonBbox[$objIndex]->minx.",".$geojsonBbox[$objIndex]->miny.",".$geojsonBbox[$objIndex]->maxx.",".$geojsonBbox[$objIndex]->maxy.");return false;'>".$gmlId."</a><br>";
+							//title
+							$html .= "<h4 class=\"mt-3 mb-1\"><a href=\"#\" onclick='zoomToExtent(".$geojsonBbox[$objIndex]->minx.",".$geojsonBbox[$objIndex]->miny.",".$geojsonBbox[$objIndex]->maxx.",".$geojsonBbox[$objIndex]->maxy.");return false;'><span itemprop=\"name\">".$gmlId."</span></a></h4>";
+							//$gmlIds = $featureCollectionObject->xpath('/wfs:FeatureCollection/wfs:member/'.$ftName.'/@gml:id');
+							//$geojsonList->features[$objIndex];
+							foreach(explode(",", $ftOutputFormats) as $outputFormat) {
+								$html .= "<a href='".$_SERVER['REQUEST_URI']."&fid=".$gmlId."&outputFormat=".$outputFormat."' target='_blank'>".$outputFormat."</a><br>";
+							}
+							foreach($geojsonList->features[$objIndex]->properties as $key=>$value) {
+								$html .= '<div class="row my-1">';
+								$html .= '<div class="col-md-6 font-weight-bold text-truncate" title="'.$key.'">'.$key.'</div>';
+								$html .= '<div class="col-md-6" >'.string2html($value).'</div>';
+								//$html .= $key.":".$value."<br>";
+								$html .= '</div>';
+							}
+							$html .= "<br>";
+							$objIndex++;
+$html .= '</div>';
+						}
+						$html .=  "</li>";
+						//$html .= '</div>';
+						$html .= '</ul>';
+//pagination ****************************************************************************************************************
+						$html .= '<nav id="pagination">';
+    						$html .= '<ul class="pagination mb-4">';
+						//page backward
+						if (($page - 1) >= 0) {
+							 $html .= "<li class=\"page-item\"><a class=\"page-link\" href='".delTotalFromQuery("p", $_SERVER['REQUEST_URI'])."&p=". ($page - 1) ."' target='_self'>". ($page - 1) . "</a><li>";
+						}
+						//page current
+						$html .=  "<li class=\"page-item\"><a class=\"page-link\" href=\"\">".$page." (".($numberOfPages - 1).")</a><li>";
+						//page forward
+
+						if (($page + 1) < $numberOfPages) {
+							$html .= "<li class=\"page-item\"><a class=\"page-link\" href='".delTotalFromQuery("p", $_SERVER['REQUEST_URI'])."&p=". ($page + 1) ."' target='_self'>". ($page + 1) ."</a></li>";
+						}
+									//depends on the gml version!
+    						$html .= '</ul>';
+						$html .= '</nav>';
+//pagination ****************************************************************************************************************
+						//$e = new mb_exception($features);
+			
+					} else {
+						$html .=  "ft not in wfs - operation not possible!";
+						//request first object and metadata
+						//count objects
+					}
+				}
+
+			} else {
+				$html .= '<div id="wfs_info">';
+				$html .= "wfs successfully instantiated!";
+				$html .= "<br>";
+				$html .= "wfs title: ".$wfs->title." - version: ".$wfs->getVersion();
+				$html .= "<br>";
+				$ftNameArray = array();					
+				$html .= '</div>';				
+				$html .= '<div id="featuretype_table">';
+				foreach ($wfs->featureTypeArray as $featureType) {
+					//$numberOfObjects = $wfs->countFeatures($featureType->name);
+					$html .= "<a href='".$_SERVER['REQUEST_URI']."&ft=".$featureType->name."' target='_self'>".$featureType->title." (".$featureType->name.")</a><br>";
+					//echo "featuretype: <a href='".$_SERVER['REQUEST_URI']."&ft=".$featureType->name."'".$featureType->name." - objects: ".$numberOfObjects."<br>";
+
+			
+			/*$ft = $wfs->findFeatureTypeByName($featureType->name);
+
+					foreach ($ft->featuretypeOutputFormatArray as $outputFormat) {
+						echo "		format: ".$outputFormat."<br>";
+					}*/
+				}
+				$html .= '</div>';
+			}
+	}
+//add javascript things that have be done after !
+$html .= "<script>";
+$html .= "	function onEachFeature(feature, layer) {";
+$html .= "		var popupContent = \"<p>I started out as a GeoJSON \" +";
+$html .= "				feature.geometry.type + \", but now I'm a Leaflet vector!</p>\";";
+
+$html .= "		if (feature.properties && feature.properties.popupContent) {";
+$html .= "			popupContent += feature.properties.popupContent;";
+$html .= "		}";
+$html .= "		for (var key in feature.properties){";
+$html .= "		    	var value = feature.properties[key];";
+$html .= "		   	popupContent += \"<br>\"+key+\": \"+value;";
+$html .= "		}";
+
+$html .= "		layer.bindPopup(popupContent);";
+$html .= "	}";
+
+
+//zoom to featurecollection
+//$e = new mb_exception($minxFC.",".$minyFC.",".$maxxFC.",".$maxyFC);
+
+$html .= "		map.fitBounds([";
+$html .= "   				[".$minxFC.",".$minyFC."],";
+$html .= "   				[".$maxxFC.",".$maxyFC."]";
+$html .= "			]);";	
+
+$html .= "	L.geoJSON([feature_".$geomType."], {";
+$html .= "		style: function (feature) {";
+$html .= "			return feature.properties && feature.properties.style;";
+$html .= "		},";
+$html .= "		onEachFeature: onEachFeature,";
+$html .= "		pointToLayer: function (feature, latlng) {";
+$html .= "			return L.circleMarker(latlng, {";
+$html .= "				radius: 8,";
+$html .= "				fillColor: \"#ff7800\",";
+$html .= "				color: \"#000\",";
+$html .= "				weight: 1,";
+$html .= "				opacity: 1,";
+$html .= "				fillOpacity: 0.8";
+$html .= "			});";
+$html .= "		}";
+$html .= "	}).addTo(map);";
+
+/*$html .= "	map.on('dragged', function() { ";
+$html .= "	     alert(map.getBounds());";
+$html .= "	});";*/
+
+
+$html .= "	function zoomToExtent(minx,miny,maxx,maxy) {";
+$html .= "		map.fitBounds([";
+$html .= "   				[minx, miny],";
+$html .= "   				[maxx, maxy]";
+$html .= "			]);";	
+$html .= "	}";
+
+/*map.fitBounds([
+    [40.712, -74.227],
+    [40.774, -74.125]
+]);*/
+
+
+
+
+$html .= "</script>";
+$html .= '</body></html>';
+echo $html;
+}
+
+$versionsWithPaging = array("2.0.0","2.0.2");
+//list outputFormats for featuretypes
+
+function delTotalFromQuery($paramName, $url) {
+	$query = explode("?", $url);
+	parse_str($query[1], $vars);
+	unset($vars[$paramName]);
+	$urlNew = $query[0]."?".http_build_query($vars);
+	return $urlNew;
+}
+
+?>



More information about the Mapbender_commits mailing list