memory_limit) && $configObject->memory_limit != "") { ini_set('memory_limit', $configObject->memory_limit); } if (isset($configObject) && isset($configObject->http_method) && ($configObject->http_method != "GET" || $configObject->http_method != "POST")) { $wfs_http_method = $configObject->http_method; } else { $wfs_http_method = "GET"; } if (isset($configObject) && isset($configObject->use_internal_bootstrap) && $configObject->use_internal_bootstrap == true) { $useInternalBootstrap = true; } if (isset($configObject) && isset($configObject->own_css) && $configObject->own_css != "") { $cssFile = $configObject->own_css; } else { $cssFile = "../css/ldproxy_ia.css"; } if (isset($configObject) && isset($configObject->default_pages) && $configObject->default_pages != "") { $limit = $configObject->default_pages; } else { $limit = 10; } if (isset($configObject) && isset($configObject->allowed_limits) && is_array($configObject->allowed_limits)) { $allowedLimits = $configObject->allowed_limits; } else { $allowedLimits = array("1","5","10","20","50","100","200"); } if (isset($configObject) && isset($configObject->initial_bbox) && is_array($configObject->initial_bbox) && count($configObject->initial_bbox) == 4) { $minxFC = $configObject->initial_bbox[0]; $minyFC = $configObject->initial_bbox[1]; $maxxFC = $configObject->initial_bbox[2]; $maxyFC = $configObject->initial_bbox[3]; } else { $minxFC = 48; $minyFC = 6; $maxxFC = 51; $maxyFC = 9; } if (isset($configObject) && isset($configObject->behind_rewrite) && $configObject->behind_rewrite == true) { $behindRewrite = true; } else { $behindRewrite = false; } if (isset($configObject) && isset($configObject->rewrite_path) && $configObject->rewrite_path != "") { $rewritePath = $configObject->rewrite_path; } else { $rewritePath = "linkedDataProxy"; } //textual data: $textualDataArray = array("title", "description", "datasource_url", "legal_notice_link", "privacy_notice_link", "map_position"); $title = "Open Spatial Data served by Mapbender WFS 3.0 Proxy"; $description = "Description of the instance of Mapbender WFS 3.0 Proxy"; $datasource_url = "https://www.geoportal.rlp.de/"; $legal_notice_link = "https://www.geoportal.rlp.de/article/Impressum"; $privacy_notice_link = "https://www.geoportal.rlp.de/article/Datenschutz"; $map_position = "side"; if (!empty($_SERVER['HTTPS'])) { $schema = "https"; } else { $schema = "http"; } $linkedDataProxyUrl = $schema."://".$_SERVER['HTTP_HOST']."/".$rewritePath; if ($behindRewrite == true) { $cssFile = MAPBENDER_PATH."/php/".$cssFile; $imagePathReplace = MAPBENDER_PATH."/img/"; //for license symbols exhange ../img/ with this string! } foreach ($textualDataArray as $textualData) { if (isset($configObject) && isset($configObject->{$textualData}) && $configObject->{$textualData} != "") { ${$textualData} = $configObject->{$textualData}; } } //$startmem = memory_get_usage(); //http://localhost/mapbender/devel_tests/wfsClientTest.php?wfsid=16&ft=vermkv:fluren_rlp&bbox=7.9,50.8,8.0,52 //problem: mapbender parses featuretype names from wfs <= 1.1.0 without namespaces, if they are not explecitly defined! //better to use wfs 2.0.0 as native interface //default page $page = 0; //default format f is html $f = "html"; //parameter to control if the native json should be requested from the server, if support for geojson is available! $nativeJson = false; //default outputFormat for wfs objects: $outputFormat = "text/xml"; $outputFormat = "text/xml; subtype=gml/3.1.1"; //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"); // $newline = " "; 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 "".$string.""; } return $string; } function delTotalFromQuery($paramName, $url) { $query = explode("?", $url); parse_str($query[1], $vars); if (is_array($paramName)) { foreach($paramName as $param) { unset($vars[$param]); } } else { unset($vars[$paramName]); } $urlNew = $query[0]."?".http_build_query($vars); return $urlNew; } function getJsonSchemaObject($feature) { $returnObject = new stdClass(); $returnObject->success = false; $url = $feature->properties->{'json-schema_0.7_id'}; if (isset($url)) { $schemaContextConnector = new Connector(); $file = $schemaContextConnector->load($url); $returnObject->schema = json_decode($file); if ($returnObject->schema == false) { $returnObject->success = false; } else { $returnObject->success = true; } $returnObject->url = $url; return $returnObject; } else { return $returnObject; } } function getJsonLdObject($feature) { $returnObject = new stdClass(); $returnObject->success = false; $url = $feature->properties->{'json-ld_1.1_context'}; if (isset($url)) { $schemaContextConnector = new Connector(); $file = $schemaContextConnector->load($url); $returnObject->schema = json_decode($file); if ($returnObject->schema == false) { $returnObject->success = false; } else { $returnObject->success = true; } $returnObject->url = $url; return $returnObject; } else { return $returnObject; } } function getOpenApi3JsonComponentTemplate() { $openApi3JsonComponent = << /linkedDataProxy/{wfsid}/collections/{collectionId}/items/{itemId}?f=html //uri of proxy have to be given absolute? - //http://localhost/linkedDataProxy/19/collections/TEHG_RLP%3Atehg_anlagen_2013_gesamt/items //http://localhost/linkedDataProxy/19/ //preg_grep() function get2Rest($requestString) { global $linkedDataProxyUrl; global $behindRewrite; //return $requestString; if ($behindRewrite == true) { $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest string to exchange: ".$requestString); //get query part: if (strpos($requestString, "?") !== false) { $queryPartArray = explode("?", $requestString); $queryString = $queryPartArray[1]; } else { $queryString = $requestString; } $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest found query: ".$queryString); //map queryString to rest url parse_str($queryString, $requestArray); $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest array of get parameters: ".json_encode($requestArray)); //initialize new api path $apiPath = ''; //would be relative //parts of api to extract from query $apiParams = array("wfsid", "collections", "collection", "items", "item"); //build path from params if (isset($requestArray['wfsid']) && $requestArray['wfsid'] != "") { $apiPath .= "/".$requestArray['wfsid'].""; } /*if (isset($requestArray['getapidescription']) && $requestArray['getapidescription'] == "true") { $apiPath .= "/api/"; }*/ if ($requestArray['collections'] == "api") { $apiPath .= "/api"; } if (isset($requestArray['collection']) && $requestArray['collection'] != "") { if ($requestArray['collection'] == "all") { $apiPath .= "/collections"; } else { $apiPath .= "/collections/".$requestArray['collection'].""; } } if (isset($requestArray['items']) && $requestArray['items'] != "") { if ($requestArray['items'] == "all") { $apiPath .= "/items"; } } if (isset($requestArray['item']) && $requestArray['item'] != "") { $apiPath .= "/items/".$requestArray['item']; } //remove all $apiParams from initial requestArray foreach ($apiParams as $apiParamName) { unset($requestArray[$apiParamName]); } //unset empty request elements - relicts? foreach ($requestArray as $key => $value){ if ($value == "") { unset($requestArray[$key]); } } $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest extracted api path: ".$apiPath); $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest further get parameters to add to api path: ".json_encode($requestArray)); //build new url from proxyPath, apiPath and the further get parameters if ($apiPath == "" && http_build_query($requestArray) == "") { $newUrl = $linkedDataProxyUrl."/"; } else { $newUrl = $linkedDataProxyUrl.$apiPath."?".ltrim(http_build_query($requestArray), "&"); } $e = new mb_notice("php/mod_linkedDataProxy.php function get2Rest new absolute url for href: ".$newUrl); return str_replace("?&", "?", rtrim($newUrl, "?")); } else { return $requestString; } } //first get request parameter for api - if invoked behind apache2 mod_rewrite to built REST if (isset($_REQUEST["api"]) && $_REQUEST["api"] != "") { $e = new mb_notice("php/mod_linkedDataProxy.php try to read GET parameters from api: ".$_REQUEST["api"]); //first get whole request "api" divide it by ? to distinguish query parameters from rest uris if (strpos($_REQUEST["api"], "?") !== false){ $pathArray = explode('?', $_REQUEST["api"]); $restPath = $pathArray[0]; $queryString = $pathArray[1]; //TODO foreach $queryString object generate one $_REQUEST[] variable - if allowed!!!!! - make a lookup table } else { $restPath = $_REQUEST["api"]; } //parse api - split by / - template: {wfsid}/collection/{collectionId}/items/{itemId} $requestParams = explode("/", $restPath); //array to store the request params from rest api - merge them afterward to get right request_uri! $apiParamsArray = array(); switch (count($requestParams)) { case "1": $_REQUEST["wfsid"] = $requestParams[0]; //$apiParamsArray["wfsid"] = $requestParams[0]; break; case "2": if ($requestParams[1] == "api") { $_REQUEST["wfsid"] = $requestParams[0]; $_REQUEST["collections"] = "api"; } else { if ($requestParams[1] == "collections") { $_REQUEST["wfsid"] = $requestParams[0]; $_REQUEST["collections"] = "all"; } else { echo 'URI not valid! {wfsid}/collection or {wfsid}/api
'; die(); } } break; case "3": if ($requestParams[1] == "collections") { $_REQUEST["wfsid"] = $requestParams[0]; $_REQUEST["collection"] = $requestParams[2]; $_REQUEST["items"] = "all"; } else { echo 'URI not valid! {wfsid}/collections/{collectionId}
'; die(); } break; case "4": if ($requestParams[1] == "collections" && $requestParams[3] == "items") { $_REQUEST["wfsid"] = $requestParams[0]; $_REQUEST["collection"] = $requestParams[2]; $_REQUEST["items"] = "all"; } else { echo 'URI not valid! {wfsid}/collections/{collectionId}/items
'; die(); } break; case "5": if ($requestParams[1] == "collections" && $requestParams[3] == "items") { $_REQUEST["wfsid"] = $requestParams[0]; $_REQUEST["collection"] = $requestParams[2]; $_REQUEST["item"] = $requestParams[4]; } else { echo 'URI not valid! {wfsid}/collections/{collectionId}/items/{itemId}
'; die(); } break; } } //TODO - built function to map get parameters back to combined rest/get uri // wfsid=...&collection=....&item=...&f=html -> /linkedDataProxy/{wfsid}/collections/{collectionId}/items/{itemId}?f=html //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: '.$testMatch.' is not valid.
'; echo 'Parameter wfsid is not valid (integer or cs integer list).
'; 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: '.$testMatch.' is not valid.
'; echo 'Parameter id is not valid (integer or cs integer list).
'; 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: '.$testMatch.' is not valid.
'; echo 'Parameter p is not valid (integer).
'; die(); } $page = $testMatch; $testMatch = NULL; } //alternate for page - limit offset if (isset($_REQUEST["limit"]) & $_REQUEST["limit"] != "") { //validate to csv integer list $testMatch = $_REQUEST["limit"]; if (!in_array($testMatch, $allowedLimits)){ echo 'Parameter limit is not valid - must be one of: '.implode(',', $allowedLimits).'
'; die(); } $limit = (integer)$testMatch; $testMatch = NULL; } if (isset($_REQUEST["offset"]) & $_REQUEST["offset"] != "") { //validate to csv integer list $testMatch = $_REQUEST["offset"]; $pattern = '/^[\d]*$/'; if (!preg_match($pattern,$testMatch)){ //echo 'id: '.$testMatch.' is not valid.
'; echo 'Parameter offset is not valid (integer).
'; die(); } $offset = (integer)$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: '.$testMatch.' is not valid.
'; echo 'Parameter collection is not valid (ogc resource name or id).
'; 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", "api"))){ echo 'Parameter collections is not valid (maybe all or api).
'; 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 items is not valid (maybe all).
'; die(); } $items = $testMatch; $testMatch = NULL; } if (isset($_REQUEST["item"]) & $_REQUEST["item"] != "") { //reg expr $testMatch = $_REQUEST["item"]; $pattern = '/^[0-9a-zA-Z\.\-_:]*$/'; if (!preg_match($pattern,$testMatch)){ //echo 'id: '.$testMatch.' is not valid.
'; echo 'Parameter item is not valid (/^[0-9a-zA-Z\.\-_:]*$/).
'; die(); } $item = $testMatch; $testMatch = NULL; } if (isset($_REQUEST["outputFormat"]) & $_REQUEST["outputFormat"] != "") { //validate to csv integer list $testMatch = $_REQUEST["outputFormat"]; if (!in_array($testMatch, $allowedOutputFormats)){ echo 'Parameter outputFormat is not valid - must be one of: '.implode(',', $allowedOutputFormats).'
'; 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 f is not valid - must be one of: '.implode(',', $allowedFormats).'
'; 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 bbox has a wrong amount of entries.
'; die(); } for($i=0; $ibbox is not a valid coordinate value.
'; die(); } } $bbox = $testMatch; $testMatch = NULL; } if (isset($_REQUEST["nativeJson"]) & $_REQUEST["nativeJson"] != "") { //validate to csv integer list $testMatch = $_REQUEST["nativeJson"]; if (!in_array($testMatch, array("true","false"))){ echo 'Parameter nativeJson is not valid - must be one of: '.implode(',', array("true","false")).'
'; die(); } if ($testMatch == "true") { $nativeJson = true; } $testMatch = NULL; } //merge together all request parameters to new global available query_string which is needed for further href's //this string holds parts from rest url and the further parameters in case of rewrite (rest) and simple invocation via php script $wholeQueryArray = $_REQUEST; //unset api part from rewrite, cause this was already read before and intgrated into request array unset($wholeQueryArray['api']); //remove api from global $wholeQuery; $wholeQuery = http_build_query($wholeQueryArray); //************************************************************************************************************************************ //overwrite request_uri if invoked from rest api to add further parameters which came from api path $e = new mb_notice("php/linkedDataProxy.php: Original request URI: ".$_SERVER['REQUEST_URI']); $e = new mb_notice("php/linkedDataProxy.php: Mapping to GET Parameters: ".$wholeQuery); //************************************************************************************************************************************ //remove api from $_SERVER['REQUEST_URI'] $_SERVER['REQUEST_URI'] = delTotalFromQuery("api", $_SERVER['REQUEST_URI']); //add all other parameters if (isset($_REQUEST['api']) && $_REQUEST['api'] != "") { if (strpos($_SERVER['REQUEST_URI'], "?") !== false){ $requestUriArray = explode("?", $_SERVER['REQUEST_URI']); $_SERVER['REQUEST_URI'] = $requestUriArray[0]."?".$wholeQuery; } else { $_SERVER['REQUEST_URI'] = $wholeQuery; } } //************************************************************************************************************************************ $e = new mb_notice("php/linkedDataProxy.php: \$_SERVER['REQUEST_URI'] after \"api\" paramter deleted: ".$_SERVER['REQUEST_URI']); //example when invoked from rest api: //before: /mapbender/php/mod_linkedDataProxy.php?api=18/collections //after: wfsid=18&collections=all //therefor we need a resubstitution of the /mapbender/php/mod_linkedDataProxy.php with {proxyPath} and //the build the further path fom the relevant GET parameters // function get2Rest() -> does the work //************************************************************************************************************************************ $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, wfs_getcapabilities, providername, fees 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, wfs_getcapabilities, providername, fees 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']; $returnObject->service[$i]->provider = $row['providername']; $returnObject->service[$i]->license = $row['fees']; $returnObject->service[$i]->accessUrl = $row['wfs_getcapabilities']; $i++; } if ($i == 0) { $returnObject->success = false; $returnObject->message = "No services found in registry"; //$e = new mb_exception("no wfs found"); } 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); //set force version to pull featuretype_name with namespace!!!!, $forceVersion = "2.0.0" if ($wfs == null) { $returnObject->success = false; $returnObject->message = "Wfs object could not be created from db!"; } else { $e = new mb_exception($wfs->providerName." - ".$wfs->summary." - ".$wfs->electronicMailAddress." - ".$wfs->fees); //repair some missing wfs data if (!isset($wfs->summary) || $wfs->summary == null || $wfs->summary == "") { $wfs->summary = "WFS description is missing!"; } if (!isset($wfs->providerName) || $wfs->providerName == null || $wfs->providerName == "") { $wfs->providerName = "WFS providername is missing!"; } if (!isset($wfs->electronicMailAddress) || $wfs->electronicMailAddress == null || $wfs->electronicMailAddress == "") { $wfs->electronicMailAddress = "test@test.org"; } if (!isset($wfs->fees) || $wfs->fees == null || $wfs->fees == "") { $wfs->fees = "No fees are given in WFS Capabilities!"; } //create service part if no collection is requested if (!isset($collection) || $collection == "" || $collections == "all" || $collections == "api") { //************************************************************************************************************************************ //service only part //************************************************************************************************************************************ //add from rlp! $returnObject->id = $wfsid; $returnObject->title = $wfs->title; $returnObject->description = $wfs->summary; $returnObject->provider = $wfs->providerName; $returnObject->providerEmail = $wfs->electronicMailAddress; //$returnObject->providerHomepage = $wfs->homepage; //TODO add to ows class! $returnObject->providerHomepage = "https://www.geoportal.rlp.de/"; $returnObject->license = $wfs->fees; //get contraints $constraints = new OwsConstraints(); $constraints->languageCode = "de"; $constraints->asTable = true; $constraints->id = $wfsid; $constraints->type = "wfs"; $constraints->returnDirect = false; $tou = $constraints->getDisclaimer();//TODO encoding problems may occur! if (isset($imagePathReplace)) { $tou = str_replace("../img/", $imagePathReplace, $tou); } if ($f == "html") { $returnObject->license = $tou; //- generate license info in json for json format!!!!! } $returnObject->accessUrl = $wfs->getCapabilities; //uri to test openapi description: //https://editor.swagger.io/ if ($collections == "api") { $apiDescriptionJson = new stdClass(); $apiDescriptionJson->openapi = "3.0.1"; $apiDescriptionJson->info->title = $wfs->title; $apiDescriptionJson->info->description = $wfs->summary; $apiDescriptionJson->info->contact->name = $wfs->providerName; $apiDescriptionJson->info->contact->url = $returnObject->providerHomepage; $apiDescriptionJson->info->contact->email = $wfs->electronicMailAddress; $apiDescriptionJson->info->license->name = $wfs->fees; $apiDescriptionJson->info->version = "1.0.0"; //server url - for the proxy!!! $apiDescriptionJson->servers[0]->url = $linkedDataProxyUrl."/".$wfsid."/"; $apiDescriptionJson->tags[0]->name = "Capabilities"; $apiDescriptionJson->tags[0]->description = "Essential characteristics of this API including information about the data."; $apiDescriptionJson->tags[1]->name = "Features"; $apiDescriptionJson->tags[1]->description = "Access to data (features)."; //path / **************************************************************** $apiDescriptionJson->paths->{'/'}->get->tags = array("Capabilities"); $apiDescriptionJson->paths->{'/'}->get->summary = "landing page of this API"; $apiDescriptionJson->paths->{'/'}->get->description = "The landing page provides links to the API definition, the Conformance statements and the metadata about the feature data in this dataset."; $apiDescriptionJson->paths->{'/'}->get->operationId = "getLandingPage"; $apiDescriptionJson->paths->{'/'}->get->parameters = array(); $apiDescriptionJson->paths->{'/'}->get->responses->{'200'}->description = "links to the API capabilities and the feature collections shared by this API."; $apiDescriptionJson->paths->{'/'}->get->responses->{'200'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/root"; $apiDescriptionJson->paths->{'/'}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{'/'}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{'/'}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{'/'}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //path / **************************************************************** //path /api **************************************************************** $apiDescriptionJson->paths->{'/api'}->get->tags = array("Capabilities"); $apiDescriptionJson->paths->{'/api'}->get->summary = "the API description - this document"; $apiDescriptionJson->paths->{'/api'}->get->operationId = "getApiDescription"; $apiDescriptionJson->paths->{'/api'}->get->parameters = array(); $apiDescriptionJson->paths->{'/api'}->get->responses->{'200'}->description = "The formal documentation of this API according to the OpenAPI specification, version 3.0. I.e., this document."; $apiDescriptionJson->paths->{'/api'}->get->responses->{'200'}->content->{'application/openapi+json;version=3.0'}->schema->type = "object"; $apiDescriptionJson->paths->{'/api'}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{'/api'}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{'/api'}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{'/api'}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //path /api **************************************************************** //path /conformance **************************************************************** $apiDescriptionJson->paths->{'/conformance'}->get->tags = array("Capabilities"); $apiDescriptionJson->paths->{'/conformance'}->get->summary = "information about standards that this API conforms to"; $apiDescriptionJson->paths->{'/conformance'}->get->description = "list all requirements classes specified in a standard (e.g., WFS 3.0 Part 1: Core) that the server conforms to"; $apiDescriptionJson->paths->{'/conformance'}->get->operationId = "getRequirementsClasses"; $apiDescriptionJson->paths->{'/conformance'}->get->parameters = array(); $apiDescriptionJson->paths->{'/conformance'}->get->responses->{'200'}->description = "the URIs of all requirements classes supported by the server"; $apiDescriptionJson->paths->{'/conformance'}->get->responses->{'200'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/req-classes"; $apiDescriptionJson->paths->{'/conformance'}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{'/conformance'}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; //path /conformance **************************************************************** //path /collections **************************************************************** $apiDescriptionJson->paths->{'/collections'}->get->tags = array("Capabilities"); $apiDescriptionJson->paths->{'/collections'}->get->summary = "describe the feature collections in the dataset"; $apiDescriptionJson->paths->{'/collections'}->get->operationId = "describeCollections"; $apiDescriptionJson->paths->{'/collections'}->get->parameters = array(); $apiDescriptionJson->paths->{'/collections'}->get->responses->{'200'}->description = "Metadata about the feature collections shared by this API."; $apiDescriptionJson->paths->{'/collections'}->get->responses->{'200'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/content"; $apiDescriptionJson->paths->{'/collections'}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{'/collections'}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{'/collections'}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{'/collections'}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //path /collections **************************************************************** //collect the elements foreach featuretype via sql foreach ($wfs->featureTypeArray as $featureType) { //path /collections **************************************************************** $featuretypePathPart = '/collections/'.$featureType->name; $apiDescriptionJson->paths->{$featuretypePathPart}->get->tags = array("Capabilities"); $apiDescriptionJson->paths->{$featuretypePathPart}->get->summary = "describe the ".$featureType->title." feature collection"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->operationId = "describeCollection".$featureType->name; $apiDescriptionJson->paths->{$featuretypePathPart}->get->parameters = array(); $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->description = "Metadata about the collection shared by this API."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'application/geo+json'}->schema->{'$ref'} = "#/components/schemas/collectionInfo"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //items ************************************************************************* $featuretypePathPart = '/collections/'.$featureType->name.'/items'; $apiDescriptionJson->paths->{$featuretypePathPart}->get->tags = array("Features"); $apiDescriptionJson->paths->{$featuretypePathPart}->get->summary = "retrieve features of ".$featureType->title." feature collection"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->operationId = "getFeatures".$featureType->name; //possible query filters: $queryParams = array("f", "limit", "offset", "bbox", "resultType", "properties"); //TODO: crs, bbox-crs, maxAllowableOffset foreach ($queryParams as $param) { $apiDescriptionJson->paths->{$featuretypePathPart}->get->parameters[]->{'$ref'} = "#/components/parameters/".$param; } //TODO : funktion ? -https://www.ldproxy.nrw.de/topographie/api/?f=json -$apiDescriptionJson->paths->{$featuretypePathPart}->get->parameters[] = $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->description = "A feature."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'application/geo+json'}->schema->{'$ref'} = "#/components/schemas/featureGeoJSON"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //items ************************************************************************* //{items}/{featureId} ************************************************************************* $featuretypePathPart = '/collections/'.$featureType->name.'/items/{featureId}'; $apiDescriptionJson->paths->{$featuretypePathPart}->get->tags = array("Features"); $apiDescriptionJson->paths->{$featuretypePathPart}->get->summary = "retrieve a ".$featureType->title; $apiDescriptionJson->paths->{$featuretypePathPart}->get->operationId = "getFeature".$featureType->name; //possible query filters: $queryParams = array("featureId", "f", "properties"); //TODO: crs, maxAllowableOffset foreach ($queryParams as $param) { $apiDescriptionJson->paths->{$featuretypePathPart}->get->parameters[]->{'$ref'} = "#/components/parameters/".$param; } //TODO : funktion ? -https://www.ldproxy.nrw.de/topographie/api/?f=json -$apiDescriptionJson->paths->{$featuretypePathPart}->get->parameters[] = $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->description = "Information about the feature collection plus the first features matching the selection parameters."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'application/geo+json'}->schema->{'$ref'} = "#/components/schemas/featureCollectionGeoJSON"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'200'}->content->{'text/html'}->schema->type = "string"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->description = "An error occured."; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'application/json'}->schema->{'$ref'} = "#/components/schemas/exception"; $apiDescriptionJson->paths->{$featuretypePathPart}->get->responses->{'default'}->content->{'text/html'}->schema->{'type'} = "string"; //{items}/{featureId}************************************************************************* //path /collections **************************************************************** //define template - first use it from ia //TODO: remove not used elements } $jsonTemplate = json_decode(getOpenApi3JsonComponentTemplate()); $apiDescriptionJson->components = $jsonTemplate->components; /* //components $apiDescriptionJson->components->schemas->exception->required[0] = "code"; $apiDescriptionJson->components->schemas->exception->type = "object"; $apiDescriptionJson->components->schemas->exception->properties->code->type = "string"; $apiDescriptionJson->components->schemas->exception->properties->description->type = "string"; $apiDescriptionJson->components->schemas->root->required[0] = "links"; $apiDescriptionJson->components->schemas->root->type = "object"; $apiDescriptionJson->components->schemas->root->properties->links->type = "array"; $apiDescriptionJson->components->schemas->root->properties->links->example[0]->href = "http://data.example.org/"; $apiDescriptionJson->components->schemas->root->properties->links->example[0]->rel = "self"; $apiDescriptionJson->components->schemas->root->properties->links->example[0]->type = "application/json"; $apiDescriptionJson->components->schemas->root->properties->links->example[0]->title = "this document"; $apiDescriptionJson->components->schemas->root->properties->links->example[1]->href = "http://data.example.org/api"; $apiDescriptionJson->components->schemas->root->properties->links->example[1]->rel = "service"; $apiDescriptionJson->components->schemas->root->properties->links->example[1]->type = "application/openapi+json;version=3.0"; $apiDescriptionJson->components->schemas->root->properties->links->example[1]->title = "the API definition"; $apiDescriptionJson->components->schemas->root->properties->links->example[2]->href = "http://data.example.org/conformance"; $apiDescriptionJson->components->schemas->root->properties->links->example[2]->rel = "conformance"; $apiDescriptionJson->components->schemas->root->properties->links->example[2]->type = "application/json"; $apiDescriptionJson->components->schemas->root->properties->links->example[2]->title = "WFS 3.0 conformance classes implemented by this server"; $apiDescriptionJson->components->schemas->root->properties->links->example[3]->href = "http://data.example.org/collections"; $apiDescriptionJson->components->schemas->root->properties->links->example[3]->rel = "data"; $apiDescriptionJson->components->schemas->root->properties->links->example[3]->type = "application/json"; $apiDescriptionJson->components->schemas->root->properties->links->example[1]->title = "Metadata about the feature collections"; $apiDescriptionJson->components->schemas->{'req-classes'}->required[0] = "conformsTo"; $apiDescriptionJson->components->schemas->{'req-classes'}->type = "object"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->type = "array"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->example[0] = "http://www.opengis.net/spec/wfs-1/3.0/req/core"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->example[1] = "http://www.opengis.net/spec/wfs-1/3.0/req/oas30"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->example[2] = "http://www.opengis.net/spec/wfs-1/3.0/req/html"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->example[3] = "http://www.opengis.net/spec/wfs-1/3.0/req/geojson"; $apiDescriptionJson->components->schemas->{'req-classes'}->properties->conformsTo->items = "string"; $apiDescriptionJson->components->schemas->link->required[0] = "href"; $apiDescriptionJson->components->schemas->link->type = "object"; $apiDescriptionJson->components->schemas->link->properties->href->type = "string"; $apiDescriptionJson->components->schemas->link->properties->href->example = "http://data.example.com/buildings/123"; $apiDescriptionJson->components->schemas->link->properties->rel->type = "string"; $apiDescriptionJson->components->schemas->link->properties->rel->example = "prev"; $apiDescriptionJson->components->schemas->link->properties->type->type = "string"; $apiDescriptionJson->components->schemas->link->properties->type->example = "application/geo+json"; $apiDescriptionJson->components->schemas->link->properties->type->hreflang = "string"; $apiDescriptionJson->components->schemas->link->properties->type->hreflang = "de"; */ /* $apiDescriptionJson->components->schemas->content-> $apiDescriptionJson->components->schemas->collectionInfo-> $apiDescriptionJson->components->schemas->extent-> $apiDescriptionJson->components->schemas->featureCollectionGeoJSON-> $apiDescriptionJson->components->schemas->featureGeoJSON-> $apiDescriptionJson->components->schemas->geometryGeoJSON-> $apiDescriptionJson->components->parameters->*/ $paramArray = array("f", "limit", "offset", "bbox", "resultType", "featureId", "limitList", "properties"); //TODO: relations, resolve, offsetList, crs, bbox-crs, maxAllowedOffset //first draft - set only json based api description and give it back header("application/json"); echo json_encode($apiDescriptionJson, JSON_UNESCAPED_SLASHES); die(); } // $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 = get2Rest($_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 = get2Rest($_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 = get2Rest($_SERVER['REQUEST_URI']."&collections=all"); //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 = get2Rest($_SERVER['REQUEST_URI']."&collection=".$featureType->name."&items=all"); //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 = get2Rest($_SERVER['REQUEST_URI']."&collection=".$featureType->name); //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) { //requested ft found! $ftNameInWfs = true; $ftTitle = $featureType->title; $ftName = $featureType->name; $ftDbId = $featureType->id; //output formats $ftOutputFormats = implode(',', array_unique($featureType->featuretypeOutputFormatArray)); //get other relevant ft information //extract schema - get all elements that are strings and integers $ftElementArray = $featureType->elementArray; //consists of name and type //get allowed attributes for filtering $ftAllowedAttributesArray = array(); foreach ($ftElementArray as $ftElement) { //$e = new mb_exception($ftElement->name ." - " .$ftElement->type); if ($ftElement->type == "string") { $ftAllowedAttributesArray[] = $ftElement->name; } } break; } } if ($ftNameInWfs) { $myFeatureType = $wfs->findFeatureTypeByName($ftName); $geomColumnName = $wfs->findGeomColumnNameByFeaturetypeId($myFeatureType->id); //check all allowed attributes to may be set by GET param $stringFilterArray = array(); $stringFilterActive = array(); $stringFilterIndex = 0; //$e = new mb_exception("test: count: ".count($ftAllowedAttributesArray)); foreach ($ftAllowedAttributesArray as $ftAllowedAttribute) { //$e = new mb_exception("search for: ".$ftAllowedAttribute); if (isset($_REQUEST[$ftAllowedAttribute]) && $_REQUEST[$ftAllowedAttribute] != "") { //$e = new mb_exception("found param:".$ftAllowedAttribute.": ".$_REQUEST[$ftAllowedAttribute]); $testMatch = $_REQUEST[$ftAllowedAttribute]; $pattern = '/^[0-9a-zA-Z\.\-_:*]*$/'; if (!preg_match($pattern,$testMatch)){ echo 'Parameter '.$ftAllowedAttribute.' is not valid (allowed string).
'; die(); } $stringFilterActive[] = $ftAllowedAttribute; $stringFilterArray[$stringFilterIndex]->elementName = $ftAllowedAttribute; $stringFilterArray[$stringFilterIndex]->elementFilter = $testMatch; $stringFilterIndex++; $testMatch = NULL; } } //first test - only use string filter from index 0! if (!isset($item) || $item == "") { //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 = get2Rest($_SERVER['REQUEST_URI']."&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(); //for rlp: $returnObject->serviceTitle = $wfs->title; $returnObject->collectionId = $myFeatureType->id; $returnObject->collectionName = $ftName; $returnObject->collectionTitle = $myFeatureType->title; // $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 = get2Rest($_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; } //add string filter if some one was given if(isset($stringFilterArray) && count($stringFilterArray) > 0) { //foreach - generate own filter - TODO /* dog:gemarkung0401 dog:flur109 dog:flurstuecksnummer00212 dog:flurstuecksnummernenner0007 */ /* st:stationName Rov* */ //TODO allow combination of different text filters!!!! - Not all wfs support this ? if (false) { if (strpos($stringFilterArray[0]->elementFilter, "*") !== false) { $textFilter .= ''; $textFilter .= ''.$stringFilterArray[0]->elementName.''; $textFilter .= ''.$stringFilterArray[0]->elementFilter.''; $textFilter .= ''; } else { $textFilter .= ''; $textFilter .= ''.$stringFilterArray[0]->elementName.''; $textFilter .= ''.$stringFilterArray[0]->elementFilter.''; $textFilter .= ''; } } else { $textFilterArray = array(); $textFilterIndex = 0; $textFilterArray[$textFilterIndex] = ""; foreach ($stringFilterArray as $stringFilter) { if (strpos($stringFilter->elementFilter, "*") !== false) { $textFilterArray[$textFilterIndex] .= ''; $textFilterArray[$textFilterIndex] .= ''.$stringFilter->elementName.''; $textFilterArray[$textFilterIndex] .= ''.$stringFilter->elementFilter.''; $textFilterArray[$textFilterIndex] .= ''; } else { $textFilterArray[$textFilterIndex] .= ''; $textFilterArray[$textFilterIndex] .= ''.$stringFilter->elementName.''; $textFilterArray[$textFilterIndex] .= ''.$stringFilter->elementFilter.''; $textFilterArray[$textFilterIndex] .= ''; } $textFilterIndex++; } if (count($textFilterArray) > 1) { //bbox is set $textFilter = ''.implode('', $textFilterArray).''; } else { $textFilter = implode('', $textFilterArray); } } } else { $textFilter = null; } //build new filter if ($filter != null && $textFilter != null) { $filter = ''.$filter.$textFilter.''; } else { if ($filter == null && $textFilter == null) { $filter = null; } else { $filter = ''.(string)$filter.(string)$textFilter.''; } } //test //$e = new mb_exception("filter: ".$filter); //write number of features to ram cache: if ($cache->isActive) { //if (false) { if ($cache->cachedVariableExists(md5("count_".$wfsid."_".$collection."_".md5($filter))) == false) { $numberOfObjects = $wfs->countFeatures($collection, $filter, "EPSG:4326", "2.0.0", false, $wfs_http_method); $cache->cachedVariableAdd(md5("count_".$wfsid."_".$collection."_".md5($filter)), $numberOfObjects); } else { //$e = new mb_exception("read count from cache!"); $numberOfObjects = $cache->cachedVariableFetch(md5("count_".$wfsid."_".$collection."_".md5($filter))); } //$e = new mb_notice("http/classes/class_crs.php - store crs info to cache!"); //return true; } else { //TODO - define post/get central //$numberOfObjects = $wfs->countFeatures($collection, $filter, "2.0.0"); $numberOfObjects = $wfs->countFeatures($collection, $filter, "EPSG:4326", "2.0.0", false, $wfs_http_method); } //$numberOfObjects = 1000; //$e = new mb_exception("counted features: ".$numberOfObjects); if ($numberOfObjects == 0 || $numberOfObjects == false) { $returnObject->success = false; $returnObject->message = "No results found or an error occured - see server logs - please try it again! Use the back button!"; //if ($f == "json") { header("application/json"); echo json_encode($returnObject); //} die(); } //$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."
"; //$html .= $ftTitle." (".$numberOfObjects.") - id: " .$ftDbId. " - output formats: ".$ftOutputFormats."
"; //get first page //calculate pages //$numberOfPages = ceil($numberOfObjects / $maxObjectsPerPage); $numberOfPages = ceil($numberOfObjects / $limit); //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 * $limit; } if (!isset($offset)) { $offset = 0; } $lastOffset = ($numberOfPages - 1) * $limit ; $startIndex = $offset; //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); $returnObject->links[1]->href = get2Rest($_SERVER['REQUEST_URI']."&offset=".($offset + 1 * $limit)."&limit=".$limit); //for rlp $returnObject->links[2]->rel = "last"; $returnObject->links[2]->type = "application/geo+json"; $returnObject->links[2]->title = "last page"; //$returnObject->links[1]->href = $_SERVER['REQUEST_URI']."&p=".($page + 1); $returnObject->links[2]->href = get2Rest($_SERVER['REQUEST_URI']."&offset=".$lastOffset."&limit=".$limit); //check if outputformat geojson is available - if - gml don't need to be parsed!!!!! TODO - where to become hits ????? - has to count in a special request!!!!! if (in_array('application/json; subtype=geojson', explode(',', $ftOutputFormats)) && $nativeJson == true) { //if (false) { $features = $wfs->getFeaturePaging($ftName, $filter, "EPSG:4326", null, null, $limit, $startIndex, "2.0.0", 'application/json; subtype=geojson', $wfs_http_method); $geojsonList = json_decode($features); $geojsonBbox = array(); $geojsonIndex = 0; $minxFC = 90; $minyFC = 180; $maxxFC = -90; $maxyFC = -180; $minxF = 90; $minyF = 180; $maxxF = -90; $maxyF = -180; if ($f == 'html'){ $geoJsonVariable = ""; $geoJsonVariable = '".$newline; } $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; //resolve json-schema ********************************************************* $resolveJsonSchema = getJsonSchemaObject($geojsonList->features[0]); $schemaObject = $resolveJsonSchema->schema; //json-ld $resolveJsonLd = getJsonLdObject($geojsonList->features[0]); $ldObject = $resolveJsonLd->schema; //add url to foreach ($geojsonList->features as $feature) { if ($resolveJsonSchema->success = true) { $feature->{'$schema'} = $resolveJsonSchema->url; } if ($resolveJsonLd->success = true) { $feature->{'$context'} = $resolveJsonLd->url; } } //***************************************************************************** $returnObject->features = $geojsonList->features; } //$e = new mb_exception("wfsid: ".$wfsid." - collection: ".$collection." - item: ".$item); } else { //$e = new mb_exception("wfsid: ".$wfsid." - collection: ".$collection." - item: ".$item); //************************************************************************************************************************************ //item part //************************************************************************************************************************************ //$e = new mb_exception("wfsid: ".$wfsid." - collection: ".$collection." - item: ".$item); if (in_array('application/json; subtype=geojson', explode(',', $ftOutputFormats)) && $nativeJson == true) { $features = $wfs->getFeatureById($collection, 'application/json; subtype=geojson', $item, "2.0.0", "EPSG:4326"); $geojsonList = json_decode($features); $geojsonBbox = array(); $geojsonIndex = 0; $minxFC = 90; $minyFC = 180; $maxxFC = -90; $maxyFC = -180; $minxF = 90; $minyF = 180; $maxxF = -90; $maxyF = -180; if ($f == 'html'){ $geoJsonVariable = ""; $geoJsonVariable .= '".$newline; } $usedProxyTime = microtime_float() - $proxyStartTime; $returnObject = $geojsonList->features[0]; //integrate json-ld @context if it is resovable!******************************************************************************* /*$ldContextConnector = new Connector(); $url = "http://localhost/mapbender/geoportal/".str_replace(":","__",$ftName).".jsonld"; $file = $ldContextConnector->load($url); //$e = new mb_exception($file); $contextObject = json_decode($file); //$e = new mb_exception(json_encode($contextObject)); $returnObject->properties->{'@context'} = $contextObject->{'@context'};*/ //integrate json-ld @context if it is resovable!******************************************************************************* //integrate json-schema @id if it is resolvable! - {json-schema_0.7_id} attribute to avoid problems with gml encoding and @ in element name! ******************************************************************************* //$schemaObject = //$e = new mb_exception(json_encode($contextObject)); //$returnObject->properties->{'@context'} = $contextObject->{'@context'}; //integrate json-ld @context if it is resovable!******************************************************************************* //add service title and collection title for navigation //for rlp $returnObject->serviceTitle = $wfs->title; $returnObject->collectionId = $myFeatureType->id; $returnObject->collectionName = $ftName; $returnObject->collectionTitle = $myFeatureType->title; //end rlp specific $returnObject->links[0]->href = get2Rest($_SERVER['REQUEST_URI']); $returnObject->links[0]->rel = "self"; $returnObject->links[0]->type = "application/geo+json"; $returnObject->links[0]->title = "this document"; $returnObject->links[1]->href = get2Rest($_SERVER['REQUEST_URI']); $returnObject->links[1]->rel = "alternate"; $returnObject->links[1]->type = "text/html"; $returnObject->links[1]->title = "this document as HTML"; $returnObject->links[2]->href = get2Rest($_SERVER['REQUEST_URI']); $returnObject->links[2]->rel = "alternate"; $returnObject->links[2]->type = "application/gml+xml;profile=\"http://www.opengis.net/def/profile/ogc/2.0/gml-sf2\";version=3.2"; $returnObject->links[2]->title = "this document as GML"; } } 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 "xml": break; case "html": $js1 = ''.$newline; $js2 = ''.$newline; $newline = " "; //define header and navigation bar $html = ''; $html .= ''.$newline; $html .= ''.$newline; $html .= ''.$newline; $html .= ''.$title.''.$newline; $html .= ''.$newline; $html .= ''.$newline; $html .= ''.$newline; //$html .= ''; //leaflet css $html .= ''.$newline; //leaflet js $html .= ''.$newline; //bootstrap if ($useInternalBootstrap == true) { if ($behindRewrite == true) { $html .= ''.$newline; } else { $html .= ''.$newline; } } else { $html .= ''.$newline; } $html .= ''.$newline; //own styles - mapviewer ... $html .= ''.$newline; //************************************************************************************************************************************ $html .= ''.$newline; //************************************************************************************************************************************ //navbar $html .= ''.$newline; // //logic if (!isset($wfsid)) { //header for proxy $html .= ""; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '

