I'm kinda rookie in this, but I need help with Google Gauge that should take latest entry in database and display it, while updating automatically without the need to reload the site. Right now I have code that displays it, but for it to update to new values I need to reload the page.
Here's what I have so far:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['ProductPurity', <?php
$servername = "localhost";
$username = "u644759843_miki";
$password = "plantaze2020!";
$dbname = "u644759843_plantazeDB";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "SELECT ProductPurity FROM `Precizno ProductPurity` ORDER BY TimesStamp DESC LIMIT 1";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
echo $row["ProductPurity"];
}
} else {
echo "0 results";
}
mysqli_close($conn);
?> ],
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data, options);
setInterval(function() {
data.setValue(0 ,1 , <?php
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
$sql = "SELECT ProductPurity FROM `Precizno ProductPurity` ORDER BY TimesStamp DESC LIMIT 1";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
echo $row["ProductPurity"];
}
} else {
echo "0 results";
}
mysqli_close($conn);
?>
);
chart.draw(data, options);
}, 5000);
setInterval(function() {
data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 5000);
setInterval(function() {
data.setValue(2, 1, 60 + Math.round(20 * Math.random()));
chart.draw(data, options);
}, 26000);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 400px; height: 120px;"></div>
</body>
</html>
php runs on the server, so it is only going to run once per page load.
to update the chart without reloading the page,
you will need to separate the php from the html / javascript.
save the php to a different file, all by itself.
you need to include the rest of the data in the php,
including the column headings.
see following snippet for the php.
for example purposes, we'll name the file --> getdata.php
<?php
$servername = "localhost";
$username = "u644759843_miki";
$password = "plantaze2020!";
$dbname = "u644759843_plantazeDB";
// Create connection
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = mysqli_connect($servername, $username, $password, $dbname);
$conn->set_charset('utf8mb4');
$sql = "SELECT ProductPurity FROM `Precizno ProductPurity` ORDER BY TimesStamp DESC LIMIT 1";
$result = mysqli_query($conn, $sql);
// create data array
$data = [];
$data[] = ["Label", "Value"];
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
$data[] = ["ProductPurity", $row["ProductPurity"]];
}
mysqli_close($conn);
// write data array to page
echo json_encode($data);
?>
next, save the html / javascript to its own file.
for example purposes, we'll name the file --> chart.html
to get the data from php,
we'll use jquery ajax.
see following snippet...
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
google.charts.load('current', {
packages: ['gauge']
}).then(function () {
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
drawChart();
function drawChart() {
$.ajax({
url: 'getdata.php',
dataType: 'json'
}).done(function (jsonData) {
// use response from php for data table
var data = google.visualization.arrayToDataTable(jsonData);
chart.draw(data, options);
// draw again in 5 seconds
window.setTimeout(drawChart, 5000);
});
}
});
</script>
</head>
<body>
<div id="chart_div" style="width: 400px; height: 120px;"></div>
</body>
</html>
EDIT
need to make sure the Value column...
is a number --> 99.9594
not a string --> "99.9594"
you can convert using --> (float)
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
$data[] = ["ProductPurity", (float) $row["ProductPurity"]];
}
and / or use the JSON_NUMERIC_CHECK constant on the encode statement...
echo json_encode($data, JSON_NUMERIC_CHECK);
Some days ago I did an ArcGISCache visor with OpenLayers 2.12 with some tiles in this folder and file format:
_alllayers\L04\R00000009\C00000a07.png
This means that my tiles are inside "_alllayers" folder and then inside other folders that means Zoom Level (L00,L01...L21). Inside them i have some other folders with their name like: "R00000009" and then inside those folders I have the images named like: "C00000a07.png".
When I did the visor for OpenLayers 2.12 or OpenLayers 2.14 I did it well and works right. But when I have tried to do the same with OpenLayers 3, it doesn't work.
OpenLayers 2.12 / OpenLayers 2.14
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
<meta name="apple-mobile-web-app-capable" content="yes">
<title>OpenLayers</title>
<style>
html, body, #map {
margin: 0;
width: 100%;
height: 100%;
}
</style>
<script src="lib/OpenLayers.2.14.js"></script>
<script>
var map,
cacheLayer,
testLayer,
//This layer requires meta data about the ArcGIS service. Typically you should use a
//JSONP call to get this dynamically. For this example, we are just going to hard-code
//an example that we got from here (yes, it's very big):
// http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer?f=json&pretty=true
layerInfo = {
"currentVersion" : 10.01,
"serviceDescription" : "This worldwide street map presents highway-level data for the world and street-level data for the United States, Canada, Japan, Southern Africa, and a number of countries in Europe and elsewhere. This comprehensive street map includes highways, major roads, minor roads, railways, water features, administrative boundaries, cities, parks, and landmarks, overlaid on shaded relief imagery for added context. The street map was developed by ESRI using ESRI basemap data, AND road data, USGS elevation data, and UNEP-WCMC parks and protected areas for the world, and Tele Atlas Dynamap� and Multinet� street data for North America and Europe. Coverage for street-level data in Europe includes Andorra, Austria, Belgium, Czech Republic, Denmark, France, Germany, Great Britain, Greece, Hungary, Ireland, Italy, Luxembourg, Netherlands, Northern Ireland (Belfast only), Norway, Poland, Portugal, San Marino, Slovakia, Spain, Sweden, and Switzerland. Coverage for street-level data elsewhere in the world includes China (Hong Kong only), Colombia, Egypt (Cairo only), Indonesia (Jakarta only), Japan, Mexico (Mexico City only), Russia (Moscow and St. Petersburg only), South Africa, Thailand, and Turkey (Istanbul and Ankara only). For more information on this map, visit us \u003ca href=\"http://goto.arcgisonline.com/maps/World_Street_Map \" target=\"_new\"\u003eonline\u003c/a\u003e.",
"mapName" : "Layers",
"description" : "This worldwide street map presents highway-level data for the world and street-level data for the United States, Canada, Japan, Southern Africa, most countries in Europe, and several other countries. This comprehensive street map includes highways, major roads, minor roads, one-way arrow indicators, railways, water features, administrative boundaries, cities, parks, and landmarks, overlaid on shaded relief imagery for added context. The map also includes building footprints for selected areas in the United States and Europe and parcel boundaries for much of the lower 48 states.\n\nThe street map was developed by ESRI using ESRI basemap data, DeLorme base map layers, AND road data, USGS elevation data, UNEP-WCMC parks and protected areas for the world, Tele Atlas Dynamap� and Multinet� street data for North America and Europe, and First American parcel data for the United States. Coverage for street-level data in Europe includes Andorra, Austria, Belgium, Czech Republic, Denmark, France, Germany, Great Britain, Greece, Hungary, Ireland, Italy, Luxembourg, Netherlands, Norway, Poland, Portugal, San Marino, Slovakia, Spain, Sweden, and Switzerland. Coverage for street-level data elsewhere in the world includes China (Hong Kong only), Colombia, Egypt (Cairo only), Indonesia (Jakarta only), Japan, Mexico, Russia, South Africa, Thailand, and Turkey (Istanbul and Ankara only). For more information on this map, visit us online at http://goto.arcgisonline.com/maps/World_Street_Map\n",
"copyrightText" : "Sources: ESRI, DeLorme, AND, Tele Atlas, First American, ESRI Japan, UNEP-WCMC, USGS, METI, ESRI Hong Kong, ESRI Thailand, Procalculo Prosis",
"layers" : [
{
"id" : 0,
"name" : "World Street Map",
"parentLayerId" : -1,
"defaultVisibility" : true,
"subLayerIds" : null,
"minScale" : 0,
"maxScale" : 0
}
],
"tables" : [
],
"spatialReference" : {
"wkid" : 102100
},
"singleFusedMapCache" : true,
"tileInfo" : {
"rows" : 256,
"cols" : 256,
"dpi" : 96,
"format" : "JPEG",
"compressionQuality" : 90,
"origin" : {
"x" : -20037700,
"y" : 30241100
},
"spatialReference" : {
"wkid" : 102100
},
"lods" : [
{'level' : 0, 'resolution' : 156543.03403606807, 'scale' : 591657528},
{'level' : 1, 'resolution' : 78271.517018034036, 'scale' : 295828764},
{'level' : 2, 'resolution' : 39135.758509017018, 'scale' : 147914382},
{'level' : 3, 'resolution' : 19567.879254508509, 'scale' : 73957191},
{'level' : 4, 'resolution' : 9783.9394949623238, 'scale' : 36978595},
{'level' : 5, 'resolution' : 4891.9698797730935, 'scale' : 18489298},
{'level' : 6, 'resolution' : 2445.9849398865467, 'scale' : 9244649},
{'level' : 7, 'resolution' : 1222.992337651342, 'scale' : 4622324},
{'level' : 8, 'resolution' : 611.49616882567102, 'scale' : 2311162},
{'level' : 9, 'resolution' : 305.74808441283551, 'scale' : 1155581},
{'level' : 10, 'resolution' : 152.87417449834899, 'scale' : 577791},
{'level' : 11, 'resolution' : 76.436954957243259, 'scale' : 288895},
{'level' : 12, 'resolution' : 38.218609770552874, 'scale' : 144448},
{'level' : 13, 'resolution' : 19.109304885276437, 'scale' : 72224},
{'level' : 14, 'resolution' : 9.5546524426382184, 'scale' : 36112},
{'level' : 15, 'resolution' : 4.7773262213191092, 'scale' : 18056},
{'level' : 16, 'resolution' : 2.3886631106595546, 'scale' : 9028},
{'level' : 17, 'resolution' : 1.1943315553297773, 'scale' : 4514},
{'level' : 18, 'resolution' : 0.59716577766488865, 'scale' : 2257},
{'level' : 19, 'resolution' : 0.2984505969011938, 'scale' : 1128},
{'level' : 20, 'resolution' : 0.1492252984505969, 'scale' : 564},
{'level' : 21, 'resolution' : 0.061383456100245537, 'scale' : 282}
]
},
"initialExtent" : {
"xmin" : -20037507.0671618,
"ymin" : -20037507.0671618,
"xmax" : 20037507.0671618,
"ymax" : 20037507.0671619,
"spatialReference" : {
"wkid" : 102100
}
},
"fullExtent" : {
"xmin" : -20037507.0671618,
"ymin" : -20037507.0671618,
"xmax" : 20037507.0671618,
"ymax" : 20037507.0671619,
"spatialReference" : {
"wkid" : 102100
}
},
"units" : "esriMeters",
"supportedImageFormatTypes" : "PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,AI,BMP",
"documentInfo" : {
"Title" : "World Street Map",
"Author" : "ESRI",
"Comments" : "",
"Subject" : "streets, highways, major roads, railways, water features, administrative boundaries, cities, parks, protected areas, landmarks ",
"Category" : "transportation(Transportation Networks) ",
"Keywords" : "World, Global, 2009, Japan, UNEP-WCMC",
"Credits" : ""
},
"capabilities" : "Map"
};
function init() {
var maxExtent = new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34);
var layerMaxExtent = new OpenLayers.Bounds(
layerInfo.fullExtent.xmin,
layerInfo.fullExtent.ymin,
layerInfo.fullExtent.xmax,
layerInfo.fullExtent.ymax
);
var resolutions = [];
for (var i=0; i<layerInfo.tileInfo.lods.length; i++) {
resolutions.push(layerInfo.tileInfo.lods[i].resolution);
}
map = new OpenLayers.Map('map', {
maxExtent: maxExtent,
StartBounds: layerMaxExtent,
units: (layerInfo.units == "esriFeet") ? 'ft' : 'm',
resolutions: resolutions,
tileSize: new OpenLayers.Size(layerInfo.tileInfo.width, layerInfo.tileInfo.height),
projection: 'EPSG:' + layerInfo.spatialReference.wkid
});
cacheLayer = new OpenLayers.Layer.ArcGISCache( "AGSCache",
"http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers", {
isBaseLayer: false,
useArcGISServer: false,
resolutions: resolutions,
tileSize: new OpenLayers.Size(layerInfo.tileInfo.cols, layerInfo.tileInfo.rows),
tileOrigin: new OpenLayers.LonLat(layerInfo.tileInfo.origin.x , layerInfo.tileInfo.origin.y),
maxExtent: layerMaxExtent,
projection: 'EPSG:' + layerInfo.spatialReference.wkid
});
testLayer = new OpenLayers.Layer.Google(
"Google Streets",
{'sphericalMercator': true, numZoomLevels: 21}
);
map.addLayers([cacheLayer, testLayer]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl( new OpenLayers.Control.MousePosition() );
map.zoomToExtent(new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34));
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
As I said, this works fine. But when I try to do the same at OpenLayers 3, I can't. I don't know why is asking for the images like there is a service.
OpenLayers 3
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
<meta name="apple-mobile-web-app-capable" content="yes">
<title>OpenLayers</title>
<style>
html, body, #map {
margin: 0;
width: 100%;
height: 100%;
}
</style>
<script src="lib/OpenLayers.3.js"></script>
<script>
function init(){
var url = 'http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers';
var layers = [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Tile({
extent: [-20037507.0671618,-20037507.0671618,20037507.0671618,20037507.0671619],
source: new ol.source.TileArcGISRest({
url: url
})
})
];
var map = new ol.Map({
layers: layers,
target: 'map',
view: new ol.View({
center: [-20037700, 30241100],
zoom: 1
})
});
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
When I try to load this OpenLayers 3 visor, I can see in the console some 404 error and this is the type of URL that it tries to find:
http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/?F=image&FORMAT=PNG32&TRANSPARENT=true&SIZE=256%2C256&BBOX=-20037508.342789244%2C0%2C0%2C20037508.342789244&BBOXSR=3857&IMAGESR=3857&DPI=90
Pretty Print
http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/?F=image
&FORMAT=PNG32
&TRANSPARENT=true
&SIZE=256%2C256
&BBOX=-20037508.342789244%2C0%2C0%2C20037508.342789244
&BBOXSR=3857
&IMAGESR=3857
&DPI=90
So, my questions are:
- Why OpenLayers 3 is asking for the images (tiles) like it was a Service behind?
- Hoy can I use my tiles in OpenLayers 3?
I have tried to change the URL with this patterns:
http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/ImageServer
http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/ImageServer/export
http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/Tiles/{z}/{x}/{y}
Edit:
Finally I have solved! I hava made in Java a program that converts all those folders and pictures names.
I was trying to understand the pattern that the names of folders and images has, and finally I realized that the first letter of the folders meant the rows ( R -> row) and the first letter of the images meant columns ( C -> column).
Once you have removed the first letter , just needed to convert that number Hexadecimal to Decimal and save the file or folder with that new name.
If someones need some help with this, I will happy to help.
ol.source.ArcGISRest is for ArcGIS server tile services. For ArcGISCache, you will want to use an ol.source.TileImage or ol.source.XYZ with a custom tileUrlFunction or tileLoadFunction. I prefer the latter, because then I do not have to convert tile coordinates. Something like
function replacer(match, letter, value) {
var str = Number(value).toString(letter == 'L' ? 10 : 16);
var len = letter == 'L' ? 2 : 8;
while (str.length < len) {
str = '0' + str;
}
return letter + str;
}
var source = new ol.source.XYZ({
url: 'http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/L{z}/R{x}/C{y}.png',
tileLoadFunction: function(image, url) {
image.getImage().src = url
.replace(/(L)([0-9]+)/, replacer)
.replace(/(R)([0-9]+)/, replacer)
.replace(/(C)([0-9]+)/, replacer);
}
});
#ahocevar solutions works. But I had to swap the x and y in the URL.
url: 'http://MY_IP:MY_PORT/MY_FOLDER/Layers/_alllayers/L{z}/R{y}/C{x}.png'
This makes sense, because y would map to rows and x to colums.
I am trying to send an $http.post AJAX data to a route configured in Laravel 5.2, everything works perfect, but the server returns this error:
Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated
and will be removed in a future version. To avoid this warning set
'always_populate_raw_post_data' to '-1' in php.ini and use the
php://input stream instead. in Unknown on line 0
Warning: Cannot modify header information - headers already sent in
Unknown on line 0
This is my code. PHP:
public function save(Request $request){
$input = $request->all();
try {
$direccion = urlencode($input['Calle']." ".$input['Numero'].", ".$input['Ciudad']);
$geocode = "https://maps.googleapis.com/maps/api/geocode/json?address=$direccion&key=APIKEY";
$datosGoogle = json_decode($this->curl($geocode), true);
$latitud = $datosGoogle['results'][0]['geometry']['location']['lat'];
$longitud = $datosGoogle['results'][0]['geometry']['location']['lng'];
if(is_double($latitud) && is_double($latitud)){
$input['Latitud'] = $latitud;
$input['Longitud'] = $longitud;
$new = MyModel::create($input);
$data = ["status"=>"ok", "message"=>"Agregado correctamente"];
}else{
$data = ["status"=>"fail", "message"=>"Dirección desconocida, compruebe que los datos son correctos para que podamos agregarla al sistema."];
}
} catch (Exception $e) {
$data = ["status"=>"error", "message"=>$e->getMessage()];
}
return response()->JSON($data);
}
JS:
$scope.registrar = function(form, datos) {
$scope.submitted = true;
if(form.$valid) {
var toSendData = JSON.stringify({
Nombre: datos.nombre,
Calle: datos.calle,
Numero: datos.numero,
Piso: datos.piso,
Puerta: datos.puerta,
CP: datos.cp,
Ciudad: datos.ciudad,
Email: datos.email,
Necesidades: datos.necesidades,
Telefono: datos.telefono
});
console.log(toSendData);
$http.post($rootScope.recibirNuevoUrl, toSendData).then(function(response){
$scope.hideLoading();
if(response.data.status == "ok"){
$state.go('registro');
}else{
$scope.$parent.showAlert("Error al introducir los datos", response.data.message);
}
})
}else{
$scope.$parent.showAlert('Validacion de datos', 'El formulario contiene errores. Por favor revise los campos marcados para comprobar los errores.');
}
};
How can I fix it?
I had the same problem with Laravel 5.2 and Angular, I got it working by adding a single line in my controller:
editorApp.controller('EditorCtrl', function ($scope, $sce, $http, $location, $interval, $document){
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
...
I found this working for me in this post: https://stackoverflow.com/a/19254137/4021927. The answer marked as correct did not work for me, the line above is from an other answer in the same post. The correct answer (https://stackoverflow.com/a/20276775/4021927) does tell you why you need it though.
In short why this problem exist is because Angular (By default) send data using JSON serialization: Content-Type: application/json and PHP does not unserialize JSON natively. By changing content-type to x-www-form-urlencoded the data will be sent as:
foo=bar&bar=foo
instead of (JSON):
{ "foo": "bar", "bar": "foo" }
I got similar problem retrieving $GLOBALS['HTTP_RAW_POST_DATA'] in Laravel 5.2. I solved the issue by using Request::getContent() in my controller
Got mine working after turning off error_reporting in php.ini
Open php.ini
Search for error_reporting
Change it to => error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
Exit and Start / Restart apache server
Restart laravel server
laravel 5.2
/resource/assets/js/bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = window.Laravel.csrfToken;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
//add default Content-Type
window.axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
2 data mast be string
const qs = require('qs')
axios.post('/api/code/create', qs.stringify(this.formItem),)
.then(function (response) {
console.log(response)
})
.catch(function (error) {
console.log(error)
})