+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Update Google Map V2 to V3?

Update Google Map V2 to V3?

9 posts, 1 answered
  1. bemara57
    bemara57 avatar
    135 posts
    Registered:
    27 Mar 2008
    25 Nov 2010
    Link to this post
    I tried replacing the api address for Google in the geomap settings.

    I changed this:
    http://maps.google.com/maps?file=api&v=2.x&key=

    To this:
    http://maps.google.com/maps/api/js?sensor=true&key=

    I was hoping this would simply work, but I am getting a Javascript error on the events pages:
    "GMap2 is not defined"

    The error is in this embedded Javascript file. Is there a way to override or correct this?

    /* CONSTANTS */
     
    /* services */
    var GOOGLE_MAPS = '1';
    var YAHOO_MAPS = '2';
    var LIVESEARCH_MAPS = '3';
     
    /* zoom levels */
    var COUNTRY_ZOOM = 1;
    var STATE_ZOOM = 2;
    var CITY_ZOOM = 3;
    var STREET_ZOOM = 4;
     
    var centerPointCallbackFunction = null;
         
    /* ******************************** GEOMAPPING **************************************/
     
    // Constructs new geomapping object
    function Geomapping(serviceName, mapContainerId)
    {
        if(document.getElementById(mapContainerId) == null)
           return null;
         
        this._serviceName = serviceName;
        this._mapContainerId = mapContainerId;
        this._map = null;
        this._centerPointCallbackFunction = null;
    }
     
    // loads map into a map container
    Geomapping.prototype.LoadMap = function(onLoadCallbackFunction)
    {
        this.UnloadMap();
        switch(this._serviceName)
        {
            case GOOGLE_MAPS:
                this._map = new GMap2(document.getElementById(this._mapContainerId));
                break;
            case YAHOO_MAPS:
                this._map = new YMap(document.getElementById(this._mapContainerId), YAHOO_MAP_REG);
                break;
            case LIVESEARCH_MAPS:
                this._map = new VEMap(this._mapContainerId);
                this._map.LoadMap();
                break;
        }
    }
     
    // unloads the map
    Geomapping.prototype.UnloadMap = function()
    {
      this._map = null;
      var ctrl = document.getElementById(this._mapContainerId);
      if(ctrl != null)
      {
        while (ctrl.childNodes[0])
        {
            ctrl.removeChild(ctrl.childNodes[0]);
        }
      }
    }
     
    // shows map in a designated container
    Geomapping.prototype.ShowMap = function(geoPoint, zoom, showLocationPin, allowDragging)
    {
        if(zoom == null)
        {
            zoom = STREET_ZOOM;
        }
        if(showLocationPin == null)
        {
            showLocationPin = true;
        }
        if(allowDragging == null)
        {
            allowDragging = false;
        }
         
        this.LoadMap();
        this.ShowMapInternal(this._serviceName, geoPoint.Lat, geoPoint.Lon, zoom, showLocationPin, allowDragging);
    }
     
    // acquires geo longitude and geo latitude of the center point of the map
    Geomapping.prototype.AcquireCenterPoint = function(street, city, country, state, callbackFunction)
    {
        centerPointCallbackFunction = callbackFunction;
        var query = GetPlaceQuery(this._serviceName, street, city, country, state);
         
        this.LoadMap();
        this.AcquireCenterPointInternal(this._serviceName, "'" + query + "'");
    }
     
    /* ******************************** INTERNAL FUNCTIONS ************************** */
    Geomapping.prototype.ShowMapInternal = function(_serviceName, lat, lon, zoom, showLocationPin, allowDragging)
    {
        var geoPoint = new GeoPoint(lon, lat);
     
        switch(_serviceName)
            {
                case GOOGLE_MAPS:
                    this._map.setCenter(new GLatLng(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName));
                    if(showLocationPin)
                        this._map.addOverlay(new GMarker(new GLatLng(geoPoint.Lat, geoPoint.Lon)));
                    if(!allowDragging)
                        this._map.disableDragging();
                break;
            case YAHOO_MAPS:
                this._map.drawZoomAndCenter(new YGeoPoint(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName));
                if(showLocationPin)
                    this._map.addMarker(new YGeoPoint(geoPoint.Lat, geoPoint.Lon));
                if(allowDragging)
                    this._map.enableDragMap();
                else
                    this._map.disableDragMap();
                break;
            case LIVESEARCH_MAPS:
                this._map.LoadMap(new VELatLong(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName), 'r', !allowDragging);
                this._map.HideDashboard();
                if(showLocationPin)
                {
                    var shape = new VEShape(VEShapeType.Pushpin, this._map.GetCenter());
                    this._map.AddShape(shape);
                }
                this._map.Resize();
                break;
        }
    }
     
    Geomapping.prototype.AcquireCenterPointInternal = function(_serviceName, query)
    {
        switch(_serviceName)
        {
            case GOOGLE_MAPS:
                geocoder = new GClientGeocoder();   
                geocoder.getLocations(query, this.AcquireCenterPointGoogle_Callback);
                break;
            case YAHOO_MAPS:
                this._map.drawZoomAndCenter(query, 12); // the zome value here is not important
                YEvent.Capture(this._map, EventsList.endMapDraw, this.AcquireCenterPointYahoo_Callback);
                break;
            case LIVESEARCH_MAPS:
                this._map.Find(null, query, null, null, 0, 1, true, true, false, true, this.AcquireCenterPointLiveSearch_Callback);
                break;
        }
    }
     
    Geomapping.prototype.AcquireCenterPointGoogle_Callback = function(response)
    {
        if(!response || response.Status.code != 200)
        {
            // TODO: implement localizable error handling here
            alert('Sorry this location could not be geomapped!');
        }
        else
        {
            var place = response.Placemark[0];
            centerPointCallbackFunction(new GeoPoint(place.Point.coordinates[0], place.Point.coordinates[1]));
        }
    }
     
    Geomapping.prototype.AcquireCenterPointYahoo_Callback = function(_e)
    {
       centerPointCallbackFunction(new GeoPoint(_e.YGeoPoint.Lon, _e.YGeoPoint.Lat));
    }
     
    Geomapping.prototype.AcquireCenterPointLiveSearch_Callback = function(layer, resultsArray, places, hasMore, veErrorMessage)
    {
        if(veErrorMessage != null)
        {
            alert(veErrorMessage);
        }
        else
        {
            centerPointCallbackFunction(new GeoPoint(places[0].LatLong.Longitude, places[0].LatLong.Latitude));       
        }
    }
     
    /* ******************************** HELPER FUNCTION ***************************** */
     
    // this function takes sitefinity zoom value and return appropriate zoom value for given service
    function GetZoomValue(zoom, _serviceName)
    {
        var zoomValue = '';
        switch(_serviceName)
        {
            case GOOGLE_MAPS:
                switch(zoom)
                {
                    case COUNTRY_ZOOM:
                        zoomValue = 5;
                        break;
                    case STATE_ZOOM:
                        zoomValue = 10;
                        break;
                    case CITY_ZOOM:
                        zoomValue = 14;
                        break;
                    case STREET_ZOOM:
                        zoomValue = 15;
                        break;
                }
                break;
            case YAHOO_MAPS:
                switch(zoom)
                {
                    case COUNTRY_ZOOM:
                        zoomValue = 14;
                        break;
                    case STATE_ZOOM:
                        zoomValue = 11;
                        break;
                    case CITY_ZOOM:
                        zoomValue = 5;
                        break;
                    case STREET_ZOOM:
                        zoomValue = 3;
                        break;
                }
                break;
            case LIVESEARCH_MAPS:
                switch(zoom)
                {
                    case COUNTRY_ZOOM:
                        zoomValue = 5;
                        break;
                    case STATE_ZOOM:
                        zoomValue = 8;
                        break;
                    case CITY_ZOOM:
                        zoomValue = 12;
                        break;
                    case STREET_ZOOM:
                        zoomValue = 15;
                        break;
                }
                break;
        }
        return zoomValue;
    }
     
    // this function takes location info from sitefinity and returns
    // a proper location query for given service
    function GetPlaceQuery(_serviceName, street, city, country, state)
    {
        var query = '';
        switch(_serviceName)
        {
            case GOOGLE_MAPS:
                query = street + ', ' + city + ', ' + country + ', ' + state;
                break;
            case YAHOO_MAPS:
                if(country.toUpperCase() == "UNITED STATES")
                {
                    query = street + ', ' + city + ', ' + state;
                }
                else
                {
                    query = street + ', ' + city + ', ' + country;
                }
                break;
            case LIVESEARCH_MAPS:
                query = street + ', ' + city + ', ' + country + ', ' + state;
                break;
        }
        return query;
    }
     
    /* ******************************** OBJECTS ************************************* */
     
    /* Geomapping point object */
    function GeoPoint(longitude, latitude)
    {
        this.Lon = longitude;
        this.Lat = latitude;
    }

  2. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    25 Nov 2010
    Link to this post
    Hello bemara57,

    What is the result if you use the approach in this forum post: Possible to override Google Key on page level.

    Regards,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. bemara57
    bemara57 avatar
    135 posts
    Registered:
    27 Mar 2008
    25 Nov 2010
    Link to this post
    I should have commented there instead.. I couldn't find it in my searches (advance search would help) and my tracked posts in my account keeps crashing when paging.

    Anyways, it has the same effect of V3. I continue to get this Javascript alert:
    "This web site needs a different Google Maps API key. A new key can be generated at http://code.google..."

    The reason why I wanted to use V3 is because I wanted the event page to serve multiple subdomains and V3 does not require an API key. The API address "http://maps.google.com/maps?file=api&v=3.2&key=" has the same restrictions as V2 and requires an API key per domain. The real V3 API address is "http://maps.google.com/maps/api/js?v=3.2&sensor=true&key=" and this is where the error happens.

    Just to clarify for the other post, I tried the following API addresses and they all gave the alert saying I need an API key:
    http://maps.google.com/maps?file=api&v=3.2 (this case I put a space for API key section)
    http://maps.google.com/maps?file=api&v=3.2&key=
    http://maps.google.com/maps?file=api&v=3.2&x=
  4. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    01 Dec 2010
    Link to this post
    Hello bemara57,

    Thank you for getting back to me.

    You would have to create a custom control similar to the one used in the backend. Then you should use this control in the control template instead of the built in one. I have attached the code of the control so that you can just apply your changes.

    Best wishes,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
    Answered
  5. bemara57
    bemara57 avatar
    135 posts
    Registered:
    27 Mar 2008
    02 Dec 2010
    Link to this post
    Radoslav - thanks a mil! It works with V3!!

    Here is what I did...

    1) Inherit GeomappingEditor and only override a single Javascript script:
    using System;
     
    namespace Netopia.Sitefinity.Events.WebControls.Admin
    {
        public class GeomappingEditor : Telerik.Events.WebControls.Admin.GeomappingEditor
        {
            #region View layout and template
            /// <summary>
            /// Gets or sets path of the external template that defines child controls of this control.
            /// </summary>
            public virtual string LayoutTemplatePath
            {
                get
                {
                    return base.LayoutTemplatePath;
                }
                set
                {
                    base.LayoutTemplatePath = value;
                }
            }
     
            /// <summary>
            /// Gets the name of the embedded layout template. This property must be overridden to provide the path (key) to an embedded resource file.
            /// </summary>
            public override string LayoutTemplateName
            {
                get
                {
                    return GeomappingEditor.GeomappingLayoutTemplateName;
                }
            }
     
            /// <summary>
            /// Gets the additional template key.
            /// </summary>
            /// <value>The additional template key.</value>
            protected override string AdditionalTemplateKey
            {
                get
                {
                    return this.ProviderName;
                }
            }
     
            public const string GeomappingLayoutTemplateName = "Netopia.Sitefinity.Events.ControlTemplates.Backend.GeomappingEditor.ascx";
     
            #endregion
     
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
     
                if (this.Page != null && base.Container != null)
                {
                    //OVERWRITE SOME JAVASCRIPT FUNCTIONS TO HANDLE GOOGLE MAP V3
                    this.Page.ClientScript.RegisterClientScriptResource(typeof(GeomappingEditor), "Netopia.Sitefinity.Events.Resources.Scripts.Geomapping.js");
                }
            }
        }
    }

    2) In the Geomapping.js file, just overwrite some functions. Because they will come after the first call of the native Geomapping.js, the prototype functions will be replaced on the 2nd call (notice not all functions are redeclared - only the ones you want to overwrite). It has been adjusted to work with V3:
    // loads map into a map container
    Geomapping.prototype.LoadMap = function(onLoadCallbackFunction)
    {
        this.UnloadMap();
        switch(this._serviceName)
        {
            case GOOGLE_MAPS:
                //this._map = new GMap2(document.getElementById(this._mapContainerId));
                this._map = new google.maps.Map(document.getElementById(this._mapContainerId)); //v3
                break;
            case YAHOO_MAPS:
                this._map = new YMap(document.getElementById(this._mapContainerId), YAHOO_MAP_REG);
                break;
            case LIVESEARCH_MAPS:
                this._map = new VEMap(this._mapContainerId);
                this._map.LoadMap();
                break;
        }
    }
     
    /* ******************************** INTERNAL FUNCTIONS ************************** */
    Geomapping.prototype.ShowMapInternal = function (_serviceName, lat, lon, zoom, showLocationPin, allowDragging) {
        var geoPoint = new GeoPoint(lon, lat);
     
        switch (_serviceName) {
            case GOOGLE_MAPS:
                //this._map.setCenter(new GLatLng(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName));
                var gLatlng = new google.maps.LatLng(geoPoint.Lat, geoPoint.Lon);
                var gOptions = {
                    zoom: GetZoomValue(zoom, _serviceName),
                    center: gLatlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP
                }
                this._map.setOptions(gOptions); //v3
                if (showLocationPin) {
                    //this._map.addOverlay(new GMarker(new GLatLng(geoPoint.Lat, geoPoint.Lon)));
                    var marker = new google.maps.Marker({
                        position: gLatlng,
                        map: this._map
                    }); //v3
                }
                //if(!allowDragging)
                //  this._map.disableDragging();
                this._map.draggable = allowDragging //v3
                break;
            case YAHOO_MAPS:
                this._map.drawZoomAndCenter(new YGeoPoint(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName));
                if (showLocationPin)
                    this._map.addMarker(new YGeoPoint(geoPoint.Lat, geoPoint.Lon));
                if (allowDragging)
                    this._map.enableDragMap();
                else
                    this._map.disableDragMap();
                break;
            case LIVESEARCH_MAPS:
                this._map.LoadMap(new VELatLong(geoPoint.Lat, geoPoint.Lon), GetZoomValue(zoom, _serviceName), 'r', !allowDragging);
                this._map.HideDashboard();
                if (showLocationPin) {
                    var shape = new VEShape(VEShapeType.Pushpin, this._map.GetCenter());
                    this._map.AddShape(shape);
                }
                this._map.Resize();
                break;
        }
    }
     
    Geomapping.prototype.AcquireCenterPointInternal = function (_serviceName, query) {
        switch (_serviceName) {
            case GOOGLE_MAPS:
                geocoder = new google.maps.Geocoder();
                geocoder.geocode({ 'address': query }, this.AcquireCenterPointGoogle_Callback);
                break;
            case YAHOO_MAPS:
                this._map.drawZoomAndCenter(query, 12); // the zome value here is not important
                YEvent.Capture(this._map, EventsList.endMapDraw, this.AcquireCenterPointYahoo_Callback);
                break;
            case LIVESEARCH_MAPS:
                this._map.Find(null, query, null, null, 0, 1, true, true, false, true, this.AcquireCenterPointLiveSearch_Callback);
                break;
        }
    }
     
    Geomapping.prototype.AcquireCenterPointGoogle_Callback = function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            centerPointCallbackFunction(new GeoPoint(results[0].geometry.location.za, results[0].geometry.location.ya));
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    }

    3) Replace the native GeomappingEditor control in EventsItemEdit.ascx and EventsItemNew.ascx

    4) In the EventsView, override the prerender to add the new V3 functions script as well:
    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
     
        if (this.itemId != Guid.Empty)
        {
            //OVERWRITE SOME JAVASCRIPT FUNCTIONS TO HANDLE GOOGLE MAP V3
            this.Page.ClientScript.RegisterClientScriptResource(typeof(EventsView), "Netopia.Sitefinity.Events.Resources.Scripts.Geomapping.js");
        }
    }

    5) In your Geomapping settings in the event module, put this for the API address:
    http://maps.google.com/maps/api/js?sensor=false&key=

    Let me know if you see something I missed. I hope this helps someone else. Thanks again Radoslav.
  6. Filipe
    Filipe avatar
    7 posts
    Registered:
    20 Jul 2009
    23 Dec 2010
    Link to this post
    I´m going to try it. This is a really horrible feature!
  7. Filipe
    Filipe avatar
    7 posts
    Registered:
    20 Jul 2009
    24 Dec 2010
    Link to this post
    Hi bemara57.

    I have some questions about this solution.

    You have created a class file named GeomappingEditor.cs in the app_code folder wright?
    Can you tell me where did you put the GeomappingEditor.ascx in the solution(file path)?
    And the js files?
    Also can you show me how your EventsItemEdit.ascx and EventsItemNew.ascx looks like now.

    Thanks in advanced
  8. Brad
    Brad avatar
    3 posts
    Registered:
    29 Sep 2010
    15 Feb 2011
    Link to this post
    I have roughly the same questions as Filpe.

    1.  Does the .cs file in the App_Code folder ("MyGeomappingEditor.cs") need to be referenced anywhere?
    2.  Where are the JavaScript files supposed to sit?
    3.  Where would one replace the native GeomappingEditor control in EventsItemEdit.ascx?  What code is used to reference the new Geomapping Editor control?

    Thanks!
  9. bemara57
    bemara57 avatar
    135 posts
    Registered:
    27 Mar 2008
    27 Feb 2011
    Link to this post
    There was some API changes in the Google V3 code. Replace the last function in the Geomapping.js file with this:

    Geomapping.prototype.AcquireCenterPointGoogle_Callback = function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var latitude = results[0].geometry.location.Ba;
            var longitude = results[0].geometry.location.za;
            centerPointCallbackFunction(new GeoPoint(latitude, longitude));
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    }

    @Filipe and @Brad, my EventsItemNew.ascx is really long with my own customizations.. so below are snippets instead. I have all my control templates and Javascript embedded in a class library. You may be able to use the app_code folder, but I am not sure how you would register it below (update the namespace to your App_Code namespace I think):

    <%@ Register TagPrefix="nt" Namespace="MyCustom.Events.WebControls.Admin" Assembly="MyCustom.Events" %>
    ....
                             <div id="geomappingSettings">
                                <p class="expandMapServiceOptions"><a href="javascript:toggleClass('geomappingSettings','');">Use geographic map in your site</a>(Google Maps, Yahoo! Maps or Live Search Maps)</p>
                                <div id="mapServiceWrapper">
                                    <nt:GeomappingEditor ID="Geomapping_Data" runat="server" CssClass="geomaping">
                                    </nt:GeomappingEditor>
    ....

    The Javascript was linked onto the page in the PreRender of my GeomappingEditor.cs class in my previous post.

    I hope this helps.
Register for webinar
9 posts, 1 answered