diff --git a/examples/popupMatrix.html b/examples/popupMatrix.html new file mode 100644 index 0000000000..1feca9e6f5 --- /dev/null +++ b/examples/popupMatrix.html @@ -0,0 +1,891 @@ + + + + + + + + + + + + +

Popup Matrix

+ +
+
+

+ All kinds of different popup configurations. +

+ +
+ + + + + + + +
+ + + + + diff --git a/examples/popupMatrix.jpg b/examples/popupMatrix.jpg new file mode 100755 index 0000000000..fb09bc0717 Binary files /dev/null and b/examples/popupMatrix.jpg differ diff --git a/examples/popups.html b/examples/popups.html index 7ed591d8b3..42bd4dfb75 100644 --- a/examples/popups.html +++ b/examples/popups.html @@ -72,26 +72,15 @@ } function mousedown(evt) { - // check to see if the popup was hidden by the close box - // if so, then destroy it before continuing - if (popup != null) { - if (!popup.visible()) { - markers.map.removePopup(popup); - popup.destroy(); - popup = null; - } - } if (popup == null) { popup = feature.createPopup(true); - popup.setContentHTML("click me"); + popup.setContentHTML("
click me
"); popup.setBackgroundColor("yellow"); popup.setOpacity(0.7); markers.map.addPopup(popup); } else { - markers.map.removePopup(popup); - popup.destroy(); - popup = null; - } + popup.toggle(); + } OpenLayers.Event.stop(evt); } diff --git a/examples/sundials.html b/examples/sundials.html new file mode 100644 index 0000000000..0efa534dcc --- /dev/null +++ b/examples/sundials.html @@ -0,0 +1,74 @@ + + + + + + + + + + +

KML Layer Example

+ +
+ +

+ Demonstrates loading and displaying a KML file on top of a basemap. +

+ +
+ +
+ + diff --git a/examples/sundials.kml b/examples/sundials.kml new file mode 100644 index 0000000000..caadf16a91 --- /dev/null +++ b/examples/sundials.kml @@ -0,0 +1,2273 @@ + + + + Sundial Collection.kmz + + + normal + #sn_sunny_copy69 + + + highlight + #sh_sunny_copy70 + + + + + + + + + normal + #sn_sunny_copy68 + + + highlight + #sh_sunny_copy69 + + + + Sundial Collection + 1 + + -56.6884384968692 + 47.91963617483238 + 0 + 9958750.824018393 + 1.303827428939919e-015 + -16.31426621668193 + + + + High Resolution + + Sundial, Madestein, Den Haag +

]]>
+ + 4.213227700645635 + 52.04260288332888 + 0 + 24.63686803544318 + 0 + 1.387289180270979e-005 + + #msn_sunny_copy69 + + 4.213209970684247,52.04268354765237,0 + +
+ + Sundial, Den Haag - Loosduinen + Thanks to A30

+ +A sundial made of wooden blocks. +The highest block in the middle is the style and casts its shadow each hour on one of the other blocks. + +

+Image source:www.dse.nl]]>
+ + 4.236038669148795 + 52.0499434967447 + 0 + 18.37312193280116 + 2.202011190893535e-011 + -0.3988978466888938 + + #msn_sunny_copy69 + + 4.236026636181407,52.049986562365,0 + +
+ + Sundial with light conductors - Paris, Les Halles +

+ +The sunlight falls on one of the three windows in the column (east, south, west) and over light conductors on the wall is indicated. + +

+ +The clock shows 16,40 o'clock. + +

+ +Quelle:http://www.home.uni-osnabrueck.de/ahaenel/sonnuhr/paris_halles.htm + +http://perso.orange.fr/cadrans.solaires/cadrans/cadran-halles-paris.html]]>
+ + 2.344185113917775 + 48.86294270160059 + 0 + 39.52787486507292 + 0 + -0.003533584730563007 + + #msn_sunny_copy69 + + 2.344143312335305,48.86302323987447,0 + +
+ + Sundial, Plymouth, Devon, UK + The gnonom is 27 foot high, the pool has 21 feet diameter. It was designed by architect Carole Vincent from Boscastle in Cornwall and was unvieled by Her Majesty the Queen on Friday July 22nd 1988 for a cost of cost £70,000 . The sundial runs one hour and seventeen minutes behind local clocks.

+

+

Image source:

+Image source:www.sundials.co.uk]]>
+ + -1.117890647596098 + 50.79319978711329 + 0 + 79.08348690288113 + 0 + 0.02100880488328328 + + #msn_sunny_copy69 + + -1.117887915142518,50.79336425684474,0 + +
+ + Sundial, Britzer Garten, Berlin + See photos on this page: +http://home.arcor.de/ruth.kirsch/sonnenuhr/berlin_1xxxx/berlin_1xxxx.htm + + 13.42078373972489 + 52.4366841172644 + 0 + 102.2086892967038 + 0 + -0.004885703167479627 + + #msn_sunny_copy69 + + 13.4207448482471,52.43682055829985,0 + + + + Sundial, Falkenplatz, Berlin + The original reasoning event for the construction of the sundial was the UNO climate conference 1995 in Berlin. The base stone of the wall spiral was layed at a festivity at the equinox of March 1995. Until June 1995 the main construction was completed, and at another festivity at the summer solstice the gnonom and the totem ("Lebensbaum") was installed by Berlin fire fighters.

+

+

The nearly spiral sundial was planned as a "living sundial" and initiated by the groups of the "Netzwerk Klimagipfel 95", mainly by the journalist T. Römer with the "Verein zur Rettung des Regenwaldes und Naturschutzgebietes La Macarena", and the "Netzwerk Spiel/Kultur" at the Prenzlauer Berg. + + +The covering clay stones were made out of three metric tons of white and brown clay, formed by children of about 50 institutions like school classes and kindergardens of the closer region. The stones were burned and installed in the summer of 1995. Partly they are constructed out of different materials, partly especially formed or ornamented. Six detail images are showing some examples: (White near Red - MC?, Smiley with Heart Eyes, Sun-Moon-Star, Red Broken and Patterned, Rain pits and Stone Hearts in Clay, Red near White - Clay Fish and Sunshine over the Sea). + +In September 1995 the sundial was completed. It was called "living sundial" because it was planned to replace the clay stones regulary when they are destroyed and to add some green to the outside wall of the clock. In December 1995 the clock got a special price of the local environmental administration.

+

.

+ + +

In September 1995 the sundial was completed. It was called "living sundial" because it was planned to replace the clay stones regulary when they are destroyed and to add some green to the outside wall of the clock. In December 1995 the clock got a special price of the local environmental administration.

+

+ +

This sundial was deconstructed at the end of 2002 or at the beginning of 2003:

+

+ +

Image source and infos:www.surveyor.in-berlin.de

]]>
+ + 13.40239121468946 + 52.54640622802566 + 0 + 55.75497205265645 + 1.489511345854323e-009 + 2.6367660621925e-005 + + #msn_sunny_copy69 + + 13.40233774797299,52.54645010247089,0 + +
+ + Sundial, Halde Schwerin, Castrop-Rauxel, Germany + Thanks to htd42

+

+ +http://www.ruhrgebiet.de/freizeit/sehenswuerdigkeiten/cr_halde_schwerin.shtml?print]]>
+ + 7.337404407947669 + 51.54597716006042 + 0 + 51.28632275218226 + 2.512805793870883e-009 + -6.529566789930303e-005 + + #msn_sunny_copy69 + + 7.337359256982781,51.54610609965799,0 + +
+ + Sundial, Lloydminster, Canada +

+

Image source and infos:www.mts.net

]]>
+ + -110.0353754682919 + 53.26386357821667 + 0 + 155.9861269181855 + 0 + -0.01432903343453666 + + #msn_sunny_copy69 + + -110.0355256583979,53.26413794825379,0 + +
+ + Giant Lady's Leg Sundial, Roselawn, Indiana, USA + The Sun Aura Nudist Resort opened in 1933. Back then it was called Club Zoro and its founder was Alois Knapp, a Chicago lawyer, German Nacktkulturist, editor of Sunshine and Health magazine, and "the father of nudism in America."

+ +

+ +

The club eventually passed into the hands of Dale and Mary Drost. Their son, Dick, had big ideas: he renamed the place Naked City, made it the home of the Ms. Nude Teeny Bopper Contest and the "Erin Go Bra-less" Dance on St. Patrick's Day, and had built the giant lady's leg sundial, 63 feet long and properly positioned to tell time -- a useful feature for wristwatchless nudists.

+ +

Naked City closed in 1986 when Dick was run out of Indiana on child molestation charges, but the leg remains and so does the resort, now under new management. The circular main building with the mirror gold windows is a combination office-sauna-restaurant.

+ +

The guy who paints the leg told us that Sun Aura is a "clothing optional" camp -- in other words, you don't have to get nude to take a picture of the big lady's leg. But for those who do choose to get into the spirit of things, a helpful sign on the exit road reads, "Stop. You Must Be Dressed Beyond This Point."

+ +

Roadside America

]]>
+ + -87.32599841452155 + 41.14248697221019 + 0 + 40.06529731982877 + 0 + -108.7495178792767 + + #msn_sunny_copy69 + + -87.32608203713804,41.14242622349031,0 + +
+ + Sundial, Ingleside, San Francisco, USA + Thanks to CostaPacific

+ +Most people in San Francsco have no idea that their city is host to the world's second largest sundial. It was built in 1913 as a gimic to attract people to a new housing development that was built arround the configuration of the old Ingleside Race Track. + +

+

Image source:]]> + + -122.4687521474299 + 37.72475779376939 + 0 + 104.1096478961583 + 0 + -6.694029629862418e-005 + relativeToGround + + #msn_sunny_copy69 + + -122.4687727980979,37.72497790751523,59.97947112427937 + + + + Sundial Bridge + Located in Redding, CA. Opened in 2004 this bridge actually acts as a sundial. The time can be read in a garden on the North side of the bridge. + +http://www.turtlebay.org/sundial/sundial.shtml + + -122.3775376532067 + 40.59329504591046 + 0 + 160.1654912126178 + 7.884938307004504e-010 + 0.008470312235033726 + + #msn_sunny_copy69 + + -122.3777030796087,40.59376952663914,0 + + + + Sundial, Jaipur,India + Villaman + +

+ + + + +

Jaipur Observatory Sundial


+
+

Walk through these doors and up the stairs to begin your journey along a line from Jaipur, India toward the North Celestial Pole. Such cosmic alignments abound in marvelous Indian observatories where the architecture itself allows astronomical measurements. The structures were built in Jaipur and other cities in the eighteenth century by the Maharaja Jai Singh II (1686-1743). Rising about 90 feet high, this stairway actually forms a shadow caster or gnomon, part of what is still perhaps the largest sundial on planet Earth. Testaments to Jai Singh II's passion for astronomy, the design and large scale of his observatories' structures still provide impressively accurate measurements of shadows and sightings of celestial angles. +

Jaipur Observatory Sundial

+

More here. + +

+]]> + + 75.82482649881683 + 26.924766672173 + 0 + 164.397137416247 + 0 + -0.02454798212483729 + relativeToGround + + #msn_sunny_copy69 + + 75.82474437483685,26.92504292845888,0 + + + + Sundial, Schothorstpark, Amersfoort, Netherlands + A large sundial in the Schothorstpark in Amersfoort. +Thanks to Acadvice]]> + + 5.385083481782106 + 52.17868238866643 + 0 + 49.70911801163624 + 5.249316070079438e-010 + 6.699999294207586e-006 + relativeToGround + + #msn_sunny_copy69 + + 5.385063337537176,52.17873082332495,0 + + + + Sundial, Jardin de Reuilly, Paris +

+ +

+Image source:http://perso.orange.fr

]]>
+ + 2.387204592843604 + 48.84242901629369 + 0 + 50.11592463998582 + 8.113900329668256e-010 + -0.001210217218456717 + relativeToGround + + #msn_sunny_copy69 + + 2.38716774037826,48.84252766103683,0 + +
+ + Sundial, Stockgrove, Soulbury, Buckinghamshire, UK + thanks to houdinia

+Sundial with analemmatic clock face. +

]]>
+ + -0.666503881371199 + 51.95548351688392 + 0 + 55.27920580004575 + 6.264058771241075e-010 + 0.06911766261471311 + relativeToGround + + #msn_sunny_copy69 + + -0.6665014664411046,51.95551857959676,0 + +
+ + Sundial, Halde Hoheward, Germany + The Obelisk – The Sundial

+ +

The seeming movement of the sun in the sky, resulting in the discrimination between day and night, was one of the earliest observations of nature performed by men. It enables us to experience the phenomenon “time” with our own senses. The first examples for telling the time with the help of the sun or its shadow date back to the Ancient World. The are numerous archetypes for sundials built inmany different styles, using different techniques.

+ +

The archetype for the horizontal sundial on top of the slagheap Hoheward is the sundial of the Roman Emperor Augustus on the Campus Martius in Rome.

