Membuat LegendControl Alternatif di MapXtreme

Apa itu legenda peta? Legenda peta adalah kotak kecil yang biasanya berada di samping peta, berisi icon atau warna-warna tertentu yang menjelaskan informasi yang ada pada peta.  Legenda peta diperlukan agar pembaca memahami informasi simbol dan warna yang tersaji di peta. Legenda peta tidak pernah terlepas dari aplikasi GIS, karena legenda peta adalah kunci utama untuk memahami peta.

Mapxtreme sebagai salah satu aplikasi GIS menyediakan tool yang berfungsi untuk membuat legenda peta disebut LegendControl.

Kita hanya melakukan drag and drop legendcontrol ke halaman web, dan menambahkan beberapa baris kode di code behind. Secara otomatis legenda peta akan terbentuk.

Contoh berikut, membuat peta tematik-range, kemudian membuat legenda peta di legendcontrol secara otomatis.

Dim rt As New MapInfo.Mapping.Thematics.RangedTheme(fLyr, Me.GetThemeOrModifierExpression, themeAlias, 5, MapInfo.Mapping.Thematics.DistributionMethod.EqualCountPerRange)
Dim lgn As MapInfo.Mapping.Legends.Legend = map.Legends.CreateLegend(New System.Drawing.Size(400, 600))
Dim frame As MapInfo.Mapping.Legends.ThemeLegendFrame = MapInfo.Mapping.Legends.LegendFrameFactory.CreateThemeLegendFrame("legend1", "legendAlias1", rt)
lgn.Frames.Append(frame)

Hanya dengan kode diatas, legenda peta akan terbentuk secara otomatis. Tapi dalam beberapa kasus, legenda peta tidak terbentuk sama sekali atau terbentuk gambar kosong tanpa informasi apapun. Berawal dari masalah inilah, saya mencoba membuat legenda peta alternatif yang tidak menggunakan LegendControl tapi menggunakan ImageControl.

Alternatif 1

Tambahkan ImageControl ke halaman web. Dari contoh kode diatas, saya menambahkan kode untuk mengeksport legenda peta yang terbentuk menjadi file gambar (jpeg/gif/png).

Dim path As String = Server.MapPath("images/temp")
Dim legendExport As New MapInfo.Mapping.LegendExport(map, lgn)
legendExport.Format = ExportFormat.Gif
legendExport.Export(path & "\namaimageUnik.gif")

Nama gambar haruslah unik, ini dimaksudkan untuk membedakan pengguna yang mengakses prosedur ini. kemudian set URL dari ImageControl ke gambar yang terbentuk.

Image1.ImageUrl = "Images/temp/namaimageUnik.gif"

Hasilnya, kita akan memperoleh gambar legenda peta yang sama persis dengan yang dibuat oleh LegendControl. Kekurangan dari cara ini adalah, jika pengguna yang mengakses banyak, semakin lama akan terbentuk temporary image yang cukup banyak di server dan tentu saja cukup merepotkan.

Alternatif 2

Gambar legenda peta dibuat di file handler. Karena menggunakan file handler, kita tidak perlu menyimpan file gambar di server, sehingga kekurangan dari alternatif pertama dapat dihindari.

Pertama simpan objek tematik ke Session(“THEME”)

Dim rt As New MapInfo.Mapping.Thematics.RangedTheme(fLyr, Me.GetThemeOrModifierExpression, themeAlias, 5, MapInfo.Mapping.Thematics.DistributionMethod.EqualCountPerRange)
Session.Add("THEME", rt)

Buat file generic handler dengan nama LegendHandler.ashx untuk membaca informasi dari Session(“THEME”). Dan tulis kode berikut.

