Bốn câu hỏi điển hình khi viết ứng dụng MapBasic

Các vấn đề điển hình mà các nhà phát triển MapBasic đang gặp phải là gì ? Họ đấu tranh nhiều nhất ở đâu khi cố gắng tự động hóa một quy trình trong MapInfo Pro với một đoạn mã được mã hóa bằng MapBasic.

Có thể đã tìm thấy nhiều hơn 4 nhưng chỉ bốn điều sau đây cung cấp khá nhiều vấn đề “điển hình”.

1. Xử lý hệ thống tọa độ (Coordinate Systems)

MapInfo Pro có thể hoạt động với một số cấp độ của các hệ tọa độ hoặc các phép chiếu mà đôi khi chúng được đề cập đến.
Hệ thống tọa độ có thể khác nhau trên tất cả các cấp độ sau:

  • Một bảng MapInfo sẽ có hệ tọa độ riêng.
  • Bảng có thể được hiển thị trong cửa sổ bản đồ với hệ thống tọa độ khác với bảng.
  • MapInfo Pro có thể hoạt động với một hệ tọa độ khác với bảng và cửa sổ bản đồ.
  • và cuối cùng, một ứng dụng MapBasic có thể sử dụng một hệ tọa độ khác hay không.

Vì vậy, những gì bạn nên biết về điều này và làm thế nào bạn có thể tận dụng lợi thế này trong ứng dụng của bạn ?
Trước hết, bạn có thể đến hệ thống tọa độ được sử dụng bởi hầu hết các cấp độ này.
Đối với một bảng bạn có thể lấy mệnh đề hệ tọa độ của nó có hoặc không có giới hạn và bạn có thể lấy tên hệ thống tọa độ.

  • TableInfo(some_table_id, TAB_INFO_COORDSYS_CLAUSE)
  • TableInfo(some_table_id, TAB_INFO_COORDSYS_NAME)
  • TableInfo(some_table_id, TAB_INFO_COORDSYS_CLAUSE_WITHOUT_BOUNDS)

Đối với cửa sổ bản đồ, bạn lại có thể lấy hệ thống tọa độ, có và không có giới hạn:

  • MapperInfo(some_win_id, MAPPER_INFO_COORDSYS_CLAUSE)
  • MapperInfo(some_win_id, MAPPER_INFO_COORDSYS_CLAUSE_WITH_BOUNDS)

Đối với phiên MapInfo Pro, bạn cũng có thể truy cập hệ tọa độ hiện đang sử dụng:

  • SessionInfo(SESSION_INFO_COORDSYS_CLAUSE)

Ngoài ra còn có một số hàm để chuyển đổi sang và từ chuỗi coordsys MapInfo:

  • CoordSysStringToWKT$(wkt_string)
  • EPSGToCoordSysString$(epsg_string)
  • CoordSysStringToEPSG() hàm CoordSysStringToEPSG(epsg_string)
  • CoordSysStringToPRJ$(prj_string)

MapBasic cũng có chức năng tích hợp có thể hiển thị hộp thoại và cho phép người dùng chọn hệ tọa độ mong muốn:

  • ChooseProjection$(initial_coordsysget_bounds)

Bây giờ làm thế nào để bạn chỉ định một hệ tọa độ, ví dụ trước khi trích xuất tọa độ từ một đối tượng không gian hoặc trước khi tạo một đối tượng không gian từ tọa độ ? Câu trả lời là sử dụng câu lệnh Set CoordSys.

Lệnh này sẽ thiết lập hệ tọa độ của phiên hiện tại. Phiên trong hầu hết các trường hợp sẽ là ứng dụng MapBasic của bạn, nhưng nó cũng có thể là phiên MapInfo Pro đang chạy nếu câu lệnh được sử dụng trong phiên đó, ví dụ thông qua cửa sổ MapBasic.