'.$title.'

'.$newline; $html .= '

'.$description.'

'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; } else { if (!isset($collection) || $collections == 'all') { //$e = new mb_exception(json_encode($returnObject)); //show service and collection info //service $html .= ""; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '

'.$returnObject->title.'

'.$newline; $html .= ' '.$returnObject->description.''.$newline; $html .= ' '.$newline;//TODO canonical url $html .= '
'.$newline; $html .= ' '.$newline;//TODO canonical url $html .= '
'.$newline; //ul 0 for keywords ... //ul 1..n for distribution - each a download url to a wfs featuretype in different formats! //new div for collections: //collection $html .= '
'.$newline; $html .= '
Collections
'.$newline; $html .= '
'.$newline; $html .= '
    '.$newline; foreach($returnObject->collections as $collection) { //get url to further page foreach ($collection->links as $link) { if ($link->rel == 'item') { $collectionHtmlUrl = delTotalFromQuery("f", $link->href)."&f=html"; break; } } $html .= '
  • '.$newline; $html .= ' '.$collection->title.''.$newline; $html .= '
  • '.$newline; } $html .= '
'.$newline; $html .= '
'.$newline; //further information about the service API TODO $html .= '
'.$newline; $html .= '
API Definition
'.$newline; $html .= '
'.$newline; $html .= ' '.get2Rest($_SERVER['REQUEST_URI']."&collections=api").''.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //further information about the service DATASOURCE TODO $html .= '
'.$newline; $html .= '
'._mb('Data source').'
'.$newline; $html .= '
'.$newline; $html .= ' '.$returnObject->accessUrl.''.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //further information about the service PROVIDER TODO $html .= '
'.$newline; $html .= '
'._mb('Provider').'
'.$newline; $html .= '
'.$newline; $html .= '
    '.$newline; $html .= '
  • '.$returnObject->provider.'
  • '.$newline; $html .= ' '.$newline; $html .= '
  • '.$newline; $html .= ' technical support'.$newline; $html .= '
      '.$newline; $html .= '
    • '.$returnObject->providerEmail.'
    • '.$newline; $html .= ' '.$newline; $html .= '
    '.$newline; $html .= '
  • '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //further information about the service LICENSE TODO $html .= '