<%@ WebHandler Language="VB" Class="LegendHandler" %>
Imports System
Imports System.Web
Imports System.Drawing.Drawing2D
Imports System.Drawing
Public Class LegendHandler : Implements IHttpHandler, IReadOnlySessionState
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Try
            If Not HttpContext.Current.Session("THEME") Is Nothing Then
                Dim theme As MapInfo.Mapping.Thematics.ITheme
                theme = CType(HttpContext.Current.Session("THEME"), MapInfo.Mapping.Thematics.ITheme)
                Dim peta As MapInfo.Mapping.Map = getMapObj()
                Dim lgn As MapInfo.Mapping.Legends.Legend = peta.Legends.CreateLegend(New System.Drawing.Size(400, 600))
                Dim frame As MapInfo.Mapping.Legends.ThemeLegendFrame
                frame = MapInfo.Mapping.Legends.LegendFrameFactory.CreateThemeLegendFrame("legend1", "legendAlias1", theme)
                lgn.Frames.Append(frame)
                context.Response.Clear()
                context.Response.ContentType = "image/jpeg"
                Dim LgnExp As New MapInfo.Mapping.LegendExport(peta, lgn)
                Dim LgnImg As System.Drawing.Image = LgnExp.Export()
                LgnImg.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                LgnImg.Dispose()
                HttpContext.Current.Session.Remove("THEME")
            Else
                NotAvailableLegend(context)
            End If
        Catch ex As Exception>
            HttpContext.Current.Session.Remove("THEME")
            NotAvailableLegend(context)
        End Try
    End Sub

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return True
        End Get
    End Property

    Private Function getMapObj() As MapInfo.Mapping.Map
        Return MapInfo.Engine.Session.Current.MapFactory.Item(0)
    End Function

    'Jika legenda peta tidak terbentuk atau ada error
    Private Sub NotAvailableLegend(ByVal context As HttpContext)
        Dim width As Integer = 200
        Dim height As Integer = 100
        Dim bitmap As New Bitmap(width, height, Imaging.PixelFormat.Format32bppPArgb)
        Dim g As Graphics = Graphics.FromImage(bitmap)
        g.SmoothingMode = SmoothingMode.AntiAlias
        Dim r As Rectangle = New Rectangle(0, 0, width, height)

        Dim format As StringFormat = New StringFormat()
        format.Alignment = StringAlignment.Center
        format.LineAlignment = StringAlignment.Center

        Dim nmFont As Font = New Font(FontFamily.GenericSansSerif.Name, 14, FontStyle.Bold)
        Dim path As GraphicsPath = New GraphicsPath()
        path.AddString("Map Legend Not Available", nmFont.FontFamily, CType(nmFont.Style, Integer), nmFont.Size, r, format)

        g.FillRectangle(Brushes.WhiteSmoke, r)
        g.FillPath(Brushes.Black, path)

        nmFont.Dispose()
        g.Dispose()

        context.Response.Clear()
        context.Response.ContentType = "image/jpeg"
        bitmap.Save(context.Response.OutputStream, Imaging.ImageFormat.Jpeg)
        bitmap.Dispose()
    End Sub
End Class

Sama seperti alternatif pertama, set URL dari ImageControl ke file handler.

Image1.ImageUrl = "legendhandler.ashx?id=" & Guid.NewGuid().ToString()

Saya menambahkan query string id=Guid.NewGuid().ToString() untuk membedakan gambar yang terbentuk, karena beberapa browser ketika refresh sering tidak merubah gambar karena nama yang sama dianggap gambar yang sama.

Hasilnya kurang lebih seperti ini

Jika tidak ada legenda peta yang dibuat, kita bisa mengaturnya untuk menampilkan informasi. Contohnya seperti gambar berikut

Update 03/02/2010
Ada pertanyaan menarik? Bagaimana jika legenda peta dibuat secara manual? Tidak dibuat secara default? Alternatif kedua, memang bisa diterapkan jika legenda peta dibuat secara default, tanpa merubah nilai interval maupun warna defaultnya. Jika legenda peta dibuat secara manual (custom), maka yang kita simpan dalam Session state adalah objek image hasil dari LegendExport, bukan objek tematik. Objek Image ini yang akan di proses di file handler.

