I'm working with PHP and JSON. I have this example of a JSON foreach loop, with this example I want to get lat/lon to add a marker in Google Maps:
"data": [
{
"end_time": "2016-02-09T22:30:00-0200",
"name": "6\u00ba Rebanh\u00e3o de Carnaval - Comunidade Cen\u00e1culo",
"place": {
"name": "Comunidade Cen\u00e1culo",
"location": {
"city": "Franca",
"country": "Brazil",
"latitude": "",
"longitude": "",
"state": "SP",
"street": "Dom Pedro I, 1040, Jardim Petr\u00e1glia"
},
"id": "410657548946610"
},
"start_time": "2016-02-05T19:30:00-0200",
"id": "940527599373114"
}
]
My problem is, some of results of latitude and longitude are empty. I want to put a specific value on it, but on each empty I want to add lat + 0.02.
For example, in first empty value I want to put this lat 40.700106, and the next empty value I want to put this 40.700106 + 0.02.
I just don't want 2 markers in same location.
How can I do this?
EDIT:
foreach($json3 ->data as $mydata1)
{
$latitude = $mydata1->place->location->latitude;
if(empty($latitude ))
{
$latitude = $latitude + 0.02;
echo ' lat :'.$latitude ;
}
}
this way i replace the empty value, but they dont add the + 0.02 on each value
You can save the previous latitude and use it.
Something like this:
$previousLatitude = null;
foreach($json3 ->data as $mydata1) {
$latitude = $mydata1->place->location->latitude;
if(empty($latitude ))
{
$latitude = $previousLatitude + 0.02;
echo ' lat :'.$latitude ;
}
$previousLatitude = $latitude
}
Related
I have a randquotes.json file
{
"author": "William Shakespeare",
"quotes": "A brave flea is a flea that can dare to get its breakfast on the lips of a lion."
},
{
"author": "Winston Churchill",
"quotes": "We live with what we get, but we bring life to what we give."
},
{
"author": "Wolfgang von Gothe",
"quotes": "Knowledge is not enough, we must practice it. Intention is not enough, we must do it."
}
Then I want "author" and "quotes" to be generated randomly with php
How?
thanks for help
Assuming you actually have valid a JSON string...
Convert the json to a PHP datatype using json_decode()
find out how large the array is
generate a random number between 0 and array size
Return that array occurance, I did that as a json string again using json_encode()
$json_string = '
[
{
"author": "William Shakespeare",
"quotes": "A brave flea is a flea that can dare to get its breakfast on the lips of a lion."
},
{
"author": "Winston Churchill",
"quotes": "We live with what we get, but we bring life to what we give."
},
{
"author": "Wolfgang von Gothe",
"quotes": "Knowledge is not enough, we must practice it. Intention is not enough, we must do it."
}
]';
$arr = json_decode($json_string);
// How big is the array
$max = count($arr) -1;
$rand_idx = rand(0, $max);
echo json_encode($arr[$rand_idx]);
I have list of users in a JSON file
[
{
"id": 1,
"first_name": "Maurise",
"last_name": "Shieldon",
"latitude": 34.003135,
"longitude": -117.7228641
},
{
"id": 2,
"first_name": "Bendix",
"last_name": "Halgarth",
"latitude": -2.9623869,
"longitude": 104.7399789
},
{
"id": 3,
"first_name": "Meghan",
"last_name": "Southall",
"latitude": "15.45033",
"longitude": "44.12768"
},
{
"id": 4,
"first_name": "Sidnee",
"last_name": "Silwood",
"latitude": -26.94087,
"longitude": 29.24905
},
{
"id": 5,
"first_name": "Rosita",
"last_name": "Ferrulli",
"latitude": 33.5719791,
"longitude": -84.3396421
}]
I am using Haversine formula to calculate distance so that i can only get users of certain LAT and LONG values this method is in my api.service.ts class.
getDistanceFromLatLon(lat1: number, lon1: number, lat2: number, lon2: number): number {
var deg2Rad = deg => {
return deg * Math.PI / 180;
}
var r = 3959; // Radius of the earth in miles
var dLat = deg2Rad(lat2 - lat1);
var dLon = deg2Rad(lon2 - lon1);
var a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(deg2Rad(lat1)) * Math.cos(deg2Rad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = r * c; // Distance in miles
return d;
}
Then in my app.component.ts file i can call JSON Array which gives me list of all users in data.json file from my list of users above.
getUsers() {
this.httpClient.get('/assets/users.json').pipe(map(data => data as Array<Users>))
.subscribe(result => { console.log(result)}
After i receive list of all users from my JSON file. I am trying to run the JSON result Array through the getDistanceFromLatLon method so that only users with LONDON_LAT and LONDON_LONG can displayed
//Latitude and longitude of London
LONDON_LAT = 51.509865;
LONDON_LONG = -0.118092;
miles;
const distance = this.apiService.getDistanceFromLatLon(result['latitude'], result['longitude'],
this.LONDON_LAT, this.LONDON_LONG);
if (distance <= this.miles) {
this.UsersByRadius = result;
}
});
}
After compiling through the .getDistanceFromLatLon my this.UsersByRadius = result is empty and i am not getting any users.
I am basically trying to replicate this PHP application in my angular app. Any help will be much appreciated.
Angular SPA are usually generated client-side. So all the mathematical calculations (a single division operation has a heavy overhead, not to mention all the trig functions) will be heavy overload when dealing with large array sets. You should consider doing it server-side.
You are retreiving an array. So you need to loop through each of them to call the function.
getUsers() {
this.httpClient.get('/assets/users.json').pipe(
map(data => data as Array<Users>)
).subscribe(result => {
console.log(result);
result.forEach(item => {
const distance = this.apiService.getDistanceFromLatLon(item['latitude'], item['longitude'], this.LONDON_LAT, this.LONDON_LONG);
if (distance <= this.miles) {
this.UsersByRadius.push({
id: item['id'],
first_name: item['first_name'],
last_name: item['last_name'],
latitude: item['latitude'],
longitude: item['longitute'],
city: 'London'
});
}
});
});
}
Here is my function - I get an error.
In variable $data['stars'] I got maximum numbers of stars with is invalid
I want correct stars from database because actually stars table are different so that's why.
Is it possible to get stars from another table in this foreach to get accurate value?
public function dbmovies()
{
$this->db->order_by("videos_id", "desc");
$this->db->where(array('publication' => 1, 'is_tvseries' => 0));
$query = $this->db->get('videos');
//get stars
foreach ($query->result() as $key => $value) {
$this->db->where_in('star_id', $value->stars);
$queryStars = $this->db->get('star');
$stars=array();
foreach ($queryStars->result() as $star) {
$stars[] = $star->star_name;
$starone = implode(", ", $stars);
}
$data['videoId'] = $value->videos_id;
$data['imdbid'] = $value->imdbid;
$data['title'] = $value->title;
$data['description'] = $value->description;
$data['duration'] = $value->runtime;
$data['views'] = $value->total_view;
$data['stars'] = $starone;
$alldata[] = $data;
}
$get['data'] = $alldata;
echo json_encode($get, JSON_PRETTY_PRINT);
}
And tge output I get like this
{
"data": [
{
"videoId": "47",
"imdbid": "tt2935510",
"title": "Ad Astra",
"description": "<p>The near future, a time when both hope and hardships drive humanity to look to the stars and beyond. While a mysterious phenomenon menaces to destroy life on planet Earth, astronaut Roy McBride undertakes a mission across the immensity of space and its many perils to uncover the truth about a lost expedition that decades before boldly faced emptiness and silence in search of the unknown.<\/p>",
"duration": "123 Min",
"views": "2",
"stars": "Brad Pitt"
},
{
"videoId": "45",
"imdbid": "tt8243160",
"title": "Hacker",
"description": "<p>13-year-old Benjamin discovers that his mother didn\u2019t die in an accident as he was led to believe. The trail leads to high-ranking officials in the Danish Secret Service. \"Trust no one!\", he is told.<\/p>",
"duration": "96 Min",
"views": "93",
"stars": "Brad Pitt, Rumle Krs"
},
{
"videoId": "44",
"imdbid": "tt7131622",
"title": "Once Upon a Time... in Hollywood",
"description": "<p>A faded television actor and his stunt double strive to achieve fame and success in the film industry during the final years of Hollywood's Golden Age in 1969 Los Angeles.<\/p>",
"duration": "161 Min",
"views": "71",
"stars": "Brad Pitt, Rumle Krs, Leonardo DiCaprio"
},
Can anyone please help me?
You have to move the $starone variable to the outside of the foreach loop so that it doesn't get overwritten inside the loop :
foreach ($queryStars->result() as $star) {
$stars[] = $star->star_name;
}
$starone = implode(", ", $stars);
Add empty array before foreach $stars=array();
$stars=array();
foreach ($queryStars->result() as $star) {
$stars[] = $star->star_name;
$starone = implode(", ", $stars);
}
i have done aggregation with name but geo-distance sorting not working properly.
i have achieved to aggregation and distance calculation. but i don't know how to soring bucket distance value.
kindly suggest me how to achieved?
Mapping:-
PUT /museums
{
"mappings": {
"doc": {
"properties": {
"location": {
"type": "geo_point"
}
}
}
}
}
Data values:
POST /museums/doc/_bulk?refresh
{"index":{"_id":1}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "52.369219,4.901618", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "52.371667,4.914722", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "51.222900,4.405200", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "48.860000,2.327000", "name": "Musée d'Orsay"}
{"index":{"_id":7}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":8}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}
Elastic Search query:
POST /museums/_search?size=0
{
"query": {
},
"sort": {
"_geo_distance": {
"location": {
"lat": 52.3760,
"lon": 4.894
},
"order": "asc",
"unit": "km",
"distance_type": "arc"
}
},
"aggregations": {
"by_id": {
"terms": {
"field": "name.keyword",
"order": {
"_count": "asc"
},
"size": 20
},
"aggregations":{
"top":{
"top_hits":
{
"sort":{
"_geo_distance":{
"location":{"lat":19.143172,"lon":72.824966
}
}
}
}
}
}
}
}
}
above query giving result but not sorting by distance.
I may have misread you, but you are trying to fetch locations within X km/miles from another point?
If so, there is an equation called the Haversine formula, which uses spherical trigonometry to calculate areas within a certain distance! It looks like this:
R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
Angles need to be in radians to pass to Trigonometric functions
Which is all very mathematical to me. In a MySQL query however, it looks like this:
SELECT *,
( 3959 * acos( cos( radians(55.864237) ) * cos( radians( latitude ) )
* cos( radians( longitude ) - radians(-4.251806) ) + sin( radians(55.864237) )
* sin( radians( latitude ) ) ) ) AS distance
FROM postcodes HAVING distance < 20
ORDER BY distance LIMIT 1;
Here I check for any area within 20 miles, but you can make this as short or long as you want. The 3959 figure at the start of the query is the number used for miles, if you are using kilometres you should change this number to 6371. I have limited it to 1 row, as I only want the closest match, however you may want to change this in other situations!
I have php code that returns this from a database,
[
{
"Time": "2012-11-27 16:10:35",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:24:55",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:25:37",
"NumPlayers": "2"
},
{
"Time": "2012-11-27 16:29:33",
"NumPlayers": "2"
The times are MySQL timestamps. I need to get it into this format to use with Highcharts javascript charting.
data: [
[Date.UTC(1970, 9, 9), 0 ],
[Date.UTC(1970, 9, 14), 0.15],
[Date.UTC(1970, 10, 28), 0.35],
[Date.UTC(1970, 11, 12), 0.46],
I'm having trouble figuring out how to loop through the MySQL results and convert the timestamps to javascript Date.UTC objects. I need to place the NumPlayers value after the Date.UTC objects, and output it in the format below. I'm a PHP and javascript noob :\
It should look something like this:
data: [
[Date.UTC(2012, 11, 27, 16, 10, 35), 1],
[Date.UTC(2012, 11, 27, 16, 24, 55), 1],
[Date.UTC(2012, 11, 27, 16, 25, 37), 2],
[Date.UTC(2012, 11, 27, 16, 29, 33), 2],
You should realize that Date.UTC(2012, 11, 27, 16, 10, 35) simply returns the number of milliseconds since the epoch (1356624635000). Therefore, you can just convert your object into UNIX timestamps (times a 1000 since JS works with millisecond timestamps, but PHP works with seconds).
Sample Code
$data = '[{"Time": "2012-11-27 16:10:35", "NumPlayers": "1"}, {"Time": "2012-11-27 16:24:55", "NumPlayers": "1"}]';
// Make sure date is parsed as UTC
date_default_timezone_set("UTC");
// Convert items into the desired format
$mapper = function($item) {
return array(strtotime($item->Time)*1000, $item->NumPlayers);
}
echo json_encode(array_map($mapper, json_decode($data)));
Output
[[1354032635000,"1"],[1354033495000,"1"]]
You seem to be getting straight JSON from your database, which you can always convert into an array:
$data = '[{"Time": "2012-11-27 16:10:35", "NumPlayers": "1"}, {"Time": "2012-11-27 16:24:55", "NumPlayers": "1"}]';
$arrayData = json_decode($data, true);
After which you can simply iterate through the array and print out the contents of the array in the JS format you need. Something like that:
echo 'data: [' . PHP_EOL;
foreach ($arrayData as $item) {
echo '[Date.UTC(';
$tmp = preg_split( '/(-| |\:)/', $item['Time'] );
echo implode(', ', $tmp);
echo '), ' . $item['NumPlayers'] . '],';
echo PHP_EOL;
}
echo PHP_EOL . '];';
You can split the time string into sections using /[^\d]+/g:
var finalData = [], numbers=/[^\d]+/g, item, dateParts, newDate;
for (var i=0, l=data.length; i<l; i++) {
item = data[i];
dateParts = item.Time.split(numbers);
newDate = Date.UTC.apply(Date, dateParts);
finalData.push([newDate, item.NumPlayers]);
}
See also: MDN's documentation on JavaScript regular expressions (/[^\d]/g is a regex).
The best way to provide data to Highcharts is getting data formated from database, so that you don't have to do it on client side.
To do it you just have to change your query to something like the following.
Backend
$query = "SELECT UNIX_TIMESTAMP(date) * 1000 AS 'date', value FROM ...";
Then to send the result to frontend:
echo json_encode($result);
Frontend
To get the result on frontend, this case using jQuery and assuming that url is your url:
$.getJSON(url, function(json) {
// decode json
var data = $.parseJSON(json);
// Then you just have to pass it to your series
});
Or better, store date values in UTC.
var php_data = [
{
"Time": "2012-11-27 16:10:35",
"NumPlayers": "1"
},
{
"Time": "2012-11-27 16:24:55",
"NumPlayers": "1"
}
];
var length = php_data.length;
hc_data = [];
for(var i = 0; i< length; i++){
php_date = new Date(php_data[i]["Time"]);
hc_data.push(
[
Date.UTC(
php_date.getFullYear(),
php_date.getMonth() + 1,
php_date.getDate()
),
php_data[i]["NumPlayers"]
]
);
}
// hc_data is your Array