'.$newline; $html .= '
'._mb('License').'
'.$newline; $html .= '
'.$newline; $html .= '
'.$returnObject->license.'
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
2018-05-18T14:45:11.573Z/2019-08-05T06:27:56.536Z
'.$newline; //TODO $html .= '
50.237351 5.612726 52.528630 9.589634
'.$newline; //TODO $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; } else { //collection is selected - show items //if (!isset($item) || $items == 'all') { //new for items and itemlists! $html .= '
'.$newline; if (!isset($item) || $items == "all") { $html .= '
'.$newline; $html .= '

'.$returnObject->collectionTitle.' ('.$numberOfObjects.')'.'

'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //TODO - further filter options $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= 'Filter'.$newline; if (isset($bbox) && $bbox != "") { $html .= '
'.$newline; } if (isset($nativeJson) && $nativeJson == true) { $html .= '
'.$newline; } //for each other set parameter show*********************************************** //variable with parameters: foreach($stringFilterArray as $stringFilter) { $html .= '
'.$newline; } //$stringFilterArray[$stringFilterIndex]->elementName = $ftAllowedAttribute; //$stringFilterArray[$stringFilterIndex]->elementFilter = $testMatch; //******************************************************************************** $html .= ''; //$html .= ''; $html .= ''.$newline; //bbox filter part from ldproxy $html .= '
'.$newline; //nativeJson Filter - to use if some memory error occur - if (in_array('application/json; subtype=geojson', explode(',', $ftOutputFormats))) { $html .= '
'.$newline; $html .= '

