3

I have been trying to get something to work with Google maps in combination with Apex and Visualforce pages, but I can't figure out what I'm doing wrong. What I want is to set different icons with different colors in a Google map. More exactly, I want to modify an existing code that was doing the job but only with two icons, one for current location (Account object), and another icon for accounts around the current location.

If I take a look to the Visualforce page that is part of the Account page layout, which contains the Google maps, I can see this section of the code that takes care of the icons and some other stuff:

`var locations = 
[
  {!locationArray}
];

    var map = new google.maps.Map(document.getElementById('map'), {mapTypeId: google.maps.MapTypeId.ROADMAP});
    var bounds = new google.maps.LatLngBounds();

      for(var i=0;i<locations.length;i++) 
      {
          var ll = new google.maps.LatLng(locations[i][1],locations[i][2]);
          bounds.extend(ll);
      }

      map.fitBounds(bounds);

var infowindow = new google.maps.InfoWindow();

var marker, i,mainX,mainY;

for (i = 0; i < locations.length; i++) 
{
  if(locations[i][3]!=-1)
    {     
      marker = new google.maps.Marker
      ({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map,    
        icon: '{!$Resource.other}'
      });
   }       
   else
   {        
       marker = new google.maps.Marker
      ({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
         map: map,
         icon: '{!$Resource.current}'
      });             
   }       
  google.maps.event.addListener(marker, 'click', (function(marker, i) {
    return function() {
      infowindow.setContent(locations[i][0]);
      infowindow.open(map, marker);
    }
  })(marker, i));
}

// Remove focus
function setFocusOnLoad() {}`

