Leveraging HTML 5 Navigator API to show the browser's current location on an ADF Faces 11gR2 Thematic Map component

Lucas Jellema
0 0
Read Time:3 Minute, 43 Second

This article demonstrates how, through a bit of JavaScript interacting with the HTML 5 Navigator API, some more JavaScript using the ADF Faces Rich Components API and the ADF Faces 11gR2 Thematic Map component, it becomes quite easy to not only learn about the end user’s physical location but to also show that location on a map – and along with it typically the nearest branches of your company.

The page developed in this article will essentially look as is shown in the next figure:

Image

The HTML 5 Navigator API is available in most modern browsers – including Firefox 3.5+, Chrome 5.0+, Safari 5.0+, IE 9, iPhone 3.0+ and Android 2.0+. Note that the user should explicitly allow an application to learn about his or her location – and not get a handle on it just like that.

See Dive into HTML 5 for more details: http://diveintohtml5.org/geolocation.html

The essential piece of JavaScript to interact with the Navigator API is shown below:

Image

When the navigator object is available and supports the geolocation option, then it is invoked to return the current position of the browser. The callback handler function object – showLocation – is passed to the function getCurrentPosition, along with a function to handle errors.

The showLocation function is shown here. It is passed a position parameter that is an object (see http://www.w3.org/TR/geolocation-API/#position) that contains the longitude and latitude coordinates found for the browser.

Image

The function then leverages the ADF Faces Rich Component JavaScript framework to push an event from the browser to the server. This event is called uploadLocation, is contains the longitude and latitude and is handled through a server listener:

<af:serverListener method=”#{locationBean.locationAbsorber}” type=”uploadLocation”/>

that is associated with a component with absolute id it1 (which happens to be an invisible inputText component).

The locationBean is a managed bean defined based on the class LocationBean. This class receives the location information from the client, uses the Google GeoCoder Service ‘reverse option’ of coordinates to human readable location and creates a Location object. It finally instructs ADF Faces to refresh the Thematic Map shown in the browser – knowing that there is now a location to be shown on the map.

    List<Location> locations = new ArrayList<Location>();
    UIComponent map ;

    public void locationAbsorber(ClientEvent event) {
        Double latitude = (Double)event.getParameters().get("latitude");
        Double longitude = (Double)event.getParameters().get("longitude");
        addCurrentLocation(longitude, latitude);
    }

    public void addLocation(Location loc) {
        locations.add(loc);
    }
    public void addCurrentLocation(Double longitude, Double latitude) {
        Location loc = new Location();
        loc.setLabel( "Your Current Location");
        loc.setCountry("NLD");
        loc.setDescription("location made available through browser and HTML5 Navigator API");
        loc.setDescription(getHumanReadableAddressForGeoLocation(longitude.floatValue(), latitude.floatValue()));
        loc.setCoordinates(new float[] {latitude.floatValue(), longitude.floatValue()});
        locations.add(loc);
        AdfFacesContext adfFacesCtx = AdfFacesContext.getCurrentInstance();
        // PPR
        adfFacesCtx.addPartialTarget(map);
    }

    private String getHumanReadableAddressForGeoLocation(float longitude, float latitude) {
        URL geoCodeUrl;
        String url= "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + Float.toString(latitude)+","+Float.toString(longitude)
+"&oe=utf8&sensor=false";
        try {
            geoCodeUrl = new URL(url);
        } catch (MalformedURLException e) {
            return null;
        }
        BufferedReader in;
        String coord = null;
        try {

            in = new BufferedReader(new InputStreamReader(geoCodeUrl.openStream()));
            char[] buf = new char[8000];

            in.read(buf);
            coord = new StringBuilder().append(buf).toString();

            in.close();
        } catch (IOException e) {
            System.out.println(e.getMessage()+" IO Exception ");
            return null;
        }
        if (coord != null) {
         try{
            // find first occurrence of formatted_address
            int posFA = coord.indexOf("\"formatted_address\"");
            //TODO really parse the JSON result
            String latString = coord.substring(posFA+41,posFA+68);
            return latString;
          }catch (Exception e) {System.out.println("Coordinates stank "+coord);}
        }
        System.out.println("Failed to create proper coordinates; sorry!");
        return null;
    }
...

The page itself contains the thematic map component – configured to show Europe, lazily assuming that the user (me) will be on that continent. It also contains an invisible inputText component with which the serverListener has been associated.

Image

When we run the page, the user will be asked by the browser to share his or her location with the web application:

Image

When the user consents, the location is made available to the JavaScript function that passes it on to the server who makes good use of it to update the map and send the refresh instruction to the client:

Image

Resources

Download the JDeveloper 11gR2 application: Html5TrialsCurrentLocationOnMap .

About Post Author

Lucas Jellema

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director and Oracle Developer Champion. Solution architect and developer on diverse areas including SQL, JavaScript, Kubernetes & Docker, Machine Learning, Java, SOA and microservices, events in various shapes and forms and many other things. Author of the Oracle Press book Oracle SOA Suite 12c Handbook. Frequent presenter on user groups and community events and conferences such as JavaOne, Oracle Code, CodeOne, NLJUG JFall and Oracle OpenWorld.
Happy
Happy
0 %
Sad
Sad
0 %
Excited
Excited
0 %
Sleepy
Sleepy
0 %
Angry
Angry
0 %
Surprise
Surprise
0 %
Next Post

Tracking the moving history of averages and other aggregates - Flashback Aggregates in Oracle SQL

You may have seen we write on Flashback functionality in the Oracle Database. It’s an area that I like – especially since the introduction of the Flashback Data Archive in Oracle 11g. As an application developer, I typically focus on Flashback Query (AS OF) and Flashback Versions query (VERSIONS BETWEEN […]
%d bloggers like this: