func densityFn(cfg *Config) error { store, err := OpenStore(cfg.Store()) if err != nil { return err } defer store.Close() index, err := OpenOfferIndex(cfg.Index()) if err != nil { return err } box := makeFranceBox() shapes, err := shpdraw.LoadAndFilterShapes("shp/TM_WORLD_BORDERS-0.3.shp", box) if err != nil { return err } points, err := listPoints(store, index, nil, *densityQuery) if err != nil { return err } grid := makeMapGrid(points, box, 1000, 1000) grid = convolveGrid(grid) img := drawGrid(grid) err = drawShapes(box, shapes, img) if err != nil { return err } return writeImage(img, *densityFile) }
func web(cfg *Config) error { publicURL := *webPublicPath adminURL := *webAdminPath home, err := ioutil.ReadFile("web/home.html") if err != nil { return err } store, err := OpenStore(cfg.Store()) if err != nil { return fmt.Errorf("cannot open data store: %s", err) } defer store.Close() index, err := OpenOfferIndex(cfg.Index()) if err != nil { return fmt.Errorf("cannot open index: %s", err) } defer index.Close() templ, err := loadTemplates() if err != nil { return err } geocoder, err := NewGeocoder(cfg.GeocodingKey(), cfg.Geocoder()) if err != nil { return fmt.Errorf("cannot open geocoder: %s", err) } spatial := NewSpatialIndex() queue, err := OpenIndexQueue(cfg.Queue()) if err != nil { return err } defer queue.Close() indexer := NewIndexer(store, index, queue) defer indexer.Close() indexer.Sync() spatialIndexer := NewSpatialIndexer(store, spatial, geocoder) defer spatialIndexer.Close() spatialIndexer.Sync() geocodingHandler := NewGeocodingHandler(store, geocoder, spatial) box := makeFranceBox() shapes, err := shpdraw.LoadAndFilterShapes("shp/TM_WORLD_BORDERS-0.3.shp", box) if err != nil { return err } // Public handlers http.HandleFunc(publicURL+"/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write(home) }) jsPrefix := publicURL + "/js/" http.Handle(jsPrefix, http.StripPrefix(jsPrefix, http.FileServer(http.Dir("web/js")))) http.HandleFunc(publicURL+"/search", func(w http.ResponseWriter, r *http.Request) { handleQuery(templ, store, index, spatial, geocoder, w, r) }) http.HandleFunc(publicURL+"/density", func(w http.ResponseWriter, r *http.Request) { err := handleDensity(templ, store, index, box, w, r) if err != nil { log.Printf("error: density failed with: %s", err) } }) http.HandleFunc(publicURL+"/densitymap", func(w http.ResponseWriter, r *http.Request) { err := handleDensityMap(templ, store, index, spatial, box, shapes, w, r) if err != nil { log.Printf("error: density failed with: %s", err) } }) // Admin handlers http.HandleFunc(adminURL+"/changes", func(w http.ResponseWriter, r *http.Request) { handleChanges(store, w, r) }) http.HandleFunc(adminURL+"/sync", func(w http.ResponseWriter, r *http.Request) { if enforcePost(r, w) { return } indexer.Sync() spatialIndexer.Sync() w.Write([]byte("OK")) }) crawlingLock := sync.Mutex{} crawling := false http.HandleFunc(adminURL+"/crawl", func(w http.ResponseWriter, r *http.Request) { if enforcePost(r, w) { return } crawlingLock.Lock() defer crawlingLock.Unlock() if !crawling { crawling = true go func() { defer func() { crawlingLock.Lock() crawling = false crawlingLock.Unlock() }() err := crawl(store, 0, nil) if err != nil { log.Printf("error: crawling failed with: %s", err) return } indexer.Sync() spatialIndexer.Sync() geocodingHandler.Geocode() }() } w.Write([]byte("OK")) }) http.Handle(adminURL+"/geocode", geocodingHandler) http.HandleFunc(adminURL+"/panic", func(w http.ResponseWriter, r *http.Request) { // Evade HTTP handler recover go func() { panic("now") }() }) return http.ListenAndServe(*webHttp, nil) }