Hi,
I wrote a quick web service which renders a map and then generates an image of that map to send back to the client. I am having some issues with using the World Map Kit with it. If I use Google as the base layer then it works fine but if I try to render the world map kit layers I get a blank map. See the attached. Any ideas what might be going wrong? Doesn't seem to make any sense to me.
Here is the code that I am using for WorldMapKit:
[WebMethod]
public byte[] GetSignSearchResultMapImage(float latitude, float longitude, int imageWidth, int imageHeight) {
List<Layer> layers = new List<Layer>();
//GoogleMapsLayer google = new GoogleMapsLayer(ConfigurationManager.AppSettings["GoogleKey"]);
//google.MapType = GoogleMapsMapType.RoadMap;
//layers.Add(google);
if(Application["worldMapKit"] == null) {
WebServicesRenderMap renderMaps = new WebServicesRenderMap(ConfigurationManager.AppSettings["MapDataDirectory"]);
renderMaps.LoadLayers(layers);
Application["worldMapKit"] = layers;
}
layers = (List<Layer>)Application["worldMapKit"];
InMemoryFeatureLayer signLayer = (InMemoryFeatureLayer)this.buildSignSearchResultLayer(latitude, longitude);
signLayer.Open();
RectangleShape worldExtent = signLayer.GetBoundingBox();
signLayer.Close();
worldExtent.ScaleUp(20);
layers.Add(signLayer);
GeoImage geoImage = GdiPlusGeoCanvas.CreateGeoImage(imageWidth, imageHeight);
GdiPlusGeoCanvas.FillBackground(geoImage, new GeoSolidBrush(GeoColor.GeographicColors.DeepOcean));
GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();
gdiPlusGeoCanvas.BeginDrawing(geoImage, worldExtent, GeographyUnit.Meter);
for(int i = 0; i < layers.Count; i++) {
Layer layer = layers[i];
lock(layer) {
try {
layer.Open();
layer.Draw(gdiPlusGeoCanvas, new Collection<SimpleCandidate>());
} finally {
layer.Close();
}
}
}
if(gdiPlusGeoCanvas.IsDrawing) {
gdiPlusGeoCanvas.EndDrawing();
}
return GdiPlusGeoCanvas.ConvertGeoImageToMemoryStream(geoImage).ToArray();
}
private Layer buildSignSearchResultLayer(float latitude, float longitude) {
int distance = 300;
List<Sign> signs = SignInventoryDAL.SearchSigns(latitude, longitude, distance);
InMemoryFeatureLayer pointLayer = new InMemoryFeatureLayer();
pointLayer.Open();
pointLayer.Columns.Add(new FeatureSourceColumn("SignId"));
pointLayer.Columns.Add(new FeatureSourceColumn("Description"));
pointLayer.Columns.Add(new FeatureSourceColumn("Latitude"));
pointLayer.Columns.Add(new FeatureSourceColumn("Longitude"));
pointLayer.Close();
pointLayer.Name = "PointLayer";
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Description", "Arial", 8, DrawingFontStyles.Italic, GeoColor.StandardColors.Black, 10, 10);
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(Server.MapPath("../images/Stop.png")));
//Sets the projection parameters to go from Geodetic (EPSG 4326) or decimal degrees to Google Map projection (Spherical Mercator).
//Proj4Projection proj4 = new Proj4Projection();
//proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
//proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
////Applies the projection to the InMemoryFeatureLayer so that the point in decimal degrees (Longitude/Latitude) can be
////match the projection of Google Map.
//pointLayer.FeatureSource.Projection = proj4;
for(int i = 0; i < signs.Count; i++) {
Sign sign = signs[i];
Vertex vertex = new Vertex(this.convertToDecimalDegrees(sign.Longitude), this.convertToDecimalDegrees(sign.Latitude));
// Add position to the point layer, also need to check whether a marker should be rendered.
PointShape pointShape = new PointShape(vertex);
Feature feature = new Feature(pointShape);
feature.ColumnValues.Add("Sign", sign.SignId.ToString());
feature.ColumnValues.Add("Description", sign.Description);
feature.ColumnValues.Add("Latitude", sign.Latitude);
feature.ColumnValues.Add("Longitude", sign.Longitude);
pointLayer.InternalFeatures.Add(feature);
}
return pointLayer;
}
And this for Google:
[WebMethod]
public byte[] GetSignSearchResultMapImage(float latitude, float longitude, int imageWidth, int imageHeight) {
List<Layer> layers = new List<Layer>();
GoogleMapsLayer google = new GoogleMapsLayer(ConfigurationManager.AppSettings["GoogleKey"]);
google.MapType = GoogleMapsMapType.RoadMap;
layers.Add(google);
//if(Application["worldMapKit"] == null) {
// WebServicesRenderMap renderMaps = new WebServicesRenderMap(ConfigurationManager.AppSettings["MapDataDirectory"]);
// renderMaps.LoadLayers(layers);
// Application["worldMapKit"] = layers;
//}
//layers = (List<Layer>)Application["worldMapKit"];
InMemoryFeatureLayer signLayer = (InMemoryFeatureLayer)this.buildSignSearchResultLayer(latitude, longitude);
signLayer.Open();
RectangleShape worldExtent = signLayer.GetBoundingBox();
signLayer.Close();
worldExtent.ScaleUp(20);
layers.Add(signLayer);
GeoImage geoImage = GdiPlusGeoCanvas.CreateGeoImage(imageWidth, imageHeight);
GdiPlusGeoCanvas.FillBackground(geoImage, new GeoSolidBrush(GeoColor.GeographicColors.DeepOcean));
GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();
gdiPlusGeoCanvas.BeginDrawing(geoImage, worldExtent, GeographyUnit.Meter);
for(int i = 0; i < layers.Count; i++) {
Layer layer = layers<i>;
lock(layer) {
try {
layer.Open();
layer.Draw(gdiPlusGeoCanvas, new Collection<SimpleCandidate>());
} finally {
layer.Close();
}
}
}
if(gdiPlusGeoCanvas.IsDrawing) {
gdiPlusGeoCanvas.EndDrawing();
}
return GdiPlusGeoCanvas.ConvertGeoImageToMemoryStream(geoImage).ToArray();
}
private Layer buildSignSearchResultLayer(float latitude, float longitude) {
int distance = 300;
List<Sign> signs = SignInventoryDAL.SearchSigns(latitude, longitude, distance);
InMemoryFeatureLayer pointLayer = new InMemoryFeatureLayer();
pointLayer.Open();
pointLayer.Columns.Add(new FeatureSourceColumn("SignId"));
pointLayer.Columns.Add(new FeatureSourceColumn("Description"));
pointLayer.Columns.Add(new FeatureSourceColumn("Latitude"));
pointLayer.Columns.Add(new FeatureSourceColumn("Longitude"));
pointLayer.Close();
pointLayer.Name = "PointLayer";
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Description", "Arial", 8, DrawingFontStyles.Italic, GeoColor.StandardColors.Black, 10, 10);
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(Server.MapPath("../images/Stop.png")));
//Sets the projection parameters to go from Geodetic (EPSG 4326) or decimal degrees to Google Map projection (Spherical Mercator).
Proj4Projection proj4 = new Proj4Projection();
proj4.InternalProjectionParametersString = Proj4Projection.GetEpsgParametersString(4326);
proj4.ExternalProjectionParametersString = Proj4Projection.GetGoogleMapParametersString();
//Applies the projection to the InMemoryFeatureLayer so that the point in decimal degrees (Longitude/Latitude) can be
//match the projection of Google Map.
pointLayer.FeatureSource.Projection = proj4;
for(int i = 0; i < signs.Count; i++) {
Sign sign = signs<i>;
Vertex vertex = new Vertex(this.convertToDecimalDegrees(sign.Longitude), this.convertToDecimalDegrees(sign.Latitude));
// Add position to the point layer, also need to check whether a marker should be rendered.
PointShape pointShape = new PointShape(vertex);
Feature feature = new Feature(pointShape);
feature.ColumnValues.Add("Sign", sign.SignId.ToString());
feature.ColumnValues.Add("Description", sign.Description);
feature.ColumnValues.Add("Latitude", sign.Latitude);
feature.ColumnValues.Add("Longitude", sign.Longitude);
pointLayer.InternalFeatures.Add(feature);
}
return pointLayer;
}
Thanks
Curtis