Skip to content

Commit

Permalink
osm-zoning edit button exists not working to update yet
Browse files Browse the repository at this point in the history
  • Loading branch information
baditaflorin committed Jun 14, 2024
1 parent bde70b2 commit b22cfa7
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 37 deletions.
26 changes: 9 additions & 17 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 49 additions & 1 deletion osm-zoning/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func HandleData(cfg *config.Config) http.HandlerFunc {
}

// Log the data that will be sent
log.Printf("Serving data: %s", data)
//log.Printf("Serving data: %s", data)

w.Write(data)
}
Expand Down Expand Up @@ -102,3 +102,51 @@ func HandleAddWay(cfg *config.Config) http.HandlerFunc {
fmt.Fprintf(w, "Way created successfully")
}
}

func HandleUpdateWay(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}

var way struct {
ID int64 `json:"id"`
Tags map[string]string `json:"tags"`
}
if err := json.NewDecoder(r.Body).Decode(&way); err != nil {
http.Error(w, "Failed to parse request body: "+err.Error(), http.StatusBadRequest)
return
}

session, _ := oauth.Store.Get(r, "session-name")
token, ok := session.Values["oauth-token"].(*oauth2.Token)
if !ok {
http.Error(w, "You are not authenticated. Please log in to update this road.", http.StatusUnauthorized)
log.Println("No OAuth token found in session")
return
}
log.Printf("Retrieved OAuth token from session: %v", token)

oauth.UpdateWayTags(cfg, token, way.ID, way.Tags)

fmt.Fprintf(w, "Way updated successfully")
}
}

func HandleSaveChanges(cfg *config.Config) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
session, _ := oauth.Store.Get(r, "session-name")
token, ok := session.Values["oauth-token"].(*oauth2.Token)
if !ok {
http.Error(w, "You are not authenticated. Please log in to save changes.", http.StatusUnauthorized)
log.Println("No OAuth token found in session")
return
}
log.Printf("Retrieved OAuth token from session: %v", token)

oauth.SaveChanges(cfg, token)

fmt.Fprintf(w, "Changes saved successfully")
}
}
2 changes: 2 additions & 0 deletions osm-zoning/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func main() {
http.HandleFunc("/login", handlers.HandleLogin(cfg))
http.HandleFunc("/callback", handlers.HandleCallback(cfg))
http.HandleFunc("/addway", handlers.HandleAddWay(cfg))
http.HandleFunc("/updateway", handlers.HandleUpdateWay(cfg)) // New handler
http.HandleFunc("/savechanges", handlers.HandleSaveChanges(cfg)) // New handler

fmt.Println("Server starting on :7777...")
err := http.ListenAndServe(":7777", nil)
Expand Down
113 changes: 101 additions & 12 deletions osm-zoning/oauth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"net/http"
"osm-zoning/config"
"osm-zoning/osm"
"osm-zoning/utils"

"github.com/gorilla/sessions"
Expand Down Expand Up @@ -36,18 +37,6 @@ func Init(cfg *config.Config) {
}
}

func createChangesetRequest(cfg *config.Config, token *oauth2.Token) (*http.Request, error) {
xmlData := fmt.Sprintf(`
<osm>
<changeset>
<tag k="created_by" v="%s"/>
<tag k="comment" v="%s"/>
</changeset>
</osm>`, cfg.CreatedBy, cfg.ChangesetComment)

return utils.CreateRequest("PUT", "https://api.openstreetmap.org/api/0.6/changeset/create", "text/xml", []byte(xmlData))
}

