Skip to content

Instantly share code, notes, and snippets.

@spencer-p
Last active November 14, 2017 00:49
Show Gist options
  • Save spencer-p/834f4c07712dd1c37aca14a84f7edb2a to your computer and use it in GitHub Desktop.
Save spencer-p/834f4c07712dd1c37aca14a84f7edb2a to your computer and use it in GitHub Desktop.
traffic lib example

Early Traffic Simulator Example

This is an early example of how we might interface with the simulator libary I am building. Nothing about the library is finalized, however, so be aware that much is likely to change.

Most interfaces and such will likely be made private. The Edge interface may gain more methods but probably won't lose any.

This program exists more for testing and edification than actually usage.

Getting the thing

First, download the preliminary traffic simulation:

go get github.com/spencer-p/traffic

This will download my simulation library (as it stands) to your $GOPATH/src/github.com/spencer-p/traffic.

Then save these two .go files in another project directory to compile and use them.

Usage

If you misuse it it will tell you what you did wrong, but here's the usage:

Usage of ./sim:
  -destination string
    	Location to go to
  -directed
    	Count edges as directed/one way
  -input string
    	GeoJSON to parse
  -start string
    	Location to start at

The input json I ran this against is from the LA City GeoHub: Intersections (APIs -> GeoJSON).

Issues

  1. The intersections are edges and streets are vertices. This is the opposite of how it should be.
  2. Every edge has equal weight. (shortest path is actually fewest intersections).
package main
// Defines the structs and their methods, for parsing data and using it in the sim.
type FeatureCollection struct {
Features []Feature
}
type Feature struct {
Properties PropertyList
}
type PropertyList struct {
From_St, To_St string
Speedlimit int
}
func (f Feature) Weight() float64 {
return 1
}
func (f Feature) From() string {
return f.Properties.From_St
}
func (f Feature) To() string {
return f.Properties.To_St
}
func (f *Feature) Reverse() *Feature {
return &Feature{Properties: PropertyList{From_St: f.Properties.To_St, To_St: f.Properties.From_St}}
}
func (f *Feature) IsReal() bool {
return f.Properties.From_St != "" && f.Properties.To_St != "" && f.Properties.From_St != "D/E" && f.Properties.To_St != "D/E"
}
package main
import (
"encoding/json"
"flag"
"log"
"os"
tf "github.com/spencer-p/traffic"
)
func main() {
// Parse command line arguments
inputFileName := flag.String("input", "", "GeoJSON to parse")
start := flag.String("start", "", "Location to start at")
destination := flag.String("destination", "", "Location to go to")
directed := flag.Bool("directed", false, "Count edges as directed/one way")
flag.Parse()
// Check input is valid
if *inputFileName == "" || *start == "" || *destination == "" {
flag.Usage()
os.Exit(1)
}
// Open input file
input, err := os.Open(*inputFileName)
if err != nil {
log.Fatal(err)
}
// Decode the streets into a FeatureCollection
dec := json.NewDecoder(input)
var streets FeatureCollection
err = dec.Decode(&streets)
if err != nil {
log.Fatal(err)
}
log.Println("Parsed", len(streets.Features), "streets")
// Create the graph
graph := tf.NewGraph()
for _, edge := range streets.Features {
if edge.IsReal() {
graph.AddEdge(edge)
if !*directed {
graph.AddEdge(edge.Reverse())
}
}
}
// Get the shorteset path using Dijkstra's alogrithm
path, err := graph.Path(*start, *destination)
if err != nil {
log.Fatal(err)
}
log.Println("Found shortest path:")
log.Println(path)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment