SharpMap 渲染流程:
Map.GetMap() 觸發渲染。Map.Layers,呼叫各 Layer.Render()。VectorLayer) 透過 DataSource.GetFeaturesInView() 取得視窗範圍要素。VectorRenderer 繪製點、線、面。TransformToImage()。Style) 繪製最終影像。private double _Zoom;
public double Zoom {
get { return _Zoom; }
set {
if (value < _MinimumZoom) _Zoom = _MinimumZoom;
else if (value > _MaximumZoom) _Zoom = _MaximumZoom;
else _Zoom = value;
if (MapViewOnChange != null) MapViewOnChange();
}
}
Zoom 代表以地圖單位 (Km、度等) 表示的地圖可視寬度。例如單位為 Km,Zoom=500 即顯示寬 500 公里範圍。此概念與 MapInfo 一致。
核心方法 Utilities.Transform.WorldtoMap(Point p, Map map):
public static System.Drawing.PointF WorldtoMap(SharpMap.Geometries.Point p, SharpMap.Map map) {
System.Drawing.PointF result = new System.Drawing.PointF();
double height = (map.Zoom * map.Size.Height) / map.Size.Width; // 可視高度 (地圖單位)
double left = map.Center.X - map.Zoom / 2; // 左上角 X
double top = map.Center.Y + height / 2; // 左上角 Y
double pxSize = map.Zoom / map.Size.Width; // 每像素代表地圖單位數
result.X = (float)Math.Round((p.X - left) / pxSize, 0);
result.Y = (float)Math.Round((top - p.Y) / pxSize, 0); // Y 軸方向相反
return result;
}
left, top:目前視窗左上角世界座標。height:依寬高比換算的可視高度。pxSize:解析度 (地圖單位/像素)。top - p.Y。對應方法 MapToWorld(PointF p, Map map),反向運算用於滑鼠點選查詢 (Identify)、框選等互動。
left, height, top, pxSize 僅在 Zoom 或 Center 變更時需重算,建議在 Map.ViewChanged 事件中快取,避免每個點重複計算 (渲染時呼叫極頻繁)。
目前 SharpMap 0.9 尚無內建單位與投影管理。ArcGIS/MapInfo 支援圖層級投影定義,渲染時動態將各圖層座標投影至地圖座標系再疊加。未來實現應於渲染管線中對每個幾何物件套用投影轉換,而非資料載入時轉換 (因空間資料庫無法一次性載入全量資料,且分析需保持原始座標)。
理解 Zoom 語意、WCS/影像座標雙向轉換公式,是掌握 SharpMap 渲染核心、實現自訂圖層、滑鼠互動與效能優化的關鍵。動態投影支援是下一階段重要演進方向。