公司產品需整合電子地圖,選用開源專案 SharpMap(簡單易用、適合入門),輔以 MapWindow GIS 製作 Shapefile、NetTopologySuite 補足空間運算。
<smap:AjaxMapControl width="1600px" Height="600px" id="ajaxMap" runat="server"
OnClickEvent="MapClicked" onmouseout="toolTip();" OnViewChange="ViewChanged"
CssClass="Ly" UseCache="false" OnViewChanging="ViewChanging" ZoomSpeed="1" />
public static SharpMap.Map InitializeMap(Size size) {
var map = new SharpMap.Map(size);
// 國家圖層
var layCountries = new VectorLayer("Countries");
layCountries.DataSource = new ShapeFile(Server.MapPath(@"~\App_data\countries.shp"), true);
layCountries.Style.Fill = new SolidBrush(Color.Green);
layCountries.Style.Outline = Pens.Black; layCountries.Style.EnableOutline = true;
layCountries.SRID = 4326;
// 河流圖層
var layRivers = new VectorLayer("Rivers");
layRivers.DataSource = new ShapeFile(Server.MapPath(@"~\App_data\rivers.shp"), true);
layRivers.Style.Line = new Pen(Color.Blue, 1);
layRivers.SRID = 4326;
// 城市圖層
var layCities = new VectorLayer("Cities");
layCities.DataSource = new ShapeFile(Server.MapPath(@"~\App_data\cities.shp"), true);
layCities.Style.SymbolScale = 0.8f;
layCities.MaxVisible = 40; layCities.SRID = 4326;
// 國家標籤層
var layLabel = new LabelLayer("Country labels");
layLabel.DataSource = layCountries.DataSource;
layLabel.Enabled = true; layLabel.LabelColumn = "Name";
layLabel.Style = new LabelStyle { ForeColor = Color.White, Font = new Font(FontFamily.GenericSerif, 12), BackColor = new SolidBrush(Color.FromArgb(128, 255, 0, 0)) };
layLabel.MaxVisible = 90; layLabel.MinVisible = 30;
layLabel.Style.HorizontalAlignment = HorizontalAlignmentEnum.Center;
layLabel.SRID = 4326;
layLabel.MultipartGeometryBehaviour = MultipartGeometryBehaviourEnum.Largest;
// 城市標籤層
var layCityLabel = new LabelLayer("City labels");
layCityLabel.DataSource = layCities.DataSource;
layCityLabel.Enabled = true; layCityLabel.LabelColumn = "Name";
layCityLabel.Style = new LabelStyle { ForeColor = Color.Black, Font = new Font(FontFamily.GenericSerif, 11) };
layCityLabel.MaxVisible = layLabel.MinVisible;
layCityLabel.Style.HorizontalAlignment = HorizontalAlignmentEnum.Left;
layCityLabel.Style.VerticalAlignment = VerticalAlignmentEnum.Bottom;
layCityLabel.Style.Offset = new PointF(3, 3);
layCityLabel.Style.Halo = new Pen(Color.Yellow, 2);
layCityLabel.TextRenderingHint = TextRenderingHint.AntiAlias;
layCityLabel.SmoothingMode = SmoothingMode.AntiAlias;
layCityLabel.SRID = 4326;
layCityLabel.LabelFilter = LabelCollisionDetection.ThoroughCollisionDetection;
layCityLabel.Style.CollisionDetection = true;
// 圖層疊加順序決定繪製順序
map.Layers.Add(layCountries);
map.Layers.Add(layRivers);
map.Layers.Add(layCities);
map.Layers.Add(layLabel);
map.Layers.Add(layCityLabel);
map.MaximumZoom = 360;
map.BackColor = Color.LightBlue;
map.Zoom = 360;
map.Center = new SharpMap.Geometries.Point(0, 0);
return map;
}
ShapeFile 實作 IProvider 介面。LabelColumn 指定顯示欄位,MaxVisible/MinVisible 控制可見縮放範圍(常被忽略導致標籤消失)。map.Layers.Add 順序即繪製順序,後加入者疊加在上層。var img = (Bitmap)map.GetMap();
context.Response.ContentType = "image/png";
using (var ms = new MemoryStream()) {
img.Save(ms, ImageFormat.Png);
img.Dispose();
context.Response.OutputStream.Write(ms.ToArray(), 0, (int)ms.Length);
}
下篇將實作:點擊地圖要素顯示屬性資訊彈窗。