天天看點

ArcGIS Silverlight API 中如何縮放到點

Map控件的 zoomto方法可以将地圖縮放到一個Geometry的 extent範圍并且将該geometry置于目前視域中心,然而對于point 要素來說,這個方法是無效的,因為point的 extent範圍為0。

然而在實際應用中,使用者對于點的zoomto需求還是比較多的,有一個比較簡單的方法就是以點為中心上下左右擴張一段距離建構一個envelope,然後zoomto到這個envelope。但是這個方法複用性不強,對于每個問題都需要重新定義合适的envelope。

于是考慮有沒有通用性比較強的zoomto方法,map控件有一個ZoomToResolution(Double, MapPoint)方法,該方法以MapPoint為錨點,将Map縮放到指定的resolution.。

然而這個方法隻是確定了縮放後Mappoint相對于螢幕的位置不變,并不會将MapPoint移動到螢幕中心。

(這個方法就是Map控件中響應double click的方法,以輕按兩下點為不動點,地圖放大一倍 Map.ZoomToResolution(Map.Resolution/2, click_point) )

下面考慮應用ZoomToResolution方法自定義一個可以将點 Zoom 并且Pan到中心的方法:

ArcGIS Silverlight API 中如何縮放到點

以上圖為例,A是Map的中點,B是我們的目标點,現在的問題就變成了如何在地圖上找到一個點C,

使得我使用ZoomToResolution(zoomRatio r, MapPoint C)之後,B點會移動到A的位置。

不失一般性,我們假設地圖放大的比例為r,即放大後的 Map.Resolution 比 放大前的Map.Resolution 等于r,

則C點必須滿足 BC:AC = r ,即 DE : AE = r ,

設A點坐标為 (CenterX, CenterY), B點坐标(X, Y),C點坐标為(Xc, Yc),代入上面的等式,得:

(Xc-X)/r = Xc - CenterX ;

(Yc-Y)/r = Yc - CenterY ;

得出C點的坐标滿足關系:

Xc = (X - CenterX*r)/(1 - r)

 Yc = (Y - CenterY*r)/(1 - r)

根據以上理論,不難寫一個滿足這個需求的函數:

private void centerAndZoom(ESRI.ArcGIS.Client.Map map, ESRI.ArcGIS.Client.Geometry.MapPoint mapPoint, double resolution)
{
	double ratio = 1.0;
	if (map.Resolution != 0.0)
		ratio = resolution / map.Resolution;

	if (ratio == 1.0)
		map.PanTo(mapPoint);
	else
	{
		ESRI.ArcGIS.Client.Geometry.MapPoint mapCenter = map.Extent.GetCenter();
		double X = (mapPoint.X - ratio * mapCenter.X) / (1 - ratio);
		double Y = (mapPoint.Y - ratio * mapCenter.Y) / (1 - ratio);
		map.ZoomToResolution(resolution, new ESRI.ArcGIS.Client.Geometry.MapPoint(X, Y));
	}
}
           

這樣,在實際使用中,如果我們想要zoom and center 到一個點 pt,可以使用以下語句完成:

centerAndZoom(map, pt, map.Resolution * 4);