Giải pháp triển khai

Một phần của tài liệu Một số thuật toán khái quát hóa bản đồ và ứng dụng (Trang 61)

4.2.1. Công nghệ GIS

Hiện nay có rất nhiều công nghệ lõi GIS phục vụ phát triển, xây dựng các ứng dụng GIS. Có thể chia ra làm hai mảng thƣơng mại: ArcGIS Engine, MapX, MapSuite,... và mã nguồn mở: MapWindows, SharpMap, DotSpatial,...

Phần mềm đƣợc xây dựng sử dụng bộ thƣ viện mã nguồn mở DotSpatial. Đây là bộ thƣ viện hỗ trợ khá nhiều tính năng đồ họa, cho phép thể hiện tốt các đối tƣợng không gian, lực nét, nhãn và ký hiệu bản đồ.

DotSpatial cung cấp môi trƣờng lập trình thuận tiện cho các nhà phát triển ứng dụng có thể xây dựng và mở rộng các ứng dụng GIS.

DotSpatial cung cấp các thành phần cơ bản: - Cung cấp các dịch vụ truy xuất dữ liệu.

- Cung cấp các chức năng biên tập, trình bày bản đồ. - Cung cấp các control cơ bản: MapControl, Legend,... - Cung cấp các API cho việc mở rộng, xây dựng ứng dụng.

57

4.2.2. Ngôn ngữ lập trình

Sử dụng ngôn ngữ lập trình C# .NET. Đây là một ngôn ngữ rất đơn giản, với khoảng 80 từ khoá và hơn mƣời kiểu dữ liệu dựng sẵn, nhƣng C# có tính diễn đạt cao. C# hỗ trợ lập trình có cấu trúc, hƣớng đối tƣợng, hƣớng thành phần (component oriented).

Trọng tâm của ngôn ngữ hƣớng đối tƣợng là lớp. Lớp định nghĩa kiểu dữ liệu mới, cho phép mở rộng ngôn ngữ theo hƣớng cần giải quyết. C# có những từ khoá dành cho việc khai báo lớp, phƣơng thức, thuộc tính (property) mới. C# hỗ trợ đầy đủ khái niệm trụ cột trong lập trình hƣớng đối tƣợng: đóng gói, thừa kế, đa hình.

Định nghĩa lớp trong C# không đòi hỏi tách rời tập tin tiêu đề với tập tin cài đặt nhƣ C++. Hơn thế, C# hỗ trợ kiểu sƣu liệu mới, cho phép sƣu liệu trực tiếp trong tập tin mã nguồn. Đến khi biên dịch sẽ tạo tập tin sƣu liệu theo định dạng XML.

C# hỗ trợ khái niệm giao diện, interfaces (tƣơng tự Java). Một lớp chỉ có thể kế thừa duy nhất một lớp cha nhƣng có thế cài đặt nhiều giao diện.

C# có kiểu cấu trúc, struct (không giống C++). Cấu trúc là kiểu hạng nhẹ và bị giới hạn.Cấu trúc không thể thừa kế lớp hay đƣợc kế thừa nhƣng có thể cài đặt giao diện.

C# cung cấp những đặc trƣng lập trình hƣớng thành phần nhƣ property, sự kiện và dẫn hƣớng khai báo (đƣợc gọi là attribute). Lập trình hƣớng component đƣợc hỗ trợ bởi CLR thông qua siêu dữ liệu (metadata). Siêu dữ liệu mô tả các lớp bao gồm các phƣơng thức và thuộc tính, các thông tin bảo mật ….

Assembly là một tập hợp các tập tin mà theo cách nhìn của lập trình viên là các thƣ viện liên kết động (DLL) hay tập tin thực thi (EXE). Trong .NET một assembly là một đơn vị của việc tái sử dụng, xác định phiên bản, bảo mật, và phân phối. CLR cung cấp một số các lớp để thao tác với assembly.

C# cũng cho truy cập trực tiếp bộ nhớ dùng con trỏ kiểu C++, nhƣng vùng mã đó đƣợc xem nhƣ không an toàn. CLR sẽ không thực thi việc thu dọn rác tự động các đối tƣợng đƣợc tham chiếu bởi con trỏ cho đến khi lập trình viên tự giải phóng.

