Assignment 2

Calculate distance using a web service

Web services were introduced in the lessons as programs that allow other programs to talk to each other, which in Web GIS usually means showing maps in a browser or app. In the previous assignment, roads, demographics, and basemap layers were streamed to our app via web services, and most of our assignments will pull data in this way. Today we will write the code to create our own web service from scratch.

To do this, we will need a web server to host our application and listen for requests from clients. We will use CodeSandbox.io as a free test environment*.

The web service will perform a simple operation: find the distance between two points on Earth. The programming language we will use is JavaScript.

*The same environment could be set up on your own server or personal computer by installing Node.js on Windows, macOS, or Linux.

Table of Contents

Prep

  1. Go to https://codesandbox.io/s and click Sign in. Use your Github account to sign in.
    CodeSandbox sign in link

  2. Under Create Sandbox, choose Node HTTP Server.
    CodeSandbox Node template

  3. Once the Sandbox is created, take a moment to absorb what is on the screen, because it will seem like a lot. Note four main areas of interest:

    • Files - index.js is created by default as our main application file. Click a file to view and edit its code.
    • Code - index.js contains some default JavaScript that we will modify here in the code area.
    • Preview - Your application’s output will be previewed here in an emulated browser.
    • URL - You can copy this URL to a real browser to view your application’s output, just like a real web app!
      CodeSandbox Node template

You don’t have a web service yet, but you’re all set to start coding one.

Data

The data to calculate distance will be two pairs of latitude and longitude coordinates representing two locations. For example, 30 degrees latitude and -90 longitude for New Orleans and 30.45 degrees latitude and -91.187 longitude for Baton Rouge.

Steps

Part 1: Make a web service

  1. Delete all default code in index.js and copy and paste the code below. Notice the three italicized lines beginning with //. These are comments and they indicate what the blocks of code under them do, for any person reading the code. You do not need to understand every bit of code here, just the general purpose of each part.
      var http = require("http");
      http
     .createServer(function (request, response) {
       // Read the URL used to contact the web service and extract the latitude and longitude values, saving them each to a variable
       var requestUrl = new URL("http://" + request.headers.host + request.url);
       var latA = requestUrl.searchParams.get("latA");
       var lonA = requestUrl.searchParams.get("lonA");
       var latB = requestUrl.searchParams.get("latB");
       var lonB = requestUrl.searchParams.get("lonB");
    
       // Use the spherical law of cosines formula to calculate distance along the surface of a sphere. It is not the most accurate method for Earth, but it is good enough. Source: https://www.movable-type.co.uk/scripts/latlong.html
       var φ1 = (latA * Math.PI) / 180;
       var φ2 = (latB * Math.PI) / 180;
       var Δλ = ((lonB - lonA) * Math.PI) / 180;
       var R = 6371; // Earth's radius in km
       var distance =
         Math.acos(
           Math.sin(φ1) * Math.sin(φ2) + Math.cos(φ1) * Math.cos(φ2) * Math.cos(Δλ)
         ) * R;
    
       // Output the calculated distance value to the client and complete the execution of the program.
       response.setHeader("Access-Control-Allow-Origin", "*");
       response.write('{"distance": ' + distance.toFixed(2) + '}');
       response.end();
     })
     .listen(8080);
    
  2. Save index.js by clicking File > Save, or use the shortcut Ctrl+S (Cmd+S on Mac).
  3. Refresh the preview browser (not your web browser); it should output {"distance": 0} because we did not provide input in the URL.
  4. In the preview browser’s address bar, add the following text to the end of the URL and press Enter on your keyboard:
    ?latA=30&lonA=-90&latB=30.45&lonB=-91.187
    The URL now contains parameters with values. When you press enter, the lat/lon values for a “point A” (New Orleans) and “point B” (Baton Rouge) are passed to the web service, which calculates the distance using the formula we entered in JavaScript.
    • latA = 30
    • lonA = -90
    • latB = 30.45
    • lonB = -91.187
  5. The web service should now output {"distance": 124.53850456983854}, which is the distance in kilometers.
  6. Note the URL that your web service is using by looking in the address bar of the Codesandbox preview browser (not your web browser). You will need this URL in the next part, so copy it now. The URL should be similar to https://abc123.sse.codesandbox.io.

The web service is ready to receive requests at that URL from other apps needing a distance calculation.

Part 2: Make an app