+(It is unknown, whether this ancient obelisk was part of a complete sun dial with hour and declination lines on the morning and afternoon side or whether only a meridian line existed to measure the elevation of the sun in upper culmination. The today's scientific knowledge indicates the existence of a meridian.) The observation of the Obelisk's shadow on the sundial enables the observer to easily determine date and time. Apart from “time” one can also experience the laws of celestial mechanics. Men encounter themselves in relation to the cosmos.

+ +

Representing the first step in the realisation of the Astronomical Theme Park the Obelisk was opened on May 17th, 2005. It is located on the already completed south-eastern plateau of the slagheap at a height of 140 m above sea level. The shadowed area is 62 m in diameter.

+ + + +

+This picture shows the Obelisk after the end of the assembly on the day of the opening. Shortly before it was put on top of the readily prepared pedestal by a helicopter and then bolted. + +

+ +

http://www.horizontastronomie.de

+ + + +

http://de.wikipedia.org/wiki/Halde_Hoheward#Sonnenuhr_mit_Obelisk

+ +

http://www.horizontastronomie.de/animationen.htm

]]>
+ + 7.170033145228383 + 51.56646738931531 + 0 + 96.7791497847863 + 4.155528307086707e-010 + 0.006376147752644328 + relativeToGround + + #msn_sunny_copy69 + + 7.169892708740022,51.56683509795316,0 + +
+ + Sundial, Fachhochschule (FH) Bielefeld +

+http://www.fh-bielefeld.de/article/fh/4412/1/505?NavItemID=0&NavCatID=162]]>
+ + 8.555263115842216 + 52.02672953436973 + 0 + 50.10364671714684 + 0 + 0.001255164290936946 + relativeToGround + + #msn_sunny_copy69 + + 8.555215193531964,52.02681111856448,0 + +
+ + Sundial, Sun City, Arizona +

+ +

]]>
+ + -112.2739996808105 + 33.61902729376313 + 0 + 44.66059102278575 + 0 + 0.0001994953180518285 + relativeToGround + + #msn_sunny_copy69 + + -112.2740228273864,33.61913038777643,0 + +
+ + Sundial, Georgina Blach Intermediate School, Los Altos, CA +

]]>
+ + -122.083063541274 + 37.36394994353518 + 0 + 99.46493929648614 + 0 + -6.524992683547596e-005 + relativeToGround + + #msn_sunny_copy69 + + -122.0831077334675,37.3641379192763,0 + +
+ + Sundial, Hilltop Park, San Francisco +

]]>
+ + -122.3837414260284 + 37.73308769461563 + 0 + 76.96447255875415 + 0 + -0.0001251047167258125 + relativeToGround + + #msn_sunny_copy69 + + -122.3837885185873,37.73313852750733,0 + +
+ + Sundial, Berlin-Weißensee +

+ +http://www.be.schule.de/schulen/wfs/pages/sundials/Weissensee.html]]>
+ + 13.46637059089964 + 52.55408525446345 + 0 + 35.24186259647233 + 0 + -0.002133411261797274 + relativeToGround + + #msn_sunny_copy69 + + 13.46637589519183,52.55412143657096,0 + +
+ + Sundial, Olbers-Planetarium, Bremen +

]]>
+ + 8.806980778676786 + 53.06988134466393 + 0 + 24.09705977000565 + 0 + -0.001876272046377585 + relativeToGround + + #msn_sunny_copy69 + + 8.806963468445417,53.0698959991562,0 + +
+ + Sundial, Westbroekpark, Denn Haag +

]]>
+ + 4.290891177932192 + 52.10450647693549 + 0 + 20.57779559985518 + 0 + -0.8669355345663358 + relativeToGround + + #msn_sunny_copy69 + + 4.290865552422943,52.10453275113748,0 + +
+ + Sundial, Amersfoort, Netherlands +

]]>
+ + 5.374167244217593 + 52.15310253836927 + 0 + 31.45592479376158 + 1.426589610824431e-009 + -0.01164696084898205 + relativeToGround + + #msn_sunny_copy69 + + 5.374145665653813,52.15310809583514,0 + +
+ + Sundial, Botanical Gardens, Sydney, Australia +

+ +

]]>
+ + 151.2154952669206 + -33.86399908828604 + 0 + 16.43666728184123 + 8.675342058213797e-007 + -0.002067228419448193 + relativeToGround + + #msn_sunny_copy69 + + 151.2154882763944,-33.86398565287625,0 + +
+ + Team Disney Sundial, Walt Disney World, Florida + Oftencold + +

+ +http://www.de-zonnewijzerkring.nl/zw-arch/eng-home-zw-07-02.htm]]>
+ + -81.52113085122878 + 28.36541360352638 + 0 + 167.7307771712135 + 1.015026730473625e-011 + -0.006287852151169638 + relativeToGround + + #msn_sunny_copy69 + + -81.52134276012195,28.36559634883421,0 + +
+ + Sundial, Janskerkhof, Utrecht, Netherlands +

+ +

]]>
+ + 5.121095723583527 + 52.09338586502101 + 0 + 24.25734051739648 + 5.490226183683639e-010 + -0.0007122606404517594 + relativeToGround + + #msn_sunny_copy69 + + 5.121088800707085,52.09341776135472,0 + +
+ + Sundial, San Jose Rep Theater, San Jose, CA +

+ +

Image credit:www.groundspeak.com

]]>
+ + -121.8860266085782 + 37.33361545835343 + 0 + 32.31958319185324 + 0 + 1.418565866412994e-005 + relativeToGround + + #msn_sunny_copy69 + + -121.886064353331,37.33364018615777,0 + +
+ + Millennium Sundial, Greenwich Park, London +

+ +

Image credit:www.groundspeak.com

]]>
+ + -0.001522539653513039 + 51.48136176862654 + 0 + 61.96314954770909 + 2.850197260451716e-009 + -0.002911073287638733 + relativeToGround + + #msn_sunny_copy69 + + -0.00156808979284051,51.48142700407306,0 + +
+ + Sundial, Veterans Park, Waukesha, WI +

+ +

Image credit:www.groundspeak.com

]]>
+ + -88.2367572684424 + 43.00995357504599 + 0 + 49.0879478099675 + 0 + -2.769547716555237e-005 + relativeToGround + + #msn_sunny_copy69 + + -88.23678272979073,43.01004377682637,0 + +
+ + Underground Sundial, Munich, Germany +

+ +

Image credit:www.groundspeak.com

]]>
+ + 11.70480163926041 + 48.13338615699044 + 0 + 49.09160069235252 + 7.359413992305611e-011 + 1.363313751616389e-005 + relativeToGround + + #msn_sunny_copy69 + + 11.70474103166116,48.13350333174798,0 + +
+ + Sundial, Crown Hill cemetery, Indianapolis, Indiana, USA +

+ +

Image credit:www.groundspeak.com

]]>
+ + -86.17300915391851 + 39.82668935299838 + 0 + 35.63730089613371 + 0 + 2.616180723282867e-005 + relativeToGround + + #msn_sunny_copy69 + + -86.17304253331795,39.82668119645058,0 + +
+ + Sundial, Coppell, TX +

+ +

Image credit:www.groundspeak.com

]]>
+ + -97.02194975520763 + 32.95633568822581 + 0 + 61.19896168864369 + 0 + 1.826645706530163e-005 + relativeToGround + + #msn_sunny_copy69 + + -97.02199840401494,32.95643533824669,0 + +
+
+ + Low Resolution + + Sundial, Kota Baru Parahyangan + voorburger. +

]]>
+ + 107.4940550739811 + -6.852038750176605 + 0 + 296.7282563680993 + 2.08633946131246e-011 + 0.5509822616366601 + relativeToGround + + #msn_sunny_copy70 + + 107.4939718861608,-6.851748821808833,0 + +
+ + Sundial, Pajala, Sweden + The world's biggest sundial today is in the Torne Valley, north of the Arctic Circle. The Guinness Book of Records has put Pajala, northern Sweden, on the map, and its sundial - formed as a "round square".

+

+

The sundial in Pajala, 38.33 m. in diameter, holds the world record, according to the Guinness Book of Records. The previous record was held by Disney World in Orlando, Florida, with 37.18 m.

+ +

The sundial was inaugurated by the Swedish Minister of Labour Margareta Winberg in July 1996. Pajala is situated at 23.28 ° East, 67.21 ° North, which is 70 km north of the Arctic Circle, making a circular sundial possible. This is due to the fact that the Midnight Sun describes a complete circle over the horizon. + +

Its masts of dried fir form a unique spatiality around a circular "square". The site is especially used for local functions such as Pajala Fair, Romp Week and the Northern Lights Festival.

+ +

The central square in Pajala, through its size and latitude, offered conditions for a sundial dedicated to the Midnight Sun. Architect Mats Winsa took his inspiration from the square in Siena, and for the sculptures in the park - astronomical instruments in India dating back to the 18th century. Naturally, it was a challenge to compete with the previous record from 1991 by the world-famous Japanese architect, Arata Isozaki.

+ +

The sundial captures the sun's movement by allowing the shadow of the central gnomon to fall across the hour divisions of the surrounding posts. The gnomon, like the Earth's axis, points toward the Pole Star, which according to Finnish-Ugrian mythology (the region has Finnish roots) holds up the firmament. The "sun wheel" embedded in the ground here (forming a cross in the circle) is in fact a calendar. Water bubbles up from four sources corresponding to the four principal points of the compass. The water gathers in the central pond, which was designed with children in mind.

+ +

For their survival, humans have followed the rhythm of the sun. The need to observe the changing seasons and days led to the early development of the sundial. Our lives today are characterised by obedience to mechanical and national time - inventions separate from true solar time. The sundial displays true solar time, which in Pajala is half-an-hour ahead of national time.

+ +

The sundial in Pajala celebrates light, and acts as a reminder of its significance for all life by functioning as a biological clock in a world fettered by artificial time. The hormone rush in spring reminds us of our direct dependence on sunlight as living beings.

+ +

Info and image source:www.pajala.se

+ +

+

Image source:http://holmers.com

]]>
+ + 23.36723004664742 + 67.21282676944374 + 0 + 124.9604027877409 + 3.010594647959025e-010 + -1.130925335798896 + relativeToGround + + #msn_sunny_copy70 + + 23.36716252896882,67.21299216873888,0 + +
+ + Sundial, Tenerife, Spain +

+ +

+ +

+ +

+

Image source:http://members.aon.at

+ +

Interactice picture

]]>
+ + -16.56926659562192 + 28.08256590461729 + 0 + 88.29371157400612 + 0 + 8.633540737161729e-005 + relativeToGround + + #msn_sunny_copy70 + + -16.5693071701084,28.08261960124695,0 + +
+ + Sundial, Perranporth, UK +

]]>
+ + -5.157517535037663 + 50.34723421976403 + 0 + 65.69642310338585 + 0 + -0.01795551609583625 + relativeToGround + + #msn_sunny_copy70 + + -5.157537433789316,50.34733238709538,0 + +
+ + Sundial, Council Bluffs, Iowa, USA +

+

+

]]>
+ + -95.84953495410247 + 41.25887711431908 + 0 + 196.5752069699831 + 2.583166383376495e-010 + 0.0002124063872384501 + + #msn_sunny_copy70 + + -95.84981881431206,41.25888611306795,294.4878429401121 + +
+ + Sundial. Meckhofen, Leverkusen, Germany +

+

Image source:www.leverkusen.de

+ +

+ +

+

Image source:www.lev2000.de

]]>
+ + 7.083354426150351 + 51.04845387008112 + 0 + 66.17616066250443 + 9.735256695418331e-010 + 0.0006924896867520876 + relativeToGround + + #msn_sunny_copy70 + + 7.083321386023442,51.04852440832129,0 + +
+ + Sundial, Adler Planetarium, Chicago, USA +

]]>
+ + -87.60711153340705 + 41.86674796371171 + 0 + 27.37440941953917 + 0 + 0.008419825260544345 + + #msn_sunny_copy70 + + -87.60710764637246,41.86681374132155,0 + +
+ + Rose Garden Sundial, Christchurch, New Zealand + Thanks to NormB

+Rose Garden History + +

+Photo - NormB 11th April 2006
+Image Hosted by ImageShack.us

+Photo - NormB 11th April 2006
+Image Hosted by ImageShack.us]]> + + 172.621331272394 + -43.53038034442864 + 0 + 86.04933199573917 + 0 + 1.801092527765711 + + #msn_sunny_copy70 + + 172.6213650004974,-43.53035465311722,0 + + + + Sundial, Natchez Park + Thanks to caroling

+ +In Seaside, NW FL, USA on the Emerald Coast. Panoramic images and movies of a sundial and visions of Xtals (energy crystals) on the March equinox, 2006. See http://www.wholeo.net/Trips/Art/Web/TripsArt/Travel/Florida/borders/flBorders.htm]]>
+ + -86.14177717779702 + 30.32184243688109 + 0 + 46.50596341362312 + 9.523139707563741e-010 + 0.0925379903960088 + + #msn_sunny_copy70 + + relativeToGround + -86.14183223138707,30.32193188899003,3 + +
+ + Sundial, Charlotte, North Carolina, USA + Thanks to BrettHo