58

4.2.3. Tổ chức triển khai

Phần mềm đƣợc xây dựng phát triển trên môi trƣờng Microsoft Visual Studio 2010.

- Thƣ mục Core lƣu trữ các project lõi của DotSpatial, cung cấp các chức năng, API phục vụ xây dựng chƣơng trình khái quá hóa.

- Thƣ mục MapGeneralization chứa project chính của chƣơng trình khái quá hóa. - Thƣ mục Plugins chứa các project đƣợc xây dựng cung cấp, mở rộng các chức năng cho chƣơng trình chính.

Project MapGeneralizationPlugin

Cài đặt triển khai các chức năng khái quát hóa. Sử dụng các thuật toán đơn giản hóa đƣờng cong.

59

Cài đặt thuật toán Douglas- Peucker

+ Thuật toán đƣợc cài đặt trong file clsDouglasPeucker.cs

/// <summary>

/// Khái quát hóa đối tượng dạng đường

/// Sử dụng thuật toán Douglas-Peucker

/// </summary>

public class DouglasPeuckerSimplifyLine

{

//Khai báo các biến toàn cục

private readonly IList<Point> _pts; private bool[] _usePoint;

private double _tolerance;

private readonly LineSegment _seg = new LineSegment(); /// <summary>

/// Đơn giải hóa đường

/// </summary>

/// <param name="pts">Danh sách các điểm</param>

/// <param name="distanceTolerance">Dung sai</param>

/// <returns>Trả lại kết quả là tập điểm được giữ lại</returns>

public static IList<Point> Simplify(IList<Point> pts, double distanceTolerance)

{

DouglasPeuckerSimplifyLine simplify = new

DouglasPeuckerSimplifyLine(pts); simplify._tolerance = distanceTolerance; return simplify.Simplify(); } /// <summary> /// Hàm khởi tạo /// </summary>

/// <param name="pts">Danh sách điểm</param>

private DouglasPeuckerSimplifyLine(IList<Point> pts) {

_pts = pts; }

/// <summary>

/// Đơn giản hóa tập điểm _pts

/// </summary>

/// <returns></returns>

private Point[] Simplify() {

//Khởi tạo mảng bool với số phần tử bằng số lượng điểm của //đường cần giản lược

_usePoint = new bool[_pts.Count];

//Gán giá trị true cho mảng bool _usePoint

for (int i = 0; i < _pts.Count; i++) _usePoint[i] = true;

60

//Gọi hàm đơn giản hóa với đường ban đầu - vị trí điểm đầu, //điểu cuối

SimplifyLine(0, _pts.Count - 1);

//Khai báo list chứa các điểm giữ lại của đường

PointList pointList = new PointList(); //Duyệt qua danh sách điểm ban đầu

for (int i = 0; i < _pts.Count; i++)

//Nếu điểm thứ i được giữ lại (_usePoint[i] = true), thì đưa //điểm đó vào danh sách kết quả

if (_usePoint[i])

pointList.Add(new Point(_pts[i])); //Trả lại kết quả là tập điểm được giữ lại

return pointList.ToPointArray(); }

/// <summary>

/// Đơn giản hóa một đoạn trên đường gốc

/// </summary>

/// <param name="i">điểm đầu đoạn</param>

/// <param name="j">điểm cuối đoạn</param>

private void SimplifyLine(int i, int j) {

//Nếu từ i đến j là một đoạn thẳng

if ((i + 1) == j) return;

//Khởi tạo một đường thẳng

_seg.P0 = _pts[i]; _seg.P1 = _pts[j];

//Khởi tạo giá trị khoảng cách lớn nhất từ các điểm đến đường //thẳng _seg

double maxDistance = -1.0;

//Vị trí của điểm có khoảng cách lớn nhất tới đường thẳng _seg

int maxIndex = i;

//Duyệt danh sách điểm từ i đến j của đường ban đầu

for (int k = i + 1; k < j; k++) {

//Tính khoảng cách từ điểm thứ k tới đường i-j

double distance = _seg.Distance(_pts[k]);

//Xác định khoảng cách lớn nhất, và vị trị điểm có khoảng //cách lớn nhất if (distance > maxDistance) { maxDistance = distance; maxIndex = k; }

61 }

//Nếu khoảng cách lớn nhất <= dung sai

if (maxDistance <= _tolerance)

//Bỏ hết các điểm nằm trong khoảng từ i đến j

for (int k = i + 1; k < j; k++) _usePoint[k] = false;

//Xác định được một điểm có khoảng cách lớn nhất, lớn hơn dung //sai

else {

//Thực hiện đơn giản trên 2 đường mới được tạo ra,

//bẻ gẫy tại vị trí điểm có khoảng cách lớn nhất

//Đơn giản đường 1 từ i đến vị trí điểm có khoảng cách lớn //nhất

SimplifyLine(i, maxIndex);

//Đơn giản đường 2 ưừ vị trí điểm có khoảng cách lớn nhất //đến j

SimplifyLine(maxIndex, j); }

} }

