[GIS] How to use Google Maps V3 Geocode with Openlayers

geocodinggooglegoogle mapsjavascriptopenlayers-2

How to use Google Maps V3 Geocode with Openlayers. Below is my code but the function does not execute when I try to integrate it with Openlayers. This works with my original google v3 file. Below is 2 sets of code one for Google maps with geocode and the other with openlayers

 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
 <!--CSS for Map -->
 <style type="text/css">

     html, body, #map {
            margin: 0;
            width: 100%;
            height: 100%;
        }
 </style>
<style type="text/css">

div.olControlPanel {
 top: 0px;
 left: 50px;
 position: absolute;
}
.olControlPanel div {
 display: block;
 width:  22px;
 height: 22px;
 border: thin solid black;
 margin-top: 10px;
 background-color: white
}

.helpButtonItemInactive {
 background-image: url("help.png");
}

#output-id {
 margin: 10px 250px;
}

 </style>

 <style type="text/css">
    #controls {
    position: absolute;
        bottom: 1em;
        left: 100px;
        width: 200px;
        z-index: 20000;
        background-color:;
        padding: 0 0.5em 0.5em 0.5em;
    }
    #controlToggle {
        padding-left: 1em;
    }
    #controlToggle li {
        list-style: none;
    }
</style>

<link rel="stylesheet" href="css/style.css" type="text/css">
<link href="css/style-map.css" rel="stylesheet" type="text/css" />

<script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false">
</script>
<script src="js/firebug.js"></script>
<script src="js/OpenLayers.js"></script>
<script type="text/javascript">

 var map;
        function init(){


  // Styles for Default and Select states
            var myStyles = new OpenLayers.StyleMap({
            "default": new OpenLayers.Style({
                fillColor: "#000",
                fillOpacity: 0.3,
                strokeColor: "#000",
                strokeOpacity: 0.3,
                strokeWidth: 1,
                graphicZIndex: 1
            }),
            "select": new OpenLayers.Style({
                fillColor: "#ccc",
                fillOpacity: 0.6,
                strokeColor: "#ccc",
                strokeWidth: 1,
                label: "Label for Mouseover",
                labelAlign: "cc",
                fontColor: "#333333",
                fontOpacity: 0.9,
                fontFamily: "Arial",
                fontSize: 14,
                graphicZIndex: 2
            })
        });

        layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
                    "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'} );


        vlayer = new OpenLayers.Layer.Vector( "Editable",{
            styleMap: myStyles,
            rendererOptions: {zIndexing: true}
        });

        map = new OpenLayers.Map( 'map', {

        // Add Openlayers Map Controls 
        controls: 

                 [
                    new OpenLayers.Control.LayerSwitcher(),
                    new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.MousePosition(),
                    new OpenLayers.Control.ScaleLine(),
                    new OpenLayers.Control.OverviewMap(),

                 ]   
         });

         var geocoder = new google.maps.Geocoder();
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
  if (status == google.maps.GeocoderStatus.OK) {
    map.setCenter(results[0].geometry.location);
    var marker = new google.maps.Marker({
        map: map, 
        position: results[0].geometry.location
    });
  } else {
    alert("Geocode was not successful for the following reason: " + status);
  }
});
  }

