Table of Contents
[Tutorial] Build simple geoserver query CQL form Cái Video này làm mấy ngày rồi, nhưng giờ mới có thời gian bổ sung cho nó hoàn thiện nên viết thành bài luôn Mọi người xem Video hướng dẫn chi tiết nhé. Về cơ bản thì cái này chỉ tìm kiếm dựa trên cú pháp truy vấn CQL được GeoServer hỗ trợ. Còn ai không biết CQL là gì, dùng thế nào thì xem video hoặc vào link đưới
http://docs.geoserver.org/stable/en/user/tutorials/cql/cql_tutorial.htmlTrong video hướng dẫn chi tiết từ bước tạo form tìm kiếm đến xử lý giá trị người dùng nhập vào form để truy vấn và hiện kết quả.
https://dothanhlong.org/demo/geoserver_query/Giờ mình không ghi lại những gì có trong video nữa, mình sẽ đi vào phần chỉnh sửa, bổ sung nâng cao xíu cho chức năng thêm hoàn thiện.
Hoàn thiện chức năng tìm kiếm cơ bản với GeoServer CQL query
Ở video, mình đã hướng dẫn tìm kiếm được đối tượng và hiển thị đối tượng. Tuy nhiên, vẫn còn một số hạn chế như:- Việc tìm kiếm mình dùng phép "LIKE", phép tìm kiếm LIKE yêu cầu người dùng nhập từ khóa tìm kiếm phân biệt chữ hoa và chữ thường. Mình sẽ hướng dẫn dùng phép tìm kiếm khác giúp người dùng dễ dàng trong việc tìm kiếm hơn.
- Kết quả chỉ hiển thị ra đối tượng cần tìm kiếm nên người dùng vẫn sẽ không biết được vị trí chính xác của đối tượng đó nằm ở khu, vùng nào trên bản đồ tổng thể. Ở bước hướng dẫn này, mình sẽ thêm cái bản đồ tổng thể vào để biết vị trí cái kết quả tìm kiếm của mình nằm ở đâu.
- Bên cạnh đó, việc nhấp nút tìm kiếm xong kết quả nhảy sang trang khác cũng khá bất tiện, mình sẽ hướng dẫn áp dụng Ajax để hiển thị kết quả luôn trên trang tìm kiếm.
Nâng cấp chức năng tìm kiếm không phân biệt chữ hoa, chữ thường.
Đối với phép tìm kiếm LIKE trong CQL (cả trong PostgreSQL) thì nó sẽ phân biệt chữ viết hoa và chữ viết thường. Ví dụ 2 câu truy vấn bên dưới:tentinh LIKE '%Nghệ%' tentinh LIKE '%nghệ%'2 câu truy vấn này sẽ cho 2 kết quả khác nhau mặc dù chỉ khác nhau chữ N viết hoa và chữ n viết thường.
tentinh LIKE '%Nghệ%' sẽ trả về kết quả là Nghệ An (Do trong bảng thuộc tính dữ liệu mình lưu là Nghệ An) tentinh LIKE '%nghệ%' sẽ trả về kết quả là không tìm thấy do trong bảng thuộc tính dữ liệu không có giá trị nào mình lưu bắt đầu bằng chữ nghệ hết.Nhưng đối với người dùng thị họ đâu biết là mình lưu trong dữ liệu là viết hoa hay viết thường, nên mình cũng không thể bắt buộc họ phải viết đúng theo mình thì mới tìm được kết quả :') Vì vậy, CQL có hỗ trợ một kiểu tìm thứ 2 là ILIKE. Kiểu này cho phép tìm kiếm không phân biệt chữ hoa hay chữ thường. Đối với ILIKE thì 2 câu truy vấn ở trên đều trả về kết quả là Nghệ An cả. Vẹn cả đôi đường :v Vậy chúng ta sẽ sửa các chỗ LIKE phần xử lý yêu cầu truy vấn do người dùng nhập vào ở file xuly.php thành ILIKE hết. Lúc đó sẽ thành:
$cql="NAME_2 ILIKE '%".$txttentinh."%' AND NAME_1 ILIKE '%".$txttenkhuvuc."%'";
Thêm bản đồ tổng thể vào kết quả tìm kiếm
Hiện tại thì sau khi tìm kiếm. Ví dụ tìm tỉnh Nghệ An, chúng ta sẽ được kết quả như sau: [caption id="attachment_1160" align="alignnone" width="529"]

