resolveSuccess = false; $this->resolveErrorMessage = false; $this->extractIdentifierType($identifier); if ($this->resolveCrsInfo() == true) { $this->resolveSuccess = true; } } /** * A public function whith a parameter for {owstype}_{version}. If the ows needs a swap of the crs axis order true is returned, * otherwise - if the axis are handled as they are defined in the epsg registry - the function returns false */ //handles ows identifier: wms_1.0.0, wms_1.1.1, wms_1.3.0, wfs_1.0.0, wfs_1.1.0, wfs_2.0.0, wfs_2.0.2 public function alterAxisOrder ($targetOws) { $owsWithSpecialOrder = array("wms_1.0.0","wms_1.1.1","wfs_1.0.0","gml_2.0.0","gml_2.1.0","gml_3.1.1","geojson");//lon/lat,east/north $owsWithOrderAsDefined = array("wms_1.3.0","wfs_1.1.0","wfs_2.0.0","wfs_2.0.2","gml_3.2.0"); //$owsWithOrderAsDefined = array("wms_1.3.0","wfs_2.0.0","wfs_2.0.2"); $order = "east,north"; //dummy postgis/oracle spatial order if (in_array($targetOws, $owsWithSpecialOrder) && $this->axisOrder !== $order) { //if (in_array($targetOws, $owsWithSpecialOrder) && $this->identifierType == 'epsg' && $this->axisOrder !== $order) { //return false; //cause it is hardcoded in the specs to user lon/lat as this is so in postgis return false; } else { if (in_array($targetOws, $owsWithOrderAsDefined) && $this->axisOrder !== $order) { return true; } return false; } } private function extractIdentifierType ($identifier) { //check for type if (substr(strtoupper($identifier), 0, 5) === "EPSG:") { $this->identifier = $identifier; $this->identifierType = 'epsg'; $this->identifierCode = explode(':',$identifier)[1]; return; } else { //check for urn based version - example: urn:ogc:def:crs:EPSG: if (substr(strtoupper($identifier), 0, 21) === "URN:OGC:DEF:CRS:EPSG:") { //delete this part from original identifier $identifierNew = str_replace('URN:OGC:DEF:CRS:EPSG:','',strtoupper($identifier)); $this->identifier = $identifier; $this->identifierType = 'urn'; if (substr($identifierNew, 0, 1 ) === ":") { $this->identifierCode = ltrim($identifierNew, ':'); } else { if (strpos($identifierNew, ":") !== false) { $this->identifierCode = explode(':',$identifierNew)[1]; } else { $this->identifierCode = $identifierNew; } } return; } else { //case urn:x-ogc:def:crs:EPSG:25832?? - geoserver if (substr(strtoupper($identifier), 0, 23) === "URN:X-OGC:DEF:CRS:EPSG:") { //delete this part from original identifier $identifierNew = str_replace('URN:X-OGC:DEF:CRS:EPSG:','',strtoupper($identifier)); $this->identifier = $identifier; //TODO - use url encoding for resolving registry ;-) maybe change this $this->identifierType = 'url'; $this->identifierCode = $identifierNew; return; } else { if (substr($identifier, 0, 31) === 'http://www.opengis.net/def/crs/') { $identifierNew = str_replace('http://www.opengis.net/def/crs/','',$identifier); //remaining string: ({OGC|EPSG}/{0}/{code}) $this->identifier = $identifier; $this->identifierType = 'url'; $this->identifierCode = explode('/',$identifierNew)[2]; return; } else { $this->identifier = $identifier; $this->identifierType = 'other'; $this->identifierCode = $identifier; } } } } } private function resolveCrsInfo () { $cache = new Cache(); //try to read from cache if already exists if ($cache->isActive && $cache->cachedVariableExists(md5($this->identifier))) { $cachedObject = json_decode($cache->cachedVariableFetch(md5($this->identifier))); $this->gmlRepresentation = $cachedObject->gmlRepresentation; $this->epsgType = $cachedObject->epsgType; $this->axisOrder = $cachedObject->axisOrder; $this->name = $cachedObject->name; $e = new mb_notice("http/classes/class_crs.php - read crs info from cache!"); return true; } //built urls to get information from registries switch ($this->identifierType) { case "epsg": $registryBaseUrl = "http://www.epsg-registry.org/export.htm?gml="; $registryUrl = $registryBaseUrl.urlencode("urn:ogc:def:crs:EPSG::".$this->identifierCode); break; case "urn": $registryBaseUrl = "http://www.epsg-registry.org/export.htm?gml="; $registryUrl = $registryBaseUrl.urlencode($this->identifier); /*$xpathCrsType = ""; $xpathAxis = "";*/ break; case "url": $registryBaseUrl = "http://www.epsg-registry.org/export.htm?gml="; $registryUrl = $registryBaseUrl.urlencode("urn:ogc:def:crs:EPSG::".$this->identifierCode); /*$xpathCrsType = ""; $xpathAxis = "";*/ break; default: break; } $crsConnector = new connector(); $crsConnector->set("timeOut", "2"); $crsConnector->load($registryUrl); if ($crsConnector->timedOut == true) { return false; } $this->gmlRepresentation = $crsConnector->file; //generate separate jsonObject $jsonCrsInfo->gmlRepresentation = $this->gmlRepresentation; //parse relevant information libxml_use_internal_errors(true); try { $crsXml = simplexml_load_string($this->gmlRepresentation); if ($crsXml === false) { foreach(libxml_get_errors() as $error) { $err = new mb_exception("class_crs:".$error->message); } throw new Exception("class_crs:".'Cannot parse crs gml!'); return false; } } catch (Exception $e) { $err = new mb_exception("class_crs:".$e->getMessage()); return false; } //if parsing was successful if ($crsXml !== false) { $crsXml->registerXPathNamespace("epsg", "urn:x-ogp:spec:schema-xsd:EPSG:1.0:dataset"); $crsXml->registerXPathNamespace("gml", "http://www.opengis.net/gml/3.2"); $crsXml->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink"); //switch for type of cs - distinguish between ellipsoidalCS and CartesianCS (begin with lowercase character in crs document) $this->epsgType = $crsXml->xpath('//gml:metaDataProperty/epsg:CommonMetaData/epsg:type'); $this->epsgType = $this->epsgType[0]; $this->name = $crsXml->xpath('//gml:name'); $this->name = $this->name[0]; $e = new mb_notice("http/classes/class_crs.php - name of crs: ".$this->name); $jsonCrsInfo->name = (string)$this->name; $jsonCrsInfo->epsgType = (string)$this->epsgType; //echo $this->name; //echo $this->epsgType; //get attribute for specific system switch ($this->epsgType) { case "projected": $xpathIdentifierCs = "//gml:cartesianCS/@xlink:href"; break; case "geographic 2D": $xpathIdentifierCs = "//gml:ellipsoidalCS/@xlink:href"; break; } $csIdentifier = $crsXml->xpath($xpathIdentifierCs); $csIdentifier = $csIdentifier[0]; //get axis order from further xml document $urlToCsDefinition = $registryBaseUrl.urlencode($csIdentifier); $csConnector = new connector($urlToCsDefinition); $csConnector->set("timeOut", "2"); if ($csConnector->timedOut == true) { return false; } $csGmlRepresentation = $csConnector->file; try { $csXml = simplexml_load_string($csGmlRepresentation); if ($csXml === false) { foreach(libxml_get_errors() as $error) { $err = new mb_exception("class_crs:".$error->message); } throw new Exception("class_crs: Cannot parse cs gml!"); return false; } } catch (Exception $e) { $err = new mb_exception("class_cs:".$e->getMessage()); return false; } if ($csXml !== false) { $csXml->registerXPathNamespace("epsg", "urn:x-ogp:spec:schema-xsd:EPSG:1.0:dataset"); $csXml->registerXPathNamespace("gml", "http://www.opengis.net/gml/3.2"); $csXml->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink"); //switch for type of cs - distinguish between ellipsoidalCS and CartesianCS (begin with lowercase character in crs document) $axis = $csXml->xpath('//gml:axis/gml:CoordinateSystemAxis/gml:axisDirection'); //TODO - think about it? switch for crs lookup table of crs which axis order was swapped from earlier ogc standards to newer - identify them by the usage og EPSG:XXXX notation - no good idea /*if (DEFINED("OLD_EPSG_AXIS_ORDER_ALTERED") && OLD_EPSG_AXIS_ORDER_ALTERED !== "") { $old_epsg_axis_order_altered = explode(",", OLD_EPSG_AXIS_ORDER_ALTERED); } else { $old_epsg_axis_order_altered = array(); } if ($this->identifierType == 'epsg' && in_array($this->identifierCode, $old_epsg_axis_order_altered)) { $this->axisOrder = $axis[1].",".$axis[0]; } else { $this->axisOrder = $axis[0].",".$axis[1]; }*/ $this->axisOrder = $axis[0].",".$axis[1]; $jsonCrsInfo->axisOrder = $this->axisOrder; } } //store information - maybe to cache, if it does not already exists! if ($cache->isActive && $cache->cachedVariableExists(md5($this->identifier)) == false) { $cache->cachedVariableAdd(md5($this->identifier), json_encode($jsonCrsInfo)); $e = new mb_notice("http/classes/class_crs.php - store crs info to cache!"); return true; } return true; } } ?>