function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
aebimoyoaebimoyo 

Adding a field to the Geo Force Google Earth visualforce page

Hello

I've just started playing with the Geo Force application that allows you to map your accounts on a google earth within salesforce. I've managed to geo code all my accounts and can view them in google earth. In the pop up bubble that appears for each account, I'd like to add some details (phone, etc). I've created custom fields on the Geo Force custom object that contain the information, and now I'm trying to work out how to add them to the bubble. 

 

I finally found the component that I think controls the bubbles and added the following line into the code:

 

<td><p><apex:outputText value="{!gLocation.geo.Phone__c}" escape="false" /></p></td>

 

Which I just copied from a previous line of code that displays the About Us field in the bubble:

 

<p><apex:outputText value="{!gLocation.geo.About_Us__c}" escape="false" /></p>

 

 

But when I try to view the google earth, I get this error:

 

SObject row was retrieved via SOQL without querying the requested field: Geo_Location__c.Phone__c

 

Anyone got any ideas?

 

Thanks

Nicole

TehNrdTehNrd
Can you post the SOQL query that is populating gLocation? Your query is probably not grabbing the phone field.
aebimoyoaebimoyo

OK, I'm not totally sure what you're after, but hopefully one of these is it!

 

There's the template used for generating the KML used by account earth mapping:

<apex:page standardController="Account" 
recordSetvar="notused"
extensions="LocationsExt"
sidebar="false"
contenttype="application/vnd.google-earth.kml+xml#sfdc_foundation.kml" ><kml xmlns="http://www.opengis.net/kml/2.2">
<Document><name>force.com</name><Folder>
<name>Account Earth KML</name><open>1</open>
<Style id='theBalloonStyle'>
<BalloonStyle><text>$[description]</text></BalloonStyle>
</Style>
<apex:repeat value="{!geolocations}" var="one" >
<Placemark>
<styleUrl>#theBalloonStyle</styleUrl>
<Style><IconStyle>
<scale>0.8</scale><Icon><href><apex:outputtext value="{!one.geo.Icon_URL__c}" /></href></Icon>
</IconStyle></Style>
<name><apex:outputtext value="{!one.geo.name}" /></name>
<description><c:balloonTemplates gLocation="{!one}" /></description>
<Point>
<coordinates>{!one.geo.lon__c},{!one.geo.lat__c},0</coordinates></Point>
</Placemark>
</apex:repeat>
</Folder></Document></kml>
</apex:page>

 

 

Or maybe this is it: 

<apex:component controller="geoApiKey" >
<apex:attribute name="kml" description="This is the KML map data" type="string" required="true" />
<apex:attribute name="height" description="This is the map height" type="integer" default="500" />
<apex:attribute name="width" description="This is the map width" type="integer" default="950" />

<apex:attribute type="Location" name="look" required="true"
description="Location to look at to begin with" />
<apex:attribute type="string" name="Location" required="true"
description="not used" />

<apex:outputPanel >
<!-- <apex:inputhidden value="{!location}" id="latlon" /> -->
<script src="{!jsapi_script}"></script>
<script src="{!maps_script}" type="text/javascript"></script>

<script> google.load("earth", "1");
google.setOnLoadCallback(init);
var ge = null;

function init() {
google.earth.createInstance('{!$Component.map3d}', initCallback, function (object) { } );
}

function initCallback(object) {
ge = object;
ge.getWindow().setVisibility(true);

var p = ge.parseKml( "<apex:outputText value="{!kml}" escape="false" />" );
ge.getFeatures().appendChild(p);

var la = computeFitLookAt(ge, p, 1.4 );
if ( la != null ) {
ge.getView().setAbstractView(la);
}

ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
}