Điều thú vị về câu lệnh Set Coordsys, hoặc trên thực tế là mệnh đề Coordsys, là bạn không cần chỉ định rõ ràng một hệ tọa độ; bạn có thể tham khảo hệ thống tọa độ của một mục hiện có trong MapInfo Pro, đó là bản đồ, bảng hoặc thậm chí chính phiên làm việc của nó.

Trong hầu hết các trường hợp, bạn sẽ tham khảo bảng hoặc cửa sổ bản đồ, tùy thuộc vào những gì bạn đang làm. Vì vậy, đây là cách thiết lập hệ tọa độ bằng cách sử dụng một mục hiện có:

  • Set CoordSys Table some_table_id
  • Set CoordSys Window some_win_id

Nếu bạn không chỉ định hệ tọa độ, bạn sẽ sử dụng Kinh độ/Vĩ độ (Latitude/Longitude) mặc định – hay đó là Vĩ độ/Kinh độ (Latitude/Longitude) ? – hệ tọa độ.

2. Duyệt/Vòng lặp bảng

Một trong những điều thường được sử dụng trong MapBasic là lặp qua bảng để đọc các giá trị từ bảng và sau đó xử lý hoặc sửa đổi các giá trị này.
MapBasic có một số phương thức lặp:

  • Do Until … Loop
  • Do While … Loop
  • While … Wend
  • For … Next

Tuy nhiên, khi nói về việc lặp một bảng: Do Until … Loop. Bạn cũng có thể sử dụng Do While … LoopWhile … Wend. Nhưng tôi sẽ khuyên bạn nên tránh xa For … Next.
Bây giờ bạn cũng cần một vài câu lệnh khác khi lặp một bảng:

  • Fetch First From some_table_name
  • Fetch Next From some_table_name
  • EOT(some_table_name)

Hãy thử kết hợp tất cả những thứ này lại với nhau:

Bốn câu hỏi điển hình khi viết ứng dụng MapBasic

Trong ví dụ trên, lặp bảng có tên MY_TABLE. Đối với mỗi bản ghi tôi đọc RowID, cột động ẩn có tên OBJ.
Và tôi đặt ứng dụng của mình sử dụng cùng hệ tọa độ với bảng.

Bây giờ vòng lặp này không thực sự làm bất cứ điều gì thông minh. Tôi sẽ cần thêm logic của mình ngay trước câu lệnh Fetch Next From. Tôi sẽ giải thích lý do tại sao bạn không nên sử dụng vòng lặp For … Next khi làm việc với bảng. Vấn đề không phải là vòng lặp nhiều, mà nhiều người có xu hướng kết hợp vòng lặp này với một câu lệnh Fetch khác nhau; Fetch Rec nRec From

Bốn câu hỏi điển hình khi viết ứng dụng MapBasic

Cấu trúc trên có thể có vấn đề ! Câu lệnh Fetch này sẽ đặt con trỏ bảng ở một hàng cụ thể trong bảng, trong hầu hết các trường hợp đều ổn. Nhưng nó có một nhược điểm: nó sẽ thất bại nếu hàng cụ thể đã bị xóa.
Fetch Next From sẽ bỏ qua các bản ghi bị xóa trong vòng lặp.

3. Làm việc với biến Alias

Miễn là ứng dụng của bạn đang sử dụng tên bảng và cột được mã hóa cứng, ví dụ trên sẽ hoạt động khá tốt cho bạn. Nhưng ngay khi bạn xử lý với tên bảng và cột động, bạn sẽ gặp rắc rối.
Vậy làm thế nào để bạn đọc các giá trị từ một bảng trong đó tên bảng và/hoặc cột là động và được lưu trữ trong một biến ? Đó là biến Alias ​.
Nếu bạn xem hệ thống Trợ giúp MapBasic, bạn sẽ tìm thấy mô tả này cho biến Alias.

