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

root/Chameleon/trunk/Chameleon/TrueNorth/TrueNorth.widget.php

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

Latest Chameleon code checkout from previous repository

Line 
1 <?php
2 /**
3  * TrueNorth Widget class
4  *
5  * @project     CWC2
6  * @revision    $Id: TrueNorth.widget.php,v 1.11 2005/01/11 16:20:24 pspencer Exp $
7  * @purpose     Zoom In Widget class
8  * @author      DM Solutions Group (sfournier@dmsolutions.ca)
9  * @copyright
10  * <b>Copyright (c) 2002, 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
33 /**
34  * TrueNorth
35  *
36  * @desc Display a bitmap indicating true north
37  */
38 class TrueNorth extends CWCWidget
39 {
40     var $mszTrueNorthImage = "";
41     var $mszImage = "";
42     var $mnWidth = "";
43     var $mnHeight = "";
44
45     /**
46      * TrueNorth
47      *
48      * Constructor. Set the default values.
49      */
50     function TrueNorth()
51     {
52         // invoke constructor of parent
53         parent::CWCWidget();
54
55         // User defined true north image to use
56         $this->maAttributes["TRUENORTHIMAGE"] = new StringAttribute("TRUENORTHIMAGE", true);
57
58         // This should be executed after navtool
59         $this->mnPriority = PRIORITY_LAST;
60
61         // set the description for this widget
62         $this->szWidgetDescription = <<<EOT
63 The TrueNorth widget just display a bitmap rotated indicating the real north.
64 EOT;
65         $this->mnMaturityLevel = MATURITY_BETA;
66     }
67
68     /**
69      * Initialize some cnfiguration parameter
70      */
71     function InitDefaults()
72     {
73         parent::InitDefaults();
74         $oApp = GetChameleonApplication();
75         
76         if (isset( $this->maParams["TRUENORTHIMAGE"]) && $this->maParams['TRUENORTHIMAGE'] != '')
77             $this->mszTrueNorthImage = $oApp->findFile( $this->maParams["TRUENORTHIMAGE"] );
78         if (!$this->mszTrueNorthImage)
79         {
80             $_SESSION['gErrorManager']->setError( ERR_CRITICAL, "TrueNorth: ".$this->maParams["TRUENORTHIMAGE"]." cannot be found." );
81             $this->mszTrueNorthImage = '';
82         }
83     }
84
85     /**
86      * Steps:
87      *        - Create a rectangle with extent of the map.
88      *        - Reproject the rectangle in degrees.
89      *        - create 2 points (vertical line) using the same x
90      *          (middle of the image) but use 2 different Y distanced
91      *          by 20 pixels.
92      *        - Reproject those 2 points in original projection.
93      *        - Calculate the angle of point1 relatively to point2.
94      *        - Load and rotate the True North image.
95      */
96     function  ParseURL()
97     {
98         parent::ParseURL();
99
100         if ($this->mszTrueNorthImage == '')
101         {
102             $_SESSION['gErrorManager']->setError( ERR_CRITICAL, "TrueNorth: invalid or no image specified." );
103             return false;
104         }
105             
106         if ( PHP_OS == "WINNT" || PHP_OS == "WIN32" )
107             $szGDModule = "php_gd2.dll";
108         else
109             $szGDModule = "php_gd2.so";
110
111         if (!extension_loaded("gd"))
112             dl($szGDModule);
113
114         $oMap = $this->moMapObject->oMap;
115         
116         // Get current projection
117         $szTmpMapProj = $oMap->getProjection();
118
119         // If the map does not have any projection, it's
120         // impossible to draw true north.
121         if ($szTmpMapProj === false)
122             return false;
123
124         $projInObj = ms_newprojectionobj( $szTmpMapProj );
125         $projOutObj = ms_newprojectionobj("init=epsg:4326");
126
127         // Get map extent and reproject in degrees
128         $oRect = ms_newrectobj();
129         $oRect->setExtent($oMap->extent->minx, $oMap->extent->miny,
130                           $oMap->extent->maxx, $oMap->extent->maxy);
131
132         if (strcasecmp("init=epsg:4326", $szTmpMapProj) != 0)
133             $oRect->project($projInObj, $projOutObj);
134
135         // Create 2 points that represent a straight line (vertical)
136         $nMinY = $this->pixel_to_geo($oMap->height/2-10, 0, $oMap->height,
137                                      $oRect->miny, $oRect->maxy);
138
139         $nMaxY = $this->pixel_to_geo($oMap->height/2+10, 0, $oMap->height,
140                                      $oRect->miny, $oRect->maxy);
141
142         $poPoint1 = ms_newpointobj();
143         $poPoint2 = ms_newpointobj();
144         $poPoint1->setXY(($oRect->maxx - $oRect->minx)/2+$oRect->minx, $nMaxY);
145         $poPoint2->setXY($poPoint1->x, $nMinY);
146
147         if (strcasecmp("init=epsg:4326", $szTmpMapProj) != 0)
148         {
149             // Reproject points back to original projection
150             $poPoint1->project($projOutObj, $projInObj);
151             $poPoint2->project($projOutObj, $projInObj);
152         }
153
154         // Calculate angle
155         $nTop = ($poPoint1->y-$poPoint2->y);
156         $nDeltaX = ($poPoint1->x-$poPoint2->x);
157         $nDeltaY = ($poPoint1->y-$poPoint2->y);
158         $nBottom = sqrt( $nDeltaX*$nDeltaX + $nDeltaY*$nDeltaY);
159         if ($nBottom == 0)
160         {
161             $nDeg = 90;
162         }
163         else
164         {
165             $nDeg rad2deg(asin($nTop/$nBottom));
166         }
167
168         if ($poPoint1->x-$poPoint2->x<0)
169             $szFileName = $this->drawSymbolRotated(90-$nDeg);
170         else
171             $szFileName = $this->drawSymbolRotated(-1*(90-$nDeg));
172
173         $this->mszImage = "<IMG src=\"".$_SESSION['gszTmpWebPath']."/".
174                            basename($szFileName)."\" width=\"".$this->mnWidth.
175                            "\" height=\"".$this->mnHeight."\">\n";
176
177         // return success
178         return true;
179     }
180
181     function drawSymbolRotated($nDeg)
182     {
183         $szSufix = strtoupper(substr($this->mszTrueNorthImage, -3));
184         if ($szSufix=="PNG")
185         {
186             $oImg = imagecreatefrompng($this->mszTrueNorthImage);
187         }
188         else
189         {
190             if ($szSufix=="GIF")
191             {
192                 $oImg = imagecreatefromgif($this->mszTrueNorthImage);
193             }
194             else
195             {
196                 if ($szSufix=="JPG")
197                 {
198                     $oImg = imagecreatefromjpeg($this->mszTrueNorthImage);
199                 }
200                 else
201                 {
202                     $oImg = imagecreatefrompng($this->mszTrueNorthImage);
203                 }
204             }
205         }
206
207         $this->mnWidth = imagesx($oImg);
208         $this->mnHeight = imagesy($oImg);
209         
210         $oMap = ms_newMapObj("");
211         $oMap->selectOutputFormat("PNG24");
212         $oMap->set("width", $this->mnWidth);
213         $oMap->set("height", $this->mnHeight);
214         $oMap->setExtent(0, 0, $this->mnWidth, $this->mnHeight);
215
216         $oLayer = ms_newLayerObj($oMap);
217         $oLayer->set("transform", MS_FALSE);
218         $oLayer->set("type", MS_LAYER_POINT);
219
220         $oImage = $oMap->prepareimage();
221
222         $oClass = ms_newClassObj($oLayer);
223
224         $nSymbol = ms_newSymbolObj($oMap, $this->mszTrueNorthImage);
225         $oStyle = ms_newStyleObj($oClass);
226         $oStyle->set("symbol", $nSymbol);
227
228         $oi = $oClass->createLegendIcon($this->mnWidth, $this->mnHeight);
229
230         $oImage->pasteImage($oi,0, $this->mnWidth/2, $this->mnHeight/2, $nDeg);
231
232         $szTmpDir = $_SESSION['gszTmpImgPath'];
233         if (substr($szTmpDir, -1) == "/")
234             $szTmpDir = substr($szTmpDir, 0, -1 );
235
236         $szFileName = str_replace("\\", "/", tempnam($szTmpDir, "TN").".png");
237
238         $oImage->saveImage($szFileName);
239
240         return $szFileName;
241     }
242
243     function drawPublish()
244     {
245         return $this->mszImage;
246     }
247
248     /**
249      * convert a pixel position to geocoded position
250      *
251      * @param nPixPos double pixel position
252      * @param dfPixMin double minimum map pixel value
253      * @param dfPixMax double maximum map pixel value
254      * @param dfGeoMin double minimum map geocoded value
255      * @param dfGeoMax double maximum map geocoded value
256      * @param nInversePix integer optional flag to inverse , set to 1 for
257      *                            Y pixel coordinates where UL > LR
258      * @return double geocoded position
259      */
260     function pixel_to_geo($nPixPos, $dfPixMin, $dfPixMax, $dfGeoMin, $dfGeoMax,
261                           $nInversePix = "")
262     {
263         // calculate the geocoded & pixel width
264         $dfWidthGeo = $dfGeoMax - $dfGeoMin;
265         $dfWidthPix = $dfPixMax - $dfPixMin;
266
267         // get ratio
268         $dfPixToGeo = $dfWidthGeo / $dfWidthPix;
269
270     // get difference
271         if (!$nInversePix)
272             $dfDeltaPix = $nPixPos - $dfPixMin;
273         else
274             $dfDeltaPix = $dfPixMax - $nPixPos;
275
276         // calculate
277         $dfDeltaGeo = $dfDeltaPix * $dfPixToGeo;
278         $dfPosGeo = $dfGeoMin + $dfDeltaGeo;
279
280         // return value
281         return ($dfPosGeo);
282
283         // end pixel_to_geo function
284     }
285
286     /**
287      * convert a geocoded position to pixel coord
288      *
289      * @param nGeoPos double Geocoded position
290      * @param dfPixMin double minimum map pixel value
291      * @param dfPixMax double maximum map pixel value
292      * @param dfGeoMin double minimum map geocoded value
293      * @param dfGeoMax double maximum map geocoded value
294      * @param nInverseGeo integer optional flag to inverse , set to 1 for
295      *                            Y pixel coordinates where UL > LR
296      * @return double geocoded position
297      */
298      function geo_to_pixel ($nGeoPos, $dfPixMin, $dfPixMax, $dfGeoMin,
299                     $dfGeoMax, $nInverseGeo = "")
300      {
301          // calculate the geocoded & pixel width
302      $dfWidthGeo = abs($dfGeoMax - $dfGeoMin);
303      $dfWidthPix = abs($dfPixMax - $dfPixMin);
304                                                                                                           
305      // get ratio
306      $dfGeoToPix = $dfWidthPix / $dfWidthGeo;
307                                                                                                             
308      // get difference
309      if (!$nInverseGeo)
310          $dfDeltaGeo = $nGeoPos - $dfGeoMin;
311          else
312          $dfDeltaGeo = $dfGeoMax - $nGeoPos;
313                                                                                                             
314      // calculate
315      $dfDeltaPix = $dfDeltaGeo * $dfGeoToPix;
316      $dfPosPix = $dfPixMin + $dfDeltaPix;
317                                                                                                           
318      // return value
319      return round ($dfPosPix);
320      // end pixel_to_geo function
321     }
322
323 }
324 ?>
325
Note: See TracBrowser for help on using the browser.