2009-12-14 39 views
6

Có ai biết cách lấy tất cả các đa giác trong một db của MySQL trong một khoảng cách nhất định từ một điểm không? Khoảng cách thực sự không quan trọng vì nó được tính cho mỗi đa giác tìm thấy sau đó, nhưng nó sẽ là một tối ưu hóa rất lớn để thực hiện phép tính đó cho các đa giác "gần".Nhận đa giác gần với một lat, dài trong MySQL

Tôi đã xem MBR và chứa các hàm nhưng vấn đề là một số đa giác không được chứa trong một hộp giới hạn được vẽ xung quanh điểm vì chúng rất lớn, nhưng một số đỉnh của chúng vẫn gần.

Mọi đề xuất?

Trả lời

3

Một phiên bản chậm (không có chỉ mục không gian):

SELECT * 
FROM mytable 
WHERE MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance)) 

Để tận dụng các chỉ số không gian, bạn cần phải denormalize bảng của bạn để mỗi đỉnh đa giác được lưu trữ trong hồ sơ riêng của mình.

Sau đó tạo các SPATIAL INDEX trên các lĩnh vực, trong đó có tọa độ của các đỉnh và chỉ phát hành truy vấn này:

SELECT DISTINCT polygon_id 
FROM vertices 
WHERE MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance)) 

Những điều sẽ được nhiều dễ dàng hơn nếu bạn lưu trữ UTM tọa độ trong cơ sở dữ liệu của bạn chứ không phải là vĩ độ và kinh độ.

+0

Cảm ơn một nhóm! Đối với những người có vấn đề tương tự: Tôi đã kết thúc bằng cách sử dụng MBR của một vòng tròn được vẽ xung quanh điểm quan tâm và tìm nạp tất cả các đa giác có MBR giao nhau với vòng tròn MBR. – Gren

+0

Bạn có thể cho tôi biết 'khoảng cách' có nghĩa là gì? Là nó trong dặm, km hoặc mét? –

+1

@ShaishavJogani: '@ distance' là một biến chứa khoảng cách bạn đang tìm kiếm bên trong. Nó có thể là trong dặm hoặc km hoặc mét, hoặc bất kỳ đơn vị khoảng cách khác, với điều kiện bạn lưu trữ tọa độ trong cùng một đơn vị. – Quassnoi

1

Tôi không nghĩ rằng có một câu trả lời duy nhất cho điều này. Nó thường là một câu hỏi về cách tổ chức dữ liệu của bạn để nó làm cho việc sử dụng các địa phương không gian vốn có cho vấn đề của bạn.

Ý tưởng đầu tiên bật vào đầu của tôi là sử dụng lưới, gán mỗi điểm cho một hình vuông và kiểm tra chọn điểm vuông ở điểm và những điểm xung quanh điểm đó. Nếu chúng ta đang nói lưới vô hạn, sau đó sử dụng một giá trị băm của hình vuông, điều này sẽ cung cấp cho bạn nhiều điểm hơn cần thiết (nơi bạn có va chạm), nhưng vẫn sẽ giảm số lượng của một bó. Tất nhiên điều này không áp dụng ngay lập tức cho đa giác, nó chỉ là một động não. Một cách tiếp cận có thể mang lại quá nhiều va chạm sẽ là HOẶC tất cả các giá trị được băm cùng nhau và chọn tất cả các mục nhập trong đó các giá trị Hash với giá trị đó không khác (không chắc chắn nếu điều này có thể trong MySQL), bạn có thể muốn sử dụng một giá trị lớn số lượng bit mặc dù.

Vấn đề với phương pháp này là giả sử chúng ta đang nói tọa độ hình cầu (lat, nói chung là dài) là các điểm kỳ dị, vì ô vuông 'lưới' tăng hẹp hơn khi bạn tiếp cận các cực. Cách tiếp cận dễ dàng này là ... không đặt bất kỳ điểm nào gần các cực ... :)

0

Tạo một hộp giới hạn cho tất cả các đa giác và (tùy chọn lưu trữ các kết quả này trong cơ sở dữ liệu sẽ làm cho nhanh hơn nhiều đối với các đa giác phức tạp). Sau đó, bạn có thể so sánh hộp giới hạn cho mỗi đa giác với một điểm tròn với kích thước mong muốn. Chọn tất cả các đa giác có hộp giới hạn giao nhau.

Các vấn đề liên quan