Exemplo n.º 1
0
func geocodeBuildings(c *maps.Client) error {
	buildings, err := models.LoadMapData()
	if err != nil {
		return err
	}
	for _, b := range buildings {
		if b.Position != nil || len(b.Address) == 0 {
			continue
		}
		log.Printf("geocoding %s", b.Name)
		req := &maps.GeocodingRequest{
			Address: b.Address,
			Region:  "ca",
		}
		result, err := c.Geocode(context.TODO(), req)
		if err != nil {
			return err
		}
		if len(result) == 0 {
			continue
		}
		loc := result[0].Geometry.Location
		b.Position = &models.LatLng{
			Lat: loc.Lat,
			Lng: loc.Lng,
		}
		time.Sleep(100 * time.Millisecond)
		if err := models.SaveMapData(buildings); err != nil {
			return err
		}
	}
	for _, b := range buildings {
		if len(b.Floors) == 0 {
			continue
		}
		var lat, lng float64
		c := float64(len(b.Floors) * 2)
		for _, f := range b.Floors {
			lat += f.Coords.North
			lat += f.Coords.South
			lng += f.Coords.West
			lng += f.Coords.East
			for _, r := range f.Rooms {
				lat += r.Position.Lat
				lng += r.Position.Lng
				c += 1
			}
		}
		b.Position.Lat = lat / c
		b.Position.Lng = lng / c
	}
	return models.SaveMapData(buildings)
}
Exemplo n.º 2
0
Arquivo: main.go Projeto: d4l3k/campus
// saveBuilding saves the changes made to a building.
func (s *Server) saveBuilding(w http.ResponseWriter, r *auth.AuthenticatedRequest) {
	b := &models.Building{}
	if err := json.NewDecoder(r.Body).Decode(b); err != nil {
		http.Error(w, err.Error(), 400)
		return
	}
	for i, b2 := range s.buildings {
		if b2.SIS != b.SIS {
			continue
		}
		for _, f := range b.Floors {
			dx, dy := newDimentions(f.Coords.DLng(), f.Coords.DLat(), f.Rotation)
			affine := graphics.I.Rotate(f.Rotation)
			log.Printf("DX %f DY %f", dx, dy)
			for _, r := range f.Rooms {
				if r.RelPosition == nil {
					continue
				}
				rotated := affine.Mul(graphics.Affine{
					(r.RelPosition.Lng - 0.5) * f.Coords.DLng(), 0, 0,
					(1 - r.RelPosition.Lat - 0.5) * f.Coords.DLat(), 0, 0,
					1, 1, 1,
				})
				px := (rotated[0]/dx + 0.5)
				py := (rotated[3]/dy + 0.5)

				log.Printf("(%f, %f) -> (%f, %f)", r.RelPosition.Lng, r.RelPosition.Lat, px, py)

				lat := (py)*f.Coords.DLat() + f.Coords.South
				lng := (px)*f.Coords.DLng() + f.Coords.West
				r.Position = &models.LatLng{
					Lat: lat,
					Lng: lng,
				}
			}
		}
		s.buildings[i] = b
		if err := models.SaveMapData(s.buildings); err != nil {
			http.Error(w, err.Error(), 500)
			return
		}
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode(s.buildings[i])
		return
	}
	http.Error(w, "building SIS not found", 404)
}
Exemplo n.º 3
0
func scrapeBuildings() error {
	buildings, err := models.LoadMapData()
	if err != nil {
		return err
	}
	doc, err := goquery.NewDocument("http://www.maps.ubc.ca/PROD/buildingsListAll.php")
	if err != nil {
		return err
	}

	detailsDup := make(map[string]bool)
	var details []string
	doc.Find("a[href]").Each(func(i int, sel *goquery.Selection) {
		href, exists := sel.Attr("href")
		if !exists || !strings.HasPrefix(href, "index_detail.php?") || detailsDup[href] {
			return
		}
		detailsDup[href] = true
		details = append(details, href)
	})
	relChan := make(chan string, 1)
	defer close(relChan)
	outChan := make(chan *models.Building, 1)
	defer close(outChan)
	for _ = range make([]interface{}, 20) {
		go fetchDetails(relChan, outChan)
	}
	go func() {
		for _, rel := range details {
			relChan <- rel
		}
	}()
	var scrapedBuildings []*models.Building
	for b := range outChan {
		if len(b.SIS) == 0 {
			b.SIS = customSIS[b.Name]
		}
		scrapedBuildings = append(scrapedBuildings, b)
		if len(scrapedBuildings) == len(details) {
			break
		}
	}
	buildingIndex := make(map[string]*models.Building)
	for _, building := range buildings {
		buildingIndex[building.SIS] = building
	}
	for _, b := range scrapedBuildings {
		if len(b.SIS) == 0 {
			continue
		}
		if b2, ok := buildingIndex[b.SIS]; ok {
			b2.Address = b.Address
			b2.Image = b.Image
			b2.Description = b.Description
			continue
		}
		buildingIndex[b.SIS] = b
		buildings = append(buildings, b)
	}
	return models.SaveMapData(buildings)
}