So I though, ok, I want to add a different icon to each account base on a value of a custom field (Point of Sales), in the Account object. What I did was to created a custom text field in the Account object, Google_marker_URL__c, to assigned a URL to different icons that are in the Documents object, base on the values in the Point of Sales field. This was easy and it works! All I needed was to change the icon: '{!$Resource.other}' to icon:'{!Account.Google_marker_URL__c}'. The problem is that is picking up the current account Google_marker_URL__c for all the accounts around, which it is obvious... now :( So my question is, how can I change that? How can I use the icon that it is assigned to the accounts that are around the current account?

I have been trying all day different things but it won't work the way I want. I use four different icons with four different colors. Any ideas on how to change this code to do what I want?

Thanks.


22.07.2014 09:00PM

I'm adding the controller here:

 `public class DoorGoogleMap_CTRL
  {       
   public List<SelectOption> RangeOptions{
       get{
        List<SelectOption> listRangeOptions = new List<SelectOption>();
        for(integer i=5; i<=50; i+=5){
       listRangeOptions.add(new SelectOption(String.valueOf(i),String.valueOf(i)));
        }
        return listRangeOptions;
    }
    set;
}   

public List<SelectOption> Units
{
  get
  {
    if(Units==null)//Units for filter purpose they show this units in picklist
    {
      Units=new List<SelectOption>();
      Units.add(new SelectOption('1.60934','mi'));
      Units.add(new SelectOption('1','km'));
    }
    return Units;
  }
  set;
}
public String selectedUnit{get;set;}
private boolean isDoor = false;
public boolean isMother=false;
public id currentAccountId{get;set;}//get the the current account id
private Account currentAccount;
private boolean isDeleted=false;
public DoorGoogleMap_CTRL(ApexPages.StandardController controller) 
{     
   Account acct=(Account)controller.getRecord();
   Account tmp_account;
    try 
    {
      tmp_account=[Select Id, Name, BillingStreet, BillingCity, BillingPostalCode, BillingCountry, Location__Latitude__s, Location__Longitude__s,Deleted__c, Mother_ID_Checkbox__c,Door_Checkbox__c, Google_marker_URL__c from Account where id=:acct.id ];//get all information about mother because the system will prevent from use any column without querying them.
       currentAccount=tmp_account;
       isDoor=tmp_account.Door_Checkbox__c ;
       isMother=tmp_account.Mother_ID_Checkbox__c;
       isDeleted=tmp_account.Deleted__c;
       xCentral=currentAccount.Location__Latitude__s;
       yCentral=currentAccount.Location__Longitude__s;
       currentAccountId=acct.id;
     }catch(Exception e)
     {          
     }        
   }

    private List<Account> lstAccount=new List<Account>();
    private List<Account> filteredAccount;
    private void prepareLocationArray()
   {
    String sAddressInfo='';
    Decimal tmp_longitude,tmp_latitude;
    String tmp_googleIconMarker; 
    integer indicator=0;
    //if(locationArray==null)
    locationArray='';
    for(integer i=0;i<filteredAccount.size();i++)
    {     
     sAddressInfo='';     
     tmp_longitude=filteredAccount.get(i).Location__Longitude__s;
     tmp_latitude=filteredAccount.get(i).Location__Latitude__s;
     tmp_googleIconMarker=filteredAccount.get(i).Google_marker_URL__c; 
     if(tmp_longitude==yCentral&&tmp_latitude==xCentral)                
    {
     indicator=-1;
    }
    else
    indicator=i;

    // CVER: display the address information
       if(filteredAccount.get(i).BillingStreet != null)  
      sAddressInfo += '<br>' + filteredAccount.get(i).BillingStreet;  
       if(filteredAccount.get(i).BillingCity != null)  
      sAddressInfo += '<br>' + filteredAccount.get(i).BillingCity;  
       if(filteredAccount.get(i).BillingPostalCode != null)  
      sAddressInfo += ',' + filteredAccount.get(i).BillingPostalCode;  
       if(filteredAccount.get(i).BillingCountry != null)  
      sAddressInfo += '<br>' + filteredAccount.get(i).BillingCountry;
      if(sAddressInfo != '') sAddressInfo = String.escapeSingleQuotes(sAddressInfo);  

         String tmp_name;
         tmp_name=String.escapeSingleQuotes(filteredAccount.get(i).name.escapeXml());

         if(i<filteredAccount.size()-1)                            
            locationArray+='[\'<a target="_parent" href="/'+filteredAccount.get(i).id+'">'+tmp_name+'</a>' + sAddressInfo + '\','+filteredAccount.get(i).Location__Latitude__s+','+filteredAccount.get(i).Location__Longitude__s+','+indicator+'],';
         else
            locationArray+='[\'<a target="_parent" href="/'+filteredAccount.get(i).id+'">'+tmp_name+'</a>' + sAddressInfo + '\','+filteredAccount.get(i).Location__Latitude__s+','+filteredAccount.get(i).Location__Longitude__s+','+indicator+']';
    }
  }
    public String locationArray
   {
   get    
  {                                          
    if(locationArray==null)
    {     
      if(isMother)
         filterRange=100;
      else if(isDoor)
         filterRange=50;                                              
      locationArray= '';
      if(lstAccount.size()==0)
      {
         if(isDoor)
         {

           String SOQLQuery='';
           if(!isDeleted)
           {                 
             SOQLQuery='SELECT Id, Name, Point_of_Sale__c, Google_marker_URL__c, BillingStreet, BillingCity, BillingPostalCode, BillingCountry,Nielsen_ID__c, Location__Latitude__s,Location__Longitude__s FROM Account where Location__Latitude__s!=null and Location__Longitude__s!=null and Deleted__c=false and Door_Checkbox__c=true and DISTANCE(Location__c, GEOLOCATION('+xCentral+','+yCentral+'), \'km\') <'+(filterRange+1);
             lstAccount=Database.query(SOQLQuery);                         
           }
           else
           {
             SOQLQuery='SELECT Id, Name, Point_of_Sale__c, Google_marker_URL__c, BillingStreet, BillingCity, BillingPostalCode, BillingCountry, Location__Latitude__s,Location__Longitude__s FROM Account where Location__Latitude__s!=null and Location__Longitude__s!=null and Deleted__c=true and Door_Checkbox__c=true and DISTANCE(Location__c, GEOLOCATION('+xCentral+','+yCentral+'), \'km\') <'+(filterRange+1);
             lstAccount=Database.query(SOQLQuery);                             
           }
         }         
        filteredAccount=lstAccount;
      }

      SelectedUnit='1';
      //calculateDistance();          
      prepareLocationArray();
    }                              
    return locationArray;  
    }
    set;
    }  
    public Decimal xCentral{get;set;}  
    public Decimal yCentral{get;set;}
    public Decimal range
    {
    get{return filterRange;}
    set
    {
    filterRange=value;
    }
  }
  private Decimal filterRange;// use this variable to avoid auto fucos problem  
  public void calculateDistance()
 {      
   system.debug('filterRange'+filterRange);
    if(isMother)
    {           
        if(filterRange>100)
          filterRange=100;                                  
    }
    else if(isDoor)
    {       
        if(filterRange>50)
          filterRange=50;
    }               
    if(range<1)
       filterRange=1;            
    Set<Account> tmp_lstAccount=new Set<Account>();
    Decimal R = 6371; // Radius of the earth in km
    Decimal dLat,dLon,a,c,d;
    Decimal rangeInKM;
    String theMarker;

    if(selectedUnit==null)
    {
       rangeInKM=filterRange*decimal.valueOf('1.60934');
    }
    else
        rangeInKM=filterRange*decimal.valueOf(selectedUnit);   

    for(Account tmp_account:lstAccount)
    {        
      try
      {  
        dLat = toRadians((xCentral-tmp_account.Location__Latitude__s));
        dLon = toRadians((yCentral-tmp_account.Location__Longitude__s));
        a = Math.sin(dLat/2)*Math.sin(dLat/2)+Math.cos(toRadians(tmp_account.Location__Latitude__s))*Math.cos(toRadians(xCentral))*Math.sin(dLon/2)*Math.sin(dLon/2); 
        c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        d = R * c; // Distance in km
        if(d<=rangeInKM)
        {
           tmp_lstAccount.add(tmp_account); 
        }
      }catch(Exception ex)
      {
         ApexPages.addMessages(ex);
      }

    }     

    //if(tmp_lstAccount.size()>0)
    //{
        tmp_lstAccount.add(currentAccount);
        filteredAccount=new List<Account>();            
        filteredAccount.addAll(tmp_lstAccount);
       // system.debug('filtered'+filteredAccount);
       // locationArray=null;
        prepareLocationArray();
    //}        
   }
   private Decimal toDegree(Decimal val)
   {
    return (val*(180/3.14));
   }
   private Decimal toRadians(Decimal val)
  {      
  return (val*(3.14/180));   
  }    `
1
  • I want to add something. I have been trying all crazy stuff but still not working. The Visualforce page have a SOQL query which eventually will become the var Locations that we can see on the Visualforce page. I was wondering if I can use that query to access the Point_of_Sale__c, and form there use if statements in java script to determinate when to use an icon base on the point to sales's values.Is this possible? Gonna to try now ... Jul 22, 2014 at 15:01

2 Answers 2

1

The place to put the marker URL is the locations array because that lets you define one per location.

So instead of:

  if(locations[i][3]!=-1)
    {     
      marker = new google.maps.Marker
      ({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map,    
        icon: '{!$Resource.other}'
      });
   }       
   else
   {        
       marker = new google.maps.Marker
      ({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
         map: map,
         icon: '{!$Resource.current}'
      });             
   } 

you could just have:

marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map,    
        icon: locations[i][4]
        });

