/// <summary>
/// Gets image
/// </summary>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="backColor"></param>
/// <param name="useLayers"></param>
/// <param name="bboxWithGutters"></param>
/// <returns></returns>
protected Image GetImage(int width, int height, Color backColor, LayerBase[] useLayers, BoundingRectangle bboxWithGutters)
{
#region Проверка на занятость ресурсов
// проверяем заняты ли ресурсы
if (_drawingRequestSemaphore != null)
if (!_drawingRequestSemaphore.WaitOne(_drawingResourcesTimeOut))
throw new Exception( "There are currently no resources on the server needed to generate the map image.");
#endregion
try
{
bool cacheable = true;
string allLayerKey = "";
foreach (var layer in useLayers.OrderBy(x=>x.Alias))
{
cacheable &= layer.Cacheable;
allLayerKey += layer.Alias;
}
if (cacheable)
{
Image res = GetImage(bboxWithGutters, allLayerKey);
if (!ReferenceEquals(res,null))
{
return res;
}
}
//Рендер для надписей.
var wmsFeatureRender = new WmsFeatureRender(_map.RenderingSettings);
using (Image bmpWithGutters = new Bitmap(width + _gutterSize * 2, height + _gutterSize * 2))
{
// рисуем фон
using (Graphics g = Graphics.FromImage(bmpWithGutters))
g.Clear(backColor);
int i = 0;
//Проверка, что вообще есть что отображать.
if (!ReferenceEquals(useLayers, null) && (useLayers.Length > 0))
do
{
IFeatureRenderer _oldFeatureRender = null;
try
{
//Начинаем рисовать новый слой.
wmsFeatureRender.BeginLayerRender();
//Делаем слой видимым. Все остальные слои мы отключили выше.
useLayers[i].Visible = true;
//Настройка слоя перед рендерингом.
if (useLayers[i] is FeatureLayer)
OnPrepareRenderFeatureLayer(new PrepareRenderFeatureLayerArgs((FeatureLayer)useLayers[i]));
//Устанавливаем свой рендер, что бы перекрыть отрисовку названий
if (useLayers[i] is FeatureLayer)
{
_oldFeatureRender = (useLayers[i] as FeatureLayer).FeatureRenderer;
(useLayers[i] as FeatureLayer).FeatureRenderer = wmsFeatureRender;
}
byte[] titleInfo = null;
//Смотрим в кэше.
using (Image bmpLayer = GetImageFromChach(useLayers[i], out titleInfo, bboxWithGutters))
{
if (!ReferenceEquals(bmpLayer, null))
{
//Добавляем данные о названиях в wmsFeatureRender.
wmsFeatureRender.AddTitleInfo(titleInfo);
//Копируем картинку в результирующий тайл.
CopyImage(bmpLayer, bmpWithGutters);
continue;
}
}
//Если промах по кэш
using (
Image bmpLayer = new Bitmap(width + _gutterSize * 2, height + _gutterSize * 2,
PixelFormat.Format32bppArgb))
{
//Загружаем данные (почему это делается вне WMS сам не понимаю).
OnBeforeRenderNewImage(new RenderNewImageEventArgs(bboxWithGutters,useLayers[i]));
//MapAround загрузит только видимые слои, по этому не заморачиваемся на загрузки слоев по отдельности.
// рисуем карту
//MapAround отрендерит только видимые слои.
//Также он попытается отрендерить косметический слой, по этой причине мы проверяем выше, что бы он не был задан.
_map.Render(bmpLayer, bboxWithGutters);
//Копируем результат на результирующий растр.
CopyImage(bmpLayer, bmpWithGutters);
// Кладем в кэш растр слоя + информацию о названиях.
SetImageToChach(useLayers[i], bmpLayer, wmsFeatureRender.CurrentTitleInfo, bboxWithGutters);
}
}
finally
{
i++;
//Делаем слой не видимым.
useLayers[i - 1].Visible = false;
if (useLayers[i - 1] is FeatureLayer)
{
//Меняем рендер на старый
(useLayers[i - 1] as FeatureLayer).FeatureRenderer = _oldFeatureRender;
}
}
} while (i < useLayers.Length);
//После того как получили все слои запроса рендерим названия.
wmsFeatureRender.RenderTitle(bmpWithGutters, bboxWithGutters);
//Подготавливаем и отправляем результат.
Image bmp = new Bitmap(width, height);
CopyImageClipped(bmp, bmpWithGutters, width, height);
if (cacheable)
{
SetImage(bboxWithGutters,bmp,allLayerKey);
}
return bmp;
}
}
finally
{
// освобождаем ресурсы, связанные с рисованием карты
if (_drawingRequestSemaphore != null)
_drawingRequestSemaphore.Release();
}
}