+On the roof of the International Trade Center is this gigantic sundial.]]>
+ + -80.84002590296151 + 35.22682691631484 + 0 + 73.21919569418378 + 0 + 12.34188537748346 + + #msn_sunny_copy70 + + -80.84002447413604,35.22696160522812,0 + +
+ + KTPalmerSundial, Carefree, Arizona, USA + seer
. +

+http://www.bigwaste.com/photos/az/sundial/]]> + + -111.9217799027029 + 33.8245907883639 + 0 + 119.8165563905356 + 2.774426682549449e-010 + -1.574999619300427e-005 + + #msn_sunny_copy70 + + -111.9218327194278,33.82468559440962,0 + + + + Sundial, University of Science and Technology, Hong Kong +

+ +

Image source:http://perso.orange.fr

]]>
+ + 114.2630116779084 + 22.33749401387006 + 0 + 111.6162130745504 + 0 + 0.0003913059632004609 + relativeToGround + + #msn_sunny_copy70 + + 114.2629690669868,22.33764072332584,0 + +
+ + Sundial, Pekin, Illinois +

+

Image source:www.pekin.net

+ +

]]>
+ + -89.63076522889526 + 40.56267466732153 + 0 + 161.1716772997438 + 0 + 0.009112399365723663 + relativeToGround + + #msn_sunny_copy70 + + -89.63089561079578,40.56281064339486,0 + +
+ + Sundial, Edinburg, Hidalgo, USA +

+ +

<7p>]]> + + -98.17095602857175 + 26.30618568257091 + 0 + 122.1950947751469 + 0 + -0.005400653570135644 + relativeToGround + + #msn_sunny_copy70 + + -98.17104492887813,26.30639237212602,0 + + + + Sundial, Keppel Henge, +

+

http://www.steveirvine.com/sundial.html

+ + +http://www.mts.net/~sabanski/sundial/sotw_canada_keppel.htm]]>
+ + -80.94374423682251 + 44.79038599160477 + 0 + 164.0454159373261 + 0 + -0.007334046679263517 + relativeToGround + + #msn_sunny_copy70 + + -80.94383190841853,44.79038705635566,0 + +
+ + Sundial at Science North, Sudbury, Ontario +

+ +

+ +

+ +http://www.mts.net/~sabanski/sundial/sotw_canada_sn.htm]]>
+ + -80.99582033913947 + 46.46976830028441 + 0 + 85.82915438648354 + 0 + 0.0003317215281456315 + relativeToGround + + #msn_sunny_copy70 + + -80.99588716181201,46.46988111501548,0 + +
+ + Sundial, Amble, UK +

+http://ourworld.compuserve.com/homepages/Patrick_Powers/amble.htm]]>
+ + -1.581634687429885 + 55.33514811404725 + 0 + 62.55005662709024 + 8.224100904372228e-010 + -0.008198736253532122 + relativeToGround + + #msn_sunny_copy70 + + -1.581720999552488,55.3352025087941,0 + +
+ + Sundial, University of Maryland, College Park +

+http://www.mts.net/~sabanski/sundial/sotw_usa_mland.htm]]>
+ + -76.94256839624576 + 38.98603731470438 + 0 + 69.47353847793947 + 0 + -0.00947513273561203 + relativeToGround + + #msn_sunny_copy70 + + -76.94253686137193,38.98616316295006,0 + +
+ + Sundial, Fort San Felipe del Morro, Puerto Rico +

]]>
+ + -66.11899284422442 + 18.46786530709565 + 0 + 122.9114928009769 + 0 + 0.001639161983653822 + relativeToGround + + #msn_sunny_copy70 + + -66.11900470518663,18.4679529172629,0 + +
+ + Sundial, Rose Garden, Phoenix +

]]>
+ + -112.0911976535298 + 33.47007786030556 + 0 + 26.72933602203598 + 4.053298886062559e-011 + 0.0001093808645832187 + relativeToGround + + #msn_sunny_copy70 + + -112.0912131593616,33.4701136927338,0 + +
+ + Sundial, Tucson, Arizona +

]]>
+ + -110.9748374101104 + 32.21591986778585 + 0 + 42.12321141209996 + 0 + -0.0002919115031976927 + relativeToGround + + #msn_sunny_copy70 + + -110.9748562940359,32.21593667064053,0 + +
+ + Sundial, Flandrau Planetarium, Tucson +

]]>
+ + -110.9477979774635 + 32.23224398378896 + 0 + 33.29181342845133 + 3.6608792363658e-017 + 0.0001605580448802178 + relativeToGround + + #msn_sunny_copy70 + + -110.9478231994691,32.23228861367718,0 + +
+ + Sundial, Vietnam Veterans Memorial, Kentucky +

+ +http://www.vietvet.org/kymem.htm]]>
+ + -84.8640348419774 + 38.17725413584271 + 0 + 136.9757698325458 + 1.322889725758878e-010 + -0.0003615314930558497 + relativeToGround + + #msn_sunny_copy70 + + -84.86405079639164,38.17749508752453,0 + +
+ + Sundial, Claremont, California +

+ +

]]>
+ + -117.7288129576152 + 34.0992297660836 + 0 + 60.73786036422235 + 1.321942869740197e-009 + -0.002677989156069468 + relativeToGround + + #msn_sunny_copy70 + + -117.7288254316814,34.09928418001653,0 + +
+ + Sundial, Hoogezand, Netherlands +

+ +http://www.hoogezand-sappemeer.nl/index.php?simaction=content&mediumid=10&pagid=335&fontsize=10&stukid=2597]]>
+ + 6.73589462010654 + 53.15594584104552 + 0 + 139.6528910743265 + 1.45482979338997e-010 + 0.002950231733866508 + relativeToGround + + #msn_sunny_copy70 + + 6.73578802230557,53.15607461082266,0 + +
+ + Sundial, Hoogeveen, Netherlands +

]]>
+ + 6.469908327982116 + 52.72012840714818 + 0 + 73.67703044709106 + 4.200981642085038e-012 + -0.0001367978398152192 + relativeToGround + + #msn_sunny_copy70 + + 6.469803362243752,52.72017851542101,0 + +
+ + Sundial, Bicentennial Park, Homebush, Australia +

]]>
+ + 151.0785472180646 + -33.84641177017981 + 0 + 163.2808310648841 + 1.201655085829064e-011 + 4.265000695512084e-006 + relativeToGround + + #msn_sunny_copy70 + + 151.0784520824468,-33.84631674048389,0 + +
+ + Sundial, Heerenveen, Netherlands +

]]>
+ + 5.948360581453846 + 52.95021342348947 + 0 + 125.5263208537314 + 3.779142327674902e-010 + 2.174750871196e-005 + relativeToGround + + #msn_sunny_copy70 + + 5.94828156186523,52.95041125062435,0 + +
+ + Sundial, Zoetermeer, Netherlands +

+ +http://www.chabot.demon.nl/sundials/index3.htm]]>
+ + 4.48801136665803 + 52.03630549285332 + 0 + 64.63218166015471 + 0 + -0.0001443420778625332 + relativeToGround + + #msn_sunny_copy70 + + 4.48796065586356,52.03633054351467,0 + +
+ + Sundial, Lancaster, Lancashire, UK +

+ +

+ +

]]>
+ + -2.781711751106886 + 54.04618182827939 + 0 + 59.27999100628823 + 0 + 2.19677695423205e-005 + relativeToGround + + #msn_sunny_copy70 + + -2.781728090880108,54.0462693701831,0 + +
+ + Sundial, Nida, Lithuania +

]]>
+ + 20.99037235133227 + 55.29501544197078 + 0 + 177.9373429950499 + 4.620370977113893e-011 + 0.0005344762650417512 + relativeToGround + + #msn_sunny_copy70 + + 20.99033020665709,55.29525661423606,0 + +
+ + Sundial, Tavel, France +

+ +http://www.de-zonnewijzerkring.nl/zw-arch/eng-home-zw-07-03.htm]]>
+ + 4.700355808916944 + 44.00154771856498 + 0 + 254.0752666918187 + 2.46623000787332e-010 + -0.0002391009248289202 + relativeToGround + + #msn_sunny_copy70 + + 4.700351044280055,44.00172761202828,0 + +
+ + Sundial, St. Michielsgestel, Netherlands +

+ +

]]>
+ + 5.346086124850936 + 51.64327189620946 + 0 + 111.9437734662239 + 6.47253437341193e-010 + 0.002375287388397793 + relativeToGround + + #msn_sunny_copy70 + + 5.346049636943462,51.64334209867396,0 + +
+ + Sundial, Halle Saale, Germany +

+ +More photos:http://home.arcor.de/peter.lindner/sonnenuhr/h/halle_saale_061xx/halle_saale_061xx.htm]]>
+ + 11.94846541701928 + 51.49449346439673 + 0 + 51.14591828296211 + 0 + 0.0003207363265956715 + relativeToGround + + #msn_sunny_copy70 + + 11.9484244247504,51.49452140024068,0 + +
+ + Sundial, Abano Terme, Italy +

+ +http://members.aon.at/sundials/bild43_d.htm]]>
+ + 11.7902588657866 + 45.36024293920432 + 0 + 88.27261765894279 + 5.645767845941023e-011 + 0.0006214879519801648 + relativeToGround + + #msn_sunny_copy70 + + 11.79017178556217,45.36037512888652,0 + +
+ + Sundial, Gasworks Park, Seattle, USA +

]]>
+ + -122.3362979085422 + 47.64532276753428 + 0 + 144.9142629968483 + 1.398328526418574e-010 + -0.002257590778485548 + relativeToGround + + #msn_sunny_copy70 + + -122.3363617333393,47.64542146106401,0 + +
+ + Sundial, Biarritz, France +

]]>
+ + -1.554172472866423 + 43.49326953476108 + 0 + 25.2767811064234 + 1.050991544755056e-009 + 0.004580769709390601 + relativeToGround + + #msn_sunny_copy70 + + -1.554180928484328,43.49329288628002,0 + +
+ + Sundial, Biarritz, France +

]]>
+ + -1.566562523529829 + 43.48379630381277 + 0 + 21.65084680450158 + 3.134801309486055e-010 + -0.003938809314781338 + relativeToGround + + #msn_sunny_copy70 + + -1.566563732160418,43.48381046528652,0 + +
+ + Sundial, Gardens of Easton Lodge, UK +

+ +

+ +http://www.sundials.co.uk/newdials.htm]]>
+ + 0.3149818536825662 + 51.89078052542742 + 0 + 55.96449646091584 + 4.648925194094304e-010 + 0.00100690081475908 + relativeToGround + + #msn_sunny_copy70 + + 0.3149732952370528,51.89085713320831,0 + +
+ + Sundial, Drake University, Des Moines, Iowa, USA +

]]>
+ + -93.65212284615454 + 41.60195541103381 + 0 + 78.72982107342352 + 1.765081595632672e-010 + 0.001286572559733559 + relativeToGround + + #msn_sunny_copy70 + + -93.65218647671061,41.60204463077999,0 + +
+ + Sundial, River State Park, Indianapolis, USA +

]]>
+ + -86.17152524772823 + 39.76773209074677 + 0 + 54.39844455317644 + 0 + 0.002275213067656348 + relativeToGround + + #msn_sunny_copy70 + + -86.17158357583082,39.76772499391254,0 + +
+ + Sundial, Lawrence Hall of Science, Berkeley, CA, USA +

]]>
+ + -122.2467934369336 + 37.87843955912407 + 0 + 75.73772829567238 + 0 + -0.0005027058674008065 + relativeToGround + + #msn_sunny_copy70 + + -122.2468395686324,37.87850249930867,0 + +
+ + Sundial, Riverwalk, Augusta, Georgia, USA +

]]>
+ + -81.96495913544699 + 33.47855115889769 + 0 + 24.10683016246917 + 0 + -0.004039593559848222 + relativeToGround + + #msn_sunny_copy70 + + -81.96497422223469,33.47856125757188,0 + +
+ + Sundial, Reggio nell'Emilia, Italy +

+

Image source:http://perso.orange.fr

]]>
+ + 10.64303919389926 + 44.71779646338597 + 0 + 189.7095730357674 + 0 + 0.0003188808607201916 + relativeToGround + + #msn_sunny_copy70 + + 10.64294491831197,44.71794161105381,0 + +
+ + Sundial, Rennes, France +

+ +

Image source:http://perso.orange.fr

]]>
+ + -1.701676278457902 + 48.13126501865703 + 0 + 61.61200771227915 + 0 + -7.297875936612596e-006 + relativeToGround + + #msn_sunny_copy70 + + -1.701699217745187,48.13129604209563,0 + +
+ + Sundial, Schneverdingen, Germany +

]]>
+ + 9.790867938787324 + 53.12943797238091 + 0 + 106.7617213575405 + 4.722006958129564e-010 + 0.00116683463628678 + relativeToGround + + #msn_sunny_copy70 + + 9.790707601654233,53.12958381093443,0 + +
+ + Sundial Obelisk, Charleston, South Carolina +