So the Apex code that builds the locationArray string should add an additional nested array entry for the marker URL (or replace the index 3 one that appears to just be a number with the marker URL).

14
  • Thanks for you answer Keith. I tried that but all I can see now are the default Google markers. I need to have the "current icon" to point out to the user the "current account".So maybe I should have said that I have 4 icons + the current location one. But, how do I connect the elements in the array location to their Google_marker_URL__c? The icon: location[i][4] only gave me the start ones... Jul 22, 2014 at 18:33
  • @Viasur Yes you would have to make sure that the "current account" marker was also set properly in the array; probably easiest to make that a Document too so the same pattern is used. I'm afraid I don;t understand your last comment; I assumed that the controller could assign the right marker so that the generated locations array was correct. But are you saying something is done at the client-side to change to a marker other than the "start one(s)"?
    – Keith C
    Jul 22, 2014 at 18:41
  • Hello again Keith. Could you explain with a bit more details on how should I approach to this now? Or maybe point me out where in the controller I need to set the link to the new icons? Jul 22, 2014 at 19:10
  • Probably here?: if(i<filteredAccount.size()-1) locationArray+='[\'<a target="_parent" href="/'+filteredAccount.get(i).id+'">'+tmp_name+'</a>' + sAddressInfo + '\','+filteredAccount.get(i).Location__Latitude__s+','+filteredAccount.get(i).Location__Longitude__s+','+indicator+'],'; else locationArray+='[\'<a target="_parent" href="/'+filteredAccount.get(i).id+'">'+tmp_name+'</a>' + sAddressInfo + '\','+filteredAccount.get(i).Location__Latitude__s+','+filteredAccount.get(i).Location__Longitude__s+','+indicator+']'; Jul 22, 2014 at 19:18
  • @Viasur Yes there, though that code is pretty ugly already. Basically make the value of indicator the URL to the marker and reference that using locations[i][3] in the JavaScript.
    – Keith C
    Jul 22, 2014 at 19:41
0

@Viasur - would be great if you could dump up the finalised code in the main body of the question. Any chance of that?

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .