Panorâmica personalizada usando o ArcGIS Engine

8

Devido a algumas restrições, nas quais não vou entrar, me deparei com a necessidade de implementar o panning personalizado no meu aplicativo.

A referência da API do ArcGIS sugere o uso dos seguintes métodos:

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

Cada um desses métodos é chamado nos seguintes manipuladores de eventos (respectivamente):

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

Então, tudo isso funciona bem, os eventos são tratados, o panorama começa, todo mundo fica feliz.

-mas-

Onde a tela realmente se move não é onde eu arrastei meu cursor. O mapa desliza em um padrão um pouco determinístico, mas não consigo descobrir como compensar o que a API está fazendo. Não consegui encontrar nenhuma documentação esclarecedora.

Alguém tem experiência com esta parte da API? Exemplo de código ou documentação seria ótimo!

tbridge
fonte
1
Você tentou configurar uma instrução de depuração para imprimir IDisplayTransformation.DeviceFrame à medida que o mapa conclui cada panorama? No passado, eu notei sob certas condições que o tamanho do quadro do dispositivo é alterado para um valor inadequado.
Kirk Kuykendall
@ Kirk - O DeviceFramenão muda em nada durante a panorâmica. Isso é de se esperar, certo? A carcaça do dispositivo é apenas o tamanho do quadro em coordenadas do dispositivo (pixels)
tbridge
Correto, não deve mudar. Você tentou ouvir ITransformEvents.VisibleBoundsUpdated na instância de transformação de exibição? Talvez esteja sendo chamado duas vezes? Além disso, você tentou ligar para o TrackPan ?
Kirk Kuykendall
@ Kirk Sem sorte em VisibleBoundsUpdatedligar duas vezes. Gostaria de usar TrackPan(), mas eu preciso para continuar a eventos do mouse punho durante o pan e são suprimidos durante umaTrackPan
tbridge
Você pode postar o código nos manipuladores de eventos. O panorama finaliza o OnMouseUp e acaba em um local inesperado? Você já tentou criar um ponto a partir do X, Y do OnMouseDown e OnMouseUp? Eles correspondem a onde o pan começa e termina.
Jakub Sisak GeoGraphics

Respostas:

2

Eu tentei este @ versão 10 SP 1, mas deve funcionar em qualquer versão.

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 {

}

}}

Mike
fonte