1

Using Python 2.7 - I'd like to make a WOEID viewer that shows density plots of photos taken in an area. So far I can generate a (transparent background) contour map of images taken in and around Barcelona (as an example area), but that's pretty much it. My questions are:

1 Within Python - How may I obtain a map of an area for a given longitude & latitude range? E.g. for Barcelona and the image I have, the ranges are:

min to max longitude: 2.101 - 2.204, centre: 2.1525

min to max latitude: 41.362 - 41.461, centre: 41.4115

[2] How may I then combine these two images such that the controur is superimposed - an example I did by hand to help illustrate: enter image description here

My code so far:

import flickrapi
import matplotlib.pylab as plt
import numpy as np

# where to get Where On Earth I.D's from:
# https://www.flickr.com/services/api/explore/flickr.places.find
# e.g. Barcelona = 753692

apikey = 'api key required'
woeid  = 753692 # woeid for Barcelona
flickr = flickrapi.FlickrAPI(apikey)
request = flickr.places_getChildrenWithPhotosPublic(woe_id=woeid)
list    = request[0].getchildren()

x = []
y = []
z = []
for each in list:
    #print each.attrib['latitude'], each.attrib['longitude']
    print each.text
    x.append(float(each.attrib['longitude']))
    y.append(float(each.attrib['latitude']))
    z.append(float(each.attrib['photo_count']))

xmin, xmax = min(x), max(x)
ymin, ymax = min(y), max(y)
x += xmin, xmin, xmax, xmax
y += ymin, ymin, ymax, ymax
z += 0,0,0,0
xrange = xmax - xmin
yrange = ymax - ymin
maxrange = max(xrange, yrange)
stepsize = maxrange/500
# create the grid
xi = np.linspace(xmin, xmax, int(xrange/stepsize))
yi = np.linspace(ymin, ymax, int(yrange/stepsize))
# grid data
zi = plt.griddata(x, y, z, xi, yi)
plt.contour(xi,yi,zi,25,cmap=plt.cm.jet, transparent=True)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.colorbar()
plt.title('Barcelona')
plt.savefig('Barcelona_contour.png', transparent=True)
print 'min to max longitude:', xmin, ' - ', xmax, 'centre:', xmin+(xmax-xmin)/2
print 'min to max latitude:',  ymin, ' - ', ymax, 'centre:', ymin+(ymax-ymin)/2
print 'done'
Harry Lime
  • 2,167
  • 8
  • 31
  • 53

1 Answers1

2

The first thing you need is a way to fetch a map given coordinates. This is tricky. (The earth is a sphere, you want to map the surface rectangle to a Cartesian rectangle.)

Fortunately for you, Google has the wonderfully simple Static Image Maps API. Don't worry, I read the docs so you don't have to.

  • Google uses the Mercator projection. [reference] Hopefully you do too.
  • Rather sadly, Google only supplies zoom levels at powers of two.
  • Also, it's difficult to get an exact region
    1. You can use the center, zoom, and size plus fancy math to compute a rectangle
    2. You can use visible to define a viewport, but Google adds padding

You might go for (1.) and steal someone else's math.

Then you'll want to superimpose the images. There's an SO question on that too.

I haven't got a working prototype and probably won't be able to get one. In particular, the Mercator math doesn't seem to be working for me, although that may be because Google Maps is quantized too coarsely, in which case you'll need some even more fancy algorithms. If you have anything specific, or if this does not help you, please tell me!

Community
  • 1
  • 1
PythonNut
  • 6,182
  • 1
  • 25
  • 41