// http://kml-samples.googlecode.com/svn/trunk/interactive/ge-poly-fit-hack.js
function getObjectCoordData(ge, kmlObject) {
var out = {
'coords': [],
'altitudeMode': -1,
'maxAltitude': -9999
};

function pushLatLngAlt(lat, lng, alt) {
out.coords.push({
lat: lat,
lng: lng,
alt: alt
});

out.maxAltitude = Math.max(out.maxAltitude, alt);
}

function pushCoord(pointOrCoord) {
pushLatLngAlt(pointOrCoord.getLatitude(), pointOrCoord.getLongitude(), pointOrCoord.getAltitude());
}

function pushChildCall(retval, altitudeMode) {
out.coords = out.coords.concat(retval.coords);
out.maxAltitude = Math.max(out.maxAltitude, retval.maxAltitude);

// stop at first altitudeMode, so if it's already set, don't update it
if (out.altitudeMode == -1)
out.altitudeMode = retval.altitudeMode;
}
//debugger;
// extract the points from the given object
if (kmlObject && 'getType' in kmlObject) {
if (out.altitudeMode == -1 && 'getAltitudeMode' in kmlObject)
out.altitudeMode = kmlObject.getAltitudeMode();

switch (kmlObject.getType()) {
// features
case 'KmlFolder':
case 'KmlDocument':
var children = kmlObject.getFeatures().getChildNodes();
var numChildren = children.getLength();
for (var i = 0; i < numChildren; i++)
pushChildCall(getObjectCoordData(ge, children.item(i)));
break;

case 'KmlPlacemark':
if ('getGeometry' in kmlObject)
return getObjectCoordData(ge, kmlObject.getGeometry());
break;

case 'KmlGroundOverlay':
var latLonBox = kmlObject.getLatLonBox();
var alt = kmlObject.getAltitude();
pushLatLngAlt(latLonBox.getNorth(), latLonBox.getEast(), alt);
pushLatLngAlt(latLonBox.getNorth(), latLonBox.getWest(), alt);
pushLatLngAlt(latLonBox.getSouth(), latLonBox.getEast(), alt);
pushLatLngAlt(latLonBox.getSouth(), latLonBox.getWest(), alt);
break;

// geometries
case 'KmlMultiGeometry':
var children = kmlObject.getGeometries().getChildNodes();
var numChildren = children.getLength();
for (var i = 0; i < numChildren; i++)
pushChildCall(getObjectCoordData(ge, children.item(i)));
break;

case 'KmlModel':
pushCoord(kmlObject.getLocation());
break;

case 'KmlPolygon':
pushChildCall(getObjectCoordData(ge, kmlObject.getOuterBoundary()));
break;

case 'KmlLinearRing':
case 'KmlLineString':
var coordsObj = kmlObject.getCoordinates();
var n = coordsObj.getLength();
for (var i = 0; i < n; i++)
pushCoord(coordsObj.get(i));
break;

case 'KmlCoord': // coordinates
case 'KmlLocation': // models
case 'KmlPoint': // points
pushCoord(kmlObject);
break;
}
}

return out;
}

function computeFitLookAt(ge, obj, aspectRatio) {
var DEGREES = Math.PI / 180;
var EARTH_RADIUS = 6378137;

var coordData = getObjectCoordData(ge, obj);

if ('getAbstractView' in obj) {
var la = obj.getAbstractView();
if (la != null)
return la;
}

if (coordData.coords.length) {
// range calculation -- the hard part
var center = null;
var range = 0.0;
if (coordData.coords.length == 1) {
center = new google.maps.LatLng(coordData.coords[0].lat, coordData.coords[0].lng);
range = 1000;
} else {
// compute bbox
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < coordData.coords.length; i++)
bounds.extend(new google.maps.LatLng(coordData.coords[i].lat, coordData.coords[i].lng));

// find center
center = bounds.getCenter();
var sw = bounds.getSouthWest();
var ne = bounds.getNorthEast();

var lngSpan = new google.maps.LatLng(center.lat(), sw.lng()).
distanceFrom(new google.maps.LatLng(center.lat(), ne.lng()));
var latSpan = new google.maps.LatLng(sw.lat(), center.lng()).
distanceFrom(new google.maps.LatLng(ne.lat(), center.lng()));

if (!aspectRatio)
aspectRatio = 1.0;

var PAD_FACTOR = 1.5; // add 50% to the computed range for padding
var beta;

var aspectUse = Math.max(aspectRatio, Math.min(1.0, lngSpan / latSpan));
var alpha = (45.0 / (aspectUse + 0.4) - 2.0) * DEGREES; // computed experimentally;

// create LookAt using distance formula
if (lngSpan > latSpan) {
// polygon is wide
beta = Math.min(90 * DEGREES, alpha + lngSpan / 2 / EARTH_RADIUS);
} else {
// polygon is taller
beta = Math.min(90 * DEGREES, alpha + latSpan / 2 / EARTH_RADIUS);
}

range = PAD_FACTOR * EARTH_RADIUS * (Math.sin(beta) *
Math.sqrt(1 / Math.pow(Math.tan(alpha),2) + 1) - 1);
}

var la = ge.createLookAt('');
la.set(center.lat(), center.lng(), coordData.maxAltitude, coordData.altitudeMode, 0, 0, range);
return la;
}

return null;
}

</script>

<apex:outputPanel id="map3d"
style="border: 1px solid silver; height: {!height}px; width: {!width}px;"
layout="block" />

</apex:outputPanel>
</apex:component>

 

 

 

Or there's the template for the balloons, but I don't think that's what you're after and I think I'm now at my character limit for this reply!

 


Hopefully one of those is it - there are other related components and pages, but I can't figure out what each is doing.

 

Thanks

Nicole