'._mb('Serverside format').'

'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; } //paging options //allowedLimits $html .= '
'.$newline; $html .= '

'._mb('Results per page').'

'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; // $html .= '
'.$newline; $html .= '

bbox

'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; if (is_array($ftAllowedAttributesArray) && count($ftAllowedAttributesArray) > 0) { $html .= '
'.$newline; $html .= '

'._mb('field').'

'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= ' '._mb('Use * as wildcard').''.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= ' '.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //add script $html .= ''; $html .= '
'.$newline; } $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; if ($map_position == "below_filter") { $html .= '
'.$newline; } } //Navigation elements $html .= '
'.$newline; $html .= '
'.$newline; if (!isset($item) || $items == 'all') { //generate page navigation********************************************************************************************************************************************************** $nav = ""; $nav .= ' '.$newline; //end navigation elements $html .= $nav; //end page navigation********************************************************************************************************************************************************** $html .= '
    '.$newline; $objIndex = 0; foreach($returnObject->features as $feature) { $html .= '
  • '.$newline; $html .= '
    '.$newline; $html .= '

    '.$feature->id.'

    miny.",".$geojsonBbox[$objIndex]->maxx.",".$geojsonBbox[$objIndex]->maxy.');return false;">'._mb('zoom to').''.$newline; $html .= ' https://www.ldproxy.nrw.de/topographie/collections/ax_bergbaubetrieb/items/DENWAT01D000CcF0'.$newline; //foreach attribute foreach($feature->properties as $key=>$value) { if (isset ($schemaObject->properties->{$key}->title)){ $attributeTitle = $schemaObject->properties->{$key}->title; } else { $attributeTitle = $key; } if (isset ($schemaObject->properties->{$key}->description)){ $attributeDescription = $schemaObject->properties->{$key}->description; } else { $attributeDescription = $attributeTitle; } //inject semantic context if ldObject given $html .= '
    '.$newline; $html .= '
    '.$attributeTitle.'
    '.$newline; //semantic annotations if (isset ($ldObject->{'@context'}->{$key})){ $uri = $ldObject->{'@context'}->{$key}; $schemaOrgArray = explode("/",str_replace("https://", "", $uri)); $schemaOrgObject = $schemaOrgArray[1]; $schemaOrgAttribute = $schemaOrgArray[2]; //$semAttribution = "vocab=\"https://schema.org/\" typeof=\"$schemaOrgObject\" property=\"$schemaOrgAttribute\""; //TODO - check semantics !!!! $semAttribution = "itemscope=\"\" itemtype=\"http://schema.org/".$schemaOrgObject."\" itemprop=\"$schemaOrgAttribute\""; } else { $semAttribution = ""; } if (gettype($value) == "string") { $html .= '
    '.string2html($value).'
    '.$newline; } else { $html .= '
    '.json_encode($value).'
    '.$newline; } $html .= '
    '.$newline; } $html .= '
    '.$newline; $html .= '
  • '.$newline; $objIndex++; } $html .= '