+ +

Image credit:www.groundspeak.com

]]>
+ + -79.93166502066842 + 32.76970334074068 + 0 + 75.62015855417492 + 4.052617221081382e-011 + 1.8933011389851e-005 + relativeToGround + + #msn_sunny_copy70 + + -79.93172500691688,32.76973746165206,0 + +
+ + Sundial, Morehead Planetarium, Chapel Hill, North Carolina +

+ +

Image credit:www.groundspeak.com

]]>
+ + -79.050938325099 + 35.91448691988588 + 0 + 64.77863580575449 + 0 + 1.662447442472179e-005 + relativeToGround + + #msn_sunny_copy70 + + -79.05097493816135,35.91457037097104,0 + +
+ + Sundial, Berkeley, +California +

+ +

Image credit:www.groundspeak.com

]]>
+ + -122.3174670551103 + 37.86291969151575 + 0 + 46.45520126730318 + 1.288314315217904e-009 + 2.022127862982459e-005 + relativeToGround + + #msn_sunny_copy70 + + -122.317517078111,37.86295037394118,0 + +
+ + Forest Lawn Cemetery Sundial, Buffalo, NY +

+ +

Image credit:www.groundspeak.com

]]>
+ + -78.85654999999994 + 42.92531666666667 + 0 + 76.25216432595194 + 0 + 1.305178628551349e-014 + relativeToGround + + #msn_sunny_copy70 + + -78.85660856395873,42.92539096384056,0 + +
+ + Ruston Way Sundial ,Tacoma, Washington +

+ +

Image credit:www.groundspeak.com

]]>
+ + -122.4622812282256 + 47.27566486193976 + 0 + 62.22457114364932 + 0 + 0.0001239840172672445 + relativeToGround + + #msn_sunny_copy70 + + -122.4623519976878,47.27567991760397,0 + +
+ + Sundial ,Science Central, Fort Wayne, Indiana +

+ +

Image credit:www.groundspeak.com

]]>
+ + -85.1392719076301 + 41.09135262868964 + 0 + 39.45104173043256 + 0 + -1.439899387224993e-005 + relativeToGround + + #msn_sunny_copy70 + + -85.13931366905783,41.09136114213859,0 + +
+ + Berkswich Millennium Sundial, Broc Hill, Staffordshire, UK +

+ +

Image credit:www.groundspeak.com

]]>
+ + -2.038136129920761 + 52.77711389120437 + 0 + 29.50351061813827 + 0 + 3.758749562499077e-005 + relativeToGround + + #msn_sunny_copy70 + + -2.038162283146562,52.77714418176907,0 + +
+ + Sundial, Tazacorte Beach ,La Palma island +

+ +

Image credit:www.groundspeak.com

]]>
+ + -17.9461489138289 + 28.65121498294262 + 0 + 64.36805201552387 + 0 + 4.047704004228316e-005 + relativeToGround + + #msn_sunny_copy70 + + -17.94620263531645,28.65124065936443,0 + +
+ + Sundial, Rochester, NY +

+ +

Image credit:www.groundspeak.com

]]>
+ + -77.66915367541856 + 43.0844306339545 + 0 + 61.69080872372956 + 0 + 9.994948692290747e-005 + relativeToGround + + #msn_sunny_copy70 + + -77.66917908415978,43.08440844604031,0 + +
+ + Sundial, Center of the World, Felicity, CA +

+ +

+The 15 foot Sundial at Felicity is a three-dimensional bronze of Michelangelo's Arm of God painted on the Sistine Chapel ceiling. The arm was sculpted and cast in bronze in New England. The rock is local but the installation required the assistance of a mining engineer and a special drill. The bronze Roman numerals give the time. A sundial is precisely accurate once a year and this was set at noon on Christmas Day. The arm points to the Hill of Prayer, site of the Church on the Hill at Felicity. +At the entrance to The Center of the World campus is a 25 ft. high section of the original stairway of the Eiffel Tower. In 1983, the Government of France removed approximately 500 ft. of the original stairway. Built with the technology of the 1860's, the weight of approximately 54,000 lbs. was causing sway at the top of the then 94 year old tower. The 6,600 lb. section serves no practical purpose, but is part of the spirit of Felicity. +The idea of making Felicity the Center of the World came to Jacques-André when he'd been mayor only a few months. Somehow he convinced Imperial County, CA, to recognize his claim. Soon he had convinced the Institut Geographique National of France, General Dynamics Corporation, and The People's Republic of China to recognize it as well. "I knew I had to build something, but I didn't know what. My wife said, 'It's a desert; why not a pyramid?' So Jacques-André had built a 21-foot-tall pink marble pyramid, its interior lined with mirrors, a plaque embedded in the floor, marking the exact spot. For a dollar, tourists can now stand on the official Center Of The World and take a picture themselves at the official "Center Of The World". +The Felicity Post Office was dedicated on 5 December 1987 at a time when thousands of small post offices were being eliminated as an economy measure. The town, whose population numbered two, saw over 2,300 letters mailed that day. The dedication ceremony was highlighted by a speech in Chinese by Consul Zhou of the People’s Republic of China who traveled 600 miles for the occasion. It is operated by the town at a cost to the Federal Government of one dollar per year. Twenty uncashed one dollar checks are on file.

+ +

Image and info credit:www.groundspeak.com

]]>
+ + -114.7654750861393 + 32.74988921016088 + 0 + 72.95555856498569 + 0 + 3.146266385893141e-005 + relativeToGround + + #msn_sunny_copy70 + + -114.7655284077745,32.74992976207647,0 + +
+ + University of São Paulo Sundial, Sao Paulo, Brazi +

+ +

Image credit:www.groundspeak.com

]]>
+ + -46.7204986760494 + -23.56120553413547 + 0 + 122.7188487961642 + 0 + 2.610051397350573e-005 + relativeToGround + + #msn_sunny_copy70 + + -46.7205459522717,-23.56115337159118,0 + +
+ + Slate bowl Sundial, Holker, UK +

+ +

Image credit:www.groundspeak.com

]]>
+ + -2.987191130383048 + 54.188865359179 + 0 + 98.16442365143851 + 2.595660029656298e-010 + 0.000142350860720713 + relativeToGround + + #msn_sunny_copy70 + + -2.987342530279506,54.18895843924356,0 + +
+ + Sundial, Jardin des Doms, Avignon +

+ +

Image credit:www.groundspeak.com

]]>
+ + 4.807697613943427 + 43.95301885165002 + 0 + 32.75914708134153 + 1.205283678723288e-009 + 2.147953504845766e-005 + relativeToGround + + #msn_sunny_copy70 + + 4.807672022945837,43.95303620373285,0 + +
+ + Rillito Riverpark Sundial, Tucson, AZ +

+ +

Image credit:www.groundspeak.com

]]>
+ + -111.0075277787534 + 32.30113621710221 + 0 + 94.15682746212195 + 0 + 2.968664599173171e-005 + relativeToGround + + #msn_sunny_copy70 + + -111.0075933392788,32.30113929573149,0 + +
+ + Helium Monument Sundial, Amarillo, TX +

+ +

Image credit:www.groundspeak.com

]]>
+ + -101.9132978901728 + 35.19956726276647 + 0 + 60.53404995378031 + 5.162016480480558e-011 + 3.00374135059527e-005 + relativeToGround + + #msn_sunny_copy70 + + -101.9133182362553,35.19966266329223,0 + +
+ + Sundial, Hershey, Pennsylvania +

+ +

Image credit:www.groundspeak.com

]]>
+ + -76.62980321024054 + 40.27170452963257 + 0 + 72.41553799015709 + 2.798231534250927e-010 + 6.256605840320539e-005 + relativeToGround + + #msn_sunny_copy70 + + -76.6298565862236,40.2718754812139,0 + +
+ + King Neptune Sundial, Hilton Head Island, South Carolina +

+ +

Image credit:www.groundspeak.com

]]>
+ + -80.72801698168738 + 32.18076491029077 + 0 + 86.36647046692004 + 2.346233297172379e-010 + 8.72178085589082e-006 + relativeToGround + + #msn_sunny_copy70 + + -80.72806102317654,32.18084680335104,0 + +
+ + Jane Larue Memorial Sundial - Ann Arbor, Michigan +

+ +

Image credit:www.groundspeak.com

]]>
+ + -83.66222470201295 + 42.30114702626376 + 0 + 26.29476256996721 + 0 + 0.0001291940559531826 + relativeToGround + + #msn_sunny_copy70 + + -83.66224748552365,42.30117333470928,0 + +
+
+ + Schoolyard Sundials + + Sundial, Julius-Brecht-Allee, Bremen + + 8.8674012861685 + 53.07651505713779 + 0 + 20.6687721420542 + 9.001122528249614e-011 + -0.00437506724289509 + relativeToGround + + #msn_sunny_copy69 + + 8.867391721405184,53.07654483342672,0 + + + + Sundial, Drebberstraße, Bremen +

]]>
+ + 8.898052233187912 + 53.0400952944841 + 0 + 14.44345748598086 + 0 + -0.001637659480767247 + relativeToGround + + #msn_sunny_copy69 + + 8.898047664850367,53.04011230005033,0 + +
+ + Sundial, Butjadingersrasse, Bremen +

]]>
+ + 8.759747956980032 + 53.08143879125452 + 0 + 37.83897098076405 + 0 + -0.002629545926081431 + relativeToGround + + #msn_sunny_copy69 + + 8.759712018733111,53.08151322706201,0 + +
+
+ + In Progress + + Sundial, Greenwich, USA +

]]>
+ + -73.61498302559443 + 41.02226092221508 + 0 + 149.2259168633856 + 1.357926888487057e-010 + -0.001539166856947675 + relativeToGround + + #msn_sunny_copy69 + + -73.61504279924034,41.022311140554,0 + +
+ + Sonnenuhr? + + 11.05508326700377 + 49.45922489288633 + 0 + 50.88443884213967 + 8.335955203191607e-009 + 0.0196675278275586 + relativeToGround + + #msn_sunny_copy69 + + 11.0551380716084,49.45927364486676,0 + + + + Sundial, Edgewood Park, New Haven, USA +