Dim thm2 As MapInfo.Mapping.Thematics.RangedTheme = New MapInfo.Mapping.Thematics.RangedTheme(flyr2, rbl_type.SelectedValue.ToString, _
"ThemeALias", 3, Thematics.DistributionMethod.EqualRangeSize)

With thm2
     .Bins(0).Style.SymbolStyle.Color = Drawing.Color.Red
     .Bins(1).Style.SymbolStyle.Color = Drawing.Color.Yellow
     .Bins(2).Style.SymbolStyle.Color = Drawing.Color.Blue
End With

Dim frame2 As MapInfo.Mapping.Legends.LegendFrame = MapInfo.Mapping.Legends.LegendFrameFactory.CreateThemeLegendFrame("lgend2", "legendalias2", thm2)
lgn.Frames.Append(frame2)
frame2.Title = "KPI " & rbl_type.SelectedItem.Text & " Per Outlet"
frame2.SubTitle = "BULAN " & ddl_bulan.SelectedItem.Text
frame2.Rows(0).Text = "Kurang"
frame2.Rows(1).Text = "Sedang"
frame2.Rows(2).Text = "Baik"
Tematik.ThemesAndModifiers.LegendStyle(frame2)

Dim legendExport As New MapInfo.Mapping.LegendExport(map, lgn)
Dim lgnImg As System.Drawing.Image = legendExport.Export()
Session.Add("THEME", lgnImg) 'Ini yang dikirim ke file handler

Kode diatas adalah contoh membuat legenda secara manual. Perhatikan di baris akhir, objek yang disimpan di Session adalah image, bukan objek tematik.

Untuk kode di file handler dapat dilihat di bawah ini

<%@ WebHandler Language="VB" Class="LegendHandler" %>

Imports System
Imports System.Web
Imports System.Drawing.Drawing2D
Imports System.Drawing

Public Class LegendHandler : Implements IHttpHandler, IReadOnlySessionState
    
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Try
            If Not HttpContext.Current.Session("THEME") Is Nothing Then
                context.Response.Clear()
                context.Response.ContentType = "image/jpeg"
                Dim LgnImg As System.Drawing.Image = CType(HttpContext.Current.Session("THEME"), System.Drawing.Image)
                LgnImg.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                
                LgnImg.Dispose()
                HttpContext.Current.Session.Remove("THEME")
            Else
                NotAvailableLegend(context)
            End If
        Catch ex As Exception
            HttpContext.Current.Session.Remove("THEME")
            NotAvailableLegend(context)
        End Try
    End Sub
 
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
    
    'jika legenda peta gak terbentuk atau ada error
    Private Sub NotAvailableLegend(ByVal context As HttpContext)
        Dim width As Integer = 200
        Dim height As Integer = 100
        Dim bitmap As New Bitmap(width, height, Imaging.PixelFormat.Format32bppPArgb)
        Dim g As Graphics = Graphics.FromImage(bitmap)
        g.SmoothingMode = SmoothingMode.AntiAlias
        Dim r As Rectangle = New Rectangle(0, 0, width, height)
        
        Dim format As StringFormat = New StringFormat()
        format.Alignment = StringAlignment.Center
        format.LineAlignment = StringAlignment.Center

        Dim nmFont As Font = New Font(FontFamily.GenericSansSerif.Name, 14, FontStyle.Bold)
        Dim path As GraphicsPath = New GraphicsPath()
        path.AddString("Map Legend Not Available", nmFont.FontFamily, CType(nmFont.Style, Integer), nmFont.Size, r, format)

        g.FillRectangle(Brushes.WhiteSmoke, r)
        g.FillPath(Brushes.Black, path)

        nmFont.Dispose()
        g.Dispose()

        context.Response.Clear()
        context.Response.ContentType = "image/jpeg"
        bitmap.Save(context.Response.OutputStream, Imaging.ImageFormat.Jpeg)
        bitmap.Dispose()
    End Sub
End Class

Ini adalah contoh sederhana, silahkan dikembangkan lebih lanjut dan semoga bermanfaat.
Happy Coding

