2012-11-30 25 views
5

Tôi có ứng dụng đường ray đang sử dụng rgeo 0.3.19 với hỗ trợ proj4 kết nối với cơ sở dữ liệu PostGIS 1.5 bằng đá quý rgeo-activerecord 0.4.5.Đa giác vùng đệm RGeo quá nhỏ

Ứng dụng của tôi có một mô hình được gọi là Khu vực có chứa một điểm địa lý, bán kính và hình đa giác. Khi một vùng mới sắp lưu nó sử dụng hàm đệm của geofactory của vùng để tạo một đa giác bằng cách sử dụng bán kính và điểm địa lý.

Đây là geofactory đang được sử dụng cho các mô hình khu vực

GEOFACTORY = RGeo::Geographic.projected_factory(:buffer_resolution => 8, :projection_proj4 => '+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m [email protected] +wktext +no_defs', :projection_srid => 3857) 

Các projection_srid Tôi đang sử dụng là của Apple và Google maps chiếu Mercator 3857. Vấn đề là bộ đệm đang được tạo ra không phải là kích thước giống như tôi vẽ trong bản đồ táo hoặc bản đồ google. Ví dụ: nếu tôi sử dụng chức năng MapKit được xây dựng MKCircle

[MKCircle circleWithCenterCoordinate:self.coordinate radius:50]; 

Vòng tròn sẽ vẽ và phủ lên như thế này. iOS Drawing Radius

Nhưng nếu tôi lấy tọa độ đã được tạo thành hàm đệm tạo nên hình đa giác trong cơ sở dữ liệu và vẽ chúng trên bản đồ google tôi nhận được điều này.

GoogleMaps Radius

Như bạn có thể thấy, đa giác được tạo ra bằng cách sử dụng hệ thống chiếu cùng là nhỏ hơn nó nên được. Vấn đề này phát triển theo cấp số nhân ngoài tầm kiểm soát dựa trên kích thước của bán kính được xác định. Tôi cũng đã cố gắng sử dụng nhà máy simple_mercator như được định nghĩa trong RGeo mang lại kết quả tương tự.

Hy vọng rằng ai đó có một số thông tin chi tiết về lý do tại sao, khi một vĩ độ, vĩ độ dự kiến ​​điểm được đệm nó tạo ra một đa giác có kích thước không chính xác.

Trả lời

9

Điều bạn đang quan sát ở đây là biến dạng Mercator. Khoảng cách "50" trong phép chiếu của máy chiếu không tương ứng với 50 mét trên bề mặt hành tinh thực, trừ khi bạn đang ở đường xích đạo.

Vòng tròn được vẽ bởi bản đồ iOS của bạn là chính xác: đó là bán kính 50 mét. Những gì tôi nghi ngờ bạn đã làm để tạo ra hình ảnh thứ hai của bạn là để dự án điểm vào một chiếu Mercator (theo Proj4 bạn cung cấp). Sau đó, bạn tiến hành tạo một bộ đệm với bán kính 50 trong hệ tọa độ dự kiến. Tuy nhiên, 50 đơn vị Mercator ở vĩ độ 40,61 chỉ tương ứng với khoảng 37,96 mét trên bề mặt của khoảng cách trái đất. Vì vậy, khi bạn chiếu đa giác đó trở lại vĩ độ và kinh độ và vẽ nó, đó là những gì bạn thấy: một vòng tròn 38 mét.

Một cách để hình dung điều này là xem toàn bộ bản đồ thế giới trên Google Maps. Vẽ một vòng tròn bán kính 50 pixel tại đường xích đạo. Và sau đó vẽ một vòng tròn bán kính khác 50 pixel trên Greenland. Trên bản đồ (trong tọa độ Mercator), các vòng tròn đó có cùng kích thước. Nhưng, nếu bạn biết phép chiếu Mercator của bạn, bạn biết nó bóp méo Greenland vì Greenland cách xa đường xích đạo, vì vậy vòng tròn của bạn trên Greenland thực sự nhỏ hơn nhiều so với vòng tròn của bạn phía trên đường xích đạo. Ở vĩ độ 40 độ, sự biến dạng không nghiêm trọng, nhưng nó vẫn còn đó.

Nếu bạn muốn sửa lỗi này, nó khá dễ dàng. Sự biến dạng kích thước gây ra bởi phép chiếu Mercator tỉ lệ thuận với độ dài của vĩ độ. Đó là, 50 đơn vị mercator trên đường xích đạo bằng 50 mét, nhưng 50 đơn vị mercator ở vĩ độ x (tính bằng radian), tương ứng với 50/sec (x) mét. Vì vậy, nếu bạn muốn bán kính 50 mét, nhân 50 giây (vĩ độ) và sử dụng số đó làm bán kính trong tọa độ của bộ phận giao dịch.Trong RGeo-talk:

p_lonlat = GEOFACTORY.point(40.610355377197266, -75.38220214843749) 
p_proj = p_lonlat.projection 
buf_proj = p_proj.buffer(50.0 * (1/Math.cos(p_lonlat.y/180.0 * Math::PI))) 
buf_lonlat = GEOFACTORY.unproject(buf_proj) 
+0

Cảm ơn bạn đã chỉnh sửa, MobileOverlord. Tôi quên không có một chức năng bảo mật nào trong Ruby. Đó là những gì tôi nhận được để đăng mã mà không thử nghiệm nó đầu tiên ... :-) –