Mouse Tekerleği İle Zoom Yapma

MapXtreme web uygulamalarında sürekli olarak eksikliğini hissettiğim bir husus vardı: Mouse tekerleği ile zoom yapma. ArcGIS Server, Autodesk MapGuide, hatta SharpMap bile bu desteği build-in olarak verirken MapXtreme’in vermemesi garibime gidiyordu. Ben bu özelliği oturup kendim implement etmeye karar verdim ve açıkçası tahmin ettiğim kadar da zor olmadığını gördüm. Server tarafında zoomlama işini yapacak olan sınıfın gayet basit olacağı aşikardı, muhtemelen asıl iş JavaScript’te bitecekti ve öyle de oldu.

Aşağıdaki adımlarda sıfırdan bir MapXtreme web projesi (daha doğrusu web site) oluşturup mouse scroll ile zoom desteğinin nasıl eklenebileceğini anlatmaya çalıştım. Hem Internet Explorer hem de Firefox’u destekleyecek şekilde yazdım.

1) Visual Studio’da New Web Site ile yeni bir MapXtreme Web projesi oluşturun.

2) Açılan New Web Site penceresinde MapXtreme 6.7.1 Web Application seçeneğini seçin. Location alanında HTTP seçin ve sağ tarafına

http://localhost/MxMouseWheelZoom

girin. Dil olarak C# seçin ve OK butonuna tıklayın.

3) MouseWheelZoomCommand adlı bir class oluşturun. (Ben bu örnekte App_Code dizininde oluşturdum.) Bu sınıfın kodları aşağıdaki gibi olsun:

using System;
using System.IO;
using System.Web;
using MapInfo.Mapping;
using MapInfo.WebControls;

namespace App_Code {

  [Serializable]
  public class MouseWheelZoomCommand : MapBaseCommand {
    private const double ZOOM_FACTOR = 0.7;

    public MouseWheelZoomCommand() {
      Name = "MouseWheelZoomCommand";
    }

    public override void Process() {
      string strWheelValue = Convert.ToString(HttpContext.Current.Request["WheelValue"]);
      int wheelValue;
      if (int.TryParse(strWheelValue, out wheelValue)) {
        MapControlModel model = MapControlModel.GetModelFromSession();
        model.SetMapSize(MapAlias, MapWidth, MapHeight);
        Map map = model.GetMapObj(MapAlias);
        MapInfo.Geometry.Distance distance;
        if (wheelValue > 0) {
          distance = new MapInfo.Geometry.Distance(map.Zoom.Value * ZOOM_FACTOR, map.Zoom.Unit);
        }
        else {
          distance = new MapInfo.Geometry.Distance(map.Zoom.Value / ZOOM_FACTOR, map.Zoom.Unit);
        }
        map.Zoom = distance;
        MemoryStream ms = model.GetMap(MapAlias, MapWidth, MapHeight, ExportFormat);
        StreamImageToClient(ms);
      }
    }
  }
}

4) Harita sayfanızın Page_Load event kodları aşağıdaki gibi olsun:

protected void Page_Load(object sender, EventArgs e) {
  if (StateManager.GetStateManagerFromSession() == null) {
    StateManager.PutStateManagerInSession(new AppStateManager());
  }
  MapControlModel controlModel = MapControlModel.SetDefaultModelInSession();
  if (controlModel.GetNamedCommand("MouseWheelZoomCommand") == null) {
    controlModel.Commands.Add(new MouseWheelZoomCommand());
  }
  StateManager.GetStateManagerFromSession().ParamsDictionary[StateManager.ActiveMapAliasKey] = MapControl1.MapAlias;
  StateManager.GetStateManagerFromSession().RestoreState();
}

5) Projenizin hemen altına js adlı bir dizin oluşturun. Bu dizinin altında MouseWheelScript.js adlı bir JavaScript dosyası oluşturun. Bunun içeriği de şöyle olsun:

