1. We have table in access database to store the zip code details with following fields.
- ZipCode (type : Double)
- XMIN (type : Double)
- YMIN (type : Double)
- XMAX (type : Double)
- YMAX (type : Double)
- WKB_GEOMETRY (type : Long binary data)
- XCoordinate (type : Double)
- YCoordinate (type : Double)
3. We are adding the BaseLayer of Active region in the map.
Detailed Implementation :
--------------------------------------------------------------------------------
- We are having structure (GeoItem) to store the data which are fetched from the access database, with following properties.
- byte[] Wkb
- object Id
- double XMin
- double YMin
- double XMax
- double YMax
- double XCoord
- double YCoord
- Dictionary<string, object> Atributes;
------------------------------------------------------
Code: Select all
public interface IGeoProvider
{
IEnumerable<GeoItem> QueryBBox(double xmin, double ymin, double xmax, double ymax, string[] attributes);
}
------------------------------------------------------
Code: Select all
public IEnumerable<GeoItem> QueryBBox(double xmin, double ymin, double xmax, double ymax, string[] attributes)
{
// Query to get the geo items from Ole database.
String queryForActiveRegion = "SELECT *
"FROM Germany_5_digit_postcode as tGeo " +
"WHERE ZipCode in ( <Here we have list of more than 4000 zip codes> );
// initializing the command by query and the connection
using (var command = new OleDbCommand(queryForActiveRegion, Connection))
{
// executing the query so that we can get the geoItem result from the access database
using (var dataReader = command.ExecuteReader())
{
// reading the data from the reader
while (dataReader.Read())
{
// storing the data in GeoItem structure
var geoItem = new GeoItem
{
Wkb = (byte[])dataReader[0],
XMin = Convert.ToDouble(dataReader[1]),
YMin = Convert.ToDouble(dataReader[2]),
XMax = Convert.ToDouble(dataReader[3]),
YMax = Convert.ToDouble(dataReader[4]),
XCoord = Convert.ToDouble(dataReader[5]),
YCoord = Convert.ToDouble(dataReader[6])
};
geoItem.Atributes = new Dictionary<string, object>();
geoItem.Atributes["COLOR"] = dataReader[8];
}
else // this means that no attribute needed for the geoitem
{
// do nothing
}
// returing geoItem
yield return geoItem;
}
}
}
}
-------------------------------------------------------------------
We have two properties and one function as follows
- public IGeoProvider Provider { get; set; }
- public GdiTheme Theme { get; set; }
- public string CacheId{ get { return "TileRenderer"; }}
- public int MinZoom{get { return 0; }}
- public int MaxZoom{get { return 19; }}
Code: Select all
public Stream GetImageStream(int x, int y, int zoom)
{
using (var bmp = new Bitmap(256, 256))
{
var rect = GeoTransform.TileToPtvMercatorAtZoom(x, y, zoom);
Func<double, double, Point> mercatorToImage =
(
mercatorX, mercatorY) => new Point(
x = (int)((mercatorX - rect.Left) / (rect.Right - rect.Left) * 256),
y = 256 + (int)-((mercatorY - rect.Top) / (rect.Bottom - rect.Top) * 256)
);
using (var graphics = Graphics.FromImage(bmp))
{
var result = Provider.QueryBBox(rect.Left, rect.Top, rect.Right, rect.Bottom, Theme.RequiredFields);
foreach (var item in result)
{
var path = WkbToGdi.Parse(item.Wkb, mercatorToImage);
var style = Theme.Mapping(item);
if (style.Fill != null)
graphics.FillPath(style.Fill, path);
if (style.Outline != null)
graphics.DrawPath(style.Outline, path);
}
}
var stream = new MemoryStream();
bmp.Save(stream, ImageFormat.Png);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
}
- We are adding BaseLayer in map as follows.
Code: Select all
MMProvider provider = new MMProvider
{
Connection = oleDbConnection,
IdColumn = "IntId",
GeometryColumn = "WKB_GEOMETRY",
XMinColumn = "XMIN",
YMinColumn = "YMIN",
XMaxColumn = "XMAX",
YMaxColumn = "YMAX",
XCoordColumn = "XCoord",
YCoordColumn = "YCoord",
ActiveRegionZipCodes = activeRegionZipCodes
};
// getting the color for AK-Region so that we can apply that color for the same
System.Drawing.Color[] palette =
{
System.Drawing.ColorTranslator.FromHtml("#009EE3"),
System.Drawing.Color.LightGray
};
// getting the GdiTheme which has the color as well as the outlining specification; so that we can apply those specifications to AK-Region
var theme = new GdiTheme
{
RequiredFields = new[] { "COLOR" }, // need to fetch the field kk_kat
Mapping = gdiStyle => new GdiStyle
{
Fill = new System.Drawing.SolidBrush(palette[System.Convert.ToInt16(gdiStyle.Atributes["COLOR"]) - 1]),
Outline = System.Drawing.Pens.Black,
}
};
// creating the tileRenderer object using the MMProvider and GdiTheme; so that we can use the tile rendered to create tile canvas
var tileRenderer = new TileRenderer
{
Provider = provider,
Theme = theme,
};
// the collection of selected elements so that it will help us to color the AK-Region using those points
var selectedRegions = new ObservableCollection<System.Windows.Media.Geometry>();
// insert layer with two canvases
var activeRegionLayer = new BaseLayer("AK-Region")
{
CanvasCategories = new[] { CanvasCategory.Content, CanvasCategory.SelectedObjects },
CanvasFactories = new BaseLayer.CanvasFactoryDelegate[]
{
m => new TiledCanvas(m, tileRenderer) { IsTransparentLayer = true },
m => new SelectionCanvas(m, provider, selectedRegions)
},
Opacity = .5,
};
// insert the active region layer above the Background layer of map
ptvMap.Layers.Insert(ptvMap.Layers.IndexOf(ptvMap.Layers["Background"]), activeRegionLayer);
- Is there any alternate way to implement usecase like "Map and Market" of Demo center ?