1: <?php
2:
3: namespace Mapbender\WmtsBundle\Component;
4: use Mapbender\WmtsBundle\Entity\WmtsService;
5: use Mapbender\WmtsBundle\Entity\WmtsLayerDetail;
6: use Mapbender\WmtsBundle\Entity\WmtsLayer;
7: use Mapbender\WmtsBundle\Entity\WmtsGroupLayer;
8: use Mapbender\WmtsBundle\Entity\Theme;
9: use Mapbender\WmtsBundle\Entity\TileMatrix;
10: use Mapbender\WmtsBundle\Entity\TileMatrixSet;
11: use Mapbender\WmtsBundle\Component\Exception\ParsingException;
12:
13: 14: 15: 16: 17: 18: 19:
20: abstract class WmtsCapabilitiesParser {
21:
22: 23: 24: 25:
26: protected $doc;
27:
28: protected $xpath;
29:
30: 31: 32:
33: public function __construct($data){
34:
35: $this->doc = new \DOMDocument();
36: if(!$this->doc->loadXML($data)){
37: if(!$this->doc->loadHTML($data)){
38: throw new \UnexpectedValueException("Could not parse CapabilitiesDocument.");
39: }
40: }
41: $this->xpath = new \DOMXPath($this->doc);
42: $this->registerNamespace();
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61: if(!@$this->doc->validate()){
62:
63: };
64: }
65:
66: private function registerNamespace() {
67:
68: $this->xpath->registerNamespace('wmts', "http://www.opengis.net/wmts/1.0");
69: $this->xpath->registerNamespace('ows', "http://www.opengis.net/ows/1.1");
70: $this->xpath->registerNamespace('xlink', "http://www.w3.org/1999/xlink");
71: $this->xpath->registerNamespace('xsi', "http://www.w3.org/2001/XMLSchema-instance");
72: $this->xpath->registerNamespace('gml', "http://www.opengis.net/gml");
73: }
74:
75: private function getValue($xpath, $contextElm){
76: try {
77: $elm = $this->xpath->query($xpath, $contextElm)->item(0);
78: if($elm->nodeType == XML_ATTRIBUTE_NODE) {
79: return $elm->value;
80: } else if($elm->nodeType == XML_TEXT_NODE){
81: return $elm->wholeText;
82: } else if($elm->nodeType == XML_ELEMENT_NODE) {
83: return $elm;
84: } else {
85: return null;
86: }
87: }catch(\Exception $E){
88: return null;
89: }
90: }
91:
92: 93: 94:
95: public function getWMTSService(){
96: $wmts = new WmtsService();
97:
98: $root = $this->doc->documentElement;
99: $wmts->setVersion($this->getValue("./@version", $root));
100: $wmts->setIdentifier("WMTS");
101:
102:
103: $serviceIdentification = $this->xpath->query("./ows:ServiceIdentification", $root)->item(0);
104: if($serviceIdentification != null){
105: $wmts->setTitle($this->getValue("./ows:Title/text()", $serviceIdentification));
106: $wmts->setAbstract($this->getValue("./ows:Abstract/text()", $serviceIdentification));
107: $wmts->setFees($this->getValue("./ows:Fees/text()", $serviceIdentification));
108: $wmts->setAccessConstraints($this->getValue("./ows:AccessConstraints/text()", $serviceIdentification));
109: $wmts->setServiceType($this->getValue("./ows:ServiceType/text()", $serviceIdentification));
110: }
111: unset($serviceIdentification);
112:
113: $serviceProvider = $this->xpath->query("./ows:ServiceProvider", $root)->item(0);
114: if($serviceProvider != null){
115: $wmts->setServiceProviderName($this->getValue("./ows:ProviderName/text()", $serviceProvider));
116: $wmts->setServiceProviderSite($this->getValue("./ows:ProviderSite/text()", $serviceProvider));
117: $wmts->setContactIndividualName($this->getValue("./ows:ServiceContact/ows:IndividualName/text()", $serviceProvider));
118: $wmts->setContactPositionName($this->getValue("./ows:ServiceContact/ows:PositionName/text()", $serviceProvider));
119: $wmts->setContactPhoneVoice($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Phone/ows:Voice/text()", $serviceProvider));
120: $wmts->setContactPhoneFacsimile($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Phone/ows:Facsimile/text()", $serviceProvider));
121: $wmts->setContactAddressDeliveryPoint($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:DeliveryPoint/text()", $serviceProvider));
122: $wmts->setContactAddressCity($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:City/text()", $serviceProvider));
123: $wmts->setContactAddressAdministrativeArea($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:AdministrativeArea/text()", $serviceProvider));
124: $wmts->setContactAddressPostalCode($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:PostalCode/text()", $serviceProvider));
125: $wmts->setContactAddressCountry($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:Country/text()", $serviceProvider));
126: $wmts->setContactElectronicMailAddress($this->getValue("./ows:ServiceContact/ows:ContactInfo/ows:Address/ows:ElectronicMailAddress/text()", $serviceProvider));
127: }
128: unset($serviceProvider);
129:
130: $operationsMetadata = $this->xpath->query("./ows:OperationsMetadata", $root)->item(0);
131: if($operationsMetadata != null){
132: $getCapabilities = $this->xpath->query("./ows:Operation[@name='GetCapabilities']", $operationsMetadata)->item(0);
133: if($getCapabilities != null){
134: $getrest = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[./ows:Constraint/ows:AllowedValues/ows:Value/text()='RESTful']/@xlink:href", $getCapabilities);
135: $wmts->setRequestGetCapabilitiesGETREST($getrest);
136: $getkvp = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[./ows:Constraint/ows:AllowedValues/ows:Value/text()='KVP']/@xlink:href", $getCapabilities);
137: $wmts->setRequestGetCapabilitiesGETKVP($getkvp);
138:
139:
140: }
141: unset($getCapabilities);
142: $getTile = $this->xpath->query("./ows:Operation[@name='GetTile']", $operationsMetadata)->item(0);
143: if($getTile != null){
144: $getrest = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[./ows:Constraint/ows:AllowedValues/ows:Value/text()='RESTful']/@xlink:href", $getTile);
145:
146: $versionAtUrl = "/".$wmts->getVersion();
147: $pos = strripos($getrest, $versionAtUrl);
148: if ($pos!==false && $pos >= (strlen($getrest) - strlen($versionAtUrl) - 1)){
149: $getrest = substr($getrest, 0, $pos);
150: }
151: $wmts->setRequestGetTileGETREST($getrest);
152: $getkvp = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[./ows:Constraint/ows:AllowedValues/ows:Value/text()='KVP']/@xlink:href", $getTile);
153: $wmts->setRequestGetTileGETKVP($getkvp);
154:
155:
156: }
157: unset($getTile);
158: $getFeatureInfo = $this->xpath->query("./ows:Operation[@name='GetFeatureInfo']", $operationsMetadata)->item(0);
159: if($getFeatureInfo != null){
160: $getrest = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[/ows:Constraint/ows:AllowedValues/ows:Value/text()='RESTful']/@xlink:href", $getFeatureInfo);
161:
162: $versionAtUrl = "/".$wmts->getVersion();
163: $pos = strripos($getrest, $versionAtUrl);
164: if ($pos!==false && $pos >= (strlen($getrest) - strlen($versionAtUrl) - 1)){
165: $getrest = substr($getrest, 0, $pos);
166: }
167: $wmts->setRequestGetFeatureInfoGETREST($getrest);
168: $getkvp = $this->getValue("./ows:DCP/ows:HTTP/ows:Get[/ows:Constraint/ows:AllowedValues/ows:Value/text()='KVP']/@xlink:href", $getFeatureInfo);
169: $wmts->setRequestGetFeatureInfoGETKVP($getkvp);
170:
171:
172: }
173: unset($getFeatureInfo);
174: }
175: unset($operationsMetadata);
176:
177:
178: $contents = $this->xpath->query("./wmts:Contents", $root)->item(0);
179: if($contents != null){
180: $layerlist = $this->xpath->query("./wmts:Layer", $contents);
181: foreach($layerlist as $layerEl) {
182: $layer = new WmtsLayerDetail();
183:
184: $layer->setTitle($this->getValue("./ows:Title/text()", $layerEl));
185: $layer->setAbstract($this->getValue("./ows:Abstract/text()", $layerEl));
186: $crs = array();
187: $bounds = array();
188:
189:
190:
191:
192: $bboxesEl = $this->xpath->query("./ows:BoundingBox", $layerEl);
193: foreach($bboxesEl as $bboxEl) {
194: $crsStr = $this->getValue("./@crs", $bboxEl);
195: $crs[] = $crsStr;
196: $bounds[$crsStr] = $this->getValue("./ows:BoundingBox/ows:LowerCorner/text()", $layerEl)
197: ." ". $this->getValue("./ows:BoundingBox/ows:UpperCorner/text()", $layerEl);
198: }
199: $layer->setCrs($crs);
200: $layer->setCrsBounds($bounds);
201:
202: $latlonbounds = $this->getValue("./ows:WGS84BoundingBox/ows:LowerCorner/text()", $layerEl)
203: ." ". $this->getValue("./ows:WGS84BoundingBox/ows:UpperCorner/text()", $layerEl);
204: $layer->setLatLonBounds($latlonbounds);
205: $crs84 = $this->getValue("./ows:WGS84BoundingBox/@crs", $layerEl);
206: $layer->setCrsLatLon($crs84);
207: if(count($crs) == 0) {
208: $layer->setDefaultCrs($this->getValue("./ows:WGS84BoundingBox/@crs", $layerEl));
209: }
210: unset($crs);
211: unset($crs84);
212: $layer->setIdentifier($this->getValue("./ows:Identifier/text()", $layerEl));
213:
214: $metadataUrlsEl = $this->xpath->query("./ows:Metadata", $layerEl);
215: $metadata = array();
216: foreach($metadataUrlsEl as $metadataUrlEl) {
217: $metadata[] = $this->getValue("./xlink:href", $metadataUrlEl);
218: }
219: $layer->setMetadataURL($metadata);
220: unset($metadata);
221: unset($metadataUrlsEl);
222:
223: $stylesEl = $this->xpath->query("./wmts:Style", $layerEl);
224: foreach($stylesEl as $styleEl) {
225: $layer->addStyle(
226: array(
227: "identifier"=>$this->getValue("./ows:Identifier/text()", $styleEl),
228: "title"=>$this->getValue("./ows:Title/text()", $styleEl),
229: "legendUrl"=> array (
230: "link" =>"")));
231: }
232: unset($stylesEl);
233:
234: $format = array();
235: $formatsEl = $this->xpath->query("./wmts:Format", $layerEl);
236: foreach($formatsEl as $formatEl) {
237: $format[] = $this->getValue("./text()", $formatEl);
238: }
239: $layer->setRequestDataFormats($format);
240:
241: $format = array();
242: $formatsEl = $this->xpath->query("./wmts:InfoFormat", $layerEl);
243: foreach($formatsEl as $formatEl) {
244: $format[] = $this->getValue("./text()", $formatEl);
245: }
246: $layer->setRequestInfoFormats($format);
247: unset($fromatsElmats);
248: unset($format);
249:
250: $tileMatrixSetLinks = array();
251: $tileMatrixSetLinksEl = $this->xpath->query("./wmts:TileMatrixSetLink", $layerEl);
252: foreach($tileMatrixSetLinksEl as $tileMatrixSetLinkEl) {
253:
254: $tileMatrixSetLinks[] = $this->getValue("./wmts:TileMatrixSet/text()", $tileMatrixSetLinkEl);
255: }
256: $layer->setTileMatrixSetLink($tileMatrixSetLinks);
257: $resourceURL = array();
258: $resourceURLsEl = $this->xpath->query("./wmts:ResourceURL", $layerEl);
259: foreach($resourceURLsEl as $resourceURLEl) {
260: $resourceURL[] = array(
261: "format" => $this->getValue("./@format", $resourceURLEl),
262: "resourceType" => $this->getValue("./@resourceType", $resourceURLEl),
263: "template" => $this->getValue("./@template", $resourceURLEl));
264: }
265: $layer->setResourceURL($resourceURL);
266: $wmts->getLayer()->add($layer);
267: }
268: unset($layerlist);
269: $tilematrixsetsEl = $this->xpath->query("./wmts:TileMatrixSet", $contents);
270: if($tilematrixsetsEl!=null) {
271: foreach($tilematrixsetsEl as $tilematrixsetEl) {
272: $tilematrixset = new TileMatrixSet();
273: $tilematrixset->setIdentifier($this->getValue("./ows:Identifier/text()", $tilematrixsetEl));
274: $tilematrixset->setTitle($this->getValue("./ows:Title/text()", $tilematrixsetEl));
275: $tilematrixset->setAbstract($this->getValue("./ows:Abstract/text()", $tilematrixsetEl));
276:
277: $srslist = $this->xpath->query("./ows:SupportedCRS", $tilematrixsetEl);
278: foreach($srslist as $srsEl) {
279: $tilematrixset->addSupportedSRS($this->getValue("./text()", $srsEl));
280: }
281:
282: $tilematrixset->setWellknowscaleset($this->getValue("./wmts:WellKnownScaleSet/text()", $tilematrixsetEl));
283:
284:
285: $tilematrixesEl = $this->xpath->query("./wmts:TileMatrix", $tilematrixsetEl);
286: if($tilematrixesEl!=null) {
287: foreach($tilematrixesEl as $tilematrixEl) {
288: $tilematrix = new TileMatrix();
289: $tilematrix->setIdentifier($this->getValue("./ows:Identifier/text()", $tilematrixEl));
290: $tilematrix->setScaledenominator($this->getValue("./wmts:ScaleDenominator/text()", $tilematrixEl));
291: $tilematrix->setTopleftcorner($this->getValue("./wmts:TopLeftCorner/text()", $tilematrixEl));
292: $tilematrix->setTilewidth($this->getValue("./wmts:TileWidth/text()", $tilematrixEl));
293: $tilematrix->setTileheight($this->getValue("./wmts:TileHeight/text()", $tilematrixEl));
294: $tilematrix->setMatrixwidth($this->getValue("./wmts:MatrixWidth/text()", $tilematrixEl));
295: $tilematrix->setMatrixheight($this->getValue("./wmts:MatrixHeight/text()", $tilematrixEl));
296: $tilematrixset->addTilematrix($tilematrix->getAsArray());
297: }
298: }
299: $wmts->addTtilematrixset($tilematrixset->getAsArray());
300: }
301: }
302: }
303: unset($contents);
304: $themes = $this->xpath->query("./wmts:Themes/wmts:Theme", $root);
305: if($themes != null){
306: foreach($themes as $themeEl) {
307: $theme = $this->findTheme(null, $themeEl);
308: $arr = $theme->getAsArray();
309: $wmts->addTheme($theme->getAsArray());
310: }
311: }
312: 313: 314: 315: 316: 317: 318: 319: 320: 321: 322: 323: 324: 325: 326: 327: 328: 329: 330:
331: return $wmts;
332: }
333:
334: private function findTheme($theme = null, $themeParentEl){
335:
336: $theme = $theme==null? new Theme():$theme;
337: $theme->setIdentifier($this->getValue("./ows:Identifier/text()", $themeParentEl));
338: $theme->setTitle($this->getValue("./ows:Title/text()", $themeParentEl));
339: $theme->setAbstract($this->getValue("./ows:Abstract/text()", $themeParentEl));
340: $theme->setLayerRef($this->getValue("./wmts:LayerRef/text()", $themeParentEl));
341: $subthemesEl = $this->xpath->query("./wmts:Theme", $themeParentEl);
342: if($subthemesEl != null) {
343: foreach($subthemesEl as $subthemeEl) {
344: $subelmname = $subthemeEl->localName;
345: $theme->addTheme($this->findTheme(new Theme(), $subthemeEl));
346: }
347: }
348: return $theme;
349: }
350: }
351: