In one of the projects that I’m currently working on the editor should, on certain page types, be able to specify a location which is displayed as a marker on a Google Maps map when the page is rendered.
The simplest solution from a technical perspective would be to add two float number properties to the page types, one for latitude and one for longitude. That would however be horrible from the editors perspective as he or she would be forced to find the exact coordinates for for instance the companies different offices around the world.
Another solution would be to let the editor specify a street address and then when the page is displayed that address would be translated into coordinates by using some geocoding service (like the one provided by Google). This solution would definitely be better for the editor and would also be quite easy to implement. However, as I started implementing it in the above mentioned project I found my self feeling grumpy and deduced that it was because I was building something I didn’t really like.
I had several problems with the solution. First of all the only feedback the editor would get if he or she misspelled the address would be when viewing the page, not in edit mode, and the feedback would only be that no map was displayed. Further I didn’t like that the geocoding of the address happened when the page was rendered. It meant another HTTP request or that I would have to implement some sort of caching.
Another alternative would have been to use the GeoPicker property from the GoogleMaps EPiCode project. It didn’t really suite my needs though. While it’s a really cool property it is made as an example of how Google Maps can be used and perhaps therefore it is a bit technical and not as intuitive for the editor as I’d like for the project I’m working on. So, while perhaps it was overkill, I finally decided to build a custom property of my own.
How it works
When editing a page the property is rendered with a disabled textbox and a button that opens up a popup-window.
The popup-window let’s the editor select a location by placing a marker in a map. The marker is placed/moved by clicking in the map, dragging the marker or searching for an address.
Once the marker is placed and the window is closed by clicking on the Select-button the textbox contains the address plus the coordinates.
The property value is stored as a new type named GoogleMapsLocation which contains three properties, Address, Latitude and Longitude. An example of how to retrieve the values:
GoogleMapsLocation location = (GoogleMapsLocation)
CurrentPage.GetValue("GoogleMapsLocation");
double latitude = location.Latitude;
string latitudeString =
latitude.ToString(
GoogleMapsLocation.GoogleMapsDoubleFormatProvider);
double longitude = location.Longitude;
string longitudeString =
longitude.ToString(
GoogleMapsLocation.GoogleMapsDoubleFormatProvider);
string address = location.Address;
Configuration
While no configuration is necessary an alert-box will be displayed when selecting a location unless a valid Google Maps API key is specified. As the API keys are host specific I made it so that the it’s possible to specify several keys as AppSettings in web.config. The keys should be named GoogleMapsKey_<hostname>, like this:
<add key="GoogleMapsKey_localhost"
value="ABQIAAAAywoXgmm79IMA7ROWRPMETBT2yXp"/>
<add key="GoogleMapsKey_www.nansen.se"
value="ZAY8_ufC3CFXhHIE1NvwkxRf28wlfK"/>
There are also three other configuration options, all specified as AppSettings. GoogleMapsLocationDefaultCenter specifies the default coordinates, separated by a comma, at which the map will be centered if a value is not already specified for the page. GoogleMapsLocationDefaultZoomLevel specifies the default zoom level if no value is set. If these settings are not specified in web.config they will default to 5 as zoom level and Skeppsbron 34 in Stockholm (home of Nansen ;-)) as center.
GoogleMapsLocationCurrentLocationZoomLevel specifies the default zoom level when a value is previously set for the page. It will default to 13 if the AppSetting isn’t specified.
Heres an example configuration (taken from my configuration/appSettings node):
<add key="GoogleMapsLocationDefaultCenter"
value="59.3239999,18.0753597"/>
<add key="GoogleMapsLocationDefaultZoomLevel" value="5"/>
<add key="GoogleMapsLocationCurrentLocationZoomLevel" value="5"/>
Source code and installer
The module is available as a zip file, which supports installation with EPiServer Deployment Center, here. The source code is available at EPiCode, here.