Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Làm cách nào để sử dụng không gian để tìm kiếm bán kính mã zip?

Vì vậy, sử dụng gợi ý của Phil, tôi đã viết lại rất nhiều điều này bằng cách sử dụng không gian. Điều này rất hiệu quả, bạn chỉ cần .NET4.5, EF5 + và máy chủ sql (tôi tin là 2008 trở lên). Tôi đang sử dụng EF6 + Sql Server 2012.

Thiết lập

Bước đầu tiên là thêm Geography vào cơ sở dữ liệu của tôi EventListings bảng (Nhấp chuột phải vào nó -> Thiết kế). Tôi đặt tên là Vị trí của tôi:

Tiếp theo, vì tôi đang sử dụng EDM với cơ sở dữ liệu đầu tiên, tôi phải cập nhật mô hình của mình để sử dụng trường mới mà tôi đã tạo. Sau đó, tôi nhận được lỗi không thể chuyển đổi Địa lý thành kép, vì vậy, những gì tôi đã làm để khắc phục là chọn thuộc tính Vị trí trong thực thể, chuyển đến thuộc tính của nó và thay đổi loại của nó từ kép thành Geography :

Truy vấn trong Bán kính &Thêm sự kiện có vị trí

Sau đó, tất cả những gì bạn phải làm là truy vấn bộ sưu tập thực thể của bạn như sau:

 var events = EventRepository.EventListings
                             .Where(x => x.Location.Distance(originCoordinates) * 0.00062 <= radiusParam); 

Phương thức mở rộng khoảng cách lấy khoảng cách từ đối tượng hiện tại đến đối tượng "khác" mà bạn truyền vào. Đối tượng khác này thuộc loại DbGeography . Bạn chỉ cần gọi một phương thức tĩnh và nó tạo ra một trong những con chó con này, sau đó chỉ cần ném Kinh độ &Vĩ độ của bạn vào đó như một điểm:

DBGeography originCoordinates = DBGeography.fromText("Point(" + originLongitude + " " + originLatitude + ")");

Đây không phải là cách tôi tạo tọa độ gốc của mình. Tôi đã tải xuống một cơ sở dữ liệu riêng biệt có danh sách tất cả các mã zip và Vĩ độ &Kinh độ của chúng. Tôi đã thêm một cột thuộc loại Geography với điều đó nữa. Tôi sẽ chỉ cách làm ở cuối câu trả lời này. Sau đó, tôi đã truy vấn ngữ cảnh mã zip để lấy đối tượng DbGeography từ trường Vị trí trong bảng ZipCode.

Nếu người dùng muốn có nguồn gốc cụ thể hơn chỉ là mã zip, tôi thực hiện cuộc gọi tới API Google Maps (Mã địa lý để cụ thể hơn) và lấy vĩ độ và kinh độ cho địa chỉ cụ thể của người dùng thông qua dịch vụ web và tạo đối tượng DBGeography từ các giá trị Vĩ độ &Kinh độ trong phản hồi.

Tôi cũng sử dụng các API của Google khi tạo sự kiện. Tôi chỉ đặt biến vị trí như thế này trước khi thêm thực thể của mình vào EF:

someEventEntity.Location = DBGeography.fromText("Point(" + longitudeFromGoogle+ " " + latitudeFromGoogle + ")");

Mẹo &Thủ thuật &Khắc phục sự cố khác

Làm cách nào để tôi có được Phương pháp Mở rộng Khoảng cách?

Để nhận phương thức mở rộng Distance bạn phải thêm tham chiếu vào dự án của mình:System.Data.Entity Sau khi làm điều đó, bạn phải thêm using:using System.Data.Entity.Spatial; đến lớp của bạn.

Distance phương thức mở rộng trả về khoảng cách với đơn vị đo là mét (Tôi nghĩ bạn có thể thay đổi nó, nhưng điều này là mặc định). Ở đây, thông số bán kính của tôi tính bằng dặm, vì vậy tôi đã thực hiện một số phép toán để chuyển đổi.

Lưu ý :Có một DBGeography lớp trong System.Data.Spatial . Đây là cái sai và nó sẽ không hiệu quả với tôi. Tôi tìm thấy rất nhiều ví dụ trên internet đã sử dụng cái này.

Cách chuyển đổi Vĩ độ / Kinh độ sang Cột Địa lý

Vì vậy, nếu bạn giống tôi và đã tải xuống cơ sở dữ liệu mã zip với tất cả Latitude &Longitude và sau đó nhận ra rằng nó không có cột Địa lý ... điều này có thể hữu ích:

1) Thêm cột Vị trí vào bảng của bạn. Đặt loại thành Địa lý.

2) Thực thi sql sau

UPDATE [ZipCodes]
SET Location = geography::STPointFromText('POINT(' + CAST([Longitude] AS VARCHAR(20)) + ' ' + CAST([Latitude] AS VARCHAR(20)) + ')', 4326)

Cách xem chi tiết của một mục Địa lý

Vì vậy, khi bạn truy vấn bảng EventListings của mình trong Sql Server Management Studio sau khi bạn đã chèn một số mục DbGeography, bạn sẽ thấy Location cột chứa giá trị hex như:0x1234513462346. Điều này không hữu ích lắm khi bạn muốn đảm bảo rằng các giá trị chính xác đã được chèn vào.

Để thực sự xem vĩ độ và kinh độ của trường này, bạn phải truy vấn nó như sau:

SELECT Location.Lat Latitude, Location.Long Longitude
FROM [EventListings]



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách sử dụng Chèn csv hàng loạt vào máy chủ sql với định dạng datetime đúng?

  2. Ưu và nhược điểm của OleDB so với SQLClient là gì?

  3. TSQL - tạo một proc được lưu trữ bên trong một báo cáo giao dịch

  4. Tạo cơ sở dữ liệu mới từ bản sao lưu của một Cơ sở dữ liệu khác trên cùng một máy chủ?

  5. Hợp nhất 2 cơ sở dữ liệu SQL Server