Package org.locationtech.udig.tools.edit

Source Code of org.locationtech.udig.tools.edit.EditBlackboardUtil$ViewportModelListener

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.tools.edit;

import java.awt.geom.AffineTransform;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.ILayerListener;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.Interaction;
import org.locationtech.udig.project.LayerEvent;
import org.locationtech.udig.project.command.UndoableComposite;
import org.locationtech.udig.project.command.UndoableMapCommand;
import org.locationtech.udig.project.internal.EditManager;
import org.locationtech.udig.project.internal.Layer;
import org.locationtech.udig.project.internal.impl.EditManagerImpl;
import org.locationtech.udig.project.internal.render.RenderPackage;
import org.locationtech.udig.project.internal.render.ViewportModel;
import org.locationtech.udig.project.render.displayAdapter.IMapDisplayListener;
import org.locationtech.udig.project.render.displayAdapter.MapDisplayEvent;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.tool.IToolContext;
import org.locationtech.udig.project.ui.tool.Tool;
import org.locationtech.udig.tool.edit.internal.Messages;
import org.locationtech.udig.tools.edit.support.EditBlackboard;
import org.locationtech.udig.tools.edit.support.EditGeom;
import org.locationtech.udig.tools.edit.support.PrimitiveShape;
import org.locationtech.udig.ui.PlatformGIS;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandEvent;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.ICommandListener;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.geotools.data.FeatureEvent;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.Id;
import org.opengis.filter.identity.Identifier;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.MathTransform;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

/**
* To delete soon EditManager will have an editblackboard.
*
* @author jones
* @since 1.1.0
*/
public class EditBlackboardUtil {
    private static final MathTransform IDENTITY;
    static {
        MathTransform tmp = null;
        try {
            tmp = CRS.findMathTransform(DefaultGeographicCRS.WGS84, DefaultGeographicCRS.WGS84);
        } catch (FactoryException e) {
            // can't happen
        }

        IDENTITY = tmp;
    }

    private volatile static ViewportModelListener listener;

    public static final EditBlackboard EMPTY_BLACKBOARD=new EditBlackboard(0,0,AffineTransform.getTranslateInstance(0, 0),
            IDENTITY);

    public static final String EDIT_BLACKBOARD_KEY = "EDIT_BLACKBOARD_KEY_839834"; //$NON-NLS-1$
   
    private static Lock blackboardLock = new ReentrantLock();
    public static EditBlackboard getEditBlackboard( IToolContext context, ILayer layer2 ) {
        if( layer2==null || !ApplicationGIS.getOpenMaps().contains(layer2.getMap()))
            return EMPTY_BLACKBOARD;
        ILayer layer = layer2;

        EditBlackboard editBlackBoard;
        blackboardLock.lock();
        try {
            EditManager editManager = ((EditManager) context.getEditManager());
            if (editManager.getEditLayer() != null && editManager.isEditLayerLocked()) {
                layer = context.getEditManager().getEditLayer();
            }

            editBlackBoard = getEditBlackBoardFromLayer(layer);
           
            if (editBlackBoard == null) {

                MathTransform layerToMapTransform;
                try {
                    layerToMapTransform = layer.layerToMapTransform();
                } catch (IOException e) {
                    EditPlugin.log("", e); //$NON-NLS-1$
                    layerToMapTransform = IDENTITY;
                }
                editBlackBoard = new EditBlackboard(context.getMapDisplay().getWidth(), context
                        .getMapDisplay().getHeight(), context.worldToScreenTransform(),
                        layerToMapTransform);

                final EditBlackboard bb = editBlackBoard;

                context.getViewportPane().addPaneListener(new IMapDisplayListener(){

                    public void sizeChanged( MapDisplayEvent event ) {
                        if (event.getOldSize() != null
                                && event.getOldSize().width != event.getSize().width)
                            bb.setWidth(event.getSize().width);
                        if (event.getOldSize() != null
                                && event.getOldSize().height != event.getSize().height)
                            bb.setHeight(event.getSize().height);
                    }

                });

                layer.getBlackboard().put(EDIT_BLACKBOARD_KEY, editBlackBoard);

            }
            enableViewportListener((ViewportModel) context.getViewportModel());
           
            //Vitalus: moved to EditToolHandler.enableListeners().
//            enableClearBlackboardCommand(context);
           
            // disabled until I fix the events
//            enableLayerChangeEventListener(layer, editBlackBoard);
        } finally {
            blackboardLock.unlock();
        }

        if (dirtyAreas.get(layer) != null) {
            openDataChangedDialog(layer, dirtyAreas.get(layer));
        }
        editBlackBoard.setToScreenTransform(context.worldToScreenTransform());
        return editBlackBoard;

    }

