DEV Community

FTwex
FTwex

Posted on

Visualize points using Geojson

In this part we will write code to visualise paths.

It's easy to copy/paste one or two points, but when we're talking about a path with thousands of points, we need some tools to help us.

Code

Setup

$ cargo add geojson
Enter fullscreen mode Exit fullscreen mode

Geojson is a Rust crate that will help us to create a geojson object.

Easier to visualise multiple points or geometries.

Code

In src/main.ts we start with our previous two points and we calculate intermediate points using two different formulae, one to simulate a straight line and one to calculate the sortest path.

Here we use Haversine formulae that are less accurate but faster.

use geo::Densify;
use geo::DensifyHaversine;
use geo::{Line, Point};

use geojson::{Feature, FeatureCollection, Geometry, JsonObject, JsonValue, Value};

fn main() {
    let my_location = Point::new(2.341882700675668, 48.877569833869785);
    let my_friend_location = Point::new(-122.4374290818876, 37.75484272253979);

    // Straight path
    let path = Line::new(my_location, my_friend_location);
    let straight_path = path.densify(2.0);

    // Shortest path
    let max_distance = 70000.0; // Maximum distance between two points (a segment)
    let shortest_path = path.densify_haversine(max_distance);
Enter fullscreen mode Exit fullscreen mode

Now that we have our points we can build the geojson to visualize them.

A GeoJson object is like this.
It can contain one or more features, which contain geometry and properties.

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}

We create a set of properties for each path to display them with a different name and colour.

let mut properties = JsonObject::new();
properties.insert(String::from("stroke-width"), JsonValue::from("2"));
properties.insert(String::from("stroke-opacity"), JsonValue::from("1"));

let mut straight_path_properties = properties.clone();
straight_path_properties.insert(String::from("name"), JsonValue::from("Straight path"));
straight_path_properties.insert(String::from("stroke"), JsonValue::from("#ff2600"));

let mut shortest_path_properties = properties.clone();
shortest_path_properties.insert(String::from("name"), JsonValue::from("Shortest path"));
shortest_path_properties.insert(String::from("stroke"), JsonValue::from("#000000"));
Enter fullscreen mode Exit fullscreen mode

Now we can create geometries and features, and then pack them into a FeatureCollection.

let straight_path_geometry = Geometry::new(Value::from(&straight_path));
let shortest_path_geometry = Geometry::new(Value::from(&shortest_path));

let geojson = FeatureCollection {
    bbox: None,
    features: vec![
        Feature {
            bbox: None,
            geometry: Some(straight_path_geometry),
            id: None,
            properties: Some(straight_path_properties),
            foreign_members: None,
        },
        Feature {
            bbox: None,
            geometry: Some(shortest_path_geometry),
            id: None,
            properties: Some(shortest_path_properties),
            foreign_members: None,
        },
    ],
    foreign_members: None,
};
Enter fullscreen mode Exit fullscreen mode

And one more line to display the result in the console.

println!("The geojson to copy:\n{0}", geojson.to_string());
Enter fullscreen mode Exit fullscreen mode
$ cargo run
   Compiling Halfway v0.1.0 (/home/halfway)
    Finished dev [unoptimized + debuginfo] target(s) in 0.46s
     Running `target/debug/halfway`
{"features":[{"geometry":{"coordinates":[[2.341882700675668,48.877569833869785],  
...  
[-122.4374290818876,37.75484272253979]],"type":"LineString"},"properties":{"name":"Shortest path","stroke":"#000000","stroke-opacity":"1","stroke-width":"2"},"type":"Feature"}],"type":"FeatureCollection"}
Enter fullscreen mode Exit fullscreen mode

You can use a tool like geojson.io to visualise the content.

Just paste the content from console output (after The geojson to copy:)
Geojson.io

And you should have something like this (you can switch between Globe and Mercator views using the buttons at the bottom right).
Path on a mercator map

Code more

In the next part we will try to invite new friends in our trip.

ACI image

ACI.dev: The Only MCP Server Your AI Agents Need

ACI.dev’s open-source tool-use platform and Unified MCP Server turns 600+ functions into two simple MCP tools on one server—search and execute. Comes with multi-tenant auth and natural-language permission scopes. 100% open-source under Apache 2.0.

Star our GitHub!

Top comments (0)

Tiger Data image

🐯 🚀 Timescale is now TigerData: Building the Modern PostgreSQL for the Analytical and Agentic Era

We’ve quietly evolved from a time-series database into the modern PostgreSQL for today’s and tomorrow’s computing, built for performance, scale, and the agentic future.

So we’re changing our name: from Timescale to TigerData. Not to change who we are, but to reflect who we’ve become. TigerData is bold, fast, and built to power the next era of software.

Read more

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay