-
Notifications
You must be signed in to change notification settings - Fork 0
Home
A friend recently saw a picture posted on Facebook by a friend and wanted to find out where that picture was taken. The picture was of someone in a park and he could not pinpoint exactly which park it was, but had a general idea. He asked me if there was a way for him to see the location of the photo on a map.
Before you can determine the location of a photo, the photo has to be geotagged. Geotagged basically means that the longitude and latitude of the photo has been stored in the photo metadata. The metadata is the invisible part of the photo called EXIF data. Depending on the camera, EXIF data will store the current state of the camera when the photo was taken including date and time, shutter speeds, focal lengths, flash, lens type, location data, etc.
Of course, the only way you’ll see where a picture was taken is if the camera is GPS enabled. If you have a camera that doesn’t have any type of GPS option, then there won’t be any location data in the EXIF data. This is true of most SLR cameras. However, if the photo was taken with a smartphone and location services are enabled, then the GPS coordinates of the phone will be captured when you snap a picture.
We need to install a gem to read EXIF data from a given image. We shall use the exifr
gem. You can read the details of the "exifr gem"
$ gem install exifr
You can run $ bundle install
which will do this for you, as per the Gemfile
.
Let's write some code to extract the latitude and longitude info from an image. We will accept the image name (stored on the computer) on the command line.
# exifmap.rb
require 'exifr'
unless ARGV.length == 1
puts "Usage: ruby exifmap.rb path_to_image"
exit
end
begin
photo = EXIFR::JPEG.new(ARGV[0])
lat = photo.gps.latitude.to_s
lng = photo.gps.longitude.to_s
photo_map = "http://maps.googleapis.com/maps/api/staticmap?sensor=false&zoom=5&size=600x300&maptype=roadmap¢er=#{lat},#{lng}&markers=color:blue%7Clabel:I%7C#{lat},#{lng}"
puts photo_map
rescue NoMethodError
puts "Sorry. Your image has no longitude and latitude info in the photo metadata."
rescue Exception => e
puts e.message
end
- We accept the name of the image file (along with the location on the computer) on the command line
-
rescue NoMethodError
traps an error in case the image has no latitude, longitude info -
rescue Exception => e
traps other errors like a mis-spelled image name
The Google Static Maps API lets you embed a Google Maps image on your web page without requiring JavaScript or any dynamic page loading. The Google Static Map service creates your map based on URL parameters sent through a standard HTTP request and returns the map as an image you can display on your web page.
We create the string photo_map
based on the above API, as follows:
- The base URL is
http://maps.googleapis.com/maps/api/staticmap?sensor=false
where applications that determine the user's location via a sensor must passsensor=true
within the Static Maps API request URL. If your application does not use a sensor, passsensor=false
. Thesensor
parameter is required.
The additional parameters used in photo_map
are:
-
zoom
(required) defines the zoom level of the map, which determines the magnification level of the map. This parameter takes a numerical value corresponding to the zoom level of the region desired. Zoom levels between 0 (the lowest zoom level, in which the entire world can be seen on one map) to 21+ (down to individual buildings) are possible within the default roadmap maps view. -
size
(required) defines the rectangular dimensions of the map image. This parameter takes a string of the form {horizontal_value}x{vertical_value}. For example, 600x300 defines a map 600 pixels wide by 300 pixels high. -
maptype
(optional) defines the type of map to construct. There are several possible maptype values, includingroadmap
,satellite
,hybrid
, andterrain
. -
center
(required) defines the center of the map, equidistant from all edges of the map. This parameter takes a location as either a comma-separated {latitude,longitude} pair (e.g. "40.714728,-73.998672") or a string address (e.g. "city hall, new york, ny") identifying a unique location on the face of the earth. -
markers
(optional) define one or more markers to attach to the image at specified locations. This parameter takes a single marker definition with parameters separated by the pipe character (| or %7C).
The markers
parameter takes set of value assignments (marker descriptors) of the following format:
markers=markerStyles|markerLocation1| markerLocation2|...
etc.
The set of markerStyles is declared at the beginning of the markers
declaration and consists of zero or more style descriptors separated by the pipe character (|), followed by a set of one or more locations also separated by the pipe character (|).
The marker style descriptors contain the following key/value assignments:
-
size
: (optional) specifies the size of marker from the set {tiny, mid, small}. If no size parameter is set, the marker will appear in its default (normal) size. -
color
: (optional) specifies a 24-bit color (example: color=0xFFFFCC) or a predefined color from the set {black, brown, green, purple, yellow, blue, gray, orange, red, white}. -
label
: (optional) specifies a single uppercase alphanumeric character from the set {A-Z, 0-9}.
Each marker descriptor must contain a set of one or more locations defining where to place the marker on the map. These locations may be either specified as latitude/longitude values or as addresses.
Finally, our app displays the URL which should be opened in a browser window to see the map.