Google API Response JSON - php

I'm trying to use the Google Geocoder API to get me a Latitude and Longitude to use in the Google Places API. First things first, how do I code the url of the API so it returns the JSON string? I thought it would be something like a jquery load, but that doesn't work. So I have this nice url that returns the information I need but just dumps a bunch of json data. How do I capture the data?
http://maps.googleapis.com/maps/api/geocode/address=12308&sensor=false
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/geocode/address=12308&sensor=false";
document.body.appendChild(script);
resultjson = script
console.log(resultjson);
}

You can use the geocoder without the JSONP support but you have to use their Maps library instead:
Add this script tag to your HTML:
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
Then, add the following JS:
var geocoder = new google.maps.Geocoder();
geocoder.geocode(
{address: "37203" },
function(dataObject, statusObject) {
console.log(dataObject);
}
);

Related

Google Maps geocoding : "google is not defined"

I'm getting an issue when I try to load this code, and I can't figure why it doesn't work...
<script type="text/javascript">
$(document).ready(function()
{
var geocoder = new google.maps.Geocoder();
$(".textarea-autosize").autosize();
geocoder.geocode({
address: '{$order->address_delivery["address1"]},{$order->address_delivery["postecode"]},{$order->address_delivery["city"]}'
}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK)
{
var delivery_map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: results[0].geometry.location
});
var delivery_marker = new google.maps.Marker({
map: delivery_map,
position: results[0].geometry.location,
url: 'http://maps.google.com?q={$order->address_delivery["address1"]},{$order->address_delivery["postcode"]},{$order->address_delivery["city"]}'
});
google.maps.event.addListener(delivery_marker, 'click', function() {
window.open(delivery_marker.url);
});
}
});
});
// Fix wrong maps center when map is hidden
$('#tabAddresses').click(function(){
x = delivery_map.getZoom();
c = delivery_map.getCenter();
google.maps.event.trigger(delivery_map, 'resize');
delivery_map.setZoom(x);
delivery_map.setCenter(c);
});
</script>
The error occurrs on the var geocoder = new google.maps.Geocoder();
Then I tried to load the following script : <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
and I get another error :
'Uncaught TypeError: Cannot read property 'offsetWidth' of null'
Does anyone has any idea of why it doesn't work ?
Google maps aren't loaded at the time when you're trying to call it. You should be using this:
HTML:
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&callback=initMap" async defer></script>
JS:
function initMap() {
// Google maps are now initialized.
}
You need to include the async and defer attributes into your script - this will make sure that the rest of the website keep loading instead of waiting for the script to load (which is handy, because it's quite big).
Secondly, you pass the "callback" parameter when calling the script. This is the name of the function that should be executed when the script is loaded. This way you can make sure you only initialize the map when it's actually loaded and present within your window.
Simply add this script to your html file:
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
If you want to test the google geocoding api or check out some code, check out this link. Google Geocoding Service API Source

Load google maps to div loaded by ajax

I'm using jquery ajax to get some results from a php script that is parsing an xml document. After that ajax call i whant to show a map from google api, in a div created by that php script (that's my problem).
Is it possible to load the maps API to the <div id="map-canvas"> that is created in php, after the ajax call??
PHP FILE
... $xmlData = simplexml_load_file("using an http service");
echo "<div id='map-canvas'></div>"; //LOAD MAPP HERE!
echo "<ul>";
foreach($xmlData->StopTimes->StopTime as $stopTime){
echo "<li>",$stopTime->attributes()->Hour,"</li>";
}
echo "</ul>";
}
AJAX FILE
...
//station click, show next stops
$('.station_link').click(function(){
var station_text = $(this).text();
$.ajax({ //make the ajax call
type: "POST", //use POST/GET
url: "../server_side/nextStop.php", //file to send data
data: {poststation : station_text}, //postlink -> php($_POST) value / text -> jquery var value
success: function(data){ //on success, do something
$('#next_stop').html(data);
$('#next_stop').show();
//Google maps API
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&sensor=TRUE_OR_FALSE&callback=initialize";
document.body.appendChild(script);
}
loadScript();
}
});
});
});
This is what i've tried (and much more :p), but i dont even know if its just wrong.
Any help or advise would be appreciated!
-- UPDATE --
As simple as this:
javascript file
//station click, show next stops
$('.station_link').click(function(){
var station_text = $(this).text();
$.ajax({ //make the ajax call
type: "POST", //use POST/GET
url: "../server_side/nextStop.php", //file to send data
data: {poststation : station_text}, //postlink -> php($_POST) value / text -> jquery var value
success: function(data){ //on success, do something
$('#next_stop').html(data);
$('#next_stop').show();
// Google maps API
var mapOptions = {
center: new google.maps.LatLng(37.7831,-122.4039),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
});
});
});
And just adding this <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script> to the HTML file.
That's what i whanted, it´s loading the <div id="map-canvas"> as it should.
Ty for help anyway!
Sorry if i didn't proove my point earlier, i'm a bit newbie ;)
Google Maps must be loaded at the time you call center: new google.maps.LatLng(-34.397, 150.644),, so from my opinion you should create a dummy map and initialize it on page load
<div id="dummy"></div>
<script type="text/javascript">
function initGoogle(){
myLatLng = new google.maps.LatLng(0,0);
var mapOptions = {
zoom: 1,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.HYBRID
};
map = new google.maps.Map(document.getElementById('dummy'), mapOptions);
}
$(document).ready(function(){
var script = document.createElement('script');
script.type = 'text/javascript';
script.id = 'googleMaps';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initGoogle';
document.body.appendChild(script);
});
</script>
<style type="text/css">
#dummy { position: absolute; top: -5000px; left: -5000px; }
</style>
then you can bind whatever you want.
Note: I used jQuery's $(document).ready(), but if you don't use jQuery you can figure it out.
I suspect your initialize isn't getting called due to scope issues as it's only defined in the scope of the Ajax callback and not the global scope, which the Maps SDK will expect.
If you have to load the Google Maps JS asynchronously, use jQuery.getScript() and then initialise your map in getScript's callback.
It could be better though as you're effectively chaining two requests, which is not particularly performant.
You could:
Create a global variable set to 0
Fire off your Ajax call for the Maps div
Use getScript to load the Maps SDK asynchronously and concurrently
In the callback function of your Ajax and getScript calls, increment a global variable you just set
Have a loop that runs every 50ms or so (recursively calling setTimeout, for example), checking the value of the variable you set, waiting until it is equal to 2, set the timeout for another 50ms or so to check again
Once the condition above is satisfied, initialize your map as you know that both the div and maps API have loaded
You can call a js function after AJAX call. You probably better define the function of initialization of gmaps somewhere outside of AJAX call and then after a successful call to your php script call you gmap function (in case of high need with setTimeout('gmap()', 2000); function). But as I see your script it first creates div and then calls function of gmap

