Katkat

Render a GeoJSON Bike Ride with Markers and Alternating Paths via a Map API

StripeSoftware Engineer · Onsite

Last updated

An API integration exercise that reads a bike ride from a GeoJSON file, posts JSON map parameters to a static map rendering service, and saves the PNG it returns. The final part adds start and end markers and draws the route in alternating colors every ten segments, testing HTTP client usage, coordinate order and off-by-one grouping.

You are given a local file, ride-simple.json, that holds a bicycle ride as GeoJSON, and a static map rendering service called staticmap. The service takes an HTTP POST whose body is a JSON object of map parameters, and it returns the rendered map as PNG image bytes. The response body is binary, not JSON. The interview environment provides the endpoint URL, which ends in /map.png; below it is written as STATICMAP_URL. Use Python and the requests package. The task has three parts, and each part extends the previous part's code in the same file.

What the input file contains:

  • The top level is a GeoJSON FeatureCollection. The ride is the geometry of features[0], which is a LineString, so the coordinate array is at features[0]["geometry"]["coordinates"].
  • GeoJSON stores each coordinate as [longitude, latitude], longitude first. staticmap expects {"lat": latitude, "lon": longitude}.
  • The file holds 495 coordinates, which form 494 line segments between consecutive coordinates. The first coordinate is [-122.2851, 47.55126], which staticmap takes as {"lat": 47.55126, "lon": -122.2851}.

Clarifying Questions

  • Is the ride always the first feature, or could the collection hold several features or other geometry types?
  • What should the program do when staticmap returns an error status?
  • Is there a limit on the request size or on the number of paths in one request?

Part 1 — Parse the ride

Read ride-simple.json, extract the coordinates of the bicycle trip, and print the first ten.

What This Part Should Cover

  • Loading the JSON and reaching the coordinate array through the nested structure
  • Reading the longitude-first order correctly
  • Printing exactly the first ten coordinates

Part 2 — Request a base map

Write a program that sends an HTTP POST request with a JSON request body to staticmap, and save the binary response image data to bikemap2.png. Open the image by hand in a web browser or an image previewer, from the File menu or the command line. Write your code in the same file as Part 1. Use the following map parameters in the POST request data; they are the same center, width, height and zoom as in the provided staticmap_example.json:

{
 "center": {"lat": 47.579, "lon": -122.31},
 "width": 400,
 "height": 600,
 "zoom": 13
}

What This Part Should Cover

  • Sending the parameters as a real JSON body with the matching content type
  • Saving the PNG bytes unchanged, in binary mode
  • Detecting an error response before writing the file

Part 3 — Draw the ride with markers and alternating paths

Draw a map of the GeoJSON ride with staticmap, using markers and paths and the coordinates in ride-simple.json:

  • Markers: a "white" marker labeled Start at the first coordinate, and a "blue" marker labeled Stripe at the last coordinate.
  • Paths: a series of contiguous paths. Draw a "blue" path through the first ten line segments between the coordinates, a "brown" path through the second ten line segments, and keep alternating blue and brown until you have used all the coordinates.

Use the same map parameters as before, save the response image data to bikemap3.png, and open the image by hand. Extend your previous solution. The request body adds two fields to the Part 2 parameters:

FieldStructure
markersArray of objects with color, label and coord, where coord is {"lat": ..., "lon": ...}
pathsArray of objects with color and positions, where positions is an array of coordinate objects in ride order

What This Part Should Cover

  • Converting every coordinate into the service's latitude and longitude object
  • Grouping by line segments, with continuity between neighbouring paths
  • Handling a final group with fewer than ten segments, and checking the counts

Hints

Hint 1

Inspect before indexing: Look at the file's nesting before you write the index path, and keep track of which number in each pair is the longitude.

Hint 2

JSON in, bytes out: Check how your HTTP client encodes a Python dict depending on which keyword argument you pass it, and which response attribute gives you the raw bytes.

Hint 3

Segments, not points: Count how many coordinates ten line segments need. Then check that your paths leave no gap where the color changes, and that the end of the ride is still drawn.

Follow-up questions

  • If the ride had a hundred thousand points and the request became too large, how would you shrink it while keeping the route's shape?
  • How would you compute the center and zoom from the ride instead of using fixed values?
  • How would you test this program without calling the live service?
  • The service answers your Part 3 request with HTTP 400. Walk through how you would find the cause.