2010-04-16 24 views
6

Tôi đang tạo máy chủ Lớp phủ cho bản đồ Google trong C# và đã tìm thấy một vài ví dụ mã khác nhau để tính toán Y từ Latitude. Sau khi nhận được chúng để làm việc nói chung, tôi bắt đầu nhận thấy một số trường hợp mà các lớp phủ không xếp hàng đúng cách. Để kiểm tra điều này, tôi đã thực hiện một thử nghiệm khai thác để so sánh chuyển đổi Mercator LatToY của Google Map với các công thức mà tôi tìm thấy trực tuyến. Như bạn có thể thấy bên dưới, chúng không khớp trong một số trường hợp nhất định.Công thức chiếu Mercator chung cho Google Maps không hoạt động chính xác

Case # 1

thu nhỏ: Vấn đề là hầu hết rõ ràng khi thu nhỏ. Đóng lên, sự cố hầu như không hiển thị.

Case # 2

điểm tiệm cận từ đầu & Đáy vọt xem: Vấn đề là tồi tệ hơn ở giữa giới hạn xem, và trở nên tốt hơn đối với các cạnh. Hành vi này có thể phủ nhận hành vi của Case # 1

Các thử nghiệm:

Tôi tạo ra một trang bản đồ google để hiển thị đường màu đỏ bằng cách sử dụng Google Map API được xây dựng trong chuyển đổi Mercator, và phủ lớp này bằng hình ảnh bằng cách sử dụng mã tham chiếu để thực hiện chuyển đổi Mercator . Những chuyển đổi này là được biểu thị bằng các đường màu đen. So sánh sự khác biệt.

Kết quả: Equator http://www.kayak411.com/Mercator/MercatorComparison%20-%20Equator.png North Zoomed Out http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out.png

Check-out top-nhất và dưới hầu hết các dòng: North Top & Bottom Example http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Out%20-%20TopAndBottom.png

Vấn đề trở nên lớn hơn trực quan nhưng số lượng nhỏ hơn khi bạn phóng to: alt text http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20Midway.png

Và tất cả đều biến mất ở các mức thu phóng gần hơn, bất kể scre vi định hướng. alt text http://www.kayak411.com/Mercator/MercatorComparison%20-%20North%20Zoomed%20In.png

Bộ luật:

Google Maps Client Side Code:

  var lat = 0; 
     for (lat = -80; lat <= 80; lat += 5) { 
      map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2)); 
      map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2)); 
     } 

Server Side Code:

Tile Cutter: http://mapki.com/wiki/Tile_Cutter

OpenStreetMap Wiki: http://wiki.openstreetmap.org/wiki/Mercator

protected override void ImageOverlay_ComposeImage(ref Bitmap ZipCodeBitMap) 
     { 
      Graphics LinesGraphic = Graphics.FromImage(ZipCodeBitMap); 

      Int32 MapWidth = Convert.ToInt32(Math.Pow(2, zoom) * 255); 

      Point Offset = 
       Cartographer.Mercator2.toZoomedPixelCoords(North, West, zoom); 

      TrimPoint(ref Offset, MapWidth); 

      for (Double lat = -80; lat <= 80; lat += 5) 
      { 
       Point StartPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -179, zoom); 
       Point EndPoint = Cartographer.Mercator2.toZoomedPixelCoords(lat, -1, zoom); 

       TrimPoint(ref StartPoint, MapWidth); 
       TrimPoint(ref EndPoint, MapWidth); 

       StartPoint.X = StartPoint.X - Offset.X; 
       EndPoint.X = EndPoint.X - Offset.X; 

       StartPoint.Y = StartPoint.Y - Offset.Y; 
       EndPoint.Y = EndPoint.Y - Offset.Y; 


       LinesGraphic.DrawLine(new Pen(Color.Black, 2), 
        StartPoint.X, 
        StartPoint.Y, 
        EndPoint.X, 
        EndPoint.Y); 

       LinesGraphic.DrawString(
        lat.ToString(), 
        new Font("Verdana", 10), 
        new SolidBrush(Color.Black), 
        new Point(
         Convert.ToInt32((width/3.0) * 2.0), 
         StartPoint.Y)); 
      } 
     } 

     protected void TrimPoint(ref Point point, Int32 MapWidth) 
     { 
      point.X = Math.Max(point.X, 0); 
      point.X = Math.Min(point.X, MapWidth - 1); 

      point.Y = Math.Max(point.Y, 0); 
      point.Y = Math.Min(point.Y, MapWidth - 1); 
     } 

Vì vậy, ai đã từng trải qua điều này? Tôi dám hỏi, giải quyết chuyện này? Hoặc chỉ đơn giản là có một C# tốt hơn thực hiện của Mercator dự án chuyển đổi phối hợp?

Cảm ơn!

+0

bạn nên kiểm tra bản đồ sắc nét và proj.net, chúng có trên codeplex –

+0

xem gdal.org – dassouki

+0

@ Muad'Dib Cảm ơn đề xuất. Tôi nắm lấy công cụ Proj.net, nhưng công thức chiếu của họ không tính đến yếu tố thu phóng và tôi không thể tìm ra cách áp dụng nó. (http://projnet.codeplex.com/Thread/View.aspx?ThreadId=77458) Dường như SharpMap sử dụng Proj.net làm công cụ chiếu của họ, vì vậy có thể sẽ không có nhiều trợ giúp. –

Trả lời

1

Cảm ơn tất cả các bạn đã đề xuất các đề xuất của bạn &.

Điều cuối cùng tôi phát hiện ra đó không phải là công thức hoặc vấn đề kỹ thuật, tôi tin rằng đó là một vấn đề về phương pháp luận.

Bạn không thể xác định khu vực xem ở định dạng Lat/Lng và mong muốn điền vào đó với các phép chiếu Mercator phù hợp. Đó là nơi biến dạng xảy ra. Thay vào đó, bạn phải xác định đúng hộp xem trong Mercator, và dự án Mercator.

Làm điều đó tôi có thể khớp chính xác với các bản đồ của Google.

0

Bạn có thể phải tạo một số điểm dọc theo kinh độ để các điểm được chiếu dọc theo vĩ độ. Trong ví dụ của bạn, bạn chỉ thực sự chiếu hai điểm ở đầu và cuối dòng và kết nối hai điểm.

Sự cố sẽ rõ ràng hơn ở đường xích đạo do độ cong quan trọng hơn của trái đất. Nó sẽ ít hơn khi phóng to cho cùng một lý do.

Có một cái nhìn tại http://code.google.com/apis/maps/documentation/overlays.html#Great_Circles

Cố gắng tạo polylines Google của bạn với tham số geodsic để xem nếu điều này làm cho một sự khác biệt. Tôi nghĩ rằng đây thêm điểm dọc theo đường và các dự án một cách tự động:

var lat = 0; 
var polyOptions = {geodesic:true}; 
for (lat = -80; lat <= 80; lat += 5) { 
    map.addOverlay(new GPolyline([new GLatLng(lat, -180), new GLatLng(lat, 0)], "#FF0033", 2, polyOptions)); 
    map.addOverlay(new GPolyline([new GLatLng(lat, 0), new GLatLng(lat, 180)], "#FF0033", 2, polyOptions)); 
} 

tôi phải đọc vào này như tất cả các phép đo khoảng cách của tôi đã sai trong OpenLayers vì những lý do tương tự: http://geographika.co.uk/watch-out-for-openlayer-distances (thêm liên kết/giải)

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