Package org.locationtech.udig.tools.edit.support

Source Code of org.locationtech.udig.tools.edit.support.EditGeom

/* 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.support;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.locationtech.udig.tools.edit.EditPlugin;

import com.vividsolutions.jts.geom.Envelope;

/**
* Holds onto an geometry for editing, offering up PrimitiveShapes.
*
*
* Models a geometry as required by the PixelCoordMap (what is PixelCoordMap?)
*
* @author jones
* @since 1.1.0
*/
public class EditGeom implements Iterable<PrimitiveShape> {

    private final PrimitiveShape shell;
    private final List<PrimitiveShape> holes = Collections
            .synchronizedList(new ArrayList<PrimitiveShape>());
    EditBlackboard owner;
    private final AtomicReference<ShapeType> shapeType = new AtomicReference<ShapeType>();
    {
        shapeType.set(ShapeType.UNKNOWN);
    }
    private final AtomicReference<String> featureID = new AtomicReference<String>();
    private AtomicReference<Boolean> changed = new AtomicReference<Boolean>();
    boolean initializing;
   
    /**
     * The latest up-to-date bounds of the feature in datastore.
     */
    private Envelope featureBBox = null;

    /**
     * It is recommended to use constructor with bounds.
     *
     * @param owner
     * @param featureId2
     */
    public EditGeom( EditBlackboard owner, String featureId2 ) {
        this.owner = owner;
        shell = new PrimitiveShape(this);
        this.featureID.set(featureId2);
        changed.set(false);
    }
   
    /**
     *
     *
     * @param owner
     * @param featureId
     * @param featureBounds
     */
    public EditGeom( EditBlackboard owner, String featureId, Envelope featureBounds ) {
        this.owner = owner;
        shell = new PrimitiveShape(this);
        this.featureID.set(featureId);
        changed.set(false);
        this.featureBBox = featureBounds;
    }

    public EditGeom( EditGeom geom ) {
        shell = new PrimitiveShape(geom.getShell());
        for( PrimitiveShape hole : geom.getHoles() ) {
            holes.add(new PrimitiveShape(hole));
        }
        owner = geom.owner;
    }

    public PrimitiveShape getShell() {
        return shell;
    }
    /**
     * User is expected to add holes as needed.
     *
     * @return
     */
    public List<PrimitiveShape> getHoles() {
        return holes;
    }

    @Override
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(featureID.get());
        buffer.append(" "); //$NON-NLS-1$
        buffer.append(shapeType);
        buffer.append(" "); //$NON-NLS-1$
        buffer.append(shell.toString());
        buffer.append("{"); //$NON-NLS-1$       
        for( int i = 0, numHoles = this.holes.size(); i < numHoles; i++ ) {
            buffer.append(holes.get(i).toString());
        }
        buffer.append("}"); //$NON-NLS-1$
        return buffer.toString();
    }

    public PrimitiveShape newHole() {
        PrimitiveShape hole = new PrimitiveShape(this);
        hole.type="HOLE"; //$NON-NLS-1$
        holes.add(hole);
        return hole;
    }

    /**
     * @return Returns the featureID.
     */
    public AtomicReference<String> getFeatureIDRef() {
        return featureID;
    }

    /**
     * @return Returns the shape type.
     */
    public ShapeType getShapeType() {
        return shapeType.get();
    }

    /**
     * This is a thread-safe method
     *
     * @param type The new shape type.
     */
    public void setShapeType( ShapeType shapeType ) {
        this.shapeType.set(shapeType);
    }

    public Iterator<PrimitiveShape> iterator() {
        return new Iterator<PrimitiveShape>(){

            boolean shellAccessed = false;
            Iterator<PrimitiveShape> holeIter = holes.iterator();
            public boolean hasNext() {
                return !shellAccessed || holeIter.hasNext();
            }

            public PrimitiveShape next() {
                if (!shellAccessed) {
                    shellAccessed = true;
                    return shell;
                }

                return holeIter.next();
            }

            public void remove() {
                throw new UnsupportedOperationException("Remove not allowed"); //$NON-NLS-1$
            }

        };
    }

    /**
     * @return Returns the owner.
     */
    public EditBlackboard getEditBlackboard() {
        return owner;
    }
   
    /**
     * Returns an old bounding box of the feature whose geometry is wrapped by EditGeom
     * before any editing.
     *
     * @return
     *      Returns an old bounding box of the feature
     */
    public Envelope getFeatureEnvelope(){
        return featureBBox;
    }

    /**
     * Indicates that this geometry has been modified since it has been in the blackboard.
     *
     * @return true if the geometry has been modified while on the blackboard.
     */
    public boolean isChanged() {
        return changed.get();
    }

    /**
     * This method signals the in-memory state of EditGeom with respect to the actual
     * feature in datastore.
     * <p>
     <li><code>true</code> value means that the geometry is changed but not up-to-date
     *  with datastore's feature geometry.
     *  <li><code>false</code> value means that the geometry is up-to-date
     *  with datastore's feature geometry.
     *
     *
     *
     * @param changed
     */
    public void setChanged( boolean changed ) {
        if(this.changed.get() && !changed){
          synchronized(owner){
              Envelope envelope = new Envelope();
              for( int i = 0; i < shell.getNumCoords(); i++ ) {
                  envelope.expandToInclude(shell.getCoord(i));
              }
              featureBBox = envelope;
          }
        }
       
        this.changed.set(changed);

    }
    public Selection createSelection() {
        return new EditGeomSelection(this);
    }
    public void assertValid() {
        if( !EditPlugin.isDebugging(EditPlugin.RUN_ASSERTIONS))
            return;
        for( PrimitiveShape shape : this ) {
            shape.assertValid();
        }
    }

    public boolean hasVertex( Point point ) {
        if( shapeType.get()==ShapeType.POLYGON ){
            for( PrimitiveShape shape : this ) {
                if( shape.hasVertex(point) )
                    return true;
            }
            return false;
        }else{
            return shell.hasVertex(point);
        }
    }

    /**
     * Gets the closest edge in the geometry to the point.
     *
     * @param point reference point
     * @param treatUnknownAsPolygon declares whether to treat geometries of type UNKNOWN as a polygon
     * @return
     */
    public ClosestEdge getClosestEdge( Point point, boolean treatUnknownAsPolygon ) {
        assert shapeType.get()!=ShapeType.POINT;
        ClosestEdge closest = shell.getClosestEdge(point, treatUnknownAsPolygon);
        if( shapeType.get()==ShapeType.POLYGON  ||
                (shapeType.get()== ShapeType.UNKNOWN && treatUnknownAsPolygon) ){
           
            if( shell.contains(point, treatUnknownAsPolygon) ){
                for( PrimitiveShape shape : holes ) {
                    ClosestEdge current = shape.getClosestEdge(point, treatUnknownAsPolygon);
                    if ( closest==null )
                        closest=current;
                    else if( current!=null && current.distanceToEdge<closest.distanceToEdge )
                        closest=current;
                }
            }
        }
        return closest;
    }

    public Point overVertex( Point point, int radius ) {
        for( PrimitiveShape shape : this ) {
            Point p=shape.overVertex(point, radius);
            if( p!=null )
                return p;
        }
        return null;
    }

}
TOP

Related Classes of org.locationtech.udig.tools.edit.support.EditGeom

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.