> ## Content Index
> Fetch the complete content index at: https://blog.anthea.day/llms.txt
> Use this file to discover other available public pages before exploring further.

# 歡迎來到 GIS 的世界－ Day 24：旅遊規劃小專案的 API
- URL: https://blog.anthea.day/series-2022-ithome-24/
- Published: 2022-10-07T16:19:01.000Z
- Updated: 2026-11-06T19:38:09.000Z
- Author: Anthea / 芫荽
- Tags: #Migrated-1792241843742, #Import 2026-10-17 12:57, Coding, 2022 iThome 鐵人賽：歡迎來到 GIS 的世界

處理好資料之後先來寫隻 API 取得資料吧！要進行的步驟如下：

1. Table 轉換成 Model
2. 取得資料並回傳

#### 1\. 轉換 Model

這裡和昨天進行的步驟相同：

```
dotnet ef dbcontext scaffold "Host=localhost;Database=tourism;Username=postgres;Password=0000;" Npgsql.EntityFrameworkCore.PostgreSQL -o ./Models/Db -c TourismEntity -f
```

匯入成功後會看到像這樣的資料夾：

![](https://cdn-images-1.medium.com/max/800/0*hD_Q4aeIv-nT-ZJZ.png)

要注意的是，如果你沒有先安裝好 `Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite` 就執行的話，預設是不會幫你啟用 NetTopologySuite 的，`Geometry` 類型的資料也不會被讀取並轉換喔。

因此，請在開始之前確保你的程式碼中有使用到 `UseNetTopologySuite()`：

```C#
// DbContext.cs
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseNpgsql("Host=localhost;Database=tourism;Username=postgres;Password=0000;", 
                    x => x.UseNetTopologySuite());
    }
}

// Program.cs
builder.Services.AddDbContext<TourismEntity>(options => 
    options.UseNpgsql(builder.Configuration.GetConnectionString("Db"),
        s => s.UseNetTopologySuite()));
```

#### 2\. 取得資料並回傳

基本的設定這邊就不贅述，完成之後新建一隻 API，我取名為 `ScenicSpotController`：

```C#
/// <summary> 景點 </summary>
[ApiController]
[Route("api/[controller]")]
public class ScenicSpotController : ControllerBase
{
    /// <summary> 所有景點清單 </summary>
    [HttpGet]
    [SwaggerResponse(HttpStatusCode.OK, typeof(List<ScenicSpotInfo>))]
    public IActionResult List()
    {
        var scenicSpots = _db.ScenicSpots.ToList();
        var scenicSpotInfos = scenicSpots.Select(s => new ScenicSpotInfo()
        {
            Id = s.Id,
            Name = s.Name,
            Telephone = s.Telephone ?? "",
            Address = s.Address ?? "",
            X = s.Geom.Centroid.X,
            Y = s.Geom.Centroid.Y,
            Type = s.Type ?? "未分類",
            Park = s.Park ?? "",
            Info = s.Info ?? "暫無詳細資訊",
            UpdateTime = s.UpdateTime
        }).ToList();
        return Ok(scenicSpotInfos);
    }
}

/// <summary> 景點資訊 </summary>
public class ScenicSpotInfo
{
    /// <summary> 代碼 </summary>
    public string Id { get; set; } = null!;
    
    /// <summary> 名稱 </summary>
    public string Name { get; set; } = null!;
    
    /// <summary> 電話 </summary>
    public string Telephone { get; set; } = null!;
    
    /// <summary> 地址 </summary>
    public string Address { get; set; } = null!;
    
    /// <summary> X 座標 </summary>
    public double X { get; set; }
    
    /// <summary> Y 座標 </summary>
    public double Y { get; set; }
    
    /// <summary> 景點類別 </summary>
    public string Type { get; set; } = null!;
    
    /// <summary> 停車資訊 </summary>
    public string Park { get; set; } = null!;
    
    /// <summary> 參觀資訊 </summary>
    public string Info { get; set; } = null!;
    
    /// <summary> 最後更新時間 </summary>
    public DateTime? UpdateTime { get; set; }
}
```

利用 Postman 打的結果如下：

![](https://cdn-images-1.medium.com/max/800/0*aKa781elwxwNukAk.png)