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>
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>