func createWayRequest(changesetID int, nodes []int64, tags map[string]string) (*http.Request, error) {
var tagsXML string
for key, value := range tags {
Expand All @@ -70,6 +59,75 @@ func createWayRequest(changesetID int, nodes []int64, tags map[string]string) (*
return utils.CreateRequest("PUT", "https://api.openstreetmap.org/api/0.6/way/create", "text/xml", []byte(xmlData))
}

func updateWayRequest(changesetID int, wayID int64, tags map[string]string) (*http.Request, error) {
var tagsXML string
for key, value := range tags {
tagsXML += fmt.Sprintf(`<tag k="%s" v="%s"/>`, key, value)
}

xmlData := fmt.Sprintf(`
<osm>
<way id="%d" changeset="%d">
%s
</way>
</osm>`, wayID, changesetID, tagsXML)

return utils.CreateRequest("PUT", fmt.Sprintf("https://api.openstreetmap.org/api/0.6/way/%d", wayID), "text/xml", []byte(xmlData))
}

func UpdateWayTags(cfg *config.Config, token *oauth2.Token, wayID int64, tags map[string]string) {
changesetID, err := CreateChangeset(cfg, token)
if err != nil {
log.Fatalf("Failed to create changeset: %v", err)
}

client := Oauth2Config.Client(oauth2.NoContext, token)
req, err := updateWayRequest(changesetID, wayID, tags)
if err != nil {
log.Fatalf("Failed to create request: %v", err)
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

_, err = utils.DoRequest(client, req)
if err != nil {
log.Fatalf("Failed to update way: %v", err)
}

fmt.Printf("Way updated successfully\n")

if err := CloseChangeset(token, changesetID); err != nil {
log.Fatalf("Failed to close changeset: %v", err)
}
}

func createWayUpdateRequest(changesetID int, wayID int64, tags map[string]string) (*http.Request, error) {
var tagsXML string
for key, value := range tags {
tagsXML += fmt.Sprintf(`<tag k="%s" v="%s"/>`, key, value)
}

xmlData := fmt.Sprintf(`
<osm>
<way id="%d" changeset="%d">
%s
</way>
</osm>`, wayID, changesetID, tagsXML)

return utils.CreateRequest("PUT", fmt.Sprintf("https://api.openstreetmap.org/api/0.6/way/%d", wayID), "text/xml", []byte(xmlData))
}

func createChangesetRequest(cfg *config.Config, token *oauth2.Token) (*http.Request, error) {
xmlData := fmt.Sprintf(`
<osm>
<changeset>
<tag k="created_by" v="%s"/>
<tag k="comment" v="%s"/>
</changeset>
</osm>`, cfg.CreatedBy, cfg.ChangesetComment)

return utils.CreateRequest("PUT", "https://api.openstreetmap.org/api/0.6/changeset/create", "text/xml", []byte(xmlData))
}

func CreateChangeset(cfg *config.Config, token *oauth2.Token) (int, error) {
client := Oauth2Config.Client(oauth2.NoContext, token)
req, err := createChangesetRequest(cfg, token)
Expand Down Expand Up @@ -127,3 +185,34 @@ func CreateMapWay(cfg *config.Config, token *oauth2.Token, nodes []int64, tags m
log.Fatalf("Failed to close changeset: %v", err)
}
}

func SaveChanges(cfg *config.Config, token *oauth2.Token) {
changesetID, err := CreateChangeset(cfg, token)
if err != nil {
log.Fatalf("Failed to create changeset: %v", err)
}

client := Oauth2Config.Client(oauth2.NoContext, token)
pendingChanges := osm.GetPendingChanges()

for wayID, tags := range pendingChanges {
req, err := createWayUpdateRequest(changesetID, wayID, tags)
if err != nil {
log.Fatalf("Failed to create request: %v", err)
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

_, err = utils.DoRequest(client, req)
if err != nil {
log.Fatalf("Failed to update way: %v", err)
}

fmt.Printf("Way %d updated successfully\n", wayID)
}

if err := CloseChangeset(token, changesetID); err != nil {
log.Fatalf("Failed to close changeset: %v", err)
}

osm.ClearPendingChanges()
}
32 changes: 30 additions & 2 deletions osm-zoning/osm/osm.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"osm-zoning/config"
"strings"
"sync"
)

type Data struct {
Expand All @@ -28,9 +29,14 @@ type Geometry struct {

var Ways Data

var (
pendingChanges = make(map[int64]map[string]string)
mu sync.Mutex
)

func FetchWays(cfg *config.Config, bbox string) {
url := "https://overpass-api.de/api/interpreter"
query := fmt.Sprintf(`[out:json];way["highway"](%s);out ids geom;`, bbox)
query := fmt.Sprintf(`[out:json];way["highway"](%s);out geom;`, bbox)

log.Printf("Fetching data with query: %s", query) // Log the query

Expand All @@ -44,7 +50,7 @@ func FetchWays(cfg *config.Config, bbox string) {
log.Fatalf("Error reading response from Overpass API: %s", err)
}

log.Printf("Overpass API response: %s", body) // Log the response
//log.Printf("Overpass API response: %s", body) // Log the response

var tempWays Data
err = json.Unmarshal(body, &tempWays)
Expand All @@ -56,3 +62,25 @@ func FetchWays(cfg *config.Config, bbox string) {

Ways.Elements = tempWays.Elements
}

func AddPendingChange(wayID int64, tags map[string]string) {
mu.Lock()
defer mu.Unlock()
pendingChanges[wayID] = tags
}

func GetPendingChanges() map[int64]map[string]string {
mu.Lock()
defer mu.Unlock()
changes := make(map[int64]map[string]string)
for k, v := range pendingChanges {
changes[k] = v
}
return changes
}

func ClearPendingChanges() {
mu.Lock()
defer mu.Unlock()
pendingChanges = make(map[int64]map[string]string)
}
1 change: 1 addition & 0 deletions osm-zoning/static/map.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
<div id="login">
<a href="/login">Log in with OpenStreetMap</a>
</div>
<button id="saveChangesButton">Save Changes</button>
</body>
</html>
Loading

0 comments on commit b22cfa7

Please sign in to comment.