/* * Copyright (C) 2014 Alec Dhuse * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package co.foldingmap.actions; import co.foldingmap.map.vector.VectorLayer; import co.foldingmap.map.vector.CoordinateList; import co.foldingmap.map.vector.VectorObject; import co.foldingmap.map.vector.Coordinate; import co.foldingmap.map.vector.LineString; import co.foldingmap.Logger; import co.foldingmap.map.DigitalMap; import co.foldingmap.map.Layer; import java.util.HashMap; /** * Splits an object at a given point * * @author Alec */ public class SplitObject extends Action { private Coordinate coordinateToSplitAt; private DigitalMap currentMap; private VectorObject objectToSplit, newObject1, newObject2; /** * Constructor for objects of class CommandSplitObject * * @param dMap * @param objectToSplit * @param coordinateToSplitAt */ public SplitObject(DigitalMap dMap, VectorObject objectToSplit, Coordinate coordinateToSplitAt) { this.commandDescription = "Split Object"; this.coordinateToSplitAt = coordinateToSplitAt; this.currentMap = dMap; this.objectToSplit = objectToSplit; } /** * Returns if this Action can be undone. * * @return */ @Override public boolean canUndo() { return true; } @Override public void execute() { boolean matchFound; Coordinate currentCoordinate; CoordinateList<Coordinate> parentObjectCoordinates, newObjectCoordinates1, newObjectCoordinates2; VectorLayer parentLayer; try { matchFound = false; parentObjectCoordinates = this.objectToSplit.getCoordinateList(); newObjectCoordinates1 = new CoordinateList<Coordinate>(); newObjectCoordinates2 = new CoordinateList<Coordinate>(); /** * Processes point by point, add it to the first new object until * the split point is found then add to the the second object */ for (int i = 0; i < parentObjectCoordinates.size(); i++) { currentCoordinate = parentObjectCoordinates.get(i); if (!matchFound) { newObjectCoordinates1.add(currentCoordinate); } else { newObjectCoordinates2.add(currentCoordinate); } if (currentCoordinate.equals(this.coordinateToSplitAt) && !matchFound) { matchFound = true; currentCoordinate.setShared(true); newObjectCoordinates2.add(currentCoordinate); } } if (matchFound) { if (objectToSplit instanceof LineString) { newObject1 = new LineString((objectToSplit.getName()), objectToSplit.getObjectClass(), newObjectCoordinates1); newObject2 = new LineString((objectToSplit.getName()), objectToSplit.getObjectClass(), newObjectCoordinates2); if (objectToSplit.getParentLayer() instanceof VectorLayer) { parentLayer = (VectorLayer) objectToSplit.getParentLayer(); //Preserve visibility with split objects if (objectToSplit.getVisibility() != null) { newObject1.setVisibility(objectToSplit.getVisibility().clone()); newObject2.setVisibility(objectToSplit.getVisibility().clone()); } parentLayer.removeObject(objectToSplit); parentLayer.addObject(newObject1); parentLayer.addObject(newObject2); } else { //Parent layer not set, search for it for (Layer currentLayer: currentMap.getLayers()) { if (currentLayer instanceof VectorLayer) { VectorLayer vl = (VectorLayer) currentLayer; if (vl.getObjectList().contains(objectToSplit)) { vl.removeObject(objectToSplit); vl.addObject(newObject1); vl.addObject(newObject2); } } } } } currentMap.deselectObjects(); } // end if matchFound //copy over custom data fields if (newObject1 != null && newObject2 != null) { newObject1.setCustomDataFields((HashMap<String, String>) objectToSplit.getCustomDataFields().clone()); newObject2.setCustomDataFields((HashMap<String, String>) objectToSplit.getCustomDataFields().clone()); } } catch (Exception e) { Logger.log(Logger.ERR, "Error in SplitObject.execute() - " + e); } } @Override public void undo() { VectorLayer parentLayer; try { parentLayer = (VectorLayer) newObject1.getParentLayer(); parentLayer.removeObject(newObject1); parentLayer = (VectorLayer) newObject2.getParentLayer(); parentLayer.removeObject(newObject2); parentLayer = (VectorLayer) objectToSplit.getParentLayer(); parentLayer.addObject(objectToSplit); } catch (Exception e) { Logger.log(Logger.ERR, "Error SplitObject.undo() - " + e); } } }