How do I load Google Charts in node.js?

When I attempt to load a Google Chart in node.js, nothing happens.
I tried loading the first example from the line chart docs in both zombie.js and jsdom, but the chart never loads in either case.
The end goal is to retrieve the SVG data of the generated chart for export into an image or PDF. So if an alternate method (server side using node.js or PHP) to achieve this is possible, I'm open to suggestions.
NOTE: I have successfully generated a images of a few charts using gChartPhp, but the requirements of this project state that the embedded version be the interactive version provided by the current API and the exported version be visually IDENTICAL to the embedded one (without being interactive, obviously).
Edit: I tagged PhantomJS, since that is the solution with which I ultimately went.
Sorry for the lack of links, but the spam prevention mechanism will only allow me to post 2.
I'm 8 years late but I've just released an open-source project Google Charts Node that renders chart images in Puppeteer (somewhat of a successor to the original PhantomJS solution).
google-charts-node is available as an NPM library and can be used like so:
const GoogleChartsNode = require('google-charts-node');
function drawChart() {
// Set up your chart here, just like in the browser
// ...
const chart = new google.visualization.BarChart(container);
chart.draw(data, options);
}
// Render the chart to image
const image = await GoogleChartsNode.render(drawChart, {
width: 400,
height: 300,
});
Now you can save this image buffer as a file or return it as an HTTP response, etc.
It was pretty straightforward to create this. The main caveats were:
Not all charts support getImageURI, so I fall back to puppeteer to take a screenshot when this happens.
It's slow! But if you must use Google Charts as a requirement, you don't really have an alternative. This problem can be mitigated with enough cloud compute resources.
You can view the full source at the Github project, but here's the raw puppeteer flow if you want to do it yourself:
async function render() {
// Puppeteer setup
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Add the chart
await page.setContent(`...Insert your Google Charts code here...`);
// Use getImageURI if available (not all charts support)
const imageBase64 = await page.evaluate(() => {
if (!window.chart || typeof window.chart.getImageURI === 'undefined') {
return null;
}
return window.chart.getImageURI();
});
let buf;
if (imageBase64) {
buf = Buffer.from(imageBase64.slice('data:image/png;base64,'.length), 'base64');
} else {
// getImageURI was not available - take a screenshot using puppeteer
const elt = await page.$('#chart_div');
buf = await elt.screenshot();
}
await browser.close();
return buf;
}
It wasn't the ideal solution, but I found an alternative to node.js for accomplishing the same end goal in PhantomJS. Simply create an HTML file containing the chart (test.html) and like node.js, create a JS file containing your code (test.js). Then run your JS file with PhantomJS.
In your JS file, open your HTML file as a webpage, then render it, either saving the image buffer to a file:
var page = require('webpage').create();
page.open('test.html', function () {
page.render('test.png');
phantom.exit();
});
Then run it:
phantomjs test.js
To dynamically create a chart, create the following JS file (test2.js):
var system = require('system');
var page = require('webpage').create();
page.onCallback = function(data)
{
page.clipRect = data.clipRect;
page.render('test.png');
phantom.exit();
};
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js', function()
{
page.includeJs('https://www.google.com/jsapi', function()
{
page.evaluate(function(chartType, data_json, options_json)
{
var div = $('<div />').attr('id', 'chart').width(900).height(500).appendTo($('body'));
google.load("visualization", "1",
{
packages:[chartType == 'GeoChart' ? 'geochart' : 'corechart'],
callback: function()
{
data_arr = $.parseJSON(data_json);
data = google.visualization.arrayToDataTable(data_arr);
options = $.parseJSON(options_json);
chart = new google.visualization[chartType]($(div).get(0));
google.visualization.events.addListener(chart, 'ready', function()
{
window.callPhantom(
{
clipRect: $(div).get(0).getBoundingClientRect()
});
});
chart.draw(data, options);
}
});
}, system.args[1], system.args[2], system.args[3]);
});
});
Then run it:
phantomjs test2.js LineChart '[["Date","Steve","David","Other"],["Dec 31",8,5,3],["Jan 1",7,10,4],["Jan 2",9,4,3],["Jan 3",7,5,3]]' '{"hAxis.slantedText":true}'
phantomjs test2.js PieChart '[["Employee","Calls"],["Steve",31],["David",24],["Other",13]]' '{"is3D":true}'
phantomjs test2.js GeoChart '[["State","Calls"],["US-CA",7],["US-TX",5],["US-FL",4],["US-NY",8]]' '{"region":"US","resolution":"provinces"}'
To get the image data from an external script, make a copy of test2.js (test3.js) and change
page.render('test.png');
to
console.log(page.renderBase64('png'));
Then call it (from PHP, for example):
<?php
$data = array(
array("Employee", "Calls"),
array("Steve", 31),
array("David", 24),
array("Other", 13)
);
$options = array(
"is3D" => true
);
$command = "phantomjs test3.js PieChart '" . json_encode($data) . "' '" . json_encode($options) . "'";
unset($output);
$result = exec($command, $output);
$base64_image = implode("\n", $output);
$image = base64_decode($base64_image);
?>
NOTE: Looking back on this whole process, the problem I was having with node.js was possibly that I didn't setup callbacks or timeouts to wait until the charts were "ready".

