0

I found the following example code on https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_maps_example.htm

After some minor changes to fit my needs, I got his running to show me the "nearest" customers to the account I am currently on - displayed in a visualforce page with customized markers and a Info window.

The info window however is causing me headaches since I don't know how to store and access the values of every marker (account).

When I understand the code correctly the SOQL Query is called "querystring" and gives back accounts based on the criteria. These accounts are then stored in a List called "warehouses"

What I need now is to store the values of a couple of account fields from those accounts that got added to the list. For example Name and Owner.

I want to reuse these as variables in thr visualforce page. Being part of the original code, this already works for:

locations = new List<Map<String,Double>>()

This is being accessed in the visualforce page by using

<apex:repeat value="{!locations}" var="pos">

which allows me to show the geolocations of every marker I click

<apex:outputPanel layout="block"> <apex:outputText >{!pos}</apex:outputText> </apex:outputPanel>

enter image description here

As being said I would need that not only for 'locations' but as well for a couple of other fields from the account. The goal is to see the corresponding accountname, owner and so on for the clicked marker.

Here is the complete APEX Code:

/* https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_maps_example.htm */


 public class FindNearbyController {

 public List<Map<String,Double>> locations { get; private set; }

 public Account currentAccount {get;set;}

 public Geolocation__mdt GeoConfig { get; set; }

 public FindNearbyController(ApexPages.StandardController stdController) {
    currentAccount  = [SELECT ID,Name, Geolocation__c,Accountinhaber_Text__c,Auftragseingangstyp_picklist__c,ShippingStreet,URL_zum_CC__c FROM Account WHERE ID =: stdController.getID()];

}



  public String currentPosition { 
    get {
        if (String.isBlank(currentPosition)) {
            currentPosition = currentAccount.Geolocation__c; 

        }
        return currentPosition;
    }
    set; 
}


public Boolean resultsAvailable {
    get {
        if(locations == Null) {
            return false;
        }
        return true;
    }
}    


public PageReference findNearby() {
    String lat, lon;

    // FRAGILE: You'll want a better lat/long parsing routine
    // Format: "<latitude>,<longitude>" (must have comma, but only one comma)
    List<String> latlon = currentPosition.split(',');
    lat = latlon[0].trim();
    lon = latlon[1].trim();

    // SOQL query to get the nearest warehouses
    String queryString =
       'SELECT Id, Name,ShippingStreet,LocateCity__longitude__s, LocateCity__latitude__s  ' +
       'FROM Account ' +
       'WHERE DISTANCE(LocateCity__c, GEOLOCATION('+lat+','+lon+'), \'km\') <  3 and Kundenstatus_Direktvertrieb__c = \'Bestandskunde\' ' +
       'ORDER BY DISTANCE(LocateCity__c, GEOLOCATION('+lat+','+lon+'), \'km\') '; //+ 
    // 'LIMIT 50'; (semikolon muss dann in der zeile oben weg)

    // Run the query
    List <Account> warehouses = database.Query(queryString);

    if(0 < warehouses.size()) {
        // Convert to locations that can be mapped
        locations = new List<Map<String,Double>>();
        for (Account wh : warehouses) {
            locations.add(
                new Map<String,Double>{
                    'latitude' => wh.LocateCity__latitude__s, 
                    'longitude' => wh.LocateCity__longitude__s


                }
            );
        }
    }
    else {
        System.debug('No results. Query: ' + queryString);
    }

    return null;
}

}

Here is the visualforce page:

<apex:page standardcontroller="Account" extensions="FindNearbyController" docType="html-5.0" >