Chuẩn bị một tấm hình làm bản đồ nền.
Điều kiện tiên quyết của cái bản đồ nền là là nó phải cùng kích thước với cái bản đồ kết quả. Vậy làm sao để có cái bản đồ cùng kích thước? Đơn giản nhất là chúng ta cũng xuất từ GeoServer ra rồi save lại thành tấm hình là được. Vào GeoServer, để style lớp bản đồ lại thành mặc định (polygon) Kết quả khi preview sẽ như hình dưới: [caption id="attachment_1166" align="alignnone" width="808"]
http://dev.dothanhlong.org:8080/geoserver/dothanhlong/wms?service=WMS&version=1.1.0&request=GetMap&layers=dothanhlong:vn_provinces&styles=&bbox=102.066223144531,7.31143283843994,117.895713806152,23.4724426269531&width=752&height=768&srs=EPSG:4326&format=application/openlayersGiờ chúng ta sẽ save hình này lại để làm bản đồ nền với tên là
dothanhlong-vn_provinces.png http://dev.dothanhlong.org:8080/geoserver/dothanhlong/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&LAYERS=dothanhlong%3Avn_provinces&STYLES&SRS=EPSG%3A4326&WIDTH=752&HEIGHT=768&BBOX=101.71142578125%2C6.96533203125%2C118.23486328125%2C23.84033203125
Sửa file xuly.php đề chèn bản đồ nền vào
Để chèn hình vào thì chúng ta cũng echo thẻ img như đối với kết quả tìm kiếmecho '<img src="dothanhlong-vn_provinces.png">';Tuy nhiên, để hình nền nằm phía sau kết quả thì chũng ta phả echo hình ra trước, sau đó mới đến kết quả vì mặc định code php sẽ đọc và thực thi từ trên xuống dưới. [caption id="attachment_1174" align="alignnone" width="1177"]


position: Khai báo loại vị trí left: Canh lề trái top: Canh lề trên[caption id="attachment_1177" align="alignnone" width="1280"]




Sử dụng kỹ thuật Ajax trong hiển thị kết quả tìm kiếm bản đồ
Hiện tại ứng dụng của chúng ta đang thưc hiện gửi, nhận kết quả theo hình thức Form GET bình thường. Hạn chế của chế độ mặc định khi submit form này là kết quả sẽ được hiển thị ở một trang khác (trang xuly.php) khi chúng ta submit gửi dữ liệu.Vậy để hiển thị kết quả ngay bên dưới form tìm kiếm thì thể nào?Chúng ta có một kỹ thuật gọi là kỹ thuật Ajax. Kỹ thuật này cho phép gửi, nhận dữ liệu trên cùng một trang, mọi yêu request đều được thực hiện "ngầm" Để sử dụng thì bắt buộc phải biết Javascript. Xem bài sau về gọi Ajax bằng Jquery: https://dothanhlong.org/get-method-ajax/ Ở đây mình mặc định là các bạn biết Javascript rồi nhé! Bắt tay nào!
Sửa file chứa form tìm kiếm (index.html)
Ở file này, do chúng ta sử dụng Bootstrap để thiết kế form nên chúng ta đã khai báo sẵn luôn thư viện Jquery, không cần khai báo lại :v [caption id="attachment_1184" align="alignnone" width="1092"]
Xác định vị trí hiển thị kế quả trên form
Mình cho hiện kết quả bên dưới form tìm kiếm, như sau: [caption id="attachment_1188" align="alignnone" width="1120"]

Thêm đoạn Javascript gọi Ajax đến file xuly.php
[caption id="attachment_1189" align="alignnone" width="1116"]
txttenkhuvuc txttentinhFile để xử lý các kết quả vẫn là file xuly.php Kết quả được trả về sẽ được hiển thị ở thẻ div có id là kq
Thêm sự kiện để gọi Ajax
Chúng ta đã có một nút bấm submit để tìm kiếm theo cách thông thường. Bây giờ để gọi Ajax, chúng ta cần tạo một nút khác với sự kiện click chuột vào sẽ gọi cái hàm Ajax của chúng ta khai báo ở trên [caption id="attachment_1191" align="alignnone" width="994"]

Và kết quả cuối cùng
https://dothanhlong.org/demo/geoserver_query/v2/Tìm kiếm với từ khóa tỉnh Nghệ An [caption id="attachment_1194" align="alignnone" width="1280"]