    private static Map<ILayer, ILayerListener> layerListenerMap = new HashMap<ILayer, ILayerListener>();
    private static Map<ILayer, Envelope> dirtyAreas = new HashMap<ILayer, Envelope>();
    /**
     * Adds a listener so that the editblackboards can be notified when the data in the feature
     * store are modified.
     */
    private static synchronized void enableLayerChangeEventListener( final ILayer layer,
            final EditBlackboard editBlackboard ) {
        ILayerListener listener = layerListenerMap.get(layer);
        if (listener == null) {
            listener = new ILayerListener(){
                public void refresh( LayerEvent event ) {
                    if (event.getSource() != layer) {
                        layer.removeListener(this);
                        return;
                    }
                    if (event.getType() != LayerEvent.EventType.EDIT_EVENT)
                        return;

                    EditManager editManager = (EditManager) layer.getMap().getEditManager();
                    ILayer editlayer = editManager.getSelectedLayer();
                    if (editManager.getEditLayer() != null && editManager.isEditLayerLocked()) {
                        editlayer = editManager.getEditLayer();
                    }
                    EditState currentEditState=(EditState)layer.getMap().getBlackboard().get(EditToolHandler.EDITSTATE);
                    if (editlayer == layer
                            && (currentEditState == EditState.COMMITTING || EditManagerListener.committing==editManager) )
                        return;

                    FeatureEvent editEvent = (FeatureEvent) event.getNewValue();
                   
                    if (editEvent == null )
                        return;
                  
                    Envelope dirtyArea = dirtyAreas.get(editlayer);
                    if (dirtyArea == null) {
                        dirtyArea = editEvent.getBounds();
                    } else {
                        dirtyArea.expandToInclude(editEvent.getBounds());
                    }

                    dirtyAreas.put(editlayer, dirtyArea);

                    if (editlayer == layer && layer.getMap() == ApplicationGIS.getActiveMap()) {
                        openDataChangedDialog(editlayer, dirtyArea);
                    }
                }
            };
            layerListenerMap.put(layer, listener);
        }

        layer.addListener(listener);

    }
    static volatile Dialog dialog;
    public static void openDataChangedDialog( final ILayer layer, final Envelope dirtyArea ) {
        Display d = Display.getCurrent();
        if (d == null)
            d = Display.getDefault();

        Condition condition = blackboardLock.newCondition();
        try {
            blackboardLock.lock();
            if (dialog != null) {
                // we're in the display thread, which means that the viewport is repainting since the dialog has any other input blocked.
                // so just return
                if( Display.getCurrent()!=null )
                    return;
                // the issue is being resolved we should wait for it to be resolved.
                while( dialog != null ) {
                    try{
                            condition.await(500, TimeUnit.MILLISECONDS);
                    }catch(InterruptedException e){
                        return;
                    }
                }
                return;
            }
        } finally {
            blackboardLock.unlock();
        }

        PlatformGIS.syncInDisplayThread(d, new Runnable(){
            public void run() {
                try {
                    blackboardLock.lock();
                    if (dirtyAreas.get(layer) == null)
                        return;

                    dialog = new Dialog(Display.getCurrent().getActiveShell()){
                        private final int UPDATE = 1;
                        private final int CLEAR = 2;
                        private final int IGNORE = 3;

                        public Control createDialogArea( Composite parent ) {
                            Composite comp = new Composite(parent, SWT.NONE);
                            comp.setLayout(new GridLayout(2, false));
                            Display display = Display.getCurrent();
                            Label label = new Label(comp, SWT.NONE);
                            label
                                    .setBackground(display
                                            .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
                            label
                                    .setForeground(display
                                            .getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
                            label.setImage(Dialog.getImage(Dialog.DLG_IMG_WARNING));
                           
                            label.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
                            Text text = new Text(comp, SWT.WRAP | SWT.READ_ONLY);
                            text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
                            text.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
                            text.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
                            text
                                    .setText(Messages.EditBlackboardUtil_data_changed);
                            return comp;
                        }

                        public void createButtonsForButtonBar( Composite composite ) {
                            createButton(composite, UPDATE, Messages.EditBlackboardUtil_update, false);
                            createButton(composite, CLEAR, Messages.EditBlackboardUtil_clear, true);
                            createButton(composite, IGNORE, Messages.EditBlackboardUtil_ignore, false);
                        }
                        public void buttonPressed( int button ) {
                            switch( button ) {
                            case UPDATE: {
                                boolean ok = MessageDialog.openConfirm(getParentShell(),
                                        Messages.EditBlackboardUtil_Update_Selection,
                                        Messages.EditBlackboardUtil_update_selection_confirmation);
                                if (ok) {
                                    try {
                                        ProgressMonitorDialog d = new ProgressMonitorDialog(this
                                                .getParentShell());

                                        blackboardLock.unlock();
                                        d.run(false, false, new IRunnableWithProgress(){
                                            public void run( IProgressMonitor monitor ) {
                                                updateFeatures(layer, monitor, dirtyArea);
                                            }
                                        });
                                        okPressed();
                                    } catch (Exception e) {
                                        EditPlugin.log("", e); //$NON-NLS-1$
                                    }
                                }
                                break;
                            }
                            case CLEAR: {
                                boolean ok = MessageDialog
                                        .openConfirm(getParentShell(), Messages.EditBlackboardUtil_clear_selection,
                                                Messages.EditBlackboardUtil_changes_will_be_lost);
                                if (ok) {
                                    blackboardLock.unlock();
                                    (getEditBlackBoardFromLayer(layer)).clear();
                                    layer.getMap().getBlackboard().put(
                                            EditToolHandler.CURRENT_SHAPE, null);
                                    ((EditManager) layer.getMap().getEditManager()).setEditFeature(
                                            null, null);
                                    okPressed();
                                }
                                break;
                            }
                            case IGNORE:
                                boolean ok = MessageDialog
                                        .openConfirm(getParentShell(), Messages.EditBlackboardUtil_ignore_change,
                                                Messages.EditBlackboardUtil_changes_will_be_overwritten);
                                if (ok) {
                                    okPressed();
                                }
                                break;

                            default:
                                cancelPressed();
                                break;
                            }
                        }
                        public void okPressed() {
                            dirtyAreas.remove(layer);
                            super.okPressed();
                        }
                    };
                    dialog.setBlockOnOpen(true);
                    dialog.open();
                } finally {
                    blackboardLock.unlock();
                    dialog = null;
                }

            }
        });
    }

    /**
     * Updates the features in the "dirty Area" so that the {@link EditGeom}s reflect the actual state of the stored features. 
     * Any changes to the {@link EditGeom} will be lost.
     *
     * @param layer that needs to be updated.
     * @param monitor progress monitor
     * @param dirtyArea area that needs to be updated.
     */
    public static void updateFeatures( ILayer layer, IProgressMonitor monitor, Envelope dirtyArea ) {
        EditBlackboard bb = getEditBlackBoardFromLayer(layer);
        List<EditGeom> geoms = bb.getGeoms();
        monitor.beginTask(Messages.EditBlackboardUtil_updating_selected_features, geoms.size());

        PrimitiveShape shape = (PrimitiveShape) layer.getMap().getBlackboard().get(
                EditToolHandler.CURRENT_SHAPE);
        EditManager editManager = (EditManager) layer.getMap().getEditManager();

        FilterFactory factory = CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
        Set<Identifier> ids = new HashSet<Identifier>();
        for( EditGeom geom : geoms ) {
          ids.add(factory.featureId(geom.getFeatureIDRef().get()));
        }
        Id fidFilter = factory.id(ids);
        Filter filter =factory.and(fidFilter, layer.createBBoxFilter(dirtyArea, new NullProgressMonitor()));
         
        try {
            FeatureSource<SimpleFeatureType, SimpleFeature> fs = layer.getResource(FeatureSource.class, monitor);
            FeatureCollection<SimpleFeatureType, SimpleFeature>  results = fs.getFeatures(filter);
            FeatureIterator<SimpleFeature> reader = results.features();
            try {
                int read = 0;
                boolean selectedFound = false;
                List<EditGeom> toRemove = new ArrayList<EditGeom>();
                while( reader.hasNext() ) {
                  int count = geoms.size() - read;
                    monitor.setTaskName(MessageFormat.format(Messages.EditBlackboardUtil_count_remaining, new Object[] {count}));
                    read++;
                    SimpleFeature feature = reader.next();

                    for( EditGeom geom : geoms ) {
                        if (feature.getID().equals(geom.getFeatureIDRef().get())) {
                            toRemove.add(geom);
                        }
                    }

                    Map<Geometry, EditGeom> mapping = bb.addGeometry((Geometry) feature.getDefaultGeometry(),
                            feature.getID());
                    if (feature.getID().equals(shape.getEditGeom().getFeatureIDRef().get())) {
                        editManager.setEditFeature(feature, (Layer) layer);
                        layer.getMap().getBlackboard().put(EditToolHandler.CURRENT_SHAPE,
                                mapping.values().iterator().next().getShell());
                        selectedFound = true;
                    }
                    monitor.worked(1);
                }
                if (!selectedFound) {
                    layer.getMap().getBlackboard().put(EditToolHandler.CURRENT_SHAPE, null);
                    editManager.setEditFeature(null, null);
                }
                bb.removeGeometries(toRemove);
            } finally {
                reader.close();
                monitor.done();
            }
        } catch (IOException e) {
            EditPlugin.log("", e); //$NON-NLS-1$
        }
    }

    /**
     * Returns the Editblackboard from the layer if it is on the layer or null if it hasn't been created yet.
     * {@link #getEditBlackboard(IToolContext, ILayer)} will create and initialize the blackbaord
     *
     * @param layer
     * @return
     */
    private static EditBlackboard getEditBlackBoardFromLayer( ILayer layer ) {
        blackboardLock.lock();
        try{
            return (EditBlackboard) layer.getBlackboard().get(EDIT_BLACKBOARD_KEY);
        }finally{
            blackboardLock.unlock();
        }
    }

    /**
     * Command handler for the command "org.locationtech.udig.tool.edit.clearAction"
     *  to clear EditBlackboard.
     */
    static IHandler clearEditBlackboardHandler;
   
    /**
     * Listener for "org.locationtech.udig.tool.edit.clearAction" command.
     */
    static ICommandListener clearEditBlackboardCommandListener;

    /**
     * Sets the command handler for the "ESC" button. The handler clears current edit blackboard.
     *  <p>
     *  Called from <code>EditToolHandler.enableListeners()</code>.
     * 
     * @param context
     */
    static synchronized void enableClearBlackboardCommand( final IToolContext context ) {
        if (clearEditBlackboardHandler == null) {
            clearEditBlackboardHandler = new AbstractHandler(){

                public Object execute( ExecutionEvent event ) throws ExecutionException {
                    Tool tool = ApplicationGIS.getToolManager().getActiveTool();

                    if (tool instanceof AbstractEditTool) {
                        EditToolHandler editToolHandler = ((AbstractEditTool) tool).getHandler();
                        List<Behaviour> behaviours = editToolHandler.getCancelBehaviours();
                        UndoableComposite compositeCommand = new UndoableComposite();
                        for( Behaviour behaviour : behaviours ) {
                            if (behaviour.isValid(editToolHandler)) {
                                UndoableMapCommand command = behaviour.getCommand(editToolHandler);
                                if (command != null)
                                    compositeCommand.getCommands().add(command);
                            }
                        }
                        if (!compositeCommand.getCommands().isEmpty())
                            editToolHandler.getContext().sendASyncCommand(compositeCommand);
                    }

                    return null;
                }
            };

        }
        ICommandService service = (ICommandService) PlatformUI.getWorkbench().getAdapter(
                ICommandService.class);

        Command command = service.getCommand("org.locationtech.udig.tool.edit.clearAction"); //$NON-NLS-1$
        command.setHandler(clearEditBlackboardHandler);
       
        if(clearEditBlackboardCommandListener == null){
            clearEditBlackboardCommandListener  =  new ICommandListener(){

                public void commandChanged( CommandEvent commandEvent ) {
                    if (commandEvent.isHandledChanged()) {
                        commandEvent.getCommand().removeCommandListener(this);
                        clearEditBlackboardCommandListener = null;
                       
                        IMap map = ApplicationGIS.getActiveMap();
                        resetBlackboards(map);
                    }
                }

            };
            command.addCommandListener(clearEditBlackboardCommandListener);
        }
    }
   
    /**
     *  Removes a command handler for the "ESC" button.
     *  <p>
     *  Called from <code>EditToolHandler.disableListeners()</code>.
     */
    static synchronized void disableClearBlackboardCommand() {
        ICommandService service = (ICommandService) PlatformUI.getWorkbench().getAdapter(
                ICommandService.class);
        Command command = service.getCommand("org.locationtech.udig.tool.edit.clearAction"); //$NON-NLS-1$

        if(clearEditBlackboardCommandListener != null){
            command.removeCommandListener(clearEditBlackboardCommandListener);
            clearEditBlackboardCommandListener = null;
        }
       
        command.setHandler(null);

    }

    /**
     * Disables listeners so that they will not get events.
     * Should be called when tool is disabled or when a blackboard is no longer required.
     *
     * @see #getEditBlackboard(IToolContext, ILayer) (it enables listeners).
     */
    public static void doneListening() {
        disableViewportListener();
//        disableLayerEvents();
    }

    /**
     * Disables the listeners listening to layers for edit events.
     * @see #enableLayerChangeEventListener(ILayer, EditBlackboard)
     */
    public static synchronized void disableLayerEvents() {
        Collection<Map.Entry<ILayer, ILayerListener>> entries = layerListenerMap.entrySet();
        for( Map.Entry<ILayer, ILayerListener> entry : entries ) {
            entry.getKey().removeListener(entry.getValue());
        }
        layerListenerMap.clear();
    }

    /**
     * Returns the selectedLayer or if it is not editable or not visible then the edit layer will be
     *
     * @return
     */
    public static ILayer findEditLayer( IToolContext context ) {
        ILayer layer = null;
        IMap map = context.getMap();
        // The selected layer will become the edit layer! If it's a featureStore and editable of
        // course.
        ILayer selectedLayer = ((EditManagerImpl) map.getEditManager()).getSelectedLayer();
        if (isEditable(selectedLayer)) {
            return selectedLayer;
        }
        // Otherwise we'll fall back to the current editLayer
        if (isEditable(map.getEditManager().getEditLayer()))
            return map.getEditManager().getEditLayer();
        // If all else fails we'll iterate through the layer and find the first layer eligable for
        // editing.
        // We should really never get here though.
        for( Iterator<ILayer> iter = map.getMapLayers().iterator(); iter.hasNext(); ) {
            layer = iter.next();
            if (isEditable(layer))
                break;
        }
        return layer;
    }

    /**
     * Checks that a layer has a FeatureStore, is editable and is visible.
     */
    private static boolean isEditable( ILayer layer ) {
        return layer != null && layer.hasResource(FeatureStore.class)
                && layer.getInteraction(Interaction.EDIT) && layer.isVisible(); //$NON-NLS-1$
    }
    @SuppressWarnings("unchecked")
    private synchronized static void enableViewportListener( ViewportModel model ) {
        disableViewportListener();
        listener = new ViewportModelListener(model);

        listener.model.eAdapters().add(listener);

    }

    private synchronized static void disableViewportListener() {
        if (listener != null)
            listener.model.eAdapters().remove(listener);
        listener = null;
    }

    /**
     * Listens for changes to the viewport model and transforms the edit blackboards to the new CRS or bounds
     *
     */
    static class ViewportModelListener extends AdapterImpl {
        ViewportModel model;
        private ILayer layer;
        ViewportModelListener( ViewportModel model ) {
            this.model = model;
            this.layer = model.getMap().getEditManager().getSelectedLayer();
        }
        @Override
        public void notifyChanged( Notification msg ) {
            if (listener == null) {
                model.eAdapters().remove(listener);
                listener = this;
                return;
            }
      switch( msg.getFeatureID(ViewportModel.class) ) {
            case RenderPackage.VIEWPORT_MODEL__BOUNDS: {
                EditBlackboard editBlackBoard = getEditBlackBoardFromLayer(layer);
                if( editBlackBoard == null ){
                  return; // cannot notify edit blackboard
                }
              editBlackBoard.setToScreenTransform(model.worldToScreenTransform());
                break;
            }
            case RenderPackage.VIEWPORT_MODEL__CRS: {             
                EditBlackboard editBlackBoard = getEditBlackBoardFromLayer(layer);
                if( editBlackBoard == null ){
                  return; // cannot notify edit blackboard
                }
                try {
                    editBlackBoard
                            .setMapLayerTransform(layer.mapToLayerTransform());
                } catch (IOException e) {
                    EditPlugin.log("", e); //$NON-NLS-1$
                }
                editBlackBoard.setToScreenTransform(model.worldToScreenTransform());
                break;
            }
      }
        }
    }
    /**
     *  clears edit blackboard for all layers in a given map... Critical to prevent memory leaks
     */
    public static void resetBlackboards(IMap map) {
        if (map != null) {
            blackboardLock.lock();
            try {
                List<ILayer> layers = map.getMapLayers();
                for( ILayer layer : layers ) {
                    EditBlackboard blackboard = getEditBlackBoardFromLayer(layer);
                    if (blackboard != null){
                        blackboard.clear();
                        layer.getBlackboard().put(EDIT_BLACKBOARD_KEY, null);
                    }
                }
            } finally {
                blackboardLock.unlock();
            }
        }
    }

}
TOP

Related Classes of org.locationtech.udig.tools.edit.EditBlackboardUtil$ViewportModelListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.