Tên cột.
Một biến Alias ​​có thể được sử dụng để trỏ đến sự kết hợp của tên bảng và tên cột. Bạn sẽ thường sử dụng loại biến này cho các kết hợp tên bảng và/hoặc tên cột động, nhưng bạn cũng có thể sử dụng nó cho các tên mã cứng.
Thông thường, bạn đề cập đến sự kết hợp tên bảng và cột bằng cách ghép hai điểm với một điểm (.), Ví dụ: MY_TABLE.OBJ. Nhưng nếu chỉ một trong số này, hoặc bảng hoặc tên cột hoặc cả hai, là một biến, bạn không thể sử dụng cấu trúc cơ bản này. Bạn cần dùng biến Alias.
Có ba bước trong việc sử dụng biến Bí danh:

  1. Khai báo biến: Dim aRowID As Alias
  2. Gán biến: aRowID = sTab & “.ROWID”
  3. Lấy giá trị biến: nRowID = aRowID

Đây là một ví dụ đầy đủ hơn xây dựng trên ví dụ vòng lặp trước:

Bốn câu hỏi điển hình khi viết ứng dụng MapBasic

Lưu ý rằng: đặt biến bên ngoài vòng lặp và sử dụng nó trong vòng lặp. Nó sẽ trả về giá trị từ hàng hiện tại trong bảng: đó là hàng mà con trỏ bảng hiện đang trỏ tới.

4. Cập nhật các bản ghi trong khi lặp một bảng

Vấn đề cuối cùng tôi sẽ giải thích một chút trong bài viết là làm thế nào để cập nhật các bản ghi trong một vòng lặp. Từ các ví dụ trên, bây giờ bạn biết cách đọc dữ liệu từ bảng thành các biến để có thể phân tích hoặc sửa đổi dữ liệu này. Chỉ cần nhớ rằng dữ liệu hiện tại trong biến của bạn không còn được kết nối với dữ liệu trong bảng của bạn.
Điều này cũng có nghĩa là bạn không thay đổi bất cứ điều gì trong bảng của mình chỉ bằng cách sửa đổi giá trị trong biến của bạn. Nếu bạn muốn thay đổi dữ liệu trong bảng, bạn cần đẩy dữ liệu đã sửa đổi trong biến của mình trở lại một cột trong bảng. Cho rằng bạn sẽ cần một câu lệnh SQL: lệnh Update.

  • Update some_table_name Set some_column_name = some_expr
    [, some_column_name = some_expr, …] 
    Where RowID = rowid_num ]

Từ cú pháp trên, chúng ta có thể thấy rằng bạn có thể cập nhật nhiều cột trong một bảng và bạn có thể cập nhật tất cả các hàng trong bảng hoặc chỉ một hàng được chỉ định bằng điều kiện RowID.
Chúng tôi sẽ sử dụng điều kiện RowID trong ví dụ của chúng tôi và khi cập nhật bảng trong một vòng lặp, bạn hầu như sẽ luôn sử dụng điều kiện đó để giới hạn câu lệnh Update chỉ ảnh hưởng đến hàng hiện tại.
Nếu chúng ta áp dụng điều này cho ví dụ trên, nó sẽ trông như thế này:

Bốn câu hỏi điển hình khi viết ứng dụng MapBasic

Trong ví dụ này, tôi thay đổi Pen trên đối tượng không gian trong biến oFeature của tôi và sau đó tôi đẩy đối tượng không gian đã thay đổi trở lại hàng hiện tại trong bảng của mình.
Khi tôi đã lặp qua tất cả các bản ghi, tôi lưu các thay đổi vào bảng của mình bằng cách sử dụng câu lệnh Commit Table.

Tóm lược

Trên đây là 4 câu hỏi điển hình mà bạn có thể gặp phải khi xây dựng ứng dụng MapBasic (đầu tiên) của mình. Nếu bạn đã gặp phải, đừng lo lắng – tất cả chúng ta đều đã trải qua những điều này.
Nếu bạn đã xây dựng ứng dụng MapBasic đầu tiên của mình, bạn có thể gặp một số vấn đề “điển hình” khác mà bạn đã gặp phải. Hãy chia sẻ những điều này thông qua phần Bình luận bên dưới. Tôi có thể chọn một vài trong số này cho một bài viết trong tương lai.

Bình luận bằng Facebook Comments