Created
April 20, 2012 09:40
-
-
Save josher19/2427363 to your computer and use it in GitHub Desktop.
Use Google and YQL to geocode addresses
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Geocode TSV</title> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js" ></script> | |
</head> | |
<body> | |
<form> | |
<textarea rows=10 cols=80 name=inp id=inp > | |
Post_author,post_date,post_date_gmt,post_title,category,IMAGE,tags,post_content,post_excerpt,post_status,comment_status,ping_status,post_password,post_name,to_ping,pinged,post_modified,post_modified_gmt,post_content_filtered,post_parent,menu_order,post_type,post_mime_type,comment_count,geo_address,geo_latitude,geo_longitude,map_view,add_feature,timing,contact,email,twitter,facebook,proprty_feature,post_city_id,video,is_featured,paid_amount,alive_days,paymentmethod,remote_ip,ip_status,pkg_id,featured_type,total_amount,website,comments_data,rating_data | |
1,01/06/12 9:13,01/06/12 9:13,Embassy Suites Philadelphia,Hotels,hotels5.jpg,, The newly renovated Embassy Suites Philadelphia ,,publish,open,open,,embassy-suites-philadelphia,,,01/06/12 9:13,01/06/12 9:13,,0,0,post,,0,1776 Benjamin Franklin Parkway Philadelphia PA 19103,39.95646452,-75.16884327,,,Daily 10:30 am ,(111) 111-0000,[email protected],http://twitter.com/embassysuites1,http://facebook.com/embassysuites1,,1,,,,,,,,,,,http://embassysuites1.hilton.com/en_US/es/hotel/PHLDTES-Embassy-Suites-Philadelphia-Center-City-Pennsylvania/index.do,, | |
1,01/06/12 9:13,01/06/12 9:13,Loews Philadelphia Hotel,Feature&Hotels,hotels1.jpg,, <h3>OVERVIEW </h3> One of the most important architectural works of the 20th Century the PSFS Philadelphia Savings Fund Society Building has been converted into the new 585-room Loews Philadelphia Hotel. Designed by George Howe and William Lescaze the building was erected in 1932 and was the first international style modernist high-rise building. Today the building retains period details such as Cartier clocks bank vault doors and polished granite as well as modern amenities such as a full service health spa business center spinning room lap pool and over 40 000 square feet of multi-purpose space including three ballrooms. <h3>THE HOTEL </h3> Loews Hotels is proud to have restored the landmark PSFS Building to its original grandeur while transforming it into a hotel that people from all over the world can experience and enjoy. The hotel takes full advantage of the building´s historical features. The three-story former banking room has been preserved as Millennium Hall a dramatic banquet space. The historic rooftop boardroom has been converted to a spectacular setting for catered events. The building retains period details such as Cartier clocks bank vault doors and polished granite as well as modern amenities such as a full service health spa business center spinning room lap pool and over 40 000 square feet of multi-purpose space including three ballrooms. Feel the comforts of home in accommodations that perfectly balance the contemporary with the elegant. Where every detail from the lofty ten-foot ceilings to the miles of spectacular views is designed to serve one purpose ,,publish,open,open,,loews-philadelphia-hotel,,,01/06/12 9:13,01/06/12 9:13,,0,0,post,,0,1200 Market Street Philadelphia PA 19107,39.95180958,-75.16021729,,,Daily 6:30 am ,(111) 111-0000,[email protected],http://twitter.com/loewshotels,http://facebook.com/loewshotels,,1,,1,,,,,,,,,http://www.loewshotels.com/en/hotels/philadelphia-hotel/overview.aspx,, | |
1,01/06/12 9:13,01/06/12 9:13,Rittenhouse Square,Attractions,a19.jpg,Museum, Unlike the other squares the early Southwest Square was never used as a burial ground although it offered pasturage for local livestock and a convenient dumping spot for ,,publish,open,open,,rittenhouse-square,,,01/06/12 9:13,01/06/12 9:13,,0,0,post,,0,18th and Walnut Streets Philadelphia PA 19103,39.94911187,-75.15073299,,,The center is open year round 9 a.m. ,(777) 666-6666,[email protected],http://twitter.com/fairmountpark,http://facebook.com/fairmountpark,,1,,,,,,,,,,,http://www.fairmountpark.org/rittenhousesquare.asp,, | |
1,01/06/12 9:13,01/06/12 9:13,Franklin Square,Attractions&Feature,a1.jpg,Sample Tags&Tags, <h3> Location </h3> 6th and Race Streets in Historic Philadelphia <h3>The Experience</h3> One of Philadelphia´s newest historic attractions is also one of its oldest. Franklin Square one of the five public squares that William Penn laid out in his original plan for the city has undergone a dramatic renovation. The park now boasts several all new family-friendly attractions including a miniature golf course a classic carousel storytelling benches a picnic area and more. <h3>Mini Golf </h3> At Philly Mini Golf an 18-hole miniature golf course decorated with some of Philadelphia´s favorite icons play a round of putt-putt and learn a little history at the same time. <h3>Carousel </h3> Close your eyes and take a nostalgic ride on the Philadelphia Park Liberty Carousel a classic tribute to Philadelphia´s great heritage of carousel-making. It´s sure to be a instant kid favorite. Storytelling Benches Then catch up on your history at one of the storytelling benches located throughout the park where you can hear tales of Franklin Square´s past or learn about the many communities touched by the Square courtesy of the friendly storytellers of Once Upon a Nation. <h3>Fountain</h3> And emanating from the corners of the historic park four new herringbone brick walking paths with nighttime lighting bring even more charm to the Square after dark. The paths lead to the centerpiece of the Square the Franklin Square Fountain a marble masterpiece built in 1838 surrounded by wrought iron fences which is currently still going under cosmetic restoration. <h3>The History </h3> Originally named ,,publish,open,open,,franklin-square,,,01/06/12 9:13,01/06/12 9:13,,0,0,post,,0,6th and Race Streets Philadelphia PA 19103,39.95458942,-75.14953136,,,Open today until 5 p.m. Sunday 10 am to 9 pm,(111) 677-4444,[email protected],http://twitter.com/franklinsquare,http://facebook.com/franklinsquare,,1,,1,,,,,,,,,http://franklinsquare.com,, | |
</textarea> | |
<input type=button id=geo value="Geocode" /> | |
<input type=checkbox id=redo name=redo /> | |
<textarea rows=10 cols=80 name=outp id=outp > | |
</textarea> | |
<table id="tabular"></table> | |
</form> | |
<script> | |
function TR(cells) { var tr = $('<tr />'); tr.html("<td>" + cells.join("</td><td>") + "</td>"); return tr; } | |
function datamart() { | |
} | |
/** | |
* Geocode all addresses in textarea with id=inp and put in textarea with id=outp using YQL and Google geocoding version 1.0 | |
* Opts: | |
* - 'geolat': String name of "latitude" field in database. Default: "geo_latitude" | |
* - 'jQuery' : Object containing jQuery or compatible with $(selector).click and $.getScript | |
* - 'silent' : boolean suppress logging. Default: false | |
* - 'global' : Object with global scope. Default: `window` or `this`. | |
* - 'cbName' : String global name of callback to call. NOT YET IMPLEMENTED. | |
* - 'cb' : function callback call after geocoding. NOT YET IMPLEMENTED. | |
* - 'wait' : seconds to wait between geocodes. Default: 1 | |
* - 'redo' : boolean to determine whether to redo all geocodes. Default value: $('#redo').attr('checked') | |
*/ | |
function yqlGeocoder(opts, $) { | |
var defaultOpts = {"wait":1, "redo": !! $('#redo').attr('checked') }; | |
var _opts = $.extend(defaultOpts, opts); | |
var global = _opts.global || typeof window !== "undefined" ? window : this ; | |
if (null == $) $ = _opts.jQuery || _opts.$ || global.jQuery ; | |
var GEOCODE = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address="; | |
// http://query.yahooapis.com/v1/public/yql?q={your yql here}&format=json&callback={your function here} | |
var YQL = 'http://query.yahooapis.com/v1/public/yql?format=json&q=select+*+from+json+where+url="' | |
// q={your yql here}&callback={your function here} | |
// http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20json%20where%20url%3D%22http%3A%2F%2Fmaps.googleapis.com%2Fmaps%2Fapi%2Fgeocode%2Fjson%3Fsensor%3Dfalse%26address%3D18th%2520and%2520Walnut%2520Streets%2520Philadelphia%2520%2520PA%252019103%22&format=json&callback=cbfunc | |
function yql(address, funcname) { | |
return address && 'http://query.yahooapis.com/v1/public/yql?q=select%20results.geometry%20from%20json%20where%20url%3D%22http%3A%2F%2Fmaps.googleapis.com%2Fmaps%2Fapi%2Fgeocode%2Fjson%3Fsensor%3Dfalse%26address%3D'+escape(escape(address))+'%22&format=json&callback=' + (funcname || 'geodone') | |
} | |
function log() { | |
if (global.console && !_opts.silent) console.log.call(console, arguments); | |
} | |
var slice = Array.prototype.slice | |
global.geodone = function geodone(data) { | |
var v = $('#outp').val() | |
global.lastdata = data | |
if (global.console) console.log(JSON.stringify(data)) | |
if (data && data.query && data.query.count) { | |
var t = data.query.results.json.results.geometry.location_type | |
var loc = data.query.results.json.results.geometry.location; | |
$('#outp').val(v + "\n" + [loc.lat, loc.lng, t] ) | |
$('#tabular').append(TR([loc.lat, loc.lng])); | |
// Emit: "geocoded", {lat:loc.lat, lng:loc.lng, location_type:t, addr:geo_address} | |
} | |
} | |
function doGeo(addr,funcname, cb) { | |
var qry = yql(addr, funcname); // YQL + GEOCODE + addr + (opts || "") + '"'; | |
log(qry); | |
$.getScript(qry, function success() { log("done", [origdata, global.lastdata], qry, slice.call(arguments)); if (cb) cb(); }); | |
} | |
function makeTimeout(here, origdata, row) { | |
return function() { doGeo(here, 'geodone', function() { $('#tabular').append(TR(origdata)); }); } | |
} | |
// Emit: "now processing", {row:row, col:lat, fields:fields, data:origdata} | |
function geocode(ev) { | |
var t = $('#inp').val(), res = [] | |
var lines = t.split("\n"), sep="\t"; | |
var fields = lines[0].split(sep); | |
if (fields.length < 2) fields = lines[0].split(sep=","); | |
/* TODO: fallback to latitude or lat if geo_latitude not found. Priority: -5 LOW. */ | |
var lat=(fields.indexOf(_opts.geolat || "geo_latitude")), lon = lat + 1, addr = lat - 1; | |
$.extend(_opts, {lat:lat, lon:lon, addr:addr}); | |
$('#tabular').append(TR(fields)) | |
for(var r=1; r<lines.length; ++r) { | |
var tabs = lines[r].split(sep) | |
var here = tabs[addr] | |
if (here && (!tabs[lat] || !tabs[lon] || _opts.redo)) { | |
res.push([ tabs[addr], tabs[lat], tabs[lon] ]); | |
setTimeout( makeTimeout(here, tabs, r), r * 1000 * _opts.wait) | |
} else { | |
res.push([r, here, tabs].join(" : ")); | |
} | |
} | |
$('#outp').val(res.join("\n")) | |
// if (global.console) console.log(qres.join("\n") + "\n\n") | |
} | |
// $('#inp').change(geocode); | |
$('#geo').click(geocode); | |
} | |
jQuery(function($) { | |
yqlGeocoder({}, $); | |
}); | |
</script> | |
<h3>TODO</h3> | |
<ul> | |
<li>Less verbose | |
<li>Only geocode if lat-lng not found | |
<li><strike>Random pause between geocodes</strike> | |
<li>Get some data to geocode | |
</u> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment