PHP getting the value of the highest dynamic select - php
I have a series of selects that contain world regions.
For instance select r0 would contain
Africa
North America
Europe
When the user selects North America, a new select named r1 would appear with the following values:
Canada
United States
Mexico
Then the user would select US, r2 would appear with the states and so on.
As the data structure allows, currently, there can be up to 5 boxes (r0-r4)
I am trying to figure out how in php I can determine that there are 4 or 5 selects, and save that value of the highest number select to the database.
Am I going at this the wrong way?
Currently, I don't have any code written, because I'm not sure how to test the range of the $_POST["r#"] arrays, but was thinking something along the lines of:
<?php
$i = 0;
while (isset($_POST['r'.$i])) {
$highest_value = $_POST['r'.$i];
$i++;
}
?>
is there a better way?
I will try this :
$Value = null;
for ($i = 5; $i >= 0; $i--) {
if(isset($_POST['r'.$i]) AND $_POST['r'.$i]){
$Value = $_POST['r'.$i];
break;
}
}
I did not test it out.
Related
Golf league payout to six finishing positions
I have a golf league of 40 individuals. We all throw money in a pot and pay out the first 6 places based on final score. If there were no ties the pay out would be simple but often we have, for example, 2 people tied for first place, 3 people tied for second, 1 person alone in third, etc. The variations seem endless. I've been trying to automate the calculated payouts for each place using PHP but have not been successful. Any suggestions, help, or pointing in the right direction would be much appreciated. I noticed that someone else tried to ask a similar question on this site but was not successful in framing the question. I'll try to do a better job. Here is some data I've been playing around with: $playerNumber=40; $totalPoints=100; Payouts: $pointsFirst=0.6*$totalPoints; $pointsSecond=0.2*$totalPoints; $pointsThird=0.15*$totalPoints; $pointsFourth=0.03*$totalPoints; $pointsFifth=0.02*$totalPoints; $pointsSixth=0.01*$totalPoints; For the example given above and to pay out six places, we would calculate the payouts as follows: If two people are tied for first place, we add first and second place points and divide by two. If three people are tied for second place, we add third, fourth and fifth place points and divide by three. If one person is alone in third, this person would win sixth place points. I can count the number of players who are in or tied for a certain place. $countFirst=2; $countSecond=3; $countThird=1; $countFourth=2; $countFifth=1; $countSixth=2; In this example the player scores would be 72, 72, 73, 73, 73, 74, 75, 75, 76, 77, 77. At first I thought this was an application for nested arrays. Then I thought perhaps using arrays, array slice, etc, may be a way to go. Each time I end up in the woods. I'm not seeing the logic. I have used conditional statements for paying out three places but to pay out six places with this method puts me deep in the woods. Example of payout to three places using conditional statements: $pointsFirst=0.5*$totalPoints; $pointsSecond=0.3*$totalPoints; $pointsThird=0.2*$totalPoints; if($countFirst>2) { $ptsA=round($totalPoints/$countFirst,2); } elseif($countFirst==2) { $ptsA=round(($pointsFirst+$pointsSecond)/2,2); if($countSecond>1) { $ptsB=round($pointsThird/$countSecond,2); } elseif($countSecond==1) { $ptsB=round($pointsThird,2); } } elseif($countFirst==1) { $ptsA=round($pointsFirst,2); if($countSecond>1) { $ptsB=round(($pointsSecond+$pointsThird)/2,2); } elseif($countSecond==1) { $ptsB=round($pointsSecond,2); if($countThird>1) { $ptsC=round($pointsThird/$countThird,2); } elseif($countThird==1) { $ptsC=round($pointsThird,2); } } } I hope I have been clear in my request. I'll be glad to clarify anything. If anyone has any ideas on how to efficiently automate a payout calculation to six places I will be eternally grateful. Thank-you! Mike Per request: $scores=array(); $scores[0]=72; $scores[1]=72; $scores[2]=73; $scores[3]=73; $scores[4]=73; $scores[5]=74; $scores[6]=75; $scores[7]=75; $scores[8]=76; $scores[9]=77; $scores[10]=77; $payout=array(); $payout[0]=0.6*$totalPoints; $payout[1]=0.2*$totalPoints; $payout[2]=0.15*$totalPoints; $payout[3]=0.03*$totalPoints; $payout[4]=0.02*$totalPoints; $payout[5]=0.01*$totalPoints; $countScores=array(); $countScores[0]=$countFirst; $countScores[1]=$countSecond; $countScores[2]=$countThird; $countScores[3]=$countFourth; $countScores[4]=$countFifth; $countScores[5]=$countSixth;
First, there is a problem with your Payouts. If you add them up you get 1.01 not 1 0.6 (1st) + 0.2 (2nd ) + 0.15 (3rd) + 0.03 (4th) + 0.02 (5th) + 0.01 (6th) = 1.01 Second, it is easier if you make your Payouts and Counts into arrays - change these - $pointsFirst=0.6*$totalPoints; $pointsSecond=0.2*$totalPoints; $pointsThird=0.15*$totalPoints; $pointsFourth=0.03*$totalPoints; $pointsFifth=0.02*$totalPoints; $pointsSixth=0.01*$totalPoints; $countFirst=2; $countSecond=3; $countThird=1; $countFourth=2; $countFifth=1; $countSixth=2; to these $payout=array(); $payout[0]=0.6*$totalPoints; $payout[1]=0.2*$totalPoints; $payout[2]=0.15*$totalPoints; $payout[3]=0.03*$totalPoints; $payout[4]=0.02*$totalPoints; $payout[5]=0.01*$totalPoints; $count=array(); $count[0]=2; $count[1]=3; $count[2]=1; $count[3]=2; $count[4]=1; $count[5]=2; Here is the start of one way to do it. Although I would eventually change this into a function so that I can use it again with different payouts, and number of places (see phpfiddle examples below) I see this in 4 steps- Step 1 // Add together the payments if there are ties - ie. 2 tied for first $payout[0]+$payout[1], etc $payout_groups = array(); // start a payout array $payout_groups_key = 0; // array key count $payout_groups_count = 0; // array counter, use to match the $count array values for($w=0;$w<count($payout);$w++){ // if(array_key_exists($payout_groups_key,$payout_groups)){ $payout_groups[$payout_groups_key] += $payout[$w]; // if there are ties, add them together } else{ $payout_groups[$payout_groups_key] = $payout[$w]; // else set a new payout level } $payout_groups_count++; // increase the counter if($payout_groups_count == $count[$payout_groups_key]){ // if we merged all the ties, set a new array key and restart the counter $payout_groups_key++; $payout_groups_count = 0; } } Step 2 // basic counter to get how many placers/winners. This makes it possible to have ties for 6th (last) place $x = 0; $y = 0; while($y < count($payout)){ $y += $count[$x]; // the $count array values until we reach the amount of places/payouts $x++; } Step 3 // Create array for winnings per placing $winnings = array(); // start an array $placings_count = 0; // $placings_counter = 0; for($z=0;$z<$y;$z++){ $winnings[$z] = $payout_groups[$placings_count]/$count[$placings_count]; $placings_counter++; if($placings_counter == $count[$placings_count]){ $placings_count++; $placings_counter = 0; } } Step 4 // Assign winnings to scorecard $scoreboard = array(); for($t=0;$t<count($winnings);$t++){ $scoreboard[$t]['score'] = $scores[$t]; $scoreboard[$t]['payout'] = $winnings[$t]; } You can see this using your defined values at - http://phpfiddle.org/main/code/a1g-qu0 Using the same code above, I changed the payout amounts, and increased it to 7th places - http://phpfiddle.org/main/code/uxi-qgt
How do you rearrange text within a string from a MySQL query?
Solution I am looking for: I would like to rearrange words within the text string results such that the job title is moved from the end of the string to the beginning of the string for each line item. Currently, I am retrieving data from an external medical database query ($query). However, I cannot make any changes to the database or to the MySQL query statement itself. The $query is retrieved and I then place the results in a $data array via the following command: while($row = mysql_fetch_assoc($query)){$data[] = $row;} I then change all the job titles to uppercase in the $data array as follows: $job_01 = 'anesthesiologist'; $job_02 = 'dentist'; $job_03 = 'general practitioner'; $job_04 = 'internist'; $job_05 = 'lawyer'; $job_06 = 'manager'; $job_07 = 'pediatrician'; $job_08 = 'psychiatrist'; $replace_01 = 'ANESTHESIOLOGIST'; $replace_02 = 'DENTIST'; $replace_03 = 'GENERAL PRACTITIONER'; $replace_04 = 'INTERNIST'; $replace_05 = 'LAWYER'; $replace_06 = 'MANAGER'; $replace_07 = 'PEDIATRICIAN'; $replace_08 = 'PSYCHIATRIST'; $searchArray = array($job_01, $job_02, $job_03, $job_04, $job_05, $job_06, $job_07, $job_08); $replaceArray = array($replace_01, $replace_02, $replace_03, $replace_04, $replace_05, $replace_06, $replace_07, $replace_08); for ($i=0; $i<=count($data)-1; $i++) { $line[$i] = str_ireplace($searchArray, $replaceArray, $data[$i])); } The final output is in the following line item text string format: Example Query results (4 line items) California Long time medical practitioner - ANESTHESIOLOGIST 55yr New York Specializing in working with semi-passive children - PEDIATRICIAN (doctor) 42yr Nevada Currently working in a new medical office - PSYCHIATRIST 38yr Texas Represents the medical-liability industry - LAWYER (attorney) 45yr I would like to rearrange these results such that I can output the data to my users in the following format by moving the job title to the beginning of each line item as in: Desired results (usually over 1000 items) ANESTHESIOLOGIST - California Long time medical practitioner - 55yr PEDIATRICIAN - New York Specializing in working with semi-passive children - (doctor) 42yr PSYCHIATRIST - Nevada Currently working in a new medical office - psychiatrist 38yr LAWYER - Texas Represents the medical-liability industry - lawyer (attorney) 45yr Ideally, if possible, it would also be nice to have the age moved to the beginning of the text string results as follows: Ideal Results 55yr - ANESTHESIOLOGIST - California Long time medical practitioner 42yr - PEDIATRICIAN - New York Specializing in working with semi-passive children - (doctor) 38yr - PSYCHIATRIST - Nevada Currently working in a new medical office - psychiatrist 45yr - LAWYER - Texas Represents the medical-liability industry - lawyer (attorney)
You could use a regular expression to extract and rearrange the array: for ($i=0; $i<=count($data)-1; $i++) { $line[$i] = str_ireplace($searchArray, $replaceArray, $data[$i])); // variant a, complete line if(preg_match_all('/(.*)\s+-\s+(.*)\s+(\d+)yr$/', $line[$i],$matches)) { $line[$i] = $matches[3][0].'yr - '.$matches[2][0].' - '.$matches[1][0]; // variant b, a line with age, but no jobtitle } elseif(preg_match_all('/(.*)\s+-\s+(\d+)yr$/', $line[$i],$matches)) { $line[$i] = $matches[2][0].'yr - '.$matches[1][0]; // variant c, no age } elseif(preg_match_all('/(.*)\s+-\s+(.*)$/', $line[$i],$matches)) { $line[$i] = $matches[2][0].' - '.$matches[1][0]; } // in other cases (no age, no jobtitle), the line is not modified at all. }
Add all instance of a variable together in a PHP foreach loop?
I am trying to do something that's quite complex (for me anyway) and I've got a point which has stopped me in my tracks. In this project, you enter the weight of a box, and the percentage of materials held in that box. So for example, a box may have 10% of wood, 40% of plastic, and 50% of paper. The weights of the materials are held in the database as they dont change. So the value of 1% of wood is held in the database, as 1% of plastic and paper. The controller should then take the percentage of material given, and then multiply it by the 1% value held in the database. So far, this is my code: foreach($wastestream as $ws) { $genweight = $ws['Materialtype']['1pc'] * $ws['Valuegiven']['percent']; } And this gives the following values: 10% Wood = 97.5 40% Plastic = 100.4 50% Paper = 40.3 The problem I now have is that I have to add all of these variables together. So essentially what I want to do after it pumps out the values is to add them all up together, so: 97.5 + 100.4 + 40.3 = 238.2 What should I do? Cheers!
I think I have misunderstood something, since it seems not complicated at all... $total=0; foreach($wastestream as $ws) { $total += $ws['Materialtype']['1pc'] * $ws['Valuegiven']['percent']; } $total will hold the total value
Could you add the values as they are created? $totalweight = 0; foreach($wastestream as $ws) { $genweight = $ws['Materialtype']['1pc'] * $ws['Valuegiven']['percent']; $totalweight += $genweight; }
PHP implementation of Bayes classificator: Assign topics to texts
In my news page project, I have a database table news with the following structure: - id: [integer] unique number identifying the news entry, e.g.: *1983* - title: [string] title of the text, e.g.: *New Life in America No Longer Means a New Name* - topic: [string] category which should be chosen by the classificator, e.g: *Sports* Additionally, there's a table bayes with information about word frequencies: - word: [string] a word which the frequencies are given for, e.g.: *real estate* - topic: [string] same content as "topic" field above, e.h. *Economics* - count: [integer] number of occurrences of "word" in "topic" (incremented when new documents go to "topic"), e.g: *100* Now I want my PHP script to classify all news entries and assign one of several possible categories (topics) to them. Is this the correct implementation? Can you improve it? <?php include 'mysqlLogin.php'; $get1 = "SELECT id, title FROM ".$prefix."news WHERE topic = '' LIMIT 0, 150"; $get2 = mysql_abfrage($get1); // pTOPICS BEGIN $pTopics1 = "SELECT topic, SUM(count) AS count FROM ".$prefix."bayes WHERE topic != '' GROUP BY topic"; $pTopics2 = mysql_abfrage($pTopics1); $pTopics = array(); while ($pTopics3 = mysql_fetch_assoc($pTopics2)) { $pTopics[$pTopics3['topic']] = $pTopics3['count']; } // pTOPICS END // pWORDS BEGIN $pWords1 = "SELECT word, topic, count FROM ".$prefix."bayes"; $pWords2 = mysql_abfrage($pWords1); $pWords = array(); while ($pWords3 = mysql_fetch_assoc($pWords2)) { if (!isset($pWords[$pWords3['topic']])) { $pWords[$pWords3['topic']] = array(); } $pWords[$pWords3['topic']][$pWords3['word']] = $pWords3['count']; } // pWORDS END while ($get3 = mysql_fetch_assoc($get2)) { $pTextInTopics = array(); $tokens = tokenizer($get3['title']); foreach ($pTopics as $topic=>$documentsInTopic) { if (!isset($pTextInTopics[$topic])) { $pTextInTopics[$topic] = 1; } foreach ($tokens as $token) { echo '....'.$token; if (isset($pWords[$topic][$token])) { $pTextInTopics[$topic] *= $pWords[$topic][$token]/array_sum($pWords[$topic]); } } $pTextInTopics[$topic] *= $pTopics[$topic]/array_sum($pTopics); // #documentsInTopic / #allDocuments } asort($pTextInTopics); // pick topic with lowest value if ($chosenTopic = each($pTextInTopics)) { echo '<p>The text belongs to topic '.$chosenTopic['key'].' with a likelihood of '.$chosenTopic['value'].'</p>'; } } ?> The training is done manually, it isn't included in this code. If the text "You can make money if you sell real estates" is assigned to the category/topic "Economics", then all words (you,can,make,...) are inserted into the table bayes with "Economics" as the topic and 1 as standard count. If the word is already there in combination with the same topic, the count is incremented. Sample learning data: word topic count kaczynski Politics 1 sony Technology 1 bank Economics 1 phone Technology 1 sony Economics 3 ericsson Technology 2 Sample output/result: Title of the text: Phone test Sony Ericsson Aspen - sensitive Winberry Politics ....phone ....test ....sony ....ericsson ....aspen ....sensitive ....winberry Technology ....phone FOUND ....test ....sony FOUND ....ericsson FOUND ....aspen ....sensitive ....winberry Economics ....phone ....test ....sony FOUND ....ericsson ....aspen ....sensitive ....winberry Result: The text belongs to topic Technology with a likelihood of 0.013888888888889 Thank you very much in advance!
It looks like your code is correct, but there are a few easy ways to optimize it. For example, you calculate p(word|topic) on the fly for every word while you could easily calculate these values beforehand. (I'm assuming you want to classify multiple documents here, if you're only doing a single document I suppose this is okay since you don't calculate it for words not in the document) Similarly, the calculation of p(topic) could be moved outside of the loop. Finally, you don't need to sort the entire array to find the maximum. All small points! But that's what you asked for :) I've written some untested PHP-code showing how I'd implement this below: <?php // Get word counts from database $nWordPerTopic = mystery_sql(); // Calculate p(word|topic) = nWord / sum(nWord for every word) $nTopics = array(); $pWordPerTopic = array(); foreach($nWordPerTopic as $topic => $wordCounts) { // Get total word count in topic $nTopic = array_sum($wordCounts); // Calculate p(word|topic) $pWordPerTopic[$topic] = array(); foreach($wordCounts as $word => $count) $pWordPerTopic[$topic][$word] = $count / $nTopic; // Save $nTopic for next step $nTopics[$topic] = $nTopic; } // Calculate p(topic) $nTotal = array_sum($nTopics); $pTopics = array(); foreach($nTopics as $topic => $nTopic) $pTopics[$topic] = $nTopic / $nTotal; // Classify foreach($documents as $document) { $title = $document['title']; $tokens = tokenizer($title); $pMax = -1; $selectedTopic = null; foreach($pTopics as $topic => $pTopic) { $p = $pTopic; foreach($tokens as $word) { if (!array_key_exists($word, $pWordPerTopic[$topic])) continue; $p *= $pWordPerTopic[$topic][$word]; } if ($p > $pMax) { $selectedTopic = $topic; $pMax = $p; } } } ?> As for the maths... You're trying to maximize p(topic|words), so find arg max p(topic|words) (IE the argument topic for which p(topic|words) is the highest) Bayes theorem says p(topic)*p(words|topic) p(topic|words) = ------------------------- p(words) So you're looking for p(topic)*p(words|topic) arg max ------------------------- p(words) Since p(words) of a document is the same for any topic this is the same as finding arg max p(topic)*p(words|topic) The naive bayes assumption (which makes this a naive bayes classifier) is that p(words|topic) = p(word1|topic) * p(word2|topic) * ... So using this, you need to find arg max p(topic) * p(word1|topic) * p(word2|topic) * ... Where p(topic) = number of words in topic / number of words in total And p(word, topic) 1 p(word | topic) = ---------------- = p(word, topic) * ---------- p(topic) p(topic) number of times word occurs in topic number of words in total = -------------------------------------- * -------------------------- number of words in total number of words in topic number of times word occurs in topic = -------------------------------------- number of words in topic
How to find the centre of a grid of lines on google maps
I'm struggling with a problem with some GIS information that I am trying to put into a KML file to be used by google maps and google Earth. I have SQL database containing a number of surveys, which are stored in lines. When all the lines are drawn on the map, they create a grid. What I am trying to do is work out the centre of these 'grids' so that I can put a placemarker reference into the kml to show all the grid locations on a map. lines is stored in the database like this: 118.718318,-19.015803,0 118.722449,-19.016919,0 118.736223,-19.020637,0 118.749936,-19.024023,0 118.763897,-19.027722,0 118.777705,-19.031277,0 118.791416,-19.034826,0 118.805276,-19.038367,0 118.818862,-19.041962,0 118.832862,-19.045582,0 118.846133,-19.049563,0 118.859801,-19.053851,0 118.873322,-19.058145,0 118.887022,-19.062349,0 118.900595,-19.066594,0 118.914066,-19.070839,0 118.927885,-19.075151,0 118.941468,-19.079354,0 118.955064,-19.083658,0 118.968766,-19.087896,0 118.982247,-19.092054,0 118.995795,-19.096324,0 119.009192,-19.100448,0 119.022805,-19.104787,0 119.036414,-19.10893,0 119.049625,-19.113166,0 119.063155,-19.11738,0 119.076626,-19.121563,0 119.090079,-19.125738,0 119.103679,-19.129968,0 119.117009,-19.134168,0 119.130637,-19.138418,0 119.144134,-19.142613,0 119.157749,-19.146767,0 119.171105,-19.151058,0 119.184722,-19.155252,0 119.19844,-19.159399,0 119.211992,-19.163737,0 119.225362,-19.167925,0 119.239109,-19.17218,0 119.252552,-19.176239,0 119.265975,-19.180483,0 119.279718,-19.184901,0 119.2931,-19.189118,0 119.306798,-19.193267,0 119.320561,-19.197631,0 119.33389,-19.201898,0 119.34772,-19.206063,0 119.361322,-19.210282,0 119.374522,-19.214505,0 119.38825,-19.218753,0 119.401948,-19.22299,0 119.415609,-19.227171,0 119.42913,-19.231407,0 119.44269,-19.235604,0 119.456221,-19.240254,0 119.469772,-19.244165,0 119.483159,-19.248341,0 119.496911,-19.252483,0 119.510569,-19.256818,0 119.524034,-19.261068,0 119.537822,-19.265332,0 119.551409,-19.269529,0 119.564744,-19.273764,0 119.578357,-19.277874,0 119.591935,-19.282171,0 119.605472,-19.286424,0 119.619009,-19.290593,0 119.632777,-19.294862,0 119.646394,-19.299146,0 119.660107,-19.303469,0 119.673608,-19.307602,0 119.6872,-19.31182,0 119.700838,-19.31605,0 119.714555,-19.320301,0 119.728202,-19.324615,0 119.741511,-19.328794,0 119.755299,-19.333098,0 119.768776,-19.337206,0 119.782216,-19.341528,0 119.796141,-19.345829,0 119.809691,-19.349879,0 119.822889,-19.354112,0 119.836822,-19.358414,0 119.850077,-19.362618,0 119.864069,-19.366916,0 119.8773,-19.371092,0 119.891263,-19.37536,0 119.904612,-19.379556,0 119.918522,-19.38394,0 119.932101,-19.388108,0 119.945577,-19.392184,0 119.959304,-19.396544,0 119.973042,-19.400809,0 119.986433,-19.405015,0 119.999196,-19.408981,0 120.011959,-19.412946,0 120.014512,-19.41374,0 118.990393,-19.523933,0 118.990833,-19.522296,0 118.994368,-19.509069,0 118.997911,-19.49589,0 119.001249,-19.48258,0 119.004939,-19.469658,0 119.008437,-19.456658,0 119.01183,-19.443361,0 119.015332,-19.430439,0 119.01869,-19.417491,0 119.022303,-19.40421,0 119.025853,-19.391381,0 119.029387,-19.377966,0 119.032821,-19.365006,0 119.036247,-19.352047,0 119.039935,-19.338701,0 119.043376,-19.325781,0 119.046824,-19.312713,0 119.050223,-19.299634,0 119.053822,-19.286711,0 119.05736,-19.273441,0 119.060722,-19.260467,0 119.064357,-19.247382,0 119.067863,-19.234069,0 119.071361,-19.221168,0 119.07486,-19.208268,0 119.078303,-19.19503,0 119.081721,-19.181915,0 119.085296,-19.169016,0 119.088851,-19.155937,0 119.092245,-19.142828,0 119.095887,-19.12944,0 119.099337,-19.116291,0 119.102821,-19.103421,0 119.106333,-19.090384,0 119.109885,-19.077356,0 119.113395,-19.063976,0 119.116866,-19.050973,0 119.120467,-19.037886,0 119.123751,-19.024888,0 119.127385,-19.011622,0 119.130775,-18.998856,0 119.134503,-18.98547,0 119.13873,-18.9728,0 119.14289,-18.959666,0 119.146076,-18.946541,0 119.149065,-18.933693,0 119.152281,-18.920522,0 119.155414,-18.907033,0 119.158442,-18.894058,0 119.161421,-18.88097,0 119.164632,-18.867484,0 119.167668,-18.854501,0 119.170744,-18.841401,0 119.173939,-18.827999,0 119.17703,-18.815028,0 119.17984,-18.802218,0 119.182902,-18.789334,0 119.186088,-18.776136,0 119.189031,-18.762862,0 119.192179,-18.749824,0 119.19539,-18.7365,0 119.198255,-18.723279,0 119.201476,-18.710134,0 119.204345,-18.69705,0 119.20746,-18.683768,0 119.210555,-18.670607,0 119.213641,-18.657632,0 119.216727,-18.644301,0 119.21982,-18.630956,0 119.223094,-18.617243,0 119.22625,-18.603885,0 119.229368,-18.590534,0 119.232494,-18.577364,0 119.235477,-18.564287,0 119.238496,-18.550953,0 119.241392,-18.53789,0 119.244609,-18.524881,0 119.247551,-18.512017,0 119.250532,-18.498916,0 119.253729,-18.485859,0 119.256428,-18.473845,0 119.259288,-18.461645,0 119.262064,-18.4491,0 119.265024,-18.437048,0 119.267877,-18.424992,0 119.270457,-18.4136,0 119.273429,-18.401305,0 119.276346,-18.388484,0 119.279506,-18.375299,0 119.282307,-18.362197,0 119.285494,-18.34918,0 119.288695,-18.336115,0 119.291008,-18.323772,0 119.294026,-18.310635,0 119.297332,-18.297714,0 119.300499,-18.284553,0 119.303442,-18.271193,0 119.307081,-18.258278,0 119.309945,-18.245139,0 119.313121,-18.232137,0 119.31642,-18.218993,0 119.319499,-18.205722,0 119.322801,-18.192774,0 119.325986,-18.179558,0 119.329173,-18.166332,0 119.33236,-18.15312,0 119.335558,-18.140071,0 119.338761,-18.126696,0 119.342007,-18.113502,0 119.345238,-18.100349,0 119.34808,-18.088343,0 119.350259,-18.079138,0 119.912412,-18.177179,0 119.910223,-18.183223,0 119.905619,-18.195973,0 119.901171,-18.208645,0 119.896641,-18.221452,0 119.89198,-18.234323,0 119.887547,-18.246912,0 119.882922,-18.259925,0 119.878421,-18.272522,0 119.873909,-18.285223,0 119.869264,-18.298194,0 119.864746,-18.310939,0 119.860203,-18.323628,0 119.855692,-18.336434,0 119.850997,-18.349262,0 119.846561,-18.362014,0 119.841916,-18.374866,0 119.837406,-18.387565,0 119.832778,-18.400657,0 119.828259,-18.413072,0 119.82364,-18.426273,0 119.819088,-18.438992,0 119.814546,-18.451696,0 119.810103,-18.464425,0 119.80548,-18.477041,0 119.800935,-18.48989,0 119.796359,-18.502741,0 119.791812,-18.515489,0 119.787314,-18.528536,0 119.782724,-18.540965,0 119.778079,-18.553994,0 119.773558,-18.56663,0 119.768931,-18.57955,0 119.76446,-18.592177,0 119.759793,-18.605255,0 119.755393,-18.617736,0 119.750648,-18.630757,0 119.746479,-18.643371,0 119.741779,-18.656176,0 119.737071,-18.669135,0 119.732572,-18.681798,0 119.727954,-18.694669,0 119.723453,-18.707473,0 119.718855,-18.720259,0 119.714169,-18.733198,0 119.70946,-18.746355,0 119.704998,-18.759005,0 119.700581,-18.771793,0 119.696226,-18.784893,0 119.691577,-18.797373,0 119.68662,-18.810064,0 119.682182,-18.822772,0 119.677711,-18.835621,0 119.672955,-18.848475,0 119.668536,-18.861252,0 119.663856,-18.873901,0 119.659412,-18.88663,0 119.654815,-18.899592,0 119.650185,-18.912338,0 119.645586,-18.925118,0 119.640925,-18.937923,0 119.636617,-18.950753,0 119.631874,-18.963446,0 119.627376,-18.976275,0 119.622845,-18.98893,0 119.618175,-19.001942,0 119.613727,-19.014668,0 119.608878,-19.027398,0 119.60445,-19.039954,0 119.599954,-19.053249,0 119.595066,-19.066008,0 119.590562,-19.078866,0 119.586062,-19.091703,0 119.58155,-19.104199,0 119.576948,-19.116924,0 119.572431,-19.129926,0 119.567449,-19.142699,0 119.563227,-19.155474,0 119.558555,-19.168309,0 119.553956,-19.181053,0 119.549545,-19.193649,0 119.544854,-19.20646,0 119.540133,-19.21929,0 119.535606,-19.232162,0 119.53108,-19.245054,0 119.526509,-19.257772,0 119.522079,-19.270427,0 119.517419,-19.283013,0 119.512755,-19.296126,0 119.508159,-19.309031,0 119.503557,-19.321821,0 119.498966,-19.334394,0 119.494487,-19.347232,0 119.489815,-19.359907,0 119.485201,-19.372962,0 119.48067,-19.385811,0 119.476151,-19.398326,0 119.471526,-19.411138,0 119.466856,-19.424266,0 119.462284,-19.436788,0 119.457752,-19.449628,0 119.452975,-19.462718,0 119.448612,-19.47499,0 119.444249,-19.48726,0 119.439886,-19.499531,0 119.437704,-19.505666,0 Each point is where a mesasurement took place. Is there a PHP library or a formula that can be used to work this out without being too intensive? Thanks
It depends very much on how you define "center". One somewhat sophisticated approach you might like to try: Extract a list of points from the lines Find the convex hull of the points: Find the centroid of the convex hull (source: algorithmic-solutions.info) The convex hull is simply described as the simplest polygon that passes through some of the points, forming an envelop that encloses all of the points within the polygon. wikipedia has a more rigorous description. The centroid provides a simple way for finding the "center of gravity" of a polygon. A wikipedia and a nice tutorial provide more information.
Alternatively, a very simple implementation might find the minimum bounding rectangle of the lines, and then find the geometric center of the box. The following code assumes the lines you posted above are represented as strings, and are in an array. I'm no php performance expert, but this algorithm should execute in O(n) asymptotic time: <?php $line_strs = array( "118.718318,-19.015803,0 118.722449,-19.016919,0 118.736223,-19.020637,0 118.749936,-19.024023,0 118.763897,-19.027722,0 118.777705,-19.031277,0", "118.791416,-19.034826,0 118.805276,-19.038367,0 118.818862,-19.041962,0 118.832862,-19.045582,0 118.846133,-19.049563,0 118.859801,-19.053851,0", [SNIP majority of lines...] "119.448612,-19.47499,0 119.444249,-19.48726,0 119.439886,-19.499531,0 119.437704,-19.505666,0"); $xs = array(); $ys = array(); foreach ($line_strs as $line){ $points = explode(' ', $line); foreach ($points as $pt){ $xyz = explode(',', $pt); $xs[] = (float)$xyz[0]; $ys[] = (float)$xyz[1]; } } $x_mean = (max($xs) + min($xs)) / 2; $y_mean = (max($ys) + min($ys)) / 2; echo "$x_mean,$y_mean\n"; ?> This outputs 119.366415,-18.8015355.
centroids ? If I have time, I'll edit this answer to include a python implementation
Another very simple answer finds the mean location of all vertices. It favours areas that are densely populated by points. This returns a slightly different answer to the bounding box method. You might want to try them box to see which provides a "better" result for your data. <?php $line_strs = array( "118.718318,-19.015803,0 118.722449,-19.016919,0 118.736223,-19.020637,0 118.749936,-19.024023,0 118.763897,-19.027722,0 118.777705,-19.031277,0", "118.791416,-19.034826,0 118.805276,-19.038367,0 118.818862,-19.041962,0 118.832862,-19.045582,0 118.846133,-19.049563,0 118.859801,-19.053851,0", [SNIP majority of lines...] "119.448612,-19.47499,0 119.444249,-19.48726,0 119.439886,-19.499531,0 119.437704,-19.505666,0"); $x_sum = 0.0; $y_sum = 0.0; $n = 0; foreach ($line_strs as $line){ $points = explode(' ', $line); foreach ($points as $pt){ $xyz = explode(',', $pt); $x_sum += (float)$xyz[0]; $y_sum += (float)$xyz[1]; $n++; } } $x_mean = $x_sum / $n; $y_mean = $y_sum / $n; echo "$x_mean,$y_mean\n"; ?> This outputs 119.402034114,-18.9427670536.