Render a GeoJSON Bike Ride with Markers and Alternating Paths via a Map API
Company: Stripe
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Onsite
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.
```hint 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.
```
#### 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`:
```json
{
"center": {"lat": 47.579, "lon": -122.31},
"width": 400,
"height": 600,
"zoom": 13
}
```
```hint 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.
```
#### 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:
| Field | Structure |
|---|---|
| `markers` | Array of objects with `color`, `label` and `coord`, where `coord` is `{"lat": ..., "lon": ...}` |
| `paths` | Array of objects with `color` and `positions`, where `positions` is an array of coordinate objects in ride order |
```hint 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.
```
#### 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
### What a Strong Answer Covers
- Correct use of the HTTP client: a JSON request body, a binary response and a status check
- Correct coordinate order throughout, verified on the first coordinate
- Segment grouping without off-by-one errors, with continuous paths and the remainder included
- Code that grows part by part in one file, checked by opening each image
- A methodical debugging approach when the service rejects a request
### 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.
Overview: 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.
Read the full Stripe Software Engineer interview experience this question came from