Gerando e modificando imagens de mapas do MapPoint Web Service

Francois Joffre - Microsoft Corporation

Fevereiro de 2005

Aplica-se a:

  • Microsoft MapPoint Web Service

Resumo: Aprenda a modificar imagens de mapas geradas pelo MapPoint Web Service. (20 páginas impressas.)

Nesta página

Introdução
Criando uma página ASP.NET que gera mapas
Modificando imagens de mapas
Conclusão

Introdução

Em um cenário comum, um aplicativo ASP.NET que processa mapas do MapPoint Web Service usa a opção MapReturnType.ReturnUrl ao chamar o método RenderServiceSoap.GetMap. Essa é a maneira mais fácil de lidar com imagens em um aplicativo ASP.NET, pois, para exibir um mapa, basta você definir o atributo src de uma marca HTML img como a URL retornada. No entanto, esse método tem algumas limitações. Em primeiro lugar, a URL do mapa que é retornada refere-se a um servidor do MapPoint Web Service externo ao seu próprio servidor, e talvez seja conveniente evitar essa situação por várias razões. Em segundo lugar, a URL é baseada na sessão e, portanto, tem limites de tempo e volume. Você receberá uma imagem expirada se tentar recarregar a imagem depois de 15 minutos ou cinco outras consultas de mapas, o que fizer primeiro.

Este artigo descreve como usar a opção MapReturnType.ReturnImage para obter um maior controle sobre a imagem do mapa. Para ilustrar os conceitos contidos neste artigo, desenvolveremos uma página ASP.NET que gera mapas com base nos parâmetros de consulta de URL. Em seguida, aproveitaremos o controle que temos sobre a imagem do mapa e usaremos as classes de desenho da GDI+ do Microsoft .NET Framework para modificar a imagem. Especificamente, adicionaremos uma marca d'água, exibiremos mais de 100 pinos e realçaremos polígonos.

Este artigo assume que você já esteja familiarizado com o MapPoint Web Service de forma geral, a API SOAP do MapPoint Web Services e as classes de desenho da GDI+. Para obter mais informações sobre o MapPoint Web Service ou para se inscrever em uma conta de avaliação, visite o site do MapPoint Web Service (em inglês). Para obter mais informações sobre como programar com o MapPoint Web Service, consulte o SDK do MapPoint Web Service (em inglês).

Criando uma página ASP.NET que gera mapas

Como estamos trabalhando no contexto de um aplicativo habilitado para Web, a imagem do mapa deve ser gerada em um local diferente da página na qual é exibida. Portanto, a página que contém o mapa deve transmitir informações sobre o local de exibição para a página que processa o mapa. Você pode transmitir essas informações de várias maneiras. Por exemplo, é possível usar parâmetros de sessão para que a página que processa o mapa obtenha as informações nas variáveis de sessão definidas pela página de chamada. Neste artigo, usaremos parâmetros de pesquisa para transmitir as informações.

A página de chamada criará uma URL com as informações da página que processa o mapa. Esse método tem o benefício de tornar cada mapa exclusivo com base na URL para que ele possa receber um indicador. Além disso, os mapas processados dessa maneira são fáceis de testar, pois você pode criar a URL na barra de endereços do navegador. Por outro lado, esse método também os torna vulneráveis. Portanto, talvez seja conveniente considerar a adição de algum tipo de criptografia caso planeje usar esse método em um aplicativo publicamente disponível na Internet.

A página que processa o mapa pode aceitar vários parâmetros de personalização, por exemplo, para especificar o ponto central ou o tamanho do mapa. Este artigo concentra-se em alguns parâmetros essenciais. Primeiro, definiremos uma classe que especifica os parâmetros possíveis e como recuperá-los e, em seguida, usaremos a classe no código da página que processa o mapa.

Obtendo os parâmetros do mapa

Para processar um mapa, devemos, no mínimo, especificar valores para as propriedades DataSourceName e Views (ou Route) do objeto MapSpecification. Em seguida, desenvolveremos nosso aplicativo de forma que os objetos DataSource e ViewByHeightWidth possam também ser especificados (embora outros tipos de modos de exibição também possam ser implementados). O mapa também aceitará um pino de exibição. Finalmente, permitiremos a especificação de altura e largura personalizadas para o mapa.