With the web service now listening for requests, let’s make an app to request a distance calculation from it.

  1. Follow the steps in the Prep section again to create another sandbox, but this time under Create Sandbox choose Vanilla for a plain web server.
  2. Once the sandbox is created, click index.html in the Files area.
  3. Replace the contents of index.html with the code below, but replace https://abc123.sse.codesandbox.io with the URL of your own web service from the last step in Part 1.

     <!DOCTYPE html>
     <html>
       <head>
         <title>Distance Calculator</title>
       </head>
       <body>
         <h2>Enter latitude and longitude</h2>
         Place A
         <input type="text" id="latA" placeholder="Place A lat" />
         <input type="text" id="lonA" placeholder="Place A lon" />
         <hr />
         Place B
         <input type="text" id="latB" placeholder="Place B lat" />
         <input type="text" id="lonB" placeholder="Place B lon" />
         <hr />
         <input type="submit" id="submit" value="Calculate Distance (km)" />
         <br /><br />
         Distance:
         <h1 id="output">0</h1>
         <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
         <script>
           $("#submit").click(function () {
             // Read the text input boxes to get the user's coordinates, add them to the URL to request the web service
             $.getJSON(
               "https://abc123.sse.codesandbox.io",
               {
                 latA: $("#latA").val(),
                 lonA: $("#lonA").val(),
                 latB: $("#latB").val(),
                 lonB: $("#lonB").val()
               },
               // Receive the response from the web service, print the distance on the webpage
               function (data) {
                 $("#output").html(data.distance);
               }
             );
           });
         </script>
       </body>
     </html>
    

    This code is a mix of HTML and JavaScript to build a user interface. This interface is a more human-friendly way to use our web service, allowing the user to enter the latitude and longitude into a form instead of crafting a URL. The interface also returns the distance as part of the webpage text instead of the raw output {"distance": value}, like we did to test our web service in Part 1. The preview browser area will show the webpage form to calculate distance.

  4. Save index.html by clicking File > Save, or use the shortcut Ctrl+S (Cmd+S on Mac) . You might have to refresh the page to see the form.
  5. Use the same lat/lon test values from Part 1 (30,-90 and 30.45,-91.187) and click the button to submit the form. It should print the distance value on the page.

Try it

Option 1: Test and document

  1. Use Google Maps to get the latitude and longitude of two locations of your choosing, different from the New Orleans and Baton Rouge example above. Right-click the map to copy the coordinates at each place you choose.
  2. Substitute the new coordinate values into the form you made and observe the new distance value. Compare this value to the distance measured with Google Maps (right-click the map, Measure distance) to make sure it is roughly correct.
  3. At the top of your web service code, on Line 1, insert a new comment. An alternative syntax for multiline comments opens with /* and closes with */. Give the following in the comment:
    • A description of your program in one or two brief sentences. What does it do, and what are the expected input and output?
    • Your complete input URL with the coordinates you found. It should be something like:
      https://yoursandbox.sse.codesandbox.io/?latA=30&lonA=-90&latB=30.45&lonB=-91.187
    • The names of the locations you used for your coordinates (e.g., “the southwestern corner of Howe-Russell”, or “Beijing”)
    • The output distance
  4. The comment should look similar to the screenshot below.
    Screenshot of a JavaScript comment
  5. You can change your sandbox names by clicking their names at the top of the window.
    Where to change sandbox name
  6. Copy the URL to your web app sandbox (the one with the form from Part 2) to submit for this assignment.
    Sandbox URL

Option 2: Change the function

Instead of the web service calculating distance, what else could it do with lat/lon coordinates or other input? Replace the appropriate code from the assignment so it performs a different task, such as finding the midpoint between two coordinates. See https://www.movable-type.co.uk/scripts/latlong.html, or do something entirely different if you have an idea for a web service. Follow these guidelines:

  1. Change the web service sandbox to perform a different task.
  2. Change the interface webpage to allow input to and output from the new web service.
  3. Add a description to the web service code describing succinctly what the service does and the input and output you used to test if it works. See the template below.
    /*
      Description of what the web service accomplishes
      Example input:
      Example output:
    */
    

Checklist

  1. A Node.js sandbox
  2. An HTML and JavaScript (“vanilla”) sandbox.
  3. A comment in the Node.js sandbox explaining what it does, the input you tested, and the expected output.
  4. Copy the URL to the vanilla sandbox.
  5. Test your URL in an incognito window to make sure it works and shows the source code.

Submit

  1. Submit the URL to your “vanilla” web app sandbox, the one with the HTML form in index.html. The sandbox should include a working form that sends a request to your web service sandbox and prints the response on the webpage under the form. Since your web app code includes the URL to your web service, you do not need to submit the web service URL separately.

The URL to your web app sandbox should look like:
https://codesandbox.io/s/your-app-name-abc123

Note that this is different from the preview URL, which you do not need to submit.

Appendix

  1. You can save your sandbox code to a Github repository if you used your Github account to sign into CodeSandbox. Changes made in CodeSandbox will be reflected in the Github repository and vice versa. Be aware that creating a Github repository from a sandbox appears to change the sandbox’s URL.
    Sandbox URL
Top