'.$newline; $html .= $nav; } else { //only one feature is found! if ($map_position == "below_filter") { $html .= '
'.$newline; } $feature = $returnObject; $html .= '
'.$newline; $html .= '

'.$feature->id.'

'.$newline; $html .= ' '.$newline; //foreach attribute foreach($feature->properties as $key=>$value) { if (isset ($schemaObject->properties->{$key}->title)){ $attributeTitle = $schemaObject->properties->{$key}->title; } else { $attributeTitle = $key; } if (isset ($schemaObject->properties->{$key}->description)){ $attributeDescription = $schemaObject->properties->{$key}->description; } else { $attributeDescription = $attributeTitle; } $html .= '
'.$newline; $html .= '
'.$attributeTitle.'
'.$newline; //semantic annotations if (isset ($ldObject->{'@context'}->{$key})){ $uri = $ldObject->{'@context'}->{$key}; $schemaOrgArray = explode("/",str_replace("https://", "", $uri)); $schemaOrgObject = $schemaOrgArray[1]; $schemaOrgAttribute = $schemaOrgArray[2]; //$semAttribution = "vocab=\"https://schema.org/\" typeof=\"$schemaOrgObject\" property=\"$schemaOrgAttribute\""; //TODO - check semantics !!!! $semAttribution = "itemscope=\"\" itemtype=\"http://schema.org/".$schemaOrgObject."\" itemprop=\"$schemaOrgAttribute\""; } else { $semAttribution = ""; } if (gettype($value) == "string") { $html .= '
'.string2html($value).'
'.$newline; } else { $html .= '
'.json_encode($value).'
'.$newline; } $html .= '
'.$newline; } $html .= '
'.$newline; } $html .= '
'.$newline; $html .= ''.$newline; $js1 = ' '.$newline; $html .= ''.$newline; $js2 = ' '.$newline; //add first scripts to html $html .= $js1; $html .= '
'.$newline; if ($map_position == 'side') { $html .= '
'.$newline; } $html .= "".$newline; $html .= $js2; $html .= "".$newline; $html .= $geoJsonVariable; $html .= ''.$newline; $js3 = " ".$newline; //add geojson object from page //$html .= $geojsonVariable.$newline; $html .= $js3; /*} else { //item is set ! //$html .= '
'; //header("Content-Type: application/gml+xml;version=3.1"); header("Content-Type: ".$outputFormat); echo $wfs->getFeatureById($collection, $outputFormat, $item, "2.0.0", "EPSG:4326"); die(); }*/ } } //************************************************************************************************************************************ $html .= '
'.$newline; $html .= '
'.$newline; $html .= '
'.$newline; //************************************************************************************************************************************ //footer $html .= ''.$newline; //************************************************************************************************************************************ $html .= ''.$newline; $html .= ''.$newline; // header("text/html"); echo $html; die(); } die(); ?>