Source Code Cross Referenced for EditBlackboard.java in  » GIS » udig-1.1 » net » refractions » udig » tools » edit » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » udig 1.1 » net.refractions.udig.tools.edit.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**
0002:         * 
0003:         */package net.refractions.udig.tools.edit.support;
0004:
0005:        import java.awt.geom.AffineTransform;
0006:        import java.util.ArrayList;
0007:        import java.util.Collection;
0008:        import java.util.Collections;
0009:        import java.util.HashMap;
0010:        import java.util.HashSet;
0011:        import java.util.Iterator;
0012:        import java.util.LinkedList;
0013:        import java.util.List;
0014:        import java.util.ListIterator;
0015:        import java.util.Map;
0016:        import java.util.Set;
0017:
0018:        import net.refractions.udig.core.WeakHashSet;
0019:        import net.refractions.udig.tools.edit.EditPlugin;
0020:        import net.refractions.udig.tools.edit.preferences.PreferenceUtil;
0021:        import net.refractions.udig.tools.edit.support.EditBlackboardEvent.EventType;
0022:        import net.refractions.udig.tools.edit.support.PrimitiveShape.Mutator;
0023:
0024:        import org.opengis.referencing.operation.MathTransform;
0025:
0026:        import com.vividsolutions.jts.geom.Coordinate;
0027:        import com.vividsolutions.jts.geom.Envelope;
0028:        import com.vividsolutions.jts.geom.Geometry;
0029:        import com.vividsolutions.jts.geom.GeometryCollection;
0030:        import com.vividsolutions.jts.geom.Polygon;
0031:
0032:        /**
0033:         * Maps between each pixel to a list of coordinates. Also provides convenience methods to move all
0034:         * coordinates at a location
0035:         * 
0036:         * @author jeichar
0037:         */
0038:        public class EditBlackboard {
0039:
0040:            protected Map<Point, List<LazyCoord>> coordMapping;
0041:            Map<Point, Set<EditGeom>> geomMapping;
0042:            private final List<EditGeom> geometries;
0043:            private Set<EditBlackboardListener> listeners = Collections
0044:                    .synchronizedSet(new WeakHashSet<EditBlackboardListener>());
0045:            private Selection selection = new Selection(this );
0046:            private volatile int height;
0047:            private volatile int width;
0048:            private boolean collapseVertices;
0049:            PointCoordCalculator pointCoordCalculator;
0050:            private volatile int batchingEvents = 0;
0051:            private List<EditBlackboardEvent> batchedEvents = new LinkedList<EditBlackboardEvent>();
0052:
0053:            /**
0054:             * Creates a PixelCoordMap. A default GeomShape will be created and can be obtained by
0055:             * {@link #getGeoms()}.get(0)
0056:             * 
0057:             * @param width width of the current ViewportPane
0058:             * @param height height of the current ViewportPane
0059:             * @param toScreen transform to take the coordinates to a screen location.
0060:             * @param layerToMap transform to transform coordinates from a layer's CRS to the map's CRS
0061:             * @param coords coordinates that need to be mapped.
0062:             */
0063:            public EditBlackboard(int width, int height,
0064:                    AffineTransform toScreen, MathTransform layerToMap) {
0065:                collapseVertices = true;
0066:                this .width = width;
0067:                this .height = height;
0068:                coordMapping = new HashMap<Point, List<LazyCoord>>();
0069:                geomMapping = new HashMap<Point, Set<EditGeom>>();
0070:                pointCoordCalculator = new PointCoordCalculator(toScreen,
0071:                        layerToMap);
0072:                geometries = new ArrayList<EditGeom>();
0073:
0074:                geometries.add(new EditGeom(this , null));
0075:            }
0076:
0077:            /**
0078:             * Returns the list of Listeners so that listeners can be added and removed. This is thread
0079:             * safe. Each Listener can only be added once.
0080:             * 
0081:             * @return Returns the listeners.
0082:             */
0083:            public Set<EditBlackboardListener> getListeners() {
0084:                return listeners;
0085:            }
0086:
0087:            /**
0088:             * Adds a Geometry to the contained geometries. If the Geometry is a MultiGeometry it will not
0089:             * be in the mapping only the sub geometries will be in the geometry.
0090:             * 
0091:             * @param geom the geometry that will be added.
0092:             * @param featureId The id of the feature the geometry was part of. Maybe null.
0093:             */
0094:            public Map<Geometry, EditGeom> setGeometries(Geometry geom,
0095:                    String featureId) {
0096:                Map<Geometry, EditGeom> mapping = null;
0097:                ArrayList<EditGeom> old = new ArrayList<EditGeom>(geometries);
0098:                synchronized (this ) {
0099:                    geometries.clear();
0100:                    coordMapping.clear();
0101:                    geomMapping.clear();
0102:                    mapping = new HashMap<Geometry, EditGeom>();
0103:                    doAddGeometry(geom, mapping, featureId);
0104:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS)) {
0105:                        for (EditGeom geom2 : mapping.values()) {
0106:                            geom2.assertValid();
0107:                        }
0108:                    }
0109:                }
0110:                if (mapping != null && !mapping.isEmpty())
0111:                    notify(new EditBlackboardEvent(this , this ,
0112:                            EventType.SET_GEOMS, old, new ArrayList<EditGeom>(
0113:                                    geometries)));
0114:                return mapping;
0115:
0116:            }
0117:
0118:            /**
0119:             * Adds a Geometry to the contained geometries. If the Geometry is a MultiGeometry it will not
0120:             * be in the mapping only the sub geometries will be in the geometry.
0121:             * 
0122:             * @param geom the geometry that will be added.
0123:             * @param featureID The id of the feature the geometry was part of. Maybe null.
0124:             */
0125:            public Map<Geometry, EditGeom> addGeometry(Geometry geom,
0126:                    String featureID) {
0127:                List<EditGeom> unmodifiableList = null;
0128:                Map<Geometry, EditGeom> mapping = null;
0129:                synchronized (this ) {
0130:                    mapping = new HashMap<Geometry, EditGeom>();
0131:                    doAddGeometry(geom, mapping, featureID);
0132:                    unmodifiableList = Collections
0133:                            .unmodifiableList(new ArrayList<EditGeom>(mapping
0134:                                    .values()));
0135:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS)) {
0136:                        for (EditGeom geom2 : mapping.values()) {
0137:                            geom2.assertValid();
0138:                        }
0139:                    }
0140:                }
0141:                if (unmodifiableList != null && !unmodifiableList.isEmpty())
0142:                    notify(new EditBlackboardEvent(this , this ,
0143:                            EditBlackboardEvent.EventType.ADD_GEOMS, null,
0144:                            unmodifiableList));
0145:                return mapping;
0146:            }
0147:
0148:            /**
0149:             * Adds a Coordinate the nearest edge .
0150:             * <p>
0151:             * If two edges are equidistant the first edge in the geometry will be targeted edge
0152:             * </p>
0153:             * 
0154:             * @param x the x screen location to place the new coordinate
0155:             * @param y the x screen location to place the new coordinate
0156:             * @param geom the geometry to append the point to.
0157:             * @param treatUnknownAsPolygon declares whether to treat geometries of type UNKNOWN as a polygon 
0158:             * @returns The edge that the point was added to.
0159:             */
0160:            public ClosestEdge addToNearestEdge(int x, int y, EditGeom geom,
0161:                    boolean treatUnknownAsPolygon)
0162:                    throws IllegalArgumentException {
0163:                EditBlackboardEvent editBlackboardEvent = null;
0164:                ClosestEdge geomClosest = null;
0165:                synchronized (this ) {
0166:                    if (!geometries.contains(geom))
0167:                        throw new IllegalArgumentException(
0168:                                "EditBlackboard does not contain EditGeom " + geom); //$NON-NLS-1$
0169:                    Point p = Point.valueOf(x, y);
0170:                    geomClosest = geom.getClosestEdge(p, treatUnknownAsPolygon);
0171:                    Coordinate toCoord = toCoord(p);
0172:                    LazyCoord lazyCoord = doInsertCoord(p, toCoord,
0173:                            geomClosest.indexOfPrevious + 1, geomClosest.part);
0174:
0175:                    geom.assertValid();
0176:                    editBlackboardEvent = new EditBlackboardEvent(this ,
0177:                            geomClosest.part, EventType.ADD_POINT, null, p);
0178:                    editBlackboardEvent.privateData = lazyCoord;
0179:                }
0180:                if (editBlackboardEvent != null)
0181:                    notify(editBlackboardEvent);
0182:                return geomClosest;
0183:            }
0184:
0185:            /**
0186:             * Adds a Coordinate the nearest edge .
0187:             * <p>
0188:             * If two edges of the same geometry are equidistant the first edge in the geometry will be
0189:             * targeted edge
0190:             * </p>
0191:             * <p>
0192:             * If two edges of different geometries are equidistant both will have a vertex added.
0193:             * </p>
0194:             * <p>
0195:             * If the vertex would end up being added to the same location as an existing vertex then no
0196:             * vertext is added
0197:             * </p>
0198:             * 
0199:             * @param x the x screen location to place the new coordinate
0200:             * @param y the x screen location to place the new coordinate
0201:             * @param treatUnknownAsPolygon declares whether to treat geometries of type UNKNOWN as a polygon 
0202:             * @return the list of GeomShapes that had the coordinate added to.
0203:             */
0204:            public List<ClosestEdge> addToNearestEdge(int x, int y,
0205:                    boolean treatUnknownAsPolygon)
0206:                    throws IllegalArgumentException {
0207:                EditBlackboardEvent editBlackboardEvent;
0208:                List<ClosestEdge> candidates;
0209:                synchronized (this ) {
0210:                    candidates = getCandidates(x, y, treatUnknownAsPolygon);
0211:                    Point p = Point.valueOf(x, y);
0212:                    Coordinate toCoord = toCoord(p);
0213:                    if (candidates.size() == 0) {
0214:                        EditGeom editGeom = getGeoms().get(0);
0215:                        LazyCoord lazyCoord = doAddCoord(p, toCoord, editGeom
0216:                                .getShell());
0217:                        editGeom.getShell().assertValid();
0218:                        editBlackboardEvent = new EditBlackboardEvent(this ,
0219:                                editGeom.getShell(), EventType.ADD_POINT, null,
0220:                                p);
0221:                        editBlackboardEvent.privateData = lazyCoord;
0222:                    } else {
0223:                        Map<EditGeom, PrimitiveShape> changed = new HashMap<EditGeom, PrimitiveShape>();
0224:                        for (ClosestEdge edge : candidates) {
0225:                            EditGeom geom = edge.shape;
0226:
0227:                            doInsertCoord(p, toCoord, edge.indexOfPrevious + 1,
0228:                                    edge.part);
0229:                            changed.put(geom, edge.part);
0230:
0231:                            edge.part.assertValid();
0232:                        }
0233:                        editBlackboardEvent = new EditBlackboardEvent(this ,
0234:                                changed.values(), EventType.ADD_POINT_TO_MANY,
0235:                                null, p);
0236:                    }
0237:                }
0238:                if (editBlackboardEvent != null)
0239:                    notify(editBlackboardEvent);
0240:                return candidates;
0241:            }
0242:
0243:            /**
0244:             * Adds a Coordinate at the x,y location on the screen to the end of the geomtry. Closure of the
0245:             * hole is not enforced.
0246:             * 
0247:             * @param x the x screen location to place the new coordinate
0248:             * @param y the x screen location to place the new coordinate
0249:             * @param holeIndex the hole to append to.
0250:             * @return
0251:             * @return added coordinate. <b>Do not modify coordinate otherwise the state of this class will
0252:             *         be wrong and bugs will occur in the code.</b>
0253:             */
0254:            public Coordinate addPoint(int x, int y, PrimitiveShape shape)
0255:                    throws IllegalArgumentException {
0256:                LazyCoord lazyCoord = null;
0257:                EditBlackboardEvent editBlackboardEvent = null;
0258:                synchronized (this ) {
0259:                    if (!geometries.contains(shape.getEditGeom()))
0260:                        throw new IllegalArgumentException(
0261:                                "Blackboard does not contain shape:" + shape); //$NON-NLS-1$
0262:
0263:                    Point point = Point.valueOf(x, y);
0264:                    Coordinate coord = toCoord(point);
0265:                    lazyCoord = doAddCoord(point, coord, shape);
0266:                    shape.assertValid();
0267:                    editBlackboardEvent = new EditBlackboardEvent(this , shape,
0268:                            EventType.ADD_POINT, null, point);
0269:                    editBlackboardEvent.privateData = lazyCoord;
0270:                }
0271:                if (editBlackboardEvent != null)
0272:                    notify(editBlackboardEvent);
0273:                return lazyCoord;
0274:            }
0275:
0276:            public Point addCoordinate(Coordinate coord, PrimitiveShape shape) {
0277:                return insertCoordinate(coord, shape.getNumPoints(), shape);
0278:            }
0279:
0280:            public Point insertCoordinate(Coordinate coord, int index,
0281:                    PrimitiveShape shape) {
0282:                EditBlackboardEvent editBlackboardEvent = null;
0283:                Point p = null;
0284:                synchronized (this ) {
0285:                    if (!geometries.contains(shape.getEditGeom()))
0286:                        throw new IllegalArgumentException(
0287:                                "Blackboard does not contain shape:" + shape); //$NON-NLS-1$
0288:                    p = toPoint(coord);
0289:                    LazyCoord lazyCoord = doInsertCoord(p, coord, index, shape);
0290:                    shape.assertValid();
0291:                    editBlackboardEvent = new EditBlackboardEvent(this , shape,
0292:                            EventType.ADD_POINT, null, p);
0293:                    editBlackboardEvent.privateData = lazyCoord;
0294:                }
0295:                if (editBlackboardEvent != null)
0296:                    notify(editBlackboardEvent);
0297:
0298:                return p;
0299:            }
0300:
0301:            /**
0302:             * Adds a Coordinate at the index indicated.
0303:             * <p>
0304:             * The index is the position in the coordinate list in the shell of the geometry.
0305:             * </p>
0306:             * 
0307:             * @param x the x screen location to place the new coordinate
0308:             * @param y the x screen location to place the new coordinate
0309:             * @param pointIndex the index in terms of points in the shape to add the coordinate.
0310:             * @param geom the geometry to append the point to.
0311:             * @return added coordinate. <b>Do not modify coordinate otherwise the state of this class will
0312:             *         be wrong and bugs will occur in the code.</b>
0313:             */
0314:            public Coordinate insertCoord(int x, int y, int pointIndex,
0315:                    PrimitiveShape shape) throws IllegalArgumentException {
0316:                EditBlackboardEvent editBlackboardEvent = null;
0317:                Coordinate coord = null;
0318:                synchronized (this ) {
0319:                    if (!geometries.contains(shape.getEditGeom()))
0320:                        throw new IllegalArgumentException(
0321:                                "Blackboard does not contain shape:" + shape); //$NON-NLS-1$
0322:                    Point point = Point.valueOf(x, y);
0323:                    coord = toCoord(point);
0324:                    LazyCoord lazyCoord = doInsertCoord(point, coord,
0325:                            pointIndex, shape);
0326:                    shape.assertValid();
0327:                    editBlackboardEvent = new EditBlackboardEvent(this , shape,
0328:                            EventType.ADD_POINT, null, point);
0329:                    editBlackboardEvent.privateData = lazyCoord;
0330:                }
0331:                if (editBlackboardEvent != null)
0332:                    notify(editBlackboardEvent);
0333:                return coord;
0334:            }
0335:
0336:            /**
0337:             * Inserts the list of coordinates into the shape at the index indicated.
0338:             * 
0339:             * @param pointIndex the location that the coordinates will be inserted.
0340:             * @param coords coords that will inserted.insertCoords
0341:             * @param shape the shape that will have the coords inserted.
0342:             */
0343:            public void insertCoords(int pointIndex, Point p,
0344:                    List<Coordinate> coords, PrimitiveShape shape) {
0345:                List<LazyCoord> lazyCoords = null;
0346:                synchronized (this ) {
0347:                    if (!geometries.contains(shape.getEditGeom()))
0348:                        throw new IllegalArgumentException(
0349:                                "Blackboard does not contain shape:" + shape); //$NON-NLS-1$
0350:                    if (coords.isEmpty())
0351:                        throw new IllegalArgumentException(
0352:                                "Coordinates cannot be empty"); //$NON-NLS-1$
0353:                    lazyCoords = shape.getMutator().addPoint(pointIndex, p,
0354:                            coords);
0355:                    List<LazyCoord> mappedCoords = coordMapping.get(p);
0356:                    if (mappedCoords == null) {
0357:                        mappedCoords = new ArrayList<LazyCoord>();
0358:                        coordMapping.put(p, mappedCoords);
0359:                    }
0360:                    mappedCoords.addAll(lazyCoords);
0361:                    Set<EditGeom> geoms = geomMapping.get(p);
0362:                    if (geoms == null) {
0363:                        geoms = new HashSet<EditGeom>();
0364:                        geomMapping.put(p, geoms);
0365:                    }
0366:                    if (!geoms.contains(shape.getEditGeom()))
0367:                        geoms.add(shape.getEditGeom());
0368:
0369:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS)) {
0370:                        for (EditGeom geom : geoms) {
0371:                            geom.assertValid();
0372:                        }
0373:                    }
0374:
0375:                }
0376:                EditBlackboardEvent editBlackboardEvent = new EditBlackboardEvent(
0377:                        this , shape, EventType.ADD_POINT, null, p);
0378:
0379:                editBlackboardEvent.privateData = lazyCoords;
0380:                if (lazyCoords != null && !lazyCoords.isEmpty())
0381:                    notify(editBlackboardEvent);
0382:            }
0383:
0384:            /**
0385:             * Returns the GeomShapes that will have the coordinate added if
0386:             * {@linkplain #addToNearestEdge(int, int)} is called.
0387:             * 
0388:             * @param x the x screen location to place the new coordinate
0389:             * @param y the x screen location to place the new coordinate
0390:             * @param treatUnknownAsPolygon declares whether to treat geometries of type UNKNOWN as a polygon 
0391:             * @return the GeomShapes that will have the coordinate added if
0392:             *         {@linkplain #addToNearestEdge(int, int)} is called.
0393:             */
0394:            public synchronized List<ClosestEdge> getCandidates(int x, int y,
0395:                    boolean treatUnknownAsPolygon) {
0396:                Point p = Point.valueOf(x, y);
0397:                List<EditGeom> geoms = getGeoms();
0398:                List<ClosestEdge> candidates = new ArrayList<ClosestEdge>();
0399:                int closest = Integer.MAX_VALUE;
0400:                List<ClosestEdge> closestDistances = new ArrayList<ClosestEdge>();
0401:
0402:                for (int i = 0; i < geoms.size(); i++) {
0403:                    ClosestEdge geomClosest = geoms.get(i).getClosestEdge(p,
0404:                            treatUnknownAsPolygon);
0405:                    if (geomClosest == null)
0406:                        continue;
0407:                    if (geomClosest.distanceToEdge < closest)
0408:                        closest = (int) geomClosest.distanceToEdge;
0409:                    closestDistances.add(geomClosest);
0410:                }
0411:
0412:                for (ClosestEdge edge : closestDistances) {
0413:                    if (((int) edge.distanceToEdge) == closest
0414:                            && !edge.part.getMutator().hasPoint(
0415:                                    edge.pointOnLine)) {
0416:                        candidates.add(edge);
0417:                    }
0418:                }
0419:
0420:                return candidates;
0421:            }
0422:
0423:            /**
0424:             * returns the list of coordinates at location:(x,y) <b>TREAT COORDINATES AS IMMUTABLE!!</b>
0425:             * <p>
0426:             * This is a dangerous method because the coordinates are mutable but if they are modified
0427:             * outside of this class then the model is messed up and crazy bugs will happen. The weakness is
0428:             * permitted for performance reasons. I'm trusting people to not be stupid.
0429:             * </p>
0430:             * 
0431:             * @return the list of coordinates at location:(x,y). <b>TREAT COORDINATES AS IMMUTABLE!!</b>
0432:             */
0433:            public synchronized List<Coordinate> getCoords(int x, int y) {
0434:                Point point = Point.valueOf(x, y);
0435:                List<LazyCoord> list = coordMapping.get(point);
0436:                if (list == null)
0437:                    return Collections.<Coordinate> emptyList();
0438:                return new CoordResolvingList(list, point);
0439:            }
0440:
0441:            /**
0442:             * The list of geometries mapped.
0443:             * 
0444:             * @return list of geometries mapped.
0445:             */
0446:            public synchronized List<EditGeom> getGeoms() {
0447:                return Collections.unmodifiableList(new ArrayList<EditGeom>(
0448:                        geometries));
0449:            }
0450:
0451:            /**
0452:             * Returns a list of the geometries with vertices at the position (x,y). Edges are not
0453:             * calculated.
0454:             * 
0455:             * @param x x coordinate of point
0456:             * @param y x coordinate of point
0457:             * @return
0458:             * @return a list of the geometries at the position (x,y)
0459:             */
0460:            public synchronized List<EditGeom> getGeoms(int x, int y) {
0461:                Set<EditGeom> geoms = geomMapping.get(Point.valueOf(x, y));
0462:                if (geoms == null)
0463:                    return Collections.<EditGeom> emptyList();
0464:                return new ArrayList<EditGeom>(geoms);
0465:            }
0466:
0467:            /**
0468:             * Moves all the coordinates at location by an offset of (deltaX, deltaY).
0469:             * 
0470:             * @param x x coordinate of coords to move
0471:             * @param y y coordinate of coords to move
0472:             * @param deltaX the number of pixels to move coords in the positive x direction(Screen space)
0473:             * @param deltaY the number of pixels to move coords in the positive y direction(Screen space)
0474:             */
0475:            public List<Coordinate> moveCoords(int x, int y, int endX, int endY) {
0476:
0477:                Set<PrimitiveShape> changed = new HashSet<PrimitiveShape>();
0478:                List<LazyCoord> coords = null;
0479:                Point start = Point.valueOf(x, y);
0480:                Point end = Point.valueOf(endX, endY);
0481:                synchronized (this ) {
0482:
0483:                    if (start.equals(end))
0484:                        return Collections.<Coordinate> emptyList();
0485:
0486:                    coords = coordMapping.remove(start);
0487:                    if (coords == null || coords.size() == 0)
0488:                        return Collections.<Coordinate> emptyList();
0489:
0490:                    List<LazyCoord> endCoords = coordMapping.get(end);
0491:
0492:                    if (endCoords != null) {
0493:                        endCoords.addAll(coords);
0494:                    } else {
0495:                        coordMapping.put(end, coords);
0496:                    }
0497:
0498:                    Set<EditGeom> startGeoms = geomMapping.get(start);
0499:                    Set<EditGeom> endGeoms = geomMapping.get(end);
0500:
0501:                    endGeoms = endGeoms == null ? new HashSet<EditGeom>()
0502:                            : endGeoms;
0503:                    for (EditGeom geom : startGeoms) {
0504:                        geom.setChanged(true);
0505:                        if (!endGeoms.contains(geom))
0506:                            endGeoms.add(geom);
0507:                        for (PrimitiveShape hole : geom) {
0508:                            for (ListIterator<Point> iter = hole.getMutator()
0509:                                    .iterator(); iter.hasNext();) {
0510:                                Point p = iter.next();
0511:                                if (p.equals(start)) {
0512:                                    changed.add(hole);
0513:                                    for (LazyCoord coord : coords) {
0514:                                        if (hole.hasVertex(p, coord)) {
0515:                                            iter.set(end);
0516:                                            break;
0517:                                        }
0518:
0519:                                    }
0520:                                }
0521:                            }
0522:                        }
0523:                    }
0524:
0525:                    geomMapping.put(end, endGeoms);
0526:                    geomMapping.remove(start);
0527:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS))
0528:                        for (PrimitiveShape shape : changed) {
0529:                            shape.assertValid();
0530:                        }
0531:                }
0532:                if (!changed.isEmpty())
0533:                    notify(new EditBlackboardEvent(this , changed,
0534:                            EventType.MOVE_POINT, start, end));
0535:                return new CoordResolvingList(coords, end);
0536:            }
0537:
0538:            /**
0539:             * Moves the selection
0540:             * 
0541:             * @param diffX the distance to move the geometry in the x direction. The delta is in pixels.
0542:             * @param diffY the distance to move the geometry in the y direction. The delta is in pixels.
0543:             * @param selection the selection to move.
0544:             */
0545:            public void moveSelection(int diffX, int diffY, Selection selection) {
0546:
0547:                if (selection instanceof  EditGeomSelection) {
0548:                    moveGeom(diffX, diffY, ((EditGeomSelection) selection)
0549:                            .getGeom());
0550:                } else {
0551:                    doMoveSelection(diffX, diffY, selection);
0552:                }
0553:            }
0554:
0555:            private void doMoveSelection(int diffX, int diffY,
0556:                    Selection selection2) {
0557:                if (diffX == 0 && diffY == 0)
0558:                    return;
0559:
0560:                if (selection.size() == 0)
0561:                    return;
0562:
0563:                startBatchingEvents();
0564:                synchronized (this ) {
0565:                    for (Point start : selection) {
0566:                        Collection<LazyCoord> coords = selection
0567:                                .getLazyCoordinates(start);
0568:                        Point end = Point.valueOf(start.getX() + diffX, start
0569:                                .getY()
0570:                                + diffY);
0571:                        List<LazyCoord> endCoords = coordMapping.get(end);
0572:
0573:                        coordMapping.get(start).removeAll(coords);
0574:                        if (endCoords != null) {
0575:                            endCoords.addAll(coords);
0576:                        } else {
0577:                            coordMapping.put(end, new LinkedList<LazyCoord>(
0578:                                    coords));
0579:                        }
0580:
0581:                        Set<EditGeom> startGeoms = geomMapping.get(start);
0582:                        Set<EditGeom> endGeoms = geomMapping.get(end);
0583:                        Set<PrimitiveShape> changed = new HashSet<PrimitiveShape>();
0584:
0585:                        if (startGeoms == null)
0586:                            continue;
0587:
0588:                        endGeoms = endGeoms == null ? new HashSet<EditGeom>()
0589:                                : endGeoms;
0590:                        Set<EditGeom> toRemove = new HashSet<EditGeom>();
0591:                        Set<EditGeom> toAdd = new HashSet<EditGeom>();
0592:                        for (Iterator<EditGeom> geomIter = startGeoms
0593:                                .iterator(); geomIter.hasNext();) {
0594:                            EditGeom geom = geomIter.next();
0595:                            geom.setChanged(true);
0596:
0597:                            for (PrimitiveShape shape : geom) {
0598:
0599:                                for (Iterator<Point> shapeIter = shape
0600:                                        .getMutator().getCopyIterator(); shapeIter
0601:                                        .hasNext();) {
0602:                                    Point p = shapeIter.next();
0603:                                    if (p.equals(start)) {
0604:                                        toAdd.add(geom);
0605:                                        for (LazyCoord coord : coords) {
0606:                                            if (shape.hasVertex(p, coord)) {
0607:                                                changed.add(shape);
0608:                                                shape.getMutator().move(start,
0609:                                                        end, coord);
0610:                                            }
0611:
0612:                                        }
0613:                                    }
0614:                                }
0615:                                if (shape.getMutator().getLazyCoordsAt(start)
0616:                                        .isEmpty())
0617:                                    toRemove.add(geom);
0618:                            }
0619:
0620:                            if (!changed.isEmpty())
0621:                                notify(new EditBlackboardEvent(this , changed,
0622:                                        EventType.MOVE_POINT, start, end));
0623:                        }
0624:                        endGeoms.addAll(toAdd);
0625:                        startGeoms.removeAll(toRemove);
0626:                        geomMapping.put(end, endGeoms);
0627:                        if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS))
0628:                            for (EditGeom geom : endGeoms) {
0629:                                geom.assertValid();
0630:                            }
0631:
0632:                    }
0633:                }
0634:                fireBatchedEvents();
0635:
0636:            }
0637:
0638:            /**
0639:             * Moves a geometry deltaX, deltaY pixels.
0640:             * 
0641:             * @param deltaX the distance to move the geometry in the x direction. The delta is in pixels.
0642:             * @param deltaY the distance to move the geometry in the y direction. The delta is in pixels.
0643:             * @param geom the geometry to move.
0644:             */
0645:            private void moveGeom(int deltaX, int deltaY, EditGeom geom) {
0646:                if (!geometries.contains(geom))
0647:                    throw new IllegalArgumentException(
0648:                            "Blackboard does not contain EditGeom:" + geom); //$NON-NLS-1$
0649:
0650:                if (deltaX == 0 && deltaY == 0)
0651:                    return;
0652:                synchronized (this ) {
0653:                    Set<Point> moved = new HashSet<Point>();
0654:                    Map<Point, List<LazyCoord>> newCoordMapping = new HashMap<Point, List<LazyCoord>>();
0655:
0656:                    startBatchingEvents();
0657:                    for (PrimitiveShape shape : geom) {
0658:                        for (Point point : shape) {
0659:                            if (moved.contains(point))
0660:                                continue;
0661:
0662:                            moved.add(point);
0663:                            Point destPoint = Point.valueOf(point.getX()
0664:                                    + deltaX, point.getY() + deltaY);
0665:
0666:                            List<LazyCoord> coords = shape.getMutator()
0667:                                    .getLazyCoordsAt(point);
0668:                            coordMapping.get(point).removeAll(coords);
0669:
0670:                            newCoordMapping.put(destPoint, coords);
0671:
0672:                            geomMapping.get(point).remove(geom);
0673:
0674:                            notify(new EditBlackboardEvent(this , Collections
0675:                                    .singleton(shape), EventType.MOVE_POINT,
0676:                                    point, destPoint));
0677:                        }
0678:                    }
0679:
0680:                    for (PrimitiveShape shape : geom) {
0681:                        shape.getMutator().move(deltaX, deltaY);
0682:                    }
0683:
0684:                    for (Map.Entry<Point, List<LazyCoord>> entry : newCoordMapping
0685:                            .entrySet()) {
0686:                        List<LazyCoord> destCoords = coordMapping.get(entry
0687:                                .getKey());
0688:                        if (destCoords == null) {
0689:                            destCoords = new ArrayList<LazyCoord>();
0690:                            coordMapping.put(entry.getKey(), destCoords);
0691:                        }
0692:                        destCoords.addAll(entry.getValue());
0693:
0694:                        Set<EditGeom> destGeoms = geomMapping.get(entry
0695:                                .getKey());
0696:                        if (destGeoms == null) {
0697:                            destGeoms = new HashSet<EditGeom>();
0698:                            destGeoms.add(geom);
0699:                            geomMapping.put(entry.getKey(), destGeoms);
0700:                        } else {
0701:                            if (!destGeoms.contains(geom))
0702:                                destGeoms.add(geom);
0703:                        }
0704:                    }
0705:
0706:                    geom.assertValid();
0707:                    geom.setChanged(true);
0708:                }
0709:                fireBatchedEvents();
0710:            }
0711:
0712:            /**
0713:             * Deletes all the coordinates at a location <b>TREAT COORDINATES AS IMMUTABLE!!</b>
0714:             * 
0715:             * @return the deleted coordinates. <b>TREAT COORDINATES AS IMMUTABLE!!</b>
0716:             */
0717:            public List<Coordinate> removeCoordsAtPoint(int x, int y) {
0718:                Point p = Point.valueOf(x, y);
0719:                HashSet<PrimitiveShape> changed = new HashSet<PrimitiveShape>();
0720:                List<Coordinate> result = null;
0721:                synchronized (this ) {
0722:
0723:                    List<LazyCoord> coords = coordMapping.remove(p);
0724:
0725:                    result = coords == null ? Collections
0726:                            .<Coordinate> emptyList() : new CoordResolvingList(
0727:                            coords, p);
0728:
0729:                    Set<EditGeom> geoms = geomMapping.remove(p);
0730:                    if (geoms == null)
0731:                        return Collections.<Coordinate> emptyList();
0732:                    for (EditGeom geom : geoms) {
0733:
0734:                        for (PrimitiveShape part : geom) {
0735:                            Mutator mutator = part.getMutator();
0736:                            if (mutator.remove(p))
0737:                                changed.add(part);
0738:                            while (mutator.remove(p))
0739:                                ;
0740:                        }
0741:                    }
0742:
0743:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS)) {
0744:                        for (PrimitiveShape shape : changed) {
0745:                            shape.assertValid();
0746:                        }
0747:                    }
0748:                }
0749:                if (!changed.isEmpty())
0750:                    notify(new EditBlackboardEvent(this , changed,
0751:                            EventType.REMOVE_POINT, p, null));
0752:                return result;
0753:            }
0754:
0755:            /**
0756:             * Deletes the coordinates at the provided point in the provided shape.
0757:             * 
0758:             * @param x x coordinate in screen coords
0759:             * @param y y coordinate in screen coords
0760:             * @param shape shape to delete from.
0761:             */
0762:            public void removeCoords(int x, int y, PrimitiveShape shape) {
0763:                Point p = Point.valueOf(x, y);
0764:                synchronized (this ) {
0765:                    shape.getMutator().remove(p);
0766:                    Set<EditGeom> geoms = geomMapping.get(p);
0767:                    if (geoms.isEmpty()) {
0768:                        throw new IllegalStateException(
0769:                                "for some reason there was no shape at the location"); //$NON-NLS-1$
0770:                    }
0771:                    boolean noMoreReferences = true;
0772:
0773:                    for (PrimitiveShape shape2 : shape.getEditGeom()) {
0774:                        if (!shape2.getMutator().getLazyCoordsAt(p).isEmpty()) {
0775:                            noMoreReferences = false;
0776:                            break;
0777:                        }
0778:                    }
0779:
0780:                    if (noMoreReferences) {
0781:                        geoms.remove(shape.getEditGeom());
0782:                    }
0783:                    shape.assertValid();
0784:                }
0785:                notify(new EditBlackboardEvent(this , Collections
0786:                        .singleton(shape), EventType.REMOVE_POINT, p, null));
0787:            }
0788:
0789:            /**
0790:             * Removes a coordinate from the shape. The index indicates which point to remove, the Point
0791:             * parameter is a check to ensure that the correct point is indicated, and the coord is the
0792:             * coordinate that will be removed
0793:             * 
0794:             * @param pointIndex index of point in shape
0795:             * @param coord coordinate to remove
0796:             * @param shape shape to remove from
0797:             */
0798:            public void removeCoordinate(int pointIndex, Coordinate coord,
0799:                    PrimitiveShape shape) {
0800:
0801:                if (!geometries.contains(shape.getEditGeom()))
0802:                    throw new IllegalArgumentException(
0803:                            "Blackboard does not contain shape:" + shape); //$NON-NLS-1$
0804:
0805:                Point toRemove = null;
0806:                synchronized (this ) {
0807:                    toRemove = shape.getPoint(pointIndex);
0808:
0809:                    Mutator mutator = shape.getMutator();
0810:                    LazyCoord removed = mutator.removePoint(pointIndex, coord);
0811:
0812:                    boolean occupiesPoint = false;
0813:
0814:                    for (Point point : mutator) {
0815:                        if (point.equals(toRemove))
0816:                            occupiesPoint = true;
0817:                    }
0818:
0819:                    List<LazyCoord> coords = coordMapping.get(toRemove);
0820:                    for (Iterator<LazyCoord> iter = coords.iterator(); iter
0821:                            .hasNext();) {
0822:                        if (iter.next() == removed)
0823:                            iter.remove();
0824:                    }
0825:                    if (coords.isEmpty()) {
0826:                        coordMapping.remove(toRemove);
0827:                    }
0828:
0829:                    if (!occupiesPoint) {
0830:                        Set<EditGeom> geoms = geomMapping.get(toRemove);
0831:                        geoms.remove(shape.getEditGeom());
0832:                        if (geoms.isEmpty())
0833:                            geomMapping.remove(toRemove);
0834:                    }
0835:
0836:                    shape.assertValid();
0837:                }
0838:                if (toRemove != null)
0839:                    notify(new EditBlackboardEvent(this , Collections
0840:                            .singleton(shape), EventType.REMOVE_POINT,
0841:                            toRemove, null));
0842:            }
0843:
0844:            public synchronized Coordinate toCoord(Point point) {
0845:                return pointCoordCalculator.toCoord(point);
0846:            }
0847:
0848:            /**
0849:             * Transforms a Coordinate into the point location it would occupy on the screen.
0850:             * 
0851:             * @param coord coordinate object
0852:             * @return point coordinate would occupy on the screen.
0853:             */
0854:            public synchronized Point toPoint(Coordinate coord) {
0855:                return pointCoordCalculator.toPoint(coord);
0856:            }
0857:
0858:            /**
0859:             * Modifies the mapping of points to coordinates so that the transform passed in as a parameter
0860:             * is the new toScreen transform.
0861:             * 
0862:             * @param transform new transform
0863:             */
0864:            public void setToScreenTransform(AffineTransform newToScreen) {
0865:                AffineTransform oldToScreen = null;
0866:                Map<Point, List<Point>> map = new HashMap<Point, List<Point>>();
0867:                synchronized (this ) {
0868:                    if (newToScreen.equals(pointCoordCalculator.toScreen))
0869:                        return;
0870:
0871:                    oldToScreen = new AffineTransform(
0872:                            pointCoordCalculator.toScreen);
0873:                    AffineTransform oldToWorld = new AffineTransform(
0874:                            pointCoordCalculator.toWorld);
0875:
0876:                    geomMapping.clear();
0877:                    coordMapping.clear();
0878:                    PointCoordCalculator calculator = new PointCoordCalculator(
0879:                            newToScreen, pointCoordCalculator.layerToMap);
0880:                    for (EditGeom geom : geometries) {
0881:                        for (PrimitiveShape shape : geom) {
0882:                            map.putAll(shape.getMutator().transform(
0883:                                    oldToScreen, oldToWorld, calculator));
0884:                        }
0885:                    }
0886:
0887:                    pointCoordCalculator.toScreen.setTransform(newToScreen);
0888:                    pointCoordCalculator.toWorld
0889:                            .setTransform(calculator.toWorld);
0890:
0891:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS))
0892:                        for (EditGeom geom : geometries) {
0893:                            geom.assertValid();
0894:                        }
0895:                }
0896:                notify(new EditBlackboardEvent(this , this ,
0897:                        EventType.TRANFORMATION, new AffineTransform(
0898:                                oldToScreen), map));
0899:            }
0900:
0901:            public Selection getSelection() {
0902:                return selection;
0903:            }
0904:
0905:            /**
0906:             * Removes all EditGeometries from blackboard and places an empty one on the black board.
0907:             */
0908:            public void clear() {
0909:                EditBlackboardEvent event = null;
0910:                synchronized (this ) {
0911:                    event = new EditBlackboardEvent(this , this ,
0912:                            EventType.REMOVE_GEOMS, new ArrayList<EditGeom>(
0913:                                    geometries), null);
0914:                    coordMapping.clear();
0915:                    geometries.clear();
0916:                    geomMapping.clear();
0917:                    geometries.add(new EditGeom(this , null));
0918:                    selection.doClear();
0919:                }
0920:                notify(event);
0921:            }
0922:
0923:            /**
0924:             * Removes all the geometries in the list from the blackboard and all the coordinates in the
0925:             * geometries
0926:             * 
0927:             * @param geomsToRemove the list of geometries to remove.
0928:             */
0929:            public List<EditGeom> removeGeometries(
0930:                    Collection<EditGeom> geomsToRemove) {
0931:                ArrayList<EditGeom> removed = new ArrayList<EditGeom>();
0932:                synchronized (this ) {
0933:                    for (EditGeom geom : geomsToRemove) {
0934:                        if (!geometries.contains(geom)) {
0935:                            continue;
0936:                        }
0937:                        removed.add(geom);
0938:                        for (PrimitiveShape shape : geom) {
0939:                            for (int i = 0; i < shape.getNumPoints(); i++) {
0940:                                Point point = shape.getPoint(i);
0941:                                List<LazyCoord> coords = shape.getMutator()
0942:                                        .getLazyCoordsAt(i);
0943:                                coordMapping.get(point).removeAll(coords);
0944:                                geomMapping.get(point).remove(geom);
0945:                            }
0946:                        }
0947:                    }
0948:                    geometries.removeAll(geomsToRemove);
0949:                }
0950:                notify(new EditBlackboardEvent(this , this ,
0951:                        EventType.REMOVE_GEOMS, removed, null));
0952:                return removed;
0953:            }
0954:
0955:            /**
0956:             * Creates a new EditGeom in the map. If there is only one geometry on the bb and it has no
0957:             * points and has not been editted it will be removed.
0958:             * 
0959:             * @param featureId The id of the feature the geometry was part of. Maybe null.
0960:             * @param type the type of geometry to create if null then the type will be unknown
0961:             * @return the created geometry
0962:             */
0963:            public EditGeom newGeom(String featureId, ShapeType type) {
0964:                EditGeom editGeom = new EditGeom(this , featureId);
0965:                if (type != null)
0966:                    editGeom.setShapeType(type);
0967:                synchronized (this ) {
0968:                    if (!geometries.isEmpty() && !geometries.get(0).isChanged()
0969:                            && geometries.get(0).getShell().getNumPoints() == 0)
0970:                        geometries.clear();
0971:                    geometries.add(editGeom);
0972:                }
0973:                notify(new EditBlackboardEvent(this , this , EventType.ADD_GEOMS,
0974:                        null, Collections.singletonList(editGeom)));
0975:                return editGeom;
0976:            }
0977:
0978:            /**
0979:             * @return Returns the height.
0980:             */
0981:            public synchronized int getHeight() {
0982:                return height;
0983:            }
0984:
0985:            /**
0986:             * @param height The height to set.
0987:             */
0988:            public synchronized void setHeight(int height) {
0989:                this .height = height;
0990:            }
0991:
0992:            /**
0993:             * @return Returns the width.
0994:             */
0995:            public synchronized int getWidth() {
0996:                return width;
0997:            }
0998:
0999:            /**
1000:             * @param width The width to set.
1001:             */
1002:            public synchronized void setWidth(int width) {
1003:                this .width = width;
1004:            }
1005:
1006:            /**
1007:             * @return Returns the collapseVertices.
1008:             */
1009:            public synchronized boolean isCollapseVertices() {
1010:                return this .collapseVertices;
1011:            }
1012:
1013:            /**
1014:             * @param collapseVertices The collapseVertices to set.
1015:             */
1016:            public synchronized void setCollapseVertices(
1017:                    boolean collapseVertices) {
1018:                this .collapseVertices = collapseVertices;
1019:            }
1020:
1021:            /**
1022:             * Returns the point closest to location. The search is a square of height and width radius + 1.
1023:             * 
1024:             * @param location the locations to start searching from.
1025:             * @param radius the distance away from location to search.
1026:             * @return the point closest to location or null if no point exists.
1027:             */
1028:            public Point overVertex(Point location, int radius) {
1029:                return overVertex(location, radius, false);
1030:            }
1031:
1032:            /**
1033:             * Returns the point closest to location. If ignore is true the point at locations will not be
1034:             * returned. The search is a square of height and width radius + 1.
1035:             * 
1036:             * @param location the locations to start searching from.
1037:             * @param radius radius the distance away from location to search.
1038:             * @param ignore true if the vertex at location is ignored
1039:             * @return the point closest to location or null if no point exists.
1040:             */
1041:            public synchronized Point overVertex(Point location, int radius,
1042:                    boolean ignore) {
1043:                if (!ignore
1044:                        && getCoords(location.getX(), location.getY()).size() != 0)
1045:                    return location;
1046:                for (int i = 1; i <= radius; i++) {
1047:                    Point result = findVertex(location, i);
1048:                    if (result != null)
1049:                        return result;
1050:                }
1051:                return null;
1052:            }
1053:
1054:            /**
1055:             * Changes the behaviour of the EditBlackboard so that events are not fired but batched together
1056:             * until {@linkplain #fireBatchedEvents()} is called.
1057:             */
1058:            public synchronized void startBatchingEvents() {
1059:                batchingEvents++;
1060:            }
1061:
1062:            /**
1063:             * Fires all the batched events and resets the EditBlackboard so that it no longer batches
1064:             * events.
1065:             */
1066:            public void fireBatchedEvents() {
1067:                List<EditBlackboardEvent> events;
1068:                synchronized (this ) {
1069:                    batchingEvents--;
1070:                    if (batchingEvents > 0)
1071:                        return;
1072:                    events = this .batchedEvents;
1073:                    this .batchedEvents = new LinkedList<EditBlackboardEvent>();
1074:                }
1075:
1076:                if (events.isEmpty())
1077:                    return;
1078:
1079:                EditBlackboardListener[] l = listeners
1080:                        .toArray(new EditBlackboardListener[0]);
1081:                startBatchingEvents();
1082:                try {
1083:                    for (EditBlackboardListener listener : l) {
1084:                        listener.batchChange(events);
1085:                    }
1086:                } finally {
1087:                    fireBatchedEvents();
1088:                }
1089:            }
1090:
1091:            private LazyCoord doAddCoord(Point p, Coordinate c,
1092:                    PrimitiveShape hole) {
1093:                int index = hole.getNumPoints();
1094:                return doInsertCoord(p, c, index, hole);
1095:            }
1096:
1097:            private LazyCoord doInsertCoord(Point point, Coordinate c,
1098:                    int pointIndex, PrimitiveShape hole) {
1099:                if (hole == null || c == null || point == null)
1100:                    throw new IllegalArgumentException(
1101:                            "hole=" + hole + " coordIndex=" + pointIndex + " c=" + c + " p=" + point); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
1102:
1103:                // So that all the vertices don't make a big mess look around point in a 3x3 radius
1104:                // if another point is there add to that point.
1105:                Point overLappingPoint = null;
1106:                if (collapseVertices)
1107:                    overLappingPoint = overVertex(point, PreferenceUtil
1108:                            .instance().getVertexRadius());
1109:
1110:                Point p = overLappingPoint;
1111:                if (p == null || !collapseVertices)
1112:                    p = point;
1113:
1114:                Coordinate coord = new Coordinate(c);
1115:
1116:                Collection<LazyCoord> added = hole.getMutator().addPoint(
1117:                        pointIndex, p, Collections.singletonList(coord));
1118:                LazyCoord lazyCoord = added.iterator().next();
1119:                Collection<EditGeom> geomList = updateMappings(p, lazyCoord);
1120:
1121:                if (!geomList.contains(hole.getEditGeom()))
1122:                    geomList.add(hole.getEditGeom());
1123:                return lazyCoord;
1124:            }
1125:
1126:            /**
1127:             * Updates the coordMapping and geomMapping ensuring that there are lists at the Point and adds
1128:             * c to the CoordMapping.
1129:             */
1130:            private Set<EditGeom> updateMappings(Point p, LazyCoord c) {
1131:                List<LazyCoord> coordList = coordMapping.get(p);
1132:                Set<EditGeom> geomList = geomMapping.get(p);
1133:                if (coordList == null) {
1134:                    coordList = new ArrayList<LazyCoord>();
1135:                    geomList = new HashSet<EditGeom>();
1136:                    coordMapping.put(p, coordList);
1137:                    geomMapping.put(p, geomList);
1138:                }
1139:                coordList.add(c);
1140:                return geomList;
1141:            }
1142:
1143:            private void doAddGeometry(Geometry geom,
1144:                    Map<Geometry, EditGeom> jtsEditGeomMapping, String featureID) {
1145:
1146:                Envelope bbox = geom.getEnvelopeInternal();
1147:
1148:                if (geom instanceof  GeometryCollection) {
1149:                    int num = geom.getNumGeometries();
1150:                    for (int i = 0; i < num; i++) {
1151:                        doAddGeometry(geom.getGeometryN(i), jtsEditGeomMapping,
1152:                                featureID);
1153:                    }
1154:                } else {
1155:                    EditGeom geomShape = new EditGeom(this , featureID, bbox);
1156:                    geomShape.initializing = true;
1157:                    geomShape.setShapeType(ShapeType.valueOf(geom));
1158:                    geometries.add(geomShape);
1159:                    jtsEditGeomMapping.put(geom, geomShape);
1160:
1161:                    if (geom instanceof  Polygon) {
1162:                        Polygon poly = (Polygon) geom;
1163:                        addShell(poly.getExteriorRing(), geomShape);
1164:                        for (int i = 0, numHoles = poly.getNumInteriorRing(); i < numHoles; i++) {
1165:                            addHole(poly.getInteriorRingN(i), geomShape, i);
1166:                        }
1167:                    } else {
1168:                        addShell(geom, geomShape);
1169:                    }
1170:                    geomShape.initializing = false;
1171:
1172:                    if (geomShape.isChanged())
1173:                        geomShape.setChanged(false);
1174:                }
1175:            }
1176:
1177:            private void addHole(Geometry geom, EditGeom geomShape,
1178:                    int holeIndex) {
1179:                PrimitiveShape hole;
1180:                if (holeIndex == geomShape.getHoles().size()) {
1181:                    hole = geomShape.newHole();
1182:                } else {
1183:                    hole = geomShape.getHoles().get(holeIndex);
1184:                }
1185:
1186:                Coordinate[] coords = geom.getCoordinates();
1187:                for (int i = 0; i < coords.length; i++) {
1188:                    doAddCoord(toPoint(coords[i]), coords[i], hole);
1189:                }
1190:            }
1191:
1192:            private void addShell(Geometry geom, EditGeom editGeom) {
1193:                Coordinate[] coords = geom.getCoordinates();
1194:                for (int i = 0; i < coords.length; i++) {
1195:                    doAddCoord(toPoint(coords[i]), coords[i], editGeom
1196:                            .getShell());
1197:                    editGeom.getShell().assertValid();
1198:                }
1199:            }
1200:
1201:            void notify(EditBlackboardEvent event) {
1202:                if (event == null)
1203:                    throw new NullPointerException();
1204:                EditBlackboardListener[] l = null;
1205:                synchronized (this ) {
1206:                    if (batchingEvents > 0) {
1207:                        batchedEvents.add(event);
1208:                    } else {
1209:                        l = listeners.toArray(new EditBlackboardListener[0]);
1210:                    }
1211:                }
1212:                if (l != null) {
1213:                    for (EditBlackboardListener listener : l) {
1214:                        listener.changed(event);
1215:                    }
1216:                }
1217:            }
1218:
1219:            /**
1220:             * Searchs for a vertext in a square i pixels away from the location.
1221:             * 
1222:             * @param location center of search
1223:             * @param i distance from center to search (is not an area search)
1224:             * @param ignore
1225:             * @param element
1226:             */
1227:            private Point findVertex(Point location, int i) {
1228:
1229:                final int maxX = location.getX() + i;
1230:                final int maxY = location.getY() + i;
1231:                final int minX = location.getX() - i;
1232:                final int minY = location.getY() - i;
1233:
1234:                for (int x = minX; x <= maxX; x++) {
1235:                    if (getCoords(x, minY).size() > 0)
1236:                        return Point.valueOf(x, minY);
1237:                }
1238:
1239:                for (int y = minY + 1; y <= maxY; y++) {
1240:                    if (getCoords(maxX, y).size() > 0)
1241:                        return Point.valueOf(maxX, y);
1242:                }
1243:
1244:                for (int x = maxX - 1; x >= minX; x--) {
1245:                    if (getCoords(x, maxY).size() > 0)
1246:                        return Point.valueOf(x, maxY);
1247:                }
1248:
1249:                for (int y = maxY - 1; y >= minY; y--) {
1250:                    if (getCoords(minX, y).size() > 0)
1251:                        return Point.valueOf(minX, y);
1252:                }
1253:
1254:                return null;
1255:            }
1256:
1257:            public boolean selectionAdd(Point point) {
1258:                return selection.doAdd(point);
1259:            }
1260:
1261:            public boolean selectionAddAll(Collection<Point> points) {
1262:                return selection.doAddAll(points);
1263:            }
1264:
1265:            public void selectionClear() {
1266:                selection.doClear();
1267:            }
1268:
1269:            public boolean selectionRemoveAll(Collection<Point> points) {
1270:                return selection.doRemoveAll(points, true);
1271:            }
1272:
1273:            public boolean selectionRemove(Point point) {
1274:                return selection.doRemove(point);
1275:            }
1276:
1277:            public boolean selectionRetainAll(Collection<Point> points) {
1278:                return selection.doRetainAll(points);
1279:            }
1280:
1281:            /**
1282:             * Returns true if the blackboard currently holds the noted feature ID.
1283:             * 
1284:             * @param fid Feature ID
1285:             * @return boolean
1286:             */
1287:            public boolean contains(String fid) {
1288:                List<EditGeom> geoms = getGeoms();
1289:                for (EditGeom geom : geoms) {
1290:                    if (geom.getFeatureIDRef().toString().equals(fid))
1291:                        return true;
1292:                }
1293:                return false;
1294:            }
1295:
1296:            public void setMapLayerTransform(MathTransform mapToLayer) {
1297:                AffineTransform oldToScreen = null;
1298:                Map<Point, List<Point>> map = new HashMap<Point, List<Point>>();
1299:                synchronized (this ) {
1300:                    if (mapToLayer.equals(pointCoordCalculator.mapToLayer))
1301:                        return;
1302:
1303:                    oldToScreen = new AffineTransform(
1304:                            pointCoordCalculator.toScreen);
1305:                    AffineTransform oldToWorld = new AffineTransform(
1306:                            pointCoordCalculator.toWorld);
1307:
1308:                    geomMapping.clear();
1309:                    coordMapping.clear();
1310:                    PointCoordCalculator calculator = new PointCoordCalculator(
1311:                            pointCoordCalculator.toScreen, mapToLayer);
1312:                    for (EditGeom geom : geometries) {
1313:                        for (PrimitiveShape shape : geom) {
1314:                            map.putAll(shape.getMutator().transform(
1315:                                    oldToScreen, oldToWorld, calculator));
1316:                        }
1317:                    }
1318:
1319:                    pointCoordCalculator.setMapToLayer(mapToLayer);
1320:
1321:                    if (EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS))
1322:                        for (EditGeom geom : geometries) {
1323:                            geom.assertValid();
1324:                        }
1325:                }
1326:                notify(new EditBlackboardEvent(this , this ,
1327:                        EventType.TRANFORMATION, oldToScreen, map));
1328:
1329:            }
1330:
1331:            /**
1332:             * Sets all the coordinates at the point to provided coordinate.
1333:             * <em>The coodinate must still map to the point</em>
1334:             * 
1335:             * @param point the point at which all the coordinates will be changed
1336:             * @param newValue the new coordinate value of coordinates at the point
1337:             */
1338:            public void setCoords(Point point, Coordinate newValue) {
1339:                synchronized (this ) {
1340:                    if (!toPoint(newValue).equals(point))
1341:                        throw new IllegalArgumentException(
1342:                                "newValue has to map to point.  newValue maps to: " + toPoint(newValue) //$NON-NLS-1$
1343:                                        + " but should map to" + point); //$NON-NLS-1$
1344:                    List<LazyCoord> coords = coordMapping.get(point);
1345:                    for (LazyCoord coord : coords) {
1346:                        coord.get(point);
1347:                        coord.coord = newValue;
1348:                        coord.x = newValue.x;
1349:                        coord.y = newValue.y;
1350:                        coord.z = newValue.z;
1351:                    }
1352:                }
1353:            }
1354:
1355:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.