O exemplo de código a seguir contém uma classe simples que aceita um conjunto definido de parâmetros da seqüência de caracteres de consulta para obter os elementos do mapa que acabamos de descrever e os transforma em uma estrutura facilmente usada pelo MapPoint Web Service.

A classe é formada a partir de um objeto System.Web.UI.Page, o qual será usado para recuperar os parâmetros da seqüência de caracteres de consulta. A classe é construída de forma a poder usar valores padrão definidos no arquivo Web.config para alguns parâmetros, como o nome da fonte de dados e a largura e altura, para que sejam transmitidas menos informações para a URL do mapa.

[C#]
public class MapParams
{
   private NameValueCollection requestParams;
   private NameValueCollection configParams;

//Declare constants to define the names of the parameters
//in the URL query string.
   public const string ParamPushpin="PP";
   public const string ParamDataSource="DSN";
   public const string ParamViewHeightWidth="VHW";
   public const string ParamMapWidth="W";
   public const string ParamMapHeight="H";

   public MapParams(System.Web.UI.Page page)
   {
      requestParams=page.Request.Params;
      configParams=ConfigurationSettings.AppSettings;
   }

//If there is a non-empty element with the given key defined 
//in the page request, return it.
//Otherwise, if there is an element with the given key in the 
//Web.config file, return that.
//Else, return an empty string.
   public string this[string key]
   {
      get
      {
         if (null!=requestParams[key] && requestParams[key].Length>0)
         {
            return requestParams[key];
         }
         if (null!=configParams[key] && configParams[key].Length>0)
         {
            return configParams[key];
         }
         return String.Empty;
      }
   }

//Convert a given string to a double. If the string is not
//a number or is null, return 0.
   private static double GetStringAsDouble(string number)
   {
      try
      {
         return Double.Parse(number);
      }
      catch (ArgumentNullException)
      {
         return 0;
      }
      catch (FormatException)
      {
         return 0;
      }
   }

//Convert a given string to an int. If the string is not
//a number or is null, return 0.
   private static int GetStringAsInt(string number)
   {
      try
      {
         return Int32.Parse(number);
      }
      catch (ArgumentNullException)
      {
         return 0;
      }
      catch (FormatException)
      {
         return 0;
      }
   }

   public string DataSource
   {
      get
      {
         return this[ParamDataSource];
      }
   }

   public int MapWidth
   {
      get
      {
         return GetStringAsInt(this[ParamMapWidth]);
      }
   }

   public int MapHeight
   {
      get
      {
         return GetStringAsInt(this[ParamMapHeight]);
      }
   }

//Return the ViewByHeightWidth property for the map to be rendered.
//The parameter that holds the value is assumed to be of the form
//Latitude:Longitude:Height:Width.
//If Height and Width aren't defined, they default to 1 and 1.
//If Latitude and Longitude aren't defined, they default 
//to 0 and 0.
   public ViewByHeightWidth View
   {
      get
      {
         ViewByHeightWidth retView=new ViewByHeightWidth();
         retView.CenterPoint=new LatLong();
         string[] vhw=this[ParamViewHeightWidth].Split(new char[] {':'});
         if (vhw.Length>=2)
         {
            retView.CenterPoint.Latitude=GetStringAsDouble(vhw[0]);
            retView.CenterPoint.Longitude=GetStringAsDouble(vhw[1]);
         }
         else
         {
            retView.CenterPoint.Latitude=0;
            retView.CenterPoint.Longitude=0;
         }
         if (vhw.Length>=4)
         {
            retView.Height=GetStringAsDouble(vhw[2]);
            retView.Width=GetStringAsDouble(vhw[3]);
         }
         else
         {
            retView.Height=1;
            retView.Width=1;
         }
         return retView;
      }
   }

//Return the icon (pushpin) to display on the map.
//The format of the pushpin is assumed to be in the form
//Latitude:Longitude:IconName:Label:IconDataSource.
//Only Latitude and Longitude are required. All other parameters
//have default values.
//If no pushpin is set in the query string, return null.
   public Pushpin Icon
   {
      get
      {
         Pushpin retP=new Pushpin();
         string[] pp=this[ParamPushpin].Split(new char[] {':'});
         if (pp.Length>=2)
         {
            retP.LatLong=new LatLong();
            retP.LatLong.Latitude=GetStringAsDouble(pp[0]);
            retP.LatLong.Longitude=GetStringAsDouble(pp[1]);
            if (pp.Length>=3)
            {
               retP.IconName=pp[2];
            }
            else
            {
               retP.IconName="32"; //Default to pink asterisk.
            }
            if (pp.Length>=4)
            {
               retP.Label=pp[3];
            }
            if (pp.Length>=5)
            {
               retP.IconDataSource=pp[4];
            }
            else
            {
               retP.IconDataSource="MapPoint.Icons";
            }
            return retP;
         }
         else
         {
            return null;
         }
      }
   }
}

Processando o mapa

Agora que temos as informações necessárias, podemos trabalhar na página ASP.NET que processará o mapa. Primeiro, devemos definir o tipo MIME da página para que ele retorne uma imagem.

Para definir o tipo MIME

  1. No Microsoft Visual Studio, crie um novo formulário da Web, abra-o e alterne para o modo de exibição HTML.

  2. Remova todo o código, com exceção da primeira linha, a qual contém a diretiva Page. Na diretiva Page, adicione um atributo chamado ContentType e defina-o como "image/png". Por exemplo, se o formulário da Web chamar MapServer.aspx, o arquivo de origem do ASPX conterá o seguinte código:

      <%@ Page ContentType="image/png" language="c#"
      Codebehind="MapServer.aspx.cs" AutoEventWireup="false"
      Inherits="SolutionName.MapServer" %>
      

Observe que estamos usando o formato PNG para a imagem retornada, em vez do formato GIF, que é o padrão do MapPoint Web Service. Poderíamos ter usado o formato GIF, mas nas próximas seções modificaremos a imagem do mapa usando a classe Graphics do espaço para nome System.Drawing, a qual é principalmente um invólucro ao redor da GDI+. O mecanismo da GDI+ usa codificação de 32 bits por pixel ao modificar imagens. As imagens GIF estão limitadas a uma paleta de 256 cores e, quando você está trabalhando com a GDI+, a imagem é convertida em 32 bits por pixel. Quando uma imagem modificada dessa maneira é gravada em um arquivo GIF, o mecanismo usa uma paleta de cores de meio-tom, o que resulta em uma imagem pontilhada. Para obter mais informações, consulte o artigo da Microsoft Knowledge Base: HOW TO: Save a .gif File with a New Color Table By Using Visual C# .NET (em inglês).

A codificação PNG, ao contrário da codificação GIF, não está limitada a uma paleta de 256 cores; portanto, salvar uma imagem GDI+ no formato PNG não resulta em pontilhados. Por outro lado, a imagem resultante é um tanto maior do que uma imagem GIF correspondente. Se houver problema de largura de banda, use as informações contidas no artigo da Knowledge Base para implementar uma solução usando codificação GIF. Lembre-se de que esse problema será relevante somente se você quiser modificar a imagem usando GDI+. Para apenas processar o mapa, defina o tipo MIME como "image/gif" e use o método WriteGifToStream, em vez do método WritePngToStream, no código a seguir.

O exemplo de código a seguir mostra o método que obtém a imagem do mapa seguido pelo código do método Page_Load, o qual processa o mapa.

[C#]
private MapParams mParams;
//Build a map based on query string parameters, as defined by mParams.
private MapImage GetMap()
{
//Create a new MapSpecification object to build the map.
   MapSpecification mapSpec=new MapSpecification();
   //Get the DataSource directly from mParams.
   mapSpec.DataSourceName=mParams.DataSource;
//Set the view.
   mapSpec.Views=new MapView[1];
   mapSpec.Views[0]=mParams.View;
//Set the pushpin (if applicable).
   Pushpin icon=mParams.Icon;
   if (null!=icon)
   {
      mapSpec.Pushpins=new Pushpin[1];
      mapSpec.Pushpins[0]=icon;
   }
//Set the properties of the MapOptions object and
//set the width and height properties of mParams.
   mapSpec.Options=new MapOptions();
   mapSpec.Options.ReturnType=MapReturnType.ReturnImage;
   mapSpec.Options.Format=new MapPointService.ImageFormat();
   mapSpec.Options.Format.MimeType="image/png";
   mapSpec.Options.Format.Width=mParams.MapWidth;
   mapSpec.Options.Format.Height=mParams.MapHeight;
//Call MapPoint Web Service and return its corresponding 
//MapImage object.
   return RenderService.GetMap(mapSpec)[0];
}

//Write the contents of a bitmap to a stream, in GIF format.
private void WriteGifToStream(Bitmap image, Stream outStream)
{
   image.Save(outStream,System.Drawing.Imaging.ImageFormat.Gif);
   image.Dispose();
}

//Write the contents of a bitmap to a stream, in PNG format.
//Because PNG cannot be written to a non-seekable stream, an
//intermediate MemoryStream object (which is seekable) is used.
private void WritePngToStream(Bitmap image, Stream outStream)
{
   MemoryStream writeStream=new MemoryStream();
   image.Save(writeStream,System.Drawing.Imaging.ImageFormat.Png);
   writeStream.WriteTo(outStream);
   image.Dispose();
}

private void Page_Load(object sender, System.EventArgs e)
{
//Initialize the parameters from the query string.
   mParams=new MapParams(this);
   MapImage map=GetMap();
   MemoryStream imageStream=new MemoryStream(map.MimeData.Bits);
   Bitmap rawBitmap=new Bitmap(imageStream,false);
//Code to modify the image will be added here
//and the following line will be deleted.
   WritePngToStream(rawBitmap,Response.OutputStream);
}

Chamando a página

Agora, vamos confirmar se podemos recuperar um mapa chamando a página que acabamos de criar. Supondo-se que o nome do formulário da Web seja MapServer.aspx, o nome da solução seja Mapper e o servidor seja executado no host local, a URL a seguir retornará o mapa mostrado na Figura 1:

https://localhost/Mapper/MapServer.aspx?DSN=MapPoint.NA&VHW=47.6:-
122.33:1:1&PP=47.6:-122.33:33:You+are+here&W=400&H=300

ms980711.mws_imgmod1(pt-br,MSDN.10).gif

Figura 1. Mapa do MapPoint Web Service

Como a classe MapParams pode obter parâmetros do arquivo Web.config, podemos optar por reduzir o comprimento da URL adicionando as seguintes chaves à seção appSettings do arquivo Web.config:

<appSettings>
   <add key="DSN" value="MapPoint.NA"/>
   <add key="W" value="400"/>
   <add key="H" value="300"/>
</appSettings>

Em seguida, podemos obter o mesmo mapa usando a seguinte URL reduzida:

https://localhost/Mapper/MapServer.aspx?VHW=47.6:-122.33:1:1&PP=47.6:-
122.33:33:You+are+here

Modificando imagens de mapas

Agora que já vimos como é fácil criar uma página que gera mapas, vamos aproveitar o controle que temos dos bits do mapa para modificar a imagem.

Usando a GDI+

Como mencionado anteriormente, podemos usar a classe Graphics do espaço para nome System.Drawing para modificar imagens. O código da seção anterior contém um comentário que indica onde ele deve ser incluído nesta seção. Para modificar a imagem do mapa, substitua o comentário pelo código a seguir e remova a linha de código indicada no comentário.

[C#]
   
   Bitmap mapBitmap=new Bitmap(mParams.MapWidth,mParams.MapHeight);
   Graphics mapGraphics=Graphics.FromImage(mapBitmap);
   mapGraphics.DrawImage(rawBitmap,0,0,mParams.MapWidth,mParams.MapHeight);
   rawBitmap.Dispose();
   DrawOnMap(mapGraphics);
   mapGraphics.Dispose();
   WritePngToStream(mapBitmap,Response.OutputStream);

Lembre-se de que o código chama um método, DrawOnMap, que ainda não foi definido. Esse método contém o código que realmente modifica a imagem. Para ilustrar apenas algumas das formas de modificação da imagem de um mapa, as próximas seções trazem alguns exemplos de como implementar esse método para executar várias manipulações de elementos gráficos. Há muitos outros tipos de manipulação, dependendo das necessidades de seu aplicativo.

Adicionando uma marca d'água

Você pode adicionar uma marca d'água a um mapa para que uma marca apareça. Uma marca d'água pode ser uma imagem ou um texto em fonte e cor específicas.

Os mapas do MapPoint Web Service já contêm marcas d'água. Quando você usa uma conta de avaliação do MapPoint Web Service, os mapas retornados pelo serviço contêm uma marca d'água em cada canto, com exceção do canto inferior direito. Nossos exemplos usarão esse canto para exibir marcas d'água personalizadas.

O exemplo a seguir mostra uma versão do método DrawOnMap, o qual exibe uma imagem como uma marca d'água.

[C#]
private void DrawOnMap(Graphics mapGraphics)
{
   Bitmap waterMark=new Bitmap(Request.PhysicalApplicationPath +
System.IO.Path.DirectorySeparatorChar + "store_locator.gif",false);
   ImageAttributes attr=new ImageAttributes();
   attr.SetColorKey(Color.White,Color.White);
   Rectangle rect=new Rectangle(0,0,waterMark.Width,waterMark.Height);
   Rectangle rect2=new Rectangle(mParams.MapWidth - waterMark.Width ,
mParams.MapHeight - waterMark.Height , waterMark.Width , waterMark.Height);
   mapGraphics.DrawImage(waterMark , rect2 , rect.X , rect.Y ,
rect.Width , rect.Height , GraphicsUnit.Pixel , attr);
}

A imagem usada nesse exemplo é uma versão redimensionada da imagem do Store Locator, um aplicativo de exemplo incluído no SDK do MapPoint Web Service. Ao usar esse código e a URL a seguir, obteremos a imagem mostrada na Figura 2.

https://localhost/Mapper/MapServer.aspx?VHW=47.6:-122.33:.25:.25&PP=47.6:-
122.33:33:You+are+here

ms980711.mws_imgmod2(pt-br,MSDN.10).gif
Figura 2. Mapa com imagem de marca d'água

Para exibir texto em vez de uma imagem, podemos usar os recursos de desenho de texto da GDI+ para implementar DrawOnMap da seguinte maneira:

[C#]
private void DrawOnMap(Graphics mapGraphics)
{
   Font font=new Font("Courier New",13,FontStyle.Bold);
   string text="Fourth Coffee";
   SizeF txtSize=mapGraphics.MeasureString(text,font);
   mapGraphics.DrawString(text , font , Brushes.DarkBlue ,
mParams.MapWidth - txtSize.Width , mParams.MapHeight - txtSize.Height);
}

Em seguida, usando a URL a seguir, obteremos a imagem mostrada na Figura 3.

https://localhost/Mapper/MapServer.aspx?VHW=47.6:-122.31:.25:.25&PP=47.6:-
122.31:33:You+are+here

ms980711.mws_imgmod3(pt-br,MSDN.10).gif
Figura 3. Mapa com marca d'água de texto

Exibindo mais de 100 pinos

Quando você usa o método GetMap do MapPoint Web Service para processar pinos, no máximo 100 pinos podem ser exibidos em um determinado mapa. Embora esse limite normalmente seja suficiente para a maioria dos tipos de aplicativos, talvez você precise exibir mais. Nesse caso, poderá desenhar os pinos diretamente no mapa. Para isso, primeiro convertemos as latitudes e as longitudes dos pinos em suas coordenadas correspondentes no sistema de imagens. Basta fazer uma chamada para o método ConvertToPoint do MapPoint Web Service.

O exemplo de código a seguir demonstra como usar o ConvertToPoint e desenhar pinos diretamente no mapa. Os pinos a serem exibidos são recuperados por meio do uso do método FindNearby do MapPoint Web Service na fonte de dados FourthCoffeeSample.

[C#]
private void DrawOnMap(Graphics mapGraphics)
{
//Call FindNearby to get locations to display on the map.
   FindNearbySpecification findSpec=new FindNearbySpecification();
   findSpec.DataSourceName="MapPoint.FourthCoffeeSample";
   findSpec.Filter=new FindFilter();
   findSpec.Filter.EntityTypeName="FourthCoffeeShops";
   findSpec.Options=new FindOptions();
   findSpec.Options.Range=new FindRange();
   findSpec.Options.Range.Count=500;
   findSpec.Options.ResultMask=FindResultMask.LatLongFlag;
   findSpec.LatLong=mParams.View.CenterPoint;
   findSpec.Distance=50;
   FindResults locs=FindService.FindNearby(findSpec);
//Display the retrieved locations as pushpins.
//Start by setting up a font to display the pushpins index.
   Font font=new Font("Arial",6,System.Drawing.FontStyle.Regular);
   StringFormat format=new StringFormat();
   format.LineAlignment=StringAlignment.Center;
   format.Alignment=StringAlignment.Center;
//Convert each retrieved latitude and longitude to its
//corresponding coordinate in the image system.
   if (locs!=null && locs.NumberFound>0)
   {
      LatLong[] latLongs=new LatLong[locs.Results.Length];
      for (int i=0;i&lt;latLongs.Length;i++)
      {
         latLongs[i]=locs.Results[i].FoundLocation.LatLong;
      }
      PixelCoord[] pixels=RenderService.ConvertToPoint(latLongs ,
mParams.View , mParams.MapWidth , mParams.MapHeight);
      int radius=10; //This is the radius of the pushpin.
//Draw a pushpin for each location.
      for (int i=0;i&lt;pixels.Length;i++)
      {
         PixelCoord pixel=pixels[i];
         Rectangle rect=new Rectangle(pixel.X-radius,pixel.Y-radius,radius*2,radius*2);
         mapGraphics.DrawEllipse(Pens.Lavender,rect);
         mapGraphics.FillEllipse(Brushes.Purple , rect.Left+1 , rect.Top+1 ,
rect.Width-2 , rect.Height-2);
         mapGraphics.DrawString(i.ToString() , font , Brushes.White ,
rect , format);
      }
   }
}

Usando a URL a seguir, obteremos a imagem mostrada na Figura 4.

https://localhost/Mapper/MapServer.aspx?VHW=47.6:-122.33:50:50

ms980711.mws_imgmod4(pt-br,MSDN.10).gif
Figura 4. Pinos desenhados diretamente no mapa

Realçando polígonos

Em algumas situações, talvez seja conveniente desenhar polígonos no mapa. Por exemplo, se a sua organização tiver definido regiões, você poderá delineá-las no mapa usando as coordenadas de latitude e longitude dos pontos que as definem. Uma região também pode ser uma área predefinida, como um país ou estado.

No exemplo a seguir, definiremos polígonos em alguns estados dos Estados Unidos. Os estados que vamos usar foram escolhidos porque suas fronteiras são praticamente retas e podem ser definidas com o uso de apenas alguns pontos. A maioria das regiões é bastante complexa e é definida por vários pontos. As coordenadas usadas nesse exemplo não são os pontos exatos que definem os polígonos desses estados, mas aproximações. Desenhar polígonos usando essas coordenadas em uma escala menor do que a usada aqui poderá resultar no alinhamento inexato das bordas dos polígonos com as fronteiras do estado.

Como no exemplo anterior, usaremos o método ConvertToPoint do MapPoint Web Service para converter as coordenadas de latitude e longitude em seus valores correspondentes no sistema de imagens de mapas. O método que faz essa conversão é um tanto complexo, pois aceita uma matriz de matrizes de polígonos definindo vários polígonos. Para fazer todas as conversões em uma chamada, devemos mesclar essa estrutura em uma matriz para transmitir para ConvertToPoint. Em seguida, expandiremos o resultado retornado para que se encaixe em uma matriz de matrizes equivalente àquela que foi transmitida.

[C#]
//Define the polygon outline for several United States states.
private readonly double[] polyUtah={
                     37.018358,-114.047383,
                     36.977346,-109.038487,
                     40.959254,-109.043443,
                     40.974323,-111.039242,
                     41.986081,-111.059671,
                     41.966724,-114.081657
                  };
private readonly double[] polyWyoming={
                     40.974323,-111.039242,
                     44.993195,-111.061800,
                     44.983281,-104.064114,
                     41.006306,-104.053786
                  };
private readonly double[] polyColorado={
                     36.977346,-109.038487,
                     40.959254,-109.043443,
                     40.982078,-102.063672,
                     36.984590,-102.047244
                  };
//Convert the latitudes and longitudes of a set of polygons 
//to an equivalent array of points in the map coordinate system.
private Point[][] ConvertPolygonsLatLongToPoints(double[][] polygons)
{
   int nbPoints=0;
   Point[][] points=new Point[polygons.Length][];
   for (int i=0;i<polygons.Length;i++)
   {
      nbPoints+=polygons[i].Length/2;
      points[i]=new Point[polygons[i].Length/2];
   }
   LatLong[] latLongs=new LatLong[nbPoints];
   int idx=0;
   foreach (double[] polygon in polygons)
   {
      for (int i=0;i<polygon.Length;i=i+2)
      {
         latLongs[idx]=new LatLong();
         latLongs[idx].Latitude=polygon[i];
         latLongs[idx].Longitude=polygon[i+1];
         idx++;
      }
   }
   PixelCoord[] coords=RenderService.ConvertToPoint(latLongs ,
mParams.View , mParams.MapWidth , mParams.MapHeight);
   idx=0;
   for (int i=0;i<points.Length;i++)
   {
      for(int j=0;j<points[i].Length;j++)
      {
         points[i][j]=new Point(coords[idx].X,coords[idx].Y);
         idx++;
      }
   }
   return points;
}
//Draw a polygon using different levels of transparency of a given
//color for the outline and interior.
private void OutlinePolygon(Graphics mapGraphics,Point[] poly,Color col)
{
   GraphicsPath path=new GraphicsPath();
   path.AddPolygon(poly);
   SolidBrush brush=new SolidBrush(Color.FromArgb(50,col));
   Pen pen=new Pen(Color.FromArgb(100,col),5);
   mapGraphics.FillPolygon(brush,poly);
   mapGraphics.DrawPolygon(pen,poly);
}

private void DrawOnMap(Graphics mapGraphics)
{
   double[][] polygons=new double[3][];
   polygons[0]=polyUtah;
   polygons[1]=polyWyoming;
   polygons[2]=polyColorado;
   Point[][] points=ConvertPolygonsLatLongToPoints(polygons);
   OutlinePolygon(mapGraphics,points[0],Color.Green);
   OutlinePolygon(mapGraphics,points[1],Color.Blue);
   OutlinePolygon(mapGraphics,points[2],Color.Red);
}

Depois, usando a URL a seguir, obteremos a imagem mostrada na Figura 5:

https://localhost/Mapper/MapServer.aspx?VHW=41:-108:1000:1000

ms980711.mws_imgmod5(pt-br,MSDN.10).gif
Figura 5. Mapa com polígonos

Conclusão

Você pode usar a opção MapReturnType.ReturnImage do método GetMap para gerar imagens de mapa diretamente de um servidor de uma empresa. A vantagem desse método é fornecer um maior controle sobre a imagem do mapa. Você pode tirar proveito desse controle modificando a imagem do mapa a fim de adicionar informações, desenhar pinos, realçar polígonos e muito mais. Os tipos de modificações ilustrados neste artigo são apenas exemplos. Dependendo das necessidades do aplicativo, há muito mais a fazer para modificar a aparência de um determinado mapa.

© .

Inicio da pagina