<apex:pageBlock >
    <!-- Form field to send currentPosition in request. You can make it
         an <apex:inputHidden> field to hide it. -->
    <apex:pageBlockSection >
        <apex:form >
            <apex:outputLabel for="currentPosition">Bestandskunden in der Nähe</apex:outputLabel> 
            <apex:input size="30" 
                 html-placeholder="Attempting to obtain your position..."
                 id="currentPosition" styleClass="currentPosition" 
                 value="{!currentPosition}" />
            <apex:commandButton action="{!findNearby}" value="Go!"/>
        </apex:form>
    </apex:pageBlockSection>

    <!-- Map of the results -->
    <apex:pageBlockSection rendered="{!resultsAvailable}" title="Locations" columns="1">


        <apex:map width="100%" height="350px" mapType="roadmap" center="{!currentAccount.ShippingStreet}" showOnlyActiveInfoWindow="false" >
            <apex:repeat value="{!locations}" var="pos">
                <apex:mapMarker position="{!pos}" icon="{!URLFOR($Resource.ms_marker)}" title="{!currentAccount.Name}">

                <apex:mapInfoWindow >

                 <!-- Test -->
                <apex:outputPanel layout="block">
                <apex:outputText >{!pos}</apex:outputText>
                </apex:outputPanel>


                <!-- Name + Link -->
                 <apex:outputPanel layout="block" style="font-weight: bold;">
                 <apex:outputLink value="{! '/' + currentAccount.Id}">
                <apex:outputText >{! currentAccount.Name }</apex:outputText>
                </apex:outputLink>
                </apex:outputPanel>

                <!-- Straße -->
                <apex:outputPanel layout="block">
                <apex:outputText >{! currentAccount.ShippingStreet }</apex:outputText>
                </apex:outputPanel>

                <!-- Owner -->
                <apex:outputPanel layout="block">
                <apex:outputText >{! currentAccount.Accountinhaber_Text__c }</apex:outputText>
                </apex:outputPanel>

                <!-- Vertriebskanal -->
                <apex:outputPanel layout="block">
                <apex:outputText >{! currentAccount.Auftragseingangstyp_picklist__c}</apex:outputText>
                </apex:outputPanel>

                <!-- Link zum Customer Cockpit -->
                <apex:outputPanel layout="block">
               <apex:outputLink value="{!'/' + currentAccount.URL_zum_CC__c}">
                <apex:outputText >zum Customer Cockpit</apex:outputText>
                </apex:outputLink>
                </apex:outputPanel>


                </apex:mapInfoWindow>

                </apex:mapMarker>

            </apex:repeat>
        </apex:map>

    </apex:pageBlockSection>

</apex:pageBlock>

3
  • 1
    locations is a list of Maps of lat=>double, log=>doub; you need to make locations a list of accounts so you have access to the geoloc plus account fields
    – cropredy
    Apr 7, 2020 at 3:29
  • Hello cropredy, thanks for your reply. Any chance of giving me a more detail example of how this may look like?
    – Jan Tonnet
    Apr 7, 2020 at 19:05
  • Sorry for bothering @cropredy but this cracks me up. Can´t solve this one...
    – Jan Tonnet
    Apr 10, 2020 at 18:58

1 Answer 1

0

After some more trial and error I solved this one myself.

 public List<Account> warehouses  {get; private set;} 

 warehouses =  [
                           SELECT Id, Name,URL_zum_CC__c,Auftragseingangstyp_picklist__c,AD_MS_Rel_Anzahl_bez__c,Vollst_ndiger_Name__c,ShippingStreet,LocateCity__longitude__s, LocateCity__latitude__s, WZ_Buchstabe__c,OwnerId,GeoLocPosition__c,Accountinhaber_Text__c,WirtschaftszweigWZ08__c,AE_letzte_12_Monate__c,anzeigendaten_de_ID_account__c,indexurl__c
                           FROM Account 
                           WHERE Letzte_gew_Opp_OneSales_in_Tagen__c <= :lastDeal AND DISTANCE(LocateCity__c, GEOLOCATION(:dlat,:dlon), 'km') < :maxDistance AND Id != :theaccId AND WZ_Buchstabe__c = :currentAccount.WZ_Buchstabe__c
                           ORDER BY DISTANCE(LocateCity__c, GEOLOCATION(:dlat,:dlon), 'km')  
                           LIMIT :recordLimit
                  ]; 

Then in my VF Page:

<apex:repeat value="{!warehouses}" var="war">
                <apex:mapMarker position="{!war.GeoLocPosition__c}" title="{!war.Name}" 

GeoLocPosition__c is formula field that allows me to get the latitude and longitude in the same format as the "locations" Map did:

"{latitude="&TEXT(LocateCity__Latitude__s)&",longitude="&TEXT(LocateCity__Longitude__s)&"}"

You must log in to answer this question.

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