// Make Variables for Google Version 3 
var gmap = new OpenLayers.Layer.Google(
    "Google Streets", // the default
    {numZoomLevels: 20}
);
var ghyb = new OpenLayers.Layer.Google(
    "Google Hybrid",
    {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
);
var gsat = new OpenLayers.Layer.Google(
    "Google Satellite",
    {type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}
);
var gphy = new OpenLayers.Layer.Google(
    "Google Physical",
    {type: google.maps.MapTypeId.TERRAIN}
);

    // Add layers to map
    map.addLayers([gmap, ghyb, gsat, gphy]);




    // Google.v3 uses EPSG:900913 as projection, so we have to transform our coordinates
    map.setCenter(new OpenLayers.LonLat(25, -28).transform(
    new OpenLayers.Projection("EPSG:4326"),
    map.getProjectionObject()
 ), 5);


    // Now we must make a layer for the circles and call our styles
        var polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer", {
            styleMap: myStyles,
            rendererOptions: {zIndexing: true}
        });

        // Now we add the vector and circle layers
        map.addLayers([polygonLayer]);

        // Options for the sides wanted in the default circle e.g 3 sides = triangle
        polyOptions = {sides: 40};

        // At this point we must make a control to draw a circle on the map after a button to activate is clicked
        polygonControl = new OpenLayers.Control.DrawFeature(polygonLayer,
                                        OpenLayers.Handler.RegularPolygon,
                                        {handlerOptions: polyOptions} );


        // This adds the naivgational pan panel
        map.addControl( new OpenLayers.Control.Navigation() );

        // This adds a control to be able to switch between the different layers
        map.addControl( new OpenLayers.Control.LayerSwitcher() );

        // This adds the Scale Line on the bottom left of the window
        map.addControl( new OpenLayers.Control.ScaleLine() );

        // This adds the overview map on the left toward the bottom of the window there is a + button
        map.addControl( new OpenLayers.Control.OverviewMap() );

        // Now we add the an alert for an option to delete once the user has drawn a circle or vector on the map
        polygonLayer.events.on({
        featuresadded: function (event) {
        var confirmPolygon = function () { return confirm("Do you want to keep this polygon?") };

        if (!confirmPolygon()) {
            polygonLayer.removeFeatures(event.features);
          }
         }
        });

        // Now we call an alert to get the bounds or coordinates from a circle or vector we have drawn 
        polygonLayer.events.on({
        featuresadded: onFeaturesAdded
        });

        function onFeaturesAdded(event){
        var bounds = event.features[0].geometry.getBounds();
        var answer = "bottom: " + bounds.bottom  + "\n";
        answer += "left: " + bounds.left  + "\n";
        answer += "right: " + bounds.right  + "\n";
        answer += "top: " + bounds.top  + "\n";
        alert(answer);
        }

        // The Drag function is now made and called
         // Add Drag
     drag = new OpenLayers.Control.DragFeature(polygonLayer, {
     autoActivate: true,
     onComplete: displayRadius
     });


    function displayRadius(circle) {
 var area = circle.geometry.getArea();
 var radius = 0.565352 * Math.sqrt(area);
 alert(radius);
  }



         // A Hover Control is now made and executed
        var select = new OpenLayers.Control.SelectFeature(polygonLayer, {hover: true});
        map.addControl(select);
        select.activate();

        // The drag Control and the control for vectors is made
        map.addControl(drag);
        map.addControl(polygonControl);

        // This is the toggle control for the buttons on the bottom left corner
        document.getElementById('noneToggle').checked = true;
        document.getElementById('irregularToggle').checked = false;
        }

        function toggleControl(element) {
        for(key in controls) {
            var control = controls[key];
            if(element.value == key && element.checked) {
                control.activate();
            } else {
                control.deactivate();
             }
           }
         }

    </script>
   </head>
   <body onLoad="init()">



    <div id="map"></div>
 <!--Call the Circle Controls onto the Canvas -->
    <div id="controls">

<!--Finally for the Radio buttons -->
    <ul id="controlToggle">
         <li>
            <input type="radio" name="type"
                   value="none" id="noneToggle"
                   onclick="polygonControl.deactivate()"
                   checked="checked" />
            <label for="noneToggle">navigate</label>
        </li>
        <li>
            <input type="radio" name="type"
                   value="polygon" id="polygonToggle"
                   onclick="polygonControl.activate()" />
            <label for="polygonToggle">draw polygon</label>
        </li>
    </ul>

  <div>
<input id="address" type="textbox" value="Sydney, NSW">

<input type="button" value="Geocode" onclick="codeAddress()">
 </div>
    </div>


   </body>
 </html> 

The code that I am battling with is:

         var geocoder = new google.maps.Geocoder();
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
  if (status == google.maps.GeocoderStatus.OK) {
    map.setCenter(results[0].geometry.location);
    var marker = new google.maps.Marker({
        map: map, 
        position: results[0].geometry.location
    });
  } else {
    alert("Geocode was not successful for the following reason: " + status);
  }
});
 }

Below is the working code for the geocoder:

       <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps JavaScript API v3 Example: Geocoding Simple</title>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" />
<script src="http://maps.google.com/maps/api/js?v=3.5&amp;sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
  zoom: 8,
  center: latlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}

function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
  if (status == google.maps.GeocoderStatus.OK) {
    map.setCenter(results[0].geometry.location);
    var marker = new google.maps.Marker({
        map: map, 
        position: results[0].geometry.location
    });
  } else {
    alert("Geocode was not successful for the following reason: " + status);
  }
 });
 }
</script>
</head>
<body onload="initialize()">
<div>
<input id="address" type="textbox" value="Sydney, NSW">

<input type="button" value="Geocode" onclick="codeAddress()">
</div>
<div id="map_canvas" style="height:90%;top:30px"></div>
</body>
</html>

Best Answer

Besides compliance with Google Maps API Usage Terms , the problem with your code is trying to add a Gmaps Marker to an OpenLayers map, which is impossibile and causes the error you are probably battling with.

I have created a fiddle here showing (open your browser console for proof) that the address is correctly geocoded and left as an exercise to the reader implement the remaining part using a OpenLayers.Marker (which boils down to cut'n paste mostly).