Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Code Reviews

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.

+6
−0

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;
History
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

2 answers

+5
−0

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.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

+4
−0
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:

  1. Define what you mean by "square".
  2. Give a reference or derivation for the formulae.
  3. 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.

History
Why does this post require moderator attention?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »