TOTD #51: Embedding Google Maps in Java Server Faces using GMaps4JSF


GMaps4JSF allows Google Maps to be easily integrated with any JSF application. This blog shows how to use this library with Mojarra - JSF implementation delivered from the GlassFish community.

TOTD #50 explains how to create a simple JSF 2.0 application and deploy on GlassFish v3 prelude using Mojarra 2.0 EDR2. The application allows to create a database of cities/country that you like. It uses integrated Facelets and the newly introduced JavaScript APIs to expose Ajax functionality. This blog shows how to extend that application to display a Google Map and Street View of the entered city using this library.
  1. Configure GMapsJSF library in the NetBeans project (created as described in TOTD #50)
    1. Download gmaps4jsf-core-1.1.jar.
    2. In the existing NetBeans project, right-click on the project, select Properties, Libraries, click on "Add JAR/Folder" and point to the recently download JAR.
    3. Configure Facelets support for this library. This is an important step since Facelets are the default viewing technology in JSF 2.0.
  2. In the NetBeans project, create a new Java class "server.CityCoordinates" that will use Google Geocoding APIs to retrieve latitude and longitude of the entered city. It also create a "details" entry by concatenating city and country name. Use the code listed below:

        private float latitude;
        private float longitude;
        private String details;
        @ManagedProperty(value="#{cities}")
        private Cities cities;

        private final String BASE_GEOCODER_URL = "http://maps.google.com/maps/geo?";
        private final String ENCODING = "UTF-8";
        private final String GOOGLE_MAPS_KEY = "GOOGLE_MAPS_API_KEY";
        private final String OUTPUT_FORMAT = "CSV";

        public String getLatLong() throws IOException {
            details = cities.getCityName() + ", " + cities.getCountryName();

            String GEOCODER_REQUEST =
                    BASE_GEOCODER_URL +
                    "q=" + URLEncoder.encode(details, ENCODING) +
                    "&key=" + GOOGLE_MAPS_KEY +
                    "&output=" + OUTPUT_FORMAT;
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(
                        new URL(GEOCODER_REQUEST).openStream()));
            String line = null;
            int statusCode = -1;
            while ((line = reader.readLine()) != null) {
                // 200,4,37.320052,-121.877636
                // status code,accuracy,latitude,longitude
                statusCode = Integer.parseInt(line.substring(0, 3));
                if (statusCode == 200) {
                    int secondComma = line.indexOf(",", 5);
                    int lastComma = line.lastIndexOf(",");
                    latitude = Float.valueOf(line.substring(secondComma+1, lastComma));
                    longitude = Float.valueOf(line.substring(lastComma+1));
                    System.out.println("Latitude: " + latitude);
                    System.out.println("Longitude: " + longitude);
                }
            }

            return "map";
        }

        // getters and setters

    "getLatLong()" method retrieves geocoding information using HTTP by passing the city and country name, Google Maps API key and CSV output format. The result is then processed to retrieve status code, latitude and longitude. Add the following annotation to this class:

    @ManagedBean(name="coords", scope="request")

    This ensures that "server.CityCoordinates" is injected as a managed bean in the runtime.
  3. Add a new button in "welcome.xhtml" right after "submit" button as:

    <h:commandButton action="#{coords.getLatLong}" value="map"/>
  4. Add a new page "map.xhtml" as:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:m="http://code.google.com/p/gmaps4jsf/">
        <head>
            <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAF9QYjrVEsD9al2QCyg8e-hTwM0brOpm-All5BF6PoaKBxRWWERRHQdtsJnNsqELmKZCKghs54I-0Uw" type="text/javascript"> </script>
        </head>
        <body>
            <m:map
                latitude="#{coords.latitude}"
                longitude="#{coords.longitude}"
                width="500px"
                height="300px"
                zoom="14"
                addStretOverlay="true">
                <m:marker draggable="true">
                    <m:eventListener eventName="dragend" jsFunction="showStreet"/>
                </m:marker>
                <m:htmlInformationWindow htmlText="#{coords.details}"/>
                <m:mapControl name="GLargeMapControl" position="G_ANCHOR_BOTTOM_RIGHT"/>
                <m:mapControl name="GMapTypeControl"/>
            </m:map>
            <br/> <br/>
            <m:streetViewPanorama width="500px" height="200px"
                                  latitude="#{coords.latitude}" longitude="#{coords.longitude}"
                                  jsVariable="pano1" />

            <script type="text/javascript">
                function showStreet(latlng) {
                    pano1.setLocationAndPOV(latlng);
                }

            </script>
            <form jsfc="h:form">
                <input jsfc="h:commandButton" action="back" value="Back"/>
            </form>
        </body>
    </html>

    The code is borrowed and explained in An Introduction to GMaps4JSF. Basically the code displays a Google Map and Street View where the latitude and longitude are bound by "server.CityCoordinates" managed bean. And these attributes are populated using the geocoding information earlier. The Street View corresponds to marker in the Map which is draggable. So if the marker is dropped to a different location in the map then the Street View changes accordingly.
  5. Add new navigation rules to "faces-config.xml" as:

        <navigation-rule>
            <from-view-id>/welcome.xhtml</from-view-id>
            <navigation-case>
                <from-outcome>map</from-outcome>
                <to-view-id>/map.xhtml</to-view-id>
            </navigation-case>
        </navigation-rule>
        <navigation-rule>
            <from-view-id>/map.xhtml</from-view-id>
            <navigation-case>
                <from-outcome>back</from-outcome>
                <to-view-id>/welcome.xhtml</to-view-id>
            </navigation-case>
        </navigation-rule>
