Skip to main content

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

Posted by arungupta on October 24, 2008 at 6:52 AM PDT


cellspacing="2">
style="width: 294px; height: 92px;" alt=""
src="http://blogs.sun.com/arungupta/resource/images/gmaps4jsf-logo.png">
GMaps4JSF
allows Google Maps to be easily integrated with any JSF application.
This blog shows how to use this library with href="http://javaserverfaces.dev.java.net/">Mojarra
- JSF implementation delivered from the href="http://glassfish.org/">GlassFish community.



TOTD
#50
explains how to create a simple JSF 2.0 application and
deploy on href="http://download.java.net/glassfish/v3-prelude/promoted/">GlassFish
v3 prelude using href="https://javaserverfaces.dev.java.net/files/documents/1866/114605/mojarra-2.0.0-EDR2-binary.zip">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 href="http://blogs.sun.com/arungupta/entry/totd_50_mojarra_2_0">TOTD
    #50)
    1. Download href="http://gmaps4jsf.googlecode.com/files/gmaps4jsf-core-1.1.jar">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 href="http://code.google.com/p/gmaps4jsf/wiki/FaceletsSupport">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 href="http://code.google.com/apis/maps/documentation/services.html#Geocoding">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:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
        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 href="http://code.google.com/apis/maps/documentation/services.html#Geocoding_Direct">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:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
    @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:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
    <h:commandButton
    action="#{coords.getLatLong}" value="map"/>
  4. Add a new page "map.xhtml" as:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
    <!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 href="http://www.theserverside.com/tt/articles/article.tss?track=NL-461&ad=666667&l=IntroductiontoGMaps4JSF">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:


    style="text-align: left; background-color: rgb(204, 204, 255); width: 100%;"
    cellpadding="2" cellspacing="2">
       
    <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:



src="http://blogs.sun.com/arungupta/resource/images/gmaps4jsf-sanjose-welcome.png">



Clicking on "map" button shows the following page:



src="http://blogs.sun.com/arungupta/resource/images/gmaps4jsf-sanjose-map.png">



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



src="http://blogs.sun.com/arungupta/resource/images/gmaps4jsf-sanjose-dragged-map.png">



Some other useful pointers:

  • href="http://code.google.com/p/gmaps4jsf/wiki/HowToUseTheLibrary">Usage
    examples
  • href="http://code.google.com/p/gmaps4jsf/wiki/TagLibraryDocumentation">Tag
    Library Documentation
  • gmaps4jsf-dev
    Google Group

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 href="https://javaserverfaces.dev.java.net/issues/enter_bug.cgi?issue_type=DEFECT">here
using "2.0.0 EDR2" version and ask your questions on href="mailto:webtier@glassfish.dev.java.net">webtier@glassfish.dev.java.net.



Please leave suggestions on other TOTD ( style="font-weight: bold;">Tip style="font-weight: bold;">Of style="font-weight: bold;">The style="font-weight: bold;">Day) that
you'd like to see.
An archive of all the tips is available href="http://blogs.sun.com/arungupta/tags/totd">here.




Technorati: totd
javaserverfaces
mojarra
glassfish
v3 href="http://technorati.com/tag/netbeans">netbeans
gmaps4jsf
googlemaps

Related Topics >>

Comments

Hi, I need a help from you, if you do not mind. I am asked to build an application retriving information from a Mysql database and displaying these informations on a google map. Please guide me for this. Are you an Indian, I was in India now I am in Africa.

hamyago, Here is a sample that might be useful: http://blogs.sun.com/arungupta/entry/totd_51_embedding_google_maps and another one: http://blogs.sun.com/arungupta/entry/screencast_web11_travel_map_another