NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/Chameleon/trunk/Chameleon/ExpressionBuilder/ExpressionBuilder.widget.php

Revision 13 (checked in by jcleary, 17 years ago)

Latest Chameleon code checkout from previous repository

Line 
1 <?php
2 /**
3  * ExpressionBuilder Widget Class
4  *
5  * @project     Chameleon
6  * @revision    $Id: ExpressionBuilder.widget.php,v 1.19 2004/10/14 18:19:09 pspencer Exp $
7  * @purpose     Display a dialog box to build expressions
8  * @author      DM Solutions Group (dev@dmsolutions.ca)
9  * @copyright
10  * <b>Copyright (c) 2003, DM Solutions Group Inc.</b>
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  */
29
30
31 include_once(dirname(__FILE__)."/../Widget.php");
32 include_once(dirname(__FILE__)."/../Button.php");
33 include_once(dirname(__FILE__)."/../Popup.php");
34
35 /**
36  * ExpressionBuilder
37  *
38  * @desc Display a widget that pops up a projection selection widget.
39  */
40 class ExpressionBuilder extends CWCWidget
41 {
42     var $moButton;
43     var $moPopup;
44
45     /**
46      * ExpressionBuilder
47      *
48      * Constctor method for the ExpressionBuilder
49      */
50     function ExpressionBuilder()
51     {
52         $this->mszLanguageResource = str_replace("\\","/",dirname(__FILE__))."/ExpressionBuilder.dbf";
53
54         parent::CWCWidget();
55
56         $this->moButton = new CWCButton( $this );
57         $this->moPopup = new CWCPopup( $this );
58         $this->moPopup->mszLink = $_SESSION['gszCoreWebPath']."/widgets/ExpressionBuilder/ExpressionBuilder.phtml";
59
60         // add sld attribute support (not yet implemented)
61         $this->maAttributes["SLD"] = new StringAttribute( "SLD", false );
62
63         // add like wildcard attributes
64         $this->maAttributes["WILDCARD"] = new StringAttribute( "WILDCARD", true );
65         $this->maAttributes["SINGLECHAR"] = new StringAttribute( "SINGLECHAR", true );
66         $this->maAttributes["ESCAPE"] = new StringAttribute( "ESCAPE", true );
67
68         // set the description for this widget
69         $this->szWidgetDescription = "The ExpressionBuilder widget displays a ".
70             "popup window that allows the user to interactively build ".
71             "expressions.";
72         $this->mnMaturityLevel = MATURITY_BETA;
73     }
74
75     function InitDefaults()
76     {
77         parent::InitDefaults();
78         //this widget should never belong to a toolset
79         $this->maParams["TOOLSET"] = "";
80         $this->moButton->InitDefaults();
81         $this->moButton->SetOnClick('clickExpressionBuilder');
82     }
83
84     /**
85      * SetMap
86      *
87      * Set the map session and create a navigation tool.
88      */
89     function SetMap($oMapSession)
90     {
91         $this->moMapObject = $oMapSession;
92     }
93
94
95     function GetJavascriptInitFunctions()
96     {
97         return $this->moButton->GetJavascriptInitFunctions();
98     }
99
100     function GetJavascriptVariables()
101     {
102         return $this->moButton->GetJavascriptVariables();
103     }
104
105     function GetJavascriptOnLoadFunctions()
106     {
107         $aReturn = parent::GetJavascriptOnLoadFunctions();
108
109         return $aReturn;
110     }
111
112         function GetJavascriptIncludeFunctions()
113     {
114         return $this->moButton->GetJavascriptIncludeFunctions();
115     }
116
117     /**
118      * GetHTMLHiddenVariables
119      */
120     function GetHTMLHiddenVariables()
121     {
122         // initialize return array
123         $aReturn = $this->moButton->GetHTMLHiddenVariables();
124
125         // setup the variables
126         $szVariable = 'WFS_FILTER';
127         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
128         $aReturn[$szVariable] = $szValue;
129         $szVariable = 'WFS_FILTER_LAYER_INDEX';
130         $szValue = " <INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
131         $aReturn[$szVariable] = $szValue;
132         $szVariable = 'WFS_FILTER_EXPRESSIONLIST';
133         $szValue = " <INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
134         $aReturn[$szVariable] = $szValue;
135         $szVariable = 'WFS_FILTER_APPLYTOMAP';
136         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
137         $aReturn[$szVariable] = $szValue;
138         $szVariable = 'WFS_FILTER_SLD';
139         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
140         $aReturn[$szVariable] = $szValue;
141         $szVariable = 'WFS_FILTER_SLD_FILE';
142         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
143         $aReturn[$szVariable] = $szValue;
144         $szVariable = 'WFS_FILTER_CONNECTION';
145         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
146         $aReturn[$szVariable] = $szValue;
147         $szVariable = 'WFS_FILTER_LAYERTYPE';
148         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
149         $aReturn[$szVariable] = $szValue;
150         $szVariable = 'WFS_FILTER_SLD_NAMEDLAYER';
151         $szValue = "<INPUT TYPE=HIDDEN NAME=$szVariable VALUE=\"\">\n";
152         $aReturn[$szVariable] = $szValue;
153         // return array of hidden variables
154         return $aReturn;
155     }
156
157     /**
158      * ParseURL
159      *
160      */
161     function  ParseURL()
162     {
163         // process WFS_FILTER_EXPRESSIONLIST
164         if ( $this->isVarSet("WFS_FILTER_EXPRESSIONLIST") &&
165             $this->isVarSet("WFS_FILTER_LAYER_INDEX") &&
166              strlen( $this->getVar("WFS_FILTER_LAYER_INDEX") ) > 0 )
167         {
168             // set metadata
169             $oLayer = $this->moMapObject->oMap->getlayer(
170                                $this->getVar("WFS_FILTER_LAYER_INDEX") );
171             $oLayer->setmetadata("cham_x_build_expressions",
172                                 $this->getVar("WFS_FILTER_EXPRESSIONLIST") );
173         }
174
175         // process the WFS filter if set
176         if ( $this->isVarSet("WFS_FILTER") &&
177              strlen( $this->getVar("WFS_FILTER") ) > 0 &&
178              $this->isVarSet("WFS_FILTER_LAYER_INDEX") &&
179              strlen( $this->getVar("WFS_FILTER_LAYER_INDEX") ) > 0 )
180         {
181             // get the layer object
182             $oLayer = $this->moMapObject->oMap->getlayer(
183                                    $this->getVar("WFS_FILTER_LAYER_INDEX") );
184             $_SESSION['expr_build_origin_layer'] = '';
185
186             // build the filter string
187             $szFilterString = $this->buildFilterString(
188                                       $this->getVar("WFS_FILTER"), $oLayer );
189
190             // check for and delete annotation layer
191             $nLayerCount = $this->moMapObject->oMap->numlayers;
192             for ( $i=0; $i<$nLayerCount$i++ )
193             {
194                 $oTempLayer = $this->moMapObject->oMap->getlayer($i);
195                 if ( $oTempLayer->name == 'ExpressionBuilderAnnotation'  )
196                 {
197                     $oTempLayer->set( 'status', MS_DELETE );
198                     break;
199                 }
200             }
201
202             // duplicate the layer
203             $oAnnoLayer = ms_newLayerObj( $this->moMapObject->oMap,
204                                                             $oLayer );
205             // reset orig layer name temporarily
206             $oLayer->set( 'name', $oLayer->name.'tmp_backup' );
207
208             // explcitly set to ON
209             $oAnnoLayer->set( 'status', MS_ON );
210
211             // set the template to an empty string to invalidate querying
212             $oAnnoLayer->set( 'template', '' );
213
214             // fix connection string to work around a caching problem
215             $szTmpConnection = $oAnnoLayer->connection . "&ttt=1";
216             $oAnnoLayer->set( 'connection', $szTmpConnection );
217
218             // apply the filter
219             $oAnnoLayer->setmetadata("wfs_filter", $szFilterString );
220
221             // check to see if the shared resource is specified and copy as necessary.
222             if ( isset( $this->maSharedResourceWidgets["expressionbuilderresults"] ) )
223             {
224                 $this->outputToShared( $oAnnoLayer );
225             }
226
227             // apply to map if necessary
228             if ( $this->isVarSet("WFS_FILTER_APPLYTOMAP") &&
229                  $this->getVar("WFS_FILTER_APPLYTOMAP") == 1 )
230             {
231                 // get the sld according to the selected name
232                 if ( $this->getVar("WFS_FILTER_SLD") !=
233                                                     'expressionbuilder_default' )
234                 {
235                     // set the url to the sld
236                     $szSLDURL = $this->getVar("WFS_FILTER_SLD_FILE");
237                 }
238                 else
239                 {
240                     // default
241                     if ( isset( $_SERVER['HTTPS'] ) &&
242                                     strcasecmp( $_SERVER['HTTPS'], "on" ) == 0 )
243                         $http = 'https://';
244                     else
245                         $http = 'http://';
246
247                     $szURI = $http.$_SERVER['HTTP_HOST'].
248                                      dirname($_SERVER['PHP_SELF']);
249
250                     $szSLDURL = $szURI.'/widgets/sld/expressionbuilder.sld';
251                 }
252                 //echo $szSLDURL."<BR>";
253                 // set the sld
254                 if ( isset( $szSLDURL ) )
255                 {
256                     // check the sld for proper url
257                     if ( substr( strtoupper( $szSLDURL ), 0, 4 ) == 'HTTP' )
258                     {
259                         // set annotation layer properties
260                         $oAnnoLayer->set( 'name', 'ExpressionBuilderAnnotation');
261                         $oAnnoLayer->setmetadata( 'selected', '0' );
262
263                         // select the new layer and save the origin layer ID.
264                         if( $oLayer->name != 'ExpressionBuilderAnnotation')
265                             $_SESSION['expr_build_origin_layer'] =
266                                 substr( $oLayer->name, 0, -10 );
267
268                         // flag the session variable
269                         $_SESSION['expr_build_filter_set'] = '1';
270
271                         // apply SLD according to layer type
272                         if ( $oLayer->connectiontype == MS_WMS )
273                         {
274                             // WMS
275                             // set the the sld body metadata so that classes are
276                             // used
277                              $oAnnoLayer->setmetadata( 'wms_sld_body', 'auto' );
278
279                             // update the wfs filter to be BBOX only
280                             $oAnnoLayer->setmetadata("wfs_filter",
281                                 $this->buildFilterString( 'BBOXONLY', $oLayer ) );
282
283                             // apply sld to create classes
284                             $oAnnoLayer->applysldurl( $szSLDURL,
285                                    $this->getVar('WFS_FILTER_SLD_NAMEDLAYER') );
286
287                             // re-init the layer
288                             $oAnnoLayer = $this->moMapObject->oMap->getlayer(
289                                                             $oAnnoLayer->index );
290
291                             // get first class
292                             if ( $oAnnoLayer->numclasses > 0 )
293                             {
294                                 // get first class
295                                 $oClass = $oAnnoLayer->getClass(0);
296
297                                 // get & set the expression of the class
298                                 if ( method_exists( $oAnnoLayer,
299                                                            'filterToExpression' ) )
300                                 {
301                                     // use mapscript function
302                                     $oClass->setExpression(
303                                         $oAnnoLayer->filterToExpression(
304                                                             $szFilterString ) );
305                                 }
306                                 else
307                                 {
308                                     // version of mapscript does not support
309                                     // so use own method
310                                     $aszTmpLayerInfo = $this->
311                                         filterToExpression( $szFilterString );
312
313                                     // set expression
314                                     $oClass->setExpression( $aszTmpLayerInfo[0] );
315
316                                     // set class item if necessary
317                                     if ( strlen( $aszTmpLayerInfo[1] ) > 0 )
318                                     {
319                                         $oAnnoLayer->set( 'classitem', $aszTmpLayerInfo[1] );
320                                     }
321                                     //echo $oAnnoLayer->generateSLD();
322                                 }
323                             }
324                         }
325                         else
326                         {
327                             // WFS
328                             $oAnnoLayer->applysldurl( $szSLDURL, $this->getVar('WFS_FILTER_SLD_NAMEDLAYER') );
329                         }
330                     }
331                     else
332                     {
333                         // give error
334                         $_SESSION['gErrorManager']->setError( ERR_WARNING,
335                             $this->moMLT->get("29", 'Invalid SLD URL.  Please ensure '.
336                             'that the URL is complete (not relative) and valid.' ) );
337                     }
338                 }
339                 else
340                 {
341                     // delete temp anno layer
342                     $oAnnoLayer->set( 'status', MS_DELETE );
343                 }
344             }
345             else
346             {
347                 // delete temp anno layer
348                 $oAnnoLayer->set( 'status', MS_DELETE );
349             }
350
351             // restore the layer's original name
352             $oLayer->set( 'name', substr( $oLayer->name, 0, -10 ) );
353         }
354
355         // return success
356         return true;
357     }
358
359     /**
360      * GetJavascriptFunctions
361      *
362      * Build and return the array of functions needed in the
363      * widget.
364      */
365     function GetJavascriptFunctions()
366     {
367         if (isset($this->maSharedResourceWidgets["CWCJSAPI"]))
368           $bCWCJSAPI = 1;
369         else
370           $bCWCJSAPI = 0;
371
372         // set the wildcard etc
373         if ( isset( $this->maParams["WILDCARD"] ) )
374             $szTmpWildcard = urlencode( $this->maParams["WILDCARD"] );
375         else
376             $szTmpWildcard = "";
377         if ( isset( $this->maParams["SINGLECHAR"] ) )
378             $szTmpSinglChar = urlencode( $this->maParams["SINGLECHAR"] );
379         else
380             $szTmpSinglChar = "";
381         if ( isset( $this->maParams["ESCAPE"] ) )
382             $szTmpEscape = urlencode( $this->maParams["ESCAPE"] );
383         else
384             $szTmpEscape = "";
385
386         // loop and get style names
387         $szStyles = $this->moMLT->get( '38','default (red points)' ).'@'.urlencode($_SESSION['gszCoreWebPath'].'/widgets/sld/expressionbuilder.sld').'@point@point|';
388         $szStyles .= $this->moMLT->get( '39','default (red lines)' ).'@'.urlencode($_SESSION['gszCoreWebPath'].'/widgets/sld/expressionbuilder.sld').'@line@line|';
389         $szStyles .= $this->moMLT->get( '40','default (red polygons)' ).'@'.urlencode($_SESSION['gszCoreWebPath'].'/widgets/sld/expressionbuilder.sld').'@polygon@polygon';
390
391         if ( isset( $this->maszContents['STYLE'] ) )
392         {
393             $nCount = count( $this->maszContents['STYLE'] );
394             for ( $i=0; $i<$nCount; $i++ )
395             {
396                 // add to style list
397                 if (!isset($this->maszContents['STYLE'][$i]['NAME']))
398                 {
399                     // set error handler and exit
400                     $_SESSION['gErrorManager']->setError( ERR_WARNING,
401                               $this->moMLT->get("34", "ERROR: ExpressionBuilder ".
402                               "widget missing mandatory NAME attribute in ".
403                               "STYLE declaration") );
404                 }
405                 else if (!isset($this->maszContents['STYLE'][$i]['SLD']))
406                 {
407                     // set error handler and exit
408                     $_SESSION['gErrorManager']->setError( ERR_WARNING,
409                               $this->moMLT->get("35", "ERROR: ExpressionBuilder ".
410                               "widget missing mandatory SLD attribute in ".
411                               "STYLE declaration") );
412                 }
413                 else if (!isset($this->maszContents['STYLE'][$i]['NAMEDLAYER']))
414                 {
415                     // set error handler and exit
416                     $_SESSION['gErrorManager']->setError( ERR_WARNING,
417                               $this->moMLT->get("36", "ERROR: ExpressionBuilder ".
418                               "widget missing mandatory NAMEDLAYER attribute in ".
419                               "STYLE declaration") );
420                 }
421                 else if (!isset($this->maszContents['STYLE'][$i]['LAYERTYPE']))
422                 {
423                     // set error handler and exit
424                     $_SESSION['gErrorManager']->setError( ERR_WARNING,
425                               $this->moMLT->get("37", "ERROR: ExpressionBuilder ".
426                               "widget missing mandatory LAYERTYPE attribute in ".
427                               "STYLE declaration") );
428                 }
429                 else
430                 {
431                     $szStyles .= '|'.$this->maszContents['STYLE'][$i]['NAME'];
432                     $szStyles .= '@'.urlencode( $this->maszContents['STYLE'][$i]['SLD'] );
433                     $szStyles .= '@'.$this->maszContents['STYLE'][$i]['NAMEDLAYER'];
434                     $szStyles .= '@'.$this->maszContents['STYLE'][$i]['LAYERTYPE'];
435                 }
436             }
437         }
438
439         $aReturn = $this->moButton->GetJavascriptFunctions();//array();
440         $this->moPopup->mszLink = $_SESSION['gszCoreWebPath']."/widgets/ExpressionBuilder/ExpressionBuilder.phtml?wildcard=".
441            $szTmpWildcard."&singlechar=".
442            $szTmpSinglChar."&escape=".
443            $szTmpEscape.'&styles='.
444            $szStyles."&selectedlayers=' + szSelectedLayers + ' ";
445         $szJsFunctionName = "clickExpressionBuilder";
446         $szButtonJS = $this->moPopup->DrawPublish();
447         $szFunction = <<<EOT
448 /**
449  * {$szJsFunctionName}
450  * popup a expression builder dialog
451  */
452 function {$szJsFunctionName}()
453 {
454     // set the var
455     if ( {$this->mszHTMLForm}.SELECTED_LAYERS )
456         szSelectedLayers = {$this->mszHTMLForm}.SELECTED_LAYERS.value;
457     else
458         szSelectedLayers = "";
459
460     {$szButtonJS}
461     return;
462 }
463 EOT;
464         $aReturn[$szJsFunctionName] = $szFunction;
465
466         // add the apply javascript code to apply the filter
467         $szJsFunctionName = "applyWFSFilter";
468         $szFunction = <<<EOT
469 /**
470  * {$szJsFunctionName}
471  * Apply the WFS filter
472  */
473 function {$szJsFunctionName}( szFilter, nLayerIndex, szExpressions, nApplyToMap,
474                             szSLDName, szWFSConnection, szLayerType )
475 {
476     // set the hidden form vars
477     {$this->mszHTMLForm}.WFS_FILTER.value = escape( szFilter );
478     {$this->mszHTMLForm}.WFS_FILTER_LAYER_INDEX.value = nLayerIndex;
479     {$this->mszHTMLForm}.WFS_FILTER_EXPRESSIONLIST.value = szExpressions;
480     {$this->mszHTMLForm}.WFS_FILTER_APPLYTOMAP.value = nApplyToMap;
481
482     // split the sld name and file
483     var aszTmpArray = szSLDName.split('@');
484
485     {$this->mszHTMLForm}.WFS_FILTER_SLD.value = aszTmpArray[0];
486     {$this->mszHTMLForm}.WFS_FILTER_SLD_FILE.value = aszTmpArray[1];
487     {$this->mszHTMLForm}.WFS_FILTER_SLD_NAMEDLAYER.value =aszTmpArray[2];
488
489     {$this->mszHTMLForm}.WFS_FILTER_CONNECTION.value = szWFSConnection;
490     {$this->mszHTMLForm}.WFS_FILTER_LAYERTYPE.value = szLayerType;
491
492     // submit the form
493     if ( 1 == {$bCWCJSAPI} )
494     {
495         goCWCJSAPI.oMap.oApplication.UpdateExpressionBuilder( escape( szFilter ),
496             nLayerIndex, szExpressions, nApplyToMap, aszTmpArray[0], szWFSConnection,
497             szLayerType, aszTmpArray[1] );
498     }
499     else
500         {$this->mszHTMLForm}.submit();
501
502     // return
503     return;
504 }
505 EOT;
506
507         $aReturn[$szJsFunctionName] = $szFunction;
508
509         // add the apply javascript code to apply the filter
510         $szJsFunctionName = "saveExpressions";
511         $szFunction = <<<EOT
512 /**
513  * {$szJsFunctionName}
514  * Save Expressions
515  */
516 function {$szJsFunctionName}( nLayerIndex, szExpressions )
517 {
518     // set the hidden form vars
519     {$this->mszHTMLForm}.WFS_FILTER_LAYER_INDEX.value = nLayerIndex;
520     {$this->mszHTMLForm}.WFS_FILTER_EXPRESSIONLIST.value = szExpressions;
521
522     // submit the form
523     {$this->mszHTMLForm}.submit();
524
525     // return
526     return;
527 }
528 EOT;
529
530         $aReturn[$szJsFunctionName] = $szFunction;
531
532         // return the array of functions
533         return $aReturn;
534
535     }
536
537     /**
538      * DrawPublish
539      *
540      * Return the HTML code using the name in the map file and the
541      * parameters of the CWC tag.
542      */
543     function DrawPublish()
544     {
545         if (!$this->mbVisible)
546         {
547             return "<!-- ExpressionBuilder popup widget hidden -->";
548         }
549
550         $szResult = $this->moButton->DrawPublish();
551
552         return $szResult;
553     }
554
555 /**
556  * pareseQueryResults()
557  *
558  * Postcondition:  This function reads the give and parses it reporting any error
559  *                 conditions and passes the results to a shared resource.
560  * Precondition:   This function assumes the shared resource exists.
561  *
562  * @param $szFile string - The file to parse.
563  * @param $szLayer string - Layer to parse.
564  * @param $oMLT object - Language object to use.
565  * @return boolean - true if successful, false if not;
566  * @desc Reads and parses given file and passes results to shared resource and reports errors
567  *
568  **/
569     function parseQueryResults( $szFile, $szLayer, $oMLT )
570     {
571         // int vars
572         $data = "";
573
574         // read the xml datasource
575         $aszFile = file( $szFile );
576
577         // check to see if an error was generated
578         if ( !is_array( $aszFile ) ||
579              strpos( strtoupper( $aszFile[0] ), '<SERVICEEXCEPTIONREPORT' ) !== false )
580         {
581             // give error
582             if ( !is_array( $aszFile ) )
583                 $szServerDump = $aszFile;
584             else
585             {
586                 $szServerDump = "";
587                 foreach(  $aszFile as $line )
588                     $szServerDump .= $line;
589             }
590
591             // set error handler and exit
592             $_SESSION['gErrorManager']->setError( ERR_WARNING, $oMLT->get("21", "WFS 'DescribeFeatureType' request failed.  ".
593                             "The server returned the following: %1\$s", array( $szServerDump ) ) );
594             return false;
595         }
596
597         // process url
598         foreach( $aszFile as $line )
599         {
600             // process line
601             $data .= $line;
602         }
603         //echo "data is $data<BR>";
604         // parse
605         $parser = xml_parser_create();
606         xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
607         xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
608         xml_parse_into_struct($parser,$data,$values,$tags);
609         xml_parser_free($parser);
610
611         // loop through the structures and process the layer name
612         foreach ($tags as $key=>$val)
613         {
614             //echo "processing $key=>$val for layer $szLayer<BR>";
615             // process layer name
616             if ( strtoupper( $key ) == strtoupper( $szLayer ) )
617             {
618                 //echo "here<BR>";
619                 $ranges = $val;
620                 // each contiguous pair of array entries are the
621                 // lower and upper range for each layer definition
622                 $nCount = count($ranges);
623                 for ($i=0; $i < $nCount; $i+=2)
624                 {
625                     $offset = $ranges[$i] + 1;
626                     $len = $ranges[$i + 1] - $offset;
627                     $this->parseElements( array_slice($values, $offset, $len ), $szLayer );
628                 }
629             }
630             else
631             {
632                 // otherwise skip
633                 continue;
634             }
635         }
636
637         // return
638         return true;
639
640     // end parseQueryResults
641     }
642
643 /**
644  * parseElements()
645  *
646  * Postcondition:  This function parses the given array returns an array of
647  *                 attribute->type pairs.
648  *
649  * @param axValues Array - Mixed array of XML tags to process.
650  * @param szLayer String - Layer name.
651  * @return boolean - True if successful, false if not.
652  * @desc Parses array and sets shared resource
653  */
654     function parseElements( $axValues, $szLayer )
655     {
656         // init shared resource
657         //echo "parseElements<BR>";
658         if (!isset($this->maSharedResourceWidgets['expressionbuilderresults']->maszContents['RESULT'][$szLayer]))
659         {
660           //echo "making array<BR>";
661           $this->maSharedResourceWidgets['expressionbuilderresults']->maszContents['RESULT'][$szLayer] = array();
662         }
663         //echo $szLayer."<BR>";
664         //print_r($axValues);
665         // loop through each item of the array
666         $aResult = array();
667         $nCount = count( $axValues );
668         $j = 0;
669         for ( $i=0; $i < $nCount; $i++ )
670         {
671             //echo "processing count $i<BR>";
672             // only process all non "gml..." values
673             if ( strtoupper( substr( $axValues[$i]["tag"], 0, 3 ) ) != "GML" )
674             {
675                 //echo "in if ($i)<BR>";
676                 // add to shared resource
677                 $aResult[$j]['attribute'] = $axValues[$i]['tag'];
678                 if ( isset( $axValues[$i]['value'] ) )
679                     $aResult[$j]['value'] = $axValues[$i]['value'];
680                 $j++;
681             }
682         }
683         array_push( $this->maSharedResourceWidgets['expressionbuilderresults']->maszContents['RESULT'][$szLayer], $aResult );
684
685         // return
686         return true;
687
688     // end parseElements() function
689     }
690
691 /**
692  * buildFilterString
693  *
694  * Postcondition:  This function takes the given expression and layer object
695  *                 and creates a proper wfs filter string.
696  *
697  * @param $szExpression String - The expression string returned by the popup dialog
698  * @param $oLayer object - The layer to apply the expression to.
699  * @return String - Filter string.
700  * @desc Builds and returns a properly formatted wfs filter string.
701  **/
702     function buildFilterString( $szExpression, $oLayer )
703     {
704         // get projection
705         $szProjection = trim( $oLayer->getprojection() );
706         if ( strlen( $szProjection ) <= 0 )
707             $szProjection = trim( $this->moMapObject->oMap->getprojection() );
708         if ( strlen( $szProjection ) > 0 )
709         {
710             $szProjection = substr( $szProjection, 5 );
711             $szProjection = str_replace( 'epsg', 'EPSG', $szProjection );
712         }
713         if ( substr( $szProjection, 0, 4 ) != 'EPSG' )
714         {
715             $szProjection = '';
716         }
717
718         // urldecode the filter if necessary
719         if ( $szExpression != "BBOXONLY" )
720         {
721             $szDecodeFilter = urldecode( $szExpression );
722             $szAndOpen = "<AND>";
723             $szAndClose = "</AND>";
724         }
725         else
726         {
727             $szDecodeFilter = "";
728             $szAndOpen = "";
729             $szAndClose = "";
730         }
731
732         // check for AOI
733         if ( isset( $_SESSION['ROIRENDERER'] ) &&
734              is_array( $_SESSION['ROIRENDERER'] ) &&
735              count( $_SESSION['ROIRENDERER'] ) > 0 )
736         {
737             // loop and build the filter string based on the ROI
738             $bNotFirstExpression = false;
739             $szBbox = '';
740             foreach( $_SESSION['ROIRENDERER'] as $szTmpROI )
741             {
742                 // process based on type
743                 $szThisBbox = '';
744                 switch ( strtoupper($szTmpROI['type'] ) )
745                 {
746                     case 'RECTANGLE':
747                         $szThisBbox = buildRectFilter( $szTmpROI['aGeoCoords'],
748                                                                 $szProjection );
749                         break;
750                     case 'CIRCLE':
751                         $szThisBbox = buildCircleFilter( $szTmpROI['aGeoCoords'],
752                             $szTmpROI['aGeoCoords'][2]-$szTmpROI['aGeoCoords'][0] );
753                         break;
754                     case 'POLYGON':
755                         $szThisBbox = buildPolygonFilter( $szTmpROI['aGeoCoords'] );
756                         break;
757                     default:
758                         $szBbox .= '';
759                 }
760
761                 // decide how to add to ROI
762                 if ( $bNotFirstExpression )
763                 {
764                     switch( $szTmpROI['mode'] )
765                     {
766                         // additive
767                         case 2:
768                             $szBbox = '<OR>'.$szBbox.$szThisBbox.'</OR>';
769                             break;
770                         // subtractive
771                         case 3:
772                             $szBbox = '<AND>'.$szBbox.'<NOT>'.$szThisBbox.'</NOT></AND>';
773                             break;
774                     }
775                 }
776                 else
777                     $szBbox .= $szThisBbox;
778
779                 // set flag
780                 $bNotFirstExpression = true;
781             }
782         }
783         else
784         {
785             // use current extents as bbox
786             $szBbox = buildRectFilter(
787                         array( $this->moMapObject->oMap->extent->minx,
788                                $this->moMapObject->oMap->extent->miny,
789                                $this->moMapObject->oMap->extent->maxx,
790                                $this->moMapObject->oMap->extent->maxy ),
791                         $szProjection );
792         }
793
794         // return the filter string
795         return $szAndOpen.$szBbox.$szDecodeFilter.$szAndClose;
796
797     // end of buildFilterString function
798     }
799
800 /**
801   _____________________________________________________________________________
802  |
803  |  Postcondition:  This function executes the WFSGetFeature request and
804  |                  outputs the results to a shared resource.
805  |
806  |  @param $oLayer object - The layer to output.
807  |  @return boolean - True if successful, false if not.
808  |  @desc Output features to shared resource.
809  |_____________________________________________________________________________
810
811  **/
812     function outputToShared( $oLayer )
813     {
814         // init vars
815         $bIsWMSLayer = false;
816         $szWMSConnection = '';
817
818         // convert to WFS layer is necessary
819         if ( $oLayer->connectiontype == MS_WMS )
820         {
821             $bIsWMSLayer = true;
822             $szWMSConnection = $oLayer->connection;
823             $oLayer->set( 'connectiontype', MS_WFS );
824             $oLayer->set( 'connection', $this->getVar('WFS_FILTER_CONNECTION') );
825             eval( '$oLayer->set( "type", '.
826                                 $this->getVar('WFS_FILTER_LAYERTYPE').' );' );
827         }
828
829         // create the gml file to parse into a shared resource
830         $szTmpGML = $oLayer->executeWFSGetfeature();
831
832         // check if the file exists
833         if ( file_exists( $szTmpGML ) )
834         {
835             // read the file, parse it and pass it to the shared resource
836             $this->parseQueryResults( $szTmpGML, $oLayer->name,
837                                                           $this->moMLT );
838             // delete the file
839             unlink( $szTmpGML );
840         }
841
842         // reset the connection info
843         if ( $bIsWMSLayer )
844         {
845             $oLayer->set( 'connectiontype', MS_WMS );
846             $oLayer->set( 'connection', $szWMSConnection );
847             $oLayer->set( 'type', MS_LAYER_RASTER );
848         }
849
850         // return success
851         return true;
852
853     // end outputToShared()
854     }
855
856 /**
857   _____________________________________________________________________________
858  |
859  |  Postcondition:  This function converts the given filter string to a valid
860  |                  class expression.
861  |
862  |  @param $szFilter string - Filter string to convert.
863  |  @return array - Class expression (index 0) and ClassItem (index 1).
864  |  @desc Converts filter string to class expression.
865  |_____________________________________________________________________________
866
867  **/
868     function filterToExpression( $szFilter )
869     {
870         // init vars
871         $szLayerName = 'expressionbuildertempsld';
872         $aszReturn = array( '', '' );
873
874         // create new temp layer
875         $oTmpLayer = ms_newLayerObj( $this->moMapObject->oMap );
876         $oTmpLayer->set( 'name', $szLayerName );
877         $oTmpLayer->set( 'type', MS_LAYER_POINT );
878
879         // convert filter to valid sld
880         $szSLD = '<StyledLayerDescriptor version="1.0.0">'.
881                    '<NamedLayer>'.
882                      '<Name>'.$szLayerName.'</Name>'.
883                        '<UserStyle>'.
884                          '<FeatureTypeStyle>'.
885                            '<Rule>'.
886                              '<Filter>'.
887                                $szFilter.
888                              '</Filter>'.
889                              '<PointSymbolizer>
890                                 <Graphic>
891                                   <Size>5</Size>
892                                   <Mark>
893                                     <WellKnownName>square</WellKnownName>
894                                     <Fill>
895                                       <CssParameter name="fill">#ff0000</CssParameter>
896                                     </Fill>
897                                   </Mark>
898                                 </Graphic>
899                               </PointSymbolizer>'.
900                             '</Rule>'.
901                           '</FeatureTypeStyle>'.
902                         '</UserStyle>'.
903                       '</NamedLayer>'.
904                     '</StyledLayerDescriptor>';
905
906         // apply sld to layer to create classes
907         $oTmpLayer->applySLD( $szSLD, $szLayerName );
908
909         // re-init layer
910         $oTmpLayer = $this->moMapObject->oMap->getlayer( $oTmpLayer->index );
911
912         // get first class
913         if ( $oTmpLayer->numclasses > 0 )
914         {
915             // get first class
916             $oClass = $oTmpLayer->getClass(0);
917
918             // get expression
919             $aszReturn[0] = $oClass->getExpression();
920
921             // get the class item
922             $aszReturn[1] = $oTmpLayer->classitem;
923         }
924
925         // delete temp layer
926         $oTmpLayer->set( 'status', MS_DELETE );
927
928         // return expression
929         return $aszReturn;
930
931     // end filterToExpression()
932     }
933
934 }
935
936 function buildRectFilter( $adCoords, $szProjection )
937 {
938      return '<BBOX><PropertyName>Name</PropertyName>'.
939                 "<gml:Box srsName='".$szProjection."'><coordinates>".
940                 $adCoords[0].','.
941                 $adCoords[1].' '.
942                 $adCoords[2].','.
943                 $adCoords[3].
944                 '</coordinates></gml:Box></BBOX>';
945 }
946
947 function buildCircleFilter( $adCoords, $dDistance )
948 {
949     return '<DWithin><PropertyName>Name</PropertyName><gml:Point>'.
950            '<gml:coordinates>'.$adCoords[0].','.$adCoords[1].
951            '</gml:coordinates></gml:Point><Distance '.
952            "units='http://www.uomdict.com/uom.html#meters'>".
953            $dDistance.'</Distance></DWithin>';
954 }
955
956 function buildPolygonFilter( $adCoords )
957 {
958     $szReturn = '<Intersect><PropertyName>Name</PropertyName><gml:Polygon>'.
959                 '<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>';
960
961     // loop and build list of coordinates
962     $nCount = count( $adCoords );
963     $szCoords = '';
964     for( $i=0; $i<$nCount; $i=$i+2 )
965     {
966         $szCoords .= $adCoords[$i].','.$adCoords[$i+1].' ';
967     }
968     $szReturn .= trim( $szCoords );
969     $szReturn .= '</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>'.
970                  '</gml:Polygon></Intersect>';
971     return $szReturn;
972 }
973 ?>
974
Note: See TracBrowser for help on using the browser.