That's it, now your application is ready!

Now when a city and country name are entered on "welcome.xhtml" and "map" button is clicked then the corresponding Google Map along with the street view are shown in next page.

If "San Jose" is entered on "http://localhost:8080/Cities/faces/welcome.xhtml" then the following page is shown:



Clicking on "map" button shows the following page:



If the marker is drag/dropped to 280 and 87 junction, then the page looks like:



Some other useful pointers:
Have you tried your JSF 1.2 app on Mojarra 2.0 ? Drop a comment on this blog if you have.

File JSF related bugs here using "2.0.0 EDR2" version and ask your questions on webtier@glassfish.dev.java.net.

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. An archive of all the tips is available here.

Technorati: totd javaserverfaces mojarra glassfish v3 netbeans gmaps4jsf googlemaps
Comments:

VERY NICE BLOG

ITS VERY USEFUL

THANK YOU..........

Posted by michael on October 23, 2008 at 11:35 PM PDT #

thank you :)

Posted by tattoo on October 25, 2008 at 09:46 PM PDT #

thanks.

Posted by izolasyon on November 02, 2008 at 02:03 AM PST #

Arun,

Good overview and code segment.

Thanks!

Posted by Chris on December 18, 2008 at 11:02 PM PST #

I hope they do the same with .net soon enough so that we can use this is our .net apps too.

Posted by Web Designer on January 19, 2009 at 05:50 AM PST #

Google maps have opened so many new ways and technologies. Its great.

Posted by Joy on March 12, 2009 at 07:58 AM PDT #

A very good technology..

Posted by sinema izle on March 13, 2009 at 07:08 AM PDT #

very nice blog its very useful thank you very much cong...

Posted by estetik on March 26, 2009 at 08:14 PM PDT #

very good..

Posted by komik videolar on November 17, 2009 at 06:42 PM PST #

nice works

thanks.

Posted by Va infotech on September 09, 2010 at 12:06 AM PDT #

nice works

thanks.

Posted by Va infotech on September 09, 2010 at 12:06 AM PDT #

Excellent tips .I really appreciate all these points, and I agree completely…
81

Posted by web tasarımı on December 07, 2010 at 06:36 PM PST #

Great job Done ! Thanks for sharing with us !

Posted by website developers on May 08, 2011 at 05:39 PM PDT #

WOW!! Really Interesting...

Posted by guest on February 13, 2013 at 04:48 AM PST #

Post a Comment:
Comments are closed for this entry.
About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today