Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

Due to some constraints, that I will not go into, I have found myself needing to implement custom panning in my application.

The ArcGIS API reference suggests using the following methods:

IScreenDisplay2.PanStart(IPoint start)    // Starts a pan
IScreenDisplay2.PanMoveTo(IPoint moveTo)  // Moves to a point
IScreenDisplay2.PanEnd()                  // Ends the pan

Each of these methods is called in the following event handlers (respectively):

IMapControl4.OnMouseDown     // Call PanStart()
IMapControl4.OnMouseMove     // Call PanMoveTo()
IMapControl4.OnMouseUp       // Call PanEnd()

So all of that works fine, the events are handled, the panning starts, everyone is happy.

-but-

Where the screen actually pans is not where I have dragged my cursor. The map slides around in a somewhat deterministic pattern, but I can't seem to figure out how to compensate for what the API is doing. I have been unable to find any enlightening documentation.

Does anyone have experience with this part of the API? Sample code or documentation would be great!

share|improve this question
1  
Did you try setting up a debug statement to print out IDisplayTransformation.DeviceFrame as the map completes each pan? In the past, I have noticed under certain conditions the device frame size gets changed to an inappropriate value. –  Kirk Kuykendall Jun 20 '11 at 18:27
    
@Kirk - The DeviceFrame does not change at all when panning. That is to be expected though, correct? The device frame is just the size of the frame in device coordinates (pixels) –  tbridge Jun 20 '11 at 18:37
    
Correct, it should not change. Did you try listening to ITransformEvents.VisibleBoundsUpdated on the displaytransformation instance? Maybe it is getting called twice? Also, did you try calling TrackPan instead? –  Kirk Kuykendall Jun 20 '11 at 19:06
    
@Kirk No luck with VisibleBoundsUpdated calling twice. I would use TrackPan() but I need to continue to handle mouse events while panning and they are supressed during a TrackPan –  tbridge Jun 20 '11 at 19:59
    
Can you post the code in the event handlers. Does the panning terminate OnMouseUp and just ends up in an unexpected location? Have you tried creating a point from the X,Y of OnMouseDown and OnMouseUp? Do they correspond with where panning starts and ends. –  Jakub Jun 26 '11 at 0:44

1 Answer 1

I tried this @ version 10 SP 1 but it should work on any version.

public class PanTool extends BaseCommand implements ITool {
private HookHelper hookHelper = null;
private IScreenDisplay display;

public PanTool()    {
    this.category = "Text";
    this.caption = "Text";
    this.message = "Text";
    this.toolTip = "Text";
    this.name = "Text";
    this.bitmapPath = System.getProperty("user.dir") + "/cmdbitmaps/your_icon.bmp";
    this.enabled = true;
}

@Override
public void onCreate(Object hook)   {
    if (hook == null)
        return;
    try {
        hookHelper = new HookHelper();
        hookHelper.setHookByRef(hook);
    } catch (Exception e)   {
        e.printStackTrace();
    }
}

@Override
public void onClick()   {
    try {
        MapControl map = (MapControl) ((ToolbarControl) hookHelper.getHook()).getBuddy();
        map.setCurrentToolByRef(this);
    } catch (Exception e)   {
        e.printStackTrace();
    }
}

@Override
public void onMouseDown(int button, int shift, int x, int y) throws IOException, AutomationException {
    if(button == 1) {
        MapControl map = (MapControl) ((ToolbarControl) hookHelper.getHook()).getBuddy();
        display = map.getActiveView().getScreenDisplay();

        display.panStart(display.getDisplayTransformation().toMapPoint(x, y));
    }
}

@Override
public void onMouseUp(int button, int shift, int x, int y) throws IOException, AutomationException {
    if(button == 1 && display != null)  {
        display.panStop();
        MapControl map = (MapControl) ((ToolbarControl) hookHelper.getHook()).getBuddy();

        map.getActiveView().refresh();
    }
}

@Override
public void onMouseMove(int button, int shift, int x, int y) throws IOException, AutomationException {
    if(button == 1 && display != null)  {
        display.panMoveTo(display.getDisplayTransformation().toMapPoint(x, y));
    }
}

@Override
public boolean onContextMenu(int x, int y) throws IOException, AutomationException {
    return false;
}


@Override
public boolean deactivate() throws IOException, AutomationException {
    return true;
}

@Override
public int getCursor() throws IOException, AutomationException {
    return esriSystemMouseCursor.esriSystemMouseCursorHand;
}

@Override
public void onDblClick() throws IOException, AutomationException {

}

@Override
public void onKeyDown(int keyCode, int shift) throws IOException, AutomationException {

}

@Override
public void onKeyUp(int arg0, int arg1) throws IOException, AutomationException {

}

@Override
public void refresh(int arg0) throws IOException, AutomationException {

}

} }

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.