62

Cài đặt thuật toán Reumann-Witkam

+ Thuật toán đƣợc cài đặt trong file clsReumannWitkam.cs /// <summary>

/// Khái quát hóa đối tượng dạng đường

/// Sử dụng thuật toán Reumann-Witkam

/// </summary>

public class ReumannWitkamSimplify

{

//Khai báo các biến toàn cục

private readonly IList<Point> _pts; private double _tolerance;

private readonly LineSegment _seg = new LineSegment(); /// <summary>

/// Đơn giải hóa đường

/// </summary>

/// <param name="pts">Danh sách các điểm</param>

/// <param name="distanceTolerance">Dung sai</param>

/// <returns>Trả lại kết quả là tập điểm được giữ lại</returns>

public static IList<Point> Simplify(IList<Point> pts, double distanceTolerance)

{

ReumannWitkamSimplify simplify = new

ReumannWitkamSimplify(pts); simplify._tolerance = distanceTolerance; return simplify.Simplify(); } /// <summary> /// Hàm khởi tạo /// </summary>

/// <param name="pts">Danh sách điểm</param>

private ReumannWitkamSimplify(IList<Point> pts) {

_pts = pts; }

/// <summary>

/// Đơn giản hóa tập điểm _pts

/// </summary>

/// <returns></returns>

private Point[] Simplify() {

//Số lượng điểm của đường cần giản lược

int pointCount = _pts.Count();

//Khai báo list chứa các điểm giữ lại của đường

PointList pointList = new PointList();

63

if (pointCount < 3 || _tolerance == 0) {

pointList.Add(new Point(_pts[0])); pointList.Add(new Point(_pts[1]));

//Trả lại kết quả là tập điểm được giữ lại

return pointList.ToPointArray(); }

//Khai báo các điểm cần kiểm tra

Point p0 = _pts[0]; Point p1 = _pts[1]; Point pi = p1; Point pj = p1;

//Điểm đầu tiên của đường được đưa vào kết quả

pointList.Add(new Point(_pts[0]));

//Kiểm tra các điểm _pts[j] sau đường thẳng _seg(_pts[0], //_pts[1])

for (int j = 2; j < pointCount; j++) {

pi = pj; pj = _pts[j];

//Tính khoảng cách từ điểm thứ j tới đường p0-p1

_seg.P0 = p0; _seg.P1 = p1;

double distance = _seg.Distance(_pts[j]);

//Nếu khoảng cách từ _pts[j] tới đường _seg[p0, p1] < dung //sai

if (distance < _tolerance) {

continue; }

//Khoảng cách từ pj tới đường _seg[p0, p1] > dung sai

//Đưa điểm pi trước pj vào kết quả

pointList.Add(new Point(pi)); //Cập nhật điểm mới p0 = pi; p1 = pj; _seg.P0 = p0; _seg.P1 = p1; }

//Điểm cuối của đường được đưa vào kết quả

pointList.Add(new Point(pj));

//Trả lại kết quả là tập điểm được giữ lại

return pointList.ToPointArray(); }

64 }

+ Giao diện của chức năng

Cài đặt thuật toán sử dụng điểm độc lập

+ Thuật toán đƣợc cài đặt trong file clsNPoint.cs

/// <summary>

/// Khái quát hóa đối tượng dạng đường

/// Sử dụng thuật toán sử dụng điểm độc lập

/// </summary>

public class clsNPointSimplify

{

//Khai báo các biến toàn cục

private readonly IList<Point> _pts; private int _nPoint;

private readonly LineSegment _seg = new LineSegment(); /// <summary>

/// Đơn giải hóa đường

/// </summary>

/// <param name="pts">Danh sách các điểm</param>

/// <param name="nPoint">Chu kỳ lấy điểm</param>

/// <returns>Trả lại kết quả là tập điểm được giữ lại</returns>

public static IList<Point> Simplify(IList<Point> pts, int nPoint) {

clsNPointSimplify simplify = new clsNPointSimplify(pts); simplify._nPoint = nPoint;

return simplify.Simplify(); }

65 /// <summary>

/// Hàm khởi tạo

/// </summary>

/// <param name="pts">Danh sách điểm</param>

private clsNPointSimplify(IList<Point> pts) {

_pts = pts; }

/// <summary>

/// Đơn giản hóa tập điểm _pts

/// </summary>

/// <returns></returns>

private Point[] Simplify() {

//Số lượng điểm của đường cần giản lược

int pointCount = _pts.Count();

//Khai báo list chứa các điểm giữ lại của đường

PointList pointList = new PointList();

//Kiểm tra thỏa mãn điều kiện để thực hiện giản lược hóa

if (pointCount < 3 || _nPoint < 2) {

pointList.Add(new Point(_pts[0])); pointList.Add(new Point(_pts[1]));

//Trả lại kết quả là tập điểm được giữ lại

return pointList.ToPointArray(); }

//Điểm đầu tiên của đường được đưa vào kết quả

pointList.Add(new Point(_pts[0])); bool bMove = true;

int intIndex = 0;

//Lấy điểm theo chu kỳ nPoint

while (bMove) {

//Xác định vị trí cần lấy tiếp theo

intIndex += _nPoint;

//Nếu vị trí lấy vượt quá hoặc số lượng điểm của _pts

if (intIndex >= _pts.Count() - 1) {

//Đưa điểm cuối vào danh sách kết quả

pointList.Add(new Point(_pts[_pts.Count() - 1])); bMove = false;

} else {

//Đưa điểm thứ intIndex vào kết quả

pointList.Add(new Point(_pts[intIndex])); }

66 }

//Trả lại kết quả là tập điểm được giữ lại

return pointList.ToPointArray(); }

}

67

4.3. Phần mềm khái quát hóa bản đồ - MapGeneralization

Hình 4-1 : Giao diện chính của phần mềm - MapGeneralization

Phần mềm MapGeneralization đƣợc xây dựng trên nền DotSpatial với các menu đƣợc tổ chức nhƣ sau:

68

Menu phân tích dữ liệu

Menu khái quát hóa bản đồ

4.3.1. Chức năng phân tích dữ liệu

Cho phép thống kê số lƣợng đối tƣợng dạng vùng, dạng điểm, dạng đƣờng theo sơ đồ phân mảnh, theo địa phận, theo phạm vi bất kỳ.

Ngƣời sử dụng lựa chọn một sơ đồ phân mảnh, hoặc lựa chọn một địa phận hành chính, hoặc lựa chọn một đối tƣợng dạng vùng bất kỳ. Phần mềm sẽ thống kê ra số đối tƣợng của một lớp dữ liệu(dạng đƣờng, vùng, hay điểm).

69

4.3.2. Chức năng khái quá hóa điểm

Cho phép tìm kiếm đối tƣợng trên lớp bản đồ dạng điểm, theo thuộc tính. Sau khi xác định đƣợc các đối tƣợng dạng điểm cần lƣợc bỏ. Chọn lựa chức năng xóa để loại bỏ các đối tƣợng đó.

4.3.3. Chức năng khái quát hóa đường

Với các đối tƣợng dạng đƣờng phần mềm cho phép ngƣời sử dụng lọc bỏ đƣờng theo các thông tin thuộc tính, theo ngƣỡng chiều dài tối thiểu. Ngoài ra chức năng giản lƣợc(Sử dụng các thuật toán đơn giản đƣờng cong) cho phép giảm đáng kể dung lƣợng dữ liệu mà vẫn đảm bảo độ tin cậy và tính thẩm mỹ của dữ liệu đầu ra.

70

4.3.4. Chức năng khái quá hóa vùng

Cho phép tìm kiếm đối tƣợng trên lớp bản đồ dạng vùng, theo thuộc tính. Sau khi xác định đƣợc các đối tƣợng dạng vùng cần lƣợc bỏ. Chọn lựa chức năng xóa để loại bỏ các đối tƣợng đó.

Cho phép tìm kiếm đối tƣợng trên lớp bản đồ dạng vùng có diện tích nhỏ hơn một giá trị xác định. Chọn lựa chức năng xóa để loại bỏ đối tƣợng đó.

71

4.4. Kết quả thử nghiệm

Phần mềm đƣợc thử nghiệm để khái quát hóa trên dữ liệu nền địa hình tỷ lệ 1:10.000 Thành Phố Huế, Tỉnh Thừa Thiên Huế.

Kết quả khái quát hóa các đối tƣợng dạng đƣờng, trên lớp dữ liệu đoạn tim đƣờng bộ(DoanTimDuongBo) với thuật toán Douglas-Peacker, Reumann-Witkam.

Dung sai Tổng số đối

tượng Tổng số đỉnh Tổng số đỉnh lược bỏ Douglas-Peacker Reumann-Witkam 0.2 22948 27154 98296 1977 0.5 22948 27154 148763 4294 1 22948 27154 175354 11560 2 22948 27154 193555 30108 3 22948 27154 201252 47620 0 50000 100000 150000 200000 250000 0.2 0.5 1 2 3 Douglas-Peacker Reumann-Witkam

72

KẾT LUẬN

Kết quả đạt đƣợc

Luận văn đã đạt đƣợc một số kết quả sau:

- Giới thiệu tổng quan hệ thống thông tin địa lý – GIS

- Nghiên cứu cơ sở khoa học của khái quát hóa bản đồ và tình hình nghiên cứu trong và ngoài nƣớc trong lĩnh vực khái quát hóa bản đồ.

- Nghiên cứu, trình bày các thuật toán khái quát hóa bản đồ.

- Xây dựng ứng dụng khái quát hóa bản đồ. Thử nghiệm cho dữ liệu nền địa hình tỷ lệ 1:10.000 Thành Phố Huế, Tỉnh Thừa Thiên Huế. Đảm bảo một phần các nội dung về khái quát hóa bản đồ tự động trong quá trình thành lập, xây dựng bản đồ số.

Hƣớng phát triển

Do thời gian thực hiện luận văn còn hạn chế, nên luận văn mới chỉ thực hiện cài đặt các thuật toán khái quát hóa dạng đƣờng. Hƣớng phát triển tiếp tục đầu tƣ nghiên cứu hoàn thiện các chức năng phần mềm, cũng nhƣ nghiên cứu có chiều sâu về khái quát hóa đối tƣợng dạng vùng, khái quát hóa ngữ cảnh, đặt biệt là vấn đề đánh giá chất lƣợng của khái quát hóa.

73

TÀI LIỆU THAM KHẢO

Tiếng Việt

1. Đặng Văn Đức, “Hệ thống thông tin địa lý”, NXB Khoa học kỹ thuật năm 2001. 2. Võ Quang Minh, Nguyễn Hồng Điệp , Trần Ngọc Trinh, Trần Văn Hùng, “Giáo

trình hệ thống thông tin địa lý “, 2007.

Một phần của tài liệu Một số thuật toán khái quát hóa bản đồ và ứng dụng (Trang 61)

Tải bản đầy đủ (PDF)

(78 trang)