PS: dibuat menggunakan MapXtreme versi 6.8

Download sample

About Yuniar

Penulis sekarang lebih banyak bekerja menggunakan teknologi Microsoft .NET secara umum dan TIDAK lagi menggunakan aplikasi MapXtreme.net dari MapInfo. Karena itu mohon maaf, jika pertanyaan-pertanyaan mengenai MapXtreme sudah tidak bisa saya jawab lagi.

Posted on 2 Februari 2010, in MapXtreme, Web GIS and tagged , , . Bookmark the permalink. 14 Komentar.

  1. Wuih.. mantap..!! Ada sample aplikasinya gak?

  2. Boleh minta linknya juga, mas?
    anyway, aku baru mau belajar mapxtreme nih, n baru dapet web ini yg banyak membahas mapxtreme, thanks a lot,

  3. pak yuniar boleh nanya gakk?
    sya msih awam mengenai mapxtrme..oyah bagaimana cara mengeset tool legend control default yang ada dimapxtrme tool supaya legendnya terlihat dipeta?? petunjuk ditas dgn cara menyisipkan code, baris code yang dianjurkan diatas saya kurang paham penempatannya dmn……….apakah di event load-nya??
    mohon penjelasan spesifiknya.,
    thank uu

    • kalo legend control yang default anda tinggal drag aja taruh di page, lalu set property MapId (kalo gak salah.. sory lupa) dengan id dari mapcontrol. udah, Legendanya akan terbentuk sendiri gak pake kode apapun. Coba mas, buka sample2 bawannya mapxtreme.

      Kalo contoh yang saya tulis diatas, itu kalo bikin legend control sendiri, gak pake bawaannya mapxtreme.

      • sample yg mana ya pak?
        oya saya pernah coba hanya mengeset mapcontrol IDnya ajahh kox legendnya tdk mau terbentuk,ada setting lainnya gakk pak yuniar? defaut tool legend mapxtremenya menyarankan mengeset ‘mapcontrolID’ serta ‘properti’,,,properti yg dimaksud yg mana ya pak?? maklum pak saya msh awam.
        jdnya saya kurang paham.
        saya mhn penjelasaanya dr bpk yuniar…,,,,,

      • Kalo Markus install mapxtreme, pasti ada sample2 yang terinstal. Coba Markus cari di folder “Program Files/Mapinfo/MapXtreme/6.x.x/Samples”

  4. pak yuniar,saya uda coba set mapcontrolID dan legend aliasnya sesuai dgn perintah tool defaultnya,tp knp legendanya tdk terlihat? so,,hanya terbentuk gambar putih polos,ada yg kurang gaak pak?
    apa bener gakk pAkEk coding pak kalau bOat legend tool defaultnya?!!,,,
    mohon PenjElasannya pak yuniar,saia butuh informasinya,,,,
    thankss sebelumnya pak,,,…………………..

    • Kalo saya gak salah, memang gak perlu tambahan coding (maap lupa, udah lama gak buka mapxtreme). Coba deh mas Markus buka sample mapxtreme yang membahas tentang thematik
      lalu tambahkan tool legendcontrol, dan set MapControlid nya.
      Oya, satu lagi. Legend control biasanya muncul kalo kita bikin tematik.

      • tematik?,,,,
        yang seperti apa pak?? ada contohnya gakk?? saya kurang paham.

      • Apa anda pernah membuka contoh2 aplikasi bawaan dari mapxtreme????
        Semuanya ada disitu, kalo anda instal mapxtreme, pasti sample aplikasinya juga ikut terinstal
        cek disini
        C:\Program Files\MapInfo\MapXtreme\6.x.x\Samples\VisualStudio2008\Web\Features\Thematics

  5. Mas Yunia;
    software mapxtreme yg terbaru sama gak degan versi 4.8.2????
    trus yg versi 6…..(yg baru tu) dmna bsa download nya????
    gratis atau bayar???
    trimakasih mas….

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: