Miles to go …

October 24, 2008

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

Filed under: web2.0 — arungupta @ 4:00 am


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>
        &lt
    ;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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot
Related posts:
  1. TOTD #46: Facelets with Java Server Faces 1.2
  2. TOTD #45: Ajaxifying Java Server Faces using JSF Extensions
  3. TOTD #147: Java Server Faces 2.0 Composite Components using NetBeans – DRY your code
  4. TOTD #54: Java Server Faces with Eclipse IDE
  5. TOTD #42: Hello JavaServer Faces World with NetBeans and GlassFish

12 Comments »

  1. VERY NICE BLOG

    ITS VERY USEFUL

    THANK YOU……….

    Comment by michael — October 24, 2008 @ 6:35 am

  2. thank you :)

    Comment by tattoo — October 26, 2008 @ 4:46 am

  3. thanks.

    Comment by izolasyon — November 2, 2008 @ 10:03 am

  4. Arun,

    Good overview and code segment.

    Thanks!

    Comment by Chris — December 19, 2008 @ 7:02 am

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

    Comment by Web Designer — January 19, 2009 @ 1:50 pm

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

    Comment by Joy — March 12, 2009 @ 2:58 pm

  7. A very good technology..

    Comment by sinema izle — March 13, 2009 @ 2:08 pm

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

    Comment by estetik — March 27, 2009 @ 3:14 am

  9. very good..

    Comment by komik videolar — November 18, 2009 @ 2:42 am

  10. nice works

    thanks.

    Comment by Va infotech — September 9, 2010 @ 7:06 am

  11. nice works

    thanks.

    Comment by Va infotech — September 9, 2010 @ 7:06 am

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

    Comment by web tasarımı — December 8, 2010 @ 2:36 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.
Powered by WordPress