+ +

]]> + + -72.95215163561284 + 41.31399188322968 + 0 + 154.2904142456261 + 0 + 0.002187256502984029 + relativeToGround + + #msn_sunny_copy69 + + -72.95224192688632,41.31401837758977,0 + + + + Sundial, Pearl City, Oahu, USA +

]]>
+ + -157.975920511215 + 21.39370171784438 + 0 + 93.82906502148613 + 0 + -0.001426474135915891 + relativeToGround + + #msn_sunny_copy69 + + -157.9759385077734,21.39376422631041,0 + +
+ + Sundial + http://maget.maget.free.fr/SiteMont/index.html + + -1.511135684750573 + 48.63640399624012 + 0 + 623.6899626138724 + 0 + -1.851737885201182e-005 + relativeToGround + + #msn_sunny_copy69 + + -1.511518347366319,48.63786003229999,0 + + + + Mont-Saint-Michel + http://maget.maget.free.fr/SiteMont/MSpage4.htm + + http://maget.maget.free.fr/SiteMont/images/le_Mont_Solaire-Land%20Art.jpg + 0.75 + + + 48.63770978435333 + 48.6344604605756 + -1.5070705975067 + -1.514375149320612 + -11.46597601725745 + + + + Sundial Park, Ludiver park + http://perso.orange.fr/cadrans.solaires/cadrans/cadran-parc-ludiver.html + + -1.727863357864637 + 49.63119498354116 + 0 + 473.1060190443535 + 3.883358970183465e-011 + 0.0005701632901766135 + relativeToGround + + #msn_sunny_copy69 + + -1.728331456927833,49.63191584214422,0 + + + + Sonnenuhr? + + 7.68545763101957 + 51.53642499090419 + 0 + 23.70363190324798 + 4.475657800962137e-010 + -0.1674345977313924 + relativeToGround + + #msn_sunny_copy69 + + 7.685416995069303,51.53648149450991,0 + + + + Sundial at Tower of London + ]]> + + -0.07656780337525181 + 51.50981727675416 + 0 + 61.73369699893549 + 9.251491983355112e-010 + 0.009688876514144714 + + #msn_sunny_copy69 + + -0.07656780337525181,51.50981727675417,0 + + + + War Veterans' Memorial Park Sundial, Florida, United States + + -82.77333790901622 + 27.8036881517592 + 0 + 96.43655563554265 + 4.405141995417006e-010 + 9.892674215924156e-005 + relativeToGround + + #msn_sunny_copy69 + + -82.77341348054247,27.80374932310448,0 + + +
+
+
+
diff --git a/examples/thinlong.jpg b/examples/thinlong.jpg new file mode 100755 index 0000000000..a063ab453d Binary files /dev/null and b/examples/thinlong.jpg differ diff --git a/examples/widelong.jpg b/examples/widelong.jpg new file mode 100755 index 0000000000..7ed1c5e73c Binary files /dev/null and b/examples/widelong.jpg differ diff --git a/examples/wideshort.jpg b/examples/wideshort.jpg new file mode 100755 index 0000000000..9839b82f0f Binary files /dev/null and b/examples/wideshort.jpg differ diff --git a/img/cloud-popup-relative.png b/img/cloud-popup-relative.png new file mode 100755 index 0000000000..9db138abe9 Binary files /dev/null and b/img/cloud-popup-relative.png differ diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js index c29021b67c..354f705bc3 100644 --- a/lib/OpenLayers.js +++ b/lib/OpenLayers.js @@ -120,6 +120,8 @@ "OpenLayers/Layer/TileCache.js", "OpenLayers/Popup/Anchored.js", "OpenLayers/Popup/AnchoredBubble.js", + "OpenLayers/Popup/Framed.js", + "OpenLayers/Popup/FramedCloud.js", "OpenLayers/Feature.js", "OpenLayers/Feature/Vector.js", "OpenLayers/Feature/WFS.js", diff --git a/lib/OpenLayers/Control.js b/lib/OpenLayers/Control.js index d1196f3c0e..a98cc00e3e 100644 --- a/lib/OpenLayers/Control.js +++ b/lib/OpenLayers/Control.js @@ -78,15 +78,6 @@ OpenLayers.Control = OpenLayers.Class({ */ type: null, - /** - * Property: allowSelection - * {Boolean} By deafault, controls do not allow selection, because - * it may interfere with map dragging. If this is true, OpenLayers - * will not prevent selection of the control. - * Default is false. - */ - allowSelection: false, - /** * Property: displayClass * {string} This property is used for CSS related to the drawing of the @@ -249,11 +240,6 @@ OpenLayers.Control = OpenLayers.Class({ if (this.div == null) { this.div = OpenLayers.Util.createDiv(this.id); this.div.className = this.displayClass; - if (!this.allowSelection) { - this.div.className += " olControlNoSelect"; - this.div.setAttribute("unselectable", "on", 0); - this.div.onselectstart = function() { return(false); }; - } if (this.title != "") { this.div.title = this.title; } diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js index 93776b075f..feda3b10e7 100644 --- a/lib/OpenLayers/Map.js +++ b/lib/OpenLayers/Map.js @@ -353,6 +353,13 @@ OpenLayers.Map = OpenLayers.Class({ */ panMethod: OpenLayers.Easing.Expo.easeOut, + /** + * Property: paddingForPopups + * {} Outside margin of the popup. Used to prevent + * the popup from getting too close to the map border. + */ + paddingForPopups : null, + /** * Constructor: OpenLayers.Map * Constructor for a new OpenLayers.Map instance. @@ -384,6 +391,8 @@ OpenLayers.Map = OpenLayers.Class({ OpenLayers.Map.TILE_HEIGHT); this.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90); + + this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15); this.theme = OpenLayers._getScriptLocation() + 'theme/default/style.css'; @@ -525,6 +534,8 @@ OpenLayers.Map = OpenLayers.Class({ } else { this.events.unregister("resize", this, this.updateSize); } + + this.paddingForPopups = null; if (this.controls != null) { for (var i = this.controls.length - 1; i>=0; --i) { diff --git a/lib/OpenLayers/Popup.js b/lib/OpenLayers/Popup.js index a9aa8ac5e4..94c4eec041 100644 --- a/lib/OpenLayers/Popup.js +++ b/lib/OpenLayers/Popup.js @@ -86,7 +86,8 @@ OpenLayers.Popup = OpenLayers.Class({ /** * Property: groupDiv - * {DOMElement} the parent of + * {DOMElement} First and only child of 'div'. The group Div contains the + * 'contentDiv' and the 'closeDiv'. */ groupDiv: null, @@ -97,12 +98,64 @@ OpenLayers.Popup = OpenLayers.Class({ closeDiv: null, /** - * Property: padding - * {int} the internal padding of the content div. + * APIProperty: autoSize + * {Boolean} Resize the popup to auto-fit the contents. + * Default is false. */ - padding: 5, + autoSize: false, + /** + * APIProperty: minSize + * {} Minimum size allowed for the popup's contents. + */ + minSize: null, + /** + * APIProperty: maxSize + * {} Maximum size allowed for the popup's contents. + */ + maxSize: null, + + /** + * Property: padding + * {int or } An extra opportunity to specify internal + * padding of the content div inside the popup. This was originally + * confused with the css padding as specified in style.css's + * 'olPopupContent' class. We would like to get rid of this altogether, + * except that it does come in handy for the framed and anchoredbubble + * popups, who need to maintain yet another barrier between their + * content and the outer border of the popup itself. + * + * Note that in order to not break API, we must continue to support + * this property being set as an integer. Really, though, we'd like to + * have this specified as a Bounds object so that user can specify + * distinct left, top, right, bottom paddings. With the 3.0 release + * we can make this only a bounds. + */ + padding: 0, + + /** + * Method: fixPadding + * To be removed in 3.0, this function merely helps us to deal with the + * case where the user may have set an integer value for padding, + * instead of an object. + */ + fixPadding: function() { + if (typeof this.padding == "number") { + this.padding = new OpenLayers.Bounds( + this.padding, this.padding, this.padding, this.padding + ); + } + }, + + /** + * APIProperty: panMapIfOutOfView + * {Boolean} When drawn, pan map such that the entire popup is visible in + * the current viewport (if necessary). + * Default is false. + */ + panMapIfOutOfView: false, + /** * Property: map * {} this gets set in Map.js when the popup is added to the map @@ -147,37 +200,21 @@ OpenLayers.Popup = OpenLayers.Class({ null, null, null, "hidden"); this.div.className = 'olPopup'; - this.groupDiv = OpenLayers.Util.createDiv(null, null, null, + var groupDivId = this.id + "_GroupDiv"; + this.groupDiv = OpenLayers.Util.createDiv(groupDivId, null, null, null, "relative", null, "hidden"); var id = this.div.id + "_contentDiv"; this.contentDiv = OpenLayers.Util.createDiv(id, null, this.size.clone(), - null, "relative", null, - "hidden"); + null, "relative"); this.contentDiv.className = 'olPopupContent'; this.groupDiv.appendChild(this.contentDiv); this.div.appendChild(this.groupDiv); if (closeBox) { - // close icon - var closeSize = new OpenLayers.Size(17,17); - var img = OpenLayers.Util.getImagesLocation() + "close.gif"; - this.closeDiv = OpenLayers.Util.createAlphaImageDiv( - this.id + "_close", null, closeSize, img - ); - this.closeDiv.style.right = this.padding + "px"; - this.closeDiv.style.top = this.padding + "px"; - this.groupDiv.appendChild(this.closeDiv); - - var closePopup = closeBoxCallback || function(e) { - this.hide(); - OpenLayers.Event.stop(e); - }; - OpenLayers.Event.observe(this.closeDiv, "click", - OpenLayers.Function.bindAsEventListener(closePopup, this)); - - } + this.addCloseBox(closeBoxCallback); + } this.registerEvents(); }, @@ -187,13 +224,39 @@ OpenLayers.Popup = OpenLayers.Class({ * nullify references to prevent circular references and memory leaks */ destroy: function() { - if (this.map != null) { - this.map.removePopup(this); - this.map = null; - } + + this.id = null; + this.lonlat = null; + this.size = null; + this.contentHTML = null; + + this.backgroundColor = null; + this.opacity = null; + this.border = null; + this.events.destroy(); this.events = null; + + if (this.closeDiv) { + OpenLayers.Event.stopObservingElement(this.closeDiv); + this.groupDiv.removeChild(this.closeDiv); + } + this.closeDiv = null; + + this.div.removeChild(this.groupDiv); + this.groupDiv = null; + + if (this.map != null) { + this.map.removePopup(this); + } + this.map = null; this.div = null; + + this.autoSize = null; + this.minSize = null; + this.maxSize = null; + this.padding = null; + this.panMapIfOutOfView = null; }, /** @@ -213,12 +276,39 @@ OpenLayers.Popup = OpenLayers.Class({ } } - this.setSize(); + //listen to movestart, moveend to disable overflow (FF bug) + if (OpenLayers.Util.getBrowserName() == 'firefox') { + this.map.events.register("movestart", this, function() { + var style = document.defaultView.getComputedStyle( + this.contentDiv, null + ); + var currentOverflow = style.getPropertyValue("overflow"); + if (currentOverflow != "hidden") { + this.contentDiv._oldOverflow = currentOverflow; + this.contentDiv.style.overflow = "hidden"; + } + }); + this.map.events.register("moveend", this, function() { + var oldOverflow = this.contentDiv._oldOverflow; + if (oldOverflow) { + this.contentDiv.style.overflow = oldOverflow; + this.contentDiv._oldOverflow = null; + } + }); + } + + this.moveTo(px); + if (!this.autoSize) { + this.setSize(this.size); + } this.setBackgroundColor(); this.setOpacity(); this.setBorder(); this.setContentHTML(); - this.moveTo(px); + + if (this.panMapIfOutOfView) { + this.panIntoView(); + } return this.div; }, @@ -265,7 +355,11 @@ OpenLayers.Popup = OpenLayers.Class({ * Toggles visibility of the popup. */ toggle: function() { - OpenLayers.Element.toggle(this.div); + if (this.visible()) { + this.hide(); + } else { + this.show(); + } }, /** @@ -274,6 +368,10 @@ OpenLayers.Popup = OpenLayers.Class({ */ show: function() { OpenLayers.Element.show(this.div); + + if (this.panMapIfOutOfView) { + this.panIntoView(); + } }, /** @@ -289,30 +387,61 @@ OpenLayers.Popup = OpenLayers.Class({ * Used to adjust the size of the popup. * * Parameters: - * size - {} the new size of the popup in pixels. + * size - {} the new size of the popup's contents div + * (in pixels). */ setSize:function(size) { - if (size != undefined) { - this.size = size; - } + this.size = size; + + var contentSize = this.size.clone(); + // if our contentDiv has a css 'padding' set on it by a stylesheet, we + // must add that to the desired "size". + var contentDivPadding = this.getContentDivPadding(); + var wPadding = contentDivPadding.left + contentDivPadding.right; + var hPadding = contentDivPadding.top + contentDivPadding.bottom; + + // take into account the popup's 'padding' property + this.fixPadding(); + wPadding += this.padding.left + this.padding.right; + hPadding += this.padding.top + this.padding.bottom; + + // make extra space for the close div + if (this.closeDiv) { + var closeDivWidth = parseInt(this.closeDiv.style.width); + wPadding += closeDivWidth + contentDivPadding.right; + } + + //increase size of the main popup div to take into account the + // users's desired padding and close div. + this.size.w += wPadding; + this.size.h += hPadding; + + //now if our browser is IE, we need to actually make the contents + // div itself bigger to take its own padding into effect. this makes + // me want to shoot someone, but so it goes. + if (OpenLayers.Util.getBrowserName() == "msie") { + contentSize.w += contentDivPadding.left + contentDivPadding.right; + contentSize.h += contentDivPadding.bottom + contentDivPadding.top; + } + if (this.div != null) { this.div.style.width = this.size.w + "px"; this.div.style.height = this.size.h + "px"; } if (this.contentDiv != null){ - this.contentDiv.style.width = this.size.w + "px"; - this.contentDiv.style.height = this.size.h + "px"; + this.contentDiv.style.width = contentSize.w + "px"; + this.contentDiv.style.height = contentSize.h + "px"; } }, /** - * Method: setBackgroundColor - * Sets the background color of the popup. - * - * Parameters: - * color - {String} the background color. eg "#FFBBBB" - */ + * Method: setBackgroundColor + * Sets the background color of the popup. + * + * Parameters: + * color - {String} the background color. eg "#FFBBBB" + */ setBackgroundColor:function(color) { if (color != undefined) { this.backgroundColor = color; @@ -373,13 +502,256 @@ OpenLayers.Popup = OpenLayers.Class({ this.contentHTML = contentHTML; } + if (this.autoSize) { + + // determine actual render dimensions of the contents + var realSize = + OpenLayers.Util.getRenderedDimensions(this.contentHTML); + + // is the "real" size of the div is safe to display in our map? + var safeSize = this.getSafeContentSize(realSize); + + var newSize = null; + + if (safeSize.equals(realSize)) { + //real size of content is small enough to fit on the map, + // so we use real size. + newSize = realSize; + + } else { + + //make a new OL.Size object with the clipped dimensions + // set or null if not clipped. + var fixedSize = new OpenLayers.Size(); + fixedSize.w = (safeSize.w < realSize.w) ? safeSize.w : null; + fixedSize.h = (safeSize.h < realSize.h) ? safeSize.h : null; + + if (fixedSize.w && fixedSize.h) { + //content is too big in both directions, so we will use + // max popup size (safeSize), knowing well that it will + // overflow both ways. + newSize = safeSize; + } else { + //content is clipped in only one direction, so we need to + // run getRenderedDimensions() again with a fixed dimension + var clippedSize = OpenLayers.Util.getRenderedDimensions( + this.contentHTML, fixedSize + ); + + //if the clipped size is still the same as the safeSize, + // that means that our content must be fixed in the + // offending direction. If overflow is 'auto', this means + // we are going to have a scrollbar for sure, so we must + // adjust for that. + // + var currentOverflow = OpenLayers.Element.getStyle( + this.contentDiv, "overflow" + ); + if ( (currentOverflow != "hidden") && + (clippedSize.equals(safeSize)) ) { + var scrollBar = OpenLayers.Util.getScrollbarWidth(); + if (fixedSize.w) { + clippedSize.h += scrollBar; + } else { + clippedSize.w += scrollBar; + } + } + + newSize = this.getSafeContentSize(clippedSize); + } + } + this.setSize(newSize); + } + if (this.contentDiv != null) { this.contentDiv.innerHTML = this.contentHTML; } }, + /** + * APIMethod: getSafeContentSize + * + * Parameters: + * size - {} Desired size to make the popup. + * + * Returns: + * {} A size to make the popup which is neither smaller + * than the specified minimum size, nor bigger than the maximum + * size (which is calculated relative to the size of the viewport). + */ + getSafeContentSize: function(size) { + + var safeContentSize = size.clone(); + + // if our contentDiv has a css 'padding' set on it by a stylesheet, we + // must add that to the desired "size". + var contentDivPadding = this.getContentDivPadding(); + var wPadding = contentDivPadding.left + contentDivPadding.right; + var hPadding = contentDivPadding.top + contentDivPadding.bottom; + + // take into account the popup's 'padding' property + this.fixPadding(); + wPadding += this.padding.left + this.padding.right; + hPadding += this.padding.top + this.padding.bottom; + + if (this.closeDiv) { + var closeDivWidth = parseInt(this.closeDiv.style.width); + wPadding += closeDivWidth + contentDivPadding.right; + } + + // prevent the popup from being smaller than a specified minimal size + if (this.minSize) { + safeContentSize.w = Math.max(safeContentSize.w, + (this.minSize.w - wPadding)); + safeContentSize.h = Math.max(safeContentSize.h, + (this.minSize.h - hPadding)); + } + + // prevent the popup from being bigger than a specified maximum size + if (this.maxSize) { + safeContentSize.w = Math.min(safeContentSize.w, + (this.maxSize.w - wPadding)); + safeContentSize.h = Math.min(safeContentSize.h, + (this.maxSize.h - hPadding)); + } + + //make sure the desired size to set doesn't result in a popup that + // is bigger than the map's viewport. + // + if (this.map && this.map.size) { + + // Note that there *was* a reference to a + // 'OpenLayers.Popup.SCROLL_BAR_WIDTH' constant here, with special + // tolerance for it and everything... but it was never defined in + // the first place, so I don't know what to think. + + var maxY = this.map.size.h - + this.map.paddingForPopups.top - + this.map.paddingForPopups.bottom - + hPadding; + var maxX = this.map.size.w - + this.map.paddingForPopups.left - + this.map.paddingForPopups.right - + wPadding; + + safeContentSize.w = Math.min(safeContentSize.w, maxX); + safeContentSize.h = Math.min(safeContentSize.h, maxY); + } + + return safeContentSize; + }, + + /** + * Method: getContentDivPadding + * Glorious, oh glorious hack in order to determine the css 'padding' of + * the contentDiv. IE/Opera return null here unless we actually add the + * popup's main 'div' element (which contains contentDiv) to the DOM. + * So we make it invisible and then add it to the document temporarily. + * + * Once we've taken the padding readings we need, we then remove it + * from the DOM (it will actually get added to the DOM in + * Map.js's addPopup) + * + * Returns: + * {} + */ + getContentDivPadding: function() { + + //use cached value if we have it + var contentDivPadding = this._contentDivPadding; + if (!contentDivPadding) { + //make the div invisible and add it to the page + this.div.style.display = "none"; + document.body.appendChild(this.div); + + //read the padding settings from css, put them in an OL.Bounds + contentDivPadding = new OpenLayers.Bounds( + OpenLayers.Element.getStyle(this.contentDiv, "padding-left"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-bottom"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-right"), + OpenLayers.Element.getStyle(this.contentDiv, "padding-top") + ); + + //cache the value + this._contentDivPadding = contentDivPadding; + + //remove the div from the page and make it visible again + document.body.removeChild(this.div); + this.div.style.display = ""; + } + return contentDivPadding; + }, + + /** + * Method: addCloseBox + * + * Parameters: + * callback - {Function} The callback to be called when the close button + * is clicked. + */ + addCloseBox: function(callback) { + + this.closeDiv = OpenLayers.Util.createDiv( + this.id + "_close", null, new OpenLayers.Size(17, 17) + ); + this.closeDiv.className = "olPopupCloseBox"; + + // use the content div's css padding to determine if we should + // padd the close div + var contentDivPadding = this.getContentDivPadding(); + + this.closeDiv.style.right = contentDivPadding.right + "px"; + this.closeDiv.style.top = contentDivPadding.top + "px"; + this.groupDiv.appendChild(this.closeDiv); + + var closePopup = callback || function(e) { + this.hide(); + OpenLayers.Event.stop(e); + }; + OpenLayers.Event.observe(this.closeDiv, "click", + OpenLayers.Function.bindAsEventListener(closePopup, this)); + }, + + /** + * Method: panIntoView + * Pans the map such that the popup is totaly viewable (if necessary) + */ + panIntoView: function() { + + var mapSize = this.map.getSize(); + + //start with the top left corner of the popup, in px, + // relative to the viewport + var origTL = this.map.getViewPortPxFromLayerPx( new OpenLayers.Pixel( + parseInt(this.div.style.left), + parseInt(this.div.style.top) + )); + var newTL = origTL.clone(); + + //new left (compare to margins, using this.size to calculate right) + if (origTL.x < this.map.paddingForPopups.left) { + newTL.x = this.map.paddingForPopups.left; + } else + if ( (origTL.x + this.size.w) > (mapSize.w - this.map.paddingForPopups.right)) { + newTL.x = mapSize.w - this.map.paddingForPopups.right - this.size.w; + } + + //new top (compare to margins, using this.size to calculate bottom) + if (origTL.y < this.map.paddingForPopups.top) { + newTL.y = this.map.paddingForPopups.top; + } else + if ( (origTL.y + this.size.h) > (mapSize.h - this.map.paddingForPopups.bottom)) { + newTL.y = mapSize.h - this.map.paddingForPopups.bottom - this.size.h; + } + + var dx = origTL.x - newTL.x; + var dy = origTL.y - newTL.y; + + this.map.pan(dx, dy); + }, + /** * Method: registerEvents * Registers events on the popup. diff --git a/lib/OpenLayers/Popup/Anchored.js b/lib/OpenLayers/Popup/Anchored.js index f32c3ea439..d046f3a9cd 100644 --- a/lib/OpenLayers/Popup/Anchored.js +++ b/lib/OpenLayers/Popup/Anchored.js @@ -53,27 +53,71 @@ OpenLayers.Popup.Anchored = offset: new OpenLayers.Pixel(0,0)}; }, - /** - * Method: draw + /** + * APIMethod: destroy + */ + destroy: function() { + this.anchor = null; + this.relativePosition = null; + + OpenLayers.Popup.prototype.destroy.apply(this, arguments); + }, + + /** + * APIMethod: show + * Overridden from Popup since user might hide popup and then show() it + * in a new location (meaning we might want to update the relative + * position on the show) + */ + show: function() { + this.updatePosition(); + OpenLayers.Popup.prototype.show.apply(this, arguments); + }, + + /** + * Method: moveTo + * Since the popup is moving to a new px, it might need also to be moved + * relative to where the marker is. We first calculate the new + * relativePosition, and then we calculate the new px where we will + * put the popup, based on the new relative position. + * + * If the relativePosition has changed, we must also call + * updateRelativePosition() to make any visual changes to the popup + * which are associated with putting it in a new relativePosition. * * Parameters: * px - {} - * - * Returns: - * {DOMElement} Reference to a div that contains the drawn popup. */ - draw: function(px) { - if (px == null) { - if ((this.lonlat != null) && (this.map != null)) { - px = this.map.getLayerPxFromLonLat(this.lonlat); - } - } - - //calculate relative position + moveTo: function(px) { + var oldRelativePosition = this.relativePosition; this.relativePosition = this.calculateRelativePosition(px); - return OpenLayers.Popup.prototype.draw.apply(this, arguments); + var newPx = this.calculateNewPx(px); + + var newArguments = new Array(newPx); + OpenLayers.Popup.prototype.moveTo.apply(this, newArguments); + + //if this move has caused the popup to change its relative position, + // we need to make the appropriate cosmetic changes. + if (this.relativePosition != oldRelativePosition) { + this.updateRelativePosition(); + } }, + + /** + * APIMethod: setSize + * + * Parameters: + * size - {} + */ + setSize:function(size) { + OpenLayers.Popup.prototype.setSize.apply(this, arguments); + + if ((this.lonlat) && (this.map)) { + var px = this.map.getLayerPxFromLonLat(this.lonlat); + this.moveTo(px); + } + }, /** * Method: calculateRelativePosition @@ -95,37 +139,19 @@ OpenLayers.Popup.Anchored = }, /** - * Method: moveTo - * Since the popup is moving to a new px, it might need also to be moved - * relative to where the marker is. + * Method: updateRelativePosition + * The popup has been moved to a new relative location, so we may want to + * make some cosmetic adjustments to it. * - * Parameters: - * px - {} + * Note that in the classic Anchored popup, there is nothing to do + * here, since the popup looks exactly the same in all four positions. + * Subclasses such as the AnchoredBubble and Framed, however, will + * want to do something special here. */ - moveTo: function(px) { - this.relativePosition = this.calculateRelativePosition(px); - - var newPx = this.calculateNewPx(px); - - var newArguments = new Array(newPx); - OpenLayers.Popup.prototype.moveTo.apply(this, newArguments); + updateRelativePosition: function() { + //to be overridden by subclasses }, - - /** - * Method: setSize - * - * Parameters: - * size - {} - */ - setSize:function(size) { - OpenLayers.Popup.prototype.setSize.apply(this, arguments); - if ((this.lonlat) && (this.map)) { - var px = this.map.getLayerPxFromLonLat(this.lonlat); - this.moveTo(px); - } - }, - /** * Method: calculateNewPx * diff --git a/lib/OpenLayers/Popup/AnchoredBubble.js b/lib/OpenLayers/Popup/AnchoredBubble.js index aefb357191..38c486281f 100644 --- a/lib/OpenLayers/Popup/AnchoredBubble.js +++ b/lib/OpenLayers/Popup/AnchoredBubble.js @@ -38,6 +38,11 @@ OpenLayers.Popup.AnchoredBubble = */ initialize:function(id, lonlat, size, contentHTML, anchor, closeBox, closeBoxCallback) { + + this.padding = new OpenLayers.Bounds( + 0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE, + 0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE + ); OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments); }, @@ -64,17 +69,12 @@ OpenLayers.Popup.AnchoredBubble = }, /** - * Method: moveTo - * The popup may have been moved to a new relative location, in which case + * Method: updateRelativePosition + * The popup has been moved to a new relative location, in which case * we will want to re-do the rico corners. - * - * Parameters: - * px - {} */ - moveTo: function(px) { - OpenLayers.Popup.Anchored.prototype.moveTo.apply(this, arguments); - this.setRicoCorners(!this.rounded); - this.rounded = true; + updateRelativePosition: function() { + this.setRicoCorners(); }, /** @@ -85,22 +85,8 @@ OpenLayers.Popup.AnchoredBubble = */ setSize:function(size) { OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments); - - if (this.contentDiv != null) { - var contentSize = this.size.clone(); - contentSize.h -= (2 * OpenLayers.Popup.AnchoredBubble.CORNER_SIZE); - contentSize.h -= (2 * this.padding); - - this.contentDiv.style.height = contentSize.h + "px"; - this.contentDiv.style.width = contentSize.w + "px"; - - if (this.map) { - //size has changed - must redo corners - this.setRicoCorners(!this.rounded); - this.rounded = true; - } - } + this.setRicoCorners(); }, /** @@ -117,7 +103,7 @@ OpenLayers.Popup.AnchoredBubble = if (this.div != null) { if (this.contentDiv != null) { this.div.style.background = "transparent"; - OpenLayers.Rico.Corner.changeColor(this.contentDiv, + OpenLayers.Rico.Corner.changeColor(this.groupDiv, this.backgroundColor); } } @@ -154,11 +140,8 @@ OpenLayers.Popup.AnchoredBubble = /** * Method: setRicoCorners * Update RICO corners according to the popup's current relative postion. - * - * Parameters: - * firstTime - {Boolean} This the first time the corners are being rounded. */ - setRicoCorners:function(firstTime) { + setRicoCorners:function() { var corners = this.getCornersToRound(this.relativePosition); var options = {corners: corners, @@ -166,8 +149,9 @@ OpenLayers.Popup.AnchoredBubble = bgColor: "transparent", blend: false}; - if (firstTime) { + if (!this.rounded) { OpenLayers.Rico.Corner.round(this.div, options); + this.rounded = true; } else { OpenLayers.Rico.Corner.reRound(this.groupDiv, options); //set the popup color and opacity diff --git a/lib/OpenLayers/Popup/Framed.js b/lib/OpenLayers/Popup/Framed.js new file mode 100644 index 0000000000..ebd017f6a1 --- /dev/null +++ b/lib/OpenLayers/Popup/Framed.js @@ -0,0 +1,331 @@ +/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD + * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. */ + +/** + * @requires OpenLayers/Popup/Anchored.js + */ + +/** + * Class: OpenLayers.Popup.Framed + * + * Inherits from: + * - + */ +OpenLayers.Popup.Framed = + OpenLayers.Class(OpenLayers.Popup.Anchored, { + + /** + * Property: imageSrc + * {String} location of the image to be used as the popup frame + */ + imageSrc: null, + + /** + * Property: imageSize + * {} Size (measured in pixels) of the image located + * by the 'imageSrc' property. + */ + imageSize: null, + + /** + * APIProperty: isAlphaImage + * {Boolean} The image has some alpha and thus needs to use the alpha + * image hack. Note that setting this to true will have no noticeable + * effect in FF or IE7 browsers, but will all but crush the ie6 + * browser. + * Default is false. + */ + isAlphaImage: false, + + /** + * Property: positionBlocks + * {Object} Hash of different position blocks (Object/Hashs). Each block + * will be keyed by a two-character 'relativePosition' + * code string (ie "tl", "tr", "bl", "br"). Block properties are + * 'offset', 'padding' (self-explanatory), and finally the 'blocks' + * parameter, which is an array of the block objects. + * + * Each block object must have 'size', 'anchor', and 'position' + * properties. + * + * Note that positionBlocks should never be modified at runtime. + */ + positionBlocks: null, + + /** + * Property: blocks + * {Array[Object]} Array of objects, each of which is one "block" of the + * popup. Each block has a 'div' and an 'image' property, both of + * which are DOMElements, and the latter of which is appended to the + * former. These are reused as the popup goes changing positions for + * great economy and elegance. + */ + blocks: null, + + /** + * APIProperty: fixedRelativePosition + * {Boolean} We want the framed popup to work dynamically placed relative + * to its anchor but also in just one fixed position. A well designed + * framed popup will have the pixels and logic to display itself in + * any of the four relative positions, but (understandably), this will + * not be the case for all of them. By setting this property to 'true', + * framed popup will not recalculate for the best placement each time + * it's open, but will always open the same way. + * Note that if this is set to true, it is generally advisable to also + * set the 'panIntoView' property to true so that the popup can be + * scrolled into view (since it will often be offscreen on open) + * Default is false. + */ + fixedRelativePosition: false, + + /** + * Constructor: OpenLayers.Popup.Framed + * + * Parameters: + * id - {String} + * lonlat - {} + * size - {} + * contentHTML - {String} + * anchor - {Object} Object to which we'll anchor the popup. Must expose + * a 'size' () and 'offset' () + * (Note that this is generally an ). + * closeBox - {Boolean} + * closeBoxCallback - {Function} Function to be called on closeBox click. + */ + initialize:function(id, lonlat, size, contentHTML, anchor, closeBox, + closeBoxCallback) { + + OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments); + + if (this.fixedRelativePosition) { + //based on our decided relativePostion, set the current padding + // this keeps us from getting into trouble + this.updateRelativePosition(); + + //make calculateRelativePosition always returnt the specified + // fiexed position. + this.calculateRelativePosition = function(px) { + return this.relativePosition; + }; + } + + this.contentDiv.style.position = "absolute"; + this.contentDiv.style.zIndex = 1; + + if (closeBox) { + this.closeDiv.style.zIndex = 1; + } + + this.groupDiv.style.position = "absolute"; + this.groupDiv.style.top = "0px"; + this.groupDiv.style.left = "0px"; + this.groupDiv.style.height = "100%"; + this.groupDiv.style.width = "100%"; + }, + + /** + * APIMethod: destroy + */ + destroy: function() { + this.imageSrc = null; + this.imageSize = null; + this.isAlphaImage = null; + + this.fixedRelativePosition = false; + this.positionBlocks = null; + + //remove our blocks + for(var i = 0; i < this.blocks.length; i++) { + var block = this.blocks[i]; + + if (block.image) { + block.div.removeChild(block.image); + } + block.image = null; + + if (block.div) { + this.groupDiv.removeChild(block.div); + } + block.div = null; + } + this.blocks = null; + + OpenLayers.Popup.Anchored.prototype.destroy.apply(this, arguments); + }, + + /** + * APIMethod: setBackgroundColor + */ + setBackgroundColor:function(color) { + //does nothing since the framed popup's entire scheme is based on a + // an image -- changing the background color makes no sense. + }, + + /** + * APIMethod: setBorder + */ + setBorder:function() { + //does nothing since the framed popup's entire scheme is based on a + // an image -- changing the popup's border makes no sense. + }, + + /** + * Method: setOpacity + * Sets the opacity of the popup. + * + * Parameters: + * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid). + */ + setOpacity:function(opacity) { + //does nothing since we suppose that we'll never apply an opacity + // to a framed popup + }, + + /** + * APIMethod: setSize + * Overridden here, because we need to update the blocks whenever the size + * of the popup has changed. + * + * Parameters: + * size - {} + */ + setSize:function(size) { + OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments); + + this.updateBlocks(); + }, + + /** + * Method: updateRelativePosition + * When the relative position changes, we need to set the new padding + * BBOX on the popup, reposition the close div, and update the blocks. + */ + updateRelativePosition: function() { + + //update the padding + this.padding = this.positionBlocks[this.relativePosition].padding; + + //update the position of our close box to new padding + if (this.closeDiv) { + // use the content div's css padding to determine if we should + // padd the close div + var contentDivPadding = this.getContentDivPadding(); + + this.closeDiv.style.right = contentDivPadding.right + + this.padding.right + "px"; + this.closeDiv.style.top = contentDivPadding.top + + this.padding.top + "px"; + } + + this.updateBlocks(); + }, + + /** + * Method: calculateNewPx + * Besides the standard offset as determined by the Anchored class, our + * Framed popups have a special 'offset' property for each of their + * positions, which is used to offset the popup relative to its anchor. + * + * Parameters: + * px - {} + * + * Returns: + * {} The the new px position of the popup on the screen + * relative to the passed-in px. + */ + calculateNewPx:function(px) { + var newPx = OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply( + this, arguments + ); + + newPx = newPx.offset(this.positionBlocks[this.relativePosition].offset); + + return newPx; + }, + + /** + * Method: createBlocks + */ + createBlocks: function() { + this.blocks = []; + + var position = this.positionBlocks[this.relativePosition]; + for (var i = 0; i < position.blocks.length; i++) { + + var block = {}; + this.blocks.push(block); + + var divId = this.id + '_FrameDecorationDiv_' + i; + block.div = OpenLayers.Util.createDiv(divId, + null, null, null, "absolute", null, "hidden", null + ); + + var imgId = this.id + '_FrameDecorationImg_' + i; + var imageCreator = + (this.isAlphaImage) ? OpenLayers.Util.createAlphaImageDiv + : OpenLayers.Util.createImage; + + block.image = imageCreator(imgId, + null, this.imageSize, this.imageSrc, + "absolute", null, null, null + ); + + block.div.appendChild(block.image); + this.groupDiv.appendChild(block.div); + } + }, + + /** + * Method: updateBlocks + * Internal method, called on initialize and when the popup's relative + * position has changed. This function takes care of re-positioning + * the popup's blocks in their appropropriate places. + */ + updateBlocks: function() { + + if (!this.blocks) { + this.createBlocks(); + } + + var position = this.positionBlocks[this.relativePosition]; + for (var i = 0; i < position.blocks.length; i++) { + + var positionBlock = position.blocks[i]; + var block = this.blocks[i]; + + // adjust sizes + var l = positionBlock.anchor.left; + var b = positionBlock.anchor.bottom; + var r = positionBlock.anchor.right; + var t = positionBlock.anchor.top; + + //note that we use the isNaN() test here because if the + // size object is initialized with a "auto" parameter, the + // size constructor calls parseFloat() on the string, + // which will turn it into NaN + // + var w = (isNaN(positionBlock.size.w)) ? this.size.w - (r + l) + : positionBlock.size.w; + + var h = (isNaN(positionBlock.size.h)) ? this.size.h - (b + t) + : positionBlock.size.h; + + block.div.style.width = w + 'px'; + block.div.style.height = h + 'px'; + + block.div.style.left = (l != null) ? l + 'px' : ''; + block.div.style.bottom = (b != null) ? b + 'px' : ''; + block.div.style.right = (r != null) ? r + 'px' : ''; + block.div.style.top = (t != null) ? t + 'px' : ''; + + block.image.style.left = positionBlock.position.x + 'px'; + block.image.style.top = positionBlock.position.y + 'px'; + } + + this.contentDiv.style.left = this.padding.left + "px"; + this.contentDiv.style.top = this.padding.top + "px"; + }, + + CLASS_NAME: "OpenLayers.Popup.Framed" +}); diff --git a/lib/OpenLayers/Popup/FramedCloud.js b/lib/OpenLayers/Popup/FramedCloud.js new file mode 100644 index 0000000000..c9fc2d8755 --- /dev/null +++ b/lib/OpenLayers/Popup/FramedCloud.js @@ -0,0 +1,229 @@ +/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD + * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the + * full text of the license. */ + +/** + * @requires OpenLayers/Popup/Framed.js + * @requires OpenLayers/Util.js + */ + +/** + * Class: OpenLayers.Popup.FramedCloud + * + * Inherits from: + * - + */ +OpenLayers.Popup.FramedCloud = + OpenLayers.Class(OpenLayers.Popup.Framed, { + + /** + * APIProperty: autoSize + * {Boolean} Framed Cloud is autosizing by default. + */ + autoSize: true, + + /** + * APIProperty: panMapIfOutOfView + * {Boolean} Framed Cloud does pan into view by default. + */ + panMapIfOutOfView: true, + + /** + * Property: imageSrc + * {String} + */ + imageSrc: OpenLayers.Util.getImagesLocation() + 'cloud-popup-relative.png', + + /** + * APIProperty: imageSize + * {} + */ + imageSize: new OpenLayers.Size(676, 736), + + /** + * APIProperty: isAlphaImage + * {Boolean} The FramedCloud does not use an alpha image (in honor of the + * good ie6 folk out there) + */ + isAlphaImage: false, + + /** + * APIProperty: fixedRelativePosition + * {Boolean} The Framed Cloud popup works in just one fixed position. + */ + fixedRelativePosition: false, + + /** + * Property: positionBlocks + * {Object} Hash of differen position blocks, keyed by relativePosition + * two-character code string (ie "tl", "tr", "bl", "br") + */ + positionBlocks: { + "tl": { + 'offset': new OpenLayers.Pixel(44, 0), + 'padding': new OpenLayers.Bounds(8, 40, 8, 9), + 'blocks': [ + { // top-left + size: new OpenLayers.Size('auto', 'auto'), + anchor: new OpenLayers.Bounds(0, 51, 22, 0), + position: new OpenLayers.Pixel(0, 0) + }, + { //top-right + size: new OpenLayers.Size(22, 'auto'), + anchor: new OpenLayers.Bounds(null, 50, 0, 0), + position: new OpenLayers.Pixel(-638, 0) + }, + { //bottom-left + size: new OpenLayers.Size('auto', 21), + anchor: new OpenLayers.Bounds(0, 32, 80, null), + position: new OpenLayers.Pixel(0, -629) + }, + { //bottom-right + size: new OpenLayers.Size(22, 21), + anchor: new OpenLayers.Bounds(null, 32, 0, null), + position: new OpenLayers.Pixel(-638, -629) + }, + { // stem + size: new OpenLayers.Size(81, 54), + anchor: new OpenLayers.Bounds(null, 0, 0, null), + position: new OpenLayers.Pixel(0, -668) + } + ] + }, + "tr": { + 'offset': new OpenLayers.Pixel(-45, 0), + 'padding': new OpenLayers.Bounds(8, 40, 8, 9), + 'blocks': [ + { // top-left + size: new OpenLayers.Size('auto', 'auto'), + anchor: new OpenLayers.Bounds(0, 51, 22, 0), + position: new OpenLayers.Pixel(0, 0) + }, + { //top-right + size: new OpenLayers.Size(22, 'auto'), + anchor: new OpenLayers.Bounds(null, 50, 0, 0), + position: new OpenLayers.Pixel(-638, 0) + }, + { //bottom-left + size: new OpenLayers.Size('auto', 21), + anchor: new OpenLayers.Bounds(0, 32, 22, null), + position: new OpenLayers.Pixel(0, -629) + }, + { //bottom-right + size: new OpenLayers.Size(22, 21), + anchor: new OpenLayers.Bounds(null, 32, 0, null), + position: new OpenLayers.Pixel(-638, -629) + }, + { // stem + size: new OpenLayers.Size(81, 54), + anchor: new OpenLayers.Bounds(0, 0, null, null), + position: new OpenLayers.Pixel(-215, -668) + } + ] + }, + "bl": { + 'offset': new OpenLayers.Pixel(45, 0), + 'padding': new OpenLayers.Bounds(8, 9, 8, 40), + 'blocks': [ + { // top-left + size: new OpenLayers.Size('auto', 'auto'), + anchor: new OpenLayers.Bounds(0, 21, 22, 32), + position: new OpenLayers.Pixel(0, 0) + }, + { //top-right + size: new OpenLayers.Size(22, 'auto'), + anchor: new OpenLayers.Bounds(null, 21, 0, 32), + position: new OpenLayers.Pixel(-638, 0) + }, + { //bottom-left + size: new OpenLayers.Size('auto', 21), + anchor: new OpenLayers.Bounds(0, 0, 22, null), + position: new OpenLayers.Pixel(0, -629) + }, + { //bottom-right + size: new OpenLayers.Size(22, 21), + anchor: new OpenLayers.Bounds(null, 0, 0, null), + position: new OpenLayers.Pixel(-638, -629) + }, + { // stem + size: new OpenLayers.Size(81, 54), + anchor: new OpenLayers.Bounds(null, null, 0, 0), + position: new OpenLayers.Pixel(-101, -674) + } + ] + }, + "br": { + 'offset': new OpenLayers.Pixel(-44, 0), + 'padding': new OpenLayers.Bounds(8, 9, 8, 40), + 'blocks': [ + { // top-left + size: new OpenLayers.Size('auto', 'auto'), + anchor: new OpenLayers.Bounds(0, 21, 22, 32), + position: new OpenLayers.Pixel(0, 0) + }, + { //top-right + size: new OpenLayers.Size(22, 'auto'), + anchor: new OpenLayers.Bounds(null, 21, 0, 32), + position: new OpenLayers.Pixel(-638, 0) + }, + { //bottom-left + size: new OpenLayers.Size('auto', 21), + anchor: new OpenLayers.Bounds(0, 0, 22, null), + position: new OpenLayers.Pixel(0, -629) + }, + { //bottom-right + size: new OpenLayers.Size(22, 21), + anchor: new OpenLayers.Bounds(null, 0, 0, null), + position: new OpenLayers.Pixel(-638, -629) + }, + { // stem + size: new OpenLayers.Size(81, 54), + anchor: new OpenLayers.Bounds(0, null, null, 0), + position: new OpenLayers.Pixel(-311, -674) + } + ] + } + }, + + /** + * APIProperty: minSize + * {} + */ + minSize: new OpenLayers.Size(105, 10), + + /** + * APIProperty: maxSize + * {} + */ + maxSize: new OpenLayers.Size(600, 660), + + /** + * Constructor: OpenLayers.Popup.FramedCloud + * + * Parameters: + * id - {String} + * lonlat - {} + * size - {} + * contentHTML - {String} + * anchor - {Object} Object to which we'll anchor the popup. Must expose + * a 'size' () and 'offset' () + * (Note that this is generally an ). + * closeBox - {Boolean} + * closeBoxCallback - {Function} Function to be called on closeBox click. + */ + initialize:function(id, lonlat, size, contentHTML, anchor, closeBox, + closeBoxCallback) { + + OpenLayers.Popup.Framed.prototype.initialize.apply(this, arguments); + this.contentDiv.className = "olFramedCloudPopupContent"; + }, + + /** + * APIMethod: destroy + */ + destroy: function() { + OpenLayers.Popup.Framed.prototype.destroy.apply(this, arguments); + }, + + CLASS_NAME: "OpenLayers.Popup.FramedCloud" +}); diff --git a/lib/OpenLayers/Util.js b/lib/OpenLayers/Util.js index e59063cdfe..0eb4de6c69 100644 --- a/lib/OpenLayers/Util.js +++ b/lib/OpenLayers/Util.js @@ -1321,3 +1321,134 @@ OpenLayers.Util.getBrowserName = function() { return browserName; }; + + + + +/** + * Method: getRenderedDimensions + * Renders the contentHTML offscreen to determine actual dimensions for + * popup sizing. As we need layout to determine dimensions the content + * is rendered -9999px to the left and absolute to ensure the + * scrollbars do not flicker + * + * Parameters: + * size - {} If either the 'w' or 'h' properties is + * specified, we fix that dimension of the div to be measured. This is + * useful in the case where we have a limit in one dimension and must + * therefore meaure the flow in the other dimension. + * + * Returns: + * {OpenLayers.Size} + */ +OpenLayers.Util.getRenderedDimensions = function(contentHTML, size) { + + var w = h = null; + + // create temp container div with restricted size + var container = document.createElement("div"); + container.style.overflow= ""; + container.style.position = "absolute"; + container.style.left = "-9999px"; + + //fix a dimension, if specified. + if (size) { + if (size.w) { + w = container.style.width = size.w; + } else if (size.h) { + h = container.style.height = size.h; + } + } + + // create temp content div and assign content + var content = document.createElement("div"); + content.innerHTML = contentHTML; + + // add content to restricted container + container.appendChild(content); + + // append container to body for rendering + document.body.appendChild(container); + + // calculate scroll width of content and add corners and shadow width + if (!w) { + w = parseInt(content.scrollWidth); + + // update container width to allow height to adjust + container.style.width = w + "px"; + } + // capture height and add shadow and corner image widths + if (!h) { + h = parseInt(content.scrollHeight); + } + + // remove elements + container.removeChild(content); + document.body.removeChild(container); + + return new OpenLayers.Size(w, h); +}; + +/** + * APIFunction: getScrollbarWidth + * This function has been modified by the OpenLayers from the original version, + * written by Matthew Eernisse and released under the Apache 2 + * license here: + * + * http://www.fleegix.org/articles/2006/05/30/getting-the-scrollbar-width-in-pixels + * + * It has been modified simply to cache its value, since it is physically + * impossible that this code could ever run in more than one browser at + * once. + * + * Returns: + * {Integer} + */ +OpenLayers.Util.getScrollbarWidth = function() { + + var scrollbarWidth = OpenLayers.Util._scrollbarWidth; + + if (scrollbarWidth == null) { + var scr = null; + var inn = null; + var wNoScroll = 0; + var wScroll = 0; + + // Outer scrolling div + scr = document.createElement('div'); + scr.style.position = 'absolute'; + scr.style.top = '-1000px'; + scr.style.left = '-1000px'; + scr.style.width = '100px'; + scr.style.height = '50px'; + // Start with no scrollbar + scr.style.overflow = 'hidden'; + + // Inner content div + inn = document.createElement('div'); + inn.style.width = '100%'; + inn.style.height = '200px'; + + // Put the inner div in the scrolling div + scr.appendChild(inn); + // Append the scrolling div to the doc + document.body.appendChild(scr); + + // Width of the inner div sans scrollbar + wNoScroll = inn.offsetWidth; + + // Add the scrollbar + scr.style.overflow = 'scroll'; + // Width of the inner div width scrollbar + wScroll = inn.offsetWidth; + + // Remove the scrolling div from the doc + document.body.removeChild(document.body.lastChild); + + // Pixel width of the scroller + OpenLayers.Util._scrollbarWidth = (wNoScroll - wScroll); + scrollbarWidth = OpenLayers.Util._scrollbarWidth; + } + + return scrollbarWidth; +}; diff --git a/tests/Layer/test_GeoRSS.html b/tests/Layer/test_GeoRSS.html index 8744be82b4..30277eb159 100644 --- a/tests/Layer/test_GeoRSS.html +++ b/tests/Layer/test_GeoRSS.html @@ -97,7 +97,7 @@ }); } function test_Layer_GeoRSS_popups (t) { - t.plan( 8 ); + t.plan( 4 ); layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt); var map = new OpenLayers.Map('map'); var baseLayer = new OpenLayers.Layer.WMS("Test Layer", @@ -112,18 +112,14 @@ t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); layer.markers[0].events.triggerEvent('click', event); t.eq(map.popups.length, 1, "Popup opened correctly"); - t.eq(map.popups[0].size.w, 250, "Popup sized correctly x"); - t.eq(map.popups[0].size.h, 120, "Popup sized correctly y"); layer.markers[1].events.triggerEvent('click', event); t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); - t.eq(map.popups[0].size.w, 250, "Popup sized correctly x"); - t.eq(map.popups[0].size.h, 120, "Popup sized correctly y"); }); } function test_Layer_GeoRSS_resizedPopups(t) { layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt, {'popupSize': new OpenLayers.Size(200,100)}); - t.plan( 8 ); + t.plan( 4 ); var map = new OpenLayers.Map('map'); var baseLayer = new OpenLayers.Layer.WMS("Test Layer", "http://octo.metacarta.com/cgi-bin/mapserv?", @@ -137,13 +133,9 @@ t.eq(layer.markers[0].events.listeners['click'].length, 1, "Marker events has one object"); layer.markers[0].events.triggerEvent('click', event); t.eq(map.popups.length, 1, "Popup opened correctly"); - t.eq(map.popups[0].size.w, 200, "Popup sized correctly x"); - t.eq(map.popups[0].size.h, 100, "Popup sized correctly y"); map.popups[0].size.w=300; layer.markers[1].events.triggerEvent('click', event); t.eq(map.popups.length, 1, "1st popup gone, 2nd Popup opened correctly"); - t.eq(map.popups[0].size.w, 200, "Popup sized correctly x"); - t.eq(map.popups[0].size.h, 100, "Popup sized correctly y"); }); } diff --git a/tests/test_Popup.html b/tests/test_Popup.html index d3bc0cf6b5..cf00241f7e 100644 --- a/tests/test_Popup.html +++ b/tests/test_Popup.html @@ -84,9 +84,10 @@ popup.lonlat = true; popup.updatePosition(); t.ok(true, "update position doesn't fail when getLayerPxFromLonLat fails."); + map.destroy(); } function test_03_Popup_draw(t) { - t.plan( 17 ); + t.plan( 13 ); var id = "chicken"; var x = 50; @@ -98,31 +99,28 @@ var hexColor = "#ff0000"; var opacity = 0.5; var border = "1px solid"; - + map1 = new OpenLayers.Map("map"); popup = new OpenLayers.Popup(id); popup.setSize(new OpenLayers.Size(w, h)); popup.setContentHTML(content); popup.setBackgroundColor(color); popup.setOpacity(opacity); popup.setBorder(border); - popup.draw(new OpenLayers.Pixel(x, y)); + map1.addPopup(popup); + popup.moveTo(new OpenLayers.Pixel(x, y)); t.eq(popup.div.id, id, "popup.div.id set correctly"); t.eq(popup.div.style.left, x + "px", "left position of popup.div set correctly"); t.eq(popup.div.style.top, y + "px", "top position of popup.div set correctly"); - t.eq(popup.div.style.width, w + "px", "width position of popup.div set correctly"); - t.eq(popup.div.style.height, h + "px", "heightposition of popup.div set correctly"); var contentDiv = popup.div.childNodes[0].childNodes[0]; t.eq(contentDiv.className, "olPopupContent", "correct content div className"); t.eq(contentDiv.id, "chicken_contentDiv", "correct content div id"); - t.eq(contentDiv.style.width, "500px", "correct content div width"); - t.eq(contentDiv.style.height, "400px", "correct content div height"); t.eq(contentDiv.style.position, "relative", "correct content div position"); //Safari 3 separates style overflow into overflow-x and overflow-y var prop = (OpenLayers.Util.getBrowserName() == 'safari') ? 'overflowX' : 'overflow'; - t.eq(contentDiv.style[prop], "hidden", "correct content div overflow"); + t.eq(contentDiv.style[prop], "", "correct content div overflow"); t.eq(contentDiv.innerHTML, content, "correct content div content"); var bColor = popup.div.style.backgroundColor; diff --git a/theme/default/framedCloud.css b/theme/default/framedCloud.css new file mode 100644 index 0000000000..a67f367753 --- /dev/null +++ b/theme/default/framedCloud.css @@ -0,0 +1,5 @@ + +.olFramedCloudPopupContent { + padding: 5px; + overflow: auto; +} \ No newline at end of file diff --git a/theme/default/style.css b/theme/default/style.css index aba1b1b1ec..63bac81d2e 100644 --- a/theme/default/style.css +++ b/theme/default/style.css @@ -113,6 +113,7 @@ div.olControlMousePosition { .olPopupContent { padding:5px; + overflow: auto; } .olControlNavToolbar { width:0px; @@ -231,7 +232,11 @@ div.olControlMousePosition { filter: alpha(opacity=50); } -.olControlNoSelect { - -moz-user-select: none; -} - +/* + * Due to current limitations in the OpenLayers code, you can only + * replace this image with another image which is 17px x 17px. + */ +.olPopupCloseBox { + background: url("../../img/close.gif") no-repeat; + cursor: pointer; +}