Problem with loading google map v3 asynchronously

My current solution for loading Google map scripts, is the old fashion way.
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
But this takes to long and rendering content is delayed. Then I looked at the Google Map Documentation and discovered how one can load the Goole Map javascripts asynchronously.
So I tested this in the javascript I'm already using. This is just snippets of my script.
jQuery(document).ready(function() {
googleMaploadScript();
someFunction();
}
// Script for loading googlemap with callback to initialize Google map
function googleMaploadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.google.com/maps/api/js?sensor=true&callback=initGoogleMap";
document.body.appendChild(script);
}
// Some function that calls populateGeoMap()
function someFunction() {
(...)
populateGeoMap();
}
// Script for populating google map with locations
function populateGeoMap() {
// This is where I initialized google map each time I load the page using google map
// But since I'm using a callback, I've commented this out.
//initGoogleMap();
var lat = '12.142123';
var lng = '54.524522';
latLng = new google.maps.LatLng(lat,lng); <-- THIS FAILS
}
// Google map init
function initGoogleMap() {
alert('test'); <-- THIS ALERT IS NEVER TRIGGERED
options = {zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }
map = new google.maps.Map(document.getElementById("map_canvas"), options);
geocoder = new google.maps.Geocoder();
icon = new google.maps.MarkerImage("http://mysite.com/img/pin_red.png", null, null, null, new google.maps.Size(32, 32));
bounds = new google.maps.LatLngBounds();
}
My script fails at new google.maps.LatLng(lat,lng); and this is because initGoogleMap() has not been run.
It seems that the callback in the script.src did not work - because my alert is never fired. Or it might be because things are not laoded in the correct order, but still, the alert should have been triggered.
Does anyone have experience with this?
I had the same problem and worked it out like this:
the problem is the fact that you can't get to the jQuery object itself from outside jQuery.
the API callback attribute at the end has only access to the global javascript. read up opn javascript namespace to understand better.
my solution is to set up a global object outside of the $document.ready(function(){...
var global = {};
next, you write the init function inside your jQuery block for the map as a variable and attach it to the global object:
global.initMap = function(){ ...}
now you can reference your jquery function as a global variable in the url query string like this:
...&callback=global.initMap
this worked for me.
tim's suggestion is excellent!
This is working asynchronous (lazy loading) of google maps v3 script with jQuery based Google Maps plugins.
This way no script except head.js+jquery.js are blocking the page and google maps starts loading as soon as is possible.
window.load should be accessed quickly. tested on ffox 12, ie7,8,9 and chrome 18.
due to some issues with ie7,8 it was not possible to load jquery.js asynchronously :/
//////////////////// lazy loaded google map
// load head.js normally before this code.
// due to IE7,8 or head.js bug you HAVE TO load normally jQuery too:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="/PATH/head.js"></script>
// load rest of your javascript using head.js function
head.js("yourscripts.js");
// IMPORTANT: google map plugin must be tagged like this:
head.js({gmap:"YOUR_PATHs/jquery.mapka.v3-rc.js"});
var global = {};
global.googlemaps_init = function(){
head.ready("gmap", function() {
// jquery-ui-map v3 init of google maps (place YOUR jQuery based google maps plugin init here)
$('#map_canvas').gmap({ 'center': '42.345573,-71.098326' });
}); // head.gmap.ready END
} // global.googlemaps_init END
function loadGmapScript() {
var global = {};
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?&sensor=false&callback=global.googlemaps_init";
document.body.appendChild(script);
}
window.onload = loadGmapScript;
//////////////////// lazy loaded google map END
This is because you're trying to initialize an object that you don't have access to. Try moving the GA functions into the document.onready block:
$(function(){
// Script for loading googlemap with callback to initialize Google map
function googleMaploadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.google.com/maps/api/js?sensor=true&callback=initGoogleMap";
document.body.appendChild(script);
}
// Some function that calls populateGeoMap()
function someFunction() {
(...)
populateGeoMap();
}
// Script for populating google map with locations
function populateGeoMap() {
// This is where I initialized google map each time I load the page using google map
// But since I'm using a callback, I've commented this out.
//initGoogleMap();
var lat = '12.142123';
var lng = '54.524522';
latLng = new google.maps.LatLng(lat,lng); <-- THIS FAILS
}
// Google map init
function initGoogleMap() {
alert('test'); <-- THIS ALERT IS NEVER TRIGGERED
options = {zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }
map = new google.maps.Map(document.getElementById("map_canvas"), options);
geocoder = new google.maps.Geocoder();
icon = new google.maps.MarkerImage("http://mysite.com/img/pin_red.png", null, null, null, new google.maps.Size(32, 32));
bounds = new google.maps.LatLngBounds();
}
googleMaploadScript();
someFunction();
});
I think what happens is that you actually trigger "somefunction" before the map is loaded so JS fails and never actually executes the "initGoogleMap".
Place your somefunction at the end of the initGoogleMap like that:
google.maps.event.addListener(map, 'loaded', function(){
somefunction();
});
K
you can use the async mode when loading Google Maps api, you need to provide a callback function:
http://maps.googleapis.com/maps/api/js?sensor=true&callback=my_callback_function
Here http://lucamanzo-soluzione-software.it/wp/?p=5 you can find a simple jquery plugin showing all the steps to use the async loading and jquery, and building a map with just a few lines of code. Usage example:
$.gmapstools.init();
$("#my_map_canvas").gmap({lat:37.4221913, lng:-122.08458530000001, draw_marker:true, zoom_level:13});

Google Maps Problem with Zend Framework

Hi I am having issues inserting a map from google maps and using the send framework.
My issue is similar to Question 921811
However when adding the script to my view I am getting the googlemaps api in twice and no map being rendered by the view.
This is what I am adding to the view script
<?php
$this->headScript()->appendFile('http://maps.google.com/maps?file=api&;v=2&;sensor=true&;key=ABQIAAAAHSJ3TgOTyvA1VzwU8g4Y7RT2yXp_ZAY8_ufC3CFXhHIE1NvwkxRmCy1h3nGv3n46kcqaFljsimqfWw');
$this->headScript()->appendScript(' var map = null;
var geocoder = null;
function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
geocoder = new GClientGeocoder();
}
}
function showAddress(address) {
if (geocoder) {
geocoder.getLatLng(
address,
function(point) {
if (!point) {
alert(address + " not found");
} else {
map.setCenter(point, 13);
var marker = new GMarker(point);
map.addOverlay(marker);
marker.openInfoWindowHtml(address);
}
}
);
}
}
');
?>
However this is adding the maps API in twice with a lot of escaped html, which is causing the maps to fail to load. e.g.
<script type="text/javascript" src="<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true&amp;key=ABQIAAAAHSJ3TgOTyvA1VzwU8g4Y7RT2yXp_ZAY8_ufC3CFXhHIE1NvwkxRmCy1h3nGv3n46kcqaFljsimqfWw" type="text/javascript"></script>"></script>
<script type="text/javascript" src="http://maps.google.com/maps?file=api&;v=2&;sensor=true&;key=ABQIAAAAHSJ3TgOTyvA1VzwU8g4Y7RT2yXp_ZAY8_ufC3CFXhHIE1NvwkxRmCy1h3nGv3n46kcqaFljsimqfWw"></script>
<script type="text/javascript">
//<!--
var map = null;
var geocoder = null;
function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
geocoder = new GClientGeocoder();
}
}
.....
Any idea why the google maps API is being added twice with the escaped html tags? I have no idea and the examples I have found don't seem to have this issue.
Thanks in advance
The reason you're not seeing any map is because the URL in your appendFile() call is broken. Remove all the semi-colons:
http://maps.google.com/maps?file=api&v=2&sensor=true&key=whatever
That will fix the second <script> tag and make the Google map actually work.
That still leaves you with the first <script> tag, though. But that must be related to how you're actually printing the contents of the HeadScript view helper. Can you show us what that code looks like?

Categories