Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
PHP script to create a KML square centred on a point.
The objective here is to create a set of square kml coordinates centered on a point. I use this to create a square map centered on a mountain peak and then turn that into a STL that I can 3D print.
<?php
echo "Enter Latitude\n";
$handle = fopen("php://stdin", "r");
$lat = deg2rad(trim(fgets($handle)));
fclose($handle);
echo "Enter Longitude\n";
$handle = fopen("php://stdin", "r");
$long = deg2rad(trim(fgets($handle)));
fclose($handle);
echo "Enter Distance\n";
$handle = fopen("php://stdin", "r");
$meter = trim(fgets($handle));
fclose($handle);
$kml .= "<coordinates>";
$d_rad = $meter / 6378137;
$i = 45;
for ($loop = 0; $loop <= 4; $loop += 1) {
$radial = deg2rad($i);
$lat_rad = asin(sin($lat) * cos($d_rad) + cos($lat) * sin($d_rad) * cos($radial));
$dlon_rad = atan2(sin($radial) * sin($d_rad) * cos($lat), cos($d_rad) - sin($lat) * sin($lat_rad));
$lon_rad = fmod(($long + $dlon_rad + M_PI), 2 * M_PI) - M_PI;
$kml .= rad2deg($lon_rad) . "," . rad2deg($lat_rad) . ",0 ";
$i += 90;
}
$kml .= "</coordinates>\n";
echo $kml;
2 answers
echo "Enter Latitude\n"; $handle = fopen("php://stdin", "r"); $lat = deg2rad(trim(fgets($handle))); fclose($handle); echo "Enter Longitude\n"; $handle = fopen("php://stdin", "r"); $long = deg2rad(trim(fgets($handle))); fclose($handle); echo "Enter Distance\n"; $handle = fopen("php://stdin", "r"); $meter = trim(fgets($handle)); fclose($handle);
I found the opening and closing of stdin quite confusing, but worse than that it fails to work in my test environment. Open it once and close it at the end.
$handle
is not a very descriptive name. How about $stdin
?
The prompt for "distance" will be more usable for other people (and perhaps yourself in two years) if you state the units. Degrees can reasonably be inferred for latitude and longitude, but there are various common units for distance. It might also be helpful to define what distance it is.
$kml .= "<coordinates>";
I get a "notice" complaining about using .=
instead of =
for a variable which hasn't previously been defined.
$d_rad = $meter / 6378137;
Magic! $d_rad
for "distance in radians"?
$i = 45; for ($loop = 0; $loop <= 4; $loop += 1) { $radial = deg2rad($i); $lat_rad = asin(sin($lat) * cos($d_rad) + cos($lat) * sin($d_rad) * cos($radial)); $dlon_rad = atan2(sin($radial) * sin($d_rad) * cos($lat), cos($d_rad) - sin($lat) * sin($lat_rad)); $lon_rad = fmod(($long + $dlon_rad + M_PI), 2 * M_PI) - M_PI; $kml .= rad2deg($lon_rad) . "," . rad2deg($lat_rad) . ",0 "; $i += 90; } $kml .= "</coordinates>\n"; echo $kml;
$loop++
would be more idiomatic: I think Python is probably the only language where += 1
is the idiomatic increment operator.
The mathematics could use multiple comments:
- Define what you mean by "square".
- Give a reference or derivation for the formulae.
- Address issues of valid ranges, numerical analysis, etc. For example, the code is clearly incorrect at the poles, where the output appears to collapse to a line.
There are arguments for preferring to handle string concatenation in a loop with array concatenation followed by implode
:
$kml = ["<coordinates>"];
for (...) {
...
$kml[] = rad2deg($lon_rad) . "," . rad2deg($lat_rad) . ",0 ";
}
$kml[] = "</coordinates>\n";
echo implode($kml);
This isn't a major issue with a small fixed loop, so consider this a nit-pick.
0 comment threads
1 - Rearrange the code: Open stdin, read all parameters, close stdin, then process the parameters.
2 - Consider adding some validation to the parameters.
3 - Add an explanation of the magic number 6378137 - I had to Google it to find out what it means.
4 - Replace $i = 45, $i += 90 and the for statement with:
for ($i = 45; $i <= 405; $i += 90) {
Which actually doesn't look right. Is it supposed to be $loop <= 4, which turns into $i = 405? Or should it be < 4 which would have the last $i = 315?
5 - Assign cos($d_rad), sin($d_rad), sin($lat) and cos($lat) to variables outside the loop instead of calculating them repeatedly.
0 comment threads