var mapImage = top.document.getElementById("MapControl1_Image"); // Eğer MapControl ID niz bundan farklıysa burayı değiştirin
var serverCommand = "MouseWheelZoomCommand"; // 3. adımda oluşturduğumuz server-side sınıfımızın adı
function GetMouseWheelEvent(e) {
  var evt = window.event || e
  //delta, tekerlek yukarı döndürülünce +120, aşağı döndürülünce -120 değeri döndürür
  var delta=evt.detail? evt.detail*(-120) : evt.wheelDelta
  var url = "MapController.ashx?Command=" + serverCommand
  + "&Width=" + mapImage.width
  + "&Height=" + mapImage.height
  + "&ExportFormat=" + mapImage.exportFormat
  + "&Ran=" + Math.random()
  + "&WheelValue=" + delta;
  if (mapImage.mapAlias) {
    url +=  "&MapAlias=" + mapImage.mapAlias;
  }
  mapImage.src = url;
  //sayfa kaydırmada mouse tekerleğinin default hareketini disable et
  if (evt.preventDefault) {
    evt.preventDefault()
  }
  else {
    return false
  }
}
//Firefox'daki bir sürüm farkından dolayı gerekli ayrımı yap
var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel"
//Internet Explorer için
if (mapImage.attachEvent) {
  mapImage.attachEvent("on"+mousewheelevt, GetMouseWheelEvent);
}
else if (mapImage.addEventListener) { //W3C uyumlu tarayıcılar
  mapImage.addEventListener(mousewheelevt, GetMouseWheelEvent, false)
}

6) Harita sayfanızın (MapForm.aspx) sonuna, </form> tag’ini kapamadan hemen önce şu satırı kopyalayarak MouseWheelScript.js dosyasını harita sayfasına ekleyin:

<script type="text/javascript" language="javascript" src="js/MouseWheelScript.js"></script>

Bu kodu harita sayfasının sonuna eklememiz önemli çünkü mesela sayfanın başına veya <head> kısmına eklersek “mapImage is null” gibi bir hata ile karşılaşırız. Bu hatanın verilmesi normaldir çünkü sayfada önce MapControl (yani mapImage imajı) nesnesinin yüklenmesi gerekir, ki ancak ondan sonra scriptimizden onu çağırabilelim.

Söz konusu kodu sayfa sonuna eklersek mapImage imajımızın yüklenmiş olduğunu garantilemiş oluruz.

7) Solution Explorer’da Harita sayfanıza (MapForm.aspx) sağ tıklayarak Set As Start Page tıklayın.

8 ) Projeyi çalıştırın. Eğer “Unable to make the session state request to the session state server” hatasını alırsanız web.config dosyasına giderek

sessionState mode="StateServer"

değerini

sessionState mode="InProc"

olarak değiştirin ve projeyi tekrar çalıştırın.

9) MapXtreme Web projesinde mouse tekerleği ile zoom yapmanın tadını çıkarın. 😉

Çalışır durumdaki Visual Studio 2005 projesini aşağıdaki linkten indirebilirsiniz:

https://dl.dropbox.com/u/54151940/GIS/MapInfo/MapXtreme/Net/MapXtremeWebMouseWheelZoom.rar

  1. 01/11/2010 at 13:50

    Örnek dosyayı, MapXtreme 7 kurulu bir bilgisayarda çalıştırmak isteyen arkadaşlar için ek adımlar :

    1-Yeni bir MapXtreme Web Site oluşturun -> File->New->WebSite
    2-Yeni oluşturduğunuz Web Site a ait , solution explorer da “Web.config” dosyası göreceksiniz.Bu dosyaya çift tıklayın.
    3-WebConfig in içindeki MapInfo.WebControls assembly bilgisini içeren satırı bulun.
    Örneğin :

    4-Bu satırdaki , assemlyden sonra , çift tırnakların arasında kalan bilgiyi kopyalayın.(Çift tırnakları kopyalamayın)

    5-İndirdiğiniz örnek dosyadaki web.config dosyasını açıp, MapInfo.WebControls adlı assemly bilgisinin olduğu satırı bulun ve orada tırnak içinde kalan bilgiyi , bu bilgi ile değiştirin.

    6-İndirdiğiniz örnek web uygulamasındaki MapPage.aspx dosyasının en üstünde kalan Register Assemly=”MapInfo.WebControls .. ile başlayan satırın çift tırnaklarının arasında, daha önce kopyaladığınız assemly bilgisini yapıştırın.( bir önceki adımdaki bilgi ile aynı bilgiyi yapıştırın)

    7-Test edin

    Herkese iyi çalışmalar.

  2. 01/11/2010 at 13:51

    Örneğin kısmındaki bilgi çıkmamış , orada bulmanız gereken MapInfo.WebControls ile başlayan assemly bilgisi içeren web config satırıdır.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: