NAME

makeKML.pm - Builds KML files for Google Maps and Google Earth

SYNOPSIS

Simple example:

  use makeKML;

  my $kml = makeKML->new({ name => "Some Test Map" });

  $kml->add({
    name => 'The White House',
    desc => 'This is where the president of the U.S.A. hangs out',
    link => 'http://whitehouse.gov/',
                style => 'yellowpush',
    address => '1600 Pennsylvania Ave NW',
    city => 'Washington',
    state => 'DC',   # Not actually a state in this case.
      # Can be a country, municipality, etc..
      # Address formed is "address, city state"
  });

  $kml->write("Map.kml");

DESCRIPTION

makeKML.pm allows you to create a simple list of places and write out a KML file to be used by Google Maps or Google Earth.

makeKML.pm will lookup latitude and longitude of locations by address (Called "geocoding") and will even cache the results for you. You will probably need this. See 'Geocoding' below.

You can view your KML file by putting it on a webserver, verifying the URL of the raw KML file (and that the webserver will display the KML file) and then entering that KML file into the search box of Google Maps. Google Earth can also open KML files directly.

GEOCODING

KML files need latitude and longitude for each placemark, a simple address will not suffice. makeKML.pm can look these up for you using the Google Maps API.

API KEY

You will need to register with Google or opencagedata to get a key, but it costs nothing.

For Google, simply visit: http://code.google.com/apis/maps/signup.html or https://console.developers.google.com/

Turn on the Geocoding API and look at your credentials, you need to copy the API KEY for server applications.

You can also use opencagedata which allows free geocoding limited to 1/sec by signing up at: https://opencagedata.com/

You can give your key to makeKML.pm a number of ways:

As an value in your script:
  makeKML->Key("TheKeyValueThatYouGetFromGoogleOrOpenCageData");
Saved in a key file.

Put the key on a single line in one of the following locations:

  google_api_key
  .google_api_key
  $HOME/.google_api_key

If you're using opencagedata, replace "google" with "opencagedata":

  opencagedata_api_key
  .opencagedata_api_key
  $HOME/.opencagedata_api_key

Or else put the value in a different file and hand it to the library:

  makeKML->KeyFile("KeyFile");

Furthermore, we cache the results in a simple cache file so that we don't have to go back to google each time to get the answers. It's fairly safe to assume that addresses don't move. The default file is latlong.cache, you can change this with:

  makeKML->latlongCache("CacheFile");

If multiple placemarks are at the same location, then the user won't be able to distinguish them on the map. makeKML will offset the lat/long of each placemark by a small amount. This amount can be changed (or set to 0) with:

  makeKML->offsetDuplicatePlacemarks(.001);   # Default value

If you are looking for a simple way to lookup latitude and longitude from an address, but don't need the rest of the makeKML functionality, then see the 'latlong' tool:

  http://MarginalHacks.com/index.0.html#latlong

METHODS

$kml = new makeKML(%options);

Constructs a new makeKML object.

Options include 'name' (for the map name) and 'file' (to specify file output). Also see 'write'

$kml->add(%place);

Add a place to the KML file. Places can have a number of keys:

  Required fields:
name        Name of the place
address     Street address
city        City name
state       State, country or municipality.

At least one of address/city/state is required, it should be enough information for a search in google maps to find the location.

  And some optional fields:
link        URL
desc        Long description
phone       Phone number
coords      Latitude,longitude  (if not specified, see GEOCODING)
style       One of the predefined pushpin/paddle styles:
        redpush bluepush whitepush yellowpush greenpush
        ltbluepush purplepush greenpaddle ltbluepaddle
        pinkpaddle purplepaddle redpaddle whitepaddle yellowpaddle
$kml->write(); $kml->write($file);

Write out the KML file.

If a filename is not given, then writes to the file specified in new().

LIMITATIONS

Funky Characters

It tries to take care of funky characters so that it's KML safe, but there doesn't seem to be a spec on this, and Google Maps will only tell you that a kml file has errors (and not what they are).

If you find any other characters that need to be cleaned from any of the KML fields, please let me know.

HTML EXAMPLE

Google used to allow direct entry of a KML URL to show a KML map on maps.google.com, but this has been discontinued as of Feb 2015. Now if you want to publish a KML map you have to use the Google Maps Javascript API v3 to embed the map in an HTML file. This is actually fairly simple to do, though there aren't any good examples and the docs on google are not up-to-date (as of 2015). The API v3 now requires a Google API key, though this was previously not the case and many google docs will tell you otherwise. This is not the same key as you use for the Geocoding, this is the API key for browser applications which you can also find in your credentials. Here is some example HTML and javascript that will embed a map on a web page, replace API_KEY_GOES_HERE with your browser application API key.

        <script type="text/javascript"
          src="https://maps.googleapis.com/maps/api/js?key=API_KEY_GOES_HERE">
        </script>
        <script type="text/javascript">
          function initialize() {
            var map = new google.maps.Map(
              document.getElementById('map-canvas'));
            // Timestamp that changes every 500 seconds
            var time500 = parseInt((new Date().getTime())/500000);
            var georssLayer = new google.maps.KmlLayer(
              'http://SFLindyExchange.com/2013/Map/gmap.kml?a='+time500,
              { map: map }
            );
            georssLayer.setMap(map);
          }
          google.maps.event.addDomListener(window, 'load', initialize);
        </script>
        <div style="height: 400px; width: 600px;" id="map-canvas"></div>

We add the fake 'a=<timestamp>' query because browsers will not normally reload KML files when they change, this will change the URL so that eventually the KML file will be reloaded. Since the browser key is embedded in the Javascript source (and can therefore be read by anyone), you probably want to protect this by limiting referrers for the API key on the developers console.

COPYRIGHT

  Copyright 2004,2020 David Ljung Madison Stellar L<http://GetDave.com/>
  All rights reserved.
  See: L<http://MarginalHacks.com/>