/// <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(); } }