]> git.openstreetmap.org Git - nominatim.git/blob - lib/template/search-html.php
return a marginally better error message when query string is not in UTF-8,
[nominatim.git] / lib / template / search-html.php
1 <?php
2         header("content-type: text/html; charset=UTF-8");
3 ?>
4 <html>
5 <head>
6         <title>OpenStreetMap Nominatim: Search</title>
7
8         <base href="<?php echo CONST_Website_BaseURL;?>" />
9         <link href="nominatim.xml" rel="search" title="Nominatim Search" type="application/opensearchdescription+xml" />
10
11         <script src="js/OpenLayers.js"></script>
12         <script src="js/tiles.js"></script>
13         <script src="js/prototype-1.6.0.3.js"></script>
14
15         <style>
16 * {-moz-box-sizing: border-box;}
17 body {
18   margin:0px;
19   padding:0px;
20   overflow: hidden;
21   background:#ffffff;
22   height: 100%;
23   font: normal 12px/15px arial,sans-serif;
24 }
25 #seachheader {
26   position:absolute;
27   z-index:5;
28   top:0px;
29   left:0px;
30   width:100%;
31   height:38px;
32   background:#F0F7FF;
33   border-bottom: 2px solid #75ADFF;
34 }
35 #q {
36   width:300px;
37 }
38 #seachheaderfade1, #seachheaderfade2, #seachheaderfade3, #seachheaderfade4{
39   position:absolute;
40   z-index:4;
41   top:0px;
42   left:0px;
43   width:100%;
44   opacity: 0.15;
45   filter: alpha(opacity = 15);
46   background:#000000;
47   border: 1px solid #000000;
48 }
49 #seachheaderfade1{
50   height:39px;
51 }
52 #seachheaderfade2{
53   height:40px;
54 }
55 #seachheaderfade3{
56   height:41px;
57 }
58 #seachheaderfade4{
59   height:42px;
60 }
61 #searchresultsfade1, #searchresultsfade2, #searchresultsfade3, #searchresultsfade4 {
62   position:absolute;
63   z-index:2;
64   top:0px;
65   left:200px;
66   height: 100%;
67   opacity: 0.2;
68   filter: alpha(opacity = 20);
69   background:#ffffff;
70   border: 1px solid #ffffff;
71 }
72 #searchresultsfade1{
73   width:1px;
74 }
75 #searchresultsfade2{
76   width:2px;
77 }
78 #searchresultsfade3{
79   width:3px;
80 }
81 #searchresultsfade4{
82   width:4px;
83 }
84
85 #searchresults{
86   position:absolute;
87   z-index:3;
88   top:41px;
89   width:200px;
90   height: 100%;
91   background:#ffffff;
92   border: 1px solid #ffffff;
93   overflow: auto;
94 }
95 #map{
96   position:absolute;
97   z-index:1;
98   top:38px;
99   left:200px;
100   width:100%;
101   height:100%;
102   background:#eee;
103 }
104 #report{
105   position:absolute;
106   z-index:2;
107   top:38px;
108   left:200px;
109   width:100%;
110   height:100%;
111   background:#eee;
112   font: normal 12px/15px arial,sans-serif;
113   padding:20px;
114 }
115 #report table {
116   margin-left:20px;
117 }
118 #report th {
119   vertical-align:top;
120   text-align:left;
121 }
122 #report td.button {
123   text-align:right;
124 }
125 .result {
126   margin:5px;
127   margin-bottom:0px;
128   padding:2px;
129   padding-left:4px;
130   padding-right:4px;
131   border-radius: 5px;
132   -moz-border-radius: 5px;
133   -webkit-border-radius: 5px;
134   background:#F0F7FF;
135   border: 2px solid #D7E7FF;
136   font: normal 12px/15px arial,sans-serif;
137   cursor:pointer;
138 }
139 .result img{
140   float:right;
141 }
142 .result .latlon{
143   display: none;
144 }
145 .result .place_id{
146   display: none;
147 }
148 .result .type{
149   color: #999;
150   text-align:center;
151   font: normal 9px/10px arial,sans-serif;
152   padding-top:4px;
153 }
154 .result .details, .result .details a{
155   color: #999;
156   text-align:center;
157   font: normal 9px/10px arial,sans-serif;
158   padding-top:4px;
159 }
160 .noresults{
161   color: #000;
162   text-align:center;
163   font: normal 12px arial,sans-serif;
164   padding-top:4px;
165 }
166 .more{
167   color: #ccc;
168   text-align:center;
169   padding-top:4px;
170 }
171 .disclaimer{
172   color: #ccc;
173   text-align:center;
174   font: normal 9px/10px arial,sans-serif;
175   padding-top:4px;
176 }
177 form{
178   margin:0px;
179   padding:0px;
180 }
181         </style>
182
183         <script type="text/javascript">
184         
185                 var map;
186
187                 function handleResize()
188                 {
189                         if ($('searchresults'))
190                         {
191                                 $('map').style.width = (document.documentElement.clientWidth > 0?document.documentElement.clientWidth:document.documentElement.offsetWidth) - 200;
192                                 $('report').style.width = (document.documentElement.clientWidth > 0?document.documentElement.clientWidth:document.documentElement.offsetWidth) - 200;
193                         }
194                         else
195                         {
196                                 $('map').style.width = (document.documentElement.clientWidth > 0?document.documentElement.clientWidth:document.documentElement.offsetWidth) - 0;
197                                 $('map').style.left = 0;
198                         }
199                         
200                         if ($('map')) $('map').style.height = (document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38;
201                         if ($('searchresults')) $('searchresults').style.height = (document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38;
202                         if ($('report')) $('report').style.height = (document.documentElement.clientHeight > 0?document.documentElement.clientHeight:document.documentElement.offsetHeight) - 38;
203                 }
204                 window.onresize = handleResize;
205
206                 function panToLatLon(lat,lon) {
207                         var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
208                         map.panTo(lonLat, <?php echo $iZoom ?>);
209                 }
210
211                 function panToLatLonZoom(lat,lon, zoom) {
212                         var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
213                         if (zoom != map.getZoom())
214                                 map.setCenter(lonLat, zoom);
215                         else
216                                 map.panTo(lonLat, 10);
217                 }
218
219                 function panToLatLonBoundingBox(lat,lon,minlat,maxlat,minlon,maxlon,points) {
220                         var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
221                         var proj_map = map.getProjectionObject();
222                         map.zoomToExtent(new OpenLayers.Bounds(minlon,minlat,maxlon,maxlat).transform(proj_EPSG4326, proj_map));
223
224                         var pointList = [];
225                         var style = {
226                                 strokeColor: "#75ADFF",
227                                 fillColor: "#F0F7FF",
228                                 strokeWidth: 2,
229                                 strokeOpacity: 0.75,
230                                 fillOpacity: 0.75
231                         };
232                         var proj_EPSG4326 = new OpenLayers.Projection("EPSG:4326");
233                         var proj_map = map.getProjectionObject();
234                         if (points)
235                         {
236                                 points.each(function(p){
237                                         pointList.push(new OpenLayers.Geometry.Point(p[0],p[1]));
238                                         });
239                                 var linearRing = new OpenLayers.Geometry.LinearRing(pointList).transform(proj_EPSG4326, proj_map);;
240                                 var polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([linearRing]),null,style);
241                                 vectorLayer.destroyFeatures();
242                                 vectorLayer.addFeatures([polygonFeature]);
243                         }
244                         else
245                         {
246                                 var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
247                                 var point = new OpenLayers.Geometry.Point(lonLat.lon, lonLat.lat);
248                                 var pointFeature = new OpenLayers.Feature.Vector(point,null,style);
249                                 vectorLayer.destroyFeatures();
250                                 vectorLayer.addFeatures([pointFeature]);
251                         }
252                 }
253
254                 function round(v,n)
255                 {
256                         n = Math.pow(10,n);
257                         return Math.round(v*n)/n;
258                 }
259                 function floor(v,n)
260                 {
261                         n = Math.pow(10,n);
262                         return Math.floor(v*n)/n;
263                 }
264                 function ceil(v,n)
265                 {
266                         n = Math.pow(10,n);
267                         return Math.ceil(v*n)/n;
268                 }
269
270                 function mapEventMove() {
271                         var proj = new OpenLayers.Projection("EPSG:4326");
272                         var bounds = map.getExtent();
273                         bounds = bounds.transform(map.getProjectionObject(), proj);
274                         $('viewbox').value = floor(bounds.left,2)+','+ceil(bounds.top,2)+','+ceil(bounds.right,2)+','+floor(bounds.bottom,2);
275                 }
276
277     function init() {
278                         handleResize();
279                         map = new OpenLayers.Map ("map", {
280                 controls:[
281                                                                                 new OpenLayers.Control.Navigation(),
282                                                                                 new OpenLayers.Control.PanZoomBar(),
283                                                                                 new OpenLayers.Control.MouseDefaults(),
284                                                                                 new OpenLayers.Control.MousePosition(),
285                                                                                 new OpenLayers.Control.Attribution()],
286                 maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
287                 maxResolution: 156543.0399,
288                 numZoomLevels: 19,
289                 units: 'm',
290                 projection: new OpenLayers.Projection("EPSG:900913"),
291                 displayProjection: new OpenLayers.Projection("EPSG:4326"),
292                 eventListeners: {
293                                                                         "moveend": mapEventMove
294                                                                 }
295                 } );
296                         map.addLayer(new OpenLayers.Layer.OSM.<?php echo CONST_Tile_Default;?>("Default"));
297
298                         var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
299                         layer_style.fillOpacity = 0.2;
300                         layer_style.graphicOpacity = 1;
301                         vectorLayer = new OpenLayers.Layer.Vector("Points", {style: layer_style});
302                         map.addLayer(vectorLayer);
303                         
304 //                      var lonLat = new OpenLayers.LonLat(<?php echo $fLon ?>, <?php echo $fLat ?>).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
305 //                      map.setCenter (lonLat, <?php echo $iZoom ?>);
306                 }
307
308                 function setfocus(field_id) { 
309                         $(field_id).focus() 
310                 } 
311                 
312         </script>
313 </head>
314
315 <body onload="setfocus('q');">
316
317         <div id="seachheaderfade1"></div><div id="seachheaderfade2"></div><div id="seachheaderfade3"></div><div id="seachheaderfade4"></div>
318
319         <div id="seachheader">
320                 <form accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>search.php" method="get">
321                         <table border="0" width="100%">
322                                 <tr>
323                                         <td valign="center" style="width:30px;"><img src="images/logo.gif"></td>
324                                         <td valign="center" style="width:400px;"><input id="q" name="q" value="<?php echo htmlspecialchars($sQuery); 
325 ?>" style="width:270px;"><input type="text" id="viewbox" style="width:130px;" name="viewbox"></td>
326                                         <td style="width:80px;"><input type="submit" value="Search"></td>
327 <?php if (CONST_Search_AreaPolygons) { ?>                                       <td style="width:100px;"><input type="checkbox" value="1" name="polygon" <?php if ($bShowPolygons) echo "checked"; ?>> Highlight</td>
328 <td style="text-align:right;">Data: <?php echo $sDataDate; ?></td>
329 <td style="text-align:right;">
330 <a href="http://wiki.openstreetmap.org/wiki/Nominatim" target="_blank">Documentation</a> | <a href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ" 
331 target="_blank">FAQ</a></td>
332
333 <?php } ?>                                      <td style="text-align:right;"><?php if ($sQuery) { if ($sReportDescription) {?><div style="text-align:center;"><b>Thank you for your problem report</b></div><?php } else { ?><input type="button" value="Report Problem With Results" onclick="$('report').style.visibility=($('report').style.visibility=='hidden'?'visible':'hidden')"><?php }} ?></td>
334                                 </tr>
335                         </table>
336                 </form>
337         </div>
338
339 <?php
340         if ($sQuery || sizeof($aSearchResults))
341         {
342 ?>
343         <div id="searchresultsfade1"></div><div id="searchresultsfade2"></div><div id="searchresultsfade3"></div><div id="searchresultsfade4"></div>
344         <div id="searchresults">
345 <?php
346         if ($sSuggestionURL)
347         {
348                 echo '<div class="more"><b>Suggest: </b><a href="'.$sSuggestionURL.'"><b>'.$sSuggestion.'</b></a></div>';
349         }
350         foreach($aSearchResults as $iResNum => $aResult)
351         {
352                 if ($aResult['aBoundingBox'])
353                 {
354                         echo '<div class="result" onClick=\'panToLatLonBoundingBox('.$aResult['lat'].', '.$aResult['lon'];
355                         echo ', '.$aResult['aBoundingBox'][0];
356                         echo ', '.$aResult['aBoundingBox'][1];
357                         echo ', '.$aResult['aBoundingBox'][2];
358                         echo ', '.$aResult['aBoundingBox'][3];
359                         echo ', '.javascript_renderData($aResult['aPolyPoints']);
360                         echo ');\'>';
361                 }
362                 elseif (isset($aResult['zoom']))
363                 {
364                         echo '<div class="result" onClick="panToLatLonZoom('.$aResult['lat'].', '.$aResult['lon'].', '.$aResult['zoom'].');">';
365                 }
366                 else
367                 {
368                         echo '<div class="result" onClick="panToLatLon('.$aResult['lat'].', '.$aResult['lon'].');">';
369                 }
370
371                 echo ($aResult['icon']?'<img src="'.$aResult['icon'].'">':'');
372                 echo ' <span class="name">'.$aResult['name'].'</span>';
373                 echo ' <span class="latlon">'.round($aResult['lat'],3).','.round($aResult['lat'],3).'</span>';
374                 echo ' <span class="place_id">'.$aResult['place_id'].'</span>';
375                 if (isset($aResult['label']))
376                         echo ' <span class="type">('.$aResult['label'].')</span>';
377                 else
378                         echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
379                 echo ' <span class="details">(<a href="details.php?place_id='.$aResult['place_id'].'">details</a>)</span>';
380                 echo '</div>';
381         }
382         if (sizeof($aSearchResults))
383         {
384                 if ($sMoreURL)
385                 {
386                         echo '<div class="more"><a href="'.$sMoreURL.'">Search for more results</a></div>';
387                 }
388         }
389         else
390         {
391                 echo '<div class="noresults">No search results found</div>';
392         }
393
394 ?>
395                 <div class="disclaimer">Addresses and postcodes are approximate
396                         <input type="button" value="Report Problem" onclick="$('report').style.visibility=($('report').style.visibility=='hidden'?'visible':'hidden')">
397                 </div>
398         </div>
399 <?php
400 }
401 ?>
402
403         <div id="map"></div>
404         <div id="report" style="visibility:hidden;"><div style="width:600px;margin:auto;margin-top:60px;">
405                 <h2>Report a problem</h2>
406                 <p>Before reporting problems please read the <a href="http://wiki.openstreetmap.org/wiki/Nominatim">user documentation</a> and <a 
407 href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ">FAQ</a>.  If your problem relates to the address of a particular search result please use the 'details' link 
408 to check how the address was generated before reporting a problem.</p>
409                 <p>Please use <a href="http://trac.openstreetmap.org/newticket?component=nominatim">trac.openstreetmap.org</a> to report problems 
410 making sure to set 
411 the component to 'nominatim'.  You can search for existing bug reports <a href="http://trac.openstreetmap.org/query?status=new&status=assigned&status=reopened&component=nominatim&order=priority">here</a>.</p>
412                 <p>Please ensure that you include a full description of the problem, including the search query that you used, the problem with the result and, if 
413 the problem relates to missing data, the osm id of the item that is missing.  Problems that contain enough detail are likely to get looked at before ones that 
414 require significant research!</p>
415                 </div>
416                 
417 <!--
418                 <p>Please use this form to report problems with the search results.  Of particular interest are items missing, but please also use this form to 
419 report any other problems.</p>
420                 <p>If your problem relates to the address of a particular search result please use the 'details' link to check how the address was generated before 
421 reporting a problem.</p>
422                 <p>If you are reporting a missing result please (if possible) include the OSM ID of the item you where expecting (i.e. node 422162)</p>
423                 <form method="post">
424                 <table>
425                 <tr><th>Your Query:</th><td><input type="hidden" name="report:query" value="<?php echo htmlspecialchars($sQuery); ?>" style="width:500px;"><?php echo htmlspecialchars($sQuery); ?></td></tr>
426                 <tr><th>Your Email Address(opt):</th><td><input type="text" name="report:email" value="" style="width:500px;"></td></tr>
427                 <tr><th>Description of Problem:</th><td><textarea name="report:description" style="width:500px;height:200px;"></textarea></td></tr>
428                 <tr><td colspan="2" class="button"><input type="button" value="Cancel" onclick="$('report').style.visibility='hidden'"><input type="submit" value="Report"></td></tr>
429                 </table>
430                 </form>
431                 <h2>Known Problems</h2>
432                 <ul>
433                 <li>Countries where missed out of the index</li>
434                 <li>Area Polygons relate to the search area - not the address area which would make more sense</li>
435                 </ul>
436 -->
437         </div>
438
439         <script type="text/javascript">
440 init();
441 <?php
442         foreach($aSearchResults as $iResNum => $aResult)
443         {
444                 if ($aResult['aBoundingBox'])
445                 {
446                         echo 'panToLatLonBoundingBox('.$aResult['lat'].', '.$aResult['lon'];
447                         echo ', '.$aResult['aBoundingBox'][0];
448                         echo ', '.$aResult['aBoundingBox'][1];
449                         echo ', '.$aResult['aBoundingBox'][2];
450                         echo ', '.$aResult['aBoundingBox'][3];
451                         echo ', '.javascript_renderData($aResult['aPolyPoints']);
452                         echo ');'."\n";
453                 }
454                 else
455                 {
456                         echo 'panToLatLonZoom('.$fLat.', '.$fLon.', '.$iZoom.');'."\n";
457                 }
458                 break;
459         }
460         if (!sizeof($aSearchResults))
461         {
462                 echo 'panToLatLonZoom('.$fLat.', '.$fLon.', '.$iZoom.');'."\n";
463         }
464 ?>
465